What is the best way set the search interval used by fminbnd?
3 views (last 30 days)
Show older comments
I am using fminbnd to find the minimum of a function in which the independent variable is a probability. Therefore, I thought I could use 0 and 1 as the bounds of the search interval. However, this approach is unrelaible and I have had to "cheat" by setting the search interval to something that more tightly bounds the known correct answers for my test cases. Thus, I have not built confidence in my ability to use fminbnd to find correct answers that I don't already know.
Have I missed the guidance for setting the search interval?
2 Comments
Accepted Answer
Matt J
on 16 May 2022
Edited: Matt J
on 16 May 2022
Your minimization problem is really a root-finding problem in disguise. It is better to use fzero for such things. As you can see below, we get good results over a wider search interval:
n = 1000; % Number of trials. Use 1000.
S = 1; % Number of errors. Use 1, 10, & 100.
beta = 0.95; % Confidence coefficient.
epsilon = 1-beta;
epsilon_half = epsilon/2;
% p1 SECTION - Lower end of confidence interval.
firstindex = S;
lastindex = n;
x_vector = firstindex:lastindex;
x_vector = x_vector';
f = @(p)sumbinopdf_equals_epsilon_half_2(p,x_vector,n,epsilon_half);
[p1,fval,exitflag]=fzero(f,[0,1])
% p2 SECTION - Upper end of confidence interval.
firstindex = 0;
lastindex = S;
x_vector = firstindex:lastindex;
x_vector = x_vector';
f = @(p)sumbinopdf_equals_epsilon_half_2(p,x_vector,n,epsilon_half);
[p2,fval,exitflag]=fzero(f,[0,1])
function [the_difference] = sumbinopdf_equals_epsilon_half_2(p,x_vec,n,epsilon_half)
% Sums the binomial pdf, binopdf(x,n,p) over x_vec and compare the sum to epsilon/2.
% Intent: Use this function to search for a value of p that satisfies
% sum(binopdf(x_vec,n_vec,p_vec)) = epsilon/2
% in the context of finding confidence limits p1 & p2 as decribed in
% Section 14.54 of Burington & May, Handbook of Probability and Statistics
% with Tables, 1958.
% Formulate the difference between sum(binopdf(x_vec,n_vec,p_vec)) &
% epsilon_half so the desired result is that this function equals zero.
%
% Inputs
% x_vec: vector, a range of number of successes.
% n: scalar, number of trials.
% p: scalar, p=Pr[success] - script varies this in calls to this function.
% epsilon_half: scalar = 0.5*(1-beta); beta is the confidence coefficient
%
% Output
% the_difference: absolute value of the difference between the desired sum of probabilities and epsilon_half.
%
n_vec = n.*ones(size(x_vec));
p_vec = p.*ones(size(x_vec));
the_difference = sum(binopdf(x_vec,n_vec,p_vec))-epsilon_half;
end
More Answers (1)
Matt J
on 16 May 2022
Edited: Matt J
on 16 May 2022
and I have had to "cheat" by setting the search interval to something that more tightly bounds the known correct answers for my test cases.
In cases where you don't know the solution, you can sweep the interval to find a tighter subinterval, like in the following:
xsamples=linspace(0,1,10);
fsamples = arrayfun(fun, xsamples);
[~,im]=min(fsamples);
a=xsamples( max( 1,im-1) );
b=xsamples( min(10,im+1) );
x=fminbnd(fun, a,b)
1 Comment
Matt J
on 16 May 2022
Applying this to your problem seems to do alright:
n = 1000; % Number of trials. Use 1000.
S = 1; % Number of errors. Use 1, 10, & 100.
beta = 0.95; % Confidence coefficient.
epsilon = 1-beta;
epsilon_half = epsilon/2;
% p1 SECTION - Lower end of confidence interval.
firstindex = S;
lastindex = n;
x_vector = firstindex:lastindex;
x_vector = x_vector';
f = @(p)sumbinopdf_equals_epsilon_half_2(p,x_vector,n,epsilon_half);
[p1,fval,exitflag] = searchRoot(f,30)
firstindex = 0;
lastindex = S;
x_vector = firstindex:lastindex;
x_vector = x_vector';
f = @(p)sumbinopdf_equals_epsilon_half_2(p,x_vector,n,epsilon_half);
[p2,fval,exitflag] = searchRoot(f,30)
function varargout = searchRoot(fun,N)
xsamples=linspace(0,1,N);
fsamples = arrayfun(fun, xsamples);
[~,im]=min(fsamples);
a=xsamples( max( 1,im-1) );
b=xsamples( min(N,im+1) );
[varargout{1:nargout}]=fminbnd(fun, a,b,...
optimset('TolX',1e-12,'MaxIter',1e20,'MaxFunEvals',1e20));
end
function [the_difference] = sumbinopdf_equals_epsilon_half_2(p,x_vec,n,epsilon_half)
n_vec = n.*ones(size(x_vec));
p_vec = p.*ones(size(x_vec));
the_difference = abs(sum(binopdf(x_vec,n_vec,p_vec))-epsilon_half);
end
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!