Creating Dynamic matrices in MATLAB - matlab

I have a problem with defining some matrices in MATLAB. I get three numbers x,y,z as an input from user, then I want to create y-1 empty matrices. For example consider x = 3, y = 4, and z = 2. The required y-1 matrices M1, M2, and M3 are:
size(M1) = [3,4] ~ [x,y]
size(M2) = [4,4] ~ [y,y]
size(M3) = [4,2] ~ [y,z]
The parameters x,y are not known before running the program. If y was 5, the matrices were:
size(M1) = [3,5] ~ [x,y]
size(M2) = [5,5] ~ [y,y]
size(M3) = [5,5] ~ [y,y]
size(M4) = [5,2] ~ [y,z]
Indeed the main problem is that the number of matrices is an input.
Please guide me on how I can create a function loop to define this matrices.

X = input('Enter X please: ');
Y = input('Enter Y please: ');
Z = input('Enter Z please: ');
Cells={}
Cells{1}=zeros(X,Y);
for i=2:Y-1
Cells{i}=zeros(Y,Y);
end;
Cells{Y-1}=zeros(Y,Z);

You could do this without using cells, but I strongly advice you not to, so:
One way to do this, with each matrix being part of a cell:
dims = str2num(input('Type in selected x,y,z: ', 's'));
M = arrayfun(#(n) zeros(dims(n), dims(2)), [1 2*ones(1,y-1) 3], 'UniformOutput', 0)
%% In the command window:
Type in selected x,y,z: 3 4 2
M =
[3x4 double] [4x4 double] [2x4 double]
Note that with the str2num(input()) approach, you can input both: [4 3 2], [4, 3, 2], 4 3 2, 4, 3, 2 or even 4;3;2. It's basically impossible to make mistakes here!
The way this works is: arrayfun performs an operation for each elements of the vector [1 2*ones(1,y-1) 3]. The operation is to create a matrix of zeros, with the desired dimensions. UniformOutput is a parameter that must be set to false, or 0 if the output is something other than scalars.
To access, and make changes to any of the matrices:
When you type M{x}, you can think of that as the equivalent of just a matrix name, i.e. it's fine to use () to index the matrix, straight after the {}.
So, you can do:
M{1}(3,3) = 2;
which would assign the value 2 to the element (3,3) in matrix 1.

M1 = zeros(x,y);
M2 = zeros(y,y);
M3 = zeors(z,y);
Simple enough. Though why M2 and M3 in your question are the same I haven't figured out yet.

Related

Summation in Matlab without for/while loop

How Do i solve this summation in MATLAB without using for/while loop?
Here C is a vector(1*N matrix), n=length(c) and x is scalar.
c(1)*x^1+c(2)*x^2+c()*x^3+....+c(n)*x^n.
Or can i Create a matrix with all element equal to x but with increasing power, like x, x^2,x^3....?
There are several ways:
result = polyval(fliplr([0 c]), x);
result = sum(c.*x.^(1:numel(c)));
result = sum(c.*cumprod(repmat(x, 1, numel(c))));
As an example, for
c = [3 4 -5 2 3];
x = 9;
any of the above gives
result =
186975
Check:
>> c(1)*x^1+c(2)*x^2+c(3)*x^3+c(4)*x^4+c(5)*x^5
ans =
186975

Array from vector on the basis of a second array

I have a vector v. I need to form an array a containing elements specified according to another array b. Each row in a (let's denote it by r) should contain all elements from v, with starting and ending indices corresponding to the first and last elements given in the matching column in b. For instance:
A(1, :) = v(b(1, 1):b(2, 1));
A(2, :) = v(b(1, 2):b(2, 2));
A(3, :) = v(b(1, 3):b(2, 3));
and so on. Obviously b(2,:) = b(1,:) + constant.
Can I do this without a loop in MATLAB?
Try this:
N=8; P=3; M=5;
v = rand(N,1);
b = zeros(2,M);
b(1,:) = [1 2 4 5 6];
b(2,:) = b(1,:) + P - 1;
A = cell2mat(arrayfun(#(i0,i1) v(i0:i1),b(1,:),b(2,:),'UniformOutput',false))'
You can use linear indexing and bsxfun to directly access the elements:
A = v(bsxfun(#plus, b(1,:).', 0:b(2,1)-b(1,1)));

How to vectorize the code in MATLAB

I have some Cluster Centers and some Data Points. I want to calculate the distances as below (norm is for Euclidean distance):
costsTmp = zeros(NObjects,NClusters);
lambda = zeros(NObjects,NClusters);
for clustclust = 1:NClusters
for objobj = 1:NObjects
costsTmp(objobj,clustclust) = norm(curCenters(clustclust,:)-curPartData(objobj,:),'fro');
lambda(objobj,clustclust) = (costsTmp(objobj,clustclust) - log(si1(clustclust,objobj)))/log(si2(objobj,clustclust));
end
end
How can I vectorize this snippet?
Thanks
Try this:
Difference = zeros(NObjects,NClusters);
costsTmp = zeros(NObjects,NClusters);
lambda = zeros(NObjects,NClusters);
for clustclust = 1:NClusters
repeated_curCenter = repmat(curCenter(clustclust,:), NObjects, 1);
% ^^ This creates a repeated matrix of 1 cluster center but with NObject
% rows. Now, dimensions of repeated_curCenter equals that of curPartData
Difference(:,clustclust) = repeated_curCenter - curPartData;
costsTmp(:,clustclust) = sqrt(sum(abs(costsTmp(:,clustclust)).^2, 1)); %Euclidean norm
end
The approach is to try and make the matrices of equal dimensions. You could eliminate the present for loop also by extending this concept by making 2 3D arrays like this:
costsTmp = zeros(NObjects,NClusters);
lambda = zeros(NObjects,NClusters);
%Assume that number of dimensions for data = n
%curCenter's dimensions = NClusters x n
repeated_curCenter = repmat(curCenter, 1, 1, NObjects);
%repeated_curCenter's dimensions = NClusters x n x NObjects
%curPartData's dimensions = NObject x n
repeated_curPartData = repmat(curPartData, 1, 1, NClusters);
%repeated_curPartData's dimensions = NObjects x n x NClusters
%Alligning the matrices along similar dimensions. After this, both matrices
%have dimensions of NObjects x n x NClusters
new_repeated_curCenter = permute(repeated_curCenter, [3, 2, 1]);
Difference = new_repeated_curCenter - repeated_curPartData;
Norm = sqrt(sum(abs(Difference)).^2, 2); %sums along the 2nd dimensions i.e. n
%Norm's dimensions are now NObjects x 1 x NClusters.
Norm = permute(Norm, [1, 3, 2]);
Here, Norm is kinda like costsTmp, just with an extra dimensions. I havent provided the code for lambda. I dont know what lambda is in the question's code too.
This vectorization can be done very elegantly (if I may say so) using bsxfun. No need for any repmats
costsTemp = bsxfun( #minus, permute( curCenters, [1 3 2] ), ...
permute( curPartData, [3 1 2] ) );
% I am not sure why you use Frobenius norm, this is the same as Euclidean norm for vector
costsTemp = sqrt( sum( costsTemp.^2, 3 ) ); % now we have the norms
lambda = costsTmp -reallog(si1)./reallog(si2);
you might need to play a bit with the order of the permute dimensions vector to get the output exactly the same (in terms of transposing it).

matlab sum vectors

Hi I have an object A which contains 9 vectors all of size [1 3], three dimensional vectors. How do I sum all of these to create a new vector of size [1 3] i.e. how to I take the contribution of each vector, and sum each of their contributions to give me a final vector. Thanks in advance. My vectors are stored in a cell array. How A is defined:
ri = Rix{1,1};
rj = Riy{1,1};
vec2 = #(i)[ri(i), rj(i), 0];
A = arrayfun(vec2, reshape(1:numel(ri), size(ri)), 'UniformOutput', 0);
and this is what I have tried so far:
B = cellfun(#(A)nansum(A(:))'un', 0);
with this error
??? b = cellfun(#(distance)nansum(distance(:))'un', 0);
|
Error: Unexpected MATLAB expression.
Is this what you are looking for?
dummy = [1 2 3];
A = {dummy;dummy;dummy;dummy;dummy;dummy;dummy;dummy;dummy}
Asum = sum(cell2mat(A));
Result:
Asum = [9 18 27]
As you can see, cell2mat is the trick here.

Matlab Error times Matrix dimensions must agree

I'm trying to create a GUI in Matlab that plots a specific graph once you've entered your data in the edit text zones. My problem is, when I try to plot a graph using this code:
function pushbutton3_Callback(hObject, eventdata, handles)
a = str2num(get(handles.edit1,'string'));
b = str2num(get(handles.edit2,'string'));
n1 = str2num(get(handles.edit6,'string'));
n2 = str2num(get(handles.edit4,'string'));
lambda = str2num(get(handles.edit5,'string'));
m = ones(1,a)
s = ones(1,b)
f = ones(1,n1)
g = ones(1,n2)
k = ones(1,lambda)
c = k.*(m.*s/f.*g)
i = -3:1:5
figure
p= plot(c,i)
This error message keeps poping out: Error times Matrix dimensions must agree. I don't know what to do? I seriously need help because I have a deadline for this project and I'm clueless! Thanks in advance.
m = ones(1,a)
s = ones(1,b)
f = ones(1,n1)
g = ones(1,n2)
k = ones(1,lambda)
c = k.*(m.*s/f.*g)
didn't your forget a dot at the division operator?
c = k.*(m.*s./f.*g)
And for the error itself: unless a==b==n1==n2==lambda, the dimensions of the vectors you create are not the same and you will not be able to (element-wisely) multiply them, which causes the Error times Matrix dimensions must agree
EDIT
plot(x,y) draws a line connecting the points (x,y) to eachother. If you drop the x and only use plot(y) then x is assumed to be 1:N (N being the number of elements in the vector y)
If you want to plot the value c=lambda*(a*b/n1*n2), then plot(c) will just plot that value. I don't understand why someone told you to convert it to vectors using ones??
Just to be sure, if
lambda=2
a = 3
b = 4
n1 = 5
n2 = 6
then c=2*(3*4/5*6)=28.8
What you then want is to plot the value 28.8??
If this is what you want, then this is done using
c = k.*(m.*s./f.*g);
plot(c);
If the parameters contain more values, eg:
lambda= [2 4]
a = [3 5]
b = [4 8]
n1 = [5 4]
n2 = [6 1]
the same thing applies, but c = k.*(m.*s./f.*g); will return c=[28.8 40] and plot(c) will connect the points (1; 28.8) and (2; 40)
ok? clear? The main issue then is that you have to assure that the user inputs an equal amount of numbers in each textbox, otherwise you have that mismatch between the vectors, and they won't compute: [1 4 5].*[6 7] will error