On Mon, 10 May 1999, Ted Juhl wrote:
> I am trying to maximize functions using BFGS. The functional form
> required has a very specific structrure:
>
> func(const vP, const adFunc, const avScore, const anHessian)
>
> where maximization takes place over vP. However, my functions depend on
> parameters which are fixed (so they can't be placed in vP), but I would
> like to maximize over thousands of values of these parameters (so
> I can't write a new function for each parameter case).
>
> Does anyone have any suggestions?
apparently the suggested method seems to be to place any data matrix as
global variables. so in your case, you would declare the fixed parameters
in a global vector/matrix and access them in the objective function. then
to maximize with a different set of fixed params, you overwrite the
values in the global vector.
i find this method of cluttering the global space unsatisfactory. (in
fact, java got rid of global variables.) i had a similar problem when i
wanted to implement Andrews' breakpoint test for GMM with an unknown
breakpoint. the Wald version of the test essentially requires doing GMM
for every possible breakpoints. therefore, my first attempt was to
overwrite the data in the global matrix for every breakpoint sample
(which does work). i am now convinced that the "correct" way to handle
this problem is to wrap the objective function by an interface class.
(another idea formalized in java.) you declare a class with a virtual
function that has the required form for the objective function. then for
each specific problem, you derive a class from this interface and add any
other data members necessary to implement/compute the objective function.
(for my problem, i will add a member function that resets the sample so
i don't have to overwrite the data matrix.) this sounds terribly
confusing, but an example will clarify.
//-------------------- interface example file --------------------
// Judge function with two critical points
// f(.864,1.23) = 16.0817 (global min) and f(2.35,-.319) = 20.9805
// 3/20/99 h.
#include <oxstd.h>
#include <oxfloat.h>
#import "maximize"
// interface class with pure virtual objective function
class ObjFunc
{
virtual objf(const param, const /*&*/fval, const /*&*/grad,
const /*&*/hess)/* = 0*/;
};
// derived class for specific problem
class JudgeObj : ObjFunc
{
objf(const param, const /*&*/fval, const /*&*/grad,
const /*&*/hess);
// constructor
JudgeObj();
/* data members (private) */
decl data; // y ~ x2 ~ x3
}
// constructor (set data member)
JudgeObj::JudgeObj()
{
// load data = y ~ x2 ~ x3
data = <
4.284, 0.286, 0.645;
4.149, 0.973, 0.585;
3.877, 0.384, 0.310;
0.533, 0.276, 0.058;
2.211, 0.973, 0.455;
2.389, 0.543, 0.779;
2.145, 0.957, 0.259;
3.231, 0.948, 0.202;
1.998, 0.543, 0.028;
1.379, 0.797, 0.099;
2.106, 0.936, 0.142;
1.428, 0.889, 0.296;
1.011, 0.006, 0.175;
2.179, 0.828, 0.180;
2.858, 0.399, 0.842;
1.388, 0.617, 0.039;
1.651, 0.939, 0.103;
1.593, 0.784, 0.620;
1.046, 0.072, 0.158;
2.152, 0.889, 0.704>;
}
// implement objective function
JudgeObj::objf(const x, const /*&*/fval, const /*&*/grad,
const /*&*/hess)
{
decl res = data[][0] - x[0] - x[1]*data[][1] -
x[1]*x[1]*data[][2];
fval[0] = -res'res;
return 1;
}
// main function
main()
{
decl x0 = <0.1; 0.1>; // starting values
decl maxf; // store maximized value
// instance objective function class
decl obj = new JudgeObj();
// call the BFGS routine with member objective function
decl msg = MaxBFGS(obj->objf, &x0, &maxf, 0, TRUE);
println(MaxConvergenceMsg(msg));
println("minimized objective function = ", double(-maxf));
println("params = ", x0');
delete obj; // delete object when done
}
--------------------------------------------------------------------
Time series regression studies give no sign of converging toward the
truth. (Phillip Cagan)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|