I've written this simple function on Matlab:
function [A] = tries (a, b, c, d)
global S CdM AdA
D = #(Z, Vx, Vy, Vz) 0.5*S*(Vx.^2 + Vy.^2 + Vz.^2)*CdM(sqrt(Vx.^2 + Vy.^2 + Vz.^2))*AdA(Z);
A = D(a, b, c, d);
end
but I keep getting this error:
"Index exceeds matrix dimensions"
and it says that the error is in line 3.
When I put the same text in the main function (and not in a separate one) it works perfectly.
Anything in mind what the problem might be?
The only item with index in line 3 is
AdA(Z)
that reading the function should be equal to AdA(a). So Z is useless.
D2 = #(Vx, Vy, Vz) 0.5*S*(Vx.^2 + Vy.^2 + Vz.^2)*CdM(sqrt(Vx.^2 + Vy.^2 + Vz.^2));
A = D2(b, c, d)*AdA(a);
but, ignoring what AdA is and where Z (that is equal to a) comes from, try to force your function to display dimensions in order to see if they should match when the function is called.
disp(size(AdA));
disp(a);
Related
I'm trying to solve the system below in Matlab. This system is a discrete system. I need to convert to a state space model system, to extract 4 matrices. Then find the transfer function.
y(k+2) + 4y(k+1) + 5y(k)= u(k+2)+2u(k+1)+u(k).
I solved this by hands and I found the four matrices:
A=[0,1:-5,-4]
B=[-2;4]
C=[1,0,0]
D=[1]
My problem is when I try to run my below code I got this error:
Error using ss2tf (line 26)
The A and C matrices must have the same number of columns.
Error in no1 (line 5)
[N1,D1]=ss2tf(A,B,C,D,1);
My Matlab code:
A=[0,1;-5,-4];
B=[-2;4];
C=[1,0,0];
D=[1];
[N1,D1]=ss2tf(A,B,C,D,1);
H=tf(N1,D1)
I expect to get a transfer function
Don't forget that you are dealing with a discrete-time system (add 1as third argument to ss2tf). If you correct the C matrix as already noticed in the comment, then the following code will do what you want:
A = [0,1;-5,-4];
B = [-2;4];
C = [1,0];
D = 1;
[N1,D1] = ss2tf(A,B,C,D);
H = tf(N1,D1,1)
H =
z^2 + 2 z + 1
-------------
z^2 + 4 z + 5
I'm given the a(k) matrix and e(n) and I need to compute y(n) from the following eq:
y(n) = sum(k = 1 to 10 )( a(k)*y(n-k) ) + e(n).
I have the a matrix(filter coefficients) and the e matrix (the residual), therefore there is only 1 unknown: y, which is built by the previous 10 samples of y.
An example to this equation:
say e(0) (my first residual sample) = 3
and y(-10) to y(-1) = 0
then y(0), my first sample in the signal y, would just be e(0) = 3:
y(0) = a(1)*y(-1) + a(2)*y(-2) + .... + a(10)*y(-10) + e(0) = e(0) = 3
and if e(1) = 4, and a(1) = 5, then
y(1) = a(1)*y(0) + a(2)*y(-1) + a(3)&y(-2) + ... + a(10)*y(-9) + e(1) = 19
The problem is
I don't know how to do this without loops because, say, y(n) needs y(n-1), so I need to immediately append y(n-1) into my matrix in order to get y(n).
If n (the number of samples) = say, 10,000,000, then using a loop is not ideal.
What I've done so far
I have not implemented anything. The only thing I've done for this particular problem is research on what kind of Matlab functions I could use.
What I need
A Matlab function that, given an equation and or input matrix, computes the next y(n) and automatically appends that to the input matrix, and then computes the next y(n+1), and automatically append that to the input matrix and so on.
If there is anything regarding my approach
That seems like it's on the wrong track, or my question isn't clear enough, of if there is no such matlab function that exists, then I apologize in advance. Thank you for your time.
Why am I getting this error? The matrices are absolutely of the same size:
L=rand(4,1000);
for i=1:1000;
A(i)=logzn(0.1,0.4,L(4,i));
B(i)=logzn(0.3,0.7,L(4,i));
C(i)=logzn(0.5,1.0,L(4,i));
end
F=(~A&B | ~B&C);
Here's the logzn function:
function [ y ] = logzn( aMin,aMax,x )
if ((aMin<=x)&&(aMax>=x))
y=1;
else
y=0;
end
Here's the error I get:
Error using &
Matrix dimensions must agree.
The error means exactly what it says, that A, B, and C are not the same size. You can check it with:
isequal(size(A), size(B)) && isequal(size(A), size(C))
That being said, the code as you've posted it doesn't have any issues; however if the error is in fact coming from these lines of code, you must have initialized A, B, and C to be different sizes somewhere else in the script (or you potentially used the same variable names previously and didn't clear them). You will want to pre-allocate them before the loop to ensure they are the same size.
L = rand(4, 1000);
[A, B, C] = deal(zeros(size(L,2), 1));
for k = 1:size(L,2);
A(k)=logzn(0.1,0.4,L(4,k));
B(k)=logzn(0.3,0.7,L(4,k));
C(k)=logzn(0.5,1.0,L(4,k));
end
F=(~A&B | ~B&C);
I was asked in an assignment to use Euler's method to determine the values of t and y from t=0:1000. I have all the basic code and parameters down but when i put my Euler's equation in I get the error code
In an assignment A(I) = B, the number of
elements in B and I must be the same.
Error in Project1 (line 24)
Ay(i+1) = Ay(i) + (dAy)*x;
How could I change these variables between vectors and scalars to allow the equation to run? My full code can be found below:
dt=x;
Ay=zeros(1,1001);
Ay0=1250;
Ay(1) = Ay0;
t=0;
y=0;
t=0:dt:1000;
for i=1:1000
if y > 10
Qout=3*(y-10).^1.5;
else
Qout=0;
end
Qin=1350*sin(t).^2;
dAy=Qin-Qout;
Ay(i+1) = Ay(i) + dAy*dt;
end
plot(t,y);
The issue is that your variable "Qin" is not a number it is a vector containing sin values of the whole vector t. Similarly your "dAy" is also a vector. Hence it cannot be stored in a variable Ay.
if your dt =x = 1, just replace sin(t) with sin(i) i.e.
replace
Qin=1350*sin(t).^2;
by
Qin=1350*sin(i).^2;
The problem lies in the line of your code:
Ay(i+1) = Ay(i) + dAy*dt;
dAy*dt returns a vector.
When you add it to Ay(i) you still end up with a vector.
Ay(i+1) is a SINGLE element within a vector.
You Cannot assign a vector quantity to an element within a vector.
I'm trying to execute a custom function within MatLab, such that x which is a vector is actually the exponent of a constant e. I've tried placing the dot in numerous places, but it keeps throwing an error which is telling me to use the . before the ^, which is not what I want to do on this occasion. Y needs to return a vector and not a constant.
x = [0:0.1:1];
function y = hyperT(x)
e = exp(1);
y = ((e^x*2)-1)/((e^x*2)+1);
end
I've taken the . out for the purpose of this thread.
To get a vector, you can use (MATLAB power operator):
y = ((e.^x*2) - 1) ./ (e.^(x*2) + 1);
The . operator basically means "element-wise". For example, if you are multiplying two vectors, x = [x1, x2, x3] and y = [y1, y2, y3], then using the .* operator multiplies each element by the corresponding element in the other vector, while using the * operator without the . performs an inner product (matrix multiplication):
x.*y = [x1y1, x2y2, x3y3]
x*y = error (inner matrix dimensions must agree)
x'*y = [x1y1, x2y1, x3y1;
x2y1, x2y2, x3y2;
x1y3, x2y3, x3y3]
x*y' = x1y1 + x2y2 + x3y3
Note that the ' in the above transposes the vector.
Some operators automatically broadcast because their use is un-ambiguous. Thus you do not need the . with the + and - operators. Oddly enough, the division operator does not auto-broadcast, so you need to use ./ there (MATLAB rdivide). I am not sure what it is doing when you omit the ., but it seems to be well defined and consistent at least.
In general, you can perform any operation (even one that you define) element-wise between two vectors, or between a constant and a vector, by using bsxfun (MATLAB bsxfun). For example, to perform the power operation that you are asking about, you could do:
bsxfun(#power, e, x)
or
bsxfun(#power, e, x*2)
This is actually a super-efficient way to do a lot of neat things, but in your case the functionality is already built in with .^.
Edit: Added some links
you may use:
expm(x) which is matrix exponential.