scipy.interpolate.interpnd complaining about 'Delaunay' object has no attribute 'simplices' - python

I'm dusting off some code I wrote a few months ago, and for some reason it doesn't work anymore... In a nutshell, I'm using scipy.interpolate.LinearNDInterpolator objects to interpolate models and compare to data. Now, when I attempt to call the interpolator object with the coordinates at which I would like the interpolation, I get the following error:
In [9]: a([[3500, 3.5, 1.5]])
AttributeError Traceback (most recent call last)
<ipython-input-9-91f2103e7a0c> in <module>()
----> 1 a([[3500, 3.5, 1.5]])
/usr/lib64/python2.7/site-packages/scipy/interpolate/interpnd.so in scipy.interpolate.interpnd.NDInterpolatorBase.__call__ (scipy/interpolate/interpnd.c:3133)()
/usr/lib64/python2.7/site-packages/scipy/interpolate/interpnd.so in scipy.interpolate.interpnd.LinearNDInterpolator._evaluate_double (scipy/interpolate/interpnd.c:3954)()
/usr/lib64/python2.7/site-packages/scipy/interpolate/interpnd.so in scipy.interpolate.interpnd.LinearNDInterpolator._do_evaluate (scipy/interpolate/interpnd.c:4684)()
AttributeError: 'Delaunay' object has no attribute 'simplices'
I have never seen this error before, and the code has worked previously. Did something just change in scipy that I'm not aware of?
Thanks for looking!

I guess you use an older version of the library:
The Delaunay library has two different accessors for simplices:
"Delaunay.simplices" and "Delaunay.vertices"
shown here (newest docs): http://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.Delaunay.html
Of the two Delaunay.vertices is marked "deprecated".
On Ubuntu 13.04 the simplices call does not exist however, because it still uses scipy 0.11.0:
http://docs.scipy.org/doc/scipy-0.11.0/reference/generated/scipy.spatial.Delaunay.html#scipy.spatial.Delaunay
Try with this minimal example or just rewrite your simplices call to vertices:
from __future__ import print_function
import numpy as np
from scipy.spatial import Delaunay
import sys
my_molecule = np.random.rand(400,3) #points for query
points = np.random.rand(1000, 3) #points used for Triangulation
diag = Delaunay(points)
simplices = diag.find_simplex(my_molecule)
for point,simplex in zip(my_molecule,simplices):
if simplex == -1:
print ("Point not included in diag.")
continue
print ("Doing vertices call: ")
spoints = diag.vertices[simplex]
print ("Doing simplices call: ")
spoints = diag.simplices[simplex]

Related

TypeError: only size-1 arrays can be converted to Python scalars + Solution

According to Python Documentation a TypeError is defined as
Raised when an operation or function is applied to an object of inappropriate type. The associated value is a string giving details about the type mismatch.
exception TypeError
The reason I got this Error was because my code looked like this:
import math as m
import pylab as pyl
import numpy as np
#normal distribution function
def normal(x,mu,sigma):
P=(1/(m.sqrt(2*m.pi*sigma**2)))*(m.exp((-(x-mu)**2)/2*sigma**2))
return P
#solution
x = np.linspace(-5,5,1000)
P = normal(x,0,1)
#plotting the function
pyl.plot(x,P)
pyl.show()
P=(1/(m.sqrt(2***m**.pisigma2)))(**m.exp((-(x-mu)2)/2*sigma2))
Notice the m. - This is incorrect, because math. can only handle scalars. And the Error said that a TypeError had occurred.
np. (Numpy) can handle scalers as well as arrays and the problem is solved.
The right code looks like this:
import math as m
import pylab as pyl
import numpy as np
# normal distribution function
def normal(x,mu,sigma):
P = (1/(np.sqrt(2*np.pi*sigma**2))) * (np.exp((-(x-mu)**2)/2*sigma**2))
return P
# solution
x = np.linspace(-5,5,1000)
P = normal(x,0,1)
# plotting the function
pyl.plot(x,P)
pyl.show()
In the end we get a great normal distribution function that looks like this:
This Error occurred in Spyder IDE.

Syntax for importing scipy and sklearn modules

I use (just the standards) Win10, Anaconda-2018.12, Python-3.7, MKL-2019.1, mkl-service-1.1.2, Jupyter ipython-7.2. see here e.g.
I"m wondering why the following syntax works for import statements with the numpy modules but does not work for scipy or sklearn modules:
import scipy as sp
import numpy as np
A = np.random.random_sample((3, 3)) + np.identity(3)
b = np.random.rand((3))
x = sp.sparse.linalg.bicgstab(A,b)
> AttributeError Traceback (most recent call
> last) <ipython-input-1-35204bb7c2bd> in <module>()
> 3 A = np.random.random_sample((3, 3)) + np.identity(3)
> 4 b = np.random.rand((3))
> ----> 5 x = sp.sparse.linalg.bicgstab(A,b)
> AttributeError: module 'scipy' has no attribute 'sparse'
or with sklearn
import sklearn as sk
iris = sk.datasets.load_iris()
> AttributeError Traceback (most recent call
> last) <ipython-input-2-f62557c44a49> in <module>()
> 2 import sklearn as sk
> ----> 3 iris = sk.datasets.load_iris() AttributeError: module 'sklearn' has no attribute 'datasets
This syntax however does work (but are for rare commands not really lean):
import sklearn.datasets as datasets
iris = datasets.load_iris()
and
from scipy.sparse.linalg import bicgstab as bicgstab
x = bicgstab(A,b)
x[0]
array([ 0.44420803, -0.0877137 , 0.54352507])
What type of problem is that ? Could it be eliminated with reasonable effort ?
The "problem"
The behavior you're running into is actually a feature of Scipy, though it may seem like a bug at first glance. Some of the subpackages of scipy are quite large and have many members. Thus, in order to avoid lag when running import scipy (as well as to save on usage of system memory), scipy is structured so that most subpackages are not automatically imported. You can read all about it in the docs right here.
The fix
You can work around the apparent problem by exercising the standard Python import syntax/semantics a bit:
import numpy as np
A = np.random.random_sample((3, 3)) + np.identity(3)
b = np.random.rand((3))
import scipy as sp
# this won't work, raises AttributeError
# x = sp.sparse.linalg.bicgstab(A,b)
import scipy.sparse.linalg
# now that same line will work
x = sp.sparse.linalg.bicgstab(A,b)
print(x)
# output: (array([ 0.28173264, 0.13826848, -0.13044883]), 0)
Basically, if a call to sp.pkg_x.func_y is raising an AttributeError, then you can fix it by adding a line before it like:
import scipy.pkg_x
Of course, this assumes that scipy.pkg_x is a valid scipy subpackage to begin with.

Function that computes rk method/no plotting

import math
import matplotlib
import numpy as np
from numpy import linspace
tmax=10.0
n=2000
G=4
D=-1
m=2
t=np.linspace (0,400,n+1)
phi=10
dphi=delta=phi_dot=np.linspace(0,400,n+1)
def f(delta_dot,t):
return ((G)*(D*delta+m))
def iterate (func,phi,delta,tmax,n):
dt=tmax/(n-1)
t=0.0
for i in range(n):
phi,delta = func (phi,delta,t,dt)
t += dt
return phi
def rk_iter(phi,delta,t,dt):
k1=f(t,phi)
k2=f(t+dt*0.5,phi+k1*0.5*dt)
k3=f(t+dt*0.5,phi*k2*0.5*dt)
k4=f(t*dt,phi*k3*dt)
delta +=dt*(k1+2*k2+2*k3+k4)/6
k1=k2=k3=k4=delta=phi_dot
phi += dt*(k1+2*k2+2*k3+k4)/6
return phi,delta
runge_kutta = lambda delta, phi,tmax,n:iterate(rk_iter,delta,phi,tmax,n)
def plot_result (delta,phi,tmax,n):
dt=tmax/(n-1)
error_rk=[]
r_rk=[]
t=0.0
phi=phi_rk=phi
delta=delta_rk=delta
for i in range(n):
phi_rk,delta_rk=rk_iter(phi_rk,delta_rk,t,dt=tmax/(n-1))
t+=dt
_plot("error.png","Error","time t", "error e",error_rk)
def _plot(title,xlabel,ylabel,rk):
import matplotlib.pyplot as plt
plt.title(title)
plt.ylabel(ylabel)
plt.xlabel(xlabel)
plt.plot(rk,"r--",label="Runge-Kutta")
plt.legend(loc=4)
plt.grid(True)
plt.plot(runge_kutta,t)
print "runge_kutta=", runge_kutta(phi,delta,tmax,n)
print "tmax=",t
I have no idea how to get the function plt.show() to work. What do I have to do to open a plot window?
You haven't defined f; instead, f is being imported from matplotlib by the statement from matplotlib import *:
In [10]: import matplotlib
In [11]: matplotlib.f
Out[11]: Forward: "a"
In [12]: matplotlib.f(1,1)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-12-5843007d7dbe> in <module>()
----> 1 matplotlib.f(1,1)
TypeError: __call__() takes at most 2 arguments (3 given)
You will save yourself many headaches like this in the future if you never use the * form of the import statement in your scripts. For example, instead of from math import *, use one of these two forms:
import math
# Now refer to math.sin, math.pi, etc.
or, explicilty import only the names that you will use:
from math import sin, pi
At no point do you call the plot_result procedure. And even if you called it, you do not fill the rk and error_rk lists. You could simply use the result from the runge_kutta call,...
As commented in the other, duplicate post, you define the system equation as f(y,t) but use it as f(t,y).
There is some confusion in the usage of delta, sometimes it is the integration variable, sometimes the rk4-step update.
In the rk4-step, there are some misplaced multiplications where there should be additions. And the line
k1=k2=k3=k4=delta=phi_dot
is complete nonsense and invalidates the previous computations and makes the rk4-update in the next step meaningless.
Remove the imports of math and linspace, neither is used in the code. Move the aliasing of plt to the top and merge it with the unnecessary import of matplotlib.

ValueError loading data for scipy.odr regression

I recently tried to use scipy.odr package to conduct a regression analysis. Whenever I try to load a list of data where the elements depend on a function, a value error is raised:
ValueError: x could not be made into a suitable array
I have been using the same kind of programming to make fits using scipy's leastsq and curve_fit routines without problems.
Any idea of what to change and how to proceed? Thanks a lot...
Here I include a minimal working example:
from scipy import odr
from functools import partial
import numpy as np
import matplotlib.pyplot as plt
### choose select=0 and for myModel a list of elements is called which are a function of some parameters
### this results in error message: ValueError: x could not be made into a suitable array
### choose select=1, the function temp is exlcuded, and a fit is generated
### what do i have to do in order to run the programm successfully using select=0?
## choose here!
select=1
pfit=[1.0,1.0]
q0=[1,2,3,4,5]
q1=[3,8,10,19,27]
def temp(par, val):
p1,p2=par
temp_out = p1*val**p2
return temp_out
def fodr(a,x):
if select==0:
fitf = np.array([xi(a) for xi in x])
else:
fitf= a[0]*x**a[1]
return fitf
# define model
myModel = odr.Model(fodr)
# load data
damy=q1
if select==0:
damx=[]
for el in q0:
elm=partial(temp,val=el)
damx.append(elm)
#damx=[el(pfit) for el in damx] # check that function temp works fine
#print damx
else:
damx=q0
myData = odr.Data(damx, damy)
myOdr = odr.ODR(myData, myModel , beta0=pfit, maxit=100, ifixb=[1,1])
out = myOdr.run()
out.pprint()
Edit:
# Robert:
Thanks for your reply. I am using scipy version '0.14.0'. Using select==0 in my minimal example I get following traceback:
Traceback (most recent call last):
File "scipy-odr.py", line 48, in <module>
out = myOdr.run()
File "/home/tg/anaconda/lib/python2.7/site-packages/scipy/odr/odrpack.py", line 1061, in run
self.output = Output(odr(*args, **kwds))
ValueError: x could not be made into a suitable array
In short, your code does not work because damx is a now a list of functools.partial.
scipy.odr is a simple wrapper around Fortran Orthogonal Distance Regression (ODRPACK), both xdata and ydata have to be numerical since they will be converted to some Fortran type under the hood. It doesn't know what to do with a list of functools.partial, therefore the error.

Interpolate Question

import re
from decimal import *
import numpy
from scipy.signal import cspline1d, cspline1d_eval
import scipy.interpolate
import scipy
import math
import numpy
from scipy import interpolate
Y1 =[0.48960000000000004, 0.52736099999999997, 0.56413900000000006, 0.60200199999999993, 0.64071400000000001, 0.67668399999999995, 0.71315899999999999, 0.75050499999999998, 0.61494199999999999, 0.66246900000000009]
X1 =[0.024, 0.026000000000000002, 0.028000000000000004, 0.029999999999999999, 0.032000000000000001, 0.034000000000000002, 0.035999999999999997, 0.038000000000000006, 0.029999999999999999, 0.032500000000000001]
rep = scipy.interpolate.splrep(X1,Y1)
IN the above code i am getting and error of
Traceback (most recent call last):
File "/home/vibhor/Desktop/timing_tool/timing/interpolation_cap.py", line 64, in <module>
rep = scipy.interpolate.splrep(X1,Y1)
File "/usr/lib/python2.6/site-packages/scipy/interpolate/fitpack.py", line 418, in splrep
raise _iermess[ier][1],_iermess[ier][0]
ValueError: Error on input data
Don't know what is happening
I believe it's due to the X1 values not being ordered from smallest to largest plus also you have one duplicate x point, i.e, you need to sort the values for X1 and Y1 before you can use the splrep and remove duplicates.
splrep from the docs seem to be low level access to FITPACK libraries which expects a sorted, non-duplicate list that's why it returns an error
interpolate.interp1d might seem to work, but have you actually tried to use it to find a new point? I think you'll find an error when you call it i.e. rep(2)
The X value 0.029999999999999999 occurs twice, with two different Y coordinates. It wouldn't
surprise me if that caused a problem trying to fit a polynomial spline segment....

Categories