mapping of matrices with different size

1 view (last 30 days)
i have to map the values from a matrix to another one based on the value in the first column: i used the following code
data = [0 1;0.1 2;0.2 3;0.3 4; 0.6 5 ;0.7 6;0.8 7;1 8]
[m,n]=size(data);
StopTime=1;
SampleTime=0.1;
TimeStep=(StopTime/SampleTime)+1;
initial=0
time=zeros(TimeStep,n)
for i=1:TimeStep
time(i,1)=initial;
initial=initial+SampleTime;
end
c=0;
for j=1:TimeStep
for i=1:m
if (data(i,1)==time(j,1))
time(j,2)=data(i,2);
end
end
end
the expected result is
[0 1;
0.1 2;
0.2 3;
0.3 4;
0.4 0;
0.5 0;
0.6 5;
0.7 6;
0.8 7;
0.9 0;
1 8]
but the obtained result is:
[0 1;
0.1 2;
0.2 3;
0.3 0;
0.4 0;
0.5 0;
0.6 5;
0.7 6;
0.8 0;
0.9 0;
1 0]
please hel p me to fix this issue
  1 Comment
Stephen23
Stephen23 on 21 Jan 2015
Note that you should not use i or j for the names of your loop variables, as these are the names of the inbuilt imaginary unit .

Sign in to comment.

Accepted Answer

Stephen23
Stephen23 on 21 Jan 2015
Edited: Stephen23 on 23 Jan 2015
There are multiple issues with your code:
  • Using equivalence logical tests on floating point values. It is important to realize that what looks like that same number may have a slightly different binary value, and so logical tests can give erroneous results. This often happens when you calculate the two values in different ways: for example 0.1 does not equal 0.01/0.1 (try it!).
  • Using names of inbuilt functions or values as variable names: i and j.
  • Using a loop to create a vector of values, by adding one fractional value to the last at each iteration. Doing this compounds the precision errors resulting from the binary approximation of the fractional values that you believe you are adding. It is very poor coding (in any language, not just MATLAB).
The nested for loops are not a good solution to this problem: using indexing would be much neater and faster. Learn to use MATLAB indexing and inbuilt functions such as linspace for generating a vector of equally spaced fractional values. Here is one possibility that matches your desired output:
>> data = [0,1; 0.1,2; 0.2,3; 0.3,4; 0.6,5; 0.7,6; 0.8,7; 1,8];
>> time = linspace(0,1,11);
>> idx = any(1e-10 > abs(bsxfun(@minus,time,data(:,1))), 1);
>> time(2,idx) = data(:,2);
>> disp(time.')
0.0 1
0.1 2
0.2 3
0.3 4
0.4 0
0.5 0
0.6 5
0.7 6
0.8 7
0.9 0
1.0 8
Notice how I do not test for equivalency, but instead check that the difference between the values is greater than some small value (in this example, 1e-10).
  1 Comment
Rani V.S
Rani V.S on 22 Jan 2015
Thanks for helping me. Your code failed in the case of unsorted data. So i have sorted the data according to the first column using
sortrows(data,1)
After this modification the Script handles all the data combinations..

Sign in to comment.

More Answers (1)

Thorsten
Thorsten on 21 Jan 2015
Stephen made some remarks that are useful in general, but in your case you can get along with
newdata(:,1) = 0:0.1:1; % first column
newdata(10*data(:,1)+1, 2) = data(:,2); % second column
The idea is to use the first column of data as an index. Because the values run from 0 to 1 in steps of 0.1, you can convert it to a valid Matlab index by multiplication with 10 and adding 1 (Matlab's indices always start with 1). Missing values in the index (such as 4, 5 and 9) are automatically set to zero by Matlab.
  2 Comments
Stephen23
Stephen23 on 21 Jan 2015
Edited: Stephen23 on 21 Jan 2015
Although this then mixes the data and indexing, by making the indexing a by-product of the data itself. It will fail, for example, with negative data values. Keeping the indexing independent from the data results in more robust and versatile code.
Rani V.S
Rani V.S on 22 Jan 2015
this method works ony for the samle time of 0.1. if the sample time is different it will fail

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!