mapping of matrices with different size
1 visualizzazione (ultimi 30 giorni)
Mostra commenti meno recenti
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 Commento
Stephen23
il 21 Gen 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 .
Risposta accettata
Stephen23
il 21 Gen 2015
Modificato: Stephen23
il 23 Gen 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).
Più risposte (1)
Thorsten
il 21 Gen 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 Commenti
Stephen23
il 21 Gen 2015
Modificato: Stephen23
il 21 Gen 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.
Vedere anche
Categorie
Scopri di più su Logical in Help Center e File Exchange
Prodotti
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!