How can I make all low values in a SymPy expression zero? For example, my result is:
1.0*a1*cos(q1) - 6.12e-17*(a2*sin(q2) + a3*sin(q2 + q3) + a4*sin(q2 + q3 + q
Probably there are much more efficient ways(I am not familiar with that library) but I tried to do with regex
. If e-
exist in a part of the equation it replaces it to 0(you can remove directly if you want). But to be able to do this, I had to remove to spaces between +-
operators inside the parentheses, so I could make a list by splitting from the other +-
operators.
import re
result='''1.0*a1*cos(q1) - 6.12e-17*(a2*sin(q2) + a3*sin(q2+q3)
+ a4*sin(q2+q3+q4))sin(q1) + 1.0(a2*cos(q2)
+ a3*cos(q2+q3) + a4*cos(q2+q3+q4))*cos(q1)'''
too_small='e-'
mylist=re.split(r"\s+", result)
for i in range(len(mylist)):
if too_small in mylist[i]:
mylist[i]='0'
new_result=''.join(mylist)
print(new_result)
And this is the output:
1.0*a1*cos(q1)-0+a3*sin(q2+q3)+a4*sin(q2+q3+q4))sin(q1)+1.0(a2*cos(q2)+a3*cos(q2+q3)+a4*cos(q2+q3+q4))*cos(q1)
As I said, there are probably much better ways than this.
SymPy’s nsimplify
function with the rational=True
argument converts floats within an expression to rational numbers (within a given tolerance). Something like 6.12e-17
will be converted to 0 if below the threshold. So, in your case:
from sympy import sin, cos, symbols, nsimplify
a1, a2, a3, a4 = symbols("a1, a2, a3, a4")
q1, q2, q3, q4 = symbols("q1, q2, q3, q4")
expr = (
1.0*a1*cos(q1)
- 6.12e-17*(a2*sin(q2) + a3*sin(q2 + q3) + a4*sin(q2 + q3 + q4))*sin(q1)
+ 1.0*(a2*cos(q2) + a3*cos(q2 + q3) + a4*cos(q2 + q3 + q4))*cos(q1)
)
nsimplify(expr,tolerance=1e-10,rational=True)
# a1*cos(q1) + (a2*cos(q2) + a3*cos(q2 + q3) + a4*cos(q2 + q3 + q4))*cos(q1)
A direct way to do this is to replace such numbers with 0. A naive eq.subs(small, 0)
will fail because small
that you enter is not likely to be exactly the same as the number. But eq.atoms(Float)
will give you the set of such numbers:
>>> eq.xreplace(dict([(n,0) for n in eq.atoms(Float) if abs(n) < 1e-12]))
1.0*a1*cos(q1) + (1.0*a2*cos(q2) + 1.0*a3*cos(q2 + q3) + 1.0*a4*cos(q2 + q3 + q4))*cos(q1)
What about more details? I guess you want replace part of a symbolic calculation string, Regular expression in Python could be helpful, you can code like this:
In [1]: import re
In [2]: s = '1.0*a1*cos(q1) - 6.12e-17*(a2*sin(q2) + a3*sin(q2 + q3) + ' \
...: 'a4*sin(q2 + q3 + q4))sin(q1) + 1.0(a2*cos(q2) + ' \
...: 'a3*cos(q2 + q3) + a4*cos(q2 + q3 + q4))*cos(q1)'
In [3]: s = re.sub(r'[+-/*/]\s\S*e-[1-9]\d+\S*\s', '', s)
In [4]: s
Out[4]: '1.0*a1*cos(q1) + a3*sin(q2 + q3) + a4*sin(q2 + q3 + q4))sin(q1) + 1.0(a2*cos(q2) + a3*cos(q2 + q3) + a4*cos(q2 + q3 + q4))*cos(q1)'
First argument of re.sub() function decide what you want to reduce, e-[1-9]\d+
represent a number lower than e-10 which you can modify, I hope it helps.