Situation:
I was trying to compare two signal vectors (y1 & y2 with time vectors x1 & x2) with different lengths (len(y1)=1000>len(y2)=800). For this, I followed the main piece of advice given hardly everywhere: to use interp1 or spline. In order to 'expand' y2 towards y1 in number of samples through an interpolation.
So I want:
length(y1)=length(y2_interp)
However, in these functions you have to give the points 'x' where to interpolate (xq), so I generate a vector with the resampled points I want to compute:
xq = x2(1):(length(x2))/length(x1):x2(length(x2));
y2_interp = interp1(x2,y2,xq,'spline'); % or spline method directly
RMS = rms(y1-y2_interp)
The problem:
When I resample the x vector in 'xq' variable, as the faction of lengths is not an integer it gives me not the same length for 'y2_interp' as 'y1'. I cannot round it for the same problem.
I tried interpolate using the 'resample' function:
y2_interp=resample(y2,length(y1),length(y2),n);
But I get an aliasing problem and I want to avoid filters if possible. And if n=0 (no filters) I get some sampling problems and more RMS.
The two vectors are quite long, so my misalignment is just of 2 or 3 points.
What I'm looking for:
I would like to find a way of interpolating one vector but having as a reference the length of another one, and not the points where I want to interpolate.
I hope I have explained it well... Maybe I have some misconception. It's more than i'm curious about any possible idea.
Thanks!!
The function you are looking for here is linspace
To get an evenly spaced vector xq with the same endpoints as x2 but the same length as x1:
xq = (x2(1),x2(end),length(x1));
It is not sufficient to interpolate y2 to get the right number of samples, the samples should be at locations corresponding to samples of y1.
Thus, you want to interpolate y2 at the x-coordinates where you have samples for y1, which is given by x1:
y2_interp = interp1(x2,y2,x1,'spline');
RMS = rms(y1-y2_interp)
Related
This is probably a trivial question, but I want to select a portion of a complex array in order to plot it in Matlab. My MWE is
n = 100;
t = linspace(-1,1,n);
x = rand(n,1)+1j*rand(n,1);
plot(t(45):t(55),real(x(45):x(55)),'.--')
plot(t(45):t(55),imag(x(45):x(55)),'.--')
I get an error
Error using plot
Vectors must be the same length.
because the real(x(45):x(55)) bit returns an empty matrix: Empty matrix: 1-by-0. What is the easiest way to fix this problem without creating new vectors for the real and imaginary x?
It was just a simple mistake. You were doing t(45):t(55), but t is generated by rand, so t(45) would be, say, 0.1, and t(55), 0.2, so 0.1:0.2 is only 0.1. See the problem?
Then when you did it for x, the range was different and thus the error.
What you want is t(45:55), to specify the vector positions from 45 to 55.
This is what you want:
n = 100;
t = linspace(-1,1,n);
x = rand(n,1)+1j*rand(n,1);
plot(t(45:55),real(x(45:55)),'.--')
plot(t(45:55),imag(x(45:55)),'.--')
I have 3 graphs of an IV curve (monotonic increasing function. consider a positive quadratic function in the 1st quadrant. Photo attached.) at 3 different temperatures that are not obtained linearly. That is, one is obtained at 25C, one at 125C and one at 150C.
What I want to make is an interpolated 2D array to fill in the other temperatures. My current method to build a meshgrid-type array is as follows:
H = 5;
W = 6;
[Wmat,Hmat] = meshgrid(1:W,1:H);
X = [1:W; 1:W];
Y = [ones(1,W); H*ones(1,W)];
Z = [vecsatIE25; vecsatIE125];
img = griddata(X,Y,Z,Wmat,Hmat,'linear')
This works to build a 6x6 array, which I can then index one row from, then interpolate from that 1D array.
This is really not what I want to do.
For example, the rows are # temps = 25C, 50C, 75C, 100C, 125C and 150C. So I must select a temperature of, say, 50C when my temperature is actually 57.5C. Then I can interpolate my I to get my V output. So again for example, my I is 113.2A, and I can actually interpolate a value and get a V for 113.2A.
When I take the attached photo and digitize the plot information, I get an array of points. So my goal is to input any Temperature and any current to get a voltage by interpolation. The type of interpolation is not as important, so long as it produces reasonable values - I do not want nearest neighbor interpolation, linear or something similar is preferred. If it is an option, I will try different kinds of interpolation later (cubic, linear).
I am not sure how I can accomplish this, ideally. The meshgrid array does not need to exist. I simply need the 1 value.
Thank you.
If I understand the question properly, I think what you're looking for is interp2:
Vq = interp2(X,Y,V,Xq,Yq) where Vq is the V you want, Xq and Yq are the temperature and current, and X, Y, and V are the input arrays for temperature, current, and voltage.
As an option, you can change method between 'linear', 'nearest', 'cubic', 'makima', and 'spline'
Suppose I have an MxNx3 array A, where the first two indexes refer to the coordinates a point, and the last index (the number '3') refers to the three components of a vector. e.g. A[4,7,:] = [1,2,3] means that the vector at point (7,4) is (1,2,3).
Now I need to implement the following operations:
Lx = D*ux - (x-xo)
Ly = D*uy + (y-yo)
Lz = D
where D, ux, uy, xo, yo are all constants that are already known. Lx, Ly and Lz are the three components of the vector at each point (x,y) (note: x is the column index and y is the row index respectively). The biggest problem is about the x-xo and y-yo, as x and y are different for different points. So how to carry out these operations for an MxNx3 array efficiently, using vectorized code or some other fast methods?
thanks
You could use the meshgrid function from numpy:
import numpy as np
M=10
N=10
D=1
ux=0.5
uy=0.5
xo=1
yo=1
A=np.empty((M,N,3))
x=range(M)
y=range(N)
xv, yv = np.meshgrid(x, y, sparse=False, indexing='ij')
A[:,:,0]=D*ux - (xv-xo)
A[:,:,1]=D*uy - (yv-yo)
A[:,:,2]=D
If you want to operate on the X and Y values, you should include them in the matrix (or in other matrix) instead of relying in their indexes.
For that, you could use some of range creation routines from Numpy, specially numpy.mgrid.
I'm trying to implement SLERP (described by Ken Shoemake in "Animating Rotation with Quaternion Curves)
I've read up on the topic on wikipedia (topic: quaternions, 1 and 2) and other sites and also searched stackoverflow about this problem. It seems like I understand the theory behind it, but oversee one small detail. I will use w for the scalar value of the quaternion
So initially I have two 3D vectors. Each vector has a representation in two coordinate systems (C and C'). My goal is to find a third representation of these vectors in the system "halfway" the initial two.
So what I do is I find the rotation matrix, which transform the vectors from C to C', which seems to work out quite fine.
My next step is to transform this matrix into a quaternion, which also works.
Now my issue is with the formula of slerp, which is:
slerp(q1, q2; u) = ((sin(1-u) * t)/ (sin t)) * q1 + (sin(ut)/sin t) * q2
(sorry can't upload images yet for a better representation: see source 1)
so I guess here u = 0.5, q1 is the vector I would like to rotate (with w=0) and q2 equals the quaternion I calculated previously. Theta is calculated from the dotproduct of the normalized vector and the (already) normalized quaternion.
So what I expect is that I get back a vector, rotated either from C to the third coordinate system or from C' to the third coordinate system.
My issue now is, that I don't see, how I will get a vector and not a quaternion. Meaning, how is it possible, that I will get a quaternion with (w=0), as by simply multiplying q2 with this factor won't set w to 0. Or is it something else I will get from this function?
What am I overseeing here?
Thanks for your help!
Seems like I figured it out. For someone with the same understanding problem:
slerp simply interpolates between two orientations, meaning between two actual rotations. So in my case, q1 is the quaternion corresponding to the identity matrix (so [1, 0, 0, 0]). q2 is the rotation. theta is still 0.5.
With the quaternion I get from this, I have to calculate the rotation with q^-1 v q. Where v is my vector I want to rotate. This can be calculated using the Hamilton product.
I have two lines, one straight and one curvy. Both have an arbitrary number of x and y values defining the lines - the number of x and y values are not the same for either line. I am attempting to get separate distances of points between the curved line coordinates and the straight line coordinates. You can think of discrete integration to get a better picture of what I'm talking about, something along the lines of this: http://www.scientific-solutions.ch/tech/origin/products/images/calculus_integral.gif
By adding the different distances, I would get the area. The part on which I am stuck is the actual synchronization of the points. I can simply compare the x and y values of the straight and curve coordinates every ten indices for example because the curved coordinates are time dependent (as in the points do not change at a general rate). I need a way to synchronize the actual coordinates of the two sets of points. I thought about interpolating both sets of points to a specific number of points, but again, the time dependence of the curved set of points makes that solution void.
Could someone please suggest a good way of doing this, outlining the basics? I really appreciate the help.
Code to be tried (pseudo):
xLine = [value1 value2 ...]
yLine = [value1 value2 ...]
xCurve = [value1 value2 ...]
yCurve = [value1 value2 ...]
xLineInterpolate = %interpolate of every 10 points of x until a certain value. same with yLineInterpolate, xCurveInterpolate and yCurveInterpolate.
Then, I could just take the same index from each array and do some algebra to get the distance. My worry is that my line values increase at a constant rate whereas my curve values sometimes do not change (x and y values have different rates of change) and sometimes do. Would such an interpolation method be wrong then?
If I understand correctly, you want to know the distance between a straight line and a curve. The easiest way is to perform a coordinate transformation such that the straight line is the new x-axis. In that frame, the y-values of the curved line are the distances you seek.
This coordinate transformation is equal to a rotation and a translation, as in the following:
% estimate coefficients for straight line
sol = [x1 ones(size(x1))] \ y1;
m = sol(1); %# slope
b = sol(2); %# y-offset at x=0
% shift curved line down by b
% (makes the straight line go through the origin)
y2 = y2 - b;
% rotate the curved line by -atan(m)
% (makes the straight line run parallel to the x-axis)
a = -atan(m);
R = [+cos(a) -sin(a)
+sin(a) +cos(a)];
XY = R*[x2; y2];
% the distances are then the values of y3.
x3 = XY(1,:);
y3 = XY(2,:);
You need to use interpolation. I don't see how the time-dependence is relevant here - perhaps you are thinking of fitting a straight line to both curves? That's a bad idea.
You can do a simple interpolation for any curve just by assuming that every two adjacent points are connected by a straight line. This can be shown to be a reasonable approximation for the curve.
So, let's say you are looking at (x1,y1) and (x2,y2) which are adjacent to each other and now you choose an x3 that is between x1 and x2 (x1 < x2 < x3), and want to find the y3 value.
A simple way to find y3 is the following:
p=(x3-x1)/(x2-x1)
y3=y1+p*(y2-y1)
The idea is that p shows the relative position between x1 and x2 (0.5 would be the middle, for example), and then you use p as the relative position between y1 and y2.