as @Warren Weckesser says and as you suspected, you need to lambdify the expressions first, so that the various partial derivatives dV/dvar[j]
return a floating point value.
More in general, one problem of your afleiden
function is that it evaluates the analytical derivatives of V
, without calculating the value of those expressions. I assume that v,a,c
are parameters of your problems, deacribing a potential function V(x,y,z)
. I also assume that your o.d.e. is
dX/dt = dV/dX(x,y,z)
,
where X=[x,y,z]
is your list of variables.
If this is the case, then you have 3 diff. equations, and not 6
as in your func()
(a sum of lists is the concatenation of the lists, not the list of the sums).
import numpy as np
from sympy import lambdify, sympify
from scipy.integrate import odeint
var = ['x', 'y', 'z']
V = sympify("v**2/2*log(1+x**2 + (y/a)**2 + (z/c)**2)")
dVdvar_analytical = [V.diff(var[i]) for i in range(len(var))]
dVdvar = [lambdify(('x', 'y', 'z', 'v', 'a', 'c'), df) for df in dVdvar_analytical]
def afleiden(variables, _, params, dVdvar):
x, y, z = variables
v, a, c = params
return [dVdvarj(x, y, z, v, a, c) for dVdvarj in dVdvar ]
variables0, params = [0.3, 0.2, 0.9], [0.2, 0.6, 0.7]
t = np.arange(0, 10, .1)
y = odeint(afleiden, variables0, t, args=(params, dVdvar))
plot(t, y)
Consistently with your expression for the potential V
, the origin is a repellor and the point y(t)
tends to infinity in the simulation for large times. if you add a minus sign at the begin of the expression, the origin becomes an attractor and the solution converges to 0
:
#example with minus sign
V = sympify("-v**2/2*log(1+x**2 + (y/a)**2 + (z/c)**2)")
t = np.arange(0, 100, .1)