Mercurial > forge
changeset 9674:5758bf7f1b2b octave-forge
add possibility to restrict a parameter to samin.cc
author | mcreel |
---|---|
date | Tue, 13 Mar 2012 13:53:53 +0000 |
parents | ae49c70a62f8 |
children | 248af5ad631f |
files | main/optim/src/samin.cc |
diffstat | 1 files changed, 54 insertions(+), 48 deletions(-) [+] |
line wrap: on
line diff
--- a/main/optim/src/samin.cc Tue Mar 13 13:53:22 2012 +0000 +++ b/main/optim/src/samin.cc Tue Mar 13 13:53:53 2012 +0000 @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -// simann.cc (c) 2004 Michael Creel <michael.creel@uab.es> +// // References: // // The code follows the article @@ -313,50 +313,53 @@ // generate new point by taking last and adding a random value // to each of elements, in turn for(h = 0;h < n;h++) { - xp = x; - rand_draw = octave_rand::scalar(); - xp(h) = x(h) + (2.0 * rand_draw - 1.0) * bounds(h); - if((xp(h) < lb(h)) || (xp(h) > ub(h))) { - rand_draw = octave_rand::scalar(); // change 07-Nov-2007: avoid correlation with hitting bounds - xp(h) = lb(h) + (ub(h) - lb(h)) * rand_draw; - lnobds = lnobds + 1; - } - // Evaluate function at new point - f_args(minarg - 1) = xp; - f_return = feval(obj_fn, f_args); - fp = f_return(0).double_value(); - func_evals = func_evals + 1; - // Accept the new point if the function value decreases - if(fp <= f) { - x = xp; - f = fp; - nacc = nacc + 1; // total number of acceptances - nacp(h) = nacp(h) + 1; // acceptances for this parameter - nup = nup + 1; - // If lower than any other point, record as new optimum - if(fp < fopt) { - xopt = xp; - fopt = fp; - nnew = nnew + 1; - info(0) = func_evals; - info(1) = t; - info(2) = fp; - details = details.stack(info); + // new Sept 2011, if bounds are same, skip the search for that vbl. Allows restrictions without complicated programming + if (lb(h) != ub(h)) { + xp = x; + rand_draw = octave_rand::scalar(); + xp(h) = x(h) + (2.0 * rand_draw - 1.0) * bounds(h); + if((xp(h) < lb(h)) || (xp(h) > ub(h))) { + rand_draw = octave_rand::scalar(); // change 07-Nov-2007: avoid correlation with hitting bounds + xp(h) = lb(h) + (ub(h) - lb(h)) * rand_draw; + lnobds = lnobds + 1; } - } - // If the point is higher, use the Metropolis criteria to decide on - // acceptance or rejection. - else { - p = exp(-(fp - f) / t); - rand_draw = octave_rand::scalar(); - if(rand_draw < p) { + // Evaluate function at new point + f_args(minarg - 1) = xp; + f_return = feval(obj_fn, f_args); + fp = f_return(0).double_value(); + func_evals = func_evals + 1; + // Accept the new point if the function value decreases + if(fp <= f) { x = xp; f = fp; - nacc = nacc + 1; - nacp(h) = nacp(h) + 1; - ndown = ndown + 1; + nacc = nacc + 1; // total number of acceptances + nacp(h) = nacp(h) + 1; // acceptances for this parameter + nup = nup + 1; + // If lower than any other point, record as new optimum + if(fp < fopt) { + xopt = xp; + fopt = fp; + nnew = nnew + 1; + info(0) = func_evals; + info(1) = t; + info(2) = fp; + details = details.stack(info); + } } - else nrej = nrej + 1; + // If the point is higher, use the Metropolis criteria to decide on + // acceptance or rejection. + else { + p = exp(-(fp - f) / t); + rand_draw = octave_rand::scalar(); + if(rand_draw < p) { + x = xp; + f = fp; + nacc = nacc + 1; + nacp(h) = nacp(h) + 1; + ndown = ndown + 1; + } + else nrej = nrej + 1; + } } // If maxevals exceeded, terminate the algorithm if(func_evals >= maxevals) { @@ -381,14 +384,17 @@ // Adjust bounds so that approximately half of all evaluations are accepted test = 0; for(i = 0;i < n;i++) { - ratio = nacp(i) / ns; - if(ratio > 0.6) bounds(i) = bounds(i) * (1.0 + 2.0 * (ratio - 0.6) / 0.4); - else if(ratio < .4) bounds(i) = bounds(i) / (1.0 + 2.0 * ((0.4 - ratio) / 0.4)); - // keep within initial bounds - if(bounds(i) > (ub(i) - lb(i))) { - bounds(i) = ub(i) - lb(i); - test = test + 1; + if (lb(i) != ub(i)) { + ratio = nacp(i) / ns; + if(ratio > 0.6) bounds(i) = bounds(i) * (1.0 + 2.0 * (ratio - 0.6) / 0.4); + else if(ratio < .4) bounds(i) = bounds(i) / (1.0 + 2.0 * ((0.4 - ratio) / 0.4)); + // keep within initial bounds + if(bounds(i) >= (ub(i) - lb(i))) { + bounds(i) = ub(i) - lb(i); + test = test + 1; + } } + else test = test + 1; // make sure coverage check passes for the fixed parameters } nacp.fill(0.0); // check if we cover parameter space. if we have yet to do so