Use a for loop in Matlab with increments of 15 - matlab

I'm very new to matlab and I have to use a for loop with increments of 15 for a coordinate point.
I've tried
for theta = 0; and(theta <= 360, theta >= 0)
theta +15;
end
and
theta = 0;
for theta = [0:360];
theta = theta+15;
end
the second one is the closes ive gotten to making it work but it still goes over 360, the first seems to make more sense but it gives me an error saying theta was previously used as a variable.
y12 = sind(theta) + cosd(theta);
y1 = sind(theta);
y2=cosd(theta);
plot(theta,y12)
plot(theta,y1)
plot(theta,y2)
title 'Project 7D - 3 curves(0-2*pi)'
xlabel 'Angle in Radian'
ylabel 'Function Value'

This doesn't actually need a loop.
theta=0:15:360;
y12 = sind(theta) + cosd(theta);
y1 = sind(theta);
y2 = cosd(theta);
hold all;
plot(theta,y12)
plot(theta,y1)
plot(theta,y2)
title 'Project 7D - 3 curves(0-2*pi)'
xlabel 'Angle in Radian'
ylabel 'Function Value'

for theta=0:15:360
y12 = sind(theta) + cosd(theta);
y1 = sind(theta);
y2=cosd(theta);
hold all;
plot(theta,y12)
plot(theta,y1)
plot(theta,y2)
title 'Project 7D - 3 curves(0-2*pi)'
xlabel 'Angle in Radian'
ylabel 'Function Value'
end
0:15:360 starts at 0 and increments 15 each time and ends at 360

Related

Line with NumericRuler-properties in Matlab

I want to create a relative axis in Matlab like the $\Delta I$-rulers in the following plot.
Before I start writing up a function that constructs it manually, I would like to know if there's way of creating an object with the NumericRuler-properties (like the default axes of a figure())
So I ended up using the link provided by Sardar Usama's comment as inspiration and wrote a function to create an axes-object relative to the values of a "parent"-axes:
function ax = create_value_axes(hAx, pos)
%% ax = create_value_axes(hAx, pos)
%
% Create axes at the value points of hAx.
%
% pos(1) = x-position
% pos(2) = y-position
% pos(3) = x-width
% pos(4) = y-width
%
% Get "parent" position and value limits
hAx_pos = hAx.Position;
hAx_xlm = hAx.XLim;
hAx_ylm = hAx.YLim;
% Get relative position increment pr value increment
x_step = hAx_pos(3) / (hAx_xlm(2) - hAx_xlm(1));
y_step = hAx_pos(4) / (hAx_ylm(2) - hAx_ylm(1));
% Set position
subaxes_abs_pos(1) = (pos(1)-hAx_xlm(1)) * x_step + hAx_pos(1);
subaxes_abs_pos(2) = (pos(2)-hAx_ylm(1)) * y_step + hAx_pos(2);
subaxes_abs_pos(3) = pos(3) * x_step;
subaxes_abs_pos(4) = pos(4) * y_step;
% Create axes
ax = axes('Position', subaxes_abs_pos);
% Remove background
ax.Color = 'none';
end
Sidenote: I found that I didn't need plotboxpos to get the correct positions of the "parent"-axes, using Matlab r2019b on macOS Mojave 10.14.6
Anyway, this is what I end up with:
Using the code:
% Just some random data
mockup_data_ild = [-10 -7 -4 0 4 7 10];
mockup_data_itd_45 = [-40 -20 -10 0 10 20 40];
mockup_data_itd_60 = [-30 -15 -5 0 5 15 30];
% Create figure
figure('Color', 'w')
x_axis_offset = [0 30];
hold on
% Plot 45 dB result
p1 = plot_markers(x_axis_offset(1) + mockup_data_ild, mockup_data_itd_45, ii);
% Plot 60 dB results
p2 = plot_markers(x_axis_offset(2) + mockup_data_ild, mockup_data_itd_60, ii);
p2.Color = p1.Color;
p2.HandleVisibility = 'off';
hold off
% Set axes properties
ax = gca;
ax.XAxis.TickValues = [x_axis_offset(1) x_axis_offset(2)];
ax.XAxis.TickLabels = {'45 dB' '60 dB'};
ax.XAxis.Limits = [x_axis_offset(1)-15 x_axis_offset(2)+15];
ax.XAxisLocation = 'top';
ax.YAxis.Limits = [-80 100];
ax.YAxis.Label.String = 'Interaural Time Difference, \Deltat, in samples';
ax.YGrid = 'on';
% Create 45 dB axis
ax2 = create_DeltaI_axis(ax, x_axis_offset(1));
% Create 60 dB axis
ax3 = create_DeltaI_axis(ax, x_axis_offset(2));
% Create legend
leg = legend(ax, {'P1'});
leg.Location = 'northwest';
%% Helpers
function ax = create_DeltaI_axis(hAx, x_pos)
y_pos = -70;
y_height = 170;
range = 20;
ax = create_value_axes(hAx, [x_pos-range/2 y_pos range y_height]);
ax.XAxis.TickValues = [0 .25 .5 .75 1];
ax.XAxis.TickLabels = {'-10'
'-5'
'0'
'5'
'10'};
ax.XAxis.Label.String = '\DeltaI';
ax.XGrid = 'on';
ax.XMinorGrid = 'on';
ax.YAxis.Visible = 'off';
end
function p = plot_markers(x, y, ii)
markers = {'square','^', 'v', 'o', 'd'};
p = plot(x, y);
p.LineWidth = 1.5;
p.LineStyle = 'none';
p.Marker = markers{ii};
end

Unsure about how to use event function in Matlab

I am trying to plot a state-space diagram, as well as a time-history diagram, of a dynamical system. There's a catch, though. The state-space is divided into two halves by a plane located at x1 = 0. The state-space axes are x1, x2, x3. The x1 = 0 plane is parallel to the x2/x3 plane. The state-space above the x1 = 0 plane is described by the ODEs in eqx3, whereas the state-space below the x1 = 0 plane is described by the ODEs in eqx4.
So, there is a discontinuity on the plane x1 = 0. I have a vague understanding that an event function (function [value,isterminal,direction] = myEventsFcn(t,y)) should be used, but I do not know what values to give to "value", "isterminal", and "direction".
In my code below, I have an initial condition for eqx3, and another initial condition for eqx4. The initial condition for eqx3 is in the upper half of the state-space (x1 > 0). The orbit then hits the x1 = 0 plane and there is a discontinuity, and the eqx4 trajectory begins on this plane, but from a different point from where eqx3 ended.
Can this be done? How do I put it into a code? Do I stop the integration when the orbit reaches the plane x1 = 0?
eta = 0.05;
omega = 25;
tspan = [0,50];
initcond = [2, 3, 4]
[t,x] = ode45(#(t,x) eqx3(t,x,eta, omega), tspan, initcond);
initcond1 = [0, 1, 1]
[t,y] = ode45(#(t,y) eqx4(t,y,eta, omega), tspan, initcond1);
plot3(x(:,1), x(:,2), x(:,3),y(:,1), y(:,2), y(:,3))
xlabel('x1')
ylabel('x2')
zlabel('x3')
%subplot(222)
%plot(t, x(:,1), t,x(:,2),t,x(:,3),'--');
%xlabel('t')
function xdot = eqx3(t,x,eta,omega)
xdot = zeros(3,1);
xdot(1) = -(2*eta*omega + 1)*x(1) + x(2) - 1;
xdot(2) = -(2*eta*omega + (omega^2))*x(1) + x(3) + 2;
xdot(3) = -(omega^2)*x(1) + x(2) - 1;
end
function ydot = eqx4(t,y,eta,omega)
ydot = zeros(3,1);
ydot(1) = -(2*eta*omega + 1)*y(1) + y(2) + 1;
ydot(2) = -(2*eta*omega + (omega^2))*y(1) + y(3) - 2;
ydot(3) = -(omega^2)*y(1) + y(2) + 1;
end
function [value,isterminal,direction] = myEventsFcn(t,y)
value = 0
isterminal = 1
direction = 1
end
Without events, using a close-by smooth system
First, as the difference between the systems is the addition or subtraction of a constant vector it is easy to find an approximate smooth version of the system using some sigmoid function like tanh.
eta = 0.05;
omega = 25;
t0=0; tf=4;
initcond = [2, 3, 4];
opt = odeset('AbsTol',1e-11,'RelTol',1e-13);
opt = odeset(opt,'MaxStep',0.005); % in Matlab: opt = odeset('Refine',10);
[t,x] = ode45(#(t,x) eqx34(t,x,eta, omega), [t0, tf], initcond, opt);
clf;
subplot(121);
plot3(x(:,1), x(:,2), x(:,3));
xlabel('x1');
ylabel('x2');
zlabel('x3');
subplot(122);
plot(t, 10.*x(:,1), t,x(:,2),':',t,x(:,3),'--');
xlabel('t');
function xdot = eqx34(t,x,eta,omega)
S = tanh(1e6*x(1));
xdot = zeros(3,1);
xdot(1) = -(2*eta*omega + 1)*x(1) + x(2) - S;
xdot(2) = -(2*eta*omega + (omega^2))*x(1) + x(3) + 2*S;
xdot(3) = -(omega^2)*x(1) + x(2) - S;
end
resulting in the plots
As is visible, after t=1.2 the solution is essentially constant with x(1)=0 and the other coordinates close to zero.
With events
If you want to use the event mechanism, make ODE and event function dependent on a sign parameter S denoting the phase and the direction of the zero crossing.
eta = 0.05;
omega = 25;
t0=0; tf=4;
initcond = [2, 3, 4];
opt = odeset('AbsTol',1e-10,'RelTol',1e-12,'InitialStep',1e-6);
opt = odeset(opt,'MaxStep',0.005); % in Matlab: opt = odeset('Refine',10);
T = [t0]; TE = [];
X = [initcond]; XE = [];
S = 1; % sign of x(1)
while t0<tf
opt = odeset(opt,'Events', #(t,x)myEventsFcn(t,x,S));
[t,x,te,xe,ie] = ode45(#(t,x) eqx34(t,x,eta, omega, S), [t0, tf], initcond, opt);
T = [ T; t(2:end) ]; TE = [ TE; te ];
X = [ X; x(2:end,:)]; XE = [ XE; xe ];
t0 = t(end);
initcond = x(end,:);
S = -S % alternatively = 1-2*(initcond(1)<0);
end
disp(TE); disp(XE);
subplot(121);
hold on;
plot3(X(:,1), X(:,2), X(:,3),'b-');
plot3(XE(:,1), XE(:,2), XE(:,3),'or');
hold off;
xlabel('x1');
ylabel('x2');
zlabel('x3');
subplot(122);
plot(T, 10.*X(:,1), T,X(:,2),':',T,X(:,3),'--');
xlabel('t');
function xdot = eqx34(t,x,eta,omega,S)
xdot = zeros(3,1);
xdot(1) = -(2*eta*omega + 1)*x(1) + x(2) - S;
xdot(2) = -(2*eta*omega + (omega^2))*x(1) + x(3) + 2*S;
xdot(3) = -(omega^2)*x(1) + x(2) - S;
end
function [value,isterminal,direction] = myEventsFcn(t,x,S)
value = x(1)+2e-4*S;
isterminal = 1;
direction = -S;
end
The solution enters a sliding mode for 1.36 < t < 1.43 where (theoretically) x(1)=0 and the vector field points to the other phase from both sides. The theoretical solution is to take a linear combination that sets the first component to zero, so that the resulting direction is tangential to the separating surface. In the first variant above the sigmoid achieves something like this automatically. Using events one could add additional event functions that test the vector field for these conditions, and when they cease to persist.
A quick solution is to thicken the boundary surface, that is, test for x(1)+epsilon*S==0 so that the solution has to cross the boundary surface before triggering the event. In sliding mode, it will be immediately pushed back, giving a ping-pong or zigzag motion. epsilon has to be small to not perturb the solution too much, however not too small to avoid the triggering of too many events. With epsilon=2e-4 octave gives the following solution in a close-up to the sliding interval
The octave solver, and in some way also Matlab, will not trigger a terminal event if it happens in the first integration step. For that reason the InitialStep option was set to a rather small value, it should be about 0.01*epsilon. The full solution looks now similar to the one obtained in the first variant

How to slide a plotted line in matlab figure

I am plotting a sin and cosine using below code:
x = 0 : 0.1 : 2*pi ;
y1 = sin (x) ;
y2 = cos (x) ;
figure ;
plot(x,y1) ;
hold ;
plot(x,y2,'r')
I want to move/slide the line corresponding to sin in order to overlay on top of line corresponding to cos and want to achieve it without moving pan. I searched ob web but unable to find a simple solution.
You can plot your 2 sinus/cosinus within a function, then use a callback to update your plot, here I update the phase of the sinus plot in the callback function call_S:
function [] = slider_plot()
% Plot different plots according to slider location.
S.fh = figure('position',[300 300 300 300],....
'resize','off');
S.x = 0:.01:4*pi; %range.
S.ax = axes('unit','pix',...
'position',[20 80 260 210]);
S.sin = plot(S.x,sin(S.x),'r'); %sinus phase will move
hold on
S.cos = plot(S.x,cos(S.x),'b');
S.sl = uicontrol('style','slide',...
'position',[20 10 260 30],...
'min',0,'max',3*pi/2,'val',0,... %default phase = 0
'sliderstep',[0.1 0.1],...
'callback',{#call_S,S});
function [] = call_S(varargin)
% Callback for the phase slider.
[h,S] = varargin{[1,3]}; % calling handle and data structure.
set(S.sin,'ydata',sin(S.x + get(h,'value'))) %set the new phase
I use a slider in this case, but you could also use the position of your mouse to determine the new phase.
Result:
And you can move the slider to shift the phase:
Many thanks to #obchardon:
Below is updated version of his code which meet my requirements:
function [] = slider_plot2()
x = 0 : 0.1 : 4*pi ;
y1 = sin (x) ;
y2 = cos (x) ;
% Plot different plots according to slider location.
S.fh = figure('position',[300 300 500 500],....
'resize','off');
S.x = x; %range.
S.y2 = y2 ;
S.ax = axes('unit','pix',...
'position',[30 80 460 410]);
S.line2 = plot(S.x,y2,'r'); %sinus phase will move
hold on
S.line1 = plot(S.x,y1,'b');
S.sl = uicontrol('style','slide',...
'position',[20 10 260 30],...
'min',1,'max',length(x),'val',1,... %default phase = 0
'sliderstep',[1 1],...
'callback',{#call_S,S});
function [] = call_S(varargin)
% Callback for the phase slider.
[h,S] = varargin{[1,3]}; % calling handle and data structure.
currentPosition = floor(get(h,'value')) ;
ydata = S.y2(currentPosition:end) ;
xdata = S.x(1:end-currentPosition+1) ;
set(S.line2,'xdata',xdata,'ydata',ydata) %set the new phase
%set( S.line2,'ydata',ydata) %set the new phase

Plotting animation results in blank graph

I have written this code and it will not plot. I run it with a 0:.5:100 and get a blank graph in Matlab. As well this is a inclined plane friction problem. I need to create an animation in Matlab that shows the blocks sliding based on inputs.
%Numerical Project Code 1
%mass ratio input
mratio = input('Enter the Mass Ratio(m/M): ');
%angle input
theta = input('Enter Angle in Degrees Between 0 and 90: ');
%static coeff input
mus = input('Enter Coefficient of Static Friction: ');
%kinetic coeff input
muk = input('Enter Coefficient of Kinetic Friction: ');
%constants
g = 9.81;
%interface formating
disp('--------------------------------------------');
disp('All Friction Forces are given in terms of the mass on the slope (M)');
%Loops
%NETUP
if mratio > sind(theta)
%static only
if mratio <= (sind(theta) + (mus*cosd(theta)))
ff = g*(mratio - sind(theta));
fprintf("Friction Force = %f M Newtons\n",ff);
fprintf("The Direction of the Friction Force is down the slope and the block not moving.\n")
%kinetic only
else
ff = muk * g * cosd(theta);
fprintf("Friction Force = %f M Newtons\n",ff);
fprintf("The Direction of the Friction Force is down the slope and the block is sliding up the slope.\n");
end
%NETDOWN
elseif mratio < sind(theta)
%static only
if sind(theta) <= (mratio + (mus*cosd(theta)))
ff = g*(sind(theta) - mratio);
fprintf("Friciton Force = %f M Newtons\n",ff);
fprintf("The Direction of the Friction Force is up the slope and the block is not moving.\n")
%kinetic only
else
ff = muk * g * cosd(theta);
fprintf("Friction Force = %f M Newtons\n",ff);
fprintf("The Direction of the Friction Force is up the slope and the block is sliding down the slope.\n");
end
%NETZERO
else
fprintf("Friction Force = 0 Newtons\n");
end
%graph
for i = 0:0.01:1
mratiog = i;
if mratiog > sind(theta)
if mratiog <= (sind(theta) + (mus*cosd(theta)))
ffg = g*(mratiog - sind(theta));
else
ffg = muk * g * cosd(theta);
end
elseif mratiog < sind(theta)
if sind(theta) <= (mratiog + (mus*cosd(theta)))
ffg = g*(sind(theta) - mratiog);
else
ffg = muk * g * cosd(theta);
end
else
ffg = 0;
end
plot (ffg,mratio, 'r:')
end
In addition to Erik's comments I see two other issues:
the plot changes its axis with each new iteration, so you can not see
the animation properly. It would work better if you calculate all
your points before plotting them. Then you can use min and max of data
dimensions to set axis limits. If you don't use 'hold on' you need to set the limits in each iteration.
you need to use 'pause' to slow down the
animation. otherwise you see only the last data point.
Here is a working example of the 'graph' part:
%graph
i_arr = 0:0.01:1;
n = numel(i_arr);
ffg_mratio_arr = zeros(n, 2);
for i = 1:n
mratiog = i_arr(i);
if mratiog > sind(theta)
if mratiog <= (sind(theta) + (mus*cosd(theta)))
ffg = g*(mratiog - sind(theta));
else
ffg = muk * g * cosd(theta);
end
elseif mratiog < sind(theta)
if sind(theta) <= (mratiog + (mus*cosd(theta)))
ffg = g*(sind(theta) - mratiog);
else
ffg = muk * g * cosd(theta);
end
else
ffg = 0;
end
ffg_mratio_arr(i,:) = [ffg mratio];
end
% calculating the axis limits
x_min = min(ffg_mratio_arr(:, 1))-1;
x_max = max(ffg_mratio_arr(:, 1))+1;
y_min = min(ffg_mratio_arr(:, 2))-1;
y_max = max(ffg_mratio_arr(:, 2))+1;
% animation
figure;
for i = 1:n
plot (ffg_mratio_arr(i,1), ffg_mratio_arr(i,2), 'ro');
xlim([x_min x_max]);
ylim([y_min y_max]);
pause(0.01);
end

How to find Orientation of axis of contour in matlab?

I want to find Orientation, MajorAxisLengthand MinorAxisLength of contour which is plotted with below code.
clear
[x1 , x2] = meshgrid(linspace(-10,10,100),linspace(-10,10,100));
mu = [1,3];
sigm = [2,0;0,2];
xx_size = length(mu);
tem_matrix = ones(size(x1));
x_mesh= cell(1,xx_size);
for i = 1 : xx_size
x_mesh{i} = tem_matrix * mu(i);
end
x_mesh= {x1,x2};
temp_mesh = [];
for i = 1 : xx_size
temp_mesh = [temp_mesh x_mesh{i}(:)];
end
Z = mvnpdf(temp_mesh,mu,sigm);
z_plat = reshape(Z,size(x1));
figure;contour(x1, x2, z_plat,3, 'LineWidth', 2,'color','m');
% regionprops(z_plat,'Centroid','Orientation','MajorAxisLength','MinorAxisLength');
In my opinion, I may have to use regionprops command but I don't know how to do this. I want to find direction of axis of contour and plot something like this
How can I do this task? Thanks very much for your help
Rather than trying to process the graphical output of contour, I would instead recommend using contourc to compute the ContourMatrix and then use the x/y points to estimate the major and minor axes lengths as well as the orientation (for this I used this file exchange submission)
That would look something like the following. Note that I have modified the inputs to contourc as the first two inputs should be the vector form and not the output of meshgrid.
% Compute the three contours for your data
contourmatrix = contourc(linspace(-10,10,100), linspace(-10,10,100), z_plat, 3);
% Create a "pointer" to keep track of where we are in the output
start = 1;
count = 1;
% Now loop through each contour
while start < size(contourmatrix, 2)
value = contourmatrix(1, start);
nPoints = contourmatrix(2, start);
contour_points = contourmatrix(:, start + (1:nPoints));
% Now fit an ellipse using the file exchange
ellipsedata(count) = fit_ellipse(contour_points(1,:), contour_points(2,:));
% Increment the start pointer
start = start + nPoints + 1;
count = count + 1;
end
orientations = [ellipsedata.phi];
% 0 0 0
major_length = [ellipsedata.long_axis];
% 4.7175 3.3380 2.1539
minor_length = [ellipsedata.short_axis];
% 4.7172 3.3378 2.1532
As you can see, the contours are actually basically circles and therefore the orientation is zero and the major and minor axis lengths are almost equal. The reason that they look like ellipses in your post is because your x and y axes are scaled differently. To fix this, you can call axis equal
figure;contour(x1, x2, z_plat,3, 'LineWidth', 2,'color','m');
axis equal
Thank you #Suever. It help me to do my idea.
I add some line to code:
clear
[X1 , X2] = meshgrid(linspace(-10,10,100),linspace(-10,10,100));
mu = [-1,0];
a = [3,2;1,4];
a = a * a';
sigm = a;
xx_size = length(mu);
tem_matrix = ones(size(X1));
x_mesh= cell(1,xx_size);
for i = 1 : xx_size
x_mesh{i} = tem_matrix * mu(i);
end
x_mesh= {X1,X2};
temp_mesh = [];
for i = 1 : xx_size
temp_mesh = [temp_mesh x_mesh{i}(:)];
end
Z = mvnpdf(temp_mesh,mu,sigm);
z_plat = reshape(Z,size(X1));
figure;contour(X1, X2, z_plat,3, 'LineWidth', 2,'color','m');
hold on;
% Compute the three contours for your data
contourmatrix = contourc(linspace(-10,10,100), linspace(-10,10,100), z_plat, 3);
% Create a "pointer" to keep track of where we are in the output
start = 1;
count = 1;
% Now loop through each contour
while start < size(contourmatrix, 2)
value = contourmatrix(1, start);
nPoints = contourmatrix(2, start);
contour_points = contourmatrix(:, start + (1:nPoints));
% Now fit an ellipse using the file exchange
ellipsedata(count) = fit_ellipse(contour_points(1,:), contour_points(2,:));
% Increment the start pointer
start = start + nPoints + 1;
count = count + 1;
end
orientations = [ellipsedata.phi];
major_length = [ellipsedata.long_axis];
minor_length = [ellipsedata.short_axis];
tet = orientations(1);
x1 = mu(1);
y1 = mu(2);
a = sin(tet) * sqrt(major_length(1));
b = cos(tet) * sqrt(major_length(1));
x2 = x1 + a;
y2 = y1 + b;
line([x1, x2], [y1, y2],'linewidth',2);
tet = ( pi/2 + orientations(1) );
a = sin(tet) * sqrt(minor_length(1));
b = cos(tet) * sqrt(minor_length(1));
x2 = x1 + a;
y2 = y1 + b;
line([x1, x2], [y1, y2],'linewidth',2);