Because it is possible to create a (non-constant) diagonal matrix in Matlab, f.i. A = diag([1;2;3]), I wonder if there is an easy way to create a non-constant tridiagonal matrix. Because the gallery('tridiag',...) command is only working with constant tridiagonal matrices.
If I understood your question correctly, then you can create random tridiagonal matrices using the below line of code
n=10;
p=3;
T=toeplitz([1 randn(1,n-p-1) zeros(1,p)], [1 randn(1,n-p-1) zeros(1,p)])*diag(randn(1,n))
Note, you can also change the 1 in the toeplitz function or you can remove it all along, but then you get a warning.
Related
Currently, I have used ode45 with a function that outputs a matrix (C) that 3945x9. These are supposed to be 3x3 matrices, so I did C = reshape(C.',3,3,[]). Now, I have a 3x3x3945 matrix. What I want to do is find the error of each 3x3 matrix. This is done using C*C.' - eye(3). However, I do not know how to do this with all my data now. It will work for something like C(:,:,1)*C(:,:,1).' - eye(3). However, not C(:,:,:)*C(:,:,:) - eye(3).
Use the nD matrix multiply routine pagemtimes. E.g.,
pagemtimes(C,'none',C,'transpose') - eye(3)
I have a 9x3 matrix that I subdivided into three (3) 3x3 matrix. Now I want to make a for loop function that will store each 3x3 matrix into a variable.
X=reshape(1:27,3,9)'; % sample 9x3 matrix
xx = mat2cell(X,[3,3,3],3); % subdivide X matrix into 3x3 cell matrix
for i:1:3
x(i) = xx{i,1}; %store the three cells into x1 x2 and x3 matrix
end
I know that this does not how it works in matlab but just to show the function I would like to attain.
You can use eval function.
X=reshape(1:27,3,9)'; % sample 9x3 matrix
xx = mat2cell(X,[3,3,3],3); % subdivide X matrix into 3x3 cell matrix
for i=1:3
eval(['x' num2str(i) ' = xx{' num2str(i) ',1};']);
end
But What you are asking for is not recommended at all. In fact i always avoid using eval because the code doesn't get checked by MATLAB editor.
It is also not a good idea to have multiple variables, instead use cells, structures, and so on for a better usage in the rest of your code.
Is this what you're looking for?
X=reshape(1:27,3,9)';
for i=1:3
block = X(3*i-2:3*i,:);
disp(block);
end
The preferred way to do this is to actually just store it in a 3D array and you can access each element along the third dimension. The reason for that is that MATLAB is optimized for computing using matrices, so if you keep all of your data in a matrix, operations can be performed in a vectorized fashion on all components.
Better yet you can remove the for loop needed to create it by using reshape and permute.
X = permute(reshape(X', [3 3 3]), [2 1 3]);
% And access each element
X(:,:,1)
X(:,:,2)
X(:,:,3)
This is going to be more performance than using cell arrays or eval.
In my current analysis, I am trying to multiply a matrix (flm), of dimension nxm, with the inverse of a matrix nxmxp, and then use this result to multiply it by the inverse of the matrix (flm).
I was trying using the following code:
flm = repmat(Data.fm.flm(chan,:),[1 1 morder]); %chan -> is a vector 1by3
A = (flm(:,:,:)/A_inv(:,:,:))/flm(:,:,:);
However. due to the problem of dimensions, I am getting the following error message:
Error using ==> mrdivide
Inputs must be 2-D, or at least one
input must be scalar.
To compute elementwise RDIVIDE, use
RDIVIDE (./) instead.
I have no idea on how to proceed without using a for loop, so anyone as any suggestion?
I think you are looking for a way to conveniently multiply matrices when one is of higher dimensionality than the other. In that case you can use bxsfun to automatically 'expand' the smaller matrix.
x = rand(3,4);
y = rand(3,4,5);
bsxfun(#times,x,y)
It is quite simple, and very efficient.
Make sure to check out doc bsxfun for more examples.
I need a 3D matrix in matlab, I have another 2D matrix (7570x3) too,
The 3D matrix should have zero number except of all dimensions in 2D matrix that should have 1 value. How can I do that.
i.e. 2D matrix (1,:) = 28,64,27 then 3d(27,64,27) should be 1
how can i do that?
Assuming a is your 2-d matrix, and b is the 3-d one, use sub2ind as follows:
b=false(max(a)); % preallocate memory for a logical zeros matrix b
b(sub2ind(size(b),a(:,1),a(:,2),a(:,3))) = 1;
Check to see what max(a) gives you to see if you can host a 3-d matrix of size(max(a) to begin with. Since you are interested in a logcial matrix (ones and zeros), the size of that matrix in memory is the same as the # of elements, n*m*l, so a 1000x1000x1000 will take 1 GB.
Note, it very well may be that b is very sparse, if that is the case you can refer to this thread to see how to deal with it. Know that at the moment, and to the best of my knowledge, matlab doesn't support 3d sparse matrices. So you may want to check this option from the FEX. When I think of it, you already have a sparse look-up table of the 3D matrix! it is just your 2D matrix you started with...
Thanks a lot #natan
for non-integer matrix also can use:
b=false(floor(max(a))); % preallocate memory for a logical zeros matrix b
b(sub2ind(size(b),floor(a(:,1)),floor(a(:,2)),floor(a(:,3)))) = 1;
or use round function:
b=false(round(max(a))); % preallocate memory for a logical zeros matrix b
b(sub2ind(size(b),round(a(:,1)),round(a(:,2)),round(a(:,3)))) = 1;
I have an M-by-M-by-N matrix, which is a concatenation of N M-by-M matrices. I want to reduce this matrix to an M-by-N matrix by taking the diagonals of each M-by-M submatrix and concatenating them together. How can I do this in a simple vectorized way?
You can do it by getting the linear indices of the diagonals and using it to form a new matrix
[M,~,N]=size(A);%# A is your matrix
indx=cumsum([1:(M+1):M^2; M^2.*ones(N-1,M)]);%#diagonal indices
B=A(indx');%'# transpose to get MxN
In the above, I've used ~ to disregard that output from the function. However, this works only if you're using MATLAB R2009b and above. If your version is older than that, use a dummy variable instead.