Why i have this errors in my triple integral ? change numeric methods ?

조회 수: 2 (최근 30일)
Is this triple integral, i want to get the I_value, but for ss and T below, i have many erros that the I_value is NAN. Should i use gausslegendre for integral and newton_raphson for fzero ?
function I_value = doit
ss=0.01;
T=0.1;
tic
f2 = @(r,b,g) 1./(r.^2.*sqrt(1 - (b./r).^2 - (g^-2)*((2/15)*(ss)^9 *(1./(r - 1).^9 - 1./(r + 1).^9 - 9./(8* r).*(1./(r - 1).^8 - 1./(r + 1).^8)) - (ss)^3 *(1./(r -1).^3 - 1./(r + 1).^3 - 3./(2* r).* (1./(r - 1).^2 - 1./(r + 1).^2)))));
% The folloing function only works sith scalar b and g values.
X_scalar_b_scalar_g = @(b,g)real(pi - 2*b*integral(@(r)f2(r,b,g),rmin(b,g,ss),Inf,'AbsTol',1e-3,'RelTol',1e-3));
% Make X work with array inputs for b and a scalar g value.
X_scalar_g = @(b,g)arrayfun(@(b)X_scalar_b_scalar_g(b,g),b);
f3 = @(b,g) 2*(1 - cos(X_scalar_g(b,g))).*b;
qQd_scalar_g = @(g)integral(@(b)f3(b,g),0,10,'AbsTol',1e-3,'RelTol',1e-3);
% Make qQd_scalar_g work with array g inputs.
qQd = @(g)arrayfun(qQd_scalar_g,g);
f4 =@(g) g.^5.*qQd(g)./(exp(g.^2/T));
I_value = (1/T^3)*integral(f4,0,5,'AbsTol',1e-3,'RelTol',1e-3)
toc
function r = rmin(b,g,ss)
f1 = @(r) 1 - (b./r).^2 - (g^-2)*((2/15)*(ss)^9 *(1./(r - 1).^9 - 1./(r + 1).^9 - 9./(8*r).*(1./(r - 1).^8 - 1./(r + 1).^8)) -(ss)^3 *(1./(r-1).^3 - 1./(r+1).^3 - 3./(2*r).*(1./(r-1).^2 - 1./(r+1).^2)));
r = fzero(f1,1.1);
and the error is
Exiting fzero: aborting search for an interval containing a sign change
because no sign change is detected during search.
Function may not have a root.
Warning: Infinite or Not-a-Number value encountered.
> In funfun\private\integralCalc>midpArea at 397
In funfun\private\integralCalc at 105
In integral at 88
In ajuda2>@(b,g)real(pi-2*b*integral(@(r)f2(r,b,g),rmin(b,g,ss),Inf,'AbsTol',1e-3,'RelTol',1e-3)) at 7
In ajuda2>@(b)X_scalar_b_scalar_g(b,g) at 9
In ajuda2>@(b,g)arrayfun(@(b)X_scalar_b_scalar_g(b,g),b) at 9
In ajuda2>@(b,g)2*(1-cos(X_scalar_g(b,g))).*b at 10
In ajuda2>@(b)f3(b,g) at 11
In funfun\private\integralCalc>iterateScalarValued at 314
In funfun\private\integralCalc>vadapt at 132
In funfun\private\integralCalc at 75
In integral at 88
In ajuda2>@(g)integral(@(b)f3(b,g),0,10,'AbsTol',1e-3,'RelTol',1e-3) at 11
In ajuda2>@(g)arrayfun(qQd_scalar_g,g) at 13
In ajuda2>@(g)g.^5.*qQd(g)./(exp(g.^2/T)) at 14
In funfun\private\integralCalc>iterateScalarValued at 314
In funfun\private\integralCalc>vadapt at 132
In funfun\private\integralCalc at 75
In integral at 88
In ajuda2 at 15
Warning: Reached the limit on the maximum number of intervals in use. Approximate bound on error is 3.5e-02. The integral may not exist, or it may be difficult to
approximate numerically to the requested accuracy.

채택된 답변

Mike Hosea
Mike Hosea 2015년 11월 18일
Well, theoretically like this:
ss=0.6;
T=0.1;
a = 0.0001;
f2 = @(r,b,g) 1./(r.^2.*sqrt(1 - (b./r).^2 - (g^-2)*(2/15*(ss)^9)));
% The folloing function only works sith scalar b and g values.
X_scalar_b_scalar_g = @(b,g)real(pi - 2*b*integral(@(r)f2(r,b,g),a,10,'AbsTol',1e-3,'RelTol',1e-3));
% Make X work with array inputs for b and a scalar g value.
X_scalar_g = @(b,g)arrayfun(@(b)X_scalar_b_scalar_g(b,g),b);
f3 = @(b,g) 2*(1 - cos(X_scalar_g(b,g))).*b; % somente especular
qQd_scalar_g = @(g)integral(@(b)f3(b,g),0,10,'AbsTol',1e-3,'RelTol',1e-3);
% Make qQd_scalar_g work with array g inputs.
qQd = @(g)arrayfun(qQd_scalar_g,g);
f4 =@(g) g.^5.*qQd(g)./(exp(g.^2/T));
I_value = (1/T^3)*integral(f4,0,5,'AbsTol',1e-3,'RelTol',1e-3);
But your problem has a = 0, and in that case I get non-finite numbers. I had to loosen the tolerances to get it to complete. Seems to be a difficult problem, or at least a difficult formulation of the problem. If some work can be done symbolically, it might be worth looking into. I really didn't spend any time thinking about the problem itself, just formally made the definitions you provided work.
  댓글 수: 9
Mike Hosea
Mike Hosea 2015년 11월 28일
Yes, you can easily have something like that back, but that particular section of code never did what you say/think it did. FZERO finds exactly one root or it errors. It will never find more than one root at a time. To do that, you will need to call it iteratively and do something clever to give it starting intervals that bracket each root. But if you only need the largest one, perhaps a search followed by a call to FZERO could work, but searching for a bracket on the last sign change is not a sure thing.
Lucas Pollito
Lucas Pollito 2015년 12월 1일
@Mike, in my second integral, qQd(g), for values of b and g small, the integral has a oscilatory behaviour. Which is the best method to integrate it ? you can do a plot 3d in qQd, g and b to see that. May i use quadgk ? Levin or Filon Rule ??

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 MATLAB에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by