简体   繁体   中英

Why doesn't SymPy simplify the expression?

I am just looking at the Python module SymPy and try, as a simple (useless) example the fit of a function f(x) by a function set g_i(x) in a given interval.

import sympy as sym

def functionFit(f, funcset, interval):
    N = len(funcset) - 1
    A = sym.zeros(N+1, N+1)
    b = sym.zeros(N+1, 1)
    x = sym.Symbol('x')

    for i in range(N+1):
        for j in range(i, N+1):
            A[i,j] = sym.integrate(funcset[i]*funcset[j],
            (x, interval[0], interval[1]))
            A[j,i] = A[i,j]

        b[i,0] = sym.integrate(funcset[i]*f, (x, interval[0], interval[1]))

    c = A.LUsolve(b)
    u = 0

    for i in range(len(funcset)):
        u += c[i,0]*funcset[i]

    return u, c


x = sym.Symbol('x')
f = 10*sym.cos(x)+3*sym.sin(x)
fooset=(sym.sin(x), sym.cos(x))
interval = (1,2)
print("function to approximate:", f)
print("Basic functions:")

for foo in fooset:
    print(" - ", foo)

u,c = functionFit(f, fooset, interval)

print()
print("simplified u:")
print(sym.simplify(u))
print()
print("simplified c:")
print(sym.simplify(c))

The result is the fit function u(x), to be returned, together with the coefficients by functionFit .

In my case

 f(x) = 10 * sym.cos(x) + 3 * sym.sin(x)

and I want to fit it according to a linear combination of sin(x), cos(x). So the coefficients should be 3 and 10.

The result is OK, but for u(x) I get

 u(x) = (12*sin(2)**2*sin(4)*sin(x) + 3*sin(8)*sin(x) + 12*sin(2)*sin(x) + 40*sin(2)**2*sin(4)*cos(x) + 10*sin(8)*cos(x) + 40*sin(2)*cos(x))/(2*(sin(4) + 2*sin(2))) : 

Function to approximate: 3*sin(x) + 10*cos(x) 

Basic functions:
      -  sin(x)
      -  cos(x)

Simplified u: (12*sin(2)**2*sin(4)*sin(x) + 3*sin(8)*sin(x) + 12*sin(2)*sin(x) + 40*sin(2)**2*sin(4)*cos(x) + 10*sin(8)*cos(x) + 40*sin(2)*cos(x))/(2*(sin(4) + 2*sin(2)))

Simplified c: Matrix([[3], [10]])

which is indeed the same as 10 * cos(x) + 3 * sin(x). However I wonder why it is not simplified to that expression. I tried several simplifying function available, but none of it gives the expected result.

Is there something wrong in my code or are my expectations to high?

Don't know if this is a solution for you, but I'd simply use the .evalf method of every Sympy expression

In [26]: u.simplify()                                                                     
Out[26]: (12*sin(2)**2*sin(4)*sin(x) + 3*sin(8)*sin(x) + 12*sin(2)*sin(x) + 40*sin(2)**2*sin(4)*cos(x) + 10*sin(8)*cos(x) + 40*sin(2)*cos(x))/(2*(sin(4) + 2*sin(2)))

In [27]: u.evalf()                                                                        
Out[27]: 3.0*sin(x) + 10.0*cos(x)

In [28]:                                                                                  

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM