Sympy strange interpretation of a summation - sympy

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?

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)).

SML: syntax error: replacing LET with RAISE

I'm writing a function, that takes date in (d, m, y) format. I need to count rez value, all of these +getNthInt function calls are adding certain elements from the list.
fun firstNewMoonInt ((d, m, y) : int * int * int) : int option =
let
if m = 1 orelse m = 2 then y - 1
else y
val rez = newStyleCorrection (d, m, y) * 100000
+ getNthInt(thousandCorrection, y div 1000)
+ getNthInt (hundredCorrection, y div 100 mod 10)
+ getNthInt (decadeCorrection, y mod 100 div 10)
+ getNthInt (yearCorrection, y mod 1000)
+ getNthInt (monthCorrection, m - 1)
+ getNthInt (calendarCorrection, y mod 4)
rez - lastSmaller(rez - 100000, reductions)
in
if rez div 100000 <= 30 then SOME rez
else NONE
end
I'm getting two syntax errors:
2.3-2.6 Error: syntax error: replacing LET with RAISE
13.3 Error: syntax error: inserting LET
Since I use all keywords for the constructions: let-in-end, if-then-else. I don't understand, what is wrong with my code?
Immediately inside a let, there should be a sequence of declarations. (Declarations are things like val x = ... or fun f x = ...). But in your code, there is an if which begins an expression.
You could fix this by making a new variable which is the result of the if expression:
let
val new_y =
if m = 1 orelse m = 2 then y - 1
else y
val rez = ...
And then you will need to figure out where to use new_y in the rest of the code.
Note that there is a similar problem just a few lines further down:
rez - lastSmaller(rez - 100000, reductions)
This is an expression where there should be another declaration. You could also fix it the same way: val new_rez = rez - lastSmaller (...) and then use new_rez where appropriate below that.

Sympy doing subs multiple times

I am using isympy and have the expression:
expr = x + 2 * y
And I want to substitute x with the values in [0, 1, 2, 3]. Currently I am doing:
Eq(Symbol('X_0'), expr.subs(x, 0))
Eq(Symbol('X_1'), expr.subs(x, 1))
Eq(Symbol('X_2'), expr.subs(x, 2))
Eq(Symbol('X_3'), expr.subs(x, 3))
Output:
X₀ = 2⋅y
X₁ = 2⋅y + 1
X₂ = 2⋅y + 2
X₃ = 2⋅y + 3
Is there are a better way to do this? I would like Xₖ to be a function which can take a list of k values.
Use a list comprehension to return a list given a list input:
In [1]: expr=x+2*y
In [2]: [expr.subs(x,i) for i in range(4)]
Out[2]: [2⋅y, 2⋅y + 1, 2⋅y + 2, 2⋅y + 3]
This can of course be cast as a function.

Sympy substitution of x[i]*x[j] with x[i,j]

I have an indexed symbol x in Sympy and an expression which is a sum of second degree monomials like x[1]*x[2] + x[3]**2 + x[4]*x[1]. I would like to turn such an expression into x[1,2] + x[3,3] + x[4,1], i.e. replacing x[i]*x[j] -> x[i,j]
There is an upper bound on the indices which may appear, so I could construct a large table hard coding each substitution. Is there a better way?
Responding to the comment - to create x I write
from sympy.tensor import IndexedBase
x = IndexedBase('x')
You can use ordered to put the indices in order:
>>> from sympy import *
>>> i, j = symbols('i j', cls=Wild)
>>> x = IndexedBase('x')
>>> e = x[1]*x[3] + x[2]*x[1] + x[3]**2
>>> def new(o, x):
... if o.is_Mul:
... i,j=list(ordered([i.args[1] for i in o.args]))
... elif o.is_Pow:
... i = j = o.base.args[1]
... else:
... raise NotImplementedError
... return x[i, j]
...
>>> e.xreplace(dict([(o, new(o, x)) for o in e.find(x[i]*x[j])]))
x[1, 2] + x[1, 3] + x[3, 3]
But a simpler way to do the same thing is to use a Piecewise result in the replace call:
>>> e.replace(x[i]*x[j], Piecewise((x[i,j],i<j),(x[j,i],True)))
x[1, 2] + x[1, 3] + x[3, 3]
You can use replace with a Wild.
In [1]: i, j = symbols('i j', cls=Wild)
In [2]: x = IndexedBase('x')
In [3]: e = x[1]*x[3] + x[2]*x[1]
In [4]: e.replace(x[i]*x[j], x[i, j])
Out[4]: x[1, 2] + x[1, 3]