annotate main/optim/src/samin.cc @ 9930:d30cfca46e8a octave-forge

optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
author carandraug
date Fri, 30 Mar 2012 15:14:48 +0000
parents 5758bf7f1b2b
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
9930
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
1 // Copyright (C) 2004, 2006 Michael Creel <michael.creel@uab.es>
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
2 //
9930
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
3 // This program is free software; you can redistribute it and/or modify it under
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
4 // the terms of the GNU General Public License as published by the Free Software
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
5 // Foundation; either version 3 of the License, or (at your option) any later
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
6 // version.
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
7 //
9930
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
8 // This program is distributed in the hope that it will be useful, but WITHOUT
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
9 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
10 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
11 // details.
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
12 //
9930
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
13 // You should have received a copy of the GNU General Public License along with
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
14 // this program; if not, see <http://www.gnu.org/licenses/>.
d30cfca46e8a optim: upgrade license to GPLv3+ and mention on DESCRIPTION the other package licenses
carandraug
parents: 9674
diff changeset
15
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
16 // References:
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
17 //
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
18 // The code follows the article
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
19 // Goffe, William L. (1996) "SIMANN: A Global Optimization Algorithm
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
20 // using Simulated Annealing " Studies in Nonlinear Dynamics & Econometrics
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
21 // Oct96, Vol. 1 Issue 3.
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
22 //
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
23 // The code uses the same names for control variables,
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
24 // for the most part. A notable difference is that the initial
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
25 // temperature is found automatically to ensure that the active
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
26 // bounds when the temperature begins to reduce cover the entire
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
27 // parameter space (defined as a n-dimensional
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
28 // rectangle that is the Cartesian product of the
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
29 // (lb_i, ub_i), i = 1,2,..n
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
30 //
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
31 // Also of note:
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
32 // Corana et. al., (1987) "Minimizing Multimodal Functions of Continuous
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
33 // Variables with the "Simulated Annealing" Algorithm",
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
34 // ACM Transactions on Mathematical Software, V. 13, N. 3.
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
35 //
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
36 // Goffe, et. al. (1994) "Global Optimization of Statistical Functions
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
37 // with Simulated Annealing", Journal of Econometrics,
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
38 // V. 60, N. 1/2.
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
39
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
40 #include <oct.h>
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
41 #include <octave/parse.h>
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
42 #include <octave/Cell.h>
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
43 #include <octave/lo-mappers.h>
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
44 #include <octave/oct-rand.h>
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
45 #include <float.h>
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
46 #include "error.h"
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
47
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
48 // define argument checks
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
49 static bool any_bad_argument(const octave_value_list& args)
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
50 {
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
51
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
52 // objective function name is a string?
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
53 if (!args(0).is_string()) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
54 error("samin: first argument must be string holding objective function name");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
55 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
56 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
57
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
58 // are function arguments contained in a cell?
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
59 if (!args(1).is_cell()) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
60 error("samin: second argument must cell array of function arguments");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
61 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
62 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
63
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
64 // is control a cell?
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
65 Cell control (args(2).cell_value());
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
66 if (error_state) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
67 error("samin: third argument must cell array of algorithm controls");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
68 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
69 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
70
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
71 // does control have proper number of elements?
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
72 if (!(control.length() == 11)) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
73 error("samin: third argument must be a cell array with 11 elements");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
74 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
75 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
76
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
77 // now check type of each element of control
2636
d425be1bdc29 fix bug with scalar parameters
mcreel
parents: 2571
diff changeset
78 if (!(control(0).is_real_matrix()) && !(control(0).is_real_scalar())) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
79 error("samin: 1st element of controls must be LB: a vector of lower bounds");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
80 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
81 }
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
82
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
83 if ((control(0).is_real_matrix()) && (control(0).columns() != 1)) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
84 error("samin: 1st element of controls must be LB: a vector of lower bounds");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
85 return true;
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
86 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
87
2636
d425be1bdc29 fix bug with scalar parameters
mcreel
parents: 2571
diff changeset
88 if (!(control(1).is_real_matrix()) && !(control(1).is_real_scalar())) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
89 error("samin: 1st element of controls must be UB: a vector of lower bounds");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
90 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
91 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
92
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
93 if ((control(1).is_real_matrix()) && (control(1).columns() != 1)) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
94 error("samin: 2nd element of controls must be UB: a vector of lower bounds");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
95 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
96 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
97
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
98 int tmp = control(2).int_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
99 if (error_state || tmp < 1) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
100 error("samin: 3rd element of controls must be NT: positive integer\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
101 loops per temperature reduction");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
102 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
103 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
104
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
105 tmp = control(3).int_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
106 if (error_state || tmp < 1) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
107 error("samin: 4th element of controls must be NS: positive integer\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
108 loops per stepsize adjustment");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
109 return true;
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
110 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
111
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
112 double tmp2 = control(4).double_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
113 if (error_state || tmp < 0) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
114 error("samin: 5th element of controls must be RT:\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
115 temperature reduction factor, RT > 0");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
116 return true;
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
117 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
118
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
119 tmp2 = control(5).double_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
120 if (error_state || tmp < 0) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
121 error("samin: 6th element of controls must be integer MAXEVALS > 0 ");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
122 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
123 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
124
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
125 tmp = control(6).int_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
126 if (error_state || tmp < 0) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
127 error("samin: 7th element of controls must be NEPS: positive integer\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
128 number of final obj. values that must be within EPS of eachother ");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
129 return true;
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
130 }
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
131
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
132 tmp2 = control(7).double_value();if (error_state || tmp2 < 0) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
133 error("samin: 8th element of controls must must be FUNCTOL (> 0)\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
134 used to compare the last NEPS obj values for convergence test");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
135 return true;
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
136 }
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
137
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
138 tmp2 = control(8).double_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
139 if (error_state || tmp2 < 0) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
140 error("samin: 9th element of controls must must be PARAMTOL (> 0)\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
141 used to compare the last NEPS obj values for convergence test");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
142 return true;
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
143 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
144
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
145 tmp = control(9).int_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
146 if (error_state || tmp < 0 || tmp > 2) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
147 error("samin: 9th element of controls must be VERBOSITY (0, 1, or 2)");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
148 return true;
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
149 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
150
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
151 tmp = control(10).int_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
152 if (error_state || tmp < 0) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
153 error("samin: 10th element of controls must be MINARG (integer)\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
154 position of argument to minimize wrt");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
155 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
156 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
157
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
158 // make sure that minarg points to an existing element
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
159 if ((tmp > args(1).length())||(tmp < 1)) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
160 error("bfgsmin: 4th argument must be a positive integer that indicates \n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
161 which of the elements of the second argument is the one minimization is over");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
162 return true;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
163 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
164
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
165 return false;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
166 }
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
167
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
168 //-------------- The annealing algorithm --------------
2571
3f662c38802c remove use of celleval, use a more efficient direct call to feval
mcreel
parents: 2489
diff changeset
169 DEFUN_DLD(samin, args, , "samin: simulated annealing minimization of a function. See samin_example.m\n\
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
170 \n\
3311
5a1cc2386bad minor improvements to help string
mcreel
parents: 3268
diff changeset
171 usage: [x, obj, convergence, details] = samin(\"f\", {args}, {control})\n\
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
172 \n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
173 Arguments:\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
174 * \"f\": function name (string)\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
175 * {args}: a cell array that holds all arguments of the function,\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
176 * {control}: a cell array with 11 elements\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
177 * LB - vector of lower bounds\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
178 * UB - vector of upper bounds\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
179 * nt - integer: # of iterations between temperature reductions\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
180 * ns - integer: # of iterations between bounds adjustments\n\
3311
5a1cc2386bad minor improvements to help string
mcreel
parents: 3268
diff changeset
181 * rt - (0 < rt <1): temperature reduction factor\n\
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
182 * maxevals - integer: limit on function evaluations\n\
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
183 * neps - integer: number of values final result is compared to\n\
3311
5a1cc2386bad minor improvements to help string
mcreel
parents: 3268
diff changeset
184 * functol - (> 0): the required tolerance level for function value\n\
5a1cc2386bad minor improvements to help string
mcreel
parents: 3268
diff changeset
185 comparisons\n\
5a1cc2386bad minor improvements to help string
mcreel
parents: 3268
diff changeset
186 * paramtol - (> 0): the required tolerance level for parameters\n\
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
187 * verbosity - scalar: 0, 1, or 2.\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
188 * 0 = no screen output\n\
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
189 * 1 = only final results to screen\n\
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
190 * 2 = summary every temperature change\n\
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
191 * minarg - integer: which of function args is minimization over?\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
192 \n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
193 Returns:\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
194 * x: the minimizer\n\
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
195 * obj: the value of f() at x\n\
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
196 * convergence:\n\
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
197 0 if no convergence within maxevals function evaluations\n\
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
198 1 if normal convergence to a point interior to the parameter space\n\
3311
5a1cc2386bad minor improvements to help string
mcreel
parents: 3268
diff changeset
199 2 if convergence to point very near bounds of parameter space\n\
5a1cc2386bad minor improvements to help string
mcreel
parents: 3268
diff changeset
200 (suggest re-running with looser bounds)\n\
3313
c7b7e5adca46 further fixes to help string and comments
mcreel
parents: 3311
diff changeset
201 * details: a px3 matrix. p is the number of times improvements were found.\n\
c7b7e5adca46 further fixes to help string and comments
mcreel
parents: 3311
diff changeset
202 The columns record information at the time an improvement was found\n\
c7b7e5adca46 further fixes to help string and comments
mcreel
parents: 3311
diff changeset
203 * first: cumulative number of function evaluations\n\
c7b7e5adca46 further fixes to help string and comments
mcreel
parents: 3311
diff changeset
204 * second: temperature\n\
c7b7e5adca46 further fixes to help string and comments
mcreel
parents: 3311
diff changeset
205 * third: function value\n\
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
206 \n\
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
207 Example: see samin_example\n\
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
208 ")
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
209 {
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
210 int nargin = args.length();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
211 if (!(nargin == 3)) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
212 error("samin: you must supply 3 arguments");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
213 return octave_value_list();
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
214 }
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
215
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
216 // check the arguments
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
217 if (any_bad_argument(args)) return octave_value_list();
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
218
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
219 std::string obj_fn (args(0).string_value());
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
220 Cell f_args_cell = args(1).cell_value (); // args to obj fn come in as a cell to allow arbitrary number
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
221 Cell control (args(2).cell_value());
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
222
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
223 octave_value_list f_args;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
224 octave_value_list f_return; // holder for feval returns
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
225
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
226 int m, i, j, k, h, n, nacc, func_evals;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
227 int nup, nrej, nnew, ndown, lnobds;
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
228 int converge, test, coverage_ok;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
229
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
230 // user provided controls
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
231 const ColumnVector lb (control(0).column_vector_value());
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
232 const ColumnVector ub (control(1).column_vector_value());
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
233 const int nt (control(2).int_value());
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
234 const int ns (control(3).int_value());
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
235 const double rt (control(4).double_value());
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
236 const int maxevals (control(5).int_value());
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
237 const int neps (control(6).int_value());
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
238 const double functol (control(7).double_value());
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
239 const double paramtol (control(8).double_value());
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
240 const int verbosity (control(9).int_value());
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
241 const int minarg (control(10).int_value());
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
242
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
243 // type checking for minimization parameter done here, since we don't know minarg
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
244 // until now
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
245 if (!(f_args_cell(minarg - 1).is_real_matrix() || (f_args_cell(minarg - 1).is_real_scalar()))) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
246 error("samin: minimization must be with respect to a column vector");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
247 return octave_value_list();
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
248 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
249 if ((f_args_cell(minarg - 1).is_real_matrix()) && (f_args_cell(minarg - 1).columns() != 1)) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
250 error("samin: minimization must be with respect to a column vector");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
251 return octave_value_list();
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
252 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
253
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
254 double f, fp, p, pp, fopt, rand_draw, ratio, t;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
255
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
256 Matrix details(1,3); // record function evaluations, temperatures and function values
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
257 RowVector info(3);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
258
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
259 // copy cell contents over to octave_value_list to use feval()
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
260 k = f_args_cell.length();
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
261 f_args(k); // resize only once
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
262 for (i = 0; i<k; i++) f_args(i) = f_args_cell(i);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
263
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
264 ColumnVector x = f_args(minarg - 1).column_vector_value();
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
265 ColumnVector bounds = ub - lb;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
266 n = x.rows();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
267 ColumnVector xopt = x;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
268 ColumnVector xp(n);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
269 ColumnVector nacp(n);
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
270
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
271 // Set initial values
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
272 nacc = 0; // total accepted trials
6686
200d614223e2 minor bug fixes
mcreel
parents: 4404
diff changeset
273 t = 1000.0; // temperature - will initially rise or fall to cover parameter space. Then it will fall
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
274 converge = 0; // convergence indicator 0 (failure), 1 (normal success), or 2 (convergence but near bounds)
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
275 coverage_ok = 0; // has parameter space been covered? When turns to 1, temperature starts to fall
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
276 // most recent values, to compare to when checking convergend
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
277 ColumnVector fstar(neps,1);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
278 fstar.fill(DBL_MAX);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
279 octave_rand::distribution("uniform"); // we'll be using draws from U(0,1)
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
280
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
281 // check for out-of-bounds starting values
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
282 for(i = 0; i < n; i++) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
283 if(( x(i) > ub(i)) || (x(i) < lb(i))) {
6686
200d614223e2 minor bug fixes
mcreel
parents: 4404
diff changeset
284 error("samin: initial parameter %d out of bounds", i+1);
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
285 return octave_value_list();
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
286 }
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
287 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
288
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
289 // Initial obj_value
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
290 f_return = feval(obj_fn, f_args);
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
291 f = f_return(0).double_value();
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
292 fopt = f; // give it something to compare to
4002
c185f30e3157 Minor performance change - eliminate correlation between bounds hit and next trial
mcreel
parents: 3313
diff changeset
293 func_evals = 0; // total function evaluations (limited by maxeval)
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
294 details(0,0) = func_evals;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
295 details(0,1) = t;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
296 details(0,2) = fopt;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
297
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
298 // main loop, first increase temperature until parameter space covered, then reduce until convergence
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
299 while(converge==0)
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
300 {
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
301 // statistics to report at each temp change, set back to zero
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
302 nup = 0;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
303 nrej = 0;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
304 nnew = 0;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
305 ndown = 0;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
306 lnobds = 0;
2440
112afacbdc2c minor improvements
mcreel
parents: 2370
diff changeset
307
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
308 // repeat nt times then adjust temperature
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
309 for(m = 0;m < nt;m++) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
310 // repeat ns times, then adjust bounds
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
311 for(j = 0;j < ns;j++) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
312 // generate new point by taking last and adding a random value
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
313 // to each of elements, in turn
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
314 for(h = 0;h < n;h++) {
9674
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
315 // new Sept 2011, if bounds are same, skip the search for that vbl. Allows restrictions without complicated programming
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
316 if (lb(h) != ub(h)) {
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
317 xp = x;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
318 rand_draw = octave_rand::scalar();
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
319 xp(h) = x(h) + (2.0 * rand_draw - 1.0) * bounds(h);
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
320 if((xp(h) < lb(h)) || (xp(h) > ub(h))) {
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
321 rand_draw = octave_rand::scalar(); // change 07-Nov-2007: avoid correlation with hitting bounds
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
322 xp(h) = lb(h) + (ub(h) - lb(h)) * rand_draw;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
323 lnobds = lnobds + 1;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
324 }
9674
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
325 // Evaluate function at new point
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
326 f_args(minarg - 1) = xp;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
327 f_return = feval(obj_fn, f_args);
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
328 fp = f_return(0).double_value();
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
329 func_evals = func_evals + 1;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
330 // Accept the new point if the function value decreases
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
331 if(fp <= f) {
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
332 x = xp;
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
333 f = fp;
9674
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
334 nacc = nacc + 1; // total number of acceptances
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
335 nacp(h) = nacp(h) + 1; // acceptances for this parameter
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
336 nup = nup + 1;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
337 // If lower than any other point, record as new optimum
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
338 if(fp < fopt) {
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
339 xopt = xp;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
340 fopt = fp;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
341 nnew = nnew + 1;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
342 info(0) = func_evals;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
343 info(1) = t;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
344 info(2) = fp;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
345 details = details.stack(info);
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
346 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
347 }
9674
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
348 // If the point is higher, use the Metropolis criteria to decide on
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
349 // acceptance or rejection.
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
350 else {
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
351 p = exp(-(fp - f) / t);
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
352 rand_draw = octave_rand::scalar();
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
353 if(rand_draw < p) {
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
354 x = xp;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
355 f = fp;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
356 nacc = nacc + 1;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
357 nacp(h) = nacp(h) + 1;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
358 ndown = ndown + 1;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
359 }
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
360 else nrej = nrej + 1;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
361 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
362 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
363 // If maxevals exceeded, terminate the algorithm
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
364 if(func_evals >= maxevals) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
365 if(verbosity >= 1) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
366 printf("\n================================================\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
367 printf("SAMIN results\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
368 printf("NO CONVERGENCE: MAXEVALS exceeded\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
369 printf("================================================\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
370 printf("Convergence tolerances: Func. tol. %e Param. tol. %e\n", functol, paramtol);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
371 printf("Obj. fn. value %f\n\n", fopt);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
372 printf(" parameter search width\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
373 for(i = 0; i < n; i++) printf("%20f%20f\n", xopt(i), bounds(i));
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
374 }
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
375 f_return(3) = details;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
376 f_return(2) = 0;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
377 f_return(1) = fopt;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
378 f_return(0) = xopt;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
379 return octave_value_list(f_return);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
380 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
381 }
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
382 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
383 // Adjust bounds so that approximately half of all evaluations are accepted
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
384 test = 0;
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
385 for(i = 0;i < n;i++) {
9674
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
386 if (lb(i) != ub(i)) {
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
387 ratio = nacp(i) / ns;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
388 if(ratio > 0.6) bounds(i) = bounds(i) * (1.0 + 2.0 * (ratio - 0.6) / 0.4);
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
389 else if(ratio < .4) bounds(i) = bounds(i) / (1.0 + 2.0 * ((0.4 - ratio) / 0.4));
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
390 // keep within initial bounds
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
391 if(bounds(i) >= (ub(i) - lb(i))) {
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
392 bounds(i) = ub(i) - lb(i);
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
393 test = test + 1;
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
394 }
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
395 }
9674
5758bf7f1b2b add possibility to restrict a parameter to samin.cc
mcreel
parents: 6686
diff changeset
396 else test = test + 1; // make sure coverage check passes for the fixed parameters
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
397 }
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
398 nacp.fill(0.0);
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
399 // check if we cover parameter space. if we have yet to do so
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
400 if (!coverage_ok) coverage_ok = (test == n);
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
401 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
402 // intermediate output, if desired
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
403 if(verbosity == 2) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
404 printf("\nsamin: intermediate results before next temperature change\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
405 printf("\ntemperature %e", t);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
406 printf("\ncurrent best function value %f", fopt);
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
407 printf("\ntotal evaluations so far %d", func_evals);
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
408 printf("\ntotal moves since last temperature reduction %d", nup + ndown + nrej);
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
409 printf("\ndownhill %d", nup);
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
410 printf("\naccepted uphill %d", ndown);
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
411 printf("\nrejected uphill %d", nrej);
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
412 printf("\nout of bounds trials %d", lnobds);
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
413 printf("\nnew minima this temperature %d", nnew);
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
414 printf("\n\n parameter search width\n");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
415 for(i = 0; i < n; i++) printf("%20f%20f\n", xopt(i), bounds(i));
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
416 printf("\n");
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
417 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
418 // Check for convergence, if we have covered the parameter space
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
419 if (coverage_ok) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
420 // last value close enough to last neps values?
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
421 fstar(0) = f;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
422 test = 0;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
423 for (i = 1; i < neps; i++) test = test + fabs(f - fstar(i)) > functol;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
424 test = (test > 0); // if different from zero, function conv. has failed
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
425 // last value close enough to overall best?
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
426 if (((fopt - f) <= functol) && (!test)) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
427 // check for bound narrow enough for parameter convergence
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
428 for (i = 0;i < n;i++) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
429 if (bounds(i) > paramtol) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
430 converge = 0; // no conv. if bounds too wide
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
431 break;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
432 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
433 else converge = 1;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
434 }
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
435 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
436 // check if optimal point is near boundary of parameter space, and change convergence message if so
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
437 if (converge) if (lnobds > 0) converge = 2;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
438 // Like to see the final results?
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
439 if (converge > 0) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
440 if (verbosity >= 1) {
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
441 printf("\n================================================\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
442 printf("SAMIN results\n\n");
4002
c185f30e3157 Minor performance change - eliminate correlation between bounds hit and next trial
mcreel
parents: 3313
diff changeset
443 if (converge == 1) printf("==> Normal convergence <==\n\n");
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
444 if (converge == 2)
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
445 {
4002
c185f30e3157 Minor performance change - eliminate correlation between bounds hit and next trial
mcreel
parents: 3313
diff changeset
446 printf("==> WARNING <==: Last point satisfies convergence criteria,\n");
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
447 printf("but is near boundary of parameter space.\n");
6686
200d614223e2 minor bug fixes
mcreel
parents: 4404
diff changeset
448 printf("%d out of %d evaluations were out-of-bounds in the last round.\n", lnobds, (nup+ndown+nrej));
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
449 printf("Expand bounds and re-run, unless this is a constrained minimization.\n\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
450 }
4002
c185f30e3157 Minor performance change - eliminate correlation between bounds hit and next trial
mcreel
parents: 3313
diff changeset
451 printf("Convergence tolerances:\nFunction: %e\nParameters: %e\n", functol, paramtol);
c185f30e3157 Minor performance change - eliminate correlation between bounds hit and next trial
mcreel
parents: 3313
diff changeset
452 printf("\nObjective function value at minimum: %f\n\n", fopt);
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
453 printf(" parameter search width\n");
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
454 for(i = 0; i < n; i++) printf("%20f%20f\n", xopt(i), bounds(i));
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
455 printf("================================================\n");
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
456 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
457 f_return(3) = details;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
458 f_return(2) = converge;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
459 f_return(1) = fopt;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
460 f_return(0) = xopt;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
461 return f_return; // this breaks out, if we get here
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
462 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
463 // Reduce temperature, record current function value in the
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
464 // list of last "neps" values, and loop again
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
465 t = rt * t;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
466 for(i = neps-1; i > 0; i--) fstar(i) = fstar(i-1);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
467 f = fopt;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
468 x = xopt;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
469 }
2489
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
470 else { // coverage not ok - increase temperature quickly to expand search area, to cover parameter space
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
471 t = t*t;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
472 for(i = neps-1; i > 0; i--) fstar(i) = fstar(i-1);
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
473 f = fopt;
dbb5601affd1 simplified temperature search, direct use of feval rather than though celleval
mcreel
parents: 2440
diff changeset
474 x = xopt;
2370
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
475 }
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
476 }
24d6a5cdedfe Changed the directory structure to match the package system
hauberg
parents:
diff changeset
477 }