I wanted to make a bifurcation plot to demonstrate the bistability region for the following system of equations:
Toggle switch equations
I have already determined the nullclines for this system as well as their intersection points (via MATLAB). I read from here that I'll have to plug in the said points in the Jacobian, but I honestly have no idea how to proceed from that. For the bifurcation plot, I wanted to plot alpha1 vs alpha2.
Would appreciate any additional hints for the MATLAB implementation!
% This code block sets up the differential equations
% and the equations for the nullclines
alpha1 = 5; % Effective synthesis rate of repressor 1
alpha2 = 5; % Effective synthesis rate of repressor 2
beta = 3; % Repression cooperativity of promoter 2
gamma = 3; % Repression cooperativity of promoter 1
maxY = 5.5; % Specifies max y-axis value
u = linspace(0,maxY,100);
v = linspace(0,maxY,100);
nullU = alpha1./(1+v.^beta); % Setting du/dt = 0
nullV = alpha2./(1+u.^gamma); % Setting dv/dt = 0
% I'm also exploring the time-course of u and v with respect to time
% so I'm using this function as well
function hillfx = toggle(t,y,alpha1,alpha2,beta,gamma)
du = -y(1) + alpha1/(1+(y(2)^beta));
dv = -y(2) + alpha2/(1+(y(1)^gamma));
hillfx = [du; dv];
end
You could try varying 1 of the parameters. A good way to do this is to make a new variable for the range of alpha1 for example (this can be done with the linspace() function). Next create a matrix to store the equilibrium points from the resulting differential equations and set the initial conditions for the ode45 function (y0) to [0,0]. You will also need to make variables for beta and gamma accordingly.
Loop i over the length of alpha1Range and first save alpha1Range(i) to a variable which could be called a1. Use the ode45 function which solves differential equations with a1, alpha2, beta,gamma and y0. You might need to use the toggle function aswell. Save the output(time steps and solution values) of the ODE's for the current value of alpha1 to variables and then store the equilibrium points for this data in the i position of equilibrium points matrix.
You can now plot the bifurcation diagram by calling the plot function with alpha1Range and all the elements in the first column of equilibium points.
Related
In my project, I used a generic cosine function to fit my data:
cos_fun = #(p, theta) p(1) + p(2) * cos(theta - p(3))
p = nlinfit(x,y,cos_fun,[1 1 0])
As a result, p has three values, which are y-offset, amplitude and phase.
Can I draw a smooth cosine curve using these three parameters?
TL;DR: It is possible to both fit and plot the curve, with and without requiring toolboxes. All cases presented below.
Plotting
Plotting the function follows directly from the function used to obtain your parameters using plot(). Notice that you control the smoothness of the plotted function based on the step size for the domain (see step below).
In the figure, the results obtained from the nlinfit() (Toolbox required) are the same as "SSE" obtained without a toolbox using fminsearch().
% Plot (No toolbox Required)
step = 0.01; % smaller is smoother
Xrng = 0:step:12;
figure, hold on, box on
plot(Xdata,Ydata,'b.','DisplayName','Data')
plot(Xrng,cos_fun(p_SSE,Xrng),'r--','DisplayName','SSE')
plot(Xrng,cos_fun(p_SAE,Xrng),'k--','DisplayName','SAE')
legend('show')
As pointed out in the comment by #Daniel, you can also make the plot with nlintool() but this requires the Statistics Toolbox.
nlintool(Xdata,Ydata,cos_fun,[1 1 0]) % toolbox required
Fitting
Using nlinfit(): (Statistics Toolbox Required)
pNL = nlinfit(Xdata,Ydata,cos_fun,[1 1 0]) % same as SSE approach below
A Toolbox Free Approach:
You can construct a convex error function to minimize and return the global optimum using fminsearch() as a down and dirty approach. For example, the sum of squared error or the sum of absolute error will be convex.
% MATLAB R2019a
% Generate Example Data
sigma = 0.5; % increase this for more variable data (more noise)
Xdata = [repmat(1:10,1,4)].';
Ydata = cos(Xdata)+sigma*randn(length(Xdata),1);
% Function Evaluation
cos_fun=#(p,x) p(1) + p(2).*cos(x-p(3));
% Error Functions
SSEh =#(p) sum((cos_fun(p,Xdata)-Ydata).^2); % sum of squared error
SAEh =#(p) sum(abs(cos_fun(p,Xdata)-Ydata)); % sum of absolute error
Of course, these will give you different errors for the same parameter.
% Test
SSEh([1 1 0])
SAEh([1 1 0])
But you then call fminsearch() given an initial guess for the parameters, p0, to obtain the parameters that minimize your chosen error function. Since SSEh and SAEh are both convex with respect to p, there's no need to do this multiple times and save the best one since for every p0, you'll get the same answer.
p0 = [1 1 0.25]; % Initial starting point
[p_SSE, SSE] = fminsearch(SSEh,p0)
[p_SAE, SAE] = fminsearch(SAEh,p0)
You fit slightly different curves depending on the error function.
Notice that SSEh(pNL) and SSEh(p_SSE) are the same since pNL equals p_SSE since nlinfit() estimates the coefficients "using iterative least squares estimation."
I want to determine how well the estimated model fits to the future new data. To do this, prediction error plot is often used. Basically, I want to compare the measured output and the model output. I am using the Least Mean Square algorithm as the equalization technique. Can somebody please help what is the proper way to plot the comparison between the model and the measured data? If the estimates are close to true, then the curves should be very close to each other. Below is the code. u is the input to the equalizer, x is the noisy received signal, y is the output of the equalizer, w is the equalizer weights. Should the graph be plotted using x and y*w? But x is noisy. I am confused since the measured output x is noisy and the model output y*w is noise-free.
%% Channel and noise level
h = [0.9 0.3 -0.1]; % Channel
SNRr = 10; % Noise Level
%% Input/Output data
N = 1000; % Number of samples
Bits = 2; % Number of bits for modulation (2-bit for Binary modulation)
data = randi([0 1],1,N); % Random signal
d = real(pskmod(data,Bits)); % BPSK Modulated signal (desired/output)
r = filter(h,1,d); % Signal after passing through channel
x = awgn(r, SNRr); % Noisy Signal after channel (given/input)
%% LMS parameters
epoch = 10; % Number of epochs (training repetation)
eta = 1e-3; % Learning rate / step size
order=10; % Order of the equalizer
U = zeros(1,order); % Input frame
W = zeros(1,order); % Initial Weigths
%% Algorithm
for k = 1 : epoch
for n = 1 : N
U(1,2:end) = U(1,1:end-1); % Sliding window
U(1,1) = x(n); % Present Input
y = (W)*U'; % Calculating output of LMS
e = d(n) - y; % Instantaneous error
W = W + eta * e * U ; % Weight update rule of LMS
J(k,n) = e * e'; % Instantaneous square error
end
end
Lets start step by step:
First of all when using some fitting method it is a good practice to use RMS error . To get this we have to find error between input and output. As I understood x is an input for our model and y is an output. Furthermore you already calculated error between them. But you used it in loop without saving. Lets modify your code:
%% Algorithm
for k = 1 : epoch
for n = 1 : N
U(1,2:end) = U(1,1:end-1); % Sliding window
U(1,1) = x(n); % Present Input
y(n) = (W)*U'; % Calculating output of LMS
e(n) = x(n) - y(n); % Instantaneous error
W = W + eta * e(n) * U ; % Weight update rule of LMS
J(k,n) = e(n) * (e(n))'; % Instantaneous square error
end
end
Now e consists of errors at the last epoch. So we can use something like this:
rms(e)
Also I'd like to compare results using mean error and standard deviation:
mean(e)
std(e)
And some visualization:
histogram(e)
Second moment: we can't use compare function just for vectors! You can use it for dynamic system models. For it you have to made some workaround about using this method as dynamic model. But we can use some functions as goodnessOfFit for example. If you want something like error at each step that consider all previous points of data then make some math workaround - calculate it at each point using [1:currentNumber].
About using LMS method. There are built-in function calculating LMS. Lets try to use it for your data sets:
alg = lms(0.001);
eqobj = lineareq(10,alg);
y1 = equalize(eqobj,x);
And lets see at the result:
plot(x)
hold on
plot(y1)
There are a lot of examples of such implementation of this function: look here for example.
I hope this was helpful for you!
Comparison of the model output vs observed data is known as residual.
The difference between the observed value of the dependent variable
(y) and the predicted value (ŷ) is called the residual (e). Each data
point has one residual.
Residual = Observed value - Predicted value
e = y - ŷ
Both the sum and the mean of the residuals are equal to zero. That is,
Σ e = 0 and e = 0.
A residual plot is a graph that shows the residuals on the vertical
axis and the independent variable on the horizontal axis. If the
points in a residual plot are randomly dispersed around the horizontal
axis, a linear regression model is appropriate for the data;
otherwise, a non-linear model is more appropriate.
Here is an example of residual plots from a model of mine. On the vertical axis is the difference between the output of the model and the measured value. On the horizontal axis is one of the independent variables used in the model.
We can see that most of the residuals are within 0.2 units which happens to be my tolerance for this model. I can therefore make a conclusion as to the worth of the model.
See here for a similar question.
Regarding you question about the lack of noise in your models output. We are creating a linear model. There's the clue.
So I was given a second order boundary value problem with y(0)=5 and y(20)=8. We are supposed to use the shooting method with ode45 to approximate the solution and compare it to the actual solution. I have already converted the equation to a first order equation and found the analytic solution (y1). We are supposed to have the user input guesses of -1 and -.5, but when I do this the graph doesn't resemble the actual at all. I have commented out the while loop we are supposed to use to get the solution to within a tolerance because I need the first part to work out. I'm not really sure what the issue is...
f.m file
function xp=f(t,x)
xp=zeros(2,1);
xp(1)=x(2);
xp(2)=exp(-5*t)-x(2)-9.81*sin(x(1));
main.m file
clear
clc
syms t;
c = -1.783049298*10^(-4);
d = 7.000178305;
y1 = c*exp((1/7+2*sqrt(2)/7)*t)+d*exp((1/7-2*sqrt(2)/7)*t)+t-2;
errta = 1;
prompt = 'Enter a guess for the slope';
z = input(prompt);
guesses(1) = z;
[t,x]=ode45('f',[0,20],[5,z]);
result(1) = x(length(x),1);
z = input(prompt);
guesses(2) = z;
[t,x]=ode45('f',[0,20],[5,z]);
result(2) = x(length(x),1);
% while errta>0.000001
% z = (guesses(2)+guesses(1))/2;
%
% [t,x]=ode45('f',[0,20],[5,z]);
% if x(length(x),1)>8
% guesses(2)=z;
% end
%
% if x(length(x),1)<8
% guesses(1)=z;
% end
%
% errta = abs(-.82857121689-z);
% end
plot(t,x(:,1),'r')
title('ode45 vs actual')
hold on
ezplot(y1,[0,20])
hold off
x''+x'+9.81*sin(x)=exp(-5*t)
as used in the odefunc f is a damped pendulum with some exponentially decreasing forcing. As such one can expect that at t=20 an equilibrium or stationary point is reached. Those are precisely known as x=2*pi*k. Thus the mapping from the initial velocity to the final position will resemble a step function and the bisection function will find the almost vertical segment where the final value 8 resides on. But probably not the point where the final value is exactly 8. Make a plot for initial velocities ranging from 5 t0 10 to see this effect.
The exact solution named y1 belongs to the differential equation
7*x''-2*x'-x=-t
The relation between initial velocity and final position is nearly linear with the solution v0=-0.828571216889 which appears to be independent of the step size of the numerical solver. This value is also consistent with the proposed initial guesses.
I have a set of odes written in matrix form as $X' = AX$; I also have a desired value of the states $X_des$. $X$ is a five dimensional vector. I want to stop the integration after all the states reach their desired values (or atleast close to them by $1e{-3}$). How do I use event function in matlab to do this? (All the help I have seen are about 1 dimensional states)
PS: I know for sure that all the states approach their desired values after long time. I just want to stop the integration once they are $1e{-3}$ within the desired values.
First, I presume that you're aware that you can use the matrix exponential (expm in Matlab) to solve your system of linear differential equations directly.
There are many ways to accomplish what you're trying to do. They all depend a bit on your system, how it behaves, and the particular event you want to capture. Here's a small example for a 2-by-2 system of linear differential equations:
function multipleeventsdemo
A = [-1 1;1 -2]; % Example A matrix
tspan = [0 50]; % Initial and final time
x0 = [1;1]; % Initial conditions
f = #(t,y)A*y; % ODE function
thresh = 0; % Threshold value
tol = 1e-3; % Tolerance on threshold
opts = odeset('Events',#(t,y)events(t,y,thresh,tol)); % Create events function
[t,y] = ode45(f,tspan,x0,opts); % Integrate with options
figure;
plot(t,y);
function [value,isterminal,direction] = events(t,y,thresh,tol)
value = y-thresh-tol;
isterminal = all(y-thresh-tol<=0)+zeros(size(y)); % Change termination condition
direction = -1;
Integration is stopped when both states are within tol of thresh. This is accomplished by adjusting the isterminal output of the events function. Note that separate tolerance and threshold variables isn't really necessary – you simply need to define the crossing value.
If your system oscillates as it approaches it's steady state (if A has complex eigenvalues), then you'll need to do more work. But you questions doesn't indicate this. And again, numerical integration may not be the easiest/best way to solve your problem which such a system. Here is how you could use expm in conjunction with a bit of symbolic math:
A = [-1 1;1 -2];
x0 = [1;1];
tol = 1e-3;
syms t_sym
y = simplify(expm(A*t_sym)*x0) % Y as a function of t
t0 = NaN(1,length(x0));
for i = 1:length(x0)
sol = double(solve(y(i)==tol,t_sym)) % Solve for t when y(i) equal to tol
if ~isempty(sol) % Could be no solution, then NaN
t0(i) = max(sol); % Or more than one solution, take largest
end
end
f = matlabFunction(y); % Create vectorized function of t
t_vec = linspace(0,max(t0),1e2); % Time vector
figure;
plot(t_vec,f(t_vec));
This will only work for fairly small A, however, because of the symbolic math. Numerical approaches using expm are also possible and likely more scalable.
I am trying to solve a forced mass-spring-damper system in matlab by using the Runge-Kutta method.
Currently the code uses constant values for system input but instead I would like to vectors as input. For examples, I would like to replace my force amplitude F0 with a vector value.
Should I be using for loops or what is the simplest way to do it?
function O = MSDSRK(m,b,k,F0,w,x0,v0)
% ----- Input argument -----
% m: mass for particle
% b: damping coefficient
% k: spring constant
% F0: amplitude of external force
% w: angular freuency of external force
% x0: initial condition for the position x(0)
% v0: initial condition for the velocity v(0)
dt=0.1;
options=odeset('InitialStep',dt,'MaxStep',dt);
td=[0:dt:50];
% Solve differential equation with Runge-Kutta solver
[t,x]=ode45(#(t,X)MSD(t,X,m,b,k,F0,w),td,[x0;v0],options);
% Extract only particle position trajectory
O=[t x(:,1)];
end
function dX=MSD(t,X,m,b,k,F0,w)
% With two 1st order diffeential equations,
% obtain the derivative of each variables
% (position and velocity of the particle)
dX(1,1)=X(2,1);
dX(2,1)=(1/m)*(F0*sin(w*t)-b*X(2,1)-k*X(1,1));
end
A for-loop will work for sure, but it's not what I'd advise in this situation. That approach has the drawback of making you think in a certain way, namely, that you are solving a simple 1D system, just multiple times.
The for-loop approach doesn't teach you very much more than what you already knew how to do. You'll get a passing grade I'm sure. But if you want to excell, not only here but also in future classes (and more importantly, in your job later), you have to do more. You can only learn how to tackle more complicated problems by thinking about this simple problem in a different way, namely, as a multi-dimensional mass/spring/damper system, of which the components all happen to be uncoupled and all happen to have the same initial values.
For such systems, vectorization and matrix manipulation is really the way to go. That is the generalization of 1D/2D/3D systems, to arbitrary-D systems. And matrix manipulation and vecorization, that is just what MATLAB is best at. That is indeed what you can learn here.
Here's how to do it for your case. I made it a bit smaller in scope, but the principles remain the same:
function O = MSDSRK
% Assign some random scalar values to all parameters, but
% a *vector* to the force amplitudes
[m,b,k,F0,w,x0,v0] = deal(...
1,0.2,3, rand(13,1), 2,0,0);
% We need to simulate as many mass-spring-damper systems as there are
% force amplites, so replicate the initial values
x0 = repmat(x0, numel(F0),1);
v0 = repmat(v0, numel(F0),1);
% The rest is the same as before
dt = 0.1;
options = odeset('InitialStep', dt,'MaxStep', dt);
td = 0:dt:50;
[t,x] = ode45(#(t,X) MSD(t,X,m,b,k,F0,w), td, [x0;v0], options);
% The output is now:
%
% x(:,1) position of mass in system with forcing term F0(1)
% x(:,2) position of mass in system with forcing term F0(2)
% ...
% x(:,14) speed of mass in system with forcing term F0(1)
% x(:,15) speed of mass in system with forcing term F0(2)
% ...
O = [t x(:,1:numel(F0))];
% And, to make the differences more clear:
plot(t, x(:,1:numel(F0)))
end
function dX = MSD(t,X,m,b,k,F0,w)
% Split input up in position and velocity components
x = X(1:numel(X)/2);
v = X(numel(X)/2+1:end);
% Compute derivative
dX = [
v
(F0*sin(w*t) - b*v - k*x)/m
];
end