MichaelW
MichaelW

Reputation: 1464

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?

Upvotes: 3

Views: 2825

Answers (1)

gboffi
gboffi

Reputation: 25023

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]:                                                                                  

Upvotes: 3

Related Questions