Niels Møller
Niels Møller

Reputation: 203

Save to array in for loop, with steps - Matlab

Okay, this is a bit tricky to explain, but I have a long .txt file with data (only one column). It could look like this:

data=[18
32
50
3
19
31
48
2
18
33
51
4]

Now, every fourth value (e.g. 18, 19, 18) represents the same physical quantity, just from different measurements. Now, I want Matlab to take every fourth value and put it into an array X=[18 19 18], and like wise for the other quantities.

My solution so far looks like this:

for i=1:3;
     for j=1:4:12;
        X(i)=data(j);
     end
end

... in this example, because there are three of each quantity (therefore i=1:3), and there are 12 datapoints in total (therefore j=1:4:12, in steps of 4). data is simply the loaded list of datapoints (this works fine, I can test it in command window - e.g. data(2)=32).

My problem, doing this, is, that my array turns out like X=[18 18 18] - i.e. only the last iteration is put into the array

Of course, in the end, I would like to do it for all points; saving the 2nd, 6th, and 10th datapoint into Y and so on. But this is simply having more for-loops I guess.

I hope this question makes sense. I guess it is an easy problem to solve.

Upvotes: 1

Views: 308

Answers (3)

Dan
Dan

Reputation: 45741

You can reshape the data and then either split it up into different variables or just know that each column is a different variable (I'm now assuming each measurement occurs the same number of times i.e. length(data) is a multiple of 4)

data = reshape(data, 4, []).';

So now if you want

X = data(:,1);
Y = data(:,2);
%// etc...

But also you could just leave it as data all in one variable since calling data(:,1) is hardly more hassle than X.


Now, you should NOT use for-loops for this, but I'm gong to address what's wrong with your loops and how to solve this using loops purely as an explanation of the logic. You have a nested loop:

for i=1:3;
     for j=1:4:12;
        X(i)=data(j);
     end
end

Now what you were hoping was that i and j would each move one iteration forward together. So when i==1 then j==1, when i==2 then j==5 etc but this is not what happens at all. To best understand what's going on I suggest you print out the variables at each iteration:

disp(sprintf('i:  \tj:'));
for i=1:3;
     for j=1:4:12;
        disp(sprintf('   %d\t   %d',i,j));
     end
end

This prints out

i:      j:
   1       1
   1       5
   1       9
   2       1
   2       5
   2       9
   3       1
   3       5
   3       9

What you wanted was

disp(sprintf('i:  \tj:'));
for i=1:3;
     disp(sprintf('   %d\t   %d',i,4*i-3));
end

which outputs:

i:      j:
   1       1
   2       5
   3       9

applied to your problem:

%// preallocation!
X = zeros(size(data,1)/4, 1)
for i=1:3
    X(i)=data(i*4 - 3);
end

Or alternatively you can keep a separate count of either i or j:

%// preallocation!
X = zeros(size(data,1)/4, 1)
i = 1;
for j=1:4:end;
    X(i)=data(j);
    i = i+1;
end

Upvotes: 3

PetrH
PetrH

Reputation: 730

Just for completeness your own solution should have read

 i = 0;
 for j=1:4:12;
    i = i+1;
    X(i)=data(j);
 end

Of course am304's answer is a better way of doing it.

Upvotes: 2

am304
am304

Reputation: 13876

Why don't you just do?

>> X = data(1:4:end)
X =

   18
   19
   18

>> Y = data(2:4:end)
Y =

   32
   31
   33

Upvotes: 4

Related Questions