How to avoid NaN with numerical integration (quadrature)

4 views (last 30 days)
Hi, I have written a program that I divided in several functions.
"*puzzle*" is the main function. But my question is related to a problem I have with quadv(Look in "*LnpdFut*" function).
s_ is a parameter of "*pdFut*" that I passed as a global to "*Lnpdfut*" function, the argument of integration being v.
In the loop in "*LnpdFut*", s_ takes successively values of the vector sglob_, but for the first two values of sglob_, it doesn't work. I get NaN.
Could someone help me figure out the reason? I know it's long but just run it, you can see for yourself.
function puzzle
global lnpdc_ sglob_ gamma_ g_ G_ rf_ phi_ sigmav_ sigmaw_ rho_ Sbar_ sbar_ smax_ delta_ LimInf_ LimSup_ ndivs_
gamma_= 2;
g_= 0.0174;
G_= exp(g_);
rf_ = 0.023;
phi_= 0.9016;
sigmav_= 0.01186;
sigmaw_= 0.465;
rho_= 0.3;
Sbar_= sigmav_*(gamma_/(1-phi_))^(0.5);
sbar_= log(Sbar_);
smax_= sbar_ + (1-Sbar_^2)/2;
delta_ = 1/exp(rf_)*G_^(gamma_)*exp(-gamma_*(1-phi_)/2);
ndivs_ = 15;
LimInf_ = -3*sigmav_;
LimSup_ = 3*sigmav_;
%Main function puzzle body
sglob_ = Setgrid(smax_,sbar_,ndivs_); % Grille
fprintf('sglob_ est %d x %d\n', size(sglob_,1),size(sglob_,2));
lnpdc_ = zeros(length(sglob_),1);
pdcInt = Lnpdfut(sglob_); % intègre numériquement
fprintf('pdcInt:%d x %d\n',size(pdcInt,1),size(pdcInt,2));
disp(pdcInt);
%==================================================================
function k = Lnpdfut(sg)
%Calls Futpd (below) and uses quadv
global s_ nwpdc_
nwpdc_ = zeros(length(lnpdc_),1);
j=1;
while(j<=length(lnpdc_))
s_= sg(j);
nwpdc_(j)= quadv(@Futpd,LimInf_,LimSup_); %integration sur v
j=j+1;
end
k = nwpdc_;
end
%------------------------------------------------------------------
function pdFut = Futpd(v)
%calls Transit belows
global s_
pdFut = delta_*G_^(1-gamma_).*exp(-gamma_*(Transit(s_,v)-s_.*ones(length(Transit(s_,v)),1))).*...
exp((1-gamma_)*v).*(1 + exp(interp1q(sglob_,lnpdc_,Transit(s_,v)))).*pdf('norm',v,0,sigmav_);
end
%------------------------------------------------------------------
function Futstate = Transit(s,v)
%Calls Lam below
Futstate =(1-phi_)*sbar_ + phi_.*s + Lam(s).*v;
if max(Futstate >=smax_)==1,
Futstate = (Futstate<smax_).*Futstate + (Futstate>=smax_).*smax_;
end
end
%------------------------------------------------------------------
function lambda = Lam(s)
express= 1-2*(s-sbar_);
express =(express>=0).*express;
express= express.^(0.5);
express= (1./Sbar_).*express-1;
express= (s<=smax_).*express;
lambda = express;
end
%------------------------------------------------------------------
function s_etat = Setgrid(smx,sb,nd)
s_etat = 0:exp(smx)/nd:exp(smx); %donne (ndivs+1) points
s_etat = log(s_etat(2:end));
if max(smx==s_etat)== 0,
s_etat = horzcat(s_etat,smx);
end
if max(sb==s_etat)== 0,
s_etat = horzcat(s_etat,sb);
end
s_etat = sort(s_etat);
s_etat = s_etat';
end
end
  2 Comments
Matt Fig
Matt Fig on 10 May 2011
I would try it, except you forgot to use the {} Code button when pasting your code so that it looks like a mess. You can go back and edit the question so that the rest of us can simply past it into MATLAB.
Ismael
Ismael on 11 May 2011
It's done. Thanks for pointing this to me.
I'm looking forward to your suggestion(s)

Sign in to comment.

Accepted Answer

Andrew Newell
Andrew Newell on 11 May 2011
If you set a debugging breakpoint at the call where the warning occurs, then
Futpd(LimInf_)
ans =
NaN
EDIT: The NaN occurs in this expression with v=LimInf_:
interp1q(sglob_,lnpdc_,Transit(s_,v))
The problem is that you are trying to extrapolate data for x between about -5 and -2 to x=-223, and interp1q doesn't like that. If you are always extrapolating, you could try
interp1(sglob_,lnpdc_,Transit(s_,v),'linear','extrap')
This would work for this case, where lnpdc_ is zero for all values of x, but in general extrapolation is dangerous.
Programming note: Don't use global variables.

More Answers (1)

bym
bym on 11 May 2011
I have no idea, but don't you have to declare the global variables in each subfunction? So for
Lnpdfut(sg)
you would also have to declare
LimInf_,LimSup_
  1 Comment
Ismael
Ismael on 11 May 2011
Thank you!!! Your answer inspired me. I looked closely at interp in matlab help and I found an alternative solution to extrapolate using ppval(). I needed this for my thesis.
Thank you!!!

Sign in to comment.

Categories

Find more on Matrix Computations in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!