Function argument plug-in puzzle
Show older comments
I made a function intd(). Given all the arguments except x, I am supposed to plot the function intd() in terms of x. As is shown below, I use a function handle to turn intd() into univariate h().
Suppose (r,s,q,nu,al)=(5, 2, 0.2104, 60, 0.05).Then h() gives me the below error message at xx(58) when I attempt the sequence xx=[1:0.1:10] for x. However, when I plug in the value of xx(58), which is 6.7, for x in h(), it gets through and gives me a perfectly reasonable answer. I am puzzled at why it makes a difference in my function, using a value in a sequence or a straight number for the argument.
function prob=intd(x,r,s,q,nu,al)
a=q.*(1+q.^2).^(-1./2);
b=(1+q.^2).^(-1./2);
E=@(t) fcdf((r-s)./s.*(x.*(r.*t-x.^2).^(1/2)-
a.*b.*r.*t).^2./(a.^2.*r.*t-x.^2).^2,s,r-s).*fpdf(t,r,nu) ;
up=x.^2./(b.^2)./r;
down=x.^2./r;
prob=fcdf(x.^2./r,r,nu)+quadv(E,down,up)-1+al;
end
h=@(x) intd(x,r,s,q,nu,al);
xx=[1:0.1:10]; h(xx(58))
%%%%%%%%% Error Message %%%%%%%%%%%%%%
Error using betainc Inputs must be real, full, and double or single.
Error in fcdf (line 58) p(kk) = betainc(xx, v1(kk)/2, v2(kk)/2,'lower');
Error in intd>@(t)fcdf((r-s)./s.*(x.*(r.*t-x.^2).^(1/2)-a.*b.*r.*t).^2./(a.^2.*r.*t-x.^2).^2,s,r-s).*fpdf(t,r,nu) (line 4) E=@(t) fcdf((r-s)./s.*(x.*(r.*t-x.^2).^(1/2)-a.*b.*r.*t).^2./(a.^2.*r.*t-x.^2).^2,s,r-s).*fpdf(t,r,nu) ;
Error in quadv (line 61) y{j} = feval(f, x(j), varargin{:}); %#ok<AGROW>
Error in intd (line 7) prob=fcdf(x.^2./r,r,nu)+quadv(E,down,up)-1+al;
Error in @(x)intd(x,5,2,0.2104,60,0.05) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
>>xx(58)
ans =
6.7000
>> h(6.7)
ans =
0.0500
Answers (1)
the cyclist
on 9 Feb 2013
One thing to notice is that if you type
>> format long
you will see that xx(58) is actually equal to 6.699999999999999 and not 6.7. Furthermore, hh(6.699999999999999) causes an error, just like you are seeing.
So, what you are seeing is something of a numerical stability issue, caused by the floating point representation. (One needs to be very careful doing loops over real numbers.) See, for example, this thread on floating point representation: http://www.mathworks.com/matlabcentral/answers/69-why-does-1-2-3-1-3-not-equal-zero.
It looks like this particular case can be fixed if you use
>> xx = (1:100)/10
because then the 58th element will be 6.7.
I did not dig deeply into why such a tiny difference causes the error.
2 Comments
Amykelly
on 9 Feb 2013
the cyclist
on 9 Feb 2013
I think the fundamental issue is your function E(t) inside intd(). It looks like it is prone to numerical stability issue, due to the subtractions and ratios.
I don't really have a solution for you. One thing I can suggest is that if you type
>> dbstop if error
before running your code, then execution will automatically stop when it hits the error and you will go into debug mode. Then you can see what the values are of each of your variables, and maybe diagnose more specifically what is going wrong.
Type
>> dbclear if error
when you are done, to turn off that debugging feature.
Categories
Find more on Functions 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!