Export cubic equation formulas to code in Python - python

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

Related

How to solve equations in python

I try to write a script that simulates a resistor. It takes 2 arguments for example P and R and it should calculate all missing values of this resistor.
The problem is that I don't want to write every single possible equation for every value. This means I want to write something like (U=RxI, R=U/R, I=U/R , P=UxI) and the script should then complete all equation with the given values for every equation.
For example, something like this:
in R=10
in I=5
out U=R*I
out P=I**2 * R
You can use https://pypi.org/project/Equation/ Packages.
Example
>>> from Equation import Expression
>>> fn = Expression("sin(x+y^2)",["y","x"])
>>> fn
sin((x + (y ^ (2+0j))))
>>> print fn
\sin\left(\left(x + y^{(2+0j)}\right)\right)
>>> fn(3,4)
(0.42016703682664092+0j)
Sympy
Second: https://github.com/sympy/sympy/wiki
Arbitrary precision integers, rationals and floats, as well as symbolic expressions
Simplification (e.g. ( abb + 2bab ) → (3ab^2)), expansion (e.g. ((a+b)^2) → (a^2 + 2ab + b^2)), and other methods of rewriting expressions
Functions (exp, log, sin, ...)
Complex numbers (like exp(Ix).expand(complex=True) → cos(x)+Isin(x))
Taylor (Laurent) series and limits
Differentiation and integration
In vanilla python, there is no solution as general as the one you are looking for.
The typical solution would be to write an algorithm for every option (only given U, only given R) and then logically select which option to execute.
You may also want to consider using a module like SymPy, which has a solver module that may be more up your alley.

Can Sympy identify functions in expressions, if fuctions are defined?

I've seen that Sympy has a sympy.Function feature, but can't find an answer to the following in the documentation.
Is it possible to find custom functions in expressions and use the function definition to simplify them.
As a very simple example, I define the function: f(x) = 2 * exp(x).
Now let's say I have some Sympy expression: 6 * exp(y + z)
Is it possible to tell Sympy to simplify this expression to give a result in terms of the function f.... i.e. so the output from Sympy is: 3 * f(x).
I've found that using .subs() works for simple substitution of variables, but this doesn't seem to work for functions that contain symbols as arguments, as above.
Thanks.
I think what you want to do is not supported by Sympy at the moment (see for instance this stackoverflow question). Nevertheless, something very close can be done with this code:
from sympy import symbols, exp
x, f = symbols('x, f')
expr = 6 * exp(x)
f_func = 2 * exp(x)
print(expr.subs({f_func: f}))
# 3 * f
In the above code I have assumed that the expression you wanted to simplify (expr in the code) was a function of x.

Rounding coefficients of a symbolic expression in SymPy

I'm currently trying to calculate a negative group delay of analog filters by using symbolic calculations in Python. The problem that I'm currently trying to resolve is to get rid of some very small imaginary coefficients.
For example, consider fraction with such numerator (imaginary parts are bolded):
(-1.705768*w^18 + 14.702976409432*w^16 + 1.06581410364015e-14*I*w^15 - 28.7694094371724*w^14 - 9.94759830064144e-14*I*w^13 + 59.0191623753299*w^12 + 5.6843418860808e-14*I*w^11 + 24.7015297857594*w^10 - 1.13686837721616e-13*I*w^9 - 549.093511217598*w^8 - 5.6843418860808e-14*I*w^7 + 1345.40434657845*w^6 + 2.27373675443232e-13*I*w^5 - 1594.14046181284*w^4 - 1.13686837721616e-13*I*w^3 + 980.58940367608*w^2 - 254.8428594382)
Is there any way to automatically round those small coefficients, so they would be equal 0 (in general any negligligible values)? Or at least, can I somehow filter imaginary values out? I've tried to use re(given_fraction), but it couldn't return anything. Also standard rounding function can't cope with symbolic expressions.
The rounding part was already addressed in Printing the output rounded to 3 decimals in SymPy so I won't repeat my answer there, focusing instead of dropping imaginary parts of coefficients.
Method 1
You can simply do re(expr) where expr is your expression. But for this to work, w must be known to be a real variable; otherwise there is no way for SymPy to tell what the real part of (3+4*I)*w is. (SymPy symbols are assumed to be complex unless stated otherwise.) This will do the job:
w = symbols('w', real=True)
expr = # your formula
expr = re(expr)
Method 2
If for some reason you can't do the above... another, somewhat intrusive, way to drop the imaginary part of everything is to replace I with 0:
expr = expr.xreplace({I: 0})
This assumes the expression is already in the expanded form (as shown), so there is no (3+4*I)**2, for example; otherwise the result would be wrong.
Method 3
A more robust approach than 2, but specialized to polynomials:
expr = Poly([re(c) for c in Poly(expr, w).all_coeffs()], w).as_expr()
Here the expression is first turned into a polynomial in w (which is possible in your example, since it has a polynomial form). Then the real part of each coefficient is taken, and a polynomial is rebuilt from them. The final part as_expr() returns it back to expression form, if desired.
Either way, the output for your expression:
-1.705768*w**18 + 14.702976409432*w**16 - 28.7694094371724*w**14 + 59.0191623753299*w**12 + 24.7015297857594*w**10 - 549.093511217598*w**8 + 1345.40434657845*w**6 - 1594.14046181284*w**4 + 980.58940367608*w**2 - 254.8428594382

Python-How to do Algebraic Math with Exponents and Square Roots

so I am having issues trying to do basic math in Python. I can do basic math, but when I add in exponents, square roots, etc, I have errors with the IDE. How do I do this?
Here are a few of my problems that I am having issues with:
(n(n-1))/2)
(4)* pi * r ** 2=
(r(cos(a)**2) + r(sin(b))**2)**(.5)
((y**2) - (y**1))/((x**2) - (x**1))=
(n*(n-1))/2 should work if you have already given n a numeric value (e.g. n=2 or something). Your original expression has unbalanced parentheses (three closing parens and only two opening parens) and it is missing the multiplication sign (*) which is necessary in python, otherwise n(n-1) would be interpreted as the function n supplied with the input n-1, in which case you get a message like "TypeError: 'int' object is not callable", assuming you had previously defined n=2 or the like. It's telling you that the integer n cannot be called like a function, which is how it interprets n().
To get pi (3.14159...) in python, you should import the math package and then use math.pi like this:
import math
r = 2
x = 4*math.pi*r**2
You don't need parentheses around the 4. Parentheses are used for grouping, when you need operations to be done in a different order than the standard order of operations. You don't need the trailing equal sign (that's a syntax error).
In the third expression you are using implicit multiplication notation which is fine for pencil and paper but in python you need to use * every time you multiply. Also, you need to import the math package and then use math.sin and math.cos.
import math
a = 90
b = 45
x = (r*(math.cos(a)**2) + r*(math.sin(b))**2)**(.5)
There doesn't appear to be anything wrong with the last expression except the trailing = sign which should be removed. Store the result of this expression in a variable if you want to keep it for future use:
z = ((y**2) - (y**1))/((x**2) - (x**1))
If you just type the expression at the command line it will print the result immediately:
x = 3
y = 2
((y**2) - (y**1))/((x**2) - (x**1))
but if you are using this expression in a script you want to save the result in a variable so you can use it later or print it out or something:
z = ((y**2) - (y**1))/((x**2) - (x**1))
As was previously pointed out in the comments, x**1 is the same, mathematically, as x so it's not clear why you would want to write it this way, but it's not wrong.
You can use math.pow() or the simpler ** syntax:
There are two ways to complete basic maths equations in python either:
use the ** syntax. e.g:
>>> 2 ** 4
16
>>> 3 ** 3
27
or use math.pow(). e.g:
>>> import math
>>> math.pow(5, 2)
25.0
>>> math.pow(36, 0.5)
6.0
As you can see, with both of these functions you can use any real power so negative for inverse or decimals for roots.
In general, for these types of equations, you want to look into the math module. It has lost of useful functions and defined constants that you may find useful. In particular for your specific problems: math.pi and these trig. functions.
I hope these examples and the links I made are useful for you :)

Awkward Substitution in Sympy

Is there a simpler way to do substitution in Sympy which is similar to Sage or Mathematica.
In Mathematica You have something called as eliminate() which given a set of equations you can ask it to eliminate certain variables.
In Sage you need to be more hands on with it but its still more or less similar to Mathematica.
In Sympy comparatively its more awkward to do substitution.
In the screenshot the red arrows show what i am talking about. The white Arrow is the method i think would be more appropriate.
edit 1: here is a link to the function in mathematica http://reference.wolfram.com/mathematica/ref/Eliminate.html
You can have equations (actually Equality object) in SymPy:
>>> eq1=Eq(x,y);eq2=Eq(x,5)
But you are right, subs doesn't guess everything for you. It looks like Sage assumes that if a variable is isolated on one side of an equation, that is the variable to be replaced. But there is no guarantee that you will always conveniently have the desired variable isolated. It's not hard to use solve to give you the desired variable isolated:
>>> solve(eq2,x,dict=1)
[{x:5}]
And then that can be substituted into the equation from which you want to eliminate that variable.
>>> eq1.subs(solve(eq2,x,dict=1)[0])
5=y
Use of the "exclude" keyword doesn't presently behave quite as I would expect; perhaps it should act in an elimination sense:
>>> solve((eq1,eq2), exclude=(x,))
{y:x}
Following up on the above comments and https://github.com/sympy/sympy/issues/14741, one way to do the above in Sympy would be:
from sympy import Eq, var
var('P, F, K, M, E0, E1, E2, E3, E4')
a = Eq(E1, (E0 + P - F)*K - M)
b = Eq(E2, (E1 + P - F)*K - M)
c = Eq(E3, (E2 + P - F)*K - M)
d = Eq(E4, (E3 + P - F)*K - M - F)
d.subs(*c.args).subs(*b.args).subs(*a.args)

Categories