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()、オブジェクトに存在する変数にアクセスできるかどうかです。関数は、実際の計算を行うためにオブジェクトを必要とする他の関数を呼び出す必要があります。modelnxfobj()model

    updateParms(model);
    computeF(model);

obj()実際のハンドルなしでこれらの呼び出しを行う方法がわかりませんか?次は動作しますか?

    updateParms();
    computeF();      

ありがとう、

4

2 に答える 2

1

はいといいえ。

もちろん、関数objは他のメモリと同じようにモデルにアクセスできますが、のアドレスを知るためのメカニズムはわかりませんmodel

ポインタobjを渡すための別のパラメータを追加する必要があります。model

objC ++では、おそらく。の「メンバー」を作成することでこれを行うでしょう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 */
}

もちろん、常に同じを使用するn場合はxfパスするだけで済みますmodel

ところで、void *関数ポインタには使用しないでください。これは良い考えではありません。

于 2012-06-11T15:57:35.697 に答える
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);
}

必要に応じて、実際の識別子を含むリンクリストなど、複数のモデルを格納するためのより適切な方法を見つけることができると確信しています。

于 2012-06-12T08:08:13.373 に答える