How makes all low values in the symbolic calculation become zero?

前端 未结 4 1734
长情又很酷
长情又很酷 2021-01-24 23:47

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         


        
相关标签:
4条回答
  • 2021-01-24 23:58

    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.

    0 讨论(0)
  • 2021-01-25 00:15

    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)
    
    0 讨论(0)
  • 2021-01-25 00:22

    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)
    
    0 讨论(0)
  • 2021-01-25 00:22

    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.

    0 讨论(0)
提交回复
热议问题