Include sigma in polyfit- python - python

I have 3 arrays. One array contains x-values, the second array contains y-values, and the third array contains values for sigma (errors).
How can I use the numpy.polyfit function to fit for x, y, and sigma? I have figured out how to fit the x and y values but not sigma.
import numpy as np
p = np.polyfit(x,y,2)
xp = np.linspace(0.4,1,40)
y = np.polyval(p,xp)

Use the w parameter as described here
p = np.polyfit(x,y,2,w=1/sigma)

Related

Integrate a function depending on two arrays

Initially, I have two arrays that correspond to the values of x and y in a function, but I don't know that function, I just know that the values of y depend on x. Then, I calculate a function that depends on both arrays.
I need to calculate in python the integral of that last function to obtain the total area under the curve between the first value of x and the last. Any idea of how to do that?
x = [array]
y(x) = [array]
a = 2.839*10**25
b = 4*math.pi
alpha = 0.5
z = 0.003642
def L(x,y,a,b,alpha,z):
return x*((y*b*a)/(1+z)**(1+alpha))
Your function is a function of x (in that given a value of x it spits out a value), so first you should repackage it as such (introduce a function yy which, given x, produces the requisite y), then write LL(x) = L(x, yy[x]), then use scipy.integrate to integrate it.

Python: How to resample a 3d curve given by points as spline in equal distances?

Allow me to separate this to increasing difficulty questions:
1.
I have some 1d curve, given as a (n,) point array.
I would like to have it re-sampled k times, and have the results come from a cubic spline that passes through all points.
This can be done with interp1d
2.
The curve is given at non-same-interval samples as an array of shape (n, 2) where (:, 0) represents the sample time, and (:, 1) represent the sample values.
I want to re-sample the curve at k same-time-intervals.
How can this be done?
I thought i could do t_sampler = interp1d(np.arange(0,k),arr[:, 0]) for the time, then interp1d(t_sampler(np.arange(0,k)), arr[:, 1])
Am I missing something with this?
3.
How can I re-sample the curve at equal distance intervals? (question 2 was equal time intervals)
4.
What if the curve is 3d given by an array of shape (n, 4), where (:,0) are the (non uniform) sampling times, and the rest are the locations sampled?
Sorry for many-questionsin-single-question, they seemed too similar to open a new question for every one.
Partial answer; for 1 and 2 I would do this:
from scipy.interpolate import interp1d
import numpy as np
# dummy data
x = np.arange(-100,100,10)
y = x**2 + np.random.normal(0,1, len(x))
# interpolate:
f = interp1d(x,y, kind='cubic')
# resample at k intervals, with k = 100:
k = 100
# generate x axis:
xnew = np.linspace(np.min(x), np.max(x), k)
# call f on xnew to sample y values:
ynew = f(xnew)
plt.scatter(x,y)
plt.plot(xnew, ynew)

Any differences in 3d interpolation between MATLAB and Numpy/Scipy?

I'm a MATLAB user and I'm trying to translate some code in Python as an assignment. Since I noticed some differences between the two languages in 3d interpolation results from my original code, I am trying to address the issue by analysing a simple example.
I set a 2x2x2 matrix (named blocc below) with some values, and its coordinates in three vectors (X,Y,Z). Given a query point, I use 3D-linear interpolation to find the intepolated value. Again,I get different results in MATLAB and Python (code below).
Python
import numpy as np
import scipy.interpolate as si
X,Y,Z =(np.array([1, 2]),np.array([1, 2]),np.array([1, 2]))
a = np.ones((2,2,1))
b = np.ones((2,2,1))*2
blocc = np.concatenate((a,b),axis=2) # Matrix with values
blocc[1,0,0]=7
blocc[0,1,1]=7
qp = np.array([2,1.5,1.5]) #My query point
value=si.interpn((X,Y,Z),blocc,qp,'linear')
print(value)
Here I get value=3
MATLAB
blocc = zeros(2,2,2);
blocc(:,:,1) = ones(2,2);
blocc(:,:,2) = ones(2,2)*2;
blocc(2,1,1)=7;
blocc(1,2,2)=7;
X=[1,2];
Y=[1,2];
Z=[1,2];
qp = [2 1.5 1.5];
value=interp3(X,Y,Z,blocc,qp(1),qp(2),qp(3),'linear')
And here value=2.75
I can't understand why: I think there is something I don't get about how does interpolation and/or matrix indexing work in Python. Can you please make it clear for me? Thanks!
Apparently, for MATLAB when X, Y and Z are vectors, then it considers that the order of the dimensions in the values array is (Y, X, Z). From the documentation:
V — Sample values
array
Sample values, specified as a real or complex array. The size requirements for V depend on the size of X, Y, and Z:
If X, Y, and Z are arrays representing a full grid (in meshgrid format), then the size of V matches the size of X, Y, or Z .
If X, Y, and Z are grid vectors, then size(V) = [length(Y) length(X) length(Z)].
If V contains complex numbers, then interp3 interpolates the real and imaginary parts separately.
Example: rand(10,10,10)
Data Types: single | double
Complex Number Support: Yes
This means that, to get the same result in Python, you just need to swap the first and second values in the query:
qp = np.array([1.5, 2, 1.5])
f = si.interpn((X, Y, Z), blocc, qp, 'linear')
print(f)
# [2.75]

Extrapolating with a single data point

Is there an function for extrapolating in numpy?
I tried using the interp but of course that interpolates between the range of my values and not outside the range of values.
So for example i have my x-values between 1 and 8, inclusive, and for each x-value, i have its corresponding y-value and I want to find the y-value when my x-value is 0
import numpy as np
x = np.arange(1,8,1)
y = np.array((10,20,30,40,50,60,70))
np.interp(0,x,y)
Is there a function like the interp??
scipy.interpolate.interp1d allows extrapolation.
import numpy as np
from scipy import interpolate
x = np.arange(1,8,1)
y = np.array((10,20,30,40,50,60,70))
interpolate.interp1d(x, y, fill_value='extrapolate')
hope this answers your question

Interpolation without specifying indices in Python

I have two arrays of the same length, say array x and array y. I want to find the value of y corresponding to x=0.56. This is not a value present in array x.
I would like python to find by itself the closest value larger than 0.56 (and its corresponding y value) and the closest value smaller than 0.56 (and its corresponding y value). Then simply interpolate to find the value of y when x 0.56.
This is easily done when I find the indices of the two x values and corresponding y values by myself and input them into Python (see following bit of code).
But is there any way for python to find the indices by itself?
#interpolation:
def effective_height(h1,h2,g1,g2):
return (h1 + (((0.56-g1)/(g2-g1))*(h2-h1)))
eff_alt1 = effective_height(x[12],x[13],y[12],y[13])
In this bit of code, I had to find the indices [12] and [13] corresponding to the closest smaller value to 0.56 and the closest larger value to 0.56.
Now I am looking for a similar technique where I would just tell python to interpolate between the two values of x for x=0.56 and print the corresponding value of y when x=0.56.
I have looked at scipy's interpolate but don't think it would help in this case, although further clarification on how I can use it in my case would be helpful too.
Does Numpy interp do what you want?:
import numpy as np
x = [0,1,2]
y = [2,3,4]
np.interp(0.56, x, y)
Out[81]: 2.56
Given your two arrays, x and y, you can do something like the following using SciPy.
from scipy.interpolate import InterpolatedUnivariateSpline
spline = InterpolatedUnivariateSpline(x, y, k=5)
spline(0.56)
The keyword k must be between 1 and 5, and controls the degree of the spline.
Example:
>>> x = range(10)
>>> y = range(0, 100, 10)
>>> spline = InterpolatedUnivariateSpline(x, y, k=5)
>>> spline(0.56)
array(5.6000000000000017)

Categories

Resources