How to quickly generate a large number of constraints with pyomo - pyomo

Actually I want to express a set of constraints like this: A + B + C + D + E <= F,
A,B,C,D,E,F are all l*t matrices.
Unfortunately, I only do constraint construction by using “for” loops,like this:
'''
model.TN = pyo.Set(initialize = TN)
model.LN = pyo.Set(initialize = LN)
model.Pc = pyo.Var(model.GN, model.TN, domain = pyo.NonNegativeReals)
def branch_Cap1(t, l):
return sum(Tc[l, n] * model.Pc[n, t] for n in range(GenCount)) - sum(Tl[l, bus] * ldata[bus , t] for bus in range(loadCount)) <= Fmax[l]
def branch_Cap2(t, l):
return sum(Tc[l, n] * model.Pc[n, t] for n in range(GenCount)) - sum(Tl[l, bus] * ldata[bus , t] for bus in range(loadCount)) >= - Fmax[l]
model.branch_Cap1 = pyo.Constraint(model.TN, model.LN, rule = lambda model, t, l: branch_Cap1(t, l))
model.branch_Cap2 = pyo.Constraint(model.TN, model.LN, rule = lambda model, t, l: branch_Cap2(t, l))
'''
Can somebody help me?
thanks a lot.

Related

SymPy cannot rearrange results while solving a system of equations about Stackelberg game

Function f (assume n=3 for simplicity):
There are 3 symbols related to entities, corresponding to x[j](j=1,2,3) respectively. R and c is other symbols, which can be treated like constant for now. I try to diff f w.r.t x[j], and solve the results equations together and get x[j]=g(R,c). However, sympy cannot rearrange or split x[j] from the equation.
Derivatives:
Expected Results:
from sympy import *
import sympy as sym
real_n = 3
x = IndexedBase('x')
j, k, n = symbols('j,k n', cls=Idx)
f = x[j]*Symbol("R")/Sum(x[k],(k,1,real_n))-Symbol("c")*x[j]
equ = diff(f,x[j])
ee = solve([equ.subs(j,1),equ.subs(j,2),equ.subs(j,3)], (x[1],x[2],x[3]))
simplify(ee)
Sympy's result:
{x[1]: (R*Sum(x[k], (k, 1, 3)) - c*Sum(x[k], (k, 1, 3))**2)/(R*Sum(KroneckerDelta(1, k), (k, 1, 3))),
x[2]: (R*Sum(x[k], (k, 1, 3)) - c*Sum(x[k], (k, 1, 3))**2)/(R*Sum(KroneckerDelta(2, k), (k, 1, 3))),
x[3]: (R*Sum(x[k], (k, 1, 3)) - c*Sum(x[k], (k, 1, 3))**2)/(R*Sum(KroneckerDelta(3, k), (k, 1, 3)))}
I tried to check if the indexed symbol caused the error, and wrote x[i] as 3 different symbols, but it still didn't work.
from sympy import *
a, b, c = symbols('a b c', cls=Idx)
R = symbols("R")
eq1 = diff(a/(a+b+c)-a*R,a)
eq2 = diff(b/(a+b+c)-b*R,b)
eq3 = diff(c/(a+b+c)-c*R,c)
print(eq1,"\n",eq2,"\n",eq3)
solve([eq1,eq2,eq3], [a,b,c])
Output:
-R + 1/(a + b + c) - a/(a + b + c)**2
-R + 1/(a + b + c) - b/(a + b + c)**2
-R + 1/(a + b + c) - c/(a + b + c)**2
[]
Is there something wrong with my approach? Is it possible to approach this problem in SymPy from another angle?
Any suggestions for the solution of equations are also most welcome.
You can use doit to expand the summation and then solve:
In [6]: solve([equ.subs(j,1).doit(),equ.subs(j,2).doit(),equ.subs(j,3).doit()], (x[1],x[2],x[3]))
Out[6]:
⎡⎛ ____ ⎞⎤
⎢⎜ ╱ 2 ⎟⎥
⎢⎜R + 3⋅╲╱ R 2⋅R 2⋅R⎟⎥
⎢⎜─────────────, ───, ───⎟⎥
⎣⎝ 18⋅c 9⋅c 9⋅c⎠⎦

How to generate random math expression trees with sympy?

I am scouring the web but I cannot find how to generate random math expressions with sympy. Is it even possible?
I would like to build an expression tree by randomly selecting functions (product, sum, cosine...) and symbols from a set of predefined functions and symbols.
For instance, given the set [+,.] of sum and product and the symbols [x,y] I'd like to generate expressions such as x+y, (x+y).x, y+(x.x+y)+x etc, controlling parameters as the tree depth, width and the number of nodes.
Any hints?
Something like the following might help you get started:
from random import choice, randint
from sympy import FunctionClass, Add, Mul, cos, sin, binomial, arity, S
def args(n, atoms, funcs):
a = funcs+atoms
g = []
for _ in range(n):
ai = choice(a)
if isinstance(ai, FunctionClass):
g.append(ai(*args(arity(ai), atoms, funcs)))
else:
g.append(ai)
return g
def expr(ops, atoms, funcs=()):
types = [Add, Mul]
atoms = tuple(atoms)
while 1:
e = S.Zero
while e.count_ops() < ops:
_ = choice(types)(*args(randint(1,3), atoms, funcs))
e = choice(types)(e, _)
if e is S.NaN: break
else:
return e
>>> [expr(5, (-1,0,1,x,y)) for do in range(2)]
[(x - 1)*(2*x + y + 2), x + y*(x + 4*y - 2) + y]
>>> expr(5, (-1,0,1,x,y), (cos, binomial))
x*y**2 + x + cos(1)
>>> expr(5, (-1,0,1,x,y), (cos, binomial))
(y + zoo*binomial(y, x) - 2)*(y + cos(1) + 1)
To generate rational expressions you could change make the 2nd _ arg be _**choice((1,-1)).

Sympy strange interpretation of a summation

Let us consider following code
from sympy import *
n = Symbol('n', real=True)
k = Symbol('k', real=True)
f = lambda n: summation(exp(sqrt(k)), (k, 1, n))
display(f(n))
display(f(5))
It results in ( see latex screenshot )
Piecewise((n*exp(c3_), Eq(exp(c2_), 1)), ((exp(c2_) - exp(c2_)**(n + 1))*exp(c3_)/(-exp(c2_) + 1), True))
E + exp(sqrt(2)) + exp(sqrt(3)) + exp(2) + exp(sqrt(5))
Questions
What are the constans c1_, c2_ and c3_?
Why did not the first display return a summation formula?
How did the sympy produce the second output, assumig f is represented as in the first output?

Use List comprehension instead of loop in python

def interval(a,b,n):
dx = float(b-a)/(n+1)
cnt = 1
points = [a]
xj = a
while cnt <= n+1:
xj += dx
points.append(xj)
cnt+=1
return points
Replace your function as given below :-
def interval(a,b,n):
dx = float(b-a)/(n+1)
points = [a]
xj = a
points.extend([xj + (i * dx) for i in xrange(1, n+2)])
return points

Trampolining scalaz' Monad.whileM_ to prevent stack overflow

I'm using scalaz' Monad.whileM_ to implement a while loop in a functional way as follows:
object Main {
import scalaz._
import Scalaz._
import scala.language.higherKinds
case class IState(s: Int)
type IStateT[A] = StateT[Id, IState, A]
type MTransT[S[_], A] = EitherT[S, String, A]
type MTrans[A] = MTransT[IStateT, A]
def eval(k: Int): MTrans[Int] = {
for {
state <- get[IState].liftM[MTransT]
_ <- put(state.copy(s = (state.s + 1) % k)).liftM[MTransT]
} yield (k + 1)
}
def evalCond(): MTrans[Boolean] = {
for {
state <- get[IState].liftM[MTransT]
} yield (state.s != 0)
}
def run() = {
val k = 10
eval(k).whileM_(evalCond()).run(IState(1))
}
}
While this works for small k, it results in a StackOverflow error for large k (e.g. 1000000). Is there a way to trampoline whileM_ or is there a better way to be stack safe?
Use scalaz.Free.Trampoline instead of scalaz.Id.Id.
type IStateT[A] = StateT[Trampoline, IState, A]
The state operations used here return State[S, A] which is just an alias for StateT[Id, S, A]. You need to use the lift[M[_]] function defined on StateT to lift StateT[Id, S, A] to StateT[Trampoline, S, A].
def eval(k: Int): MTrans[Int] = {
for {
state <- get[IState].lift[Trampoline].liftM[MTransT]
_ <- put(state.copy(s = (state.s + 1) % k)).lift[Trampoline].liftM[MTransT]
} yield (k + 1)
}
def evalCond(): MTrans[Boolean] = {
for {
state <- get[IState].lift[Trampoline].liftM[MTransT]
} yield (state.s != 0)
}
Finally, calling .run(IState(1)) now results in Trampoline[(IState, String \/ Unit)]. You must additionally run this as well.
eval(k).whileM_(evalCond()).run(IState(1)).run