Use interp1 to interpolate a matrix row-wise
78 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I am currently trying to expand some code to work with matrices and vectors instead of vectors and scalars. So the same calculations are to be done row-wise for n number of rows. How do I get interp1 to do this?
before I used something like this:
new_c = interp1(error,c,0,'linear',extrap')
It is used to find the value of c when an error approaches zero. Now I tried to just enter the matrices where each row is the same as the vector I used before and I get the error message "Index exceeds matrix dimensions".
I tried changing the zero to a vector of zeros but that did not help. I know I could solve it with a for-loop where I evaluate each row individually but I would prefer not to since I assume the matrix operation would save a lot of time.
0 comentarios
Respuesta aceptada
the cyclist
el 19 de Feb. de 2013
Here is an example adapted from the online documentation ("doc interp1"):
x = 0:10;
y1 = sin(x);
y2 = 2*sin(x);
y = [y1;y2]';
xi = 0:.25:10;
yi = interp1(x,y,xi);
figure
plot(x,y,'o',xi,yi)
4 comentarios
the cyclist
el 20 de Feb. de 2013
The documentation for interp1() is explicit in that x [the first input to interp1()] has to be a vector. I assumed that you had the same x values for each row of your y matrix, and that is what my example does.
If you do not have that, I'm not sure you can do this other than via a for loop. (A quick web search on the keywords suggests that it is not possible.)
The answer from Jan in this thread has a faster interpolation function than interp1(), if that helps: http://www.mathworks.com/matlabcentral/answers/44346
Más respuestas (5)
Jan
el 20 de Feb. de 2013
Editada: Jan
el 20 de Feb. de 2013
INTERP1 is slow and calling it repeatedly in a loop has a large overhead. But a linear interpolation can be implemented cheaper:
function Yi = myLinearInterp(X, Y, Xi)
% X and Xi are column vectros, Y a matrix with data along the columns
[dummy, Bin] = histc(Xi, X); %#ok<ASGLU>
H = diff(X); % Original step size
% Extra treatment if last element is on the boundary:
sizeY = size(Y);
if Bin(length(Bin)) >= sizeY(1)
Bin(length(Bin)) = sizeY(1) - 1;
end
Xj = Bin + (Xi - X(Bin)) ./ H(Bin);
% Yi = ScaleTime(Y, Xj); % FASTER MEX CALL HERE
% return;
% Interpolation parameters:
Sj = Xj - floor(Xj);
Xj = floor(Xj);
% Shift frames on boundary:
edge = (Xj == sizeY(1));
Xj(edge) = Xj(edge) - 1;
Sj(edge) = 1; % Was: Sj(d) + 1;
% Now interpolate:
if sizeY(2) > 1
Sj = Sj(:, ones(1, sizeY(2))); % Expand Sj
end
Yi = Y(Xj, :) .* (1 - Sj) + Y(Xj + 1, :) .* Sj;
The M-version is faster than INTERP1 already, but for the faster MEX interpolation: FEX: ScaleTime. Then the above code is 10 times faster than INTERP1.
0 comentarios
Thorsten
el 20 de Feb. de 2013
for i = 1:size(E, 1)
new_c(i) = interp1(E(i, :), C(i, :), 0, 'linear', 'extrap');
end
2 comentarios
Sean de Wolski
el 20 de Feb. de 2013
y = toeplitz(1:10);
interp1((1:10).',y,(1:0.5:10))
2 comentarios
Matt J
el 20 de Feb. de 2013
Editada: Matt J
el 20 de Feb. de 2013
I assume 'error' is always non-negative? If so, you're really just trying to linearly extrapolate the first 2 data points in each row, which can be done entirely without for-loops and also without INTERP1,
e1=error(:,1);
c1=c(:,1);
e2=error(:,2);
c2=c(:,2);
slopes=(c2-c1)./(e2-e1);
new_c = c1-slopes.*e1;
1 comentario
Matt J
el 20 de Feb. de 2013
Note that new_c is just the y-intercepts of the line defined by the first 2 points.
Ver también
Categorías
Más información sobre Linear Algebra en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!