I am trying to segregate real and imaginary parts of the output for the following program.
import sympy as sp
a = sp.symbols('a', imaginary=True)
b=sp.symbols('b',real=True)
V=sp.symbols('V',imaginary=True)
a=4*sp.I
b=5
V=a+b
print V
Kindly help. Thanks in advance.
The lines
b=sp.symbols('b',real=True)
V=sp.symbols('V',imaginary=True)
have no effect, because you overwrite the variables b and V in the lines
b=5
V=a+b
It's important to understand the difference between Python variables and SymPy symbols when using SymPy. Whenever you use =, you are assigning a Python variable, which is just a pointer to the number or expression you assign it to. Assigning it again changes the pointer, not the expression. See http://docs.sympy.org/latest/tutorial/intro.html and http://nedbatchelder.com/text/names.html.
To do what you want, use the as_real_imag() method, like
In [1]: expr = 4*I + 5
In [2]: expr.as_real_imag()
Out[2]: (5, 4)
You can also use the re() and im() functions:
In [3]: re(expr)
Out[3]: 5
In [4]: im(expr)
Out[4]: 4
Related
I need to solve an equation, but spider returns me this error:
import sympy as sym
import sympy as sympy
Re=100
Epsilon=0.00000075
D=0.01
f=symbols('f')
eq=(((1/(-2* sympy.log((Epsilon/D/ 3.7)+( 2.51 / (Re*(f**0.5))), 10)))**2 -f),0)
sym.solve((eq), (f))
print(f)
NotImplementedError: could not solve -4*f*log(202702702702703/10000000000000000000 + 251/(10000*sqrt(f)))**2 + log(10)**2
The solve function is for finding analytic solutions but that isn't possible for your equation (not all equations have analytic solutions):
In [11]: eq[0]
Out[11]:
2
log (10)
-f + ──────────────────────────────────────────
2⎛ -0.5 ⎞
4⋅log ⎝0.0251⋅f + 2.02702702702703e-5⎠
You can find a numeric solution with nsolve:
In [12]: sym.nsolve(eq[0], f, 0.1)
Out[12]: 0.169438052045717
https://docs.sympy.org/latest/modules/solvers/solvers.html#sympy.solvers.solvers.nsolve
This can be represented in terms of the LambertW function, but it needs some help. SymPy doesn't recognize the inverted sqrt(f) in the log. If you replace that with 1/y and solve for y and transform the solutions for y back to f you can get a symbolic solution.
It's easier in this case to let SymPy work with symbols instead of Floats and substitute the values later. Your equation looks like this:
>>> from sympy import a,b,c
>>> seq = a**2/log(b/sqrt(f) + c)**2 - f
>>> reps = {a:log(10)/2, c:Epsilon/D/3.7, b:2.51/Re}
Replace that sqrt(f) with 1/y
>>> ysol = solve(seq.xreplace(sqrt(f), 1/y), y)
Calculate the corresponding solutions for f:
>>> fsol = [((1/i)**2) for i in ysol]
Substitute in your values -- or any values that you are interested in:
>>> [i.xreplace(reps).n(3) for i in fsol]
[0.00771 - 0.107*I, 0.169]
Testing in the original shows that the second solution is valid
>>> [eq.subs(f,i).n() for i in _]
[0.148289010493944 + 0.206688429851791*I, 6.05179945288758e-6]
So your symbolic solution is
>>> fsol[1]
(-c/b + LambertW(a*exp(a*c/b)/b)/a)**(-2)
The nice thing about this form is that you can substitute any values of a,b,c and get the corresponding value of f. Whether this is faster than using nsolve, you will have to see.
I have a set of sympy expressions like this (a few hundred of them):
>>> foo = parse_expr('X | Y')
>>> bar = parse_expr('(Z & X) | (Z & Y)')
>>> baz = parse_expt('AAA & BBB') # not needed for this example; just filler
I can simplify one in isolation:
>>> simplify(bar)
Z & (X | Y)
Is there a way to simplify, including the whole set of variables available?
>>> mysimplify(bar, include=(foo,bar,baz))
Z & foo
You can take advantage of Common Subexpresion Elimination. You must use it in combination with simplify by combining all your expressions into a single artificial expression (for example, by passing them as arguments to a fictitious function). I don't think that it will always work as desired, however on a loose analogue of your example it produces the expected result:
In [1]: from sympy import *
In [2]: myexprlist = sympify('listofexpr(x|y, (z&x)|(z&y))')
In [3]: cse(simplify(myexprlist))
Out[3]: ([(x0, Or(x, y))], [listofexpr(x0, And(x0, z))])
The first entry in the result is a list of introduced subexpressions. In this case
the subexpression x|y has been denoted with x0. The second part of the result is the simplified expression (packaged into a list, since the input can be a list of expressions).
I am trying to do symbolical calculations (derivatives mostly) on time-indexed variables using sympy.
Using indexed symbols like r[t] below produces an error:
from sympy import *
t = Idx('t',10)
r = IndexedBase('r')
diff(r[t],r[t])
diff(r,r)
ValueError:
Can't differentiate wrt the variable: r[t], 1
Could the reason be that something went wrong here:
In [15]: r[t].indices
Out[15]: (t,)
The comma after the index t looks suspicious to me, but I have no idea what went wrong.
Does anyone know how to do this in sympy?
You can differentiate wrt symbols, functions and derivatives. Will this work:
>>> t = Idx('t',10)
>>> r=Function('r')
>>> r(t).diff(r(t))
1
>>> var('t')
t
>>> r(t).diff(t)
Derivative(r(t), t)
I am using Python with Sympy.
I need to solve the following equation, finding the 4 roots (omega is my unknown):
deter= 0.6*omega**4*cos(omega*t)**2 - 229.0*omega**2*cos(omega*t)**2 + 5880.0*cos(omega*t)**2
I tried to use solve:
eqcarr=solve(deter,omega,exclude=[t])
I get this output:
[-18.8143990830350, -5.26165884593044, 5.26165884593044, 18.8143990830350, 1.5707963267949/t, 4.71238898038469/t]
I only need the first 4 values, and not the values with the t coefficient. I expect the cos(omega*t)**2 to be simplified in solve, but this doesn't happen.
According to documentation solve will not solve for any of the free symbols passed in the exclude.
'exclude=[] (default)'
don't try to solve for any of the free symbols in exclude;
if expressions are given, the free symbols in them will
be extracted automatically.
It is not meant to filter solution.
You can solve your problem by doing this:
In [10]: from sympy import *
In [11]: from sympy.abc import omega, t
In [12]: deter= 0.6*omega**4*cos(omega*t)**2 - 229.0*omega**2*cos(omega*t)**2 + 5880.0*cos(omega*t)**2
In [13]: eqcarr=solve(deter,omega,exclude=[t])
In [14]: filtered = [i for i in eqcarr if not i.has(t)]
In [15]: filtered
Out[15]: [-18.8143990830350, -5.26165884593044, 5.26165884593044, 18.8143990830350]
I'm interested in a python library that permits symbolic manipulation where the symbols and can be unknowns of an arbitrary type.
This is the code that I want to write:
>>> myexpression = symbol("foo") == "bar"
>>> print myexpression
foo == "bar"
>>> print myexpression(foo="quux")
False
>>> myexpression.or_(True)
True
Or some rough approximation of that. It doesn't actually even need to be that clever, I'd be happy enough having to call a lot of extra introspection methods to get something like the above (for instance, even if the logical tautology is not directly simplified)
My first instinct was to look at sympy, but it seems that library makes the strong assumption that symbolic variables must be numbers; and I'd like to at least operate on sequences and sets:
>>> myexpression = sympy.Eq(sympy.Symbol("foo"), 5)
>>> myexpression
foo == 5
>>> myexpression = sympy.Eq(sympy.Symbol("foo"), "bar")
Traceback (most recent call last):
...
sympy.core.sympify.SympifyError: SympifyError: 'bar'
Is there a way to get sympy to understand non-numeric variables, or another library that can do similar things?
Not sure how well it fits the uses you have in mind, but the nltk (Natural Language Toolkit) has modules for symbolic manipulation, including first order logic, typed lambda calculus, and a theorem prover. Take a look at this howto.
Could you just map everything into a Sympy symbol? For instance, in your last expression:
sympy.Eq(sympy.Symbol("foo"), sympy.Symbol("bar")). Or do you mean you actually want to write logical statements about set relationships?
Boolean logic is in SymPy although not as easily expressible as it should be. Its definitely there though.
In [1]: x,y,z = symbols('x y z')
In [2]: A = Eq(x,y)
In [3]: A
Out[3]: x = y
In [4]: B = Gt(y,z)
In [5]: And(A,B)
Out[5]: x = y ∧ y > z
In [6]: C = Gt(x,z)
In [7]: And(A, Or(B,C))
Out[7]: x = y ∧ (y > z ∨ x > z)
I'm not aware of many methods to simplify these expressions. This is the sort of thing that would be easy to do if there was interest though.