I am making a math program that allows the user to input an equation and the program will solve it. I am trying to make it as user friendly as possible. I want the user to be able to easily type an equation in without having to worry about adding the multiplication symbol between every instance of multiplication.
Here is an example:
User input: y=xy+yz Program output: y=x*y+y*z
I have been able to accomplish this easily using Python's re module as follows:
equation = "y=xy+yz"
equation = re.sub(r"([xyzuvet])([xyzuvet])",r"\1*\2", equation) # x,y,z,u,v,e, and t and variables and constants the user can use in their equation.
equation = re.sub(r"([xyzuvet])([xyzuvet])",r"\1*\2", equation) # Must run twice in the event the equation looks something like y=xyzxyz
However I run into a problem when I introduce a special function such as y=yexp(x). When I run the code above, I will get an output of y=y*e*xp(x).
I later updated my code to account for pi:
equation = re.sub(r"([xyzuve]|pi)([xyzuve]|pi)",r"\1*\2", equation)
equation = re.sub(r"([xyzuve]|pi)([xyzuve]|pi)",r"\1*\2", equation)
I was thinking I could use a similar approach from above to match exp and prevent it from adding a * between the 'e' and 'x' as follows:
equation = re.sub(r"([xyzuve]|pi|exp)([xyzuve]|pi|exp)",r"\1*\2", equation)
equation = re.sub(r"([xyzuve]|pi|exp)([xyzuve]|pi|exp)",r"\1*\2", equation)
I thougt by adding exp in the same way I did pi, it would work; but unfortunately it doesn't work. Is there a way to treat exp and other functions that also contain x,y,z,u,v,t, and e as a whole?
Here are some examples of what I want an input to look like:
In: y=eexp(xyz) out: y=e*exp(x*y*z)
In: y=pifrexp(yt) out: y=pi*frexp(y*t)
In: y=sin(x)exp(y) out:y=sin(x)*exp(y)
This seems to produce what you want:
equation = re.sub(r"([)xyzuvet]|pi|exp|frexp)([xyzuvet]|pi|exp|frexp)\b",r"\1*\2", equation)
equation = re.sub(r"([)xyzuvet]|pi|exp|frexp)([xyzuvet]|pi|exp|frexp)\b",r"\1*\2", equation)
For example:
>>> import re
>>> eqns = ('y=eexp(xyz)', 'y=pifrexp(yt)', 'y=sin(x)exp(y)')
>>> for equation in eqns:
... equation = re.sub(r"([)xyzuvet]|pi|exp|frexp)([xyzuvet]|pi|exp|frexp)\b",r"\1*\2", equation)
... equation = re.sub(r"([)xyzuvet]|pi|exp|frexp)([xyzuvet]|pi|exp|frexp)\b",r"\1*\2", equation)
... print equation
...
y=e*exp(x*y*z)
y=pi*frexp(y*t)
y=sin(x)*exp(y)
You can use look arounds to as
(?<=[xyzuvtf])(?=[xyzuvtf])|(?=exp)|(?<=pi)
Regex Demo
This regex based on lookarounds works for all your test cases:
(?!^)(?=(?<!fr)(?:fr)?exp|sin|pi|(?<=[xtyzuv]|e(?!xp))[etxyzuv])
RegEx Demo
Related
I am attempting to solve for a variable (T_p) in terms of another (T_i) using sympy. However all that is returned after running is empty square brackets i.e [].
My current code is as follows:
from sympy import *
T_i, T_p = symbols('T_i T_p')
eq = Eq(1.32*(T_i - T_p)**1.25 + 58.5*T_i, 3774)
sol = (solve(eq, T_p))
print(sol)
I am unsure what is wrong as it has worked for other equations. Any help would be appreciated.
Could it be that the solve function doesn't like fractional powers? If so, is there a similar function that does?
Last Day I have been bothering with this problem. At first I made a question but after comment of needing a simplified example, I deleted the question and I finally found the "source" of the problem.
I fail to evaluate expressions AFTER substituting Functions by expressions: Following example will show you what I mean:
xx = sy.Symbol('x',real=True)
yy = sy.Symbol('y',real=True)
FuncT = sy.Function('F')
TestExp= sy.cos(sy.diff(FuncT(xx,yy),xx)+xx+yy*xx+yy)
print(TestExp.subs({FuncT(xx,yy):xx})).subs({xx:1,yy:0.1})
which results
How can it replace dx/dx = 1 ?
Just doit:
>>> TestExp.subs({FuncT(xx,yy):xx}).subs({xx:1,yy:0.1}).doit()
-0.588501117255346
How to know to use doit?
When I print (not pprint) the expressions I see
cos(Subs(Derivative(x, x), x, 1) + 1.2)
I don't want Subs there but I don't know much about Subs so I
ask for help and read the following:
>>> help(Subs)
...
There's no automatic expansion - use the method .doit() to effect all
possible substitutions of the object and also of objects inside the
expression.
...
I have some SymPy expressions of the form: 2*x1**2+7*cos(8*x2)+2*Pi (mine are longer and more complicated, but this should be enough for my question). How can I turn all the numbers appearing in this expression into parameters, something like this: a*x1**2+b*cos(c*x2)+d. Basically, I have a program which is able to give me an approximate function able to fit some data, but the parameters are integers or some well known numbers, such as pi or e (this is the first expression I provided). Then, I want to take that expression and fine tune these numbers (using gradient descent), such that to obtain the actual parameters (one can assume that the functional form is right, just the parameters need to be adjusted). For example, in the end, the right equation could be: 2.87*x1**2+6.95*cos(8.05*x2)+6.27. Is there a way to do this? Thank you!
It's a little tricky because you say "all numbers" but you are ignoring exponents. In your example you are only replacing numerical factors in a term with new symbols. To do that (and to get you on your way with a possible solution) try using replace, telling it you are looking for a Mul and then telling it what you want to do with the Mul when you have it:
from sympy import *
from sympy.abc import x,y
eq=2*x**2+7*cos(8*y)+2*pi
def nfact2dum(m):
assert m.is_Mul
nonnum = sift(m.args, lambda i:i.is_number, binary=True)[1]
return Mul(*([Dummy()] + nonnum))
deq = eq.replace(
lambda x:x.is_Mul,
lambda x: nfact2dum(x))
print(
deq.subs(list(zip(deq.atoms(Dummy),numbered_symbols('c')))))
output: c0*x**2 + c2*cos(c1*y) + c3
I want to use sympy for electronic design calculations. I have a equation, which I solve for certain resistor values. I can only use standard resistor values, so I set the choosen value again in the equation, and get a final result.
'''Example calculations for LMZ22010 switching regulator'''
from IPython import get_ipython
get_ipython().magic('reset -sf')
from sympy.solvers import solve
from sympy import Symbol, Eq, symbols, var
syms = ['Rent, Renb, Vuvlo']
var(','.join(syms))
Eq_uvlo = Eq(Rent/Renb, (Vuvlo/1.274) -1).subs({Rent:47e3, Vuvlo:8})
Renb = solve(Eq_uvlo, Renb)[0]
print(Renb)
>>> 8902.46
Now i want to try 9100 for Renb.
But i cannot calculate the final Vuvlo value, because it's already substituted.
Vuvlo = solve(Eq_uvlo.subs({Renb:9.1}), Vuvlo)
Is there any better way, to make a calculation like this?
You had Renb as a symbol, but then assigned a value to it. This means you lost that symbol, you don't have a handle on it anymore. Use a different Python variable to hold any numerical value related to that symbol, like Renb_sol below.
Also, substitution of numerical values can be done later, after the solution is obtained. This allows you to use the same equation solving for different variables in it.
Eq_uvlo = Eq(Rent/Renb, (Vuvlo/1.274) -1)
Renb_sol = solve(Eq_uvlo, Renb)[0].subs({Rent: 47e3, Vuvlo: 8})
print(Renb_sol)
Vuvlo_sol = solve(Eq_uvlo, Vuvlo)[0].subs({Rent: 47e3, Renb: 9100})
print(Vuvlo_sol)
prints
8902.46803449301
7.85400000000000
I have an equation and I need to solve it for a fraction.
I have more complex fomulas to solve but here is a minimal example: take the following simple function Y = X*a.
I want to solve for Y/X, so I expect Y/X =a.
Here is the code, it produces an empty set of answers
from sympy import *
X,Y,a = symbols('X Y a')
testEq = Eq(Y,X*a)
solve(testEq,Y/X)
I guess I'm misunderstanding something, any help appreciated!
The solve function can solve for sub-expressions provided they appear "as is" in the equation being solved. For example, in the following code, solve returns an empty solution for testEq but it returns the correct solution for testEq2 which is the same equation rearranged in terms of Y/X.
from sympy import *
X,Y,a = symbols('X Y a')
testEq = Eq(Y,X*a)
solve(testEq,Y/X)
testEq2 = Eq( Y/X, a )
sol = solve(testEq2,Y/X)
This is not weird or unreasonable at all. If you look at the source code of the solve function it uses code like
>>> testEq.has( Y/X ) # returns False
>>> testEq2.has( Y/X ) # returns True
to check if the symbol ( or sympy object ) that we are solving is present in the equation. If SymPy had to check for all possible ways in which the symbols of an expression can be combined into sub-expressions, the code would become extremely complicated for something which can be easily achieved in other ways ( like solving for Y and dividing by X, in this example ).
Packages for symbolic computations are there to help us handle complicated mathematical equations. But they are not a substitute for human intelligence. More often than not, we need to guide these packages to help them give the answer in a form we want while working around their limitations.
In this issue, a focus routine handles such a request once an auxiliary expression is added to the one of interest:
>>> eq = Eq(y, x*a)
>>> aux = Eq(b, y/x)
>>> focus((aux, eq), b)
{b: a}
Such a routine does not eliminate the need for human intervention, it just assists by allowing the user to state the relationship of interest and add that to the current equation(s) from which the implications are then deduced/solved.