Looking at the Sympy documentation, there seems to be an "expand" function which can be called upon to expand polynomial expressions; however, in practice, this is not working for me. I started off using imaginary numbers:
import sympy
sympy.expand((x - 1)(x + i)(x - i))
Hoping for "x^3 - x^2 + x - 1", however, instead, this returned the following error: module 'sympy' has no attribute 'expand'
I then changed the expression I wanted to be expanded, as this had caused me to assume that Sympy could not handle complex numbers, to what can be seen below:
import sympy
sympy.expand((x - 1)(x - 1)(x + 1))
Yet this returned the same error.
The imaginary i is represented by the capital I in sympy. To have a multiplication, an * needs to be used explicitly. Also, in Python ^ is strictly reserved for a boolean (or bitwise) exclusive or. Power is represented as **.
from sympy import symbols, I, expand
x = symbols('x')
print(expand((x - 1)*(x + I)*(x - I)))
Output: x**3 - x**2 + x - 1
Note that an alternative way to call expand() is as expression.expand() (or ((x - 1)*(x + I)*(x - I)).expand() as in the example). Often this is a handy way to concatenate several operations.
I don't have problem to run
import sympy
x = sympy.Symbol('x')
i = sympy.Symbol('i')
sympy.expand( (x - 1)*(x + i)*(x - i) )
and this gives me
-i**2*x + i**2 + x**3 - x**2
The only idea: you created file with name sympy.py and now import sympy loads your file instead of module sympy and it can't find expand in your file. You have to rename your file sympy.py to something different (which is not name of other module).
But you didn't add full error message in question so I can't confirm it.
Related
subs (from sympy library in Python) does not replace a subexpression in all cases except simple ones. MATLAB copes with this task perfectly. Is it possible to somehow achieve the same result as in MATLAB?
Sympy
MATLAB
This fails because the product 2*(x + y) automatically expands to the sum of 2x + 2*y, as #hpaulj points out. And #oscarbenjamin points out that re-arranging your substitution so it targets only an atomic part of the expression you desire to replace will work.
In addition, if you backsubstitute to restore the original atom you will see if the substitution was not able to be fully done while retaining the original variables:
>>> f = (x + y)**2 + 1/(4*x + 4*y + sin(2*x + 2*y))
>>> (f+x).subs(x,z-y).subs(y,z-x)
x + z**2 + 1/(4*z + sin(2*z))
I'm writing code for the method to solve this cubic equation. I use python's math library.
(float)(-b+pow(pow(b,3)-27*pow(a,2)*d,1/3))/3*a;
(float)((math.sqrt(delta))/(3*a))*((pow(abs(k)+math.sqrt(pow(k,2)+1),1/3))+(pow(abs(k)-math.sqrt(pow(k,2)+1),1/3)))-(b/(3*a));
Below are pictures of 2 math formulas I need to solve:
A few comments to begin with:
/3*a at the end of your first line does not do what you think it does. Use parentheses!! Parentheses are important. Write / (3 * a) instead.
It's mostly a matter of style, but personally I think A**B is easier to read than pow(A, B) (they are equivalent, as you can see in the documentation).
Note that your code will require b, a, d, Delta and k to be already-existing variables with already-given values. One way to get around that is to encapsulate your code into a function, with these four variables as arguments of the function. Another way to get around that is to use the symbolic expression library sympy.
With these comments in mind, here are two ways to rewrite your first expression and use it in python code. I will let you adapt the second expression yourself.
First way: encapsulating in a function with arguments
def expr1(a,b,d):
numerator = - b + (b**3 - 27*a*a*d)**(1/3)
denominator = 3 * a
return numerator / denominator
print(expr1(2,7,3))
# -0.7219330585463425
Second way: using sympy
Sympy is a library for symbolic calculus. This means we can use it to define symbols, which are basically variables without a value, and then ask it to remember expressions that use these symbols. We are going to use the function sympy.symbols to define our symbols, and expr.subs to evaluate an expression expr by giving values to those symbols. I encourage you to read sympy's documentation.
import sympy
a, b, d = sympy.symbols('a b d')
numerator = - b + (b**3 - 27*a*a*d) ** (1/3)
denominator = 3 * a
expr1 = numerator / denominator
print(expr1)
# (-b + (-27*a**2*d + b**3)**0.333333333333333)/(3*a)
print(expr1.subs([(a,2), (b,7), (d,3)]))
# -0.721933058546343
I am having some trouble writing this equation in Python and having it produce correct results:
y = 2.95710^-7 * x^4 – 2.34310^-5 * x^3 – 1.67*10^-4 * x^2 + 0.04938 * x – 1.083.
I have tried the following code:
y = 0.0000002957*x**4 - 0.00002343*x**3 - 0.000167*x**2 + 0.04938*x - 1.083
and also:
y = (2.957*10**-7)*x**4 - (2.343*10**-5)x**3 - (1.67*10**4)*x**2 + 0.04938*x - 1.083
any advice would be helpful, I think the problem might be the scientific notation or the exponents and the way I am inputting them
EDIT
in response to questions, the equation spits out an incorrect number than what I get on a calculator
What you have can easily be converted to Python in a very direct way. The equivalent Python statement (after fixing a flaw in the original equation...see below) is :
y = 2.95710e-7 * x**4 - 2.34310e-5 * x**3 - 1.67e-4 * x**2 + 0.04938 * x - 1.083
This involves only the simple substitution of the ^ characters, where you replace that character with e in the exponential floating point constants and with ** for raising x to an integer power.
For reference to be able to more easily compare the source with the result, here's the original equation with the one slight fix mentioned below:
y = 2.95710^-7 * x^4 – 2.34310^-5 * x^3 – 1.67^-4 * x^2 + 0.04938 * x – 1.083
UPDATE: Thanks to Pranav for pointing out a flaw in the source equation. The term 1.67*10^-4 should be changed to 1.67^-4 to match the other similar terms, and the equivalent fix made to the resulting Python equation. Those fixes were made and commented on above.
I always like to see what I'm working with in situations like this. I used matplotlib to plot this function, using an unchanged version (except for the function and the bounds on x) of this sample code. Here's what I got for x values between -500 and 500:
Thanks for answering everybody. The most helpful answer was using "e" instead of scientific notation (*10^x).
I'm not sure how to get Sympy to perform / simplify these types of identities?
It does things like sin(a + b), but doesn't seem to do others (like the one in the title)
One approach is to try various combinations of simplification functions/methods such as rewrite and simplify. For example, the following gives the result you want:
import sympy as sp
x = sp.var('x', real = True)
f = sp.tan(x/2)
sp.re(f.rewrite(sp.exp).simplify().rewrite(sp.sin)).simplify()
sin(x)/(cos(x) + 1)
When I do symbolic integration using Sympy, I would like to expand an expression along a specific symbol so that later I can collect and integrate w.r.t. that symbol. Is there a way to do such "expand" without altering the forms of other (irrelevant) symbols?
For example, consider this Python code and run results:
>>> from sympy import *
>>> var('x,a,b,c')
(x, a, b, c)
>>> f = (a + 1) * a + x * (b + exp(-c*x))
>>> collect(f, (exp(-c*x), x))
a*(a + 1) + x*(b + exp(-c*x))
>>> collect(expand(f), (exp(-c*x), x))
a**2 + a + b*x + x*exp(-c*x)
The outputs are all expected. Without "expand" first, "collect" just gives me back the original form. If we use "expand" first, I get what I want. Imagine if we have a sum of many above 'f' and symbols b and c are complex expressions, the integration will take a long time if we use the original form of f. Indeed, I have an integration taking seconds to complete if "expand" is applied first, but could not be finished after nearly one hour of run.
The problem of "expand" is that it can be expensive to "fully expand" the expression. In the above example, we see a*(a+1) was also expanded (and took computing time).
I have expressions (to be integrated later), each expanded to about 40 thousand terms. The result of expansion, as function of x, is similar to the form in the above example -- I knew it must be of that form. The most time (if it would ever finish) was spent on expanding those terms having nothing to do with 'x'. Can I avoid those unnecessary expansions?
You could try masking off the non-x-containing terms like this:
>>> def ex(e,x):
... m = [i for i in e.atoms(Mul) if not i.has(x)]
... reps = dict(zip(m,[Dummy() for i in m]))
... return expand(e.xreplace(reps)).subs([(v,k) for k,v in reps.items()])
...
>>> f = (a + 1) * a + x * (b + exp(-c*x))
>>> ex(f,x)
a*(a + 1) + b*x + x*exp(-c*x)
Notice that only the x-containing term was expanded.
Also, instead of using expand, you might only want to use expand_mul; expand does several types of expansion (see docstring).