Accessing the last element of a variable in GAMS - gams-math

I have a set:
Set t /t1*t6/;
Let us consider there is a variable called var. I have a constraint that the last element of var is less than 20.
Variable var(t);
Equation const;
const..
var('t6') < 20;
I would like to replace 't6' in the last line by something like card(t), so that if the size of t changes then I do not have to change it manually.

You can use a dollar condition to limit the equation to the last period:
const(t)$(ord(t) = card(t)).. var(t) < 20;
Or you could define a singleton subset for your end condition like so:
singleton set tEnd(t) /t6/;
const.. var(tEnd) < 20;

You could also define an upper bound with the help of the "last" attribute of the set t:
Set t /t1*t6/;
Variable var(t);
var.up(t)$(t.last) = 20;
Best,
Lutz

Related

GAMS modelation: how do i set an identifier as the last value of a set (index.last) on an equation

I'm modeling a VRP in GAMS language and one of my equations would ideally be:
SUM(i, x(i,n+1)) =e= 0;
with "n+1" being the last value of the set i /0*4/ (so it's 4)
I can't type x(i,"4") because this number (4) is just an example.
The software doesn't recognize this equation. the error says "unknown identifier set as index, which i understand is because "n" isn't a set.
so i put n as a set, just like i did with i, but then I'd have to give it a number (3, so that n+1 = 4) and i don't want that.
I just need a way to put "n+1" as a valid index for x(i,n+1)
Assuming that x is declared as x(i,i), you can do something like this:
Alias (i,i2);
Equation eq;
eq.. SUM((i,i2)$i2.last, x(i,i2)) =e= 0;

How can I define an array filled with a single value in AMPL

How can I define an unary or multidimensional array filled with one value in AMPL?
Is there something like this?
param ARRAY {i in 1..1000} [i] := 20;
Should result in:
[20, 20, 20, ..., 20]
You were almost there, but I'll throw in a couple of extra options:
param ARRAY{i in 1..1000} := 20;
# sets all values to 20
param ARRAY{i in 1..1000} default 20;
# sets all values to 20 unless otherwise specified
param ARRAY{i in 1..1000};
for{i in 1..1000} {let ARRAY[i] = 20};
# iterates over the specified set.
# more useful if you want to do something like i^2 instead of a constant.
If you use the default 20 method, then display ARRAY; will only show the values that have been changed from default - it will look as if ARRAY is empty, but referencing specific elements will work OK.

Variable indexes outside of defined range in AMPL

Not too familiar with AMPL, but running into some issues with indexes...
Basically, I have some variables defined as such:
var array{i in set};
And I need to do some amount of checking the elements around a given i in some of the constraints:
subject to Constraint{i in set}:
array[i] + array[i-1] + array[i+1] <= 12;
But obviously array[0] or array[card(set) + 1] don't exist. To add a further issue, I'm trying to model a sort of problem in which array[0] or array[card(set) + 1] just shouldn't be factored into our computation at all (e.g. it shouldn't constrain the other variables). Any help appreciated :) Thanks.
In AMPL, you can create or define your own "sets" for valid indices and use them in your constraints.
So, in your case, to avoid invalid indices, you can define a set of permissible indices: param inner_i {2..(N-1)} and loop over those when creating the constraints.
The price we pay is that we have to explicitly take care of the corner cases.
Here's one way to do it: (Note, I don't have AMPL loaded, so the code is untested.)
param N > 0; #number of elements
set ELEM; # Elements
set inner_i {2..(N-1)} > 0; #valid indices
var array {ELEM} >= 0;
subject to LimitSum{i in inner_i}:
array[i-1] + array[i] + array[i+1] <= 12;
#Take care of the boundary conditions explicitly, if needed
subject to LimitSum_start:
array[1] + array[2] <= 12;
#only two elements since array[0] doesn't exist.
subject to LimitSum_last:
array[N-1] + array[N] <= 12;
#only two elements since array[N+1] doesn't exist.
Hope this helps you move forward.
You can use an if-then-else expression to conditionally include some terms:
subject to Constraint{i in set}:
array[i] + (if i != 0 then array[i-1]) + (if i != N then array[i+1]) <= 12;
where N is the last element of the set.

iOS: Using Accelerate Framework to append / remove a column or row from a matrix?

I've looked through the vDSP and BLAS reference docs, and can't seem to find anything on appending / removing a row or column from a matrix. I'm currently using for-loops, but would rather use an accelerate function if one exists.
We can use vDSP_mmov(1) or vDSP_mmovD(2). Below sample to append 1 row at end.
//sanple to add 1 row
float dst[4][4] = { 1,2,3,4, 5,6,7,8, 9,10,11,12 } ; //last row empty
float src[1][4] = { 13,14,15,16 };
//to fill last row
int numColumnsToCopy = 4;
int numRowsToCopy = 1;
int numColsinDst = 4;
int numColsinSrc = 4;
vDSP_mmov(src, &dst[3][0], numColumnsToCopy, numRowsToCopy, numColsinSrc, numColsinDst );
The same sample could be tweaked to append/remove rows/columns at the end. Though you could overwrite rows/columns in middle, I am not sure if you could append/remove a row/column in middle of matrix as that will need shifts. You might need to split then.
Though there is no harm in using for one off runs, you might not get speed benefits you are looking for. For repetitive runs, these frameworks help.

Algorithm for max and min? (Objective-C)

This is a part of a book I'm reading to learn Objective-C.
The following defines a macro called MAX that gives the maximum of two
values: #define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
And then there are some exercises in the book that asks the reader to define a macro (MIN) to find the minimum of two values and another that asks to define a macro called MAX3 that gives the maximum of 3 values. I think these two definitions will look similar to MAX, but I don't understand how the MAXformula finds the maximum value. I mean if I just did this
int limits = MAX (4,8)
It'll just assign limits the value of 8. What does that have to do with finding a variable's maximum value?
I think you are confusing value and variable. The macro example you listed expands to a comparison between two values and returns the greater of the two values (i.e. which is greater, a or b). So you are right, int limits = MAX(4,8) just assigns 8 to limits and has nothing to do with finding the maximum value you can store in limits.
The header limits.h defines many values like INT_MAX that will tell you information about the min/max values of variable types on your system.
To break it apart:
The declaration:
#define MAX(a,b)
If a is greater than b, use a else use b:
( ((a) > (b)) ? (a) : (b) )
Then to create a MIN expression, use a similar form:
#define MIN(a,b) ( ((a) < (b)) ? (a) : (b) )
^
Then to create a MAX3 expression, you can combine them:
#define MAX3(a,b,c) ( MAX(a, MAX(b,c)) )
Specifically, this macro's intended to be used with scalars (C builtins) which can be compared using < or >. If you passed an objc variable, it would result in comparison of addresses and MAX would return the one with the higher address (it would be very rare if you actually wanted to compare addresses of objc instances).
Also note that this is the classic example of how macros can bite you. With macros, the preprocessor simply expands (textual copy/paste) the parameters in place, so: int limits = MAX (4,8) literally expands to int limits = (4 > 8 ? 4 : 8). If you write MAX(x,++y), then y will be incremented twice if y is greater than or equal to x because it expands to: int limits = (x > ++y ? x : ++y).
generally, you will use a MAX() or MIN() macro to get whichever is the higher/lower of a pair of variables, or of a variable and a constant, or even a pair of macro constants or other non-literal constant expressions. you generally won't supply 2 literal constants as you have done in your question.
Algorithm for max (Objective-C)
// get max value
- (float)maxValue:(NSArray *)arrValue
{
float maxValue = 0.0;
for (NSString *value in arrValue) {
float compareValue = [value floatValue];
if (compareValue > maxValue) {
maxValue = compareValue;
}
}
return maxValue;
}
NSArray *number=[NSArray arrayWithObjects:[NSNumber numberWithFloat:57.02], [NSNumber numberWithFloat:55.02], [NSNumber numberWithFloat:45.02], nil];
NSLog(#"%f", [self maxValue:number]);
result 57.020000