Matlab error for matrix dimensions - matlab

I get an error
Error using -
Matrix dimensions must agree.
Error in Untitled6 (line 32)
temp=double(S_bar) - (repmat(mean_face, 1, num_images));
code :
for i=1:num_images
[m,n] = size(S(:,i))
[a,b] = size(repmat(mean_face, 1, num_images))
temp=double(S(:,i)) - (repmat(mean_face, 1, num_images));
size of S(:,i) is [45045 1] and size of repmat(mean_face, 1, num_images is [45045 45]
So i tried to use the transpose of S(:,i) so the dimensions become [1 45045] so that i can get a resulting matrix of [1 45]. But even when i use the transpose i get the same error. Why am i getting the error even though the matrix dimensions are correct?

You need to do what i believe is called "broadcasting", i.e. making sure elementwise operations on matrices are done on matrices of compatible sizes. One elegant way of doing this is using bsxfun :
temp=bsxfun(#minus,double(S(:,i)),(repmat(mean_face, 1, num_images)));
You could also use repmat on your double(S(:,i)) so that it has the right number of columns.
Hope this helps,
Tepp

Related

What is Index exceeds matrix dimensions error in matlab?

What is this error?
Index exceeds matrix dimensions.
Error in evalution (line 5)
binTempX(i,[1,2,3,4,5,6,7,8])=parentXY(i,[1,2,3,4,5,6,7,8]);
function [tempX_Y_FXY] = evalution(parentXY,fXY)
for i=1:6
binTempX(i,[1,2,3,4,5,6,7,8])=parentXY(i,[1,2,3,4,5,6,7,8]);
binTempY(i,[9,10,11,12,13,14,15,16],8)=parentXY(i,[9,10,11,12,13,14,15,16]);
decTempX=bin2dec(binTempX(i,[1,2,3,4,5,6,7,8]));
decTempY=bin2dec(binTempY(i,[9,10,11,12,13,14,15,16]));
tempX_Y_FXY(i,1)=decTempX;
tempX_Y_FXY(i,2)=decTempY;
tempX_Y_FXY(i,3)=fXY(decTempX,decTempY);
end
tempX_Y_FXY=sortrows(tempX_Y_FXY,3);
end
binTempX(i,[1,2,3,4,5,6,7,8])=parentXY(i,[1,2,3,4,5,6,7,8]);
%%% ------- what is this 8 doing here???
binTempY(i,[9,10,11,12,13,14,15,16],**8**)=parentXY(i,[9,10,11,12,13,14,15,16]);
decTempX=bin2dec(binTempX(i,[1,2,3,4,5,6,7,8]));
decTempY=bin2dec(binTempY(i,[9,10,11,12,13,14,15,16]));
tempX_Y_FXY(i,1)=decTempX;
tempX_Y_FXY(i,2)=decTempY;
tempX_Y_FXY(i,3)=fXY(decTempX,decTempY);
Change this to:
binTempX(i,1:8)=parentXY(i,1:8);
% removed the 8, because I think it is typo??
binTempY(i,9:16)=parentXY(i,9:16);
decTempX=bin2dec(binTempX(i,1:8));
decTempY=bin2dec(binTempY(i,9:16));
tempX_Y_FXY(i,1)=decTempX;
tempX_Y_FXY(i,2)=decTempY;
tempX_Y_FXY(i,3)=fXY(decTempX,decTempY);
if you want to select/assign multiple consecutive columns use the 1:8 notation for example. Both should work but in my opinion the second is clearer and easier to maintain.
And like beaker said, check the sizes of your matrices, does the matrices you use have at least 6 rows and 16 columns?

Large image matrix: save to small matrices

I'm new to MATLAB and its development. I have a image which is 1134 (rows) X 1134 (columns). I want that image to save 3 (columns) X 3 (rows). In order to do that I need 378 cells. For that I used following code, but it gives me an error.
image=imread('C:\Users\ven\Desktop\test\depth.png');
I=reshape(image,1,1134*1134);
chunk_size = [3 3]; % your desired size of the chunks image is broken into
sc = sz ./ chunk_size; % number of chunks in each dimension; must be integer
% split to chunk_size(1) by chunk_size(2) chunks
X = mat2cell(I, chunk_size(1) * ones(sc(1),1), chunk_size(2) *ones(sc(2),1));
Error:
Error using mat2cell (line 97)
Input arguments, D1 through D2, must sum to each dimension of the input matrix size, [1 1285956].'
Unfortunately your code does not work as you think it would.
The ./ operator performs point wise division of two matrices. Short example:
[12, 8] ./ [4, 2] == [12/4, 8/2] == [3, 4]
In order for it to work both matrices must have exactly the same size. In your case you try to perform such an operation on a 1134x1134 matrix (the image) and a 1x2 matrix (chunk_size).
In other words you can not use it to divide matrices into smaller ones.
However, a solution to your problem is to use the mat2cell function to pick out subsets of the matrix. A explanation of how it is done can be found here (including examples): http://se.mathworks.com/matlabcentral/answers/89757-how-to-divide-256x256-matrix-into-sixteen-16x16-blocks.
Hope it helps :)
Behind the C=A./B command is loop over all elements of A(ii,jj,...) and B(ii,jj,..) and each C(ii,jj,..)=A(ii,jj,...)/B(ii,jj,...).
Therefore martices A and B must be of same dimension.
If you want to split matrix into groups you can use
sc=cell(1134/3,1);
kk=0;ll=0;
for ii=2:3:1133
kk=kk+1;
for jj=2:3:1133
ll=ll+1;
sc{kk,ll}=image(ii-1:ii+1,jj-1:jj+1);
end
end
The code allocates cell array sc for resulting submatrices and arbitrary counters kk and ll. Then it loops over ii and jj with step of 3 representing centers of each submatrices.
Edit
Or you can use mat2cell command (type help mat2cell or doc mat2cell in matlab shell)
sc=mat2cell(image,3,3);
In both cases the result is cell array and its iith and jjth elements (matrices) are accessible by sc{ii,jj}. If you want call iith anr jjth number in kkth and llth matrix, do it via sc{kk,ll}(ii,jj).
In short, you divided a 1134 x 1134 by 2 x 1 matrix. That doesn't work.
The error "Matrix dimensions must agree**" is from the dividing a matrix with another matrix that doesn't have the right dimensions.
You used the scalar divide "./" which divided a matrix by another matrix.
You want something like:
n = 1134 / 3 % you should measure the length of the image
I1=image(1:n,1:n); % first row
I2=image(1:n,n:2n);
I3=image(1:n,2n:3n);
I4=image(n:2n,1:n); % second row
I5=image(n:2n,n:2n);
I6=image(n:2n,2n:3n);
I7=image(2n:3n,1:n); % third row
I8=image(2n:3n,n:2n);
I9=image(2n:3n,2n:3n);
from here:
http://au.mathworks.com/matlabcentral/answers/46699-how-to-segment-divide-an-image-into-4-equal-halves
There would be a nice loop you could do it in, but sometimes thinking is hard.

Print the value of a multidimensional array with the output as compatible matlab code

For matrices with dimensions equal or less then 2 the command is:
For instance:
>> mat2str(ones(2,2))
ans =
[1 1;1 1]
However, as the help states, this does not work for higher dimensions:
>> mat2str(rand(2,2,2))
Error using mat2str (line 49)
Input matrix must be 2-D.
How to output matrices with higher dimensions than 2 with that is code compatible, without resorting to custom made for loops?
This isn't directly possible because there is no built-in character to represent concatenation in the third dimension (an analog to the comma and semicolon in 2D). One potential workaround for this would be to perform mat2str on all "slices" in the third dimension and wrap them in a call to cat which, when executed, would concatenate all of the 2D matrices in the third dimension to recreate your input matrix.
M = reshape(1:8, [2 2 2]);
arrays = arrayfun(#(k)mat2str(M(:,:,k)), 1:size(M, 3), 'uni', 0);
result = ['cat(3', sprintf(', %s', arrays{:}), ')'];
result =
'cat(3, [1 3;2 4], [5 7;6 8])'
isequal(eval(result), M)
1
UPDATE
After thinking about this some more, a more elegant solution is to flatten the input matrix, run mat2str on that, and then in the string used to recreate the data, we utilize reshape combined with the original dimensions to provide a command which will recreate the data. This will work for any dimension of data.
result = sprintf('reshape(%s, %s);', mat2str(M(:)), mat2str(size(M)));
So for the following 4D input
M = randi([0 9], 1, 2, 3, 4);
result = sprintf('reshape(%s, %s);', mat2str(M(:)), mat2str(size(M)));
'reshape([6;9;4;6;5;2;6;1;7;2;1;7;2;1;6;2;2;8;3;1;1;3;8;5], [1 2 3 4]);'
Now if we reconstruct the data using this generated string, we can ensure that we get the correct data back.
Mnew = eval(result);
size(Mnew)
1 2 3 4
isequal(Mnew, M)
1
By specifying both the class and precision inputs to mat2str, we can even better approximate the input data including floating point numbers.
M = rand(1,2,3,4,5);
result = sprintf('reshape(%s, %s);', mat2str(M(:),64,'class'), mat2str(size(M)));
isequal(eval(result), M)
1

compute weights by Generalized Hebbian Algorithm in matlab

I have a task to do some calculations in matlab .. I use the Generalized Hebbian Algorithm to compute some weights , here is the functions of Hebbian Algorithm , slice 15
http://www.eit.lth.se/fileadmin/eit/courses/eitn55/Downloads/ICA_Ch6.pdf
here is my code
alfa=0.5;
e=randn(3,5000);
A=[1 0 0;-0.5 0.5 0;0.3 0.1 0.1];
x=A*e;
W=rand(3);
nn=size(x);
for n=1:nn
y=W*x(:,n);
k=tril(y*y')*W;
W(:,n+1)= alfa*(y*x(:,n)'-k);
end
In my task I know that x=A*e;
but I do not know if I am iterating in correct way or not?
is my for loop doing correct?
and are those equations below correct?
y=W*x(:,n);
k=tril(y*y')*W;
W(:,n+1)= alfa*(y*x(:,n)'-k);
W(:,n+1) should print out a 3*3 matrix (that what I understood)...
Matlab says when I run this code : Error using *
Inner matrix dimensions must agree.
thanks
If you check size of each matrix, you will find out that the order is incorrect:
size(x)
ans =
3 5000
size(W)
ans =
3 3
so you should multiply them as
for n=1:nn
y=W*x;
end
However this part does not make sense either,
k=tril(y'*y)*W;
because tril(y'*y) is a matrix size 5000x5000 and W is 3x3. So I guess you should change it to:
k=tril(y*y')*W;
Then alfa*(y*x'-k); would be a 3x3 matrix.

Multiply a 180x360 array by a 156-item time-series to get 180x360x156 array?

bsxfun(#times,RegressIndexFlux.(IndexNames{i}).(FluxNames{j}), Indices.(IndexNames{i}));
So my code is above.
The problem with bsxfun is that I get the below error message:
Error using bsxfun
Non-singleton dimensions of
the two input arrays must
match each other.
So here's the question: is there a way for me to convert the 180x360 array by a timeseries without having to use for loops, if possible? (I'm using many structures of 180x360 arrays here). Basically RegressIndexFlux is regressed against the time-series Indices, and I'm trying to get a reconstruction of the time-series by only using the regression.
You can't have mismatched non-singleton dimensions. Permute the second argument. Assuming A is a m-by-n matrix and B is a (p-by-1) column vector:
A = rand(6,5); B = rand(4,1);
% m-by-n #times 1-by-1-by-p => m-by-n-by-p
C = bsxfun(#times,A,permute(B,[3 2 1]));
size(C)
ans =
6 5 4