Using fsolve to solve Differential Equation with Varying Parameters - matlab

I am using the following code to produce a numerical solution to a system of ODE's with 6 boundary conditions.
I am using the initial conditions to obtain a solution but I must vary three other conditions in order to find the true solution. The function I have is as follows:
function diff = prob5diff(M,Fx,Fy)
u0 = [pi/2 0 0]';
sSpan = [0 13];
p = #(t,u) prob5(t,u,M,Fx,Fy);
options = odeset('reltol',1e-6,'abstol',1e-6);
[s,u] = ode45(p,sSpan,u0,options);
L = length(s);
x = u(:,2); y = u(:,3); theta = u(:,1);
diff(1) = x(L) - 5;
diff(2) = y(L);
diff(3) = theta(L) + pi/2;
end
Ultimately, different values of M,Fx, and Fy will produce different solutions and I would like a solution such that the values in diff are as close to zero as possible so I want fsolve to iterate through different values of M,Fx, and Fy
I am receiving the following error: when I call it in this way:
opt = optimset('Display','iter','TolFun',1e-6);
guess = [1;1;1];
soln = fsolve(#prob5diff,guess,opt);
Error in line:
soln = fsolve(#prob5diff,guess,opt);
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE cannot continue.
Thanks!

One problem is that you have to call fsolve on prob5diff which takes a single vector input since your guess is a single vector:
prob5diff(x)
M = x(1);
Fx = x(2);
Fy = x(3);

Related

SIR model using fsolve and Euler 3BDF

Hi i've been asked to solve SIR model using fsolve command in MATLAB, and Euler 3 point backward. I'm really confused on how to proceed, please help. This is what i have so far. I created a function for 3BDF scheme but i'm not sure how to proceed with fsolve and solve the system of nonlinear ODEs. The SIR model is shown as and 3BDF scheme is formulated as
clc
clear all
gamma=1/7;
beta=1/3;
ode1= #(R,S,I) -(beta*I*S)/(S+I+R);
ode2= #(R,S,I) (beta*I*S)/(S+I+R)-I*gamma;
ode3= #(I) gamma*I;
f(t,[S,I,R]) = [-(beta*I*S)/(S+I+R); (beta*I*S)/(S+I+R)-I*gamma; gamma*I];
R0=0;
I0=10;
S0=8e6;
odes={ode1;ode2;ode3}
fun = #root2d;
x0 = [0,0];
x = fsolve(fun,x0)
function [xs,yb] = ThreePointBDF(f,x0, xmax, h, y0)
% This function should return the numerical solution of y at x = xmax.
% (It should not return the entire time history of y.)
% TO BE COMPLETED
xs=x0:h:xmax;
y=zeros(1,length(xs));
y(1)=y0;
yb(1)=y0+f(x0,y0)*h;
for i=1:length(xs)-1
R =R0;
y1(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - R, y1(i-1,:)+2*h*F(i,:))
S = S0;
y2(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - S, y2(i-1,:)+2*h*F(i,:))
I= I0;
y3(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - I, y3(i-1,:)+2*h*F(i,:))
end
end
You have an implicit equation
y(i+1) - 2*h/3*f(t(i+1),y(i+1)) = G = (4*y(i) - y(i-1))/3
where the right-side term G is constant in the call to fsolve, that is, during the solution of the implicit step equation.
Note that this is for the vector valued system y'(t)=f(t,y(t)) where
f(t,[S,I,R]) = [-(beta*I*S)/(S+I+R); (beta*I*S)/(S+I+R)-I*gamma; gamma*I];
To solve this write
G = (4*y(i,:) - y(i-1,:))/3
y(i+1,:) = fsolve(#(u) u-2*h/3*f(t(i+1),u) - G, y(i-1,:)+2*h*F(i,:))
where a midpoint step is used to get an order 2 approximation as initial guess, F(i,:)=f(t(i),y(i,:)). Add solver options for error tolerances as necessary, you want the error in the implicit equation smaller than the truncation error O(h^3) of the step. One can also keep only a short array of function values, then one has to be careful for the correspondence of the position in the short array to the time index.
Using all that and a reference solution by a higher order standard solver produces the following error graphs for the components
where one can see that the first order error of the constant first step results in a first order global error, while with a second order error in the first step using the Euler method results in a clear second order global error.
Implement the method in general terms
from scipy.optimize import fsolve
def BDF2(f,t,y0,y1):
N, h = len(t)-1, t[1]-t[0];
y = (N+1)*[np.asarray(y0)];
y[1] = y1;
for i in range(1,N):
t1, G = t[i+1], (4*y[i]-y[i-1])/3
y[i+1] = fsolve(lambda u: u-2*h/3*f(t1,u)-G, y[i-1]+2*h*f(t[i],y[i]), xtol=1e-3*h**3)
return np.vstack(y)
Set up the model to be solved
gamma=1/7;
beta=1/3;
print beta, gamma
y0 = np.array([8e6, 10, 0])
P = sum(y0); y0 = y0/P
def f(t,y): S,I,R = y; trns = beta*S*I/(S+I+R); recv=gamma*I; return np.array([-trns, trns-recv, recv])
Compute a reference solution and method solutions for the two initialization variants
from scipy.integrate import odeint
tg = np.linspace(0,120,25*128)
yg = odeint(f,y0,tg,atol=1e-12, rtol=1e-14, tfirst=True)
M = 16; # 8,4
t = tg[::M];
h = t[1]-t[0];
y1 = BDF2(f,t,y0,y0)
e1 = y1-yg[::M]
y2 = BDF2(f,t,y0,y0+h*f(0,y0))
e2 = y2-yg[::M]
Plot the errors, computation as above, but embedded in the plot commands, could be separated in principle by first computing a list of solutions
fig,ax = plt.subplots(3,2,figsize=(12,6))
for M in [16, 8, 4]:
t = tg[::M];
h = t[1]-t[0];
y = BDF2(f,t,y0,y0)
e = (y-yg[::M])
for k in range(3): ax[k,0].plot(t,e[:,k],'-o', ms=1, lw=0.5, label = "h=%.3f"%h)
y = BDF2(f,t,y0,y0+h*f(0,y0))
e = (y-yg[::M])
for k in range(3): ax[k,1].plot(t,e[:,k],'-o', ms=1, lw=0.5, label = "h=%.3f"%h)
for k in range(3):
for j in range(2): ax[k,j].set_ylabel(["$e_S$","$e_I$","$e_R$"][k]); ax[k,j].legend(); ax[k,j].grid()
ax[0,0].set_title("Errors: first step constant");
ax[0,1].set_title("Errors: first step Euler")

Problem with separating Real and Imaginary parts for fmincon (constrained MATLAB optimization). How to program it correctly?

I am trying to solve this optimization problem with fmincon function in MATLAB:
Where all H are complex matrices, g and Pdes are complex column vectors, D0 and E0 are numbers.
I expect to get complex column vector of g (and in general its should be complex), So I divided problem in two parts: real and imag, but it does not work, MATLAB returning me a message:
Not enough input arguments.
Error in temp>nonlincon (line 17)
c(1) = norm ( H_d*([g(1)+1i*g(4); g(2)+1i*g(5); g(3)+1i*g(6)]) )^2 - D_0;
Error in temp (line 12)
= fmincon(objective,x0,[],[],[],[],[],[],nonlincon);
Where I am wrong?
And in general am I right in writing given problem in the following way:?
% For example:
D_0 = 2*10^(-5)*10^(60/10);
E_0 = 50;
H_b = rand(15,3) + 1i*rand(15,3);
P_des = rand(15,1) + 1i*rand(15,1);
H_d = rand(10,3) + 1i*rand(10,3);
objective = #(g) (norm ( H_b*([g(1)+1i*g(4); g(2)+1i*g(5); g(3)+1i*g(6)]) - P_des ))^2;
x0 = ones(1,3*2)';
options = optimoptions('fmincon','MaxFunctionEvaluations',10e3);
[X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD,HESSIAN]...
= fmincon(objective,x0,[],[],[],[],[],[],nonlincon);
% So I expect to get a column vector g: 1st 3 elements - Real part, next 3 - Imag
function [c,ceq] = nonlincon(g, H_d, E_0, D_0)
c(1) = (norm ( H_d*([g(1)+1i*g(4); g(2)+1i*g(5); g(3)+1i*g(6)]) ))^2 - D_0;
c(2) = (norm ([g(1)+1i*g(4); g(2)+1i*g(5); g(3)+1i*g(6)]))^2 - E_0;
ceq = [];
end
You just need to specify that nonlincon is a function of variable g only when calling fmincon
The code is as follow
[X,FVAL,EXITFLAG,OUTPUT,LAMBDA,GRAD,HESSIAN]...
= fmincon(objective,x0,[],[],[],[],[],[],#(g)nonlincon(g, H_d, E_0, D_0));
Solution X
X = [0.2982; 0.1427; 0.3597; -0.0729; -0.1187; 0.2090]

Solving coupled nonlinear differential equations

I have a differential equation that is as follows:
%d/dt [x;y] = [m11 m12;m11 m12][x;y]
mat = #(t) sin(cos(w*t))
m11 = mat(t) + 5 ;
m12 = 5;
m21 = -m12 ;
m22 = -m11 ;
So I have that my matrix is specifically dependent on t. For some reason, I am having a super difficult time solving this with ode45. My thoughts were to do as follows ( I want to solve for x,y at a time T that was defined):
t = linspace(0,T,100) ; % Arbitrary 100
x0 = (1 0); %Init cond
[tf,xf] = ode45(#ddt,t,x0)
function xprime = ddt(t,x)
ddt = [m11*x(1)+m12*x(2) ; m12*x(1)+m12*x(2) ]
end
The first error I get is that
Undefined function or variable 'M11'.
Is there a cleaner way I could be doing this ?
I'm assuming you're running this within a script, which means that your function ddt is a local function instead of a nested function. That means it doesn't have access to your matrix variables m11, etc. Another issue is that you will want to be evaluating your matrix variables at the specific value of t within ddt, which your current code doesn't do.
Here's an alternative way to set things up that should work for you:
% Define constants:
w = 1;
T = 10;
t = linspace(0, T, 100);
x0 = [1 0];
% Define anonymous functions:
fcn = #(t) sin(cos(w*t));
M = {#(t) fcn(t)+5, 5; -5 #(t) -fcn(t)-5};
ddt = #(t, x) [M{1, 1}(t)*x(1)+M{2, 1}*x(2); M{1, 2}*x(1)+M{2, 2}(t)*x(2)];
% Solve equations:
[tf, xf] = ode45(ddt, t, x0);
One glaring error is that the return value of function ddt is xprime, not ddt. Then as mentioned in the previous answer, mm1 at the time of definition should give an error as t is not defined. But even if there is a t value available at definition, it is not the same t the procedure ddt is called with.
mat = #(t) sin(cos(w*t))
function xprime = ddt(t,x)
a = mat(t) + 5 ;
b = 5;
ddt = [ a, b; -b, -a]*x
end
should work also as inner procedure.

Numerical Integral in MatLab using integral command

I am trying to compute the value of this integral using Matlab
Here the other parameters have been defined or computed in the earlier part of the program as follows
N = 2;
sigma = [0.01 0.1];
l = [15];
meu = 4*pi*10^(-7);
f = logspace ( 1, 6, 500);
w=2*pi.*f;
for j = 1 : length(f)
q2(j)= sqrt(sqrt(-1)*2*pi*f(j)*meu*sigma(2));
q1(j)= sqrt(sqrt(-1)*2*pi*f(j)*meu*sigma(1));
C2(j)= 1/(q2(j));
C1(j)= (q1(j)*C2(j) + tanh(q1(j)*l))/(q1(j)*(1+q1(j)*C2(j)*tanh(q1(j)*l)));
Z(j) = sqrt(-1)*2*pi*f(j)*C1(j);
Apprho(j) = meu*(1/(2*pi*f(j))*(abs(Z(j))^2));
Phi(j) = atan(imag(Z(j))/real(Z(j)));
end
%integration part
c1=w./(2*pi);
rho0=1;
fun = #(x) log(Apprho(x)/rho0)/(x.^2-w^2);
c2= integral(fun,0,Inf);
phin=pi/4-c1.*c2;
I am getting an error like this
could anyone help and tell me where i am going wrong.thanks in advance
Define Apprho in a separate *.m function file, instead of storing it in an array:
function [ result ] = Apprho(x)
%
% Calculate f and Z based on input argument x
%
% ...
%
meu = 4*pi*10^(-7);
result = meu*(1/(2*pi*f)*(abs(Z)^2));
end
How you calculate f and Z is up to you.
MATLAB's integral works by calling the function (in this case, Apprho) repeatedly at many different x values. The x values called by integral don't necessarily correspond to the 1: length(f) values used in your original code, which is why you received errors.

solve a system of nonlinear equations in matlab

I'm trying to solve 4 nonlinear equations in matlab.
i wrote a code using fsolve but it failed to proceed, and wrote another one using solve but after 4 hours of running without a result I stop it myself.
I dont know what else i can use to solve it?
is it solvable at all?
this is the code I wrote using fsolve
x and y are vectors and n is the length of this vectors equal to 1200. nu is degree of freedom equal to 1196.
p(1), p(2)... and p(4) are the unknowns
x = data1(:,1);
y = data1(:,2);
n = length(x);
p0 = [0 0 0 0];
options = optimset('Display','iter');
[p,fval] = fsolve(#myfunc,p0,options);
myfunc:
function F = myfunc(p)
global x y n
r = y-p(1)*x.^3-p(2)*x.^2-p(3)*x-p(4);
F = [sum(x.^3)-(n-4-2)*sum(x.^3./r);
sum(x.^2)-(n-4-2)*sum(x.^2./r);
sum(x.^1)-(n-4-2)*sum(x.^1./r);
sum(x.^0)-(n-4-2)*sum(x.^0./r)];
Sounds like the problem is too stiff for fsolve, or you've got a poor starting guess. The code you have looks fine, however, if you may want to use a parametrized anonymous function:
x = data1(:,1);
y = data1(:,2);
n = length(x);
p0 = [0 0 0 0];
options = optimset('Display','iter');
[p,fval] = fsolve(#(p) myfunc(p,x,y,n),p0,options);
then myfunc:
function F = myfunc(p,x,y,n)
r = y-p(1)*x.^3-p(2)*x.^2-p(3)*x-p(4);
F = [sum(x.^3)-(n-4-2)*sum(x.^3./r);
sum(x.^2)-(n-4-2)*sum(x.^2./r);
sum(x.^1)-(n-4-2)*sum(x.^1./r);
sum(x.^0)-(n-4-2)*sum(x.^0./r)];
end