I can't seem to figure out how to implement the Vandermonde Matrix into Multivariate Interpolation. I am able to get the actual matrix, but I don't understand how to get the values (array) c00,c01,c02... . I know that c = V/z, but I feel like I am missing something (perhaps, not division?). I also know that I need to somehow set up a system of equations (the columns of V are each cij).
How do you do this in python?
Here is what I have so far:
import numpy as np
x = [1, 1, 1, 2, 2, 2, 3, 3, 3]
y = [1, 2, 3, 1, 2, 3, 1, 2, 3]
z = [3.2, 4.4, 6.5, 2.5, 4.7, 5.8, 5.1, 3.6, 2.9]
numpy.polynomial.polynomial.polyvander2d(x, y, [2,2])
>>>array([[ 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 2., 4., 1., 2., 4., 1., 2., 4.],
[ 1., 3., 9., 1., 3., 9., 1., 3., 9.],
[ 1., 1., 1., 2., 2., 2., 4., 4., 4.],
[ 1., 2., 4., 2., 4., 8., 4., 8., 16.],
[ 1., 3., 9., 2., 6., 18., 4., 12., 36.],
[ 1., 1., 1., 3., 3., 3., 9., 9., 9.],
[ 1., 2., 4., 3., 6., 12., 9., 18., 36.],
[ 1., 3., 9., 3., 9., 27., 9., 27., 81.]])
np.dot(V, c.flat)and numpy.polynomial.polynomial.polyval2d(x, y, c) I think have to be incorporated into this somehow, but I don't know what to do. Please help!
I am supposed to output:
c = V \ z
c =
0.97500
-5.27500
5.95000
-3.92500
19.82500
-21.55000
3.40000
-14.70000
18.50000
Here is the site where I got this example (They used MatLab):
https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/05Interpolation/multi/
Hope this helps!
Given positions x and y:
x = [1, 1, 1, 2, 2, 2, 3, 3, 3]
y = [1, 2, 3, 1, 2, 3, 1, 2, 3]
and function values z:
z = [3.2, 4.4, 6.5, 2.5, 4.7, 5.8, 5.1, 3.6, 2.9]
V will be the Vandermonde matrix:
V = numpy.polynomial.polynomial.polyvander2d(x, y, [2,2])
V = array([[ 1., 1., 1., 1., 1., 1., 1., 1., 1.],
[ 1., 2., 4., 1., 2., 4., 1., 2., 4.],
[ 1., 3., 9., 1., 3., 9., 1., 3., 9.],
[ 1., 1., 1., 2., 2., 2., 4., 4., 4.],
[ 1., 2., 4., 2., 4., 8., 4., 8., 16.],
[ 1., 3., 9., 2., 6., 18., 4., 12., 36.],
[ 1., 1., 1., 3., 3., 3., 9., 9., 9.],
[ 1., 2., 4., 3., 6., 12., 9., 18., 36.],
[ 1., 3., 9., 3., 9., 27., 9., 27., 81.]])
Each row:
a = x[i]
b = y[i]
V[i,:] = [ 1, b, b², a, a*b, a*b², a², a²b, a²b²]
A linear interpolation aims to solve:
$$z = V \cdot c$$
therefore we need to solve:
$$c = V^{-1} z$$
c = np.linalg.solve(V, z)
c now holds the coefficients in the same orders as the Vandermonde matrix does.
You can evaluate it manually:
def poly_eval(x, y, z):
return z[0] + z[1]*y + z[2]*np.power(y,2) + z[3]*x + z[4]*x*y + z[5]*x*np.power(y,2) + z[6]*np.power(x,2) + z[7]*np.power(x,2)*y + z[8]*np.power(x,2)*np.power(y,2)
or use
np.polynomial.polynomial.polyval2d([1,2], [3,4], c)
Out[22]: array([-65.5, -88.4])
Related
I am having my head confused around computing the median frequency from the fft I computed over my data, using the following function:
import numpy as np
from scipy.fft import fft, fftfreq
def fft_transfrom(data):
# data has a 4D shape
fourier = fft(data, axis=2)
mag = np.round(np.abs(fourier), 0)
fs = 5 # sample size
freq = fftfreq(fs, d=1/fs)
return mag, freq
And this sample data:
A = np.array([
[[[0, 1, 2, 3],
[3, 0, 1, 2],
[2, 3, 0, 1],
[1, 3, 2, 1],
[1, 2, 3, 0]]],
[[[9, 8, 7, 6],
[5, 4, 3, 2],
[0, 9, 8, 3],
[1, 9, 2, 3],
[1, 0, -1, 2]]],
[[[0, 7, 1, 2],
[1, 2, 1, 0],
[0, 2, 0, 7],
[-1, 3, 0, 1],
[1, 0, 1, 0]]]
])
So I get the magnitude and frequencies like so:
magnitude, frequency = fft_transfrom(A)
magnitude
array([[[[ 7., 9., 8., 7.],
[ 3., 4., 3., 3.],
[ 2., 2., 1., 2.],
[ 2., 2., 1., 2.],
[ 3., 4., 3., 3.]]],
[[[16., 30., 19., 16.],
[11., 7., 7., 2.],
[ 6., 11., 9., 5.],
[ 6., 11., 9., 5.],
[11., 7., 7., 2.]]],
[[[ 1., 14., 3., 10.],
[ 2., 4., 2., 6.],
[ 2., 7., 1., 7.],
[ 2., 7., 1., 7.],
[ 2., 4., 2., 6.]]]])
And sorted like so:
sorted_magnitude = np.sort(magnitude, axis=2)
sorted_magnitude
array([[[[ 2., 2., 1., 2.],
[ 2., 2., 1., 2.],
[ 3., 4., 3., 3.],
[ 3., 4., 3., 3.],
[ 7., 9., 8., 7.]]],
[[[ 6., 7., 7., 2.],
[ 6., 7., 7., 2.],
[11., 11., 9., 5.],
[11., 11., 9., 5.],
[16., 30., 19., 16.]]],
[[[ 1., 4., 1., 6.],
[ 2., 4., 1., 6.],
[ 2., 7., 2., 7.],
[ 2., 7., 2., 7.],
[ 2., 14., 3., 10.]]]])
Now that each array column (instance column) are sorted.
But I have problem finding the frequency that corresponds to the middle of the sorted power spectrum
median_frequency = frequency[np.where(magnitude ==
sorted_magnitude[int(len(magnitude)/2)])]
IndexError: too many indices for array: array is 1-dimensional, but 4 were indexed
How do I get the frequencies of the middle magnitude in each array.
I can directly get the median of each array in magnitude using:
np.median(magnitude, axis=2)
array([[[ 3., 4., 3., 3.]],
[[11., 11., 9., 5.]],
[[ 2., 7., 2., 7.]]])
How then do I get the frequency corresponding to the median power spectrum?
I'm trying to do multiplication of all the combination of elements in a certain dimension.
For example,
using for loops it would be
for a,i in enumerate(A):
for b,j in enumerate(B):
c[i][j] = a[1]*b[0]
not using for loop would be
A[:,None,1]*B[:,0]
this worked fine for 2-dimensions(A.shape=(4,2),B.shape=(4,2)).
However, When I am expanding above procedures to 3-dimensions(A.shape=(2,4,2),B.shape=(2,4,2)).
I tried with
A[:,:,1]*B[:,:,None,0]
but gives me an error.
How can I do this without using for loops???
For 2-dimensional tensors this is what I get
a = torch.FloatTensor([[0,1],[0,2],[0,3],[0,4]])
b = torch.FloatTensor([[1,0],[2,0],[3,0],[4,0]])
c = a[:,None,0] * b[:,1]
print(c)
tensor([[ 1., 2., 3., 4.],
[ 2., 4., 6., 8.],
[ 3., 6., 9., 12.],
[ 4., 8., 12., 16.]])
but in the case of
A = torch.cat([a.unsqueeze(0),a.unsqueeze(0)],dim=0)
B = torch.cat([b.unsqueeze(0),b.unsqueeze(0)],dim=0)
C = A[:,:,None,0] * B[:,:,1] << RuntimeError
RuntimeError: The size of tensor a (4) must match the size of tensor b (2) at non-singleton dimension 1
what I want is
tensor([[[ 1., 2., 3., 4.],
[ 2., 4., 6., 8.],
[ 3., 6., 9., 12.],
[ 4., 8., 12., 16.]],
[[ 1., 2., 3., 4.],
[ 2., 4., 6., 8.],
[ 3., 6., 9., 12.],
[ 4., 8., 12., 16.]]])
I cannot think of a way to do this without using for loop in dimension 0.
I have two numpy array like this,
this is the first one, called "pred_test"
array([2., 2., 2., 2., 2., 1., 2., 2., 2., 3., 2., 2., 3., 2., 2., 2., 2.,
2., 3., 3.], dtype=float32)
and this is the second one, called "pred_train"
array([13., 11., 9., 5., 5., 3., 2., 1., 1., 1., 4., 5., 11.,
9., 9., 4., 4., 3., 2., 1., 1., 1., 2., 1., 11., 12.,
8., 3., 3., 4., 4., 2., 2., 1., 2., 2., 4., 3., 2.,
1., 1., 1., 1., 1., 2., 1., 1., 2., 3., 2., 3., 2.,
2., 2., 2., 2., 2., 1., 2., 2., 10., 2., 2., 2., 2.,
2., 2., 3., 3., 2., 2., 3., 4., 2., 3., 3.],
dtype=float32)
How can i combine the two array to look like pred_train + pred test, something like this..
[2., 2., 2., 2., 2., 1., 2., 2., 2., 3., 2., 2., 3., 2., 2., 2., 2., 2., 3., 3.,
13., 11., 9., 5., 5., 3., 2., 1., 1., 1., 4., 5., 11.,
9., 9., 4., 4., 3., 2., 1., 1., 1., 2., 1., 11., 12.,
8., 3., 3., 4., 4., 2., 2., 1., 2., 2., 4., 3., 2.,
1., 1., 1., 1., 1., 2., 1., 1., 2., 3., 2., 3., 2.,
2., 2., 2., 2., 2., 1., 2., 2., 10., 2., 2., 2., 2.,
2., 2., 3., 3., 2., 2., 3., 4., 2., 3., 3.]
Can someone help me? Thank you..
Use numpy.concatenate((pred_test, pred_train))
You can go with:
np.append(pred_test, pred_train)
Suppose we create an numpy array like this:
x = np.linspace(1,5,5).reshape(-1,1)
which results in this:
array([[ 1.],
[ 2.],
[ 3.],
[ 4.],
[ 5.]])
now we add the transpose of this array to it:
x + x.T
which results in this:
array([[ 2., 3., 4., 5., 6.],
[ 3., 4., 5., 6., 7.],
[ 4., 5., 6., 7., 8.],
[ 5., 6., 7., 8., 9.],
[ 6., 7., 8., 9., 10.]])
I don't understand this because the two arrays have different dimensions (5x1 and 1x5) and I learned in linear algebra that we can only sum up matrices when they have the same dimension.
Edit: OK thanks, got it
Here, we have
x = array([[ 1.],[ 2.],[ 3.],[ 4.],[ 5.]])
x.T = array([[ 1., 2., 3., 4., 5.]])
Now you are trying to add two matrices of different dimensions (1 X 5) and (5 X 1).
The way numpy handles this is by copying elements in each row of 1st matrix across its columns to match a number of columns of 2nd matrix and copying elements in each column of 2nd matrix across its rows to match no. of rows of 1st matrix. This gives you 2 5 X 5 matrix which can be added together.
The element wise addition is done as
array([[ 1., 1., 1., 1., 1.],[ 2., 2., 2., 2., 2.,],[ 3., 3., 3., 3., 3.,],[4., 4., 4., 4., 4.],[ 5., 5., 5., 5., 5.,]]) + array([[ 1., 2., 3., 4., 5.],[ 1., 2., 3., 4., 5.],[ 1., 2., 3., 4., 5.],[ 1., 2., 3., 4., 5.],[ 1., 2., 3., 4., 5.]])
which produces the result
array([[ 2., 3., 4., 5., 6.],
[ 3., 4., 5., 6., 7.],
[ 4., 5., 6., 7., 8.],
[ 5., 6., 7., 8., 9.],
[ 6., 7., 8., 9., 10.]])
I would like to get several values whose i have the coordinates.
My coordinates are given by "Coord" (shape : (3, 3, 2, 3) : X and Y during 3 times and with 2 because of 2 coordinates) and my values are given by "Values" (shape : (3, 3, 3) for 3 times)
In other words, i would like to concatenate values in time with "slices" for each positions...
I dont know how to undertake that...Here there is a little part of the arrays.
import numpy as np
Coord = np.array([[[[ 4., 6., 10.],
[ 1., 3., 7.]],
[[ 3., 5., 9.],
[ 1., 3., 7.]],
[[ 2., 4., 8.],
[ 1., 3., 7.]]],
[[[ 4., 6., 10.],
[ 2., 4., 8.]],
[[ 3., 5., 9.],
[ 2., 4., 8.]],
[[ 2., 4., 8.],
[ 2., 4., 8.]]],
[[[ 4., 6., 10.],
[ 3., 5., 9.]],
[[ 3., 5., 9.],
[ 3., 5., 9.]],
[[ 2., 4., 8.],
[ 3., 5., 9.]]]])
Values = np.array([[[-4.24045246, 0.97551048, -5.78904502],
[-3.24218504, 0.9771782 , -4.79103141],
[-2.24390519, 0.97882129, -3.79298771]],
[[-4.24087775, 1.97719843, -5.79065966],
[-3.24261128, 1.97886271, -4.7926441 ],
[-2.24433235, 1.98050192, -3.79459845]],
[[-4.24129055, 2.97886284, -5.79224713],
[-3.24302502, 2.98052345, -4.79422942],
[-2.24474697, 2.98215901, -3.79618161]]])
EDIT LATER
I try in case of a simplified problem (without time first). I have used a "for loop" but
somes errors seems subsist...do you think it s the best way to treat this problem? because my arrays are important... 400x300x100
Coord3 = np.array([[[ 2, 2.],
[ 0., 1.],
[ 0., 2.]],
[[ 1., 0.],
[ 2., 1.],
[ 1., 2.]],
[[ 2., 0.],
[ 1., 1.],
[ 0., 0.]]])
Coord3 = Coord3.astype(int)
Values2 = np.array([[0., 1., 2.],
[3., 4., 5.],
[6., 7., 8.]])
b = np.zeros((3,3))
for i in range(Values2.shape[0]):
for j in range(Values2.shape[1]):
b[Coord3[i,j,0], Coord3[i,j,1]] = Values2[i,j]
b
Your second example is relatively easy to do with fancy indexing:
b = np.zeros((3,3), values2.dtype)
b[coord3[..., 0], coord3[..., 1]] = values2
The origial problem is a bit harder to do, but I think this takes care of it:
coord = coord.astype(int)
x_size = coord[..., 0, :].max() + 1
y_size = coord[..., 1, :].max() + 1
# x_size, y_size = coord.max(axis=(0, 1, 3)) + 1
nt = coord.shape[3]
b = np.zeros((x_size, y_size, nt), values.dtype)
b[coord[..., 0, :], coord[..., 1, :], np.arange(nt)] = values