Plotting realizations of a stochastic process in the same plot - matlab

I want to plot multiple realizations of a stochastic process in matlab. For a single realization I have the following code:
N = 80;
T = dt*N;
dWt = zeros(1,N);
S= repmat(S0,1,N);
S(1) = S0;
dWt = sqrt(dt) * randn;
for t=2:N
dWt(t) = sqrt(dt)*randn;
dSt = k*(mu-S(t-1))*dt + sigma*S(t-1)*dWt(t);
S(t) = S(t-1)+dSt;
end
plot(handles.pMeasure, [0:dt:T],[S0,S]);
I want to replicate this loop n times and plot the results in one plot.

You could add an additional for loop, but it would be best to vectorize everything and calculate all n instances at once:
k = ...
mu = ...
sigma = ...
S0 = ... % Initial condition
dt = ... % Time step
n = ... % Number of instances
N = 80; % Number of time steps, not counting initial condition
T = dt*N; % Final time
rng(1); % Always seed random number generator
dWt = sigma*sqrt(dt)*randn(n,N); % Calculate Wiener increments
S = zeros(n,N+1); % Allocate
S(:,1) = S0; % Set initial conditions
for t = 2:N+1
S(:,t) = S(:,t-1) + k*(mu-S(:,t-1))*dt + S(:,t-1).*dWt(:,t-1);
end
plot(handles.pMeasure,0:dt:T,S)
There are further ways to optimize this if want or you can also try sde_euler in my SDETools Matlab toolbox:
k = ...
mu = ...
sigma = ...
dt = ... % Time step
n = ... % Number of instances
N = 80; % Number of time steps, not counting initial condition
T = dt*N; % Final time
f = #(t,y)k*(mu-y); % Diffusion function
g = #(t,y)sigma*y; % Drift function
t = 0:dt:T; % Time vector
S0 = zeros(n,1); % Initial conditions
opts = sdeset('RandSeed',1,...
'SDEType','Ito'); % Set random seed, specify Ito SDE
S = sde_euler(f,g,t,S0,opts); % Simulate
plot(t,S)

Related

Calculate the phase of a signal based on the generated data

I have written a simple code to calculate the phase and magnitude of a signal, based on the sinusoidal input given in my problem. I have already determined the magnitude of the signal corresponding to different values of w. More specifically, the phase I want is a vector calculated for different values of w. Notice that the signal I'm talking about is the output signal of a linear process. As matter of fact, I want the phase difference between the input u and the output y, defined for all values of w for all time steps. I have created the time and w vector in my code. Here is the main code I have written in MATAB2021a:
clc;clear;close all;
%{
Problem 2 Simulation, By M.Sajjadi
%}
%% Predifined Parameters
tMin = 0;
tMax = 50;
Ts = 0.01; % Sample Time
n = tMax/Ts; % #Number of iterations
t = linspace(tMin,tMax,n);
% Hint: Frequency Domain
wMin = 10^-pi;
wMax = 10^pi;
Tw = 10;
w = wMin:Tw:wMax; % Vector of Frequency
Nw = length(w);
a1 = 1.8;
a2 = -0.95;
a3 = 0.13;
b1 = 1.3;
b2 = -0.5;
%% Input Generation
M = numel(w);
N = length(t);
U = zeros(M,N);
Y = U; % Response to the sinusoidal Input, Which means the initial conditions are set to ZERO.
U(1,:) = sin(w(1)*t);
U(2,:) = sin(w(2)*t);
U(3,:) = sin(w(3)*t);
Order = 3; % The Order of the Differential Equation, Delay.
%% Main Loop for Amplitude and Phase
Amplitude = zeros(Nw,1); % Amplitude Values
for i=1:numel(w)
U(i,:) = sin(w(i)*t);
for j=Order+1:numel(t)
Y(i,j) = a1*Y(i,j-1) + a2*Y(i,j-2) + a3*Y(i,j-3) + ...
b1*U(i,j-1) + b2*U(i,j-2);
end
Amplitude(i) = max(abs(Y(i,:)));
end
I know I should use fft or findpeaks function in MATLAB, but I do not know how I should do it.

MATLAB's lsim() vs for-loop Simulation // Different results for the same system

I've spent quite some time trying to simulate a simple SISO system using two approaches:
1) Using lsim() in MATLAB
2) By writing down the difference equations myself and iterate over them in a loop.
I was never able to get the same simulation results from both approaches, and I have no idea what I am doing wrong.
I stacked my code in a single m-file so it's easier to follow. Here is the code:
function main()
clear all
clc
simulateUsing_lsim()
simulateUsing_loop()
end
%%%%%% Simulating using lsim %%%%%%%
function simulateUsing_lsim()
% Define the continuous-time closed-loop system
P = getContPlant();
[Kp,Ki,Kd] = get_PIDgains();
C = pid(Kp,Ki,Kd);
clSys_cont = feedback(C*P,1);
% Define the discrete-time closed-loop system
hk = get_sampling_time();
clSys_disc = c2d(clSys_cont,hk);
% Generate the reference signal and the time vector
[r,t] = getReference(hk);
%% Simulate and plot using lsim
figure
lsim(clSys_disc,r,t)
%% Finding and plotting the error
y = lsim(clSys_disc,r);
e = r - y;
figure
p = plot(t,e,'b--');
set(p,'linewidth',2)
legend('error')
xlabel('Time (seconds)')
ylabel('error')
% xlim([-.1 10.1])
end
%%%%%% Simulating using loop iteration (difference equations) %%%%%%%
function simulateUsing_loop()
% Get the cont-time ol-sys
P = getContPlant();
% Get the sampling time
hk = get_sampling_time();
% Get the disc-time ol-sys in SS representation
P_disc = ss(c2d(P,hk));
Ad = P_disc.A;
Bd = P_disc.B;
Cd = P_disc.C;
% Get the PID gains
[Kp,Ki,Kd] = get_PIDgains();
% Generate the reference signal and the time vector
[r,t] = getReference(hk);
%% Perform the system simulation
x = [0 0]'; % Set initial states
e = 0; % Set initial errors
integral_sum = 0; % Set initial integral part value
for i=2:1:length(t)
% Calculate the output signal "y"
y(:,i) = Cd*x;
% Calculate the error "e"
e(:,i) = y(:,i) - r(i);
% Calculate the control signal vector "u"
integral_sum = integral_sum + Ki*hk*e(i);
u(:,i) = Kp*e(i) + integral_sum + (1/hk)*Kd*(e(:,i)-e(:,i-1));
% Saturation. Limit the value of u withing the range [-tol tol]
% tol = 100;
% if abs(u(:,i)) > tol
% u(:,i) = tol * abs(u(:,i))/u(:,i);
% else
% end
% Calculate the state vector "x"
x = Ad*x + Bd*u(:,i); % State transitions to time n
end
%% Subplots
figure
plot(t,y,'b',t,r,'g--')
%% Plotting the error
figure
p = plot(t,e,'r');
set(p,'linewidth',2)
legend('error')
xlabel('Time (seconds)')
ylabel('error')
end
function P = getContPlant()
s = tf('s');
P = 1/(s^2 + 10*s + 20);
end
function [Kp,Ki,Kd] = get_PIDgains()
Kp = 350;
Ki = 300;
Kd = 50;
end
function hk = get_sampling_time()
hk = 0.01;
end
function [r,t] = getReference(hk)
[r,t] = gensig('square',4,10,hk);
end
I got the plant model P and its PID controller from this page (see equation 10), where the system is simulated against a step reference and the result looks pretty much exactly like the lsim() result (just for a single step peak).
However, the result of simulating the system using lsim() is this:
whereas, using the for loop, I got this performance:
I would highly appreciate any help or clarification why I am getting different results.

Plotting a collection of sine waves

I have the following code:
Fs = 1000;
T = 1/Fs;
L = 1000;
t = (0:L-1)*T;
k = 25:1:50;
m = 1:1:25;
where k and m are corresponding. I want to plot the 25 sine waves resulting from:
x = m*sin(2*pi*k*t);
I thought about doing it using a for loop that takes one value from m and k each time, but I'm unsure how to proceed.
Below is a very basic plotting solution. You will notice that it's very difficult to see what's going on in the plot, so you might want to consider other ways to present this data.
function q45532082
Fs = 1000;
T = 1/Fs;
L = 1000;
t = (0:L-1)*T;
k = 26:1:50;
m = 1:1:25;
%% Plotting
assert(numel(m) == numel(k)); % We make sure that the number of elements is the same.
figure(); hold on; % "hold" is needed if you want to see all curves at the same time.
for ind1 = 1:numel(m)
plot(t,m(ind1)*sin(2*pi*k(ind1)*t));
end
This is the result:
Note that the number of elements in k and m in your code is different, so I had to change it.
Using the functionality of plot you can also plot all sine waves without a loop:
Fs = 1000;
T = 1/Fs;
L = 1000;
t = (0:L-1)*T;
k = 26:1:50;
m = 1:1:25;
x = m.*sin(2.*pi.*bsxfun(#times,t.',k)); %this results in an L*25 matrix, each column is data of one wave
% or, if you have version 2016b or newer:
% x = m.*sin(2.*pi.*t.'*k);
plot(t,x) % plot all sines at ones
and as #Dev-iL noted, I also had to change k.
The result with L = 1000 is too crowded, so I plot it here with L = 50:

How to run two loops in alternating fashion on Matlab?

I would like to use Matlab to compute two finite difference loops in such a manner that if we have two equations, let's say (1) and (2), it completes one step of (1) then solves (2) for one step then (1) for the next step and then (2) and so on and so forth.
To this end, I provide the parameters of my code below:
%% Parameters
L = 5; % size of domain
T = 5; % measurement time
dx = 1e-2; % spatial step
dt = 1e-3; % time step
x0 = 0;
c = 1;
%%
t = 0:dt:T; % time vector
x = (0:dx:L)'; % spatial vector
nt = length(t);
nx = length(x);
Lx = (1/dx^2)*spdiags(ones(nx,1)*[1 -2 1],-1:1,nx,nx); % discrete Laplace operator
mu = dt/dx;
I = eye(nx,nx); % identity matrix
A = spdiags(ones(nx,1)*[-1 1 0],-1:1,nx,nx); % finite difference matrix
Then the first loop is given by
%% Finite Difference Equation (1)
% preallocate memory
u = zeros(nx,nt);
v = zeros(nx,nt);
% initial condition in time
u(:,1) = sinc((x-x0)/dx);
v(:,1) = sinc((x-x0)/dx);
for i = 1:nx-1
u(:,i+1) = ((1/(c*dt))*I+(1/dx)*A)\((1/(c*dt))*u(:,i)+v(:,i));
end
and the second equation (2) is given by
%% Finite Difference Equation (2)
% preallocate memory
u = zeros(nx,nt);
v = zeros(nx,nt);
% final condition in time
u(:,nt) = sinc((x-x0)/dt);
% initial condition in space
for j = nt:-1:2
v(:,j-1) = ((1/dx)*A+(1/(c*dt))*I)\((1/(c*dt))*v(:,j)
end
In the current format, Matlab will run the first loop i = 1:nx-1 and then the second loop j = nt:-1:2.
But I want to run the two loops as follows: i = 1, then j = nt, then i = 2, then j = nt-1 and so on and so forth. How should I code this?
You can composite two loops like the following:
% define other variables and preallocations
j = nt;
for i = 1:nx-1
u(:,i+1) = ((1/(c*dt))*I+(1/dx)*A)\((1/(c*dt))*u(:,i)+v(:,i));
v(:,j-1) = ((1/dx)*A+(1/(c*dt))*I)\((1/(c*dt))*v(:,j)
j = j - 1;
end
for i = 1:nx-1
u(:,i+1) = ((1/(c*dt))*I+(1/dx)*A)\((1/(c*dt))*u(:,i)+v(:,i));
%This if will be true once each 10 iterations
if(mod((nt-i),10)==0)
j=((nt-i)/10)+1;
v(:,j-1) = ((1/dx)*A+(1/(c*dt))*I)\((1/(c*dt))*v(:,j);
end
end
Don't really know if this will work, but making it more usable as you are trying my idea.

Multiplying a vector times the inverse of a matrix in Matlab

I have a problem multiplying a vector times the inverse of a matrix in Matlab. The code I am using is the following:
% Final Time
T = 0.1;
% Number of grid cells
N=20;
%N=40;
L=20;
% Delta x
dx=1/N
% define cell centers
%x = 0+dx*0.5:dx:1-0.5*dx;
x = linspace(-L/2, L/2, N)';
%define number of time steps
NTime = 100; %NB! Stability conditions-dersom NTime var 50 ville en fått helt feil svar pga lambda>0,5
%NTime = 30;
%NTime = 10;
%NTime = 20;
%NTime = 4*21;
%NTime = 4*19;
% Time step dt
dt = T/NTime
% Define a vector that is useful for handling teh different cells
J = 1:N; % number the cells of the domain
J1 = 2:N-1; % the interior cells
J2 = 1:N-1; % numbering of the cell interfaces
%define vector for initial data
u0 = zeros(1,N);
L = x<0.5;
u0(L) = 0;
u0(~L) = 1;
plot(x,u0,'-r')
grid on
hold on
% define vector for solution
u = zeros(1,N);
u_old = zeros(1,N);
% useful quantity for the discrete scheme
r = dt/dx^2
mu = dt/dx;
% calculate the numerical solution u by going through a loop of NTime number
% of time steps
A=zeros(N,N);
alpha(1)=A(1,1);
d(1)=alpha(1);
b(1)=0;
c(1)=b(1);
gamma(1,2)=A(1,2);
% initial state
u_old = u0;
pause
for j = 2:NTime
A(j,j)=1+2*r;
A(j,j-1)=-(1/dx^2);
A(j,j+1)=-(1/dx^2);
u=u_old./A;
% plotting
plot(x,u,'-')
xlabel('X')
ylabel('P(X)')
hold on
grid on
% update "u_old" before you move forward to the next time level
u_old = u;
pause
end
hold off
The error message I get is:
Matrix dimensions must agree.
Error in Implicit_new (line 72)
u=u_old./A;
My question is therefore how it is possible to perform u=u_old*[A^(-1)] in Matlab?
David
As knedlsepp said, v./A is the elementwise division, which is not what you wanted. You can use either
v/A provided that v is a row vector and its length is equal to the number of columns in A. The result is a row vector.
A\v provided that v is a column vector and its length is equal to the number of rows in A
The results differ only in shape: v/A is the transpose of A'\v'