I want to extract the matrices from the matrix B on the nodes I defined by perm(:,i) which are the ith column matrix of emp and I want to calculate A1= B(perm(:,1),perm(:,1)), A2=B(perm(:,2),perm(:,2)) that is make a loop such that:
for i=1:n
I got A1, A2 and so on –
From what i can discern, it seems that you want to dynamically extract a sub-matrix from matrix B, according to the perms matrix. Your problem, it seems, is that you cannot do this in a loop, because you don't know how to dynamically create matrices. Your solution is to create a cell and input each sub-matrix in the cell. Thus, if A is your cell then,
A=cell(1,N);
for i=1:N
A{i}=B(perm(:,i),perm(:,i));
end
You can get the matrix Ai from the cell using,
Ai=A{i}; %notice the curly braces {}
If you really want variables named A1, A2, &c, you can use eval:
for i = 1:N
eval(['A' num2str(i) ' = B(perm(:,i),perm(:,i))']);
end
However, it's probably not a good idea and you'd better use cells as shown by #Jorge. Cells can contain anything and are much more convenient.
Related
I am interested how to create a diagonal matrix from an array of matrices.
I created an array of matrices in MATLAB:
X<62x62x1000> it consists of 1000 matrices with dimensions 62x62
I want to create a matrix of dimensions 62000x62000 with 1000 sub matrices from array X along main diagonal.
Do you have any clue how to do this, except M=blkdiag(X(:,:,1), X(:,:,2), X(:,:,3)...) because that would be to much writing.
A possible solution
M = kron(speye(1000),ones(62));
M(logical(M)) = X(:);
With kron a 62000*62000 sparse matrix M is created that contains 1000 blocks of ones on its diagonal, then replace ones with elements of X.
You can flatten out your input matrix into a column vector using (:) indexing and then pass it to diag to place these elements along the diagonal of a new matrix.
result = diag(X(:))
This will order the elements along the diagonal in column-major order (the default for MATLAB). If you want a different ordering, you can use permute to re-order the dimensions prior to flattening.
It's important to note that your resulting matrix is going to be quite large. You could use spdiags instead to create a sparse diagonal matrix
spdiags(X(:), 0, numel(X), numel(X))
A very controversial eval call can solve this very lazily, although I suspect there is a much better way to do this:
evalstring = ['M=blkdiag('];
for i = 1:999
evalstring = [evalstring, 'X(:,:,', num2str(i),'),'];
end
evalstring = [evalstring, 'X(:,:,1000));'];
eval(evalstring);
I have created a cell array of dimensions 1x10, named A. Each element contains a 100x5 matrix. Hence, I got 10 matrices 100x5. However, I want to put every matrix of the cell array into a loop. If B is a 100x5 matrix, C is a 100x1 vector and c is a constant, the loop should look like:
for t=1:100;
j=1:5;
x=c*inv((B(t,j)-A(t,j))*((B(t,j)-A(t,j))')*(A(t,j)-C(t,1)*ones(1,5));
end;
end;
At the end x should deliver a 1x10 cell array that will contain 10 elements of matrices 100x5.
I would appreciate any help. Thank you in advance!
If I understand your question correctly, you are asking how to access a cell array. Let i index the cell array. Then you can access the ith entry of the cell array by calling A{i}. Then your code is:
for i=1:10
for t=1:100
j=1:5
x{i}=c*inv((B(t,j)-A{i}(t,j))*((B(t,j)-A{i}(t,j))')*(A{i}(t,j)-C(t,1)*ones(1,5));
end
end
end
You may want to think about your problem and whether or not you can eliminate the the two middle for loops by writing it in matrix notation. It looks similar to a least-squares estimator, which is (X'X)^(-1)*X'y, but the element-by-element inverse is throwing me off.
I'd like to replace a specific number of elements of my cell to zero without using for. For example to replace elements of row 2 in example cell a below: How should I proceed possibly using cellfun?
a=cell(2,3);
cellfun(#(x)(zeros(a{x}(2,:))),a);
It gives the error "Bad cell reference operation".
what if I'd like to make row 2 empty again?
Thanks in advance for any help
The action you want to perform requires an assignment within a function. The only way to achieve this is using eval, which is considered bad practice.
A loop is therefore the best remaining option, if you want to keep everything in one script:
A = {randn(2,3),randn(2,3)};
for ii = 1:numel(A)
A{ii}(2,:) = 0;
end
If you don't bother using multiple files, you can put the assignment in a function:
function [ out ] = setZero( cellarray, rowidx )
out = cellarray;
out(rowidx,:) = 0;
end
and use it as follows:
A = cellfun(#(x) setZero(x,2),A ,'uni',0)
You need to find a transformation that turns a given matrix A to a matrix where the second row is all-zero. Here are three alternatives
A=cellfun(#(x) [x(1,:); zeros(size(x(2,:))); x(3:end,:)], A, 'uni', 0)
and
A=cellfun(#(x) diag(1:size(x,1)~=2)*x, A, 'uni', 0)
and
A=cellfun(#(x) bsxfun(#times, (1:size(x,1))' ~= 2, x), A, 'uni', 0)
The first one is the most robust one because it will handle the cases that your matrix has NaN elements. The second and third alternatives simply multiply the second row by zero. The second achieves this by multiplying it with a diagonal matrix where all diagonal elements are 1 except element (2,2) which is zero. The third alternative achieves this using bsxfun.
This is to demonstrate that you can achieve this without for loops however a simple for loop is much more readable.
I have a cell array (A) with size of 400 x 1 and each cell of this array includes a matrix with size 9 x 4. As such, it looks like this:
A={[9x4 double];[9x4 double];...;[9x4 double]};
Now, I want to remove the zero rows from these sub matrices and then obtain a new A cell array called A_new where its sub matrices don't have any zero rows like this:
A_new={[5x4 double];[7x4 double];...;[4x4 double]};
By my below code, I can find the index of rows which are not zero but I couldn't create my cell array like I mentioned above. This is my written code and for the bold part, I have a problem and I couldn't solve it.
for i=1:A_Length
[row,col]=find(A{i,1});
out=[row col];
NNZ_row=unique(row);
Length_NNZ= length(NNZ_row);
for j=1:Length_NNZ
**A_NonZero{i,1}= ??????????**
end
end
What I would do is take each cell, then use all on the opposite of the matrix over all of the columns in each row to determine which rows contain all zeroes. Once you do this, use these locations and remove those rows from this matrix and save this to your new matrix.
As such, do this:
A_new = cell(1,numel(A));
for i=1:numel(A)
mat = A{i};
ind = all(~mat, 2);
A_new{i} = mat(~ind,:);
end
The first line of code creates a new cell array that is the same size as A. Next, for each element in A, extract the matrix at each cell location, use all on the opposite of this matrix to find those elements that we need to keep, then save this new matrix into the corresponding location in A_new.
If you want to do this in a single line of code, use cellfun:
A_new = cellfun(#(x) x(~all(~x,2),:), A, 'uni', 0);
The first argument to cellfun is an anonymous function that performs what the for loop was doing. We find those rows that contain all zeroes and use those to remove the rows in each matrix in the cell array. The second argument is the matrix we want to operate on, which is A. The 'uni' and 0 flags are important because the outputs are not single values but matrices, and so the output of this function will be a cell array that is the same size as A where each element is the matrix for those corresponding locations in A with the zero rows removed.
You should use a combination of cellfun and any:
A_new = cellfun(#(x) x(any(x~=0,2),:), A, 'UniformOutput', false);
should do the trick.
How can I squeeze only a subset of singleton dimensions of a matrix in Matlab? The squeeze function removes them all.
I keep the index to those dimensions in a vector called "dims".
Code
%// Input matrix is assumed as A
sz = size(A)
t2 = sz~=1
t2(dims)=1
out = reshape(A,sz(t2)) %// out is the desired output
If you are crazy about dense codes, you can try this -
sz = size(A)
out = reshape(A,sz(sort([dims find(sz~=1)])))
In Matlab, there is no tailing singleton dimension. A n*m*1 matrix is automatically a n*m matrix. Knowing this, your problem could be solved permuting the dimensions you don't want to the end:
X=ones(2,1,2,1,2,1,2,1,2,1)
%dimensions you want to keep in any case
dims=[2:4];
%Notice, S is [2,1,2,1,2,1,2,1,2], last dimension already "gone"
S=size(X)
%keep if size>1
dimensions_to_keep=S>1
%and keep if in "dims" list
dimensions_to_keep(dims)=1
%now permute dimensions you don't want to the end
Y=permute(X,[find(dimensions_to_keep),find(~dimensions_to_keep)])