How do you write Ranged Inequality Constraint in Pyomo - python

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.

Related

Solve equations with multiple variables (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

Solving algebra equations in python

I'm new to programming and I'm having a hard time solving this equation using Python.
I would like for the system to give me the value for X.
((X-5)/(2) + (X/4) + (X-12)/(3))
Sympy looks promising, especially section 3.2.4, "Equation Solving".
Assuming your right hand side of equation is some given value or expression:
import sympy as sym
x = sym.Symbol("x")
RHS = 13
LHS = (x - 5)/2 + x/4 + (x - 12)/3
eqn = LHS - RHS
soln = sym.solve(eqn, x)
print(soln)
This yields the solution x = 18. Replace RHS with your own value or expression. If there is nothing, simply put RHS to be 0; which gives the solution x = 6.
If you want to solve your equation step by step, you are still going to need SymPy:
https://docs.sympy.org/latest/install.html

How do I implement summation and array iteration correctly based on Pseudo code. PYTHON Relaxation Method

I am trying to implement relaxation iterative solver for a project. The function we create should intake two inputs: Matrix A, and Vector B, and should return iterative vectors X that Approximate solution Ax = b.
Pseudo Code from the book is here:
enter image description here
I am new to Python so I am struggling quite a bit with implementing this method. Here is my code:
def SOR_1(A,b):
k=1
n = len(A)
xo = np.zeros_like(b)
x = np.zeros_like(b)
omega = 1.25
while (k <= N):
for i in range(n-1):
x[i] = (1.0-omega)*xo[i] + (1.0/A[i][i])[omega(-np.sum(A[i][j]*x[j]))
-np.sum(A[i][j]*xo[j] + b[i])]
if ( np.linalg.norm(x - xo) < 1e-9):
print (x)
k = k + 1.0
for i in range(n-1):
xo[i] = x[i]
return x
My question is how do I implement the for loop and generating the arrays correctly based off of the Pseudo Code.
Welcome to Python!
Variables in Python are case sensitive so n is defined but N is not defined. If they are supposed to be different variables, I don't see what your value is for N.
You are off to a good start but the following line is still psuedocode for the most part:
x[i] = (1.0-omega)*xo[i] + (1.0/A[i][i])[omega(-np.sum(A[i][j]*x[j]))
-np.sum(A[i][j]*xo[j] + b[i])]
In the textbook's pseudocode square brackets are being used as a grouping symbol but in Python, they are reserved for creating and accessing lists (which is what python calls arrays). Also, there is no implicit multiplication in Python so you have to write things like (1 + 2)*(3*(4+5)) rather than (1 + 2)[3(4+5)]
The other major issue is that you don't define j. You probably need a for loop that would either look like:
for j in range(1, i):
or if you want to do it inline
sum(A[i][j]*x[j] for j in range(1, i))
Note that range has two arguments, where to start and what value to stop before so range(1, i) is equivalent to the summation from 1 to i - 1
I think you are struggling with that line because there's far too much going on in that line. See if you can figure out parts of it using separate variables or offload some of the work to separate functions.
something like: x[i] =a + b * c * d() - e() but give a,b c, d and e meaningful names. You'd then have to correctly set each variable and define each function but at least you are trying to solve separate problems rather than one huge complex one.
Also, make sure you have your tabs correct. k = k + 1.0 should not be inside that for loop, just inside the while loop.
Coding is an iterative process. First get the while loop working. Don't try to do anything in it (except print out the variable so you can see that it is working). Next get the for loop working inside the while loop (again, just printing the variables). Next get (1.0-omega)*xo[i] working. Along the way, you'll discover and solve issues such as (1.0-omega)*xo[i] will evaluate to 0 because xo is a NumPy list initiated with all zeros.
You'd start with something like:
k = 1
N = 3
n = 3
xo = [1, 2, 3]
while (k <= N):
for i in range(n):
print(k, i)
omega = 1.25
print((1.0-omega)*xo[i])
k += 1
And slowly work more and more of the relaxation solver in until you have everything working.

Define a matrix depending on variable in Mathematica

I am translating my code from Python to Mathematica. I am trying to define a matrix, whose values depend on a variable chosen by the user, called kappa.
In Python the code looked like that:
def getA(kappa):
matrix = zeros((n, n), float)
for i in range(n):
for j in range(n):
matrix[i][j] = 2*math.cos((2*math.pi/n)*(abs(j-i))*kappa)
n = 5
return matrix
What I have done so far in Mathematica is the following piece of code:
n = 5
getA[kappa_] :=
A = Table[0.0, {n}, {n}];
For[i = 0, i < n, i++,
For[ j = 0, j < n, j++,
A[[i, j]] = 2*Cos[(2*pi/n)*(abs (j - i))*kappa]]];
b = getA[3]
But when I try to evaluate this matrix for a value of kappa equal to 3, I get the following error:
Set::partd: "Part specification A[[i,j]] is longer than depth of object.
How can I fix it?
Try something like this
n = 5;
A = Table[2*Cos[(2 \[Pi]/n) (Abs[ j - i]) \[Kappa]], {i, 1, n}, {j, 1, n}];
b = A /. \[Kappa]->3
I'll leave you to package this into a function if you want to.
You write that you are trying to translate Python into Mathematica; your use of For loops suggests that you are trying to translate to C-in-Mathematica. The first rule of Mathematica club is don't use loops.
Besides that you've made a number of small syntactical errors, such as using abs() where you should have had Abs[] (Mathematica's built-in functions all have names beginning with a capital letter, they wrap their arguments in [ and ], not ( and )), pi is not the name of the value of the ratio of a circle's diameter to its radius (it's called \[Pi]). Note too that I've omitted the multiplication operator which is often not required.
In your particular case, this would be the fastest and the most straightforward solution:
getA[κ_, n_] := ToeplitzMatrix[2 Cos[2 π κ Range[0, n - 1] / n]]

Low Autocorrelation Binary Sequence problem? Python troubleshooting

I'm trying to model this problem (for details on it, http://www.mpi-hd.mpg.de/personalhomes/bauke/LABS/index.php)
I've seen that the proven minimum for a sequence of 10 digits is 13. However, my application seems to be getting 12 quite frequently. This implies some kind of error in my program. Is there an obvious error in the way I've modeled those summations in this code?
def evaluate(self):
self.fitness = 10000000000 #horrible practice, I know..
h = 0
for g in range(1, len(self.chromosome) - 1):
c = self.evaluateHelper(g)
h += c**2
self.fitness = h
def evaluateHelper(self, g):
"""
Helper for evaluate function. The c sub g function.
"""
totalSum = 0
for i in range(len(self.chromosome) - g - 1):
product = self.chromosome[i] * self.chromosome[(i + g) % (len(self.chromosome))]
totalSum += product
return totalSum
I can't spot any obvious bug offhand, but you're making things really complicated, so maybe a bug's lurking and hiding somewhere. What about
def evaluateHelper(self, g):
return sum(a*b for a, b in zip(self.chromosome, self.chomosome[g:]))
this should return the same values you're computing in that subtle loop (where I think the % len... part is provably redundant). Similarly, the evaluate method seems ripe for a similar 1-liner. But, anyway...
There's a potential off-by-one issue: the formulas in the article you point to are summing for g from 1 to N-1 included -- you're using range(1, len(...)-1), whereby N-1 is excluded. Could that be the root of the problem you observe?
Your bug was here:
for i in range(len(self.chromosome) - g - 1):
The maximum value for i will be len(self.chromosome) - g - 2, because range is exclusive. Thus, you don't consider the last pair. It's basically the same as your other bug, just in a different place.

Categories