Solve equations with multiple variables (Python) - python

I have an equation, say x = .5 (b + c) - d. I would like to solve this equation for all of the variables. For example, d = … or b =. This would mean that the variables are equal to other variables.
Another example is this simple equation: x = b/c. C is equal to b/x and b = c * x (please correct my math if it’s wrong). Is this possible?
Thanks

Related

Finding a maximum solution to system of inequalities with Z3Py

I have a solver in Z3Py to which I've added a number of constraints. Each constraint is an inequality involving variables and/or real numbers. Here's what the first few entries in the solver might look like:
[a + b >= 1.5,
a <= 1.5 + b,
b <= 1.5 + a,
2.27 + c >= 1.41, ... ]
What I would like to do is, given this solver, return a single solution [a = ..., b = ..., c = ..., ...] with a,b,c real numbers with the property that any other solution has a smaller value for one of the variables. Since there may be multiple such "maximum" solutions, I just want the first one found. I'm not that familiar with Z3, so I don't know how to return multiple solutions / a range of solutions for a system of inequalities, how to compare them, etc. How can I do this?
This sort of optimization is known as finding the Pareto front. The elements of the Pareto front have the property that to find another optimal solution for one objective, you have to make some other objective a bit "worse."
Z3 has direct support for this support of optimization. See Section 8.1 of https://theory.stanford.edu/~nikolaj/programmingz3.html
Based on this, here's how you can code your example in z3:
from z3 import *
a, b, c = Reals('a b c')
opt = Optimize()
opt.set(priority='pareto')
opt.add(a + b >= 1.5)
opt.add(a <= 1.5 + b)
opt.add(b <= 1.5 + a)
opt.add(2.27 + c >= 1.41)
ma = opt.maximize(a)
mb = opt.maximize(b)
mc = opt.maximize(c)
while opt.check() == sat:
print ("a =", ma.value(), "b =", mb.value(), "c =", mc.value())
Alas, the optimizer is not very good at handling this program. I ran it for a few minutes but it did not produce any results. Adding extra constraints to further reduce the space might help it converge faster.

How do you write Ranged Inequality Constraint in Pyomo

I'm new to Pyomo and I need help writing this equation in Pyomo.
I'm trying to write a (ranged inequality) constraint equation in Pyomo.
Here is the equation:
So far I wrote these 2 versions:
Version 1: Not sure if this correct
model.amount_of_energy_con = pe.ConstraintList()
for t in model.time:
lhs = 0
rhs = sum(model.c_ratings[s] * model.boat_capacity * model.charging[b, t, s] * model.boats_availability[b][t] for b in model.boats for s in model.chargers)
body = sum(model.charge_energy[b, t, s] for b in model.boats for s in model.chargers)
model.amount_of_energy_con.add(lhs <= body)
model.amount_of_energy_con.add(body <= rhs)
Version 2: I think this is not correct
model.amount_of_energy_con = pe.ConstraintList()
for t in model.time:
lhs = 0
rhs = sum(model.c_ratings[s] * model.boat_capacity * model.charging[b, t, s] * model.boats_availability[b][t] for b in model.boats for s in model.chargers)
body = sum(model.charge_energy[b, t, s] for b in model.boats for s in model.chargers)
#model.amount_of_energy_con.add(expr=pe.inequality(lhs, body, rhs))
model.amount_of_energy_con.add(lhs, body, rhs)
Note:
All the subscripts in the equation are elements of 3 different sets. s Elements of Set S (model.chargers), b Elements of Set B (model.boats), t Elements of Set T (model.time).
C-rate, Availability, Battery capacity are given parameters while E and Charging are Variables in Pyomo.
Please, let me know what you think and how to write it in Pyomo. Generally if there is something you think I'm doing wrong, please me know and also if you need my full code, data and further explanation let me know as well.
Thank you so much for your help
This solution works for me:
model.amount_of_energy_con = pe.ConstraintList()
for t in model.time:
for b in model.boats:
for s in model.chargers:
lhs = model.charge_energy[b, t, s]
rhs = model.c_rating[s] * model.boat_battery_capacity * boats_availability[b, t] * model.charging[b, t, s]
model.amount_of_energy_con.add(expr= (lhs <= rhs))
The problem with those previous versions I posted above in the question are:
The sum() function/ method will do sum of the variables and parameters which is not what I want because the equation doesn't have summation. The 2 versions above will work if we are trying to do summation of the variables on the right and left hand side separately.
The 0 in the range inequalities/ left hand side was covered using the "within parameter" when writing the charge_energy variable as follows model.charge_energy = pe.Var(model.boats, model.time, model.chargers, within=pe.NonNegativeReals).
Thank you.

pulp program for the the following constraint min(a,b) > min(x,y)

Suppose for a moment that I have 4 variables a,b,x,y
and one constraint min(a,b) > min(x,y).
how can I represent this program in pulp python?
Ok. So, the first answer I posted (deleted) was a bit hasty and the logic was faulty for the relationship described. This is (hopefully) correct! ;)
max() and min() are nonlinear, so we need to linearize them somehow (with helper variable) and some logic to relate the 2 minima, which (below) can use a binary helper variable and a Big-M constraint.
in pseudocode:
a, b, x, y : real-valued variables
ab_min : real-valued variable
x_lt_y : binary variable, 1 implies x <= y, 0 else
M = some suitably large constant, depending on the max range of a, b, x, y
new constraints:
ab_min <= a
ab_min <= b
ab_min >= x - (1 - x_lt_y) * M
ab_min >= y - (x_lt_y) * M
Logic:
We find the minimum of a, b with ab_min.
We need "upward pressure" from the min(x, y)... So we know that
ab_min must be greater than either x or y, or possibly both. For the "or"
constraint, we use the binary logic above and multiply it by the
"large constant" to make the other constraint trivial.
I would reformulate this as:
z <= x
z <= y
z >= x - Mδ
z >= y - M(1-δ)
a >= z + 0.00001
b >= z + 0.00001
δ ∈ {0,1}
One extra binary variable δ is needed, and one continuous variable z. M is a large enough constant to be chosen with care.

Eigenvalues of symmetric 2 by 2 matrix in terms of variables \

So given a symmetric matrix like of the form:
[[a,c]
[c,b]]
One can get the eigenvalues with a general expression provided by the following function:
def get_eigenvals(a,b,c):
e1 = 0.5*(a + b + ((a-b)**2 + 4*c**2)**(1/2))
e2 = 0.5*(a + b - ((a-b)**2 + 4*c**2)**(1/2))
return(e1,e2)
But if I input a,b and c that contain variables, how could I get the eigenvalues in terms of the same variables? For example if I set a = 5D, D being the variable, how can I then have my eigenvalues returned as expressions containing D?
This is easy to implement in a program like Mathematica, but I'm wondering if there's a way of doing it in Python.

Shorthand code and Fibonnaci Sequence [duplicate]

This question already has answers here:
Multiple assignment and evaluation order in Python
(11 answers)
Closed 7 years ago.
I have found example for Fibonacci sequence that goes like this:
def fib(n):
a, b = 0, 1
while b < n:
print (b)
a, b = b, a+b
fib(20)
So here's what I don't get it:
a, b = 0, 1 # is just a shortcut for writing
a = 0
b = 1
right?
Now, following the same logic
a, b = b, a+b #should be the same as writing
a = b
b = a+b
But it isn't because if I write it like that, the output is different.
I'm having some hard time understanding why. Any thoughts?
Yes It isn't exactly the same , because when you write -
a, b = b, a+b
The value of a and b at the time of executing the statement is considered, lets say before this statement, a=1 , b=2 , then first right hand side is calculated , so b=2 is calculated and a+b=3 is calculated. Then the assignment occurs, that is a is assigned value 2 and b is assigned value 3.
But when you write -
a = b
b = a+b
The assignment occurs along with calculation, that is first b=2 is calculated, then assigned to a , so a becomes 2 , then a+b is calculated (with the changed value of a) , so a+b=4 and it is assigned to b , so b becomes 4 , and hence the difference.
a,b = b, a
This is a shorthand for swapping values of a and b , please note that if you want to swap the values without using this notation, you would need a temporary variable.
Internally how it works is that the right hand sid is made into a tuple, and then the values are unpacked, a simple test to see this is -
>>> a = 5
>>> b = 10
>>> t = a, b
>>> t
(5, 10)
>>> b, a = t
a, b = c, d is not shorthand for the following:
a = c
b = d
It's actually shorthand for this:
a, b = (c, d)
I.e., you're creating a tuple (c, d), a tuple with the values of c and d, which is then unpacked into the target list a, b. The tuple with its values is created before the values are unpacked into the target list. It actually is one atomic* operation, not a shorthand for several operations. So it does not matter whether one of the variables in the target list also occurs on the right hand side of the assignment operation.
* Not "atomic" in the sense of database ACID, but still not separate statements.
It is not the same thing.
x, y = y, x
equals to:
t = x
x = y
y = t
It actually uses a temporary variable to swap x and y.
So back to a, b = b, a+b. This expression equals to:
m = a; n = b
a = n
b = m + n

Categories