ODE problem : Unable to meet integration tolerances

15 views (last 30 days)
Hello,
I'm trying to solve a differential non linear equation with very high values (each constant is like 10^-20 or 10^20 or even more). And i got problems of tolerances. I've tried that :
options=odeset('RelTol',1e-30,'AbsTol',1e-30)
xvalues=30:200;
[x,y]=ode45('fun',xvalues,1, options)
Where the function is, as i told you, with very big values (for example, a term with exp(x)...)
""Warning: RelTol has been increased to
2.22045e-14.
Warning: Failure at t=3.000000e+01. Unable
to meet integration tolerances without
reducing the step size below the smallest
value allowed (1.136868e-13) at time t. ""
If you have any idea, help me !!!
Thank you
Fred
  2 Comments
Walter Roberson
Walter Roberson on 15 May 2015
Could I ask you to show your ODE in symbolic form? I have not done much work with transforming back from ode45 calls into formulae and I suspect I got it wrong when I did.
Could you confirm your boundary condition is that the derivative evaluated at the initial coordinate, xvalues(1), 35, should be 1? The documentation is not explicit about the fact that the initial (t,y) will have t be the first time and y be the initial condition, but my tests confirm it in practice. (An alternative reading would be that the initial values should be for an implicit time of 0, which would seem less practical, but I wanted to be sure I got the theory right.)
Fred Dugli
Fred Dugli on 15 May 2015
I haven't written it another way than this one I can try to make it more clear (sadly it looks i can't make LaTeX on this forum :( ) :
dy/dx= -C1*x^(-5/2)/sqrt(C2+C3/x) * ( y^2 - (1-y)*x^(3/2)*e(-x)/C4 )
With C1, C2, C3, C4 constants. I hope it can help you
Boundary condition is that y=1 for x small (for example y(x=35)=0 ; in my problem, I study x from 30 or 35, as u can see with my code, y don't change between 30 and 35)
But I think it worked well since the result really looks like what I have to find (the equation was already solved before, but I want to test influence of some parameters). From this example I really think the first alternative you are speaking about must be true.
If you want more informations, don't hesitate to ask me, i'll to my best to answer you.

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 15 May 2015
I would increase the tolerance (to perhaps 1E-8 or more) rather than decrease it, but that may not solve your problem.
The warning is that at t=30, your ODE is most likely encountering a singularity. First, plot it to see what it is doing, then start it again at some value greater than t=30 (perhaps t=35) and see what it does, then experiment further to get the result you want. You may have to do a piecewise integration. That may not work in the end (you may not be able to integrate it beyond t=30 regardless), but unless you experiment with it, you will never know.
  6 Comments
Walter Roberson
Walter Roberson on 15 May 2015
Star Strider, note you ran the ode from time 0 rather than from time 35, but you did not change the initial condition from being 1.

Sign in to comment.

More Answers (2)

Fred Dugli
Fred Dugli on 15 May 2015
Edited: Fred Dugli on 15 May 2015
I don't really know why, i made a few changes (like inverting x and y, changing tolerance). And now it works !!!!!!!!!!!!!!!!
I get the nice curve i expected. Don't ask me why it now works ...
In case people go on this post and have a similar problem (hope it could help them). Here is the code that worked for me :
function y2 = Approx2( x , y )
alpha2 = 7.1472E-14;
H = 4.5198E-11*sqrt(0.15+2.4047./x)./(x.^(3/2));
n= 3.3206e+08 ./ (x.^3);
S=2.19216e-16*exp(x)./(x.^(3/2));
y2=-alpha2*n.*(y.^2-(1-y)./S)./(x.*H);
end
And the main is :
options=odeset('RelTol',1e-12,'AbsTol',1e-12);
xvalues=[35, 160];
[x,y]=ode45(@Approx2,xvalues,1, options);
y
%
figure(1)
plot(x, y)
grid
Thank you all for your help, and time for reading/answering me (and sorry for my mistakes in english !), if I find more details about why it now works, i'll let you know

Walter Roberson
Walter Roberson on 15 May 2015
You can never get a relative tolerance of 1E-30 with double precision floating point numbers. The absolute least relative tolerance that could make sense is eps(1) = 2.22044604925031e-16 as that represents the relative difference between adjacent double precision floating point numbers.
An absolute tolerance of 1E-30 might make sense in some situations, but only when the values being computed are in the range of roughly 1E-18 to 1E-24.
If you have large values such as 1E+20 in your calculation, to get down below 1E+4 (eps(1) times the large value) you need to be dividing by large values or you need to be hoping for extreme cancellation of values.
I think you need to be re-thinking your tolerances.
  1 Comment
Fred Dugli
Fred Dugli on 15 May 2015
Edited: Fred Dugli on 15 May 2015
Thank you for your answer, I knew tolerance was too small since it's less than eps, but I just wanted to be sure to have the minimum tolerance possible. It's not possible to change the value of eps ?? I assume no ... even if that surprises me, it's not rare for practical calculus to have values under eps.
And i think it would be hard to divide anything since for example my S variable takes values from 10e3 to 10e50 ...

Sign in to comment.

Categories

Find more on Mathematics in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!