How to write this matrix in matlab, - matlab

I want to write this matrix in matlab,
s=[0 ..... 0
B 0 .... 0
AB B .... 0
. . .
. . .
. . . 0 ....
A^(n-1)*B ... AB B ]
I have tried this below code but giving error,
N = 50;
A=[2 3;4 1];
B=[3 ;2];
[nx,ny] = size(A);
s(nx,ny,N) = 0;
for n=1:1:N
s(:,:,n)=A.^n;
end
s_x=cat(3, eye(size(A)) ,s);
for ii=1:1:N-1
su(:,:,ii)=(A.^ii).*B ;
end
z= zeros(1,60,1);
su1 = [z;su] ;
s_u=repmat(su1,N);
seems like the concatenation of matrix is not being done.
I am a beginner so having serious troubles,please help.

Use cell arrays and the answer to your previous question
A = [2 3; 4 1];
B = [3 ;2 ];
N = 60;
[cs{1:(N+1),1:N}] = deal( zeros(size(B)) ); %// allocate space, setting top triangle to zero
%// work on diagonals
x = B;
for ii=2:(N+1)
[cs{ii:(N+2):((N+1)*(N+2-ii))}] = deal(x); %//deal to diagonal
x = A*x;
end
s = cell2mat(cs); %// convert cells to a single matrix
For more information you can read about deal and cell2mat.
Important note about the difference between matrix operations and element-wise operations
In your question (and in your previous one) you confuse between matrix power: A^2 and element-wise operation A.^2:
matrix power A^2 = [16 9;12 13] is the matrix product of A*A
element-wise power A.^2 takes each element separately and computes its square: A.^2 = [4 9; 16 1]
In yor question you ask about matrix product A*b, but the code you write is A.*b which is an element-by-element product. This gives you an error since the size of A and the size of b are not the same.

I often find that Matlab gives itself to a coding approach of "write what it says in the equation". That also leads to code that is easy to read...
A = [2 3; 4 1];
B = [3; 2];
Q = 4;
%// don't need to...
s = [];
%// ...but better to pre-allocate s for performance
s = zeros((Q+1)*2, Q);
X = B;
for m = 2:Q+1
for n = m:Q+1
s(n*2+(-1:0), n-m+1) = X;
end
X = A * X;
end

Related

3D matrix multiplication by 2D matrix

I have a NxNx4 matrix(A) and a 4x4 matrix (B). I need to multiply the vector a composed by the four elements of the first matrix A, let's say
a = A(1,1,1)
A(1,1,2)
A(1,1,3)
A(1,1,4)
by the 4x4 matrix B but I'm not sure if there is a faster and clever solution than using a for loop to build the vector a. Does exist a way to do this computation with few lines of code?
I built A like
A(:,:,1) = rand(20);
A(:,:,2) = rand(20);
A(:,:,3) = rand(20);
A(:,:,4) = rand(20);
and the matrix B
B = rand(4);
now I want to multiply B with
B*[A(1,1,1);A(1,1,2);A(1,1,3);A(1,1,4)]
This, for each element of A
B*[A(1,2,1);A(1,2,2);A(1,2,3);A(1,2,4)]
B*[A(1,3,1);A(1,3,2);A(1,3,3);A(1,3,4)]
...
You can do this with a simple loop, note loops aren't necessarily slow in newer MATLAB versions. Mileage may vary.
Loops have the advantage of improving code readability, it's extremely clear what's happening here:
% For matrix A of size N*N*4
C = zeros( size( A ) );
for ii = 1:N
for jj = 1:N
C( ii, jj, : ) = B * reshape( A( ii, jj, : ), [], 1 );
end
end
A loop solution that has good performance specially when N is large:
s = size(A, 3);
C = A(:,:,1) .* reshape(B(:,1),1,1,[]);
for k = 2:s
C = C + A(:,:,k) .* reshape(B(:,k),1,1,[]);
end
I think this does what you want:
C = permute(sum(bsxfun(#times, permute(B, [3 4 2 1]), A), 3), [1 2 4 3]);
Check:
>> C(1,2,:)
ans(:,:,1) =
1.501739582138850
ans(:,:,2) =
1.399465238902816
ans(:,:,3) =
0.715531734553844
ans(:,:,4) =
1.617019921519029
>> B*[A(1,2,1);A(1,2,2);A(1,2,3);A(1,2,4)]
ans =
1.501739582138850
1.399465238902816
0.715531734553844
1.617019921519029

Smarter way to generate a matrix of zeros and ones in Matlab

I would like to generate all the possible adjacency matrices (zero diagonale) of an undirected graph of n nodes.
For example, with no relabeling for n=3 we get 23(3-1)/2 = 8 possible network configurations (or adjacency matrices).
One solution that works for n = 3 (and which I think is quite stupid) would be the following:
n = 3;
A = [];
for k = 0:1
for j = 0:1
for i = 0:1
m = [0 , i , j ; i , 0 , k ; j , k , 0 ];
A = [A, m];
end
end
end
Also I though of the following which seems to be faster but something is wrong with my indexing since 2 matrices are missing:
n = 3
C = [];
E = [];
A = zeros(n);
for i = 1:n
for j = i+1:n
A(i,j) = 1;
A(j,i) = 1;
C = [C,A];
end
end
B = ones(n);
B = B- diag(diag(ones(n)));
for i = 1:n
for j = i+1:n
B(i,j) = 0;
B(j,i) = 0;
E = [E,B];
end
end
D = [C,E]
Is there a faster way of doing this?
I would definitely generate the off-diagonal elements of the adjacency matrices with binary encoding:
n = 4; %// number of nodes
m = n*(n-1)/2;
offdiags = dec2bin(0:2^m-1,m)-48; %//every 2^m-1 possible configurations
If you have the Statistics and Machine Learning Toolbox, then squareform will easily create the matrices for you, one by one:
%// this is basically a for loop
tmpcell = arrayfun(#(k) squareform(offdiags(k,:)),1:size(offdiags,1),...
'uniformoutput',false);
A = cat(2,tmpcell{:}); %// concatenate the matrices in tmpcell
Although I'd consider concatenating along dimension 3, then you can see each matrix individually and conveniently.
Alternatively, you can do the array synthesis yourself in a vectorized way, it's probably even quicker (at the cost of more memory):
A = zeros(n,n,2^m);
%// lazy person's indexing scheme:
[ind_i,ind_j,ind_k] = meshgrid(1:n,1:n,1:2^m);
A(ind_i>ind_j) = offdiags.'; %'// watch out for the transpose
%// copy to upper diagonal:
A = A + permute(A,[2 1 3]); %// n x n x 2^m matrix
%// reshape to n*[] matrix if you wish
A = reshape(A,n,[]); %// n x (n*2^m) matrix

How to get a 3D-matrix or cell array efficiently by using vectorized code?

Here is what I want, a 3-D matrix:
K = 2:2.5:10;
den = zeros(1,4,4);
for i = 1:1:4
den(:,:,i) = [1, 5, K(i)-6, K(i)];
end
Or, a cell array is also acceptable:
K = 2:2.5:10;
for i = 1:1:4
den{i} = [1, 5, K(i)-6, K(i)];
end
But I want to know if there is a more efficient way of doing this using vectorized code like:
K = 2:2.5:10;
den = [1, 5, K-6, K];
I know the last code will not get what I wanted. But, like I can use:
v = [1 2 3];
v2 = v.^2;
instead of:
v = [1 2 3];
for i = 1:length(v)
v(i) = v(i)^2;
end
to get the matrix I want. Is there a similar way of doing this so that I can get the 3-D matrix or cell array I mentioned at the beginning more efficiently?
You need to "broadcast" the scalar values in columns so they are of the same length as your K vector. MATLAB does not do this broadcasting automatically, so you need to repeat the scalars and create vectors of the appropriate size. You can use repmat() for this.
K = 2:2.5:10;
%% // transpose K to a column vector:
K = transpose(K);
%% // helper function that calls repmat:
f = #(v) repmat(v, length(K), 1);
%% // your matrix:
den = [f(1) f(5) K-6 K];
This should be more optimized for speed but requires a bit more intermediary memory than the loop does.
Just use reshape with a 1*3 size:
den = reshape([ones(1,length(K));ones(1,length(K))*5; K-6; K],[1 4 length(K)]);
I think the used extra memory by reshape should be low and constant (dependent only on the length of the vector of new sizes).
You can use the classic line equation y=a*x+b, extended to the matrix form:
k = 2:2.5:10 ;
fa = [0 0 1 1].' ; %' // "a" coefficients
fb = [1 5 -6 0].' ; %' // "b" coefficients
d(1,:,:) = fa*k + fb*ones(1,4) ;
The above is better for clarity, but if you're not bothered you can also pack everything in one line:
d(1,:,:) = [0 0 1 1].' * (2:2.5:10) + [1 5 -6 0].' * ones(1,4) ;
If you need to re-use the principle for many different values of k, then you can use an anonymous function to help:
fden = #(k) [0 0 1 1].' * k + [1 5 -6 0].' * ones(1,4) ; %// define anonymous function
k = 2:2.5:10 ;
d(1,:,:) = fden(k) ; %// use it for any value of "k"

Can I do the following fast in Matlab?

I have three matrices in Matlab, A which is n x m, B which is p x m and C which is r x n.
Say we initialize some matrices using:
A = rand(3,4);
B = rand(2,3);
C = rand(5,4);
The following two are equivalent:
>> s=0;
>> for i=1:3
for j=1:4
s = s + A(i,j)*B(:,i)*C(:,j)';
end;
end
>> s
s =
2.6823 2.2440 3.5056 2.0856 2.1551
2.0656 1.7310 2.6550 1.5767 1.6457
>> B*A*C'
ans =
2.6823 2.2440 3.5056 2.0856 2.1551
2.0656 1.7310 2.6550 1.5767 1.6457
The latter being much more efficient.
I can't find any efficient version for the following variant of the loop:
s=0;
for i=1:3
for j=1:4
x = A(i,j)*B(:,i)*C(:,j)';
s = s + x/sum(sum(x));
end;
end
Here, the matrices being added are normalized by the sum of their values after each step.
Any ideas how to make this efficient like the matrix multiplication above? I thought maybe accumarray could help, but not sure how.
You can do it efficiently with bsxfun:
aux1 = bsxfun(#times, permute(B,[1 3 2]), permute(C,[3 1 4 2]));
aux2 = sum(sum(aux1,1),2);
s = sum(sum(bsxfun(#rdivide, aux1, aux2),3),4);
Note that, because of the normalization, the result is independent of A, assuming it doesn't contain any zero entries (if it does the result is undefined).

how to select specific index in 3rd matrix from third dimention in matlab

I know this is a simple question but difficult to formulate in one sentence to google the answer.So, I have a 3d matrix with size 2x2x3 like this
A(:,:,1) =[1 1; 1 1];
A(:,:,2) =[2 2; 2 2];
A(:,:,3) =[4 4; 4 4];
and matrix B with size 2x2
B = [ 1 2; 2 3];
What i need is to chose from each third dimension in A just one number using matrix B:
for i=1:2,
for j=1:2,
C(i,j) = A(i,j,B(i,j));
end
end
How to that in one line without a loop?
Not really a single line, but without a loop:
[I J] = ind2sub (size(B), 1:numel(B));
linInd = sub2ind (size (A), I, J, B(:)');
C = reshape (A(linInd), size(B));
Here is another variation:
[r,c,~] = size(A);
[J,I] = meshgrid(1:size(B,1), 1:size(B,2));
idx = reshape(I(:) + r*(J(:)-1) + r*c*(B(:)-1), size(B));
C = A(idx)