Last beginner question of the day...Working in matlab. Suppose one has matrices A1,...,An. How can one call do something to the Ai-th matrix on the i-th iteration of a loop? Actually I would like to concatenate all the matrices except the Ai-th one, but I can probably figure that out.
My solution is to do the following:
Instead of creating matrices in the way I did above, I will create an array of matrices.
for i=1:n
A{i}= matrix with nrows:ncolumns;
end
Then you call the matrix in the obvious way.
Related
I am working on matlab with a matrix. I would like to reproduce this matrix and apply sum for elements in rows.
I have two vectors defined by this code:
unitsvector=1:5;
reordervector=1:3;
Then, I create an empty matrix to store the values:
resultvec=zeros(size(unitsvector,2)*size(reordervector,2),3);
Finally, here is the loop I use but it is not working:
for a=1:length(resultvec)
for b=reordervector
for c=unitsvector
resultvec(a,1)=b;
resultvec(a,2)=c;
resultvec(a,3)=b+c;
end
end
end
How could I reproduce this matrix in matlab. Thanks for your help.
You can use meshgrid for this without a for loop.
[a,b] = meshgrid(1:5,1:3);
M = [a(:) b(:)];
M(:,3) = sum(M,2); % Create third column by summing first two
Why are you looping at all? sum actually has vector support; a simple resultvec = [a(:,1),a(:,2),sum(a,2)] would work.
As to your code: of course it doesn't work. What do you expect to be the contents of a? You create a as a loop index, which runs over the range 1:length(resultvec). Ergo, within each loop iteration a is a scalar. You try to call it like it is a three-element vector. Nor do you define b and c. This might be possible in R, judging where you're coming from, but not in MATLAB.
i have a matrix c[38,39], and want to merge it to a new one lets say f[1,1482]. So first i pre-allocate the f and then in a for loop i tried to merge it, but it keeps saying that i exceeded the matrix dimensions.I know that there is the cat function but i get the same results, maybe the reshape function will help? Any advice appretiated, thanks in advance.
f=[]; %// pre-allocating the mew matrix
for k=1:1482 %// 1482=38*39
f(:,k)=[c(:,1);c(:,k)]; %// merging
end
It exceeds matrix dimensions because the second dimension of c is 39 and your loop is referencing values up to 1482.
Reshape may help if you are looking at different matrix sizes but if you are just wanting to convert from a matrix to a vector then just using the (:) notation works.
c=rand(38,39);
f=c(:)';
ps. pre-allocating f only really helps if you specify the final matrix size. Here all you have done is declared an empty matrix which then expands on each loop iteration.
So I have 10 matrix, they are 20x20 size. Here, I want to store the first row of the first matrix and store onto the variable call f_row1, then the first of of the second matrix to f_row2......
So A1, A2..... A10 is my 20x20 matrix.
f_row1=A1(:,1);
f_row2=A2(:,1); %and so on.....
Is it possible for me to do it in a loop? How could I do this process in a loop?
As #beaker said, there may not be a good solution. You can use eval to achieve what you want as follows:
for i=1:10
eval(['f_row' num2str(i) '=A' num2str(i) '(:,1);']);
end
I haven't tested it but should work.
A question about matlab and randomisation of a 3d matrix respecting the rows and columns.
I have a n x n x s matrix M and I want to mess it up a bit, but with some control.
I can achieve my wish with a for loop
for j=1:size(M,3)
r=randperm(size(M,1));
random_M(:,:,j)=M(r,r,j);
end
Is there a way to perform this without having to loop over j? I need many randomisation iterations and could afford the benefits of indexing.
Cheers!
edit: Some more thoughts following Alexandrew's comments
I have created a function that randomises a squeezed version of M:
function randomMat=randomiseMat(Mat)
[rows,cols]=size(Mat);
r=randperm(rows);
randomMat=Mat(r,r);
then, using arrayfun I seem to get what I want:
randomM=arrayfun(#(x) randomiseMat(M(:,:,x)),1:size(M,3),'UniformOutput', false)
however, randomM is now a cell array of size (1,size(M,3)) with each cell containing randomised array.
Is there a way to make it in a 3d matrix just like the input M?
You can calculate all the values for r in one go, and then use arrayfun:
[nRows,nCols,nPages] = size(M);
[~,r]=sort(rand(nRows,nPages));
%# you should test on a realistic example whether a for-loop
%# isn't faster here
outCell = arrayfun(#(x) M(r(:,x),r(:,x),x), 1:nPages,'UniformOutput',false);
randomM = cat(3,outCell{:});
Why create a matrix of 0's in Matlab? For example,
A=zeros(5,5);
for i = 1:5
A(i)=exp(i);
end
Following on from j_random_hacker's answer, it's much more efficient in MATLAB to pre-allocate an array rather than letting MATLAB expand it. MATLAB can expand arrays if you simply assign elements off the current "end" of the array, like so:
x = []
for ii=1:1e4
x(ii) = 1/ii;
end
That's really inefficient because at each step in the loop, MATLAB will re-allocate "x" to be one element larger than it was previously. The following is much faster:
x = zeros( 1, 1e4 );
for ii=1:1e4
x(ii) = 1/ii;
end
(Probably fastest still in this case is: x = 1./(1:1e4);, but the pre-allocation route is what you need when you can't resolve things to a vectorised operation)
This is identical to asking: Why create a variable with value 0?
Usually you would do this if you plan to accumulate a bunch of results together somehow. In this case, you have to start "somewhere".
Although it is possible to start out with an empty matrix and expand it by concatenating (adding) new elements, vector extension is highly inefficient in MATLAB because it requires new memory every time another element is concatenated. Preallocation establishes a matrix that's the right size in advance, then each zero element can be replaced with the correct value. This method is much more efficient, especially in programs involving looping.
This is helpful if you are going to work on large matrix. Or if you are going to work with sparse matrix. This is also helpful when you are using the same vector or matrix again and again.