How can I solve this differential equation in MATLAB? - matlab

The differential equation is:
k*r=sqrt( (r`)^2 + r^2 )
The value of k is 2. How can I realize the function and solve it with ode45?

This is pretty straightforward. A few important things:
You need to express your differential equation in the format that ODE45 expects, which is dy/dt = f(t,y). That means that for your function, rather than k*r=sqrt( (drdt)^2 + r^2 ), you need to consider this as drdt = sqrt( (k*r)^2 - r^2 ) (assumming that I did my algebra correctly).
The function needs to be vectorizable. For this problem, that pretty much means that instead of ^, use .^, and instead of *, use .*.
Then we can use basic anonymous function syntax to setup the function to be solved:
k = 2;
fn_drdt = #(t,r) sqrt( (k.*r).^2 - (r.^2) );
Use ODE45 to solve it
tStart = 0;
tEnd = 10;
r_init = -5;
[t, r] = ode45(fn_drdt, [tStart tEnd], r_init);
And then make a basic plot
plot(t,r,'.');
And add a title
title(sprintf('Solution to %s with k=%d ,r_0=%d', func2str(fn_drdt), k, r_init), 'fontname','courier')

Related

Trying to minimise a function wrt 2 variables for robust portfolio optimisation. How to do this with fmincon?

I am currently involved in a group project where we have to conduct portfolio selection and optimisation. The paper being referenced is given here: (specifically page 5 and 6, equations 7-10)
http://faculty.london.edu/avmiguel/DeMiguel-Nogales-OR.pdf
We are having trouble creating the optimisation problem using M-Portfolios, given below
min (wrt w,m) (1/T) * sum_(rho)*(w'*r_t - m) (Sorry I couldn't get the formatting to work)
s.t. w'e = 1 (just a condition saying that all weights add to 1)
So far, this is what we have attempted:
function optPortfolio = portfoliofminconM(returns,theta)
% Compute the inputs of the mean-variance model
mu = mean(returns)';
sigma = cov(returns);
% Inputs for the fmincon function
T = 120;
n = length(mu);
w = theta(1:n);
m = theta((n+1):(2*n));
c = 0.01*ones(1,n);
Aeq = ones(1,(2*n));
beq = 1;
lb = zeros(2,n);
ub = ones(2,n);
x0 = ones(n,2) / n; % Start with the equally-weighted portfolio
options = optimset('Algorithm', 'interior-point', ...
'MaxIter', 1E10, 'MaxFunEvals', 1E10);
% Nested function which is used as the objective function
function objValue = objfunction(w,m)
cRp = (w'*(returns - (ones(T,1)*m'))';
objValue = 0;
for i = 1:T
if abs(cRp(i)) <= c;
objValue = objValue + (((cRp(i))^2)/2);
else
objValue = objValue + (c*(abs(cRp(i))-(c/2)));
end
end
The problem starts at our definitions for theta being used as a vector of w and m. We don't know how to use fmincon with 2 variables in the objective function properly. In addition, the value of the objective function is conditional on another value (as shown in the paper) and this needs to be done over a rolling time window of 120 months for a total period of 264 months.(hence the for-loop and if-else)
If any more information is required, I will gladly provide it!
If you can additionally provide an example that deals with a similar problem, can you please link us to it.
Thank you in advance.
The way you minimize a function of two scalars with fmincon is to write your objective function as a function of a single, two-dimensional vector. For example, you would write f(x,y) = x.^2 + 2*x*y + y.^2 as f(x) = x(1)^2 + 2*x(1)*x(2) + x(2)^2.
More generally, you would write a function of two vectors as a function of a single, large vector. In your case, you could rewrite your objfunction or do a quick hack like:
objfunction_for_fmincon = #(x) objfunction(x(1:n), x(n+1:2*n));

Solve optimization using fmincon MATLAB when objective function is in constraints

I want to solve:
I use following MATLAB code, but it does not work.
Can someone please guide me?
function f=objfun
f=-f;
function [c1,c2,c3]=constraint(x)
a1=1.1; a2=1.1; a3=1.1;
c1=f-log(a1)-log(x(1)/(x(1)+1));
c2=f-log(a2)-log(x(2)/(x(2)+1))-log(1-x(1));
c3=f-log(a3)-log(1-x(1))-log(1-x(2));
x0=[0.01;0.01];
[x,fval]=fmincon('objfun',x0,[],[],[],[],[0;0],[1;1],'constraint')
You need to flip the problem around a bit. You are trying to find the point x (which is (l_1,l_2)) that makes the minimum of the 3 LHS functions the largest. So, you can rewrite your problem as, in pseudocode,
maximise, by varying x in [0,1] X [0,1]
min([log(a1)+log(x(1)/(x(1)+1)) ...
log(a2)+log(x(2)/(x(2)+1))+log(1-x(1)) ...
log(a3)+log(1-x(1))+log(1-x(2))])
Since Matlab has fmincon, rewrite this as a minimisation problem,
minimise, by varying x in [0,1] X [0,1]
max(-[log(a1)+log(x(1)/(x(1)+1)) ...
log(a2)+log(x(2)/(x(2)+1))+log(1-x(1)) ...
log(a3)+log(1-x(1))+log(1-x(2))])
So the actual code is
F=#(x) max(-[log(a1)+log(x(1)/(x(1)+1)) ...
log(a2)+log(x(2)/(x(2)+1))+log(1-x(1)) ...
log(a3)+log(1-x(1))+log(1-x(2))])
[L,fval]=fmincon(F,[0.5 0.5])
which returns
L =
0.3383 0.6180
fval =
1.2800
Can also solve this in the convex optimization package CVX with the following MATLAB code:
cvx_begin
variables T(1);
variables x1(1);
variables x2(1);
maximize(T)
subject to:
log(a1) + x1 - log_sum_exp([0, x1]) >= T;
log(a2) + x2 - log_sum_exp([0, x2]) + log(1 - exp(x1)) >= T;
log(a3) + log(1 - exp(x1)) + log(1 - exp(x2)) >= T;
x1 <= 0;
x2 <= 0;
cvx_end
l1 = exp(x1); l2 = exp(x2);
To use CVX, each constraint and the objective function has to be written in a way that is proveably convex using CVX's ruleset. Making the substitution x1 = log(l1) and x2 = log(l2) allows one to do that. Note that: log_sum_exp([0,x1]) = log(exp(0) + exp(x1)) = log(1 + l1)
This also returns the answers: l1 = .3383, l2 = .6180, T = -1.2800

Create function to use in ode45

So this is part of a larger project but I am stuck on number two of this section. I rewrote the system to get it in the required form:
dx(1)/dt = x(2)
dx(2)/dt = (-(M+m)/mL))x(4) + 1/(mL)u
dx(3)/dt = x(4)
dx(4)/dt = -(mg/M)x(1) + (1/M)u
After substituting the variables given in the problem I wrote the funcion:
function dx = fun(t,x)
dx = zeros(4,1);
dx(1) = x(2);
dx(2) = -((2+.1)/(.1*.5)).*x(4);
dx(3) = x(4);
dx(4) = -((.1*9.81)/2).*x(1);
end
I am confused on how to implement u(t) = 0 and how to create the theta function.
Any help even if its just pointing me in the right direction would be amazing. Thank you in advance :)
It's easy. You implement theta as another state. This is possible since you know the derivative, which does not even depend on the other states. To be more precise, you should add two more states here. One for theta and one for theta_dot.
dx(5) = x(6) % Theta'
dx(6) = -0.1 % Theta''
And by the way, you can also pass additional variables to your differential equation. You just add more arguments to it
function dx = diffeq(t,x,parameters)
...
end
and create a new function handle where you execute the ODE solver
[T,X] = ode45(#(t,x)diffeq(t,x,parameters),t_span,X0, ode_options);
This is just a hint since you're using magic numbers in your differential equation function.

Finding real roots of polynomial by using fzero

I want to find only real roots of the equation which is ;
4*sqrt((1-(z^2/f1^2))*(1-z^2))-(2-z^2)^2-(m*z^4*sqrt(1-z^2/f1^2)/ ...
sqrt(1-((z^2/f1^2)/y^2)))
I know that equation includes complex roots, but I do not want to see them. Moreover, my code fails and says that;
Error using fzero (line 242) Function values at interval endpoints
must be finite and real.
Error in scholte (line 21) x=fzero(fun,x0)
Here is my code;
rho2 = 1000; %kg/m3
rho1 = 2700; %kg/m3
cl2 = 1481; %m/s
cl1 = 5919; %m/s
m = rho2/rho1;
y = cl2/cl1;
poi = 0.25;
f1 = (sqrt((1-2*poi)/(2*(1-poi))))^-1;
fun = #(z) 4*sqrt((1-(z^2/f1^2))*(1-z^2))-(2-z^2)^2- ...
(m*z^4*sqrt(1-z^2/f1^2)/sqrt(1-((z^2/f1^2)/y^2)));
x0 = [1 10];
x = fzero(fun, x0)
I changed x0 interval many times, but it showed the same error. How can I fix my code?
Your problem, as Matlab tells you, is that Function values at interval endpoints must be finite and real, and in your case they are not real:
fun(x0(1))
ans =
-1.0000 + 0.1454i
Your function is probably just too complex for fzero to handle. However I am not an expert, lets see if someone with more knowledge than me can point you in the correct direction for solving that equation.

Solving coupled Differential Equation by Matlab or by calculations

Solving coupled non linear differential equation by Mat-lab or by calculations
equation 1: x'(t) = -a* x(t) /(x(t) + y(t))
equation 2: y'(t) = -b* y(t) /(x(t) + y(t))
I tried in mathematica but got a very comlicated solution.
Solve[{x'[t] == -a* x[t] /(x[t] + y[t]), y'[t] == -b* y[t] /(x[t] + y[t])}, {x, y}, t]
How can I plot it?
My initial conditions are
x(0) = xo
y(0) = yo
Also, a and b are constants.
I have to plot x and y wrt t after inserting values of a and b . ( a= 2 , b =5 say )
A lot of things to note in this situation:
You need to create a function that contains both a and b:
function dy =soProblem(t,y,a,b)
dy=[-a*y(1)/(y(1)+y(2)); -b*y(2)/(y(1)+y(2))];
end
Call the standard ode function:
a = 2;
b = 5; tend = 10; x0 = 1; y0 = 2;
[T,Y] = ode45(#(t,y)soProblem(t,y,a,b),[0 tend],[x0 y0]);
plot (T,Y)
Realize you may have a stiff equation on your hands.
Have fun identifying the ideal function call:
[T15,Y15] = ode15s(#(t,y)soProblem(t,y,a,b),[0 tend],[x0 y0]);
[T23t,Y23t] = ode23t(#(t,y)soProblem(t,y,a,b),[0 tend],[x0 y0]);
[T23tb,Y23tb] = ode23tb(#(t,y)soProblem(t,y,a,b),[0 tend],[x0 y0]);
%note ode23s doesn't converge (or at least takes forever)
plot (T,Y,T15,Y15,T23t,Y23t,T23tb,Y23tb)
Understand why mathematica becomes restless
In mathematica:
Try ndsolve
In matlab:
Create a function file yourfunction.m:
function [Y_prime]=yourfunction(t, Y)
Y_prime=[-2*Y(1)./(Y(1) + Y(2)) -5*Y(2)./(Y(1) + Y(2))];
end
and then
[T,Y] = ode45(yourfunction,[0 t_end],[x0 y0]);
plot(T,Y(:,1));
hold on
plot(T,Y(:,2));