How to check basic integer order relations in sympy? - numbers

I have a (possibly relatively large) set of assumptions about multiple integers like {x > -1, x < 5, x != 2, y > 0, x-2 < y} and I would like to check whether certain other propositions like {x > -5, x == 3, ...} either true, false or could be both.
The docs say that explicit relationships like Q.is_true(x < 3) are not supported, so I tried using .positive property, but without any luck, e.g.
# x > -1 => x > -3 - ?
x = sympy.Symbol('x')
with sympy.assuming(sympy.Q.positive(x+1), sympy.Q.integer(x)):
print(sympy.ask(sympy.Q.positive(x+3)))
produces
None
Which means that the checker gave up on checking that.
Refine also does not seem to help much (probably uses assumptions anyway)
sympy.refine(x > 0, sympy.Q.is_true(x > -1))
If there's a different library that can check that, that also works!

I have found that python bindings for the z3 solver best fitted for my problem. One can just download the binary release from the github page and add included folder into $PYTHONPATH , e.g.
LD_LIBRARY_PATH=${Z3FOLDER}/bin PYTHONPATH=${Z3FOLDER}/bin/python python
then these relations could be checked as
from z3 import *
x = Int('x')
s = Solver()
s.add(x > 10)
s.add(x > 12)
print(s) // [x > 10, x > 12]
print(s.check()) // sat
print(s.model()) // [x = 13]

Related

How to solve error 'Callbacks disabled in gurobi'?

Currently I am investigating an MILP in Pyomo with gurobi. I would like to be able to add cuts during the B&B and found that callback functions can be used for this purpose. However, when I try to implement a callback function I get the following error: "callbacks disabled for solver gurobi" (or: callbacks disabled for gurobi_persistent). This error does not seem very common, does someone have any experience with it?
I am quite new to both Pyomo and gurobi.
My code is the following (an example that I found through the Pyomo documentation).
from gurobipy import GRB
import pyomo.environ as pe
#from pyomo.core.expr.taylor_series import taylor_series_expansion
m = pe.ConcreteModel()
m.x = pe.Var(bounds=(0, 4))
m.y = pe.Var(within=pe.Integers, bounds=(0, None))
m.obj = pe.Objective(expr=2*m.x + m.y)
m.cons = pe.ConstraintList() # for the cutting planes
def _add_cut(xval):
# a function to generate the cut
m.x.value = xval
return m.cons.add(m.y >= ((m.x - 2)**2))
_add_cut(0) # start with 2 cuts at the bounds of x
_add_cut(4) # this is an arbitrary choice
opt = pe.SolverFactory('gurobi_persistent')
opt.set_instance(m)
#opt.set_gurobi_param('PreCrush', 1)
#opt.set_gurobi_param('LazyConstraints', 1)
def my_callback(cb_m, cb_opt, cb_where):
if cb_where == GRB.Callback.MIPSOL:
cb_opt.cbGetSolution(vars=[m.x, m.y])
if m.y.value < (m.x.value - 2)**2 - 1e-6:
cb_opt.cbLazy(_add_cut(m.x.value))
opt.set_callback(my_callback)
opt.solve()
assert abs(m.x.value - 1) <= 1e-6
assert abs(m.y.value - 1) <= 1e-6
Thanks.

How can I sum up functions that are made of elements of the imported dataset?

See the code and error. I have already tried Do, For,...and it is not working.
CODE + Error from Mathematica:
Import of survival probabilities _{k}p_x and _{k}p_y (calculated in excel)
px = Import["C:\Users\Eva\Desktop\kpx.xlsx"];
px = Flatten[Take[px, All], 1];
NOTE: The probability _{k}p_x can be found on the position px[[k+2, x -16]
i = 0.04;
v = 1/(1 + i);
JointLifeIndep[x_, y_, n_] = Sum[v^k*px[[k + 2, x - 16]]*py[[k + 2, y - 16]], {k , 0, n - 1}]
Part::pkspec1: The expression 2+k cannot be used as a part specification.
Part::pkspec1: The expression 2+k cannot be used as a part specification.
Part::pkspec1: The expression 2+k cannot be used as a part specification.
General::stop: Further output of Part::pkspec1 will be suppressed during this calculation.
Part of dataset (left corner of the dataset):
k\x 18 19 20
0 1 1 1
1 0.999478086278185 0.999363078716059 0.99927911905056
2 0.998841497412202 0.998642656911039 0.99858030519133
3 0.998121451605207 0.99794428814123 0.99788275311401
4 0.997423447323642 0.997247180349674 0.997174407432264
5 0.996726703362208 0.996539285828369 0.996437857252448
6 0.996019178300768 0.995803204773039 0.99563600297737
7 0.995283481416241 0.995001861216016 0.994823584922968
8 0.994482556091416 0.994189960607964 0.99405569519175
9 0.993671079225432 0.99342255996206 0.993339856748282
10 0.992904079096455 0.992707177451333 0.992611817294026
11 0.992189069953677 0.9919796017009 0.991832027835091
Without having the exact same data files to work with it is often easy for each of us to make mistakes that the other cannot reproduce or understand.
From your snapshot of your data set I used Export in Mathematica to try to reproduce your .xlsx file. Then I tried the following
px = Import["kpx.xlsx"];
px = Flatten[Take[px, All], 1];
py = px; (* fake some py data *)
i = 0.04;
v = 1/(1 + i);
JointLifeIndep[x_, y_, n_] := Sum[v^k*px[[k+2,x-16]]*py[[k+2,y-16]], {k,0,n-1}];
JointLifeIndep[17, 17, 12]
and it displays 362.402
Notice I used := instead of = in my definition of JointLifeIndep. := and = do different things in Mathematica. = will immediately evaluate the right hand side of that definition. This is possibly the reason that you are getting the error that you do.
You should also be careful with your subscript values and make sure that every subscript is between 1 and the number of rows (or columns) in your matrix.
So see if you can try this example with an Excel sheet containing only the snapshot of data that you showed and see if you get the same result that I do.
Hopefully that will be enough for you to make progress.

Merging two sorted lists, one with additional 0s

Consider the following problem:
We are given two arrays A and B such that A and B are sorted
except A has B.length additional 0s appended to its end. For instance, A and B could be the following:
A = [2, 4, 6, 7, 0, 0, 0]
B = [1, 7, 9]
Our goal is to create one sorted list by inserting each entry of B
into A in place. For instance, running the algorithm on the above
example would leave
A = [1, 2, 4, 6, 7, 7, 9]
Is there a clever way to do this in better than O(n^2) time? The only way I could think of is to insert each element of B into A by scanning linearly and performing the appropriate number of shifts, but this leads to the O(n^2) solution.
Some pseudo-code (sorta C-ish), assuming array indexing is 0-based:
pA = A + len(A) - 1;
pC = pA; // last element in A
while (! *pA) --pA; // find the last non-zero entry in A
pB = B + len(B) - 1;
while (pA >= A) && (pB >= B)
if *pA > *pB
*pC = *pA; --pA;
else
*pC = *pB; --pB;
--pC
while (pB >= B) // still some bits in B to copy over
*pC = *pB; --pB; --pC;
Not really tested, and just written off the top of my head, but it should give you the idea... May not have the termination and boundary conditions exactly right.
You can do it in O(n).
Work from the end, moving the largest element towards the end of A. This way you avoid a lot of trouble to do with where to keep the elements while iterating. This is pretty easy to implement:
int indexA = A.Length - B.Length - 1;
int indexB = B.Length - 1;
int insertAt = A.Length;
while (indexA > 0 || indexB > 0)
{
insertAt--;
A[insertAt] = max(B[indexB], A[indexA]);
if (A[indexA] <= B[indexB])
indexB--;
else
indexA--;
}

Error attempting to use initial conditions

I'm doing a quick problem in Maple with a differential equation and a few initial conditions, but I'm getting an error message that I can't seem to understand given the context. Can anyone quickly elaborate on what's going on here? How do I fix this issue?
> KVLl2 := -4*(i2(t)-2)-12*(i2(t)-i3(t)) = 0;
-16 i2(t) + 8 + 12 i3(t) = 0
> KVLl3 := -12*(i3(t)-i2(t))-4*i3(t)-3.5*(diff(i3(t), t)) = 0;
/ d \
-16 i3(t) + 12 i2(t) - 3.5 |--- i3(t)| = 0
\ dt /
> mySoln := dsolve({KVLl2, KVLl3, i2(0) = 1, i3(0) = 1}, i2, i3);
Error, (in dsolve) found the following equations not depending
on the unknowns of the input system: {1 = 1}
Thanks in advance
Maple doesn't know what to do with i2 and i3 you provided as target functions. If you look at the help of dsolve (?dsolve), you see that it requires its target functions to be specified in terms of their variables (t in this case) and as a list. Try using this
dsolve({KVLl2, KVLl3, i2(0) = 1, i3(0) = 1}, {i2(t), i3(t)});
No errors here but no solution either (this might be related to your equation)

Calculations with Real Numbers, Verilog HDL

I noticed that Verilog rounds my real number results into integer results. For example when I look at simulator, it shows the result of 17/2 as 9. What should I do? Is there anyway to define something like a: output real reg [11:0] output_value ? Or is it something that has to be done by simulator settings?
Simulation only (no synthesis). Example:
x defined as a signed input and output_value defined as output reg.
output_value = ((x >>> 1) + x) + 5;
If x=+1 then output value has to be: 13/2=6.5.
However when I simulate I see output_value = 6.
Code would help, but I suspect your not dividing reals at all. 17 and 2 are integers, and so a simple statement like that will do integer division.
17 / 2 = 8 (not 9, always rounds towards 0)
17.0 / 2.0 = 8.5
In your second case
output_value = ((x >>> 1) + x) + 5
If x is 1, x >>> 1 is 0, not 0.5 because you've just gone off the bottom of the word.
output_value = ((1 >>> 1) + 1) + 5 = 0 + 1 + 5 = 6
There's nothing special about verilog here. This is true for the majority of languages.