Пример #1
0
returnValue BoundaryConstraint::evaluateSensitivities( const DMatrix &seed, BlockMatrix &hessian ){

    // EVALUATION OF THE SENSITIVITIES:
    // --------------------------------

    int run1, run2;

    const int nc = getNC();
    const int N  = grid.getNumPoints();

    ASSERT( (int) seed.getNumRows() == nc );

    double *bseed1 = new double[nc];
    double *bseed2 = new double[nc];
    double *R      = new double[nc];

    double *J1      = new double[fcn[0].getNumberOfVariables() +1];
    double *H1      = new double[fcn[0].getNumberOfVariables() +1];
    double *fseed1  = new double[fcn[0].getNumberOfVariables() +1];

    double *J2      = new double[fcn[1].getNumberOfVariables() +1];
    double *H2      = new double[fcn[1].getNumberOfVariables() +1];
    double *fseed2  = new double[fcn[1].getNumberOfVariables() +1];

    for( run1 = 0; run1 < nc; run1++ ){
        bseed1[run1] = seed(run1,0);
        bseed2[run1] = 0.0;
    }

    for( run1 = 0; run1 < fcn[0].getNumberOfVariables()+1; run1++ )
        fseed1[run1] = 0.0;

    for( run1 = 0; run1 < fcn[1].getNumberOfVariables()+1; run1++ )
        fseed2[run1] = 0.0;

    dBackward.init( 1, 5*N );

    DMatrix Dx ( nc, nx );
    DMatrix Dxa( nc, na );
    DMatrix Dp ( nc, np );
    DMatrix Du ( nc, nu );
    DMatrix Dw ( nc, nw );

    DMatrix Hx ( nx, nx );
    DMatrix Hxa( nx, na );
    DMatrix Hp ( nx, np );
    DMatrix Hu ( nx, nu );
    DMatrix Hw ( nx, nw );

    for( run2 = 0; run2 < nx; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed1[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed1, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dx( run1, run2 ) = R[run1];
        fseed1[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J1[run1] = 0.0;
            H1[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J1, H1 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2, run1             ) = -H1[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2, run1-nx          ) = -H1[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2, run1-nx-na       ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2, run1-nx-na-np    ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2, run1-nx-na-np-nu ) = -H1[y_index[0][run1]];
    }

    if( nx > 0 ){

        dBackward.setDense( 0, 0, Dx );

        if( nx > 0 ) hessian.addDense( 0,   0, Hx  );
        if( na > 0 ) hessian.addDense( 0,   N, Hxa );
        if( np > 0 ) hessian.addDense( 0, 2*N, Hp  );
        if( nu > 0 ) hessian.addDense( 0, 3*N, Hu  );
        if( nw > 0 ) hessian.addDense( 0, 4*N, Hw  );
    }

    Hx.init ( nx, nx );
    Hxa.init( nx, na );
    Hp.init ( nx, np );
    Hu.init ( nx, nu );
    Hw.init ( nx, nw );


    for( run2 = 0; run2 < nx; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed2[y_index[1][run2]] = 1.0;
        fcn[1].AD_forward( 0, fseed2, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dx( run1, run2 ) = R[run1];
        fseed2[y_index[1][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[1].getNumberOfVariables(); run1++ ){
            J2[run1] = 0.0;
            H2[run1] = 0.0;
        }

        fcn[1].AD_backward2( 0, bseed1, bseed2, J2, H2 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2, run1             ) = -H2[y_index[1][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2, run1-nx          ) = -H2[y_index[1][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2, run1-nx-na       ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2, run1-nx-na-np    ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2, run1-nx-na-np-nu ) = -H2[y_index[1][run1]];
    }

    if( nx > 0 ){

        dBackward.setDense( 0, N-1, Dx );

        if( nx > 0 ) hessian.addDense( N-1,   N-1, Hx  );
        if( na > 0 ) hessian.addDense( N-1, 2*N-1, Hxa );
        if( np > 0 ) hessian.addDense( N-1, 3*N-1, Hp  );
        if( nu > 0 ) hessian.addDense( N-1, 4*N-1, Hu  );
        if( nw > 0 ) hessian.addDense( N-1, 5*N-1, Hw  );
    }

    Hx.init ( na, nx );
    Hxa.init( na, na );
    Hp.init ( na, np );
    Hu.init ( na, nu );
    Hw.init ( na, nw );


    for( run2 = nx; run2 < nx+na; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed1[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed1, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dxa( run1, run2-nx ) = R[run1];
        fseed1[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J1[run1] = 0.0;
            H1[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J1, H1 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx, run1             ) = -H1[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx, run1-nx          ) = -H1[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx, run1-nx-na       ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx, run1-nx-na-np    ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx, run1-nx-na-np-nu ) = -H1[y_index[0][run1]];
    }

    if( na > 0 ){

        dBackward.setDense( 0, N, Dxa );

        if( nx > 0 ) hessian.addDense( N,   0, Hx  );
        if( na > 0 ) hessian.addDense( N,   N, Hxa );
        if( np > 0 ) hessian.addDense( N, 2*N, Hp  );
        if( nu > 0 ) hessian.addDense( N, 3*N, Hu  );
        if( nw > 0 ) hessian.addDense( N, 4*N, Hw  );
    }

    Hx.init ( na, nx );
    Hxa.init( na, na );
    Hp.init ( na, np );
    Hu.init ( na, nu );
    Hw.init ( na, nw );


    for( run2 = nx; run2 < nx+na; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed2[y_index[1][run2]] = 1.0;
        fcn[1].AD_forward( 0, fseed2, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dxa( run1, run2-nx ) = R[run1];
        fseed2[y_index[1][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[1].getNumberOfVariables(); run1++ ){
            J2[run1] = 0.0;
            H2[run1] = 0.0;
        }

        fcn[1].AD_backward2( 0, bseed1, bseed2, J2, H2 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx, run1             ) = -H2[y_index[1][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx, run1-nx          ) = -H2[y_index[1][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx, run1-nx-na       ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx, run1-nx-na-np    ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx, run1-nx-na-np-nu ) = -H2[y_index[1][run1]];
    }

    if( na > 0 ){

        dBackward.setDense( 0, 2*N-1, Dxa );

        if( nx > 0 ) hessian.addDense( 2*N-1,   N-1, Hx  );
        if( na > 0 ) hessian.addDense( 2*N-1, 2*N-1, Hxa );
        if( np > 0 ) hessian.addDense( 2*N-1, 3*N-1, Hp  );
        if( nu > 0 ) hessian.addDense( 2*N-1, 4*N-1, Hu  );
        if( nw > 0 ) hessian.addDense( 2*N-1, 5*N-1, Hw  );
    }

    Hx.init ( np, nx );
    Hxa.init( np, na );
    Hp.init ( np, np );
    Hu.init ( np, nu );
    Hw.init ( np, nw );


    for( run2 = nx+na; run2 < nx+na+np; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed1[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed1, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dp( run1, run2-nx-na ) = R[run1];
        fseed1[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J1[run1] = 0.0;
            H1[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J1, H1 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na, run1             ) = -H1[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na, run1-nx          ) = -H1[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na, run1-nx-na       ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na, run1-nx-na-np    ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na, run1-nx-na-np-nu ) = -H1[y_index[0][run1]];
    }

    if( np > 0 ){

        dBackward.setDense( 0, 2*N, Dp );

        if( nx > 0 ) hessian.addDense( 2*N,   0, Hx  );
        if( na > 0 ) hessian.addDense( 2*N,   N, Hxa );
        if( np > 0 ) hessian.addDense( 2*N, 2*N, Hp  );
        if( nu > 0 ) hessian.addDense( 2*N, 3*N, Hu  );
        if( nw > 0 ) hessian.addDense( 2*N, 4*N, Hw  );
    }


    Hx.init ( np, nx );
    Hxa.init( np, na );
    Hp.init ( np, np );
    Hu.init ( np, nu );
    Hw.init ( np, nw );


    for( run2 = nx+na; run2 < nx+na+np; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed2[y_index[1][run2]] = 1.0;
        fcn[1].AD_forward( 0, fseed2, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dp( run1, run2-nx-na ) = R[run1];
        fseed2[y_index[1][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[1].getNumberOfVariables(); run1++ ){
            J2[run1] = 0.0;
            H2[run1] = 0.0;
        }

        fcn[1].AD_backward2( 0, bseed1, bseed2, J2, H2 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na, run1             ) = -H2[y_index[1][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na, run1-nx          ) = -H2[y_index[1][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na, run1-nx-na       ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na, run1-nx-na-np    ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na, run1-nx-na-np-nu ) = -H2[y_index[1][run1]];
    }

    if( np > 0 ){

        dBackward.setDense( 0, 3*N-1, Dp );

        if( nx > 0 ) hessian.addDense( 3*N-1,   N-1, Hx  );
        if( na > 0 ) hessian.addDense( 3*N-1, 2*N-1, Hxa );
        if( np > 0 ) hessian.addDense( 3*N-1, 3*N-1, Hp  );
        if( nu > 0 ) hessian.addDense( 3*N-1, 4*N-1, Hu  );
        if( nw > 0 ) hessian.addDense( 3*N-1, 5*N-1, Hw  );
    }


    Hx.init ( nu, nx );
    Hxa.init( nu, na );
    Hp.init ( nu, np );
    Hu.init ( nu, nu );
    Hw.init ( nu, nw );


    for( run2 = nx+na+np; run2 < nx+na+np+nu; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed1[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed1, R );
        for( run1 = 0; run1 < nc; run1++ )
            Du( run1, run2-nx-na-np ) = R[run1];
        fseed1[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J1[run1] = 0.0;
            H1[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J1, H1 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na-np, run1             ) = -H1[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na-np, run1-nx          ) = -H1[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na-np, run1-nx-na       ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na-np, run1-nx-na-np    ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na-np, run1-nx-na-np-nu ) = -H1[y_index[0][run1]];
    }

    if( nu > 0 ){

        dBackward.setDense( 0, 3*N, Du );

        if( nx > 0 ) hessian.addDense( 3*N,   0, Hx  );
        if( na > 0 ) hessian.addDense( 3*N,   N, Hxa );
        if( np > 0 ) hessian.addDense( 3*N, 2*N, Hp  );
        if( nu > 0 ) hessian.addDense( 3*N, 3*N, Hu  );
        if( nw > 0 ) hessian.addDense( 3*N, 4*N, Hw  );
    }

    Hx.init ( nu, nx );
    Hxa.init( nu, na );
    Hp.init ( nu, np );
    Hu.init ( nu, nu );
    Hw.init ( nu, nw );


    for( run2 = nx+na+np; run2 < nx+na+np+nu; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed2[y_index[1][run2]] = 1.0;
        fcn[1].AD_forward( 0, fseed2, R );
        for( run1 = 0; run1 < nc; run1++ )
            Du( run1, run2-nx-na-np ) = R[run1];
        fseed2[y_index[1][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[1].getNumberOfVariables(); run1++ ){
            J2[run1] = 0.0;
            H2[run1] = 0.0;
        }

        fcn[1].AD_backward2( 0, bseed1, bseed2, J2, H2 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na-np, run1             ) = -H2[y_index[1][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na-np, run1-nx          ) = -H2[y_index[1][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na-np, run1-nx-na       ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na-np, run1-nx-na-np    ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na-np, run1-nx-na-np-nu ) = -H2[y_index[1][run1]];
    }

    if( nu > 0 ){

        dBackward.setDense( 0, 4*N-1, Du );

        if( nx > 0 ) hessian.addDense( 4*N-1,   N-1, Hx  );
        if( na > 0 ) hessian.addDense( 4*N-1, 2*N-1, Hxa );
        if( np > 0 ) hessian.addDense( 4*N-1, 3*N-1, Hp  );
        if( nu > 0 ) hessian.addDense( 4*N-1, 4*N-1, Hu  );
        if( nw > 0 ) hessian.addDense( 4*N-1, 5*N-1, Hw  );
    }

    Hx.init ( nw, nx );
    Hxa.init( nw, na );
    Hp.init ( nw, np );
    Hu.init ( nw, nu );
    Hw.init ( nw, nw );


    for( run2 = nx+na+np+nu; run2 < nx+na+np+nu+nw; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed1[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed1, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dw( run1, run2-nx-na-np-nu ) = R[run1];
        fseed1[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J1[run1] = 0.0;
            H1[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J1, H1 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na-np-nu, run1             ) = -H1[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na-np-nu, run1-nx          ) = -H1[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na-np-nu, run1-nx-na       ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na-np-nu, run1-nx-na-np    ) = -H1[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na-np-nu, run1-nx-na-np-nu ) = -H1[y_index[0][run1]];
    }

    if( nw > 0 ){

        dBackward.setDense( 0, 4*N, Dw );

        if( nx > 0 ) hessian.addDense( 4*N,   0, Hx  );
        if( na > 0 ) hessian.addDense( 4*N,   N, Hxa );
        if( np > 0 ) hessian.addDense( 4*N, 2*N, Hp  );
        if( nu > 0 ) hessian.addDense( 4*N, 3*N, Hu  );
        if( nw > 0 ) hessian.addDense( 4*N, 4*N, Hw  );
    }

    Hx.init ( nw, nx );
    Hxa.init( nw, na );
    Hp.init ( nw, np );
    Hu.init ( nw, nu );
    Hw.init ( nw, nw );


    for( run2 = nx+na+np+nu; run2 < nx+na+np+nu+nw; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed2[y_index[1][run2]] = 1.0;
        fcn[1].AD_forward( 0, fseed2, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dw( run1, run2-nx-na-np-nu ) = R[run1];
        fseed2[y_index[1][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[1].getNumberOfVariables(); run1++ ){
            J2[run1] = 0.0;
            H2[run1] = 0.0;
        }

        fcn[1].AD_backward2( 0, bseed1, bseed2, J2, H2 );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na-np-nu, run1             ) = -H2[y_index[1][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na-np-nu, run1-nx          ) = -H2[y_index[1][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na-np-nu, run1-nx-na       ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na-np-nu, run1-nx-na-np    ) = -H2[y_index[1][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na-np-nu, run1-nx-na-np-nu ) = -H2[y_index[1][run1]];
    }

    if( nw > 0 ){

        dBackward.setDense( 0, 5*N-1, Dw );

        if( nx > 0 ) hessian.addDense( 5*N-1,   N-1, Hx  );
        if( na > 0 ) hessian.addDense( 5*N-1, 2*N-1, Hxa );
        if( np > 0 ) hessian.addDense( 5*N-1, 3*N-1, Hp  );
        if( nu > 0 ) hessian.addDense( 5*N-1, 4*N-1, Hu  );
        if( nw > 0 ) hessian.addDense( 5*N-1, 5*N-1, Hw  );
    }

    delete[] bseed1;
    delete[] bseed2;
    delete[] R     ;
    delete[] J1    ;
    delete[] H1    ;
    delete[] fseed1;
    delete[] J2    ;
    delete[] H2    ;
    delete[] fseed2;

    return SUCCESSFUL_RETURN;
}
Пример #2
0
returnValue PointConstraint::evaluateSensitivities( const DMatrix &seed, BlockMatrix &hessian ){

    // EVALUATION OF THE SENSITIVITIES:
    // --------------------------------

    int run1, run2;

    if( fcn == 0 ) return ACADOERROR(RET_MEMBER_NOT_INITIALISED);

    const int nc = fcn[0].getDim();
    const int N  = grid.getNumPoints();

    ASSERT( (int) seed.getNumRows() == nc );

    double *bseed1 = new double[nc];
    double *bseed2 = new double[nc];
    double *R      = new double[nc];
    double *J      = new double[fcn[0].getNumberOfVariables() +1];
    double *H      = new double[fcn[0].getNumberOfVariables() +1];
    double *fseed  = new double[fcn[0].getNumberOfVariables() +1];

    for( run1 = 0; run1 < nc; run1++ ){
        bseed1[run1] = seed(run1,0);
        bseed2[run1] = 0.0;
    }

    for( run1 = 0; run1 < fcn[0].getNumberOfVariables()+1; run1++ )
        fseed[run1] = 0.0;

    dBackward.init( 1, 5*N );

    DMatrix Dx ( nc, nx );
    DMatrix Dxa( nc, na );
    DMatrix Dp ( nc, np );
    DMatrix Du ( nc, nu );
    DMatrix Dw ( nc, nw );

    DMatrix Hx ( nx, nx );
    DMatrix Hxa( nx, na );
    DMatrix Hp ( nx, np );
    DMatrix Hu ( nx, nu );
    DMatrix Hw ( nx, nw );

    for( run2 = 0; run2 < nx; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dx( run1, run2 ) = R[run1];
        fseed[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J[run1] = 0.0;
            H[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J, H );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2, run1             ) = -H[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2, run1-nx          ) = -H[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2, run1-nx-na       ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2, run1-nx-na-np    ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2, run1-nx-na-np-nu ) = -H[y_index[0][run1]];
    }

    if( nx > 0 ){

        dBackward.setDense( 0, point_index, Dx );

        if( nx > 0 ) hessian.addDense( point_index,       point_index, Hx  );
        if( na > 0 ) hessian.addDense( point_index,   N + point_index, Hxa );
        if( np > 0 ) hessian.addDense( point_index, 2*N + point_index, Hp  );
        if( nu > 0 ) hessian.addDense( point_index, 3*N + point_index, Hu  );
        if( nw > 0 ) hessian.addDense( point_index, 4*N + point_index, Hw  );
    }

    Hx.init ( na, nx );
    Hxa.init( na, na );
    Hp.init ( na, np );
    Hu.init ( na, nu );
    Hw.init ( na, nw );

    for( run2 = nx; run2 < nx+na; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dxa( run1, run2-nx ) = R[run1];
        fseed[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J[run1] = 0.0;
            H[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J, H );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx, run1             ) = -H[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx, run1-nx          ) = -H[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx, run1-nx-na       ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx, run1-nx-na-np    ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx, run1-nx-na-np-nu ) = -H[y_index[0][run1]];
    }

    if( na > 0 ){

        dBackward.setDense( 0, N+point_index, Dxa );

        if( nx > 0 ) hessian.addDense( N+point_index,       point_index, Hx  );
        if( na > 0 ) hessian.addDense( N+point_index,   N + point_index, Hxa );
        if( np > 0 ) hessian.addDense( N+point_index, 2*N + point_index, Hp  );
        if( nu > 0 ) hessian.addDense( N+point_index, 3*N + point_index, Hu  );
        if( nw > 0 ) hessian.addDense( N+point_index, 4*N + point_index, Hw  );
    }

    Hx.init ( np, nx );
    Hxa.init( np, na );
    Hp.init ( np, np );
    Hu.init ( np, nu );
    Hw.init ( np, nw );

    for( run2 = nx+na; run2 < nx+na+np; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dp( run1, run2-nx-na ) = R[run1];
        fseed[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J[run1] = 0.0;
            H[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J, H );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na, run1             ) = -H[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na, run1-nx          ) = -H[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na, run1-nx-na       ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na, run1-nx-na-np    ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na, run1-nx-na-np-nu ) = -H[y_index[0][run1]];
    }

    if( np > 0 ){

        dBackward.setDense( 0, 2*N+point_index, Dp );

        if( nx > 0 ) hessian.addDense( 2*N+point_index,       point_index, Hx  );
        if( na > 0 ) hessian.addDense( 2*N+point_index,   N + point_index, Hxa );
        if( np > 0 ) hessian.addDense( 2*N+point_index, 2*N + point_index, Hp  );
        if( nu > 0 ) hessian.addDense( 2*N+point_index, 3*N + point_index, Hu  );
        if( nw > 0 ) hessian.addDense( 2*N+point_index, 4*N + point_index, Hw  );
    }


    Hx.init ( nu, nx );
    Hxa.init( nu, na );
    Hp.init ( nu, np );
    Hu.init ( nu, nu );
    Hw.init ( nu, nw );

    for( run2 = nx+na+np; run2 < nx+na+np+nu; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed, R );
        for( run1 = 0; run1 < nc; run1++ )
            Du( run1, run2-nx-na-np ) = R[run1];
        fseed[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J[run1] = 0.0;
            H[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J, H );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na-np, run1             ) = -H[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na-np, run1-nx          ) = -H[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na-np, run1-nx-na       ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na-np, run1-nx-na-np    ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na-np, run1-nx-na-np-nu ) = -H[y_index[0][run1]];
    }

    if( nu > 0 ){

        dBackward.setDense( 0, 3*N+point_index, Du );

        if( nx > 0 ) hessian.addDense( 3*N+point_index,       point_index, Hx  );
        if( na > 0 ) hessian.addDense( 3*N+point_index,   N + point_index, Hxa );
        if( np > 0 ) hessian.addDense( 3*N+point_index, 2*N + point_index, Hp  );
        if( nu > 0 ) hessian.addDense( 3*N+point_index, 3*N + point_index, Hu  );
        if( nw > 0 ) hessian.addDense( 3*N+point_index, 4*N + point_index, Hw  );
    }

    Hx.init ( nw, nx );
    Hxa.init( nw, na );
    Hp.init ( nw, np );
    Hu.init ( nw, nu );
    Hw.init ( nw, nw );

    for( run2 = nx+na+np+nu; run2 < nx+na+np+nu+nw; run2++ ){

        // FIRST ORDER DERIVATIVES:
        // ------------------------
        fseed[y_index[0][run2]] = 1.0;
        fcn[0].AD_forward( 0, fseed, R );
        for( run1 = 0; run1 < nc; run1++ )
            Dw( run1, run2-nx-na-np-nu ) = R[run1];
        fseed[y_index[0][run2]] = 0.0;

        // SECOND ORDER DERIVATIVES:
        // -------------------------
        for( run1 = 0; run1 <= fcn[0].getNumberOfVariables(); run1++ ){
            J[run1] = 0.0;
            H[run1] = 0.0;
        }

        fcn[0].AD_backward2( 0, bseed1, bseed2, J, H );

        for( run1 = 0          ; run1 < nx            ; run1++ ) Hx ( run2-nx-na-np-nu, run1             ) = -H[y_index[0][run1]];
        for( run1 = nx         ; run1 < nx+na         ; run1++ ) Hxa( run2-nx-na-np-nu, run1-nx          ) = -H[y_index[0][run1]];
        for( run1 = nx+na      ; run1 < nx+na+np      ; run1++ ) Hp ( run2-nx-na-np-nu, run1-nx-na       ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np   ; run1 < nx+na+np+nu   ; run1++ ) Hu ( run2-nx-na-np-nu, run1-nx-na-np    ) = -H[y_index[0][run1]];
        for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ) Hw ( run2-nx-na-np-nu, run1-nx-na-np-nu ) = -H[y_index[0][run1]];
    }

    if( nw > 0 ){

        dBackward.setDense( 0, 4*N+point_index, Dw );

        if( nx > 0 ) hessian.addDense( 4*N+point_index,       point_index, Hx  );
        if( na > 0 ) hessian.addDense( 4*N+point_index,   N + point_index, Hxa );
        if( np > 0 ) hessian.addDense( 4*N+point_index, 2*N + point_index, Hp  );
        if( nu > 0 ) hessian.addDense( 4*N+point_index, 3*N + point_index, Hu  );
        if( nw > 0 ) hessian.addDense( 4*N+point_index, 4*N + point_index, Hw  );
    }

    delete[] bseed1;
    delete[] bseed2;
    delete[] R     ;
    delete[] J     ;
    delete[] H     ;
    delete[] fseed ;

    return SUCCESSFUL_RETURN;
}
Пример #3
0
returnValue MayerTerm::evaluateSensitivities( BlockMatrix *hessian ){

    int run1, run2;
    const int N = grid.getNumPoints();

    if( (bSeed != 0) & (hessian == 0) ){

        Matrix bseed_;
        bSeed->getSubBlock( 0, 0, bseed_);

        fcn.AD_backward( bseed_.getRow(0), JJ );

        dBackward.init( 1, 5*N );

        if( nx > 0 ) dBackward.setDense( 0,   N-1, Matrix( JJ.getX (), BT_TRUE ) );
        if( na > 0 ) dBackward.setDense( 0, 2*N-1, Matrix( JJ.getXA(), BT_TRUE ) );
        if( np > 0 ) dBackward.setDense( 0, 3*N-1, Matrix( JJ.getP (), BT_TRUE ) );
        if( nu > 0 ) dBackward.setDense( 0, 4*N-1, Matrix( JJ.getU (), BT_TRUE ) );
        if( nw > 0 ) dBackward.setDense( 0, 5*N-1, Matrix( JJ.getW (), BT_TRUE ) );

        return SUCCESSFUL_RETURN;
    }

    if( hessian != 0 ){

        double  bseed1 = 1.0;
        double  bseed2 = 0.0;
        double *J      = new double[fcn.getNumberOfVariables() +1];
        double *H      = new double[fcn.getNumberOfVariables() +1];
        double *fseed  = new double[fcn.getNumberOfVariables() +1];

        for( run1 = 0; run1 < fcn.getNumberOfVariables()+1; run1++ )
            fseed[run1] = 0.0;

        dBackward.init( 1, 5*N );

        Matrix Dx ( 1, nx );
        Matrix Dxa( 1, na );
        Matrix Dp ( 1, np );
        Matrix Du ( 1, nu );
        Matrix Dw ( 1, nw );

        Matrix Hx ( nx, nx );
        Matrix Hxa( nx, na );
        Matrix Hp ( nx, np );
        Matrix Hu ( nx, nu );
        Matrix Hw ( nx, nw );

        for( run2 = 0; run2 < nx; run2++ ){

            // FIRST ORDER DERIVATIVES:
            // ------------------------
            fseed[y_index[run2]] = 1.0;
            fcn.AD_forward( 0, fseed, J );
            Dx( 0, run2 ) = J[0];
            fseed[y_index[run2]] = 0.0;

            // SECOND ORDER DERIVATIVES:
            // -------------------------
            for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
                J[run1] = 0.0;
                H[run1] = 0.0;
            }

            fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );

            for( run1 = 0; run1 < nx; run1++ ){
                 Hx( run2, run1 ) = H[y_index[run1]];
            }
            for( run1 = nx; run1 < nx+na; run1++ ){
                 Hxa( run2, run1-nx ) = H[y_index[run1]];
            }
            for( run1 = nx+na; run1 < nx+na+np; run1++ ){
                 Hp( run2, run1-nx-na ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
                 Hu( run2, run1-nx-na-np ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
                 Hw( run2, run1-nx-na-np-nu ) = H[y_index[run1]];
            }
        }

        if( nx > 0 ){

            dBackward.setDense( 0, N-1, Dx );

            if( nx > 0 ) hessian->setDense( N-1,   N-1, Hx  );
            if( na > 0 ) hessian->setDense( N-1, 2*N-1, Hxa );
            if( np > 0 ) hessian->setDense( N-1, 3*N-1, Hp  );
            if( nu > 0 ) hessian->setDense( N-1, 4*N-1, Hu  );
            if( nw > 0 ) hessian->setDense( N-1, 5*N-1, Hw  );
        }

        Hx.init ( na, nx );
        Hxa.init( na, na );
        Hp.init ( na, np );
        Hu.init ( na, nu );
        Hw.init ( na, nw );

        for( run2 = nx; run2 < nx+na; run2++ ){

            // FIRST ORDER DERIVATIVES:
            // ------------------------
            fseed[y_index[run2]] = 1.0;
            fcn.AD_forward( 0, fseed, J );
            Dxa( 0, run2-nx ) = J[0];
            fseed[y_index[run2]] = 0.0;

            // SECOND ORDER DERIVATIVES:
            // -------------------------
            for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
                J[run1] = 0.0;
                H[run1] = 0.0;
            }

            fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );

            for( run1 = 0; run1 < nx; run1++ ){
                 Hx( run2-nx, run1 ) = H[y_index[run1]];
            }
            for( run1 = nx; run1 < nx+na; run1++ ){
                 Hxa( run2-nx, run1-nx ) = H[y_index[run1]];
            }
            for( run1 = nx+na; run1 < nx+na+np; run1++ ){
                 Hp( run2-nx, run1-nx-na ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
                 Hu( run2-nx, run1-nx-na-np ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
                 Hw( run2-nx, run1-nx-na-np-nu ) = H[y_index[run1]];
            }
        }

        if( na > 0 ){

            dBackward.setDense( 0, 2*N-1, Dxa );

            if( nx > 0 ) hessian->setDense( 2*N-1,   N-1, Hx  );
            if( na > 0 ) hessian->setDense( 2*N-1, 2*N-1, Hxa );
            if( np > 0 ) hessian->setDense( 2*N-1, 3*N-1, Hp  );
            if( nu > 0 ) hessian->setDense( 2*N-1, 4*N-1, Hu  );
            if( nw > 0 ) hessian->setDense( 2*N-1, 5*N-1, Hw  );
        }

        Hx.init ( np, nx );
        Hxa.init( np, na );
        Hp.init ( np, np );
        Hu.init ( np, nu );
        Hw.init ( np, nw );

        for( run2 = nx+na; run2 < nx+na+np; run2++ ){

            // FIRST ORDER DERIVATIVES:
            // ------------------------
            fseed[y_index[run2]] = 1.0;
            fcn.AD_forward( 0, fseed, J );
            Dp( 0, run2-nx-na ) = J[0];
            fseed[y_index[run2]] = 0.0;

            // SECOND ORDER DERIVATIVES:
            // -------------------------
            for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
                J[run1] = 0.0;
                H[run1] = 0.0;
            }

            fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );

            for( run1 = 0; run1 < nx; run1++ ){
                 Hx( run2-nx-na, run1 ) = H[y_index[run1]];
            }
            for( run1 = nx; run1 < nx+na; run1++ ){
                 Hxa( run2-nx-na, run1-nx ) = H[y_index[run1]];
            }
            for( run1 = nx+na; run1 < nx+na+np; run1++ ){
                 Hp( run2-nx-na, run1-nx-na ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
                 Hu( run2-nx-na, run1-nx-na-np ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
                 Hw( run2-nx-na, run1-nx-na-np-nu ) = H[y_index[run1]];
            }
        }

        if( np > 0 ){

            dBackward.setDense( 0, 3*N-1, Dp );

            if( nx > 0 ) hessian->setDense( 3*N-1,   N-1, Hx  );
            if( na > 0 ) hessian->setDense( 3*N-1, 2*N-1, Hxa );
            if( np > 0 ) hessian->setDense( 3*N-1, 3*N-1, Hp  );
            if( nu > 0 ) hessian->setDense( 3*N-1, 4*N-1, Hu  );
            if( nw > 0 ) hessian->setDense( 3*N-1, 5*N-1, Hw  );
        }


        Hx.init ( nu, nx );
        Hxa.init( nu, na );
        Hp.init ( nu, np );
        Hu.init ( nu, nu );
        Hw.init ( nu, nw );

        for( run2 = nx+na+np; run2 < nx+na+np+nu; run2++ ){

            // FIRST ORDER DERIVATIVES:
            // ------------------------
            fseed[y_index[run2]] = 1.0;
            fcn.AD_forward( 0, fseed, J );
            Du( 0, run2-nx-na-np ) = J[0];
            fseed[y_index[run2]] = 0.0;

            // SECOND ORDER DERIVATIVES:
            // -------------------------
            for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
                J[run1] = 0.0;
                H[run1] = 0.0;
            }

            fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );

            for( run1 = 0; run1 < nx; run1++ ){
                 Hx( run2-nx-na-np, run1 ) = H[y_index[run1]];
            }
            for( run1 = nx; run1 < nx+na; run1++ ){
                 Hxa( run2-nx-na-np, run1-nx ) = H[y_index[run1]];
            }
            for( run1 = nx+na; run1 < nx+na+np; run1++ ){
                 Hp( run2-nx-na-np, run1-nx-na ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
                 Hu( run2-nx-na-np, run1-nx-na-np ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
                 Hw( run2-nx-na-np, run1-nx-na-np-nu ) = H[y_index[run1]];
            }
        }

        if( nu > 0 ){

            dBackward.setDense( 0, 4*N-1, Du );

            if( nx > 0 ) hessian->setDense( 4*N-1,   N-1, Hx  );
            if( na > 0 ) hessian->setDense( 4*N-1, 2*N-1, Hxa );
            if( np > 0 ) hessian->setDense( 4*N-1, 3*N-1, Hp  );
            if( nu > 0 ) hessian->setDense( 4*N-1, 4*N-1, Hu  );
            if( nw > 0 ) hessian->setDense( 4*N-1, 5*N-1, Hw  );
        }


        Hx.init ( nw, nx );
        Hxa.init( nw, na );
        Hp.init ( nw, np );
        Hu.init ( nw, nu );
        Hw.init ( nw, nw );

        for( run2 = nx+na+np+nu; run2 < nx+na+np+nu+nw; run2++ ){

            // FIRST ORDER DERIVATIVES:
            // ------------------------
            fseed[y_index[run2]] = 1.0;
            fcn.AD_forward( 0, fseed, J );
            Dw( 0, run2-nx-na-np-nu ) = J[0];
            fseed[y_index[run2]] = 0.0;

            // SECOND ORDER DERIVATIVES:
            // -------------------------
            for( run1 = 0; run1 <= fcn.getNumberOfVariables(); run1++ ){
                J[run1] = 0.0;
                H[run1] = 0.0;
            }

            fcn.AD_backward2( 0, &bseed1, &bseed2, J, H );

            for( run1 = 0; run1 < nx; run1++ ){
                 Hx( run2-nx-na-np-nu, run1 ) = H[y_index[run1]];
            }
            for( run1 = nx; run1 < nx+na; run1++ ){
                 Hxa( run2-nx-na-np-nu, run1-nx ) = H[y_index[run1]];
            }
            for( run1 = nx+na; run1 < nx+na+np; run1++ ){
                 Hp( run2-nx-na-np-nu, run1-nx-na ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np; run1 < nx+na+np+nu; run1++ ){
                 Hu( run2-nx-na-np-nu, run1-nx-na-np ) = H[y_index[run1]];
            }
            for( run1 = nx+na+np+nu; run1 < nx+na+np+nu+nw; run1++ ){
                 Hw( run2-nx-na-np-nu, run1-nx-na-np-nu ) = H[y_index[run1]];
            }
        }

        if( nw > 0 ){

            dBackward.setDense( 0, 5*N-1, Dw );

            if( nx > 0 ) hessian->setDense( 5*N-1,   N-1, Hx  );
            if( na > 0 ) hessian->setDense( 5*N-1, 2*N-1, Hxa );
            if( np > 0 ) hessian->setDense( 5*N-1, 3*N-1, Hp  );
            if( nu > 0 ) hessian->setDense( 5*N-1, 4*N-1, Hu  );
            if( nw > 0 ) hessian->setDense( 5*N-1, 5*N-1, Hw  );
        }

        delete[] J;
        delete[] H;
        delete[] fseed;

        return SUCCESSFUL_RETURN;
    }

    return ACADOERROR(RET_NOT_IMPLEMENTED_YET);
}