Logical condition in set (GAMS) - how do this in pyomo? - set

I'm passing code from Gams to pyomo and I don't know if this option to access an index has in python.
In gams:
k purifiers /PSA4241, PSA241, PSA241A, PSA3241, NEW/
oldk(k) = yes$(ord(k) le 4) ; newk(k) = yes$(ord(k) eq 5) ;
EL31(i,k,s)$newk(k).. zkns(k,s) =g= ZIK(i,k,s);
$newk(k) it would just be a part of the set k.
How could I use this selection in pyomo? Any tips?

Seeing your question and comments, what I understand is: You got a full Set (lest call it S) in a ConcreteModel() in pyomo and you need, to use just a slice of that Set (lets call it S1) in order to use it into a Constraint. Your approach is just creating a couple of Sets such that S = S1∪S2 to use it as you want.
In pyomo for the constraint you can do that, or you can just pass the value you want into the Constraint
Lets assume a problem structure:
import pyomo.environ as pyo
mySet = ['m1', 'm2', 'm3', 'm4', 'm5']
model = pyo.ConcreteModel()
model.s = pyo.Set(initialize=mySet)
model.x = pyo.Var(model.s, domain=pyo.NonNegativeReals)
If you want to apply a certain constraint just to the final value of the set, you can just pass it into one single constraint, like this
model.const = pyo.Constraint(expr=model.x[model.s[-1]]>=5)
or you can use the last() method of the OrderedSimpleSet class
model.const = pyo.Constraint(expr=model.x[model.s.last()]>=5)
In the same way you can use the indexedConstraint approach to apply the same structure to several values.
def constr2(model, s):
return model.x[s] >= 5
model.constr2 = pyo.Constraint(model.s.ordered_data()[-2:], )
This will apply the constraint to the last 2 values of the Set.
If you definitely need to split your original data, you can create a first new set and then apply the difference method to generate the rest values
model.s2 = pyo.Set(initialize=['m1','m2'])
model.s1 = model.s.difference(model.s2)
This will give you this result
>>>model.s1.display()
s1 : Size=1, Index=None, Ordered=True
Key : Dimen : Domain : Size : Members
None : 1 : s - s2 : 3 : {'m3', 'm4', 'm5'}
>>>model.s2.display()
s2 : Size=1, Index=None, Ordered=Insertion
Key : Dimen : Domain : Size : Members
None : 1 : Any : 2 : {'m1', 'm2'}
I hope this help you to understand how you can deal with slicing Set in pyomo and why using a programming language as Python can improve the performance of a modeling task.

Related

Is there a way to use range with Z3ints in z3py?

I'm relatively new to Z3 and experimenting with it in python. I've coded a program which returns the order in which different actions is performed, represented with a number. Z3 returns an integer representing the second the action starts.
Now I want to look at the model and see if there is an instance of time where nothing happens. To do this I made a list with only 0's and I want to change the index at the times where each action is being executed, to 1. For instance, if an action start at the 5th second and takes 8 seconds to be executed, the index 5 to 12 would be set to 1. Doing this with all the actions and then look for 0's in the list would hopefully give me the instances where nothing happens.
The problem is: I would like to write something like this for coding the problem
list_for_check = [0]*total_time
m = s.model()
for action in actions:
for index in range(m.evaluate(action.number) , m.evaluate(action.number) + action.time_it_takes):
list_for_check[index] = 1
But I get the error:
'IntNumRef' object cannot be interpreted as an integer
I've understood that Z3 isn't returning normal ints or bools in their models, but writing
if m.evaluate(action.boolean):
works, so I'm assuming the if is overwritten in a way, but this doesn't seem to be the case with range. So my question is: Is there a way to use range with Z3 ints? Or is there another way to do this?
The problem might also be that action.time_it_takes is an integer and adding a Z3int with a "normal" int doesn't work. (Done in the second part of the range).
I've also tried using int(m.evaluate(action.number)), but it doesn't work.
Thanks in advance :)
When you call evaluate it returns an IntNumRef, which is an internal z3 representation of an integer number inside z3. You need to call as_long() method of it to convert it to a Python number. Here's an example:
from z3 import *
s = Solver()
a = Int('a')
s.add(a > 4);
s.add(a < 7);
if s.check() == sat:
m = s.model()
print("a is %s" % m.evaluate(a))
print("Iterating from a to a+5:")
av = m.evaluate(a).as_long()
for index in range(av, av + 5):
print(index)
When I run this, I get:
a is 5
Iterating from a to a+5:
5
6
7
8
9
which is exactly what you're trying to achieve.
The method as_long() is defined here. Note that there are similar conversion functions from bit-vectors and rationals as well. You can search the z3py api using the interface at: https://z3prover.github.io/api/html/namespacez3py.html

Octave: matrix multiplication over a group

I'd like to simply compute multiplication of two matrices.
But instead of real numbers I'd like to use elements of a finite group in the matrix.
Namely I want to use elements of F4={0,1,x,1+x} (so i only have 4 possible elements). In this group, addition and multiplication are well-defined, and the relations x^2=1+x, 1+1=0 and x+x=0 hold.
Since I'm a beginner at programming in Octave, I have no idea how to compute operations with something different than real numbers.
My idea was, that if it's possible to define some operations on a certain set of elements (here F4), then it's maybe possible to use these operations when multiplicating matrices.
I think the most efficient way to do arithmetic with a finite group of possible values and non-standard addition and multiplication is by table lookup.
Table lookup requires matrices to be encoded such that the elements are indices into the list of group elements. And since indexing starts at 1, you'll need to represent {0,1,x,x+1} as {1,2,3,4}.
But aside the awkward mapping of 1=0, 2=1, things are quite straightforward with table lookup. This is some example code I cooked up, it seems to work but I might have made some mistake (and I might have misunderstood the exact arithmetic rules):
function out = group_mtimes(lhs,rhs)
[I,K] = size(lhs);
[K2,J] = size(rhs);
if K~=K2, error('Inner dimensions must agree'), end
out = zeros(I,J);
for j=1:J
for i=1:I
v = 1;
for k=1:K
v = group_scalar_add(v, group_scalar_times(lhs(i,k),rhs(k,j)));
end
out(i,j) = v;
end
end
disp('lhs = ')
group_print(lhs)
disp('rhs = ')
group_print(rhs)
disp('lhs * rhs = ')
group_print(out)
end
function group_print(in)
names = {'0','1','x','1+x'};
disp(names(in)) % Quick-and-dirty, can be done much better!
end
function out = group_scalar_add(lhs,rhs)
table = [
1,2,3,4
2,1,4,3
3,4,1,2
4,3,2,1
];
out = table(lhs,rhs);
end
function out = group_scalar_times(lhs,rhs)
table = [
1,1,1,1
1,2,3,4
1,3,4,2
1,4,2,3
];
out = table(lhs,rhs);
end
For example:
>> lhs=[1,2,3,4;2,3,1,4]';
>> rhs=[2,3;4,1];
>> group_mtimes(lhs,rhs);
lhs =
'0' '1'
'1' 'x'
'x' '0'
'1+x' '1+x'
rhs =
'1' 'x'
'1+x' '0'
lhs * rhs =
'1+x' '0'
'0' 'x'
'x' '0'
'x' '1'
There is no input checking in this code, if the input contains a 5, you'll get and index out of range error.
As I mentioned in a comment, you could make a class that encapsulates arrays of this type. You could then overload plus, times and mtimes (for operators +, .* and *, respectively), as well as disp to write out the values properly. You would define the constructor so that objects of this class always have valid values, this would prevent lookup table indexing errors. Such a class would make working with these functions a lot simpler.
For the special case of Galois fields of even characteristic, such as F4, you can use the functions provided by the communications package from Octave Forge:
Functions reference: Galois Fields of Even Characteristic
Galois fields of odd charactristic are not implemented yet:
Functions reference: Galois Fields of Odd Characteristic

How to create the equivalent of a HashMap<Int, Int[]> in Lua

I would like to have a simple data structure in lua resembling a Java HashMap equivalent.
The purpose of this is that I wish to maintain a unique key 'userID' mapped against a set of two values which get constantly updated, for example;
'77777', {254, 24992}
Any suggestions as to how can I achieve this?
-- Individual Aggregations
local dictionary = ?
-- Other Vars
local sumCount = 0
local sumSize = 0
local matches = redis.call(KEYS, query)
for _,key in ipairs(matches) do
local val = redis.call(GET, key)
local count, size = val:match(([^:]+):([^:]+))
topUsers(string.sub(key, 11, 15), sumCount, sumSize)
-- Global Count and Size for the Query
sumCount = sumCount + tonumber(count)
sumSize = sumSize + tonumber(size)
end
local result = string.format(%s:%s, sumCount, sumSize)
return result;
-- Users Total Data Aggregations
function topUsers()
-- Do sums for each user
end
Assuming that dictionary is what you are asking about:
local dictionary = {
['77777'] = {254, 24992},
['88888'] = {253, 24991},
['99999'] = {252, 24990},
}
The tricky part is that the key is a string that can't be converted to a Lua variable name so you must surround each key with []. I can't find a clear description of rule for this in Lua 5.1 reference manual, but the Lua wiki says that if a key "consists of underscores, letters, and numbers, but doesn't start with a number" only then does it not require the [] when defined in the above manner, otherwise the square brackets are required.
Just use a Lua table indexed by userID and with values another Lua table with two entries:
T['77777']={254, 24992}
This is possible implementation of the solution.
local usersTable = {}
function topUsers(key, count, size)
if usersTable[key] then
usersTable[key][1] = usersTable[key][1] + count
usersTable[key][2] = usersTable[key][2] + size
else
usersTable[key] = {count, size}
end
end
function printTable(t)
for key,value in pairs(t) do
print(key, value[1], value[2])
end
end

USing AddExpression / MathExpression in Weka

I am working on a very basic WEKA assignment, and I'm trying to use WEKA to preprocess data from the GUI (most current version). I am trying to do very basic if statements and mathematical statements in the expression box when double clicking on MathExpression and I haven't had any success. For example I want to do
if (a5 == 2 || a5 == 0) then y = 1; else y = 0
Many different variations of this haven't worked for me and I'm also unclear on how to refer to "y" or if it needs a reference within the line.
Another example is -abs(log(a7)–3) which I wasn't able to work out either. Any ideas about how to make these statements work?
From javadoc of MathExpression
The 'A'
letter refers to the value of the attribute being processed.
Other attribute values (numeric only) can be accessed through
the variables A1, A2, A3, ...
Your filter applies to all attributes of your dataset. If I load iris dataset and apply following filter.
weka.filters.unsupervised.attribute.MathExpression -E log(A).
your attribute ,sepallength values change as following.
Before Filter After Filter
Minimum 4.3 Minimum 1.459
Maximum 7.9 Maximum 2.067
Mean 5.843 Mean 1.755
StdDev 0.828 StdDev 0.141
Also if you look to javadoc, there is no if else function but ifelse function. Therefore you should write something like
ifelse ( (A == 2 || A == 0), 1,0 )
Also this filter applies to all attributes. If you want to change only one attribute and according to other attribute values ; then you need to use "Ignore range option" and use A1,A2 to refer to other attribute values.
if you need to add new attribute use AddExpression.
An instance filter that creates a new attribute by applying a mathematical expression to existing attributes.

Looking for the name of algorithm for turning around keys and values in specific hashes

UPDATE : Let me elaborate to the closers : I am asking for the name of a routine.
I try to honour the Principle of least astonishment and naming is very important.
Besides : if this is an existant routine, and my guess is it is, there is an objective name for it. When I know this name I could, to name just 1 thing,google on it.
I need to 'turnaround' a hash in javascript as shown here. (the values are always arrays). The function turnaround() is not the problem (I have written it already) but the name is.
What Am I doing here exactly, or put differently has this routine a name?
If it isn't a well-known algoritm, how should I name it so that the name defines what it's doing?
true == ( (h2 == turnaround(h1)) && (h1 == turnaround(h2))
h1 : {
a : [ 2, 3 ],
b : [ 3, 4 ],
c : [ 2, 4 ],
d : [ 1, 5 ] }
h2 : {
1 : ["d"],
2 : ["a","c"],
3 : ["a","b"],
4 : ["b","c"],
5 : ["d"] }
Typically, if you have a map associating keys with lists of values, the corresponding mapping from values to lists of keys is called an inverted index. Since what you are doing is constructing the inverted index for a particular mapping, you could call your function something to the effect of createInvertedIndex or invertIndex.
Your function is such that turnAround(turnAround()) = Identity .
turnAround = turnAround^-1
when applying turnAround(h) you find the unique element h^-1 such that h = turnAround(h^-1)
therefore you've inversed h. (inverse function)
You can call it inverseHashFunction ?
I think it's explicit enough,
otherwise reciprocalHash ? reciprocalBijectionHash ? etc...
If you want, you can think of your hash as describing a relation R, according to the definition that x R y if and only if y is in h1[x].
Then, the return value of your turnaround function describes the inverse relation in the same way: by definition y R-1 x if and only if x R y. That happens if and only if x is in turnaround(h1)[y].
So, if you're actually using h1 and h2 as descriptions of relations, then I'd call it invertedRelation or similar. If you're not using them as descriptions of relations (or you are using them as that, but the mathematical term 'relation' isn't familiar to your readers), that might just be confusing.
What kind of variable names do you really use for these hashes? If you're fanatical about function names being descriptive, surely you don't really call your variables h1 and h2!

Resources