I am trying to perform the following loop:
I have three arrays:
l, val_lambda, val_alpha, each of them contains 10 values
and a datasets, a list of 1000 class results, i.e dataset[i] = traj_analysis(dt, X, Y, x, y, z) for x, y, z in l, val_lambda, val_alpha.
Now I would like to print on a file one of the instance's result of the class traj_analysis - with a certain concern for the folders. This is what I wrote down:
the_vals = [(x, y, z) for x in val_lambda for y in val_alpha for z in l]
for (x, y, z) in tqdm(the_vals):
for data in datasets:
if x == data.par_lambda & y == data.par_alpha & z == data.l0:
filename_msd = './simulation/lamda =' +str(f'{x:.2f}')+'/ alpha ='+str(f'{y:.2f}')+'/cargo/l0='+str(f'{z:.2f}')+'/cargo_msd.csv'
os.makedirs(os.path.dirname(filename_msd), exist_ok=True)
np.savetxt(filename_msd, data.msd, delimiter=',')
Unfortunately I got this error:
ufunc 'bitwise_and' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
Can someone help me to reformulate the loop in a coherent way and maybe also to speed it up?
Firstly, Consider using zip instead,
for (x, y, z) in tqdm(zip(val_lambda, val_alpha, l)):
Secondly, the issue could be in your if statement logic.
This is because & has higher precedence over ==, so in your statement, it might have been evaluated as:
if x == (data.par_lambda & y) == (data.par_alpha & z) == data.l0:
The fix would be to put the appropriate bracket at the appropriate places:
if (x == data.par_lambda) & (y == data.par_alpha) & (z == data.l0):
Just to add on, & is more commonly used for bitwise operations, hence, as fferri suggested, you might want to change it to and instead. The and operator has lower precedence over ==, thus == will be evaluted first. Nonetheless, it's still good practice to have the brackets!
if (x == data.par_lambda) and (y == data.par_alpha) and (z == data.l0):
Related
I want to implement the modulo operation using Z3Py. I've found this discussion on the Z3 github page where one of the creators has the following solution. However, I'm not sure I fully understand it.
from z3 import *
mod = z3.Function('mod', z3.RealSort(), z3.RealSort(), z3.RealSort())
quot = z3.Function('quot', z3.RealSort(), z3.RealSort(), z3.IntSort())
s = z3.Solver()
def mk_mod_axioms(X, k):
s.add(Implies(k != 0, 0 <= mod(X, k)),
Implies(k > 0, mod(X, k) < k),
Implies(k < 0, mod(X, k) < -k),
Implies(k != 0, k * quot(X, k) + mod(X, k) == X))
x, y = z3.Reals('x y')
mk_mod_axioms(x, 3)
mk_mod_axioms(y, 5)
print(s)
If you set no additional constraints the model evaluates to 0, the first solution. If you set additional constraints that x and y should be less than 0, it produces correct solutions. However, if you set the constraint that x and y should be above 0 it produces incorrect results.
s.add(x > 0)
s.add(y > 0)
The model evaluates to 1/2 for x and 7/2 for y.
Here's the model z3 prints:
sat
[y = 7/2,
x = 1/2,
mod = [(7/2, 5) -> 7/2, else -> 1/2],
quot = [else -> 0]]
So, what it's telling you is that it "picked" mod and quot to be functions that are:
def mod (x, y):
if x == 3.5 and y == 5:
return 3.5
else:
return 0.5
def quot (x, y):
return 0
Now go over the axioms you put in: You'll see that the model does satisfy them just fine; so there's nothing really wrong with this.
What the answer you linked to is saying is about what sort of properties you can state to get a "reasonable" model. Not that it's the unique such model. In particular, you want quot to be the maximum such value, but there's nothing in the axioms that require that.
Long story short, the answer you're getting is correct; but it's perhaps not useful. Axiomatizing will take more work, in particular you'll need quantification and SMT solvers don't deal with such specifications that well. But it all depends on what you're trying to achieve: For specific problems you can get away with a simpler model. Without knowing your actual application, the only thing we can say is that this axiomatization is too weak for your use case.
from z3 import *
x = Real('x')
s = Solver()
s.add(x > 1 or x < -1)
print(s.check())
if s.check() == sat:
print(s.model())
I want to solve a or expressions , how can i do it?
when z3 told me "Symbolic expressions cannot be cast to concrete Boolean values"
Python's or is not symbolic aware. Instead, use z3py's Or:
from z3 import *
x = Real('x')
s = Solver()
s.add(Or(x > 1, x < -1))
r = s.check()
print(r)
if r == sat:
print(s.model())
This prints:
sat
[x = -2]
Note that I'd also avoid two separate calls to check, by storing the result in a variable first. (Which I called r above.) In general, the second call to check will be cheap since you haven't added any constraints after the first, but this makes the intention clearer.
Let us assume I have a finite set {e1, e2, e3}. I want to be able to distinguish transitive constraints so I can handle this behavior:
from z3 import *
solver = Solver()
A = DeclareSort('A')
x = Const('x', A)
y = Const('y', A)
z = Const('z', A)
solver.add(x!=y)
solver.add(y!=z)
solver.add(x==z)
assert solver.check() != z3.sat
The only way I found to solve it is changing the last constraint with this one:
solver.add(ForAll([x,z],x==z))
Is this the way to model it? Is there any finite sort available? Should I need to add all the constraints declaring the elements different from each other?
Some clarification: Maybe is not a variable what I need, because {x == y, y == z, x == z } is clearly sat, but the behavior I want to model is more like this {x == 1, 2 == z, x == z } that is obviously unsat (assuming some finite sort like {1,2,3,4}).
What I was looking for was the EnumSort:
from z3 import *
solver = Solver()
S, (a, b, c) = EnumSort('round', ['a','b','c'])
x = Const("x", S)
z = Const("z", S)
solver.add(x==a)
solver.add(z==b)
solver.add(x==z)
assert solver.check() != z3.sat
I have a set of three variables x, y, z and I want to check if they all share the same value. In my case, the value will either be 1 or 0, but I only need to know if they are all the same. Currently I'm using
if 1 == x and 1 == y and 1 == z:
sameness = True
Looking for the answer I've found:
if 1 in {x, y, z}:
However, this operates as
if 1 == x or 1 == y or 1 == z:
atleastOneMatch = True
Is it possible to check if 1 is in each: x, y, and z?
Better yet, is there a more concise way of checking simply if x, y, and z are the same value?
(If it matters, I use Python 3.)
If you have an arbitrary sequence, use the all() function with a generator expression:
values = [x, y, z] # can contain any number of values
if all(v == 1 for v in values):
otherwise, just use == on all three variables:
if x == y == z == 1:
If you only needed to know if they are all the same value (regardless of what value that is), use:
if all(v == values[0] for v in values):
or
if x == y == z:
To check if they are all the same (either 1 or 2):
sameness = (x == y == z)
The parentheses are optional, but I find it improves readability
How about this?
x == y == z == 1
In my case, the value will either by 1 or 2, but I only need to know if they are all the same
Is it possible to check if 1 is in each: x, y, and z?
Better yet, is there a more concise way of checking simply if x, y, and z are the same value?
Sure:
x == y == z
which is equivalent to
(x == y) and (y == z)
If you have an arbitrary (nonzero) number of values to compare:
all(values[0] == v for v in values[1:])
You could use something similar to what you have:
sameness = (len({x, y, z}) == 1)
This allows for any number of variables. For example:
variables = {x, y, z, a, b, ...}
sameness = (len(variables) == 1)
Note: Creating a set means that each variable needs to be hashed and the hashed values need to be stored, but all() with a generator expression is short-circuiting and keeps track of only two values at a time. Therefore, besides its readability, the generator expression is more efficient.
Another way:
sameness = all(e == 1 for e in [x, y, z])
[x,y,z].count(1)
will count how many variables have 1 as value
Below all() and any() functions in python can server the purpose.
all() act as "AND": if all the values in any ittertable object is equal to given condition value, then Return True else return False.
Examples
assert all(b == True for b in [True,True,True,True]) == True
assert all(b == True for b in [False,True,True,True]) == False
any() act as "OR": if any one value in any ittertable object is equal to given condition value, then Return True else return False.
Examples
assert any(b == True for b in [False,False,False,True]) == True
assert any(b == True for b in [False,False,False,False]) == False
If you had more variables, this way might be most concise:
{x} == {y, z}
(Not as fast as x == y == z, but the question asked for concise, not for fast.)
I'm new to programming and am having a little trouble understanding the lambda function in Python. I understand why it's used and its effectiveness. Just having trouble learning to apply it. I've read a guide and watched a lecture on using lambda as an argument. I've tried using the map function. Not sure if that's the correct approach, but this is my broken code in its most basic form:
def Coord(x, y, z=lambda: z*2 if z < x or z < y else z)):
print(z)
Coord(10,20,30)
Coord(10,20,12)
Coord(10,20,8)
Needs to return 30, 24, and 32, respectively.
Working code without using lambda:
def Coord(x, y, z):
while z < x or z < y:
z*=2
print(z)
You cannot use other parameters from the Coord function in your default parameter definition for z (which is a lambda function in your case).
You may want to do something like this:
def Coord(x, y, w, z=lambda a,b,c: c*2 if c < a or c < b else c):
print(z(x,y,w))
or
def Coord(x, y, w):
z=lambda: w*2 if w < x or w < y else w
print(z())
Both definitions are equivalent when evaluating them with 3 arguments, and they result in:
>>> Coord(10,20,30)
30
>>> Coord(10,20,12)
24
>>> Coord(10,20,8)
16