sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.99k stars 4.44k forks source link

simplify regression in newer versions #7769

Open unknownuser75 opened 10 years ago

unknownuser75 commented 10 years ago
S,K,T,t,r,sigma=symbols('S K T t r sigma')
simplify(-sqrt(2)*K*exp(-r*(T - t))*exp(-(sigma*sqrt(T - t)/2 - log(S*exp(r*(T - t))/K)/(sigma*sqrt(T - t)))**2/2)/(2*sqrt(pi)*S*sigma*sqrt(T - t)) + sqrt(2)*exp(-(sigma*sqrt(T - t)/2 + log(S*exp(r*(T - t))/K)/(sigma*sqrt(T - t)))**2/2)/(2*sqrt(pi)*sigma*sqrt(T - t)))

The above expression is 0. I've just started using sympy and this was one of the first examples I tried. On my older Ubuntu 12.04 with sympy 0.7.1.rc1 this correctly simplifies to zero. On newer sympy versions (0.7.4, 0.7.5) it does not simplify to zero.

debugger22 commented 10 years ago

This change was introduced in 3305c73b265691be4a411971cdbbd8e39e8810ca. @smichr

smichr commented 3 years ago

It's good to see that nothing too heroic has to be done to show that this is zero. How to put this into simplify in a meaningful way will take some thought:

>>> ok
-sqrt(2)*K*exp(-8*r*sigma**2*(T - t)**2/(8*T*sigma**2 - 8*sigma**2*t) - (T*sigma**2 - sigma**2*t - 2*log(S*exp(T*r - r*t)/K))**2/(8*T*sigma**2 - 8*sigma**2*t))/(2*sqrt(pi)*S*sigma*sqrt(T - t)) + sqrt(2)*exp(-(T*sigma**2 - sigma**2*t + 2*log(S*exp(T*r - r*t)/K))**2/(8*T*sigma**2 - 8*sigma**2*t))/(2*sqrt(pi)*sigma*sqrt(T - t))
>>> bottom_up(ok, factor_terms)
sqrt(2)*(-K*exp(-r*(T - t) - (T*sigma**2 - sigma**2*t - 2*log(S*exp(r*(T - t))/K))**2/(8*sigma**2*(T - t)))/S + exp(-(T*sigma**2 - sigma**2*t + 2*log(S*exp(r*(T - t))/K))**2/(8*sigma**2*(T - t))))/(2*sqrt(pi)*sigma*sqrt(T - t))
>>> r,e = cse(_); e=factor_terms(e[0].expand().as_numer_denom()[0]);e
sqrt(2)*sqrt(pi)*sigma*sqrt(x0)*(-K*exp(4*x2*x4*x5) + S*exp(x1))*exp(x2**2*x5)*exp(x4**2*x5)
>>> _.args
(sigma, sqrt(2), sqrt(pi), sqrt(x0), -K*exp(4*x2*x4*x5) + S*exp(x1), exp(x2**2*x5), exp(x4**2*x5))
>>> _[4].subs(reversed(r))
-K*exp((T*sigma**2 - sigma**2*t)*log(S*exp(r*(T - t))/K)/(sigma**2*(T - t))) + S*exp(r*(T - t))
>>> factor_terms(_)
0

That last factor_terms is important: if you don't eliminate that factor then things get out of control again with expansion.

>>> e.args[4].subs(reversed(r)).expand()
-K*exp(T*sigma**2*log(S*exp(T*r)*exp(-r*t)/K)/(T*sigma**2 - sigma**2*t))*exp(-sigma**2*t*log(S*exp(T*r)*exp(-r*t)/K)/(T*sigma**2 - sigma**2*t)) + S*exp(T*r)*exp(-r*t)

A point to consider: