Matlab : system of four coupled odes - matlab

So, I've been working on this physics problem where I face a system of four coupled differential equations which I can't seem to find the answer to
TT0 = 0; %initial release angle Theta
l0 = 1; %initial left line length (in meters)
m = 1;
M = 3;
R = 0.3;
g = 9.8;
mu = 0.5;
syms t Ti(t) Tx(t) TT(t) l(t);
ode1 = (M*g) - Tx == -M*(diff(l,t,2)+R*diff(TT,t,2));
ode2 = m*g*sin(TT) - Ti == m*(R*diff(TT,t,2)-l*(diff(TT,t))^2 + diff(l,t,2));
ode3 = m*g*cos(TT) == m*(R*(diff(TT,t))^2 + 2*diff(l,t)*diff(TT,t) + l*diff(TT,t,2));
ode4 = Tx == Ti*exp(mu*(pi/2 + TT));
odes = [ode1; ode2; ode3; ode4];
conds = [TT(0) == TT0; l(0) == l0;Ti(0) == 0; Tx(0) == M*g];
D = dsolve(odes,conds);
Here's the code I've written. There are four equations and four indeterminates but I get this error when I run the code:
Error using mupadengine/feval (line 163)
Cannot reduce to the square system because the number of equations
differs from the number of indeterminates.
Error in dsolve>mupadDsolve (line 332)
T = feval(symengine,'symobj::dsolve',sys,x,options);
Error in dsolve (line 193)
sol = mupadDsolve(args, options);
Error in Untitled (line 16)
D = dsolve(odes,conds)
I've searched the internet and altered my code several times but it didn't seem to work. I'll highly appreciate any kind of help.

Related

Matlab GUI ODE solver 'Value' must be a double scalar

I am trying to make an 2nd order ODE solver but it's not working (Error using matlab.ui.control.internal.model.AbstractNumericComponent/set.Value (line 111)
'Value' must be a double scalar.) when I run it on the normal matlab (not the app designer), I get the right answer.
m1 = app.m.Value;
c1 = app.c.Value;
k1 = app.k.Value;
syms y(x)
Dy = diff(y);
ode = m1*diff(y,x,2) == app.u.Value - c1*Dy - k1*y;
cond1 = y(0) == 1;
cond2 = Dy(0) == 0;
conds = [cond1 cond2];
ySol(x) = dsolve(ode,conds);
ySol = simplify(ySol);
app.EditField.Value = ySol;

Unable to meet integration tolerances in fmincon to solve ODE optimization problem

I have constrained ODE optimization problem to be solved using Matlab, I started by solving the ODE using ode15s which working will this initial values, also I had very good results without constraints using fminsearch, the problem started when I used fmincon it gave me these warnings:
Warning: Length of lower bounds is < length(x); filling in missing lower bounds with -Inf.
> In checkbounds (line 33)
In fmincon (line 318)
In Optimization (line 64)
Warning: Length of upper bounds is < length(x); filling in missing upper bounds with +Inf.
> In checkbounds (line 47)
In fmincon (line 318)
In Optimization (line 64)
Warning: Failure at t=2.340250e+01. Unable to meet integration tolerances without reducing the step size below the smallest value
allowed (5.684342e-14) at time t.
> In ode15s (line 668)
In ObjFun (line 6)
In barrier
In fmincon (line 813)
In Optimization (line 64)
I tried to remove constraints, but nothing changed...
y1_max = 5; y2_max = 2.3;
y01 = 1; y02 = 1.6;
%Control function parameter
Umin = -0.3; Umax = -0.1;
%Creation the structure of model parameters
params.T0=T0; params.Tf=Tf;
params.y1d=y1d; params.y2d=y2d;
params.y01=y01; params.y02=y02;
params.y2_max=y2_max;
n=2;
U0=-0.2*ones(1,n);
params.n=n;
params.U=U0; params.Umax=Umax; params.Umin=Umin;
params.dt=(Tf-T0)/n;
%for initial value of optimization parameters
options = odeset('RelTol',1e-7,'AbsTol',1e-7);
U=U0;
[t,y]=ode15s(#ODEsolver,[T0,Tf],[y01 y02],options,params);
%adding the ode solution as input prameters
params.t=t; params.y1= y(:,1); params.y2= y(:,2);
U0=-0.2*ones(1,n);
params.n=n; params.U=U0;
params.dt=(Tf-T0)/n;
A = [];
B = [];
Aq = []; Bq = [];
options1 = optimset('MaxIter',5000);
[x,fval,exitflag,output] = fmincon(#ObjFun,U0,A,B,Aq,Bq,Umin,Umax,IneqConst(U0,params),options1,params)
function y = ODEsolver(t,y,params)
dt = params.dt;
nu = floor(t/dt)+1;
nu = min(nu,params.n-1);
t1 = (nu-1)*dt;
Ut = params.U(nu) + ((t-t1)/dt)*(params.U(nu+1) - params.U(nu));
dy1a = ((0.63*y(1))/(1 + y(1)));
dy1b = (Ut*y(1)*y(2))/(1+0.6*y(1));
dy1 = dy1a + dy1b;
dy2a = (0.15*y(2))/(0.05-0.2*y(2));
dy2 = -0.2*y(2) + dy1b * dy2a;
y = [dy1; dy2];
end
function ObjFun1 = ObjFun(u,params)
% Calculating the value of the optimization criteria
params.U=u;
options = odeset('RelTol',1e-8,'AbsTol',1e-8);
[t,y]=ode15s(#ODEsolver,[0,100],[params.y01,
params.y02],options,params);
ObjFun1 =trapz(t,(y(:,1)-params.y1d).^2);
end
function [c,Const] = IneqConst(u, params)
params.U=u;
options = odeset('RelTol',1e-8,'AbsTol',1e-8);
[t,y]=ode15s(#ODEsolver,[0,100],[params.y01, params.y02],options,params);
c =[];
yCon = y(:,2)-params.y2_max;
Const = trapz(t,(abs(yCon)+yCon).^2);
end
The bug in this code is that the dimension of the bounds (Umin, Umax) should be an array with the same size of the control function U
so if the control function parameters n = 2 then Umin = [-0.3 -0.3] & Umax = [-0.1 -0.1]

MATLAB. Setting up bvp4c for second order ode - reaction diffusion equation

I'm trying to solve for this second order ODE in steady state using bvp4c with the boundary conditions where at x=0, C_L=1 and x=100, C_L=0.
Image of equations
function bvp4c_test
%Diffusion coefficient
D_ij= 1*10^-6;
%Rate constants
k_1 = 0.00193;
k_2 = 0.00255;
k_3 = 4.09;
d_1 = 0.007;
d_2 = 3.95*10^-5;
d_3 = 2.26;
%Equilibrium constants
K_1 = 3.63;
K_2 = 0.0155;
K_3 = 0.553;
K_4 = 9.01;
%K_5 = 0.077;
%K_6 = 0.000818;
K_i = 0.139;
%Total Receptors
N_T =1.7;
solinit = bvpinit(linspace(0,10,11),[0 0]);
sol = bvp4c(#(x,y)odefcn(x,y,D_ij,k_1,k_2,k_3,d_1,d_2,d_3,K_1,K_2,K_3,K_4,K_i,N_T),#twobc,solinit);
plot(sol.x,sol.y(1,:))
function dC_Ldx = odefcn(x,C_L_derivs,D_ij,k_1,k_2,k_3,d_1,d_2,d_3,K_1,K_2,K_3,K_4,K_i,N_T)
C_L = C_L_derivs(1);
dC_Ldx(1) = C_L_derivs(1);
N_r = (-(1+(C_L./K_2))+...
sqrt(((1+(C_L./K_2)).^2)-4.*((2./K_4).*(1+(C_L./K_2).*(1+(1./K_i).*(1+(C_L./K_3))))).*(-N_T)))./...
(2.*(2./K_4).*(1+(C_L./K_2).*(1+(1./K_i).*(1+(C_L./K_3)))));
N_R = (C_L./K_1).*N_r;
N_r2 = (1./K_4).*(N_r).^2;
N_rR = (C_L./(2.*K_2.*K_4)).*(N_r).^2;
N_pR = (C_L./(2.*K_2.*K_4.*K_i)).*(N_r).^2;
N_R2 = ((C_L.^2)./(K_2.*K_3.*K_4.*K_i)).*(N_r).^2;
R_L = ((2.*d_1.*(N_T-N_r-N_r2-N_rR-N_pR-N_R2))-(2.*k_1.*C_L.*N_r))+...
((2.*d_2.*(N_T-N_r-N_R-N_r2-N_pR-N_R2)))-((k_2.*C_L.*(N_T-N_r-N_R-N_rR-N_pR-N_R2)))+...
(d_3.*(N_T-N_r-N_R-N_r2-N_rR-N_pR))-(2.*k_3.*C_L.*(N_T-N_r-N_R-N_r2-N_rR-N_R2));
dC_Ldx(2) = -R_L./D_ij;
end
function res = twobc(ya,yb)
res = [ ya(1)-1; yb(1) ];
end
end
After running the code the get the following error messages:
Error using bvp4c (line 251)
Unable to solve the collocation equations -- a singular Jacobian encountered.
Error in bvp4c_test (line 30)
sol = bvp4c(#(x,y)odefcn(x,y,D_ij,k_1,k_2,k_3,d_1,d_2,d_3,K_1,K_2,K_3,K_4,K_i,N_T),#twobc,solinit);
Am I setting up my code correctly? Did I write the second order differential equation correctly?
I'm still very new to MATLAB and would appreciate any help I can get. Thank you!

Elastic line equation in Matlab - Error using Mupadengine/feval - Error in dsolve>mupadDsolve - Error in dsolve

I can't understand the solution of multiple differential equations in Matlab. In this example, I'm trying to work with independent equations: the program should solve them separately (and it does, see below) and together (it doesn't!), shouldn't it?
N.B. The equations describe the elastic line according to Euler Bernoulli. I'd like to use them, just setting the appropriate intitial conditions and known data for each problem.
This is the part of code in common with both procedures:
Creating symbolic functions
syms v(z) w(z)
syms B Chiterm p mx by l A Eterm p bz
Differentiating
D1v = diff(v,z);
D2v = diff(v,z,2);
D3v = diff(v,z,3);
D4v = diff(v,z,4);
D1w = diff(w,z);
D2w = diff(w,z,2);
Setting known values (and parameters, like p)
by=-p;
Chiterm=0;
mx=0
bz=0;
Eterm=0
Defining differential equations
odetrasv = diff(B*(diff(v,z,2)+Chiterm),z,2)-mx-by == 0;
odelong = diff(A*(diff(w,z)-Eterm),z)+bz == 0;
Defining initial conditions
cond1 = B*D2v(l) == 0;
cond2 = D1v(0) == 0;
cond3 = v(0) == 0;
cond4 = v(l) == 0;
cond5 = D1w(l) == 0;
cond6 = w(0) == 0;
Here is the part of the code that solves the equations separately:
condstrasv = [cond1 cond2 cond3 cond4];
condslong = [cond5 cond6];
vSol(z) = dsolve(odetrasv, condstrasv);
wSol(z) = dsolve(odelong, condslong);
vSol = simplify(vSol)
wSol = simplify(wSol)
Here's the part that is not working. I'm trying to solve them togheter, since the next step is solving a system of multiple equations:
odes = [odetrasv; odelong];
conds = [cond1; cond2; cond3; cond4; cond5; cond6];
[vSol(z), wSol(z)] = dsolve(odes,conds)
Matlab returns:
Error using Mupadengine/feval - Invalid initial conditions
Error in dsolve>mupadDsolve - T=feval(symengine,'symobj::dsolve',sys....
Error in dsolve - sol = mupadDsolve(args, options);
Why are the initial conditions invalid in the second case? Solving without them works:
[vSol(z), wSol(z)] = dsolve(odes)

Calculate the derivative of the sum of a mathematical function-MATLAB

In Matlab I want to create the partial derivative of a cost function called J(theta_0, theta_1) (in order to do the calculations necessary to do gradient descent).
The function J(theta_0, theta_1) is defined as:
Lets say h_theta(x) = theta_1 + theta_2*x. Also: alpha is fixed, the starting values of theta_1 and theta_2 are given. Let's say in this example: alpha = 0.1 theta_1 = 0, theta_2 = 1. Also I have all the values for x and y in two different vectors.
VectorOfX =
5
5
6
VectorOfX =
6
6
10
Steps I took to try to solve this in Matlab: I have no clue how to solve this problem in matlab. So I started off with trying to define a function in Matlab and tried this:
theta_1 = 0
theta_2 = 1
syms x;
h_theta(x) = theta_1 + t2*x;
This worked, but is not what I really wanted. I wanted to get x^(i), which is in a vector. The next thing I tried was:
theta_1 = 0
theta_2 = 1
syms x;
h_theta(x) = theta_1 + t2*vectorOfX(1);
This gives the following error:
Error using sym/subsindex (line 672)
Invalid indexing or function definition. When defining a
function, ensure that the body of the function is a SYM
object. When indexing, the input must be numeric, logical or
':'.
Error in prog1>gradientDescent (line 46)
h_theta(x) = theta_1 + theta_2*vectorOfX(x);
I looked up this error and don't know how to solve it for this particular example. I have the feeling that I make matlab work against me instead of using it in my favor.
When I have to perform symbolic computations I prefer to use Mathematica. In that environment this is the code to get the partial derivatives you are looking for.
J[th1_, th2_, m_] := Sum[(th1 + th2*Subscript[x, i] - Subscript[y, i])^2, {i, 1, m}]/(2*m)
D[J[th1, th2, m], th1]
D[J[th1, th2, m], th2]
and gives
Coming back to MATLAB we can solve this problem with the following code
%// Constants.
alpha = 0.1;
theta_1 = 0;
theta_2 = 1;
X = [5 ; 5 ; 6];
Y = [6 ; 6 ; 10];
%// Number of points.
m = length(X);
%// Partial derivatives.
Dtheta1 = #(theta_1, theta_2) sum(2*(theta_1+theta_2*X-Y))/2/m;
Dtheta2 = #(theta_1, theta_2) sum(2*X.*(theta_1+theta_2*X-Y))/2/m;
%// Loop initialization.
toll = 1e-5;
maxIter = 100;
it = 0;
err = 1;
theta_1_Last = theta_1;
theta_2_Last = theta_2;
%// Iterations.
while err>toll && it<maxIter
theta_1 = theta_1 - alpha*Dtheta1(theta_1, theta_2);
theta_2 = theta_2 - alpha*Dtheta2(theta_1, theta_2);
it = it + 1;
err = norm([theta_1-theta_1_Last ; theta_2-theta_2_Last]);
theta_1_Last = theta_1;
theta_2_Last = theta_2;
end
Unfortunately for this case the iterations does not converge.
MATLAB is not very flexible for symbolic computations, however a way to get those partial derivatives is the following
m = 10;
syms th1 th2
x = sym('x', [m 1]);
y = sym('y', [m 1]);
J = #(th1, th2) sum((th1+th2.*x-y).^2)/2/m;
diff(J, th1)
diff(J, th2)