Home > database >  python (SymPy) giving different result to Maple
python (SymPy) giving different result to Maple

Time:09-11

I am trying to convert some Maple code to python using SymPy. The following is the Maple code I am trying to convert: enter image description here

The following is my attempt at python code to do the same, but this is as far as I got.

from sympy import *
c, k, x, t, tau, Y, xi = symbols('c k x t tau Y xi')

u = Function('u')
F = Function('F') 
xi = k*(x-c*t)

U = Function('U')
pde = diff(u(x,t), t)   6*u(x,t)*diff(u(x,t), x) 
ode = simplify(pde.xreplace({t:tau,u(x,t):U(xi)}))
ode1 = simplify(ode.xreplace({xi:atanh(Y), U(xi):F(Y)}))

display('pde = ', pde)
display('ode = ', ode)
display('ode1 = ', ode1)

The output generated by python is:

python output

The ode1 output from python should be the same (or similar) to the Maple output "F1".

Any help appreciated.

CodePudding user response:

This line: pde = diff(u(x,t), t) 6*u(x,t)*diff(u(x,t), x) reads pde = diff(u(x,t), x) 6*u(x,t)*diff(u(x,t), x) in your maple example, that might be the culprit.

CodePudding user response:

Notice first that your Python code defines the Python variable xi in two different ways. You need to distinguish between xi the symbol and the expression k*(x - c*t) so let's call the expression xi_e instead:

In [30]: from sympy import *
    ...: c, k, x, t, tau, Y, xi = symbols('c k x t tau Y xi')
    ...: 
    ...: u = Function('u')
    ...: F = Function('F')
    ...: xi_e = k*(x-c*t)
    ...: 
    ...: U = Function('U')
    ...: pde = diff(u(x,t), t)   6*u(x,t)*diff(u(x,t), x)

In [31]: pde
Out[31]: 
          ∂             ∂          
6⋅u(x, t)⋅──(u(x, t))   ──(u(x, t))
          ∂x            ∂t

Now we need to use xi and xi_e in different ways here and we have to be careful about the order of substitutions. I'll show each step so you can see what's happening:

In [35]: pde.xreplace({u(x,t):U(xi_e)})
Out[35]: 
                  ∂                     ∂                  
6⋅U(k⋅(-c⋅t   x))⋅──(U(k⋅(-c⋅t   x)))   ──(U(k⋅(-c⋅t   x)))
                  ∂x                    ∂t                 

In [36]: pde.xreplace({u(x,t):U(xi_e)}).xreplace({t: tau})
Out[36]: 
                  ∂                     ∂                  
6⋅U(k⋅(-c⋅τ   x))⋅──(U(k⋅(-c⋅τ   x)))   ──(U(k⋅(-c⋅τ   x)))
                  ∂x                    ∂τ                 

In [37]: pde.xreplace({u(x,t):U(xi_e)}).xreplace({t: tau}).doit()
Out[37]: 
      ⎛ d        ⎞│                                      ⎛ d        ⎞│               
- c⋅k⋅⎜───(U(ξ₁))⎟│                  6⋅k⋅U(k⋅(-c⋅τ   x))⋅⎜───(U(ξ₁))⎟│               
      ⎝dξ₁       ⎠│ξ₁=k⋅(-c⋅τ   x)                       ⎝dξ₁       ⎠│ξ₁=k⋅(-c⋅τ   x)

In [40]: pde.xreplace({u(x,t):U(xi_e)}).xreplace({t: tau}).doit().xreplace({x: xi/k   c*tau})
Out[40]: 
      ⎛ d        ⎞│                ⎛ d        ⎞│    
- c⋅k⋅⎜───(U(ξ₁))⎟│       6⋅k⋅U(ξ)⋅⎜───(U(ξ₁))⎟│    
      ⎝dξ₁       ⎠│ξ₁=ξ            ⎝dξ₁       ⎠│ξ₁=ξ

In [41]: pde.xreplace({u(x,t):U(xi_e)}).xreplace({t: tau}).doit().xreplace({x: xi/k   c*tau}).doit()
Out[41]: 
      d                   d       
- c⋅k⋅──(U(ξ))   6⋅k⋅U(ξ)⋅──(U(ξ))
      dξ                  dξ 

That's your ode1 shown in your Maple code (or ode in the Python code):

In [42]: ode = pde.xreplace({u(x,t):U(xi_e)}).xreplace({t: tau}).doit().xreplace({x: xi/k   c*tau}).doit()

In [43]: ode
Out[43]: 
      d                   d       
- c⋅k⋅──(U(ξ))   6⋅k⋅U(ξ)⋅──(U(ξ))
      dξ                  dξ 

Next you want to replace xi with atanh(Y) and U(xi) with F(Y). In Maple you are using dchange for this but SymPy does not have an equivalent for dchange to change the variable being differentiated wrt. There is an open issue to add something like dchange: https://github.com/sympy/sympy/issues/17590

In that issue you can see some example code that can do this. It just involves a bit of fiddling with intermediate variables. I'll show all of the steps so you can see what's happening:

In [44]: xi_f = Function('xi')

In [45]: xi_s = atanh(Y)

In [46]: diff_xi = lambda e, n: Derivative(e, Y) / Derivative(xi_f(Y), Y)

In [47]: changex = lambda e: e.replace(Derivative, lambda e, vs: diff_xi(e, vs[1]))

In [50]: eqf = ode.subs(xi, xi_f(Y))

In [51]: eqf
Out[51]: 
        d                            d           
- c⋅k⋅─────(U(ξ(Y)))   6⋅k⋅U(ξ(Y))⋅─────(U(ξ(Y)))
      dξ(Y)                        dξ(Y)  

In [61]: changex(eqf)
Out[61]: 
      d                         d          
  c⋅k⋅──(U(ξ(Y)))   6⋅k⋅U(ξ(Y))⋅──(U(ξ(Y)))
      dY                        dY         
- ───────────────   ───────────────────────
      d                     d              
      ──(ξ(Y))              ──(ξ(Y))       
      dY                    dY             

In [62]: changex(eqf).xreplace({U(xi_f(Y)): F(Y)})
Out[62]: 
      d                   d       
  c⋅k⋅──(F(Y))   6⋅k⋅F(Y)⋅──(F(Y))
      dY                  dY      
- ────────────   ─────────────────
    d                 d           
    ──(ξ(Y))          ──(ξ(Y))    
    dY                dY          

In [63]: changex(eqf).xreplace({U(xi_f(Y)): F(Y)}).xreplace({xi_f(Y): xi_s})
Out[63]: 
      d                   d       
  c⋅k⋅──(F(Y))   6⋅k⋅F(Y)⋅──(F(Y))
      dY                  dY      
- ────────────   ─────────────────
  d                 d             
  ──(atanh(Y))      ──(atanh(Y))  
  dY                dY            

In [64]: changex(eqf).xreplace({U(xi_f(Y)): F(Y)}).xreplace({xi_f(Y): xi_s}).doit()
Out[64]: 
      ⎛     2⎞ d              ⎛     2⎞      d       
- c⋅k⋅⎝1 - Y ⎠⋅──(F(Y))   6⋅k⋅⎝1 - Y ⎠⋅F(Y)⋅──(F(Y))
               dY                           dY 

That matches your final ode1.

  • Related