Reduce symbolic expressions with MatrixSymbol (reduce +- to -) - sympy

I am using SymPy to write mathematical proofs which are automatically included in a Latex document. Unfortunately in some cases sympy returns equations with a '+-' instead of - and adds an additional 1 in front of some symbolic variables.
Minimal Example: (tested on Python 3.6.0 and Sympy 1.1)
from sympy import *
n = Symbol('n')
p = Symbol('p')
q = Symbol('q')
Ci = MatrixSymbol('Ci', q,n)
Li = MatrixSymbol('Li', p,n)
Sl = MatrixSymbol('Sl', p, n)
Tl = MatrixSymbol('Tl', p, q)
Xi31 = (Li-Tl*Ci-Sl)
Xi31
which returns
−1Sl+−1TlCi+L
Question: How Do I get
−Sl−TlCi+L
simplify() and block_collapse() do not have any effect.

Related

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

python sympy lambdify not working inside function

I'm trying to write a function that has a literal function as a parameter:
def derive(x, y):
x = symbols(x)
y = symbols(y)
return lambdify(x, y)
derive(5, 'x**2')
This returns a syntax error:
File "<lambdifygenerated-32>", line 1
def _lambdifygenerated(25.0):
^
SyntaxError: invalid syntax
If I write (outside the function scope):
f = lambdify(x, x**2)
f(5)
it works.
I appreciate any help on this.
In sympy you can get the derivative of a function via diff(). .subs(x, 5) fills in the value 5 for x. An example:
from sympy.abc import x
f = x**2
print(f.diff(x).subs(x,5))
Here is how a function that would calculate the derivative of a given function at a given value could look like. evalf() can be used to iron out symbolic parts (such as giving a numeric approximation for 2*pi or Sqrt(5) which sympy standard wants to keep in their exact symbolic form).
def derive_and_evaluate(x, f, xval):
return f.diff(x).subs(x, xval).evalf()
derive_and_evaluate(x, x**2, 5)
If you need the same derivative for a lot of x-values, you can do:
from sympy import lambdify
g = lambdify(x, f.diff(x)) # now `g` is a numpy function with one parameter
Or, if you want a function that does the derivation and converts to numpy form:
def derive_and_lambdify(x, f):
return lambdify(x, f.diff(x))
g = derive_and_lambdify(x, x**2)
print(g(5))
From then on, you can use g similar to other numpy functions. Here is a more elaborate example:
from sympy import lambdify, sin
from sympy.abc import x
f = sin(1 / (1 + x ** 2))
g = lambdify(x, f.diff(x))
import numpy as np
from matplotlib import pyplot as plt
xs = np.linspace(-5, 5, 100)
ys = g(xs)
plt.plot(xs, ys)
plt.show()

Sympy .replace() doesn't detect product

I'm trying to make some replacements, but .replace() is confusingly missing occurrences:
from sympy import *
x, y = symbols('x y')
f = Function('f')
expr = x*f(x)*f(y)
expr.replace(x*f(x), 1)
# Output: x*f(x)*f(y)
# Expected: f(y)
Is this a bug?
It does work when I use .subs() instead of .replace(), but I have no idea why this would be needed.
(also, I wanna use this in the context of a Sum expression where .subs() would not work).

Using `replace` to put terms under a common denominator with sympy

I'm trying to get a subexpression of a larger expression under a common denominator. However, when I use replace() for this, it applies to sums of functions, even though there's no ratio.
>>> x = Function('x')(t)
>>> f = Function('f')(t)
>>> g = Function('g')(t)
>>> a,b = Wild('a'), Wild('b')
>>> f + g
f(t) + g(t)
>>> (f + g).replace(a/x+b/x, (a+b)/x)
f(t)⋅x(t) + g(t)⋅x(t)
─────────────────────
x(t)
How do I get this to apply only where the original source expression has an explicit / x(t) in both terms?
Note: if either f & g, or x, are Symbols, rather than UndefinedFunctions, no replacement happens, which is what I want.

How to rewrite an abstract derivative of a sum as a sum of derivatives in sympy?

I want to convert (L + L')' into L' + L'' using sympy and some sort of expanding or simplifying function.
import sympy
sympy.init_printing() # math as latex
z, L = sympy.symbols('z,L')
expr = sympy.Derivative(L + sympy.Derivative(L,z), z)
expr
I tried standard functions like expand, which rewrites the expression (even with a flag force=True), or doit which returns zero.
Question. Is there a way to apply sp.Derivative to sum of two functions and expand it to sum of sp.Derivative's?
If we work with derivatives, it is better to use sympy.Function instead of sympy.Symbol. In order to expand the derivative, one can use .doit() method.
Example.
import sympy
sympy.init_printing() # math as latex
z = sympy.Symbol('z')
f = sympy.Function("f")(z)
expr = sympy.Derivative(sympy.Derivative(f) + f)
expr
expr.doit()