How can I define an array filled with a single value in AMPL - 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.

Related

Inline index addition in gams

I want to use an index equation to iterate over a tensors, whereas I always want to extract the value at index i and index i+1. An example:
Variable x; x.up = 10;
Parameter T /1=1,2=2,3=3,4=4,5=5/;
Set a /1,2,4/;
equation eq(a); eq(a).. x =g= T[a+1];
*x ist restricted by the values of T at the indices 2,3 and 5.
Model dummy /all/;
solve dummy min x use lp;
I am aware that gams sees the indices as string-keys rather than numerical ones, so the addition is not intended. Is this possible anyway? This e.g. can be solved by defining another tensor, unfortunaly my given conditions require the index operation inline (i.e. I am not allowed to define additional parameters or sets.
Does this work for you?
Variable x; x.up = 10;
Set aa /1*6/;
Parameter T(aa) /1=1,2=2,3=3,4=4,5=5/;
Set a(aa) /1,2,4/;
equation eq(a); eq(a(aa)).. x =g= T[aa+1];
*x ist restricted by the values of T at the indices 2,3 and 5.
Model dummy /all/;
solve dummy min x use lp;

Questions on the prime number calculating code in Raku

I've come across this code at RosettaCode
constant #primes = 2, 3, { first * %% none(#_), (#_[* - 1], * + 2 ... Inf) } ... Inf;
say #primes[^10];
Inside the explicit generator block:
1- What or which sequence do the #_ s refer to?
2- What does the first * refer to?
3- What do the * in #_[* - 1] and the next * refer to?
4- How does the sequence (#_[* - 1], * + 2 ... Inf) serve the purpose of finding prime numbers?
Thank you.
The outer sequence operator can be understood as: start the sequence with 2 and 3, then run the code in the block to work out each of the following values, and keep going until infinity.
The sequence operator will pass that block as many arguments as it asks for. For example, the Fibonacci sequence is expressed as 1, 1, * + * ... Inf, where * + * is shorthand for a lambda -> $a, $b { $a + $b }; since this wishes for two parameters, it will be given the previous two values in the sequence.
When we use #_ in a block, it's as if we write a lambda like -> *#_ { }, which is a slurpy. When used with ..., it means that we wish to be passed all the previous values in the sequence.
The sub first takes a predicate (something we evaluate that returns true or false) and a list of values to search, and returns the first value matching the predicate. (Tip for reading things like this: whenever we do a call like function-name arg1, arg2 then we are always parsing a term for the argument, meaning that we know the * cannot be a multiplication operator here.)
The predicate we give to first is * %% none(#_). This is a closure that takes one argument and checks that it is divisible by none of the previous values in the sequence - for if it were, it could not be a prime number!
What follows, #_[* - 1], * + 2 ... Inf, is the sequence of values to search through until we find the next prime. This takes the form: first value, how to get the next value, and to keep going until infinity.
The first value is the last prime that we found. Once again, * - 1 is a closure that takes an argument and subtracts 1 from it. When we pass code to an array indexer, it is invoked with the number of elements. Thus #arr[* - 1] is the Raku idiom for "the last thing in the array", #arr[* - 2] would be "the second to last thing in the array", etc.
The * + 2 calculates the next value in the sequence, and is a closure that takes an argument and adds 2 to it. While we could in fact just do a simple range #_[* - 1] .. Inf and get a correct result, it's wasteful to check all the even numbers, thus the * + 2 is there to produce a sequence of odd numbers.
So, intuitively, this all means: the next prime is the first (odd) value that none of the previous primes divide into.

Destructuring a list with equations in maxima

Say that I have the following list of equations:
list: [x=1, y=2, z=3];
I use this pattern often to have multiple return values from a function. Kind of of like how you would use an object, in for example, javascript. However, in javascript, I can do things like this. Say that myFunction() returns the object {x:1, y:2, z:3}, then I can destructure it with this syntax:
let {x,y,z} = myFunction();
And now x,y,z are assigned the values 1,2,3 in the current scope.
Is there anything like this in maxima? Now I use this:
x: subst(list, x);
y: subst(list, y);
z: subst(list, z);
How about this. Let l be a list of equations of the form somesymbol = somevalue. I think all you need is:
map (lhs, l) :: map (rhs, l);
Here map(lhs, l) yields the list of symbols, and map(rhs, l) yields the list of values. The operator :: means evaluate the left-hand side and assign the right-hand side to it. When the left-hand side is a list, then Maxima assigns each value on the right-hand side to the corresponding element on the left.
E.g.:
(%i1) l : [a = 12, b = 34, d = 56] $
(%i2) map (lhs, l) :: map (rhs, l);
(%o2) [12, 34, 56]
(%i3) values;
(%o3) [l, a, b, d]
(%i4) a;
(%o4) 12
(%i5) b;
(%o5) 34
(%i6) d;
(%o6) 56
You can probably achieve it and write a function that could be called as f(['x, 'y, 'z], list); but you will have to be able to make some assignments between symbols and values. This could be done by writing a tiny ad hoc Lisp function being:
(defun $assign (symb val) (set symb val))
You can see how it works (as a first test) by first typing (form within Maxima):
:lisp (defun $assign (symb val) (set symb val))
Then, use it as: assign('x, 42) which should assign the value 42 to the Maxima variable x.
If you want to go with that idea, you should write a tiny Lisp file in your ~/.maxima directory (this is a directory where you can put your most used functions); call it for instance myfuncs.lisp and put the function above (without the :lisp prefix); then edit (in the very same directory) your maxima-init.mac file, which is read at startup and add the two following things:
add a line containing load("myfuncs.lisp"); before the following part;
define your own Maxima function (in plain Maxima syntax with no need to care about Lisp). Your function should contain some kind of loop for performing all assignments; now you could use the assign(symbol, value) function for each variable.
Your function could be something like:
f(vars, l) := for i:1 thru length(l) do assign(vars[i], l[i]) $
which merely assign each value from the second argument to the corresponding symbol in the first argument.
Thus, f(['x, 'y], [1, 2]) will perform the expected assigments; of course you can start from that for doing more precisely what you need.

Accessing the last element of a variable in GAMS

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

What is a data structure for quickly finding non-empty intersections of a list of sets?

I have a set of N items, which are sets of integers, let's assume it's ordered and call it I[1..N]. Given a candidate set, I need to find the subset of I which have non-empty intersections with the candidate.
So, for example, if:
I = [{1,2}, {2,3}, {4,5}]
I'm looking to define valid_items(items, candidate), such that:
valid_items(I, {1}) == {1}
valid_items(I, {2}) == {1, 2}
valid_items(I, {3,4}) == {2, 3}
I'm trying to optimize for one given set I and a variable candidate sets. Currently I am doing this by caching items_containing[n] = {the sets which contain n}. In the above example, that would be:
items_containing = [{}, {1}, {1,2}, {2}, {3}, {3}]
That is, 0 is contained in no items, 1 is contained in item 1, 2 is contained in itmes 1 and 2, 2 is contained in item 2, 3 is contained in item 2, and 4 and 5 are contained in item 3.
That way, I can define valid_items(I, candidate) = union(items_containing[n] for n in candidate).
Is there any more efficient data structure (of a reasonable size) for caching the result of this union? The obvious example of space 2^N is not acceptable, but N or N*log(N) would be.
I think your current solution is optimal big-O wise, though there are micro-optimization techniques that could improve its actual performance. Such as using bitwise operations when merging the chosen set in item_containing set with the valid items set.
i.e. you store items_containing as this:
items_containing = [0x0000, 0x0001, 0x0011, 0x0010, 0x0100, 0x0100]
and your valid_items can use bit-wise OR to merge like this:
int valid_items(Set I, Set candidate) {
// if you need more than 32-items, use int[] for valid
// and int[][] for items_containing
int valid = 0x0000;
for (int item : candidate) {
// bit-wise OR
valid |= items_containing[item];
}
return valid;
}
but they don't really change the Big-O performance.
One representation that might help is storing the sets I as vectors V of size n whose entries V(i) are 0 when i is not in V and positive otherwise. Then to take the intersection of two vectors you multiply the terms, and to take the union you add the terms.