How get an output from a function in another function? - matlab

I have a function Matrices that gives me Along. I want Along from first function to pass another function MatricesElse as an argument. This code has error, why?
function theOutput = Matrices()
theOutput = Along;
function MatricesElse(Along)
disp(theInput); % // Will print value of Along returned from first function,
syms teta q u w Se Sth v p r o Y SR SA s
% // Aircraft Equations of Longitudinal Motion
Ilong=[1 0 0 0;0 1 0 0; 0 1 0 0;0 0 0 1];
Xlong=[teta;q;u;w];
Ulong=[Se;Sth];
Xlong=(inv(s*Ilong-Along))*Blong*Ulong;
teta=Xlong(1,1)
q=Xlong(2,1)
u=Xlong(2,1)
w=Xlong(3,1)
% // Aircraft Equations of Lateral Motion
Ilat=[1 0 0 0 0;0 1 0 0 0;0 0 1 0 0;0 0 0 1 0;0 0 0 0 1];
Xlat=[v;p;r;o;Y];
Ulat=[SR;SA];
Xlat=(inv(s*I-Alat))*Blat*Ulong;
v=Xlat(1,1)
p=Xlat(2,1)
r=Xlat(3,1)
o=Xlat(4,1)
Y=Xlat(5,1)
end

Short explanation: you are trying to call a private variable of function Matrices() outside of this function, that's why it doesn't work.
This code should work. Note that the name CalcMatrix can differ from theOutput and Along, but all of these variables have the same content:
function main
CalcMatrix = Matrices()
MatricesElse(CalcMatrix)
function theOutput = Matrices()
theOutput = Along;
function MatricesElse(Along)
disp(theInput); % // Will print value of Along returned from first function,
syms teta q u w Se Sth v p r o Y SR SA s
% // Aircraft Equations of Longitudinal Motion
Ilong=[1 0 0 0;0 1 0 0; 0 1 0 0;0 0 0 1];
Xlong=[teta;q;u;w];
Ulong=[Se;Sth];
Xlong=(inv(s*Ilong-Along))*Blong*Ulong;
teta=Xlong(1,1)
q=Xlong(2,1)
u=Xlong(2,1)
w=Xlong(3,1)
% // Aircraft Equations of Lateral Motion
Ilat=[1 0 0 0 0;0 1 0 0 0;0 0 1 0 0;0 0 0 1 0;0 0 0 0 1];
Xlat=[v;p;r;o;Y];
Ulat=[SR;SA];
Xlat=(inv(s*I-Alat))*Blat*Ulong;
v=Xlat(1,1)
p=Xlat(2,1)
r=Xlat(3,1)
o=Xlat(4,1)
Y=Xlat(5,1)

Related

Undefined function or variable for 3dos mechanism

I tried to make a 3dof(3 degrees of freedom mechanism) in matlab but i get this error and i don't know why.
this is for a school project and i need to simulate a human finger.
the code is running normal but after i enter the values for the angles it says that A,B,C are
undefined and i don't know why
a1 = input('valuarea lui q1(grade):');
a2 = input('valuarea lui q2(grade):');
a3 = input('valuarea lui q3(grade):');
L1=35;
L2=45;
L3=30;
z = [-10 10];
plot(z,10);
grid ON;
O=[0;0;0;1];
m= linspace(pi/2,pi/2+a1*pi/180,100);
n = linspace(-pi/2,a2*pi/180,100);
k=linspace(-pi/2,a3*pi/180,100);
for a=1:100
[A1,B1,C1] = Transform(m(a),n(a),k(a),L1,L2,L3);
x = [O(1) A(1) B(1) C(1)];
y = [O(2) A(2) B(2) C(2)];
Cx(i)= C1(1);
Cy(i) = C1(2);
i=i+1;
Plot = plot(x,y,'r',...1
'LineWidth',1);
title('Sumularea unui deget');
plot(Cx,Cy,'--g',...
'LineWidth',1);
pause(0.075);
delete(Plot);
end
plot(x,y,'r',...
'LineWidth',3);
function [A,B,C ] = Transform( m,n,p,l1,l2,l3 )
P = [0;0;0;1];
T1 = [cos(m) -sin(m) 0 0;sin(m) cos(m) 0 0;0 0 1 0; 0 0 0 1];
T2 = [cos(n) -sin(n) 0 11;sin(n) cos(n) 0 0;0 0 1 0; 0 0 0 1];
T3 = [cos(p) -sin(p) 0 12;sin(p) cos(p) 0 0;0 0 1 0; 0 0 0 1];
T4 = [1 0 0 13;0 1 0 0; 0 0 1 0; 0 0 0 1];
A = T1*T2*P;
B = T1*T2*T3*P;
C = T1*T2*T3*T3*P;
end
In your main function, this is the first use of the variables:
x = [O(1) A(1) B(1) C(1)];
They are never written previously. Instead A1 is written, which is a different variable. I guess you mixed the two up.

How to fix the plot of the symbolic eigenvalues of the 1st matrix (matlab)?

I'm calculating the eigenvalues of a 8x8-matrix including a symbolic variable "W". Plotting the 8 eigenvalues as functions of W returns a strange result in the plot which looks like someone rode his bike over my diagram.
For the 2nd matrix, where I just set some off-diagonal elements equal to 0, everything works fine. But I don't know what the problem with the 1st one is.
syms W;
w0=1/780;
wl=1/1064;
h=1; % for now this seems unnecessary, but I want to change this value later on
% This is the 1st matrix which causes some strange plotting results
A=h*[w0+3*wl 2*W 0 0 0 sqrt(3)*W 0 0;
2*W 4*wl 0 0 0 0 0 0;
0 0 2*wl+w0 sqrt(3)*W 0 0 0 sqrt(2)*W;
0 0 sqrt(3)*W 3*wl 0 0 0 0;
0 0 0 0 wl+w0 sqrt(2)*W 0 0;
sqrt(3)*W 0 0 0 sqrt(2)*W 2*wl 0 0;
0 0 0 0 0 0 w0 W;
0 0 sqrt(2)*W 0 0 0 W wl];
% This is the 2nd matrix for which everything is working fine
B=h*[w0+3*wl 2*W 0 0 0 0 0 0;
2*W 4*wl 0 0 0 0 0 0;
0 0 2*wl+w0 sqrt(3)*W 0 0 0 0;
0 0 sqrt(3)*W 3*wl 0 0 0 0;
0 0 0 0 wl+w0 sqrt(2)*W 0 0;
0 0 0 0 sqrt(2)*W 2*wl 0 0;
0 0 0 0 0 0 w0 W;
0 0 0 0 0 0 W wl];
X = eig(A);
X2 = eig(B);
eva22 = X2(1);
eva1 = X(1);
figure(1);
fplot(X2,[-0.002 0.002]);
hold on;
fplot(X,[-0.002 0.002]);
hold off;
xlabel('Rabi frequency [THz]','FontSize',11);
ylabel('dressed states','FontSize',11);
grid on;
box on;
I'm expecting the plot for matrix A to just be similar to the plot of matrix B, but somehow it doesn't work properly. I'd appreciate some tips and tricks how to fix this.
The second plot looks like that because the eigenvalues of B are imaginary. When using plot(), it plots the real part of complex numbers by default, but apparently fplot() doesn't. You can do fplot(real(X), [-0.002 0.002]) instead to plot just the real part of the eigenvalues (assuming that's what you want).

How to count the number of 1's from the total matrix

I have code like below:
N=10;
R=[1 1 1 1 1 0 0 0 0 0;1 1 1 1 1 1 1 1 1 1];
p=[0.1,0.2,0.01];
B = zeros(N , N);
B(1:N,1:N) = eye(N);
C=[B;R];
for q=p(1:length(p))
Rp=C;
for i=1:N
if(rand < p)
Rp(i,:) = 0;
end
end
end
from this code I vary the value of p. So for different value of p, i am getting different Rp. Now I want to get the total number of "1"'s from each Rp matrix. it means may be for p1 I am getting Rp1=5, for p2, Rp=4.
For example
Rp1=[1 0 0 0 0;0 1 0 0 0;0 0 0 0 0],
Rp2=[1 0 0 0 0;0 1 0 0 0;1 0 0 0 0],
Rp3=[0 0 0 0 0;0 1 0 0 0;0 0 0 0 0],
So total result will be 2,3,1.
I want to get this result.
If the matrix contains only 0 and 1 you are trying to count the nonzero values and there is a function for that called nnz
n = nnz(Rp);
As I mentioned in the comments you should replace
if(rand < p)
with
if(rand < q)
Then you can add the number of nonzero values to a vector like
r = [];
for q=p(1:length(p))
Rp=C;
for i=1:N
if(rand < p)
Rp(i,:) = 0;
end
end
r = [r nnz(Rp)];
end
Then r will contain your desired result. There are many ways to improve your code as mentioned in other answers and comments.
Assuming Rp is your matrix, then simply do one of the following:
If your matrix only contains zeros and ones
sum(Rp(:))
Or if your matrix contains multiple values:
sum(Rp(:)==1)
Note that for two dimensional matrices sum(Rp(:)) is the same as sum(sum(Rp))
I think your real question is how to save this result, you can do this by assigning it to an indexed varable, for example:
S(count) = sum(Rp(:));
This will require you to add a count variable that increases with one every step of the loop. It will be good practice (and efficient) to initialize your variable properly before the loop:
S = zeros(length(p),1);
If you need to count the 1's in any matrix M you should be able to do sum(M(:)==1)

Plot the density of a matrix

Good day,
In Matlab I have got a matrix which is very sparse. Now I would like to plot the 'density' of the matrix. Let's say I have a matrix A:
A = [3 0 0
0 2 0
0 0 1];
Now the plot should look something like:
x
x
x
So there should be a dot (or something else) at each location (row, column) in which matrix A has got a nonzero value.
Any ideas?
spy is what you need:
% taken from MatLab documentation
B = bucky;
spy(B)
Consider something like this:
subs = zeros(0,2);
for ind = [find(A)']
[r,c] = ind2sub(size(A), ind);
subs = [subs; [r,c]];
end
scatter(subs(:,2), subs(:,1));
set(gca,'YDir','Reverse')
xlim([1 size(A,2)])
ylim([1 size(A,1)])
Which, for the matrix A:
0 1 0 1 1
0 0 0 0 0
0 1 0 0 0
0 1 0 1 1
0 0 1 1 0
Gives you the following scatter plot:
What about this :
A=[3 0 0; 0 2 0; 0 0 1];
imagesc(A)

How to calculate the centroid of a matrix?

I have the following 5x5 Matrix A:
1 0 0 0 0
1 1 1 0 0
1 0 1 0 1
0 0 1 1 1
0 0 0 0 1
I am trying to find the centroid in MATLAB so I can find the scatter matrix with:
Scatter = A*Centroid*A'
If you by centroid mean the "center of mass" for the matrix, you need to account for the placement each '1' has in your matrix. I have done this below by using the meshgrid function:
M =[ 1 0 0 0 0;
1 1 1 0 0;
1 0 1 0 1;
0 0 1 1 1;
0 0 0 0 1];
[rows cols] = size(M);
y = 1:rows;
x = 1:cols;
[X Y] = meshgrid(x,y);
cY = mean(Y(M==1))
cX = mean(X(M==1))
Produces cX=3 and cY=3;
For
M = [1 0 0;
0 0 0;
0 0 1];
the result is cX=2;cY=2, as expected.
The centroid is simply the mean average computed separately for each dimension.
To find the centroid of each of the rows of your matrix A, you can call the mean function:
centroid = mean(A);
The above call to mean operates on rows by default. If you want to get the centroid of the columns of A, then you need to call mean as follows:
centroid = mean(A, 2);