How to generalize 2 dimensions into n dimensions with a for loop?

Hi,
In 2D, I have a script like this:
bx = [min(x(1,:)) : ( (max(x(1,:)) - min(x(1,:))) /20 ) : max(x(1,:))];
by = [min(x(2,:)) : ( (max(x(2,:)) - min(x(2,:))) /20 ) : max(x(2,:))];
But here's the problem: x can have more than 2 rows. As a result, I want to have b's like:
bz = [min(x(3,:)) : ( (max(x(3,:)) - min(x(3,:))) /20 ) : max(x(3,:))];
ba = [min(x(4,:)) .....
....
....
So I need a for loop. I tried to do it like:
[M N] = size(x);
for s=1:1:M-1
b(s,:) = [min(x(s,:)) : (max(x(s,:))-min(x(s,:)))/20 : max(x(s,:))];
end
But I get the "Subscripted assignment dimension mismatch." error. I tried to ask this in http://www.mathworks.com/matlabcentral/answers/84556-how-can-i-create-a-specific-matrix-in-a-for-loop but since I couldn't clarify myself clearly, I didn't get the correct answer, the suggestion with doing this with linspace instead of colon didn't seem to work.
Edit: Another idea that comes to mind is this:
b = min(x(1,end)) : ((max(x(1,end))-min(x(1,end)))/20) : max(x(1,end));
but this doesn't generate a b matrix strangely. In the variable editor b seems like a 1x0 matrix with nothing inside if I do this statement instead.
The problem is not with the for loop, even if I don't do a for loop, and just write
b(1,:) = [min(x(1,:)) : ((max(x(1,:))-min(x(1,:)))/20) : max(x(1,:))];
I still get the same dimension mismatch error. So the problem has to do with the b(1,:) colon in this statement.

 Accepted Answer

i1=min(x,[],2);i2=max(x,[],2); % the limits for conciseness
n=repmat(20,size(x,1),1); % the number of points wanted
b= cell2mat(arrayfun(@linspace,i1,i2,n,'uniformoutput',0));
Original problem is that apparently linspace() is not able to handle a vector input -- I didn't look into why too much (like any).
The straightforward addressing of
b=i1:(i2-i1)/(n-1):i2;
doesn't work since only the first row is evaluated by colon().

4 Comments

Thanks, this actually works! Can I ask one more question related to this? How do I make this more general? For example, if my x variable has 3 rows, this works. But what if x is more than 3 dimensional? If I write i1=min(x,[],M) instead of i1=min(x,[],2) to make it more general where M is from [M N]=size(x), I get the following error:
??? Error using ==> arrayfun All of the input arguments must be of the same size and shape. Previous inputs had size 1001 in dimension 2. Input #4 has size 2.
So my question is: Is it possible to make this more compact (since this was my aim all along) by making it work with any row number of x?
Of course it works... :)
It's general for 2D expanding along columns as was requested.
To do in a third dimension (that is, fill in planes instead of vectors) you'll have to write a function to handle those extra dimensions as well as just computing the ranges along that dimension. OTOMH I don't see a wholly generic simple solution that I can just write down.
Oh I got it wrong, it already works for any x I write even if x has 4 rows! Thank you very much.
If it's just the size you mean by "dimensions" sure...it uses the size of the inputs.
If by 'dimensions' you do mean an added subscript can expand to higher dimensions but reordering output starts to get messy...
>> x=randi(10,3,3,3); % sample 3D dataset
>> i1=min(x,[],3);i2=max(x,[],3); % the ranges per plane
>> n=repmat(4,size(i1)); % number same size
>> arrayfun(@linspace,i1,i2,n,'uniformoutput',0)
ans =
[1x4 double] [1x4 double] [1x4 double]
[1x4 double] [1x4 double] [1x4 double]
[1x4 double] [1x4 double] [1x4 double]
>> ans{1}
ans =
5.0000 6.3333 7.6667 9.0000
>> [i1(1,1) i2(1,1)]
ans =
5 9
>>
As you see, get a cell for each position -- permute/reshape to put into a 3D array. Will get even more convoluted keeping track of dimensions as continue to go to higher dimensionality.

Sign in to comment.

More Answers (0)

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Tags

Asked:

on 12 Aug 2013

Community Treasure Hunt

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

Start Hunting!