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
Related
This question contains a lot of code, but a lot of it is error messages and parameter definitions.
I am trying to generate a matlab function script to calculate the dynamics of a 4-link robot manipulator. The goal is to make the function take a bunch of parameters(vectors/matrices) as inputs and return system matrices D, C and G. All calculations are done symbolically according to standard formulas found in any robotics textbook. I have looked through all my calculations and find no errors here.
When the calculations are complete, the function file is generated by the following line of code:
matlabFunction(D,C,G,'File','getDynamicsFnc','Vars',{[q], [q_dot], [I1], [I2], [I3], [I4],
[th_a], [DH_params], [m], [com], [g]});
This leads to the following error message:
Error using horzcat
Dimensions of arrays being concatenated are not consistent.
Error in sym/matlabFunction>computeVarnames (line 902)
allNames = matlab.lang.makeUniqueStrings([repelem("ft",1,nuOfBlocks-1), "ft"
allVars],1:nuOfBlocks-1,namelengthmax);
Error in sym/matlabFunction>postProcessing (line 826)
[newFunctionNames, newArgumentName] = computeVarnames(blocks);
Error in sym/matlabFunction (line 198)
blocks = postProcessing(blocks);
Error in generate_func_complete (line 119)
matlabFunction(D,C,G,'File','getDynamicsFnc','Vars',{[q], [q_dot], [I1], [I2], [I3], [I4],
[th_a], [DH_params], [m], [com], [g]});
I have checked the dimensions of all elements in the workspace and find no inconsistencies. I tried running the script with dummy-values for D, C and G and it worked properly (even when they were made up of elements from the transformation/Jacobi matricies that are calculated in the script).
The following code shows how D, C and G are calculated:
D = sym(zeros(dim)); C = sym(zeros(dim)); G = sym(zeros(dim,1));
% D matrix
for i = 1:dim % T{i} is a 4X4 matrix that was calculated previously
R = T{i}(1:3,1:3);
It = simplify(R*I{i}*R');
D = D + m(i)*J_v{i}'*J_v{i} + J_w{i}'*It*J_w{i}; % Calculate D
P = P + m(i)*gvec'*rc{i}; % Potential energy. Used to find G later
end
P = simplify(P);
% C matrix
for i= 1:dim
for j=1:dim
for k=1:dim
christ = 0.5*(diff(D(i,j),q(k)) + diff(D(i,k),q(j)) - diff(D(k,j),q(i))); % Calculating Christoffel symbols
C(i,j) = C(i,j) + christ*q_dot(k); % Summing Christoffel symbols to find elements of C
end
end
end
% G matrix
for i = 1:dim
G(i) = diff(P,q(i)); % Calculating G
end
I will not include calculations for T, J or rc due to the length of the code, but I have already verified that they are not the problem. All other parameters used are defined as follows:
dim = 4;
q = sym('q',[dim 1],'real');
q_dot = sym('q_dot',[dim 1],'real');
I1 = sym('I1', [3 3],'real');
I2 = sym('I2', [3 3],'real');
I3 = sym('I3', [3 3],'real');
I4 = sym('I4', [3 3],'real');
I = cell(1,4);
I{1} = I1; I{2} = I2; I{3} = I3; I{4} = I4;
th_a = sym('th_a','real');
DH_params = sym('DH_params', [5 4],'real');
com = sym('com', [5 3],'real');
m = sym('m', [1 dim],'real');
g = sym('g','real');
gvec = [0;0;g];
NOTE: I do not use the simplify function when calculating the outputs. This is due to the extreme increase in runtime for the script, to the point where it won't finnish over several hours.
I included a lot of code in this question, but I believe it is fairly simple to understand and hopefully not too exessive. Please give feedback if I overdid it.
If we have a vector v of 1- 5 numbers we can use nchoosek(v,2) to get all the combinations having two elements. But this function does now allow us to get all the combinations of a matrix. I want to use it to get all the combinations of rows of a matrix.
Here's one way to do it:
function p = q47204269(inMat)
% Input handling:
if nargin == 0 || isempty(inMat)
inMat = magic(5);
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
rowsCell = num2cell(inMat,2);
nRows = size(inMat,1);
p = cell(nRows,1);
for indR = 1:nRows
r = nchoosek(1:nRows,indR);
p{indR} = cell2mat(reshape(rowsCell(r.',:).',indR,1,[]));
end
See also:
The perms function, as it might come in handy in what you're doing.
This question.
with square matrix A
v = 1:size(A,1);
a = nchoosek(v,2);
B = zeros(2,size(A,1),length(a));
for i = 1:length(a)
B(:,:,i) = A(a(i,:)',:);
end
Each layer of array B is a 2 row matrix with the row combos from A
Not the most readable answer, but just for the sake of a one-liner :-)
A = randn(5,3); % example matrix
N = 2; % number of rows to pick each time
result = permute(reshape(A(nchoosek(1:size(A,1), N).', :), N, [], size(A,2)), [1 3 2]);
The result is a 3D array, such that each third-dim slice gives one of the a submatrices of A.
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
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.
Hey there, I've been having difficulty writing the matlab equivalent of the conv(x,y) function. I cant figure out why this gives the incorrect output. For the arrays
x1 = [1 2 1] and x2 = [3 1 1].
Here's what I have
x1 = [1 2 1];
x2 = [3 1 1];
x1len = leng(x1);
x2len = leng(x2);
len = x1len + x2len - 1;
x1 = zeros(1,len);
x2 = zeros(1,len);
buffer = zeros(1,len);
answer = zeros(1,len);
for n = 1:len
buffer(n) = x(n);
answer(n) = 0;
for i = 1:len
answer(n) = answer(n) + x(i) * buffer(i);
end
end
The matlab conv(x1,x2) gives 3 7 6 3 1 as the output but this is giving me 3 5 6 6 6 for answer.
Where have I gone wrong?
Also, sorry for the formatting I am on opera mini.
Aside from not having x defined, and having all zeroes for your variables x1, x2, buffer, and answer, I'm not certain why you have your nested loops set up like they are. I don't know why you need to reproduce the behavior of CONV this way, but here's how I would set up a nested for-loop solution:
X = [1 2 1];
Y = [3 1 1];
nX = length(X);
nY = length(Y);
nOutput = nX+nY-1;
output = zeros(1,nOutput);
for indexY = 1:nY
for indexX = 1:nX
indexOutput = indexY+indexX-1;
output(indexOutput) = output(indexOutput) + X(indexX)*Y(indexY);
end
end
However, since this is MATLAB, there are vectorized alternatives to looping in this way. One such solution is the following, which uses the functions SUM, SPDIAGS, and FLIPUD:
output = sum(spdiags(flipud(X(:))*Y));
In the code as given, all vectors are zeroed out before you start, except for x which is never defined. So it's hard to see exactly what you're getting at. But a couple of things to note:
In your inner for loop you are using values of buffer which have not yet been set by your outer loop.
The inner loop always covers the full range 1:len rather than shifting one vector relative to the other.
You might also want to think about "vectorizing" some of this rather than nesting for loops -- eg, your inner loop is just calculating a dot product, for which a perfectly good Matlab function already exists.
(Of course the same can be said for conv -- but I guess you're reimplementing either as homework or to understand how it works?)