I have a list of symbols in sympy:
x,y,z = symbols(["x","y","z"])
_symbols = [x,y,z]
I need to use these symbols in some algorithmically generated expressions, and these expressions must not be evaluated because I'm using them as excercises.
Is there a method to prevent evaluation by defining these symbols as UnevaluatedExpr? I was thinking as something as
map(UnevaluatedExpr, _symbols)
but this does not affect the output, as x+x gives anyway 2x.
Also something along the lines of
for symbol in _symbols:
symbol = UnevaluatedExpr(symbol)
does not work.
EDIT: I noticed that there is a somewhat weird behavior of UnevaluatedExpr (at least for me), namely
UnevaluatedExpr(x)**0
gives 1. I would have expected simply x**0 as output, since x could be 0 and in that case it's not true that the result is 1.
Creating your expressions in an evaluate(False) context might be what you want:
>>> with evaluate(False):
... x + x
...
x + x
Related
I have a function that computes a large expression based on Sympy symbols passed as arguments. A very simplified version for readability is:
def expr(a):
return (1+a)/a
This generally works but if the passed argument is the infinity symbol then this becomes a NaN, whereas I'd prefer the result to be somehow evaluated as a limit and return 1 (in this simplified case).
Since in my actual code there are many arguments which could be infinite and the expression is quite large, I'd rather avoid an if-else sequence covering every possible combination of infinite-valued arguments.
I've tried using unevaluated expressions but that doesn't seem to work either. Is there a good workaround for this?
You could write the expression as a limit:
from sympy import oo, limit
from sympy.abc import a, x
def expr(a):
return limit((1 + x) / x, x, a)
print(expr(oo)) # 1
Python's abstraction is often seen as magic by many. Coming from a C background, I know very well there is no such thing as magic, only cold hard code made up of simple components that produces abstraction.
So, when a textbook and my teacher say that we can "store conditions" or use "named conditions" for readability, and say that assigning a boolean expression to a variable suddenly makes it a dynamic condition akin to a macro, I lose it.
EDIT 1 : They don't explicitly say its like a macro (direct quotes are placed within quotes) since we aren't expected to know any other language beforehand.
The way they say that " the variable stores the condition unevaluated ", is like saying it is a macro , and this is my opinion. They imply it to be practically the equivalent of a macro by their articulation, just without saying the word 'macro'.
Here's the claim in code form :
x,y = 1,2
less = x < y
more = x > y
'''
less/ more claimed to store not boolean True/False but some magical way of storing the
expression itself (unevaluated, say like a macro) and apparently
'no value is being stored to less and more'.
'''
It is being represented as though one was doing :
// C-style
#define less (x < y)
#define more (x > y)
Of course, this is not true, because all less and more store in the so-called 'named conditions' is just the return value of the operator between x and y .
This is obvious since < , >, == , <= , >= all have boolean return values as per the formal man pages and the spec, and less or more are only storing the True or False boolean return value , which we may prove by calling print() on them and/or by calling type() on them.
Also, changing the values of x and y , say by doing x,y = y,x does not change the values of less or more because they store not a dynamic expression but the static return value of the > or < operand on the initial x and y values.
The question isn't that this claim is a misunderstanding of the purported abstraction ( its not actually an abstraction, similar storage can be achieved in asm or C too) , but rather how to clearly and efficiently articulate to my teacher that it is not working like a C macro but rather storing the boolean return value of >or < statically.
Obviously less = x < y just looks at the current values of x and y and stores either True or False into the variable less.
If I understand where you and your teacher disagree, you two have a different idea of what the following code will print out:
x, y = 1, 2
less = x < y
print(less)
x, y = 2, 1
print(less)
"Macro's" could be implemented as text strings that can be evaluated, like (bad example - not the recommended solution):
less = "({0}) < ({1})"
and use them like:
x = 1
y = 3
outcome = eval(less.format("x", "y"))
But this is really a silly thing to do, and eval() is susceptible for security issues.
Perhaps your teacher meant to use lambda expressions, which are nameless, ad-hoc functions:
less = lambda a, b: a < b
x = 1
y = 3
outcome = less(x, y)
Note:
There is already a function for lambda a, b: a < b available in the standard library operator module: operator.lt.
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.
I have to solve a equation in python, which i get as a string input. I don't know how many symbols are in the equation or what their signature is. A typical Symbol could be "mm", "cm", "x" or something like this. The function should return some kind of array/json with the solved equation.
Little Example how it should look like:
solve("x/2=4")
>> ["x=8"]
>>
solve("x + 2 = y - 1")
>> ["x=y-3", "y=x+3"]
I tried to use SymPy-Module for this, but I didn't find a way to enter a dynamic string like above. SymPy seems to only accept "hardcoded" Symbols.
Note: String comes from a "sys.argv"-Parameter.
SymPy can parse strings with sympify, but its format for equations is Eq(x/2, 4) instead of x/2 = 4. So a little preprocessing is necessary: surround the string with Eq( ) and replace "=" by a comma.
eq = "x/2=4"
sympy_eq = sympify("Eq(" + eq.replace("=", ",") + ")")
solve(sympy_eq) # [8]
and
eq = "x + 2 = y - 1"
sympy_eq = sympify("Eq(" + eq.replace("=", ",") + ")")
solve(sympy_eq) # [{x: y - 3}]
In the latter case, SymPy picked one of the variables to solve for. To choose which one it should be, you can provide a Symbol:
solve(sympy_eq, Symbol('y')) # [x + 3]
Or, to solve for every symbol:
[solve(sympy_eq, sym, dict=True) for sym in sympy_eq.free_symbols]
returns [[{y: x + 3}], [{x: y - 3}]]. The list is nested because multiple solutions could appear for each symbol. Flatten the nested list if necessary.
The options list=True and dict=True of solve are convenient for enforcing particular forms of output.
The answer is most probably two different parts.
Parsing:
Parsing means turning some input into a usable output, where in your case the input is some string and the output is something, sympy can work with. A simple parsing step for example is turning strings into integers by doing int(your_string). In your case, you should iterate through your string and find variables, units etc. for example by comparing with a dictionary or a list of strings. Parsing arbitrary input is quite hard, so the best idea is starting with a small set of options, e.g. search the string for occurences of typical variable names like x, y and z by comparing with a list variables=['x','y','z'].
Computing
Once the parsing is clean, simply plug everything into your number crunching / solvers used by sympy.
To see how such a system can work if done correctly, you can have a look at wolfram alpha. They do a quite good parsing / natural language processing and try to guess what to do from there.
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