I am trying to use a Dirac delta function within a system of equations so that h(t) increases at t=1.5, t=3, t=4.5 etc.
Here is my code below:
A:=30: a:=1: dm:=3: c3:=5: d0:=1/a: t0:=1/dm: h0:=B0: y:=A*a: cc:=t0*c3: #same as cc=c3/Bm
N:=8: T:=0.5:
sys_ode:= diff(h(t),t)=y*sum(Dirac(t-dm*n*T),n=0..N) - exp(1-d(t))*h(t), diff(d(t),t)=exp(1-d(t))*h(t) - cc*d(t);
ics:=h(0)=A*a, d(0)=0:
ND:=dsolve([sys_ode,ics],numeric); #numerical solution to the system
ND(1);
ND(2);
ND(3);
ND(4);
Currently when I run this I get:
ND(1);
[t = 1., d(t) = HFloat(2.6749858704773097),
h(t) = HFloat(23.164506116038023)]
ND(2);
[t = 2., d(t) = HFloat(2.5365091646635465),
h(t) = HFloat(18.95651519442652)]
ND(3);
[t = 3., d(t) = HFloat(2.376810307084265),
h(t) = HFloat(15.018803909414379)]
ND(4);
[t = 4., d(t) = HFloat(2.1927211646807137),
h(t) = HFloat(11.391114874494281)]
But h(t) in theory should be increasing in value since there is input into the system at t=1.5 and at t=3 and not have decreased all the way down to h(t)=11.39 at t=4.
Any ideas where I have gone wrong would be appreciated. Thanks.
Support for numerical integration of ODE problems containing 0-order Dirac functions was added for Maple 2015.0. Since this addition the results from the integration you show look like this:
> ND(1);
[t = 1., d(t) = 3.01973877409584, h(t) = 37.2561191650856]
> ND(2);
[t = 2., d(t) = 3.38932165514909, h(t) = 61.6360962313253]
> ND(3);
[t = 3., d(t) = 3.32743891599543, h(t) = 71.0940887774625]
> ND(4);
[t = 4., d(t) = 3.59829473587253, h(t) = 79.8444924691185]
The function is indeed increasing.
In prior versions of Maple, no special treatment of Dirac was performed for numeric integration, so unless one hits the Dirac-0 points exactly, they would be ignored, and if they were hit, integration would halt with an undefined. The old way would have worked just as though the Dirac functions were not even there, which is consistent with your result:
> sys_ode:= diff(h(t),t)= - exp(1-d(t))*h(t),
> diff(d(t),t)=exp(1-d(t))*h(t) - cc*d(t):
> ND:=dsolve([sys_ode,ics],numeric):
> ND(1);
[t = 1., d(t) = 2.67498587047731, h(t) = 23.1645061160380]
> ND(2);
[t = 2., d(t) = 2.53650916466355, h(t) = 18.9565151944265]
> ND(3);
[t = 3., d(t) = 2.37681030708426, h(t) = 15.0188039094144]
> ND(4);
[t = 4., d(t) = 2.19272116468071, h(t) = 11.3911148744943]
Related
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!
h=0.005;
x = 0:h:40;
y = zeros(1,length(x));
y(1) = 0;
F_xy = ;
for i=1:(length(x)-1)
k_1 = F_xy(x(i),y(i));
k_2 = F_xy(x(i)+0.5*h,y(i)+0.5*h*k_1);
k_3 = F_xy((x(i)+0.5*h),(y(i)+0.5*h*k_2));
k_4 = F_xy((x(i)+h),(y(i)+k_3*h));
y(i+1) = y(i) + (1/6)*(k_1+2*k_2+2*k_3+k_4)*h;
end
I have the following code, I think it's right. I know there's parts missing on the F_xy because this is my follow up question.
I have dx/dt = = −x(2 − y) with t_0 = 0, x(t_0) = 1
and dy/dt = y(1 − 2x) with t_0 = 0, y(t_0) = 2.
My question is that I don't know how to get these equations in to the code. All help appreciated
You are using both t and x as independent variable in an inconsistent manner. Going from the actual differential equations, the independent variable is t, while the dependent variables of the 2-dimensional system are x and y. They can be combined into a state vector u=[x,y] Then one way to encode the system close to what you wrote is
h=0.005;
t = 0:h:40;
u0 = [1, 2]
u = [ u0 ]
function udot = F(t,u)
x = u(1); y = u(2);
udot = [ -x*(2 - y), y*(1 - 2*x) ]
end
for i=1:(length(t)-1)
k_1 = F(t(i) , u(i,:) );
k_2 = F(t(i)+0.5*h, u(i,:)+0.5*h*k_1);
k_3 = F(t(i)+0.5*h, u(i,:)+0.5*h*k_2);
k_4 = F(t(i)+ h, u(i,:)+ h*k_3);
u(i+1,:) = u(i,:) + (h/6)*(k_1+2*k_2+2*k_3+k_4);
end
with a solution output
Is F_xy your derivative function?
If so, simply write it as a helper function or function handle. For example,
F_xy=#(x,y)[-x*(2-y);y*(1-2*x)];
Also note that your k_1, k_2, k_3, k_4, y(i) are all two-dimensional. You need to re-size your y and rewrite the indices in your iterating steps accordingly.
I would like to solve the following equation :
f''+tau(x)*f+f^3=0
f'(0)=0
f(inf)=1
Where tau(x) can be any function of x. The problem is to translate the boundary condition f(inf)=1 into matlab. My first solution, by reading different posts on the web was to approximate infinity by a large finite number but it doesn't give satisfying solution. Here is the code that I use :
function f = solve_GL(tau)
options = bvpset('RelTol', 1e-5);
Xstart = 0;
Xend = 1000;
solinit = bvpinit(linspace(Xstart, Xend, 50), [0, 1]);
sol = bvp4c(#twoode, #twobc, solinit, options);
x = linspace(Xstart,Xend);
y = deval(sol,x);
plot(x,y(1,:))
function dydx = twoode(x,y)
dydx = [y(2); (-heaviside(x-2)+1).*y(1)+y(1).^3];
function res = twobc(ya,yb)
res = [ya(2); yb(1)-1];
If somebody has a solution to this problem, I would be glad to hear it !
I'm trying to solve a system of ordinary differential equations from y_1 to y_2, say
G' = D
D' = f(y,G,D)
with the initial conditions
G(y_1) = 0
D(y_1) = 0
My problem is that I do not know y_1 and y_2, to counter for this I of course need two additional equations which is
F_1(y_1,y_2,G(y_2)) = 0
F_2(y_1,y_2,G(y_2)) = 0
So far I have tried to implement it using fsolve (i guess the new name is fzero) to find the zeros, then from the functions F_1 and F_2 i call the ode45 to solve from y_1 to y_2 in order to calculate the functions. However it does not work and I can not seem to find any mistakes. Therefore i looked for new methods/ideas and I found the method bvp4c, but I'm not sure whether i can use it in my case. Does anyone have experience with bvp4c and know whether and how I should use it, or do you have other ideas?
Any help is appreciated.
Code for reference:
function [Fval,sol,t,G] = EntrepreneurialFinanceNondiversifiableRisk
global sigma rf tau b epsilon gamma theta1 theta2 alpha ya K I taug mu eta...
omega
sigma=0.2236; rf=0.03; tau=0.1129; b=0.85; epsilon=0.2; gamma=2;
theta1 = -0.704; alpha = 0.6; theta2=1.704; ya=0.1438; K=27; I = 10;
taug = 0.1; mu = 0.04; eta = 0.4; omega = 0.1;
tau = 0;
option = optimset('Display','iter');
sol = fsolve(#f,[0.1483,2.8],option);
Fval = f(sol);
[t,G] = solvediff(sol(1),sol(2));
function F = f(x)
yd = x(1);
yu = x(2);
global rf tau b theta1 alpha theta2 K I taug
Vstar =# (y) (1-tau+tau*(1-theta1-(1-alpha)*(1-tau)* theta1/tau)^...
(1/theta1))*y/rf;
VstarPrime = (1-tau+tau*(1-theta1-(1-alpha)*(1-tau)...
*theta1/tau)^(1/theta1))*1/rf;
qbar =#(yd,yu) (yd^theta1-yd^theta2)/(yu^theta2*yd^theta1-yu^theta1*...
yd^theta2);
qunderbar =# (yd,yu) (yu^theta2-yu^theta1)/(yu^theta2*yd^theta1-...
yu^theta1*yd^theta2);
A =# (y) (1-tau)*(y/rf);
V = #(y,yd) A(y) + (tau * b)/rf * (1 - (y/yd)^(theta2)) - (1-alpha)*A(yd)*...
(y/yd)^(theta2);
F0 =# (yd,yu) b/rf-(b/rf-alpha*A(yd))*qunderbar(yd,yu)/(1-qbar(yd,yu));
[t,G] = solvediff(yd,yu);
F = zeros(2,1);
F(1) = Vstar(yu)-F0(yd,yu)-K-taug*(Vstar(yu)-K-I)-G(end,2);
F(2) = (1-taug)*VstarPrime-G(end,2);
function [t,G] = solvediff(yd,yu)
[t,G] = ode45(#diff,[yd,yu],[0,0]);
Assuming the domain of definition is big enough and you have good initial values, a Newton implementation with divided differences for the construction of the Jacobian looks like this:
h=1e-5
for k=1:10 do
Fval = F(yd, yu)
dFdyd = (F(yd+h, yu)-F(yd-h, yu))/(2*h)
dFdyu = (F(yd, yu+h)-F(yd, yu-h))/(2*h)
dF = [ dFdyd dFdyu ]
ynext = [ yd; yu ] - dF^(-1)*Fval;
yd = ynext(1); yu = ynext(2);
end
I am implementing the expression given in the image which is the log-likelihood for AR(p) model.
In this case, p=2. I am using fmincon as the optimization tool. I checked the documentation and other examples over internet regarding the syntax of this command. Still, I am unable to mitigate the problem. Can somebody please help in eliminating the problem?
The following is the error
Warning: Options LargeScale = 'off' and Algorithm = 'trust-region-reflective' conflict.
Ignoring Algorithm and running active-set algorithm. To run trust-region-reflective, set
LargeScale = 'on'. To run active-set without this warning, use Algorithm = 'active-set'.
> In fmincon at 456
In MLE_AR2 at 20
Error using ll_AR2 (line 6)
Not enough input arguments.
Error in fmincon (line 601)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in MLE_AR2 (line 20)
[theta_hat,likelihood] =
fmincon(#ll_AR2,theta0,[],[],[],[],low_theta,up_theta,[],opts);
Caused by:
Failure in initial user-supplied objective function evaluation. FMINCON cannot
continue.
The vector of unknown parameters,
theta_hat = [c, theta0, theta1, theta2] where c = intercept in the original model which is zero ; theta0 = phi1 = 0.195 ; theta1 = -0.95; theta2 = variance of the noise sigma2_epsilon.
The CODE:
clc
clear all
global ERS
var_eps = 1;
epsilon = sqrt(var_eps)*randn(5000,1); % Gaussian signal exciting the AR model
theta0 = ones(4,1); %Initial values of the parameters
low_theta = zeros(4,1); %Lower bound of the parameters
up_theta = 100*ones(4,1); %upper bound of the parameters
opts=optimset('DerivativeCheck','off','Display','off','TolX',1e-6,'TolFun',1e-6,...
'Diagnostics','off','MaxIter', 200, 'LargeScale','off');
ERS(1) = 0.0;
ERS(2) = 0.0;
for t= 3:5000
ERS(t)= 0.1950*ERS(t-1) -0.9500*ERS(t-2)+ epsilon(t); %AR(2) model y
end
[theta_hat,likelihood,exit1] = fmincon(#ll_AR2,theta0,[],[],[],[],low_theta,up_theta,[],opts);
exit(1,1)=exit1;
format long;disp(num2str([theta_hat],5))
function L = ll_AR2(theta,Y)
rho0 = theta(1); %c
rho1 = theta(2); %phi1
rho2 = theta(3); %phi2
sigma2_epsilon = theta(4);
T= size(Y,1);
p=2;
mu_p = rho0./(1-rho1-rho2); %mean of Y for the first p samples
%changed sign of the log likelihood expression
cov_p = xcov(Y);
L1 = (Y(3:end) - rho0 - rho1.*Y(1:end-1) - rho2.*Y(1:end-2)).^2;
L = (p/2).*(log(2*pi)) + (p/2).*log(sigma2_epsilon) - 0.5*log(det(inv(cov_p))) + 0.5*(sigma2_epsilon^-1).*(Y(p) - mu_p)'.*inv(cov_p).*(Y(p) - mu_p)+...
(T-p).*0.5*log(2*pi) + 0.5*(T-p).*log(sigma2_epsilon) + 0.5*(sigma2_epsilon^-1).*L1;
L = sum(L);
end
You are trying to pass constant parameters to the objective function (Y) in addition to the optimization variables (theta).
The right way of doing so is using anonymous function:
Y = ...; %// define your parameter here
fmincon( #(theta) ll_AR2(theta, Y), theta0, [],[],[],[],low_theta,up_theta,[],opts);
Now the objective function, as far as fmincon concerns, depends only on theta.
For more information you can read about anonymous functions and passing const parameters.