Matrix Expansion Row Wise Using Interpolation

20 views (last 30 days)
Hey,
I have a matrix X of 6000 by 12 elements, I would like to expand the matrix X to be 12000 by 12 by interpolation between two rows. The data is from an experiment and each row is a timed measurement of 12 variables.
I have had a look at interp1 and interp2 but it is not making much sense.
The way I can do this is by using two for loops one that does go through each column the other that goes through each element within a column, compares them and inserts a value in between two existing. This seems rather complicated and I am sure there are methods in Matlab that can do exactly that.
What I ideally want is to be able to take a matrix of measurements, down sample it by removing each second row, then expand it back up using interpolation, compare the results, then repeat by removing more consecutive rows and re interpolating. Look at it as a downsample and upsample process in which I want to see at which point I am beginning to lose valuable information.
for j=1:size(X_downsampled,1)-1
error = X_downsampled(j+1,:) - X_downsampled(j,:);
error = error ./ 2;
X_Upsampled = [X_Upsampled; X_downsampled(j,:)];
X_Upsampled = [X_Upsampled; (X_downsampled(j,:)' + error')'];
if j == size(X_downsampled,1)-1
X_Upsampled = [X_Upsampled; X_downsampled(j+1,:)];
end
end
There is probably a much better and cleverer way of doing this.
Thanks a lot
  1 Comment
Stephen23
Stephen23 on 5 Jun 2015
Edited: Stephen23 on 5 Jun 2015
Concatenating arrays inside a loop is slow and inefficient, as MATLAB has to check and move the array every time it grows beyond the current allocated memory. This has been discussed many times on this forum, and you will find lots of advice online about how to avoid doing this. This is a good start:

Sign in to comment.

Answers (3)

Stephen23
Stephen23 on 5 Jun 2015
Edited: Stephen23 on 5 Jun 2015
Here is a complete working example of how you could use interp1 to interpolate between the rows of a matrix:
>> A = [1,2,3;3,6,9;5,10,15;7,14,21]
A =
1 2 3
3 6 9
5 10 15
7 14 21
>> Xi = 2*(1:size(A,1));
>> Xo = 2:Xi(end);
>> B = interp1(Xi,A,Xo)
B =
1 2 3
2 4 6
3 6 9
4 8 12
5 10 15
6 12 18
7 14 21
To select specific rows we can use basic MATLAB indexing:
>> B(1:2:end,:)
ans =
1 2 3
3 6 9
5 10 15
7 14 21
  2 Comments
SG
SG on 5 Jun 2015
Thank you, this works very well with a single step between original rows in A. I am struggling to see if this can be expanded in to more than that. Say 0.5 increments between 1 and 3. If one specifies Xo specifies missing values as such
Xo = 1.5:0.5:Xi(end);
The result is
NaN NaN NaN
1 2 3
1,5 3 4,5
2 4 6
2,5 5 7,5
3 6 9
3,5 7 10,5
4 8 12
4,5 9 13,5
5 10 15
5,5 11 16,5
6 12 18
6,5 13 19,5
7 14 21
Stephen23
Stephen23 on 5 Jun 2015
Edited: Stephen23 on 6 Jun 2015
You can change one value in two places: the 2 on the line that defines Xi, and in Xo. This sets how many lines the output matrix with have for each line of the input matrix (as a simple introduction to using interpolation):
>> N = 4;
>> Xi = N*(1:size(A,1));
>> Xo = N:Xi(end);
>> B = interp1(Xi,A,Xo)
B =
1.0000 2.0000 3.0000
1.5000 3.0000 4.5000
2.0000 4.0000 6.0000
2.5000 5.0000 7.5000
3.0000 6.0000 9.0000
3.5000 7.0000 10.5000
4.0000 8.0000 12.0000
4.5000 9.0000 13.5000
5.0000 10.0000 15.0000
5.5000 11.0000 16.5000
6.0000 12.0000 18.0000
6.5000 13.0000 19.5000
7.0000 14.0000 21.0000

Sign in to comment.


Guillaume
Guillaume on 5 Jun 2015
Edited: Guillaume on 5 Jun 2015
interp1 is the function to use (unless there's something in the signal processing toolbox).
%demo X consisting of 12 columns of sinusoidals at various frequency
timings = linspace(0, 2*pi, 6000)';
X = cell2mat(arrayfun(@(f) sin(f*timings), 1:12, 'UniformOutput', false));
figure;plot(timings, X);
newtimings = linspace(timings(1), timings(end), numel(timings)*2)'; %twice as many samples
X_upsampled = interp1(timings, X, newtimings);
figure;plot(newtimings, X_upsampled);
  2 Comments
SG
SG on 5 Jun 2015
Edited: SG on 5 Jun 2015
This look very efficient. Little difficult to get linspace to create only missing values between two adjacent rows of the original data matrix if I want to insert more than one in between but this looks excellent.
Thank you
Guillaume
Guillaume on 8 Jun 2015
I'm not sure what you mean by missing values, but to insert a number of points in between each original timings, with guarantee that all your original points are still present, you could use:
originaltimings = [0:4, 5:2:9, 11:3:20]'; %demo data
numpointstoinsert = 3;
increments = linspace(0, 1, numpointstoinsert + 1);
scaledincrements = bsxfun(@times, diff(originaltimings), increments(1:end-1));
newtimings = bsxfun(@plus, originaltimings(1:end-1), scaledincrements)';
newtimings = [newtimings(:); originaltimings(end)]

Sign in to comment.


Antonio Jossimar Lazos Toledo
this help me a lot, but how i can use this to interpolate columns? can anyone help me

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!