Scipy odeint ODE error on array sizes - python

I am trying to solve an ODE which arises from N-body problems in field theory in Physics. For that I thought of using scipy.integrate.odeint function and I have written some code which can be found on:
http://pastebin.com/yuBbEjwg (updated since the question was first posed)
However, when I try to execute it, I get the following error:
Traceback (most recent call last):
File "./main.py", line 87, in <module>
solution = odeint(ODE,XV0,t,args=(M,))
File "/usr/lib/python2.7/site-packages/scipy/integrate/odepack.py", line 143, in odeint
ixpr, mxstep, mxhnil, mxordn, mxords)
ValueError: object too deep for desired array
Could somebody point me out what am I doing wrong? And why my code doesn't work? Also, I wanted to ask if there is any difference between using ode and odeint functions in my case?
Thanks.
EDIT: corrected silly mistakes (shape() -> shape), thanks to Talonmies for pointing that out. The link above should point to the correct script now.
EDIT 2: I somehow suspect that the odeint function doesn't like the tuple returned by the ODE function. Could somebody help on how one formats the tuple if coupled vector ODE need to be solved? I found cases were people are solving coupled ODEs or vector ODEs but not both...
EDIT 3: I have reworked the example so that I give odeinit function a matrix of initial conditions and the returned matrix from the function named ODE, is a matrix of the same dimensions... However, I get the same error.

Related

Python - Rolling Function (Step - Pandas 1.5.0)

I updated all the relevant libraries to the latest version, hence I thought that I could now use the new feature (step) in the rolling-function:
print(df['600028.SS'].rolling(window=125, step=20).corr(df['600121.SS']))
However, when executing the commande, I always get the following error message:
NotImplementedError: step not implemented for corr
How can I implement the step-feature for corr, or is there any way to circumvent the error message. By the way '600028.SS' and '600121.SS' are just the names of two columns in the dataframe
I want to get the correlation coefficient for those two stocks on a rolling basis. Every correlation coefficient should include the last 125 observations, and the step-size should be 20. And with the new step feature since the latest pandas update (1.5.0) I thought it should be fine to use now, however, I still receive the massage that step would not be implemented for corr.
The symptom is easily reproduced:
>>> df = pd.DataFrame([dict(a=1, b=2)])
>>> df.a.rolling(window=125, step=20).corr(df.b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jhanley/miniconda3/envs/problems/lib/python3.10/site-packages/pandas/core/window/rolling.py", line 2829, in corr
return super().corr(
File "/Users/jhanley/miniconda3/envs/problems/lib/python3.10/site-packages/pandas/core/window/rolling.py", line 1757, in corr
raise NotImplementedError("step not implemented for corr")
NotImplementedError: step not implemented for corr
I am reading the 1.5.1 documentation, https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.core.window.rolling.Rolling.corr.html .
It lists four possible args:
other
pairwise
ddof
numeric_only
It doesn't mention a step parameter.
It explains that additional args
are accepted
"for NumPy compatibility and will not have an effect on the result."
The diagnostic error message is accurate.
You are attempting to use something that
is not implemented.
That won't work.

solving a Non- linear first order differential equation and getting a break in the plot

I am trying to solve the elliptical differential equation using fourth-order runge-kutta method in python.
After execution, I get a very small part of the actual plot that should be obtained and alongside with it an error saying that:
"RuntimeWarning: invalid value encountered in double_scalars"
import numpy as np
import matplotlib.pyplot as plt
#Define constants
g=9.8
L=1.04
#Define the differential Function
def fun(y,x):
return-(2*(g/L)*(np.cos(y)-np.cos(np.pi/6)))**(1/2)
#Define variable arrays
x=np.zeros(1000)
y=np.zeros(1000)
y[0]=np.pi/6
dx=0.5
#Runge-Kutta Method
for i in range(len(y)-1):
k1=fun(x[i],y[i])
k2=fun(x[i]+dx/2, y[i]+dx*k1/2)
k3=fun(x[i]+dx/2, y[i]+dx*k2/2)
k4=fun(x[i]+dx, y[i]+dx*k3)
y[i+1]=y[i]+dx/6*(k1+2*k2+2*k3+k4)
x[i+1]=x[i]+dx
#print(y)
#print(x)
plt.plot(x,y)
plt.xlabel('Time')
plt.ylabel('Theta')
plt.grid()
And the graph I obtain is something like,
My question is why am I getting the error message? Thanks for helping!
Several points that lead to this behavior. First, you switched the order of the arguments in the ODE function, probably to make it compatible with odeint. Use the tfirst=True optional argument to avoid that and have the independent variable always first.
The actual source of the error is the term
(np.cos(y)-np.cos(np.pi/6)))**(1/2)
remember that in your version y has the value x[i], so that at some point the expression under the root becomes negative.
If you correct the first point, you will probably still encounter the second error as the exact solution moves parabolically towards the fixed point, so that the stages of RK4 are likely to overshoot. One can fix that by providing a sufficiently secured square root function,
def softroot(x): return x/max(1e-12,abs(x))**0.5
#Define the differential Function
def fun(x,y):
return -(2*(g/L)*softroot(np.cos(y)-np.cos(np.pi/6)))
#Define variable arrays
dx=0.01
x=np.arange(0,1,dx)
y=np.zeros(x.shape)
y[0]=np.pi/6
...
results in a plot
as the solution already starts in the fixed point. Shifting the initial point a little down to y[0]=np.pi/6-1e-8 produces a jump to the fixed point below.

How to fix step size and number of steps in the scipy integrator 'dopri5'?

I have written code in python to solve differential equations using scipy integrator dopri5. Frequently I am getting an error unsuccessful integration. Then I tried to change number of steps but again I am getting the error that step size become too small. When I am setting nsteps=1 then error showing that more step should be needed.
I don't know where I am wrong? And how to fix this problem?
Warning (from warnings module):
self.messages.get(istate, unexpected_istate_msg)))
UserWarning: dopri5: step size becomes too small
state = ODE.integrate(0.0001)
File "/home/.local/lib/python3.6/site-packages/jitcode/_jitcode.py", line 644, in integrate
return self.integrator.integrate(*args,**kwargs)
packages/jitcode/integrator_tools.py", line 143, in integrate
raise UnsuccessfulIntegration
jitcode.integrator_tools.UnsuccessfulIntegration

vectorizing an optimization in python

I am trying to vectorize an optimization (root finding) problem where I need to find roots of an integral. I haven't found any good integration functions that work with vectorization so I coded up a tradezoidal approach to integration. The following code is an attempt to vectorize the roots (for each d there is a different root) finding problem for an input array d of length N=300000 instead of using a loop for different values of d.
from scipy import optimize as op
import numpy as np
N=300000
d=np.random.rand(N)
def f(z): # vectorized version- depends on d as well
return ((1-2*z)*np.exp(-d[:,None]/z))/(((1-z)**(2+d[:,None]))*(z**(2-d[:,None])))
def trap(func,start,end,num): #trapezoidal approach to integration
diff=(end-start)/(num-1.0)
g=np.arange(num)
xlinear=diff[:,None]*g+start[:,None]
fx=func(xlinear)
return np.trapz(fx,xlinear)
def integral(p):
start=np.zeros_like(p) +0.001
return trap(f,start,p,100)
root=op.fsolve(integral,0.75*np.ones_like(d))
However, the above code is throwing a memory error for me.
Traceback (most recent call last):
...
File "H:...my_module.py", line 344, in
root=op.fsolve(integral,0.75*np.ones_like(a))
File "C:..scipy\optimize\minpack.py", line 140, in fsolve
res = _root_hybr(func, x0, args, jac=fprime, **options)
File "C:...scipy\optimize\minpack.py", line 209, in _root_hybr
ml, mu, epsfcn, factor, diag)
MemoryError
I am open to completely different approaches to do this.

Which unsupervised clustering algorithm from the sklearn library can I use with custom distance?

I have a function that takes as input two samples and return their distance and from this function I have defined a metric
def TwoPointsDistance(x1, x2):
cord1 = f.rf.apply(x1)
cord2 = f.rf.apply(x2)
return 1 - (cord1==cord2).sum()/f.n_trees
metric = sk.neighbors.DistanceMetric.get_metric('pyfunc',
func=TwoPointsDistance)
Now I would like to cluster my data according to this metric. I would like to see some examples of algorithms for unsupervised clustering that use this as a distance metric.
EDIT: I am particularly interested in this algorithm:
http://scikit-learn.org/stable/modules/generated/sklearn.cluster.DBSCAN.html#sklearn.cluster.DBSCAN
EDIT: I have tried
DBSCAN(metric=metric, algorithm='brute').fit(Xor)
but I receive an error:
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.4/dist-packages/sklearn/cluster/dbscan_.py", line 249, in fit
clust = dbscan(X, **self.get_params())
File "/usr/local/lib/python3.4/dist-packages/sklearn/cluster/dbscan_.py", line 100, in dbscan
metric=metric, p=p)
File "/usr/local/lib/python3.4/dist-packages/sklearn/neighbors/unsupervised.py", line 83, in __init__
leaf_size=leaf_size, metric=metric, **kwargs)
File "/usr/local/lib/python3.4/dist-packages/sklearn/neighbors/base.py", line 127, in _init_params
% (metric, algorithm))
ValueError: Metric '<sklearn.neighbors.dist_metrics.PyFuncDistance object at 0x7ff5c299f358>' not valid for algorithm 'brute'
>>>
I've tried to figure out why this error arises... I first thought sklearn.neighbors.NearestNeighbors (which is what DBSCAN is based upon) would be constrained to those distances listed in sklearn.neighbors.base.VALID_METRICS["brute"]. But judging from the source code, any callable function should be okay - so it seems your distance isn't callable?
Please try this:
DBSCAN(metric=TwoPointsDistance, algorithm='brute').fit(Xor)
i.e. without wrapping your distance as neighbors.DistanceMetric. It seems a bit inconsistent to me to now allow these to be used here...
Myself, I have used ELKI with great success with a custom distance function, and there is a short tutorial on how to write these available: http://elki.dbs.ifi.lmu.de/wiki/Tutorial/DistanceFunctions
Today, years later, I still stumbled over this in a different context. The solution is simple: pass the function directly as a metric.
BSCAN(metric=TwoPointsDistance, algorithm='brute').fit(Xor)

Categories

Resources