On 9/9/06, Paul Kienzle <address@hidden> wrote:
On Sep 9, 2006, at 2:32 AM, address@hidden wrote:
> I agree that the potential effect of a change in the way the random
> number is generated is limited here, what I meant by overhead. But if
> feval is very costly, it could be having a big effect, since it is
> used by "celleval" every time the objective function is evaluated. If
> there is some way to call an objective function, the name of which is
> not known a priori to samin or bfgsmin, avoiding feval, I'm very
> interested to know about it. That could give a dramatic speedup.
I implemented this in python. The same thing will work in any
scripting language. You need to do the following steps:
1. Define an cobjective type in the scripting language. This
takes a pointer to a C objective function (prototype below),
a pointer to user data and a pointer to the function to clean
up the user data when objective function is deleted.
typedef double (*optfn)(int n, const double p[], void *data);
2. For convenience the cobjective type should be callable directly
from the scripting language, so the following wrapper will
be needed:
scriptfn cobjective(args, returns)
a. process input arguments for p and objective function fn
b. convert p into double p[] and length n
c. if fn is a cobjective wrapper extract cfn and data from fn
otherwise signal an error
d. call cfn(n,p,data), returning the result as a script double
In octave, this wrapper would be attached to the do_multi_index
method of the cobjective type.
3. Define a minimizer that accepts a C function.
double minimizer(int n, double p[], optfn fn, void *data)
The minimizer needs to check periodically for user interrupt.
This could be done in a variety of ways. The minimizer may
also need to provide an opportunity for the script language
event loop to run in the case of a single threaded GUI.
4. Define a c function which can call back into the scripting
language. This is useful if the user passes a scripted
objective function rather than one implemented in C.
double scriptcall(int n, const double p[], void *data);
a. convert n,p into a vector v in the scripting language
b. cast data into function type fn in the scripting language
c. call fn with v using feval in the scripting language
d. if the script function raised an exception return inf
otherwise convert the script return value into a c double
and return it
5. Define a wrapper for the minimizer so it can be called from the
scripting language:
scriptfn minimize(args, returns)
a. process input arguments for initial value p0 and function fn
b. convert p0 into double p[] and length n
c. if fn is a cobjective type extract cfn and data from fn
otherwise set cfn to scriptcall and data to fn
d. call minimizer(n, p, fn, data)
6. Define a cobjective factory for each C function. The constructor
can take parameters to initialize the associated data:
typedef struct {
associated user data
} mycfn_data;
double mycfn_implementation(int n, const double p[], void *data)
{
mycfn_data *d = (mycfn_data *)data;
double result;
evaluate objective function mycfn(p;d)
return result;
}
void mycfn_cleanup(void *data)
{
free resources associated with data
}
scriptfn mycfn(args, returns)
a. parse args for attributes of mycfn_data
b. allocate and assign mycfn_data
c. create and return a new instance of the cobjective type
- Paul
I'm going to need to think about this for a while. I think what you propose looks like the way to go, but it's a big challenge to my C programming ability. If you happen to have some time, please look at
bfgsmin.cc and bfgsmin.m in o-f CVS. I'd be glad to get any help you can offer. Based upon the speedup from getting rid of some fevals in samin.cc, I think that removing all the fevals to evaluate the objective function should make a big difference. I'll also study some other minimizers written in C, probably starting with those in the Open Optimization Library. Thanks, Michael