I have a system that looks like
dn/dt=f(n,v)
dh/dt=g(h,v)
I want to solve this equation on the manifold F(v,n,h)=0, a nonlinear function in v. I tried to use something like v=fzero(#(x) F(x,n,h),0) to solve for the value of v on the manifold at each time step. But this is incredibly slow and ode15s (my system is a relaxation oscillator) fails to meet integration tolerance. How do I find solution to the ODE on the manifold defined by F(v,n,h)=0?
I find #LutzL's comment very helpful. It is possible to set up a DAE solver using ode15s.
Example: The "Solve Robertson Problem as Semi-Explicit Differential Algebraic Equations (DAEs)" section in https://www.mathworks.com/help/matlab/ref/ode15s.html
In my case, I would setup a matrix:
M=[zeros(1,3);0,1,0;0,0,1];
options = odeset('Mass',M,'RelTol',1e-5,'AbsTol',1e-6,'MaxStep',0.01);
y0=[v0,n0,h0];
[T,Y]=ode15s(#slow,[0 50],y0,options);
And slow is a function defined as:
function dy = slow(t,y)
v=y(1); n=y(2); h=y(3);
dy=zeros(3,1);
dy(1)=F(v,n,h);
dy(2)=f(n,v);
dy(3)=g(h,v);
end
One of the possible ways to solve this problem is to differentiate
the F(v,n,h)=0 equation:
Now we can obtain the ODE system
or
which can be solved in the usual way.
Related
I have to analyze 802.11 saturation throughput using matlab, and here is my problem. I'm trying to solve parametric equations below (parameters are m,W,a) using solve function and i get
Warning: Explicit solution could not be found
How could I solve above equations using matlab?
I guess you were trying to find an analytical solution for tau and p using symbolic math. Unless you're really lucky with your parameters (e.g. m=1), there won't be an analytical solution.
If you're interested in numerical values for tau and p, I suggest you manually substitue p in the first equation, and then solve an equation of the form tau-bigFraction=0 using, e.g. fzero.
Here's how you'd use fzero to solve a simple equation kx=exp(-x), with k being a parameter.
k = 5; %# set a value for k
x = fzero(#(x)k*x-exp(-x),0); %# initial guess: x=0
I have a problem in solving nonlinear parabolic pde of following form.
(consider u_x as differentiation of u w.r.t. x)
U(1)_t = a1(U(1),x)*U(2)_t + b1(U(1),x,U(3)) = ( D1(x,U(1))*U(1)_x )_x + c1( U(1), U(3))*U(1)_x ---(1)
and its coupled equation
U(3)_t = a2(U(1),U(3))*U(2)_t + b2(U(1),x,U(3)) = ( D3*U(3)_x )_x ---(2)
as you can see U(1), U(2), U(3) are there with only two PDE. That is because U(2) is not function of x and has its own pde as
U(2)_t = (1/r)( D2(U(2))*U(2)_r )_r ---(3)
Now (3) is standalone solvable. I solved it with pdepe in MATLAB. Now I need to put value of U(2)_t in (1)&(2) then solve them, which I couldn't do in pdepe.
So this is my question. Is there any way that after solving (3), value of U(2)_t could be imported in (1)&(2) and solve them simultaneously. Alternatively, is there any way that I can incoporate (3) directly in differential form in (1)&(2) and solve resulting coupled system in MATLAB. Thanks in Advance.
You'll have to linearize and do an iterative solution. Newton-Raphson is usually the preferred method, although some people like BFGS.
I don't know how you formulate your PDEs. Finite difference, finite element, boundary element, or something else? Just posting the PDEs doesn't tell me enough.
In Matlab I know how to solve an ODE until an even occurs (for example, solve the ODE until the y-coordinate is zero):
http://www.mathworks.com/help/techdoc/ref/odeset.html#f92-1017470
Is there an analogy in Octave?
Here is the relevant code:
lsode_options('Events', #events);
t0 = linspace (0, 20, 1000);
[t,x,te,ye,ie] = lsode(#HH, ynot, t0);
Install the package odepkg from Octave-Force. You may well already have this installed. You then use the ode solver functions from this package, which have identical syntax to the Matlab ode solvers, such as ode45. Note that the names of the solvers may not be identical, and you will need to find the appropriate one for your problem. ode45 does appear to have an implementation in the latest version though.
I want to solve a nonlinear differential equation and I have tried many methods, such as ode45,ode15s, but failed. Could you please give me a help. The equation is
x''+0.01x'+x+2(x'-0.55x)^3=sin(0.1t)% (I will expand it in my program).
I have wrote the ode method in Matlab, please have a look.
%system governing function
function xdot=ForcedOscillator1(t,x,dummy,zeta,a,b,c,d,Omega,Xo)
xdot=[x(2);-zeta*x(2)-x(1)-a*x(2)^3-b*x(2)^2*x(1)-c*x(2)*x(1)^2-d*x(1)^3+Xo*sin(Omega*t)];
%ode program
clear all
clc
zeta=0.01;
a=2;
b=-3.3;
c=1.815;
d=-0.3328;
Omega=0.1; Xo=1;
tspan=[0 100]
options=odeset('RelTol',1e-8,'AbsTol',[1e-8 1e-8]);
for m=1:1
[t,x]=ode15s('ForcedOscillator1',tspan,[0 0]',options,zeta,a(m),b(m),c(m),d (m),Omega,Xo);
plot(t,zeta.*x(:,2)+x(:,1)+a.*x(:,2).^3+b.*x(:,2).^2.*x(:,1)+c.*x(:,2).*x(:,1).^2+d.*x(:,1).^3);
grid on
xlabel('t(s)');
ylabel('F_t(N)');
title('Response of a nonlinear system');
hold on
end
As you can see, when I run this file, the output will be extraordinarily large, it will reach about 10^49. I think it must be something wrong in my program or the system is unstable.
could you please help solve this question in the numerical methods. Or prove this equation is unstable.
your system is just unstable...
If you need proof, I suggest finding good ode textbook
Here is the MATLAB/FreeMat code I got to solve an ODE numerically using the backward Euler method. However, the results are inconsistent with my textbook results, and sometimes even ridiculously inconsistent. What is wrong with the code?
function [x,y] = backEuler(f,xinit,yinit,xfinal,h)
%f - this is your y prime
%xinit - initial X
%yinit - initial Y
%xfinal - final X
%h - step size
n = (xfinal-xinit)/h; %Calculate steps
%Inititialize arrays...
%The first elements take xinit and yinit corespondigly, the rest fill with 0s.
x = [xinit zeros(1,n)];
y = [yinit zeros(1,n)];
%Numeric routine
for i = 1:n
x(i+1) = x(i)+h;
ynew = y(i)+h*(f(x(i),y(i)));
y(i+1) = y(i)+h*f(x(i+1),ynew);
end
end
Your method is a method of a new kind. It is neither backward nor forward Euler. :-)
Forward Euler: y1 = y0 + h*f(x0,y0)
Backward Euler solve in y1: y1 - h*f(x1,y1) = y0
Your method: y1 = y0 +h*f(x0,x0+h*f(x0,y0))
Your method is not backward Euler.
You don't solve in y1, you just estimate y1 with the forward Euler method. I don't want to pursue the analysis of your method, but I believe it will behave poorly indeed, even compared with forward Euler, since you evaluate the function f at the wrong point.
Here is the closest method to your method that I can think of, explicit as well, which should give much better results. It's Heun's Method:
y1 = y0 + h/2*(f(x0,y0) + f(x1,x0+h*f(x0,y0)))
The only issue I can spot is that the line:
n=(xfinal-xinit)/h
Should be:
n = abs((xfinal-xinit)/h)
To avoid a negative step count. If you are moving in the negative-x direction, make sure to give the function a negative step size.
Your answers probably deviate because of how coarsely you are approximating your answer. To get a semi-accurate result, deltaX has to be very very small and your step size has to be very very very small.
PS. This isn't the "backward Euler method," it is just regular old Euler's method.
If this is homework please tag it so.
Have a look at numerical recipes, specifically chapter 16, integration of ordinary differential equations. Euler's method is known to have problems:
There are several reasons that Euler’s method is not recommended for practical use, among them, (i) the method is not very accurate when compared to other, fancier, methods run at the equivalent stepsize, and (ii) neither is it very stable
So unless you know your textbook is using Euler's method, I wouldn't expect the results to match. Even if it is, you probably have to use an identical step size to get an identical result.
Unless you really want to solve an ODE via Euler's method that you've written by yourself you should have a look at built-in ODE solvers.
On a sidenote: you don't need to create x(i) inside the loop like this: x(i+1) = x(i)+h;. Instead, you can simply write x = xinit:h:xfinal;. Also, you may want to write n = round(xfinal-xinit)/h); to avoid warnings.
Here are the solvers implemented by MATLAB.
ode45 is based on an explicit
Runge-Kutta (4,5) formula, the
Dormand-Prince pair. It is a one-step
solver – in computing y(tn), it needs
only the solution at the immediately
preceding time point, y(tn-1). In
general, ode45 is the best function to
apply as a first try for most
problems.
ode23 is an implementation of an
explicit Runge-Kutta (2,3) pair of
Bogacki and Shampine. It may be more
efficient than ode45 at crude
tolerances and in the presence of
moderate stiffness. Like ode45, ode23
is a one-step solver.
ode113 is a variable order
Adams-Bashforth-Moulton PECE solver.
It may be more efficient than ode45 at
stringent tolerances and when the ODE
file function is particularly
expensive to evaluate. ode113 is a
multistep solver — it normally needs
the solutions at several preceding
time points to compute the current
solution.
The above algorithms are intended to
solve nonstiff systems. If they appear
to be unduly slow, try using one of
the stiff solvers below.
ode15s is a variable order solver
based on the numerical differentiation
formulas (NDFs). Optionally, it uses
the backward differentiation formulas
(BDFs, also known as Gear's method)
that are usually less efficient. Like
ode113, ode15s is a multistep solver.
Try ode15s when ode45 fails, or is
very inefficient, and you suspect that
the problem is stiff, or when solving
a differential-algebraic problem.
ode23s is based on a modified
Rosenbrock formula of order 2. Because
it is a one-step solver, it may be
more efficient than ode15s at crude
tolerances. It can solve some kinds of
stiff problems for which ode15s is not
effective.
ode23t is an implementation of the
trapezoidal rule using a "free"
interpolant. Use this solver if the
problem is only moderately stiff and
you need a solution without numerical
damping. ode23t can solve DAEs.
ode23tb is an implementation of
TR-BDF2, an implicit Runge-Kutta
formula with a first stage that is a
trapezoidal rule step and a second
stage that is a backward
differentiation formula of order two.
By construction, the same iteration
matrix is used in evaluating both
stages. Like ode23s, this solver may
be more efficient than ode15s at crude
tolerances.
I think this code could work. Try this.
for i =1:n
t(i +1)=t(i )+dt;
y(i+1)=solve('y(i+1)=y(i)+dt*f(t(i+1),y(i+1)');
end
The code is fine. Just you have to add another loop within the for loop. To check the level of consistency.
if abs((y(i+1) - ynew)/ynew) > 0.0000000001
ynew = y(i+1);
y(i+1) = y(i)+h*f(x(i+1),ynew);
end
I checked for a dummy function and the results were promising.