Suppose I have the following matrix expression:
import sympy
sympy.init_printing(use_unicode=True)
x = sympy.MatrixSymbol('x', 2, 2)
y = sympy.MatrixSymbol('y', 2, 2)
a = x * y
I would like to substitute the second matrix with the same matrix times negative one:
a.subs(y, (-y))
If x and y were regular SymPy symbols, this would show as -xy. But in this case it shows as x - y. Even though upon substitution of matrix values it evaluates correctly (i.e. as -xy), this demonstration quickly becomes ambiguous. How do I make it display correctly?
When sympy.init_printing() is not called, it displays unambiguously as x\*(-y).
I use this in Jupyter.
This is a bug in SymPy's LaTeX printer: it does not consider that MatMul(Integer(-1), MatrixSymbol(...)) needs parentheses in a product.
Until the bug is fixed, a workaround is to use "pretty" printing instead of LaTeX:
sympy.init_printing(use_latex=False)
resulting in x⋅(-y). Pretty-print is generally more readable than str output like x*(-y).
The big is fixed in the current master branch and therefore should not appear in SymPy versions above 1.3.
Related
I have two equalities and an inequality relationship between them. I would like to simplify those to a single inequality (I do not need to solve the unknowns). Here is my code:
from sympy.abc import x,y
from sympy import reduce_inequalities
eq1 = np.multiply(array_1[0], (1-delta))+delta*Q[0]*[x,y]
eq2 = np.multiply(array_1[1], (1-delta)) + delta*Q[1]*[x,y]
print(reduce_inequalities(eq1, eq2))
array_1 is a 1x4 array I defined previously, and I only need one element (I choose the elements by slicing the array). Q is a 4x2 array I defined previously. The unknowns are x and y. The output I get is True.
Is there any way to simplify this with sympy or any other python library in such a way I could use the simplified version later on?
Edit: I forgot to mention delta is also defined previously.
In my quest to learn Python for mathematics course, I have stumbled upon a rather unique problem. I'm looking to concatenate the output of an integration (an equation) along with a string say "Fx(x)" and using the print command to concatenate them results in the integration output been converted into string.
Link for the image to describe the issue - Desired Concatenation
The output of the integration is 1/x+1 and I would like it to be displayed normally as it would be in a textbook and not in the string format.
Following is my code
from sympy import integrate, symbols, exp, oo
from IPython.display import display, Markdown
x, y = symbols('x,y', positive=True)
integral = integrate(exp(-y*(x+1)), (y, 0, oo))
display(Markdown(r'$f_X(x) =$'))
integral
The current output of this code shows both in different lines, while the output I'm looking for it Fx(X) = 1/x+1, as it would be displayed in a textbook.
print("Fx(X)=", integral)
o/p
Fx(X) = 1/(x + 1)
First I want to point out that I'm a total sympy noob.
I'm trying to create a Custom Formula-based Measurement class with this sympy expression:
from sympy import Symbol, S, floor, sympify, Float
SU = Symbol('millimeter')
exp = S(20.0) + floor((((SU-S(212.5)) / S(10.0))) / S(0.5)) * S(0.5)
The problem I face is that for the same SU I get different result based on the way the expression is evaluated. Here is what I mean:
>>> exp.subs(SU, 215)
20.0000000000000
>>> exp.evalf(subs={SU: 215})
0.e+1 #This is actually 16.0 when: float(exp.evalf(subs={SU: 215}))
More interestingly the problem exists only when SU is between [213:217] (when I expect the result to be 20.0)
For the rest of the values its fine (AFAIK)
>>> exp.subs(SU, 212)
19.5000000000000
>>> exp.evalf(subs={SU: 212})
19.50
>>> exp.subs(SU, 218)
20.5000000000000
>>> exp.evalf(subs={SU: 218})
20.50
Any Ideas for this strange behavior ?
This was due to incorrect precision values. The bug was reported and is already corrected in the current version of SymPy available on GitHub; the versions of SymPy > 1.1.1 will not have this bug.
Using srepr on the output of subs provides some explanation:
x = Symbol('x')
srepr((floor(x)+20).evalf(subs={x:0.5}))
The output is Float('16.0', precision=1). This is binary precision. SymPy thinks that the output of floor, when it happens to be zero, has only one bit of precision. So it subsequently truncates the added +20 accordingly, to nearest power of 2.
Of course, this is a bug. There are several open issues related to Float class and rounding, such as this one; they may be related.
The workaround is to avoid evalf(subs=dict) construction (is it even documented?). Using the methods in the natural order: substitute, then evaluate, gives correct results:
srepr((floor(x)+20).subs({x:0.5}).evalf())
"Float('20.0', precision=53)"
When I type
import sympy as sp
x = sp.Symbol('x')
sp.simplify(sp.log(sp.exp(x)))
I obtain
log(e^x)
Instead of x. I know that "there are no guarantees" on this function.
Question. Is there some specific simplification (through series expansion or whatsoever) to convert logarithm of exponent into identity function?
You have to set x to real type and your code will work:
import sympy as sp
x = sp.Symbol('x', real=True)
print(sp.simplify(sp.log(sp.exp(x))))
Output: x.
For complex x result of this formula is not always is equal to x. Example is here.
If you want to force the simplification, expand can help because it offers the force keyword which basically makes certain assumptions like this for you without you having to declare your variables as real. But be careful with the result -- you will not want to use it when those assumptions are not warranted.
>>> log(exp(x)).expand(force=True)
x
You can also set the argument "inverse" to "True" in the simplify function:
>>> simplify(log(exp(x)), inverse=True)
x
So I am starting with an equality of an equation and a fraction that I use to solve for both x and y:
mrs = y/x
ratio = 2/5
x = sympy.solveset(sympy.Eq(mrs, ratio), x)
y = sympy.solveset(sympy.Eq(mrs, ratio), y)
In the end, solving for y returns:
{2*x/5}
Which is a FiniteSet
But solving for x returns:
{5*y/2} \ {0}
Which is a Complement
I don't get why solving for one variable gives me a FiniteSet when solving for the other doesn't do the same? Also, would there be a way to solve for the other variable so as to get a FiniteSet instead of a Complement?
What do you expect as a result? Could you solve this problem by hand and write the expected solution? And why would you want a FiniteSet as solution?
I myself can not come up with a better notation than sympy, since x=0 needs to be excluded.
When you continue working with the solutions sympy can easily work with both, FiniteSet and Complement. Mathematically those are not completely different structures. The difference is that sympy somehow needs to represent these solutions internally and can not use the same construction for everything, but rather uses small building blocks to create the solution. The result you get with type(x) is symply the last building block used.
EDIT: Some math here: x=0 does not solve the equation y/x=2/5 for any y. So this must be excluded from the solutionset.
If you solve for y, then x=0 is already excluded since y/0 is not well defined.
If you solve for y, then y=0 is a priori possible, since 0/x=0 for x!=0. Thus sympy needs to exclude x=0 manually, which it does by removing 0 from the set of solutions.
Now, since we know that x=0 can never be a solution of the equation we can exclude it before even trying to solve the equation. Therefore we do
x = sympy.symbols('x', real=True, nonzero=True)
right at the beginning of the example (before the definition of mrs). The rest can remain unchanged.