2012-06-11 44 views
0

我的应用库需要调用的优化例程:Ç回调数值优化功能

err = optim(int n, double *x, double *f, void *obj) 

然后,该例程将调用目标函数来请求目标函数值。

void obj(int n, double *x, double *f) 

optim()是外部库的一部分。 optim()和obj()的签名是固定的。

功能obj()需要访问包含在单个对象“模型”中的数据。所有其他函数都围绕指向模型对象的指针传递。因此,调用运行优化程序可能是这样:

err = doOptimize(model) 

doOptimize()将设置问题,并呼吁optim()

err= optim(model->n, model->x, model->f, model->obj) 

的问题是,可以在obj()函数访问的变量驻留在model除了n,xfobj()功能需要调用需要的model对象做实际的计算等功能:

updateParms(model); 
    computeF(model); 

我不知道怎么obj()可能使这些电话没有实际处理?以下工作可以吗?

updateParms(); 
    computeF();  

感谢,

+0

你说的是不是'N','x'和'F'成员的其他数据?你能提供一个更详细的代码示例,并指出你正在尝试做什么? –

回答

1

yes和no。

您的功能obj可以像其他任何内存一样访问模型,但我没有看到任何机制让它知道地址model

您需要将另一个参数添加到obj中,以便在其中传递model指针。

在C++中,您可能需要将obj设置为Class Model的“成员”。然后编译器会添加一个名为this的隐藏参数(它为所有成员函数执行),它将包含指向对象实例'model'的指针。如果你想在普通的C中获得相同的结果,那么你必须传递你自己的this指针(不过你可以随意调用它)。

所以,这样的事情:

... doOptimize (... model) 
{ 
    .... 
    optim (model->n, model->x, model->x, model) 
    .... 
} 

... optim (int n, double *x, double *f, ... model) 
{ 
    .... 
    model->obj (n, x, f, model); 
    .... 
} 

void obj (int n, double *x, double *f, ... model) 
{ 
    /* use n, x, and f */ 
    /* use model->stuff */ 
} 

当然,如果你总是使用相同nxf然后你只需要通过model

顺便说一句,不要使用void *函数指针:这不是一个好主意。

+0

您的解决方案描述的问题比我的描述更好。 optim()是外部库的一部分。 optim()和obj()的签名是固定的。我无法如所提出的那样提出问题的这一事实激发了这个问题。 – user151410

0

既然你不能修改的optim()obj()签名,您将需要创建执行您obj()功能实际通话的中间步骤。根据电话多少优化需要进行一次,这可能是作为一个全局/静态变量保存模型指针,例如简单:

void obj(struct model *m, int n, double *x, double *f) 
{ 
    /* Access to all information here */ 
} 

static struct model *optim_model; 

void obj_caller(int n, double *x, double *f) 
{ 
    obj(optim_model, n, x, f); 
} 

int doOptimize(struct model *m) 
{ 
    optim_model = m; 
    return optim(m->n, m->x, m->f, obj_caller); 
} 

或者,如果你需要更先进的或不喜欢有单一的全球性和有可能使用n个参数作为您可以使用它打出来才能够调用多个优化模型的标识符:

void obj(struct model *m, int n, double *x, double *f) 
{ 
    /* Access to all information here */ 
} 

#define MAX_MODELS (10) 
static struct model *optim_models[MAX_MODELS] = {0}; 

void obj_caller(int n, double *x, double *f) 
{ 
    for (int i = 0; i < MAX_MODELS; i++) 
    { 
     if (optim_models[i]->n == n) 
     { 
      obj(optim_models[i], n, x, f); 
      break; 
     } 
    } 
} 

int doOptimize(struct model *m) 
{ 
    return optim(m->n, m->x, m->f, obj_caller); 
} 

int main(void) 
{ 
    struct model m1; 
    struct model m2; 

    m1.n = 1; 
    optim_models[0] = &m1; 

    m2.n = 2; 
    optim_models[1] = &m1; 

    int err = doOptimize(&m2); 
} 

我敢肯定你承担责任:水灾找到存储多个车型更合适的方法如果你需要的话,比如带有真实标识符的链表。