Hi guys,
i have a problem with NLopt SLSQP in C,
my compiler throws out a exception after 2 iterations of optimization in my 
object function, at my computation of gradient, it said:

Exception thrown: write access violation.
grad was nullptr.


the problem is , i used the same code on matlab , it works fine, but the 
results of cost function under the initialized value between matlab and c are 
not the same, the gradient as well,
the difference is about 1e-5, and the difference between gradient are huge, 
could that caused my exception?

i noticed that the difference from xAll(solution of A*x + B*u = x_dot, it is my 
state equation) started at 200th row(xAll should be 2500x5), and the difference 
is about 1e-12 to 1e-15
did anyone know why?

attached is my c-code , could anyone help me

#pragma warning (disable : 4146)





// nlopt-Bibliothek
#include"nlopt.h"// nlopt Header-Datei


//c-Standard-Bibliothek
#include <stdio.h>
#include <stdlib.h>
#include<math.h>
#include <string.h>
#include<malloc.h>

//selbst geschriebene Bibliothek
#include "light_matrix.h" //Bibliothek für Matrixberechnung
#include"linspace.h"//wie linspace in MATLAB
#include"one_D_Array.h" //generieren dynamische Speicherplatz für 1 
dimensionale Matrix
#include"two_D_Array.h"//generieren dynamische Speicherplatz für 2 
dimensionale Matrix
#include"KostenFunktion_linear.h"//berechnen den Wert der Kostenfunktion
#include"Berechnungsmodell.h"
#include"struct.h" //Deklaration der Parameter[







double ObjFunc(unsigned n, const double *OptVec, double *grad, void *data)
{
        



        tag*para = (tag*)data;

        // Messwerte der zu identifizierenden Parametern
        // messdaten of the identified parameter
        printf("\ntrue vector is %f %f %f\n", para->trueOptVec[0], 
para->trueOptVec[1], para->trueOptVec[2]);


        //Kontinuierliche Zeit-Vektor
        // time vektor
        double *p_contTimeVec = NULL;
        p_contTimeVec = one_D_Array(p_contTimeVec, para->NT);
        linspace(para->t_start, para->t_end, para->NT, p_contTimeVec);




        //berechnen die Lösung des Zustandsmodeles A*X+B*u = x_dot mit 
Messwerte der zu identifizierenden Parametern
        //solution of the A*x +B*u =x_dot
        double **xAll; // 2500 X 5
        xAll = Berechnungsmodell( para->trueOptVec, para,\
        p_contTimeVec, 0);

        //die 2.te und 3.te Spalte der oberen Matrix(xAll), damit rechnet man 
den Wert der Kostenfunktion
        // the second and third column from xAll, with them to compute the 
gradient
        Mat phiDotMMeas_init;
        Mat *phiDotMMeas;
        phiDotMMeas = &phiDotMMeas_init;
        MatCreate(phiDotMMeas, para->NT, 1);

        Mat phiAMeas_init;
        Mat *phiAMeas;
        phiAMeas = &phiAMeas_init;
        MatCreate(phiAMeas, para->NT, 1);

        for (int i = 0; i < para->NT; i++) {
                phiDotMMeas->element[i][0] = xAll[i][1];
                phiAMeas->element[i][0] = xAll[i][2];
        }


        //Pointer xAll freigeben
        //Point release
        for (int i = 0; i < para->NT; i++) {
                free(xAll[i]);
        }
        free(xAll);
        xAll = NULL;



        
//Gradient berechnen
// compute the gradient
   /*wie die Syntax in MATLAB: optFun = @(initOptVec) 
KostenFunktion_linear(para, initOptVec, model_input_fun, time, \
   phiDotMMeas, phiAMeas);*/


        // die Werte der Kostenfunktion je nach Methode-FiniteDifferenzes
        // values of cost function according to finte difference
        double myfunc, myfunc_g1, myfunc_g11, myfunc_g2, myfunc_g22 
,myfunc_g3,myfunc_g33;
                
        //pass = 0 , OptVec ist der zu identifzierende Parameter-Vektor
        myfunc = KostenFunktion_linear( OptVec, p_contTimeVec, phiDotMMeas, \
                phiAMeas,  0,para);


        //pass = 1,Vektor x ist {x[0]+h,x[1],x[2]}
        myfunc_g1 = KostenFunktion_linear( OptVec, p_contTimeVec, phiDotMMeas, \
                phiAMeas,  1, para);
        //pass = 11,Vektor x ist {x[0]-h,x[1],x[2]}
        myfunc_g11 = KostenFunktion_linear( OptVec, p_contTimeVec, phiDotMMeas, 
\
                phiAMeas,  11, para);

        //pass = 2,Vektor x ist {x[0],x[1]+h,x[2]}
        myfunc_g2 = KostenFunktion_linear( OptVec, p_contTimeVec, phiDotMMeas, \
                phiAMeas,  2, para);
        //pass = 22,Vektor x ist {x[0],x[1]-h,x[2]}
        myfunc_g22 = KostenFunktion_linear(  OptVec, p_contTimeVec, 
phiDotMMeas, \
                phiAMeas,   22, para);

        //pass = 3,Vektor x ist {x[0],x[1],x[2]+h}
        myfunc_g3 = KostenFunktion_linear(  OptVec, p_contTimeVec, phiDotMMeas, 
\
                phiAMeas,  3, para);
        //pass = 33,Vektor x ist {x[0],x[1],x[2]-h}
        myfunc_g33 = KostenFunktion_linear( OptVec, p_contTimeVec, phiDotMMeas, 
\
                phiAMeas, 33, para);

        



        //Gradient berechnen je nach Methode-FiniteDifferenzes
        //gradient compute

        grad[0] = (myfunc_g1 - myfunc_g11)/(2.0*para->h);//after 2 iterations 
of optimization : Exception thrown: write access violation:grad was nullptr.
        
        grad[1] = (myfunc_g2 - myfunc_g22)/(2.0*para->h);

        grad[2] = (myfunc_g3 - myfunc_g33)/(2.0*para->h);


        printf("\n myfunc is %.10f", myfunc);
        printf("\n myfunc_g1 is %.10f myfunc_g2 is %.10f myfunc_g3 is %.10f 
\n", myfunc_g1, myfunc_g2, myfunc_g3);
        printf("\n myfunc_g11 is %.10f myfunc_g22 is %.10f myfunc_g33 is %.10f 
\n", myfunc_g11, myfunc_g22, myfunc_g33);
        printf("\nmyfunc_g1- myfunc_g11 is %.10f,myfunc_g2- myfunc_g22 is 
%.10f,,myfunc_g3- myfunc_g33 is %.10f,\n", myfunc_g1 - myfunc_g11, myfunc_g2 - 
myfunc_g22, myfunc_g3 - myfunc_g33);
        printf("\nx[0] is %f OptVec[1] is %f OptVec[2] is %f\n", OptVec[0], 
OptVec[1], OptVec[2]);
        printf("\ngrad[0] is %f grad[1] is %f grad[2] is %f\n", grad[0], 
grad[1], grad[2]);
        


        MatDelete(phiDotMMeas);
        MatDelete(phiAMeas);



        free(p_contTimeVec);
        p_contTimeVec = NULL;







        return myfunc;







        
}
        


int main() {

//Parameter zuweisen
//parameter assignment
        tag*para;
        tag paraa;
        para = &paraa;

        para->NT = 2500;
        para->NX = 5;
                

        //physikalisches Modell
        para->P1 = 2.0;
        para->I1 = 32.0;
        para->P2 = 4096.0;
        para->u = 203.52;
        para->R = 764.0;
        para->c = 8938100.0 ;
        para->J_MR = 1.18/100.0 + 27.3/10000.0;
        para->J_AG = 1562.0;
        para->maxTorque = 16.9;
        para->J_AG_min = 361.0;
        para->cG_min = 89381.0;
        para->R_min = 7.64;


        // dabei werden A und B durch 10 dividiert, damit kann der Programm mit 
wenigen Iterationen die Parameter idntifizieren(in MATLAB)
        para->val_B[0] = 0.0;
        para->val_B[1] = (para->P1 *  para->P2 / para->J_MR)/10.0;
        para->val_B[2] = 0.0;
        para->val_B[3] = 0.0;
        para->val_B[4] = 1/10.0;
        


        para->val_A[0] = 0.0;
        para->val_A[1] = 1/10.0;
        para->val_A[2] = 0.0;
        para->val_A[3] = 0.0;
        para->val_A[4] = 0.0;
        para->val_A[5] = (-para->c / (para->J_MR*pow(para->u, 2)) - para->I1 / 
para->J_MR) / 10.0;
        para->val_A[6] = (-para->P1 / para->J_MR) / 10.0;
        para->val_A[7] = (para->c / (para->J_MR*para->u) - para->P1 * para->P2 
/ para->J_MR) / 10.0;
        para->val_A[8] = 0.0;
        para->val_A[9] = (para->I1*para->P2 / para->J_MR) / 10.0;
        para->val_A[10] = 0.0;
        para->val_A[11] = 0.0;
        para->val_A[12] = 0;
        para->val_A[13] = 1/10.0;
        para->val_A[14] = 0.0;
        para->val_A[15] = (para->c / (para->u*para->J_AG)) / 10.0;
        para->val_A[16] = 0.0; 
        para->val_A[17] = ((-para->c) / para->J_AG) / 10.0;
        para->val_A[18] = ((-para->R) / para->J_AG)/10.0; 
        para->val_A[19] = 0.0;
        para->val_A[20] = 0.0;
        para->val_A[21] = 0.0;
        para->val_A[22] = -1/10.0;
        para->val_A[23] = 0.0;
        para->val_A[24] = 0.0;
        
        //trueOptVec
        para->trueOptVec[0] = 1562.0;
        para->trueOptVec[1] = 8938100.0;
        para->trueOptVec[2] = 764.0;

        //Zeit
        para->t_start = 0;
        para->dt_init = 0.001;
        para->t_end = (para->NT - 1) * para->dt_init;


        //Schrittweite der Methode-FiniteDifferenzes
        para->h = 1e-07;





        

        
        




        double OptVec[3] = {.0};
        double initOptVec[3];
        //double ww = rand() % 1 + (double)(rand() % 1000) / 1000.0;
        //double xx = rand() % 1 + (double)(rand() % 1000) / 1000.0;
        //double hh = rand() % 1 + (double)(rand() % 1000) / 1000.0;
        //double random_OptVec[3] = { 0 };
        //random_OptVec[0] = ww;
        //random_OptVec[1] = xx;
        //random_OptVec[2] = hh;
        ////initiale Werte der zu identifizierenden Parameter, dieselbe Werte 
in MATLAB, um den Pragramm zu vergleichen
        //for (int i = 0; i < 3; i++) {
        //      initOptVec[i] = para->trueOptVec[i] * (1 + 2 * 
(random_OptVec[i] - 0.5));
        //}

        initOptVec[0] = 0.000443252921871 *pow(10, 6);
        initOptVec[1] = 7.539489040483818 *pow(10, 6);
        initOptVec[2] = 0.001399243882489 *pow(10, 6);

        for (int i = 0; i < 3; i++) {

                OptVec[i] = initOptVec[i];
                printf("initial OptVec is \n");
                printf("  %f", OptVec[i]);
                printf("\n");
                
        }
        double f_min = 0;//-10000000;
        double tol = 1e-11;
        double J_AG_min = 361.0;
        double cG_min = 89381.0;
        double R_min = 7.64;
        double lb[] = { J_AG_min, cG_min, R_min };
        double ub[] = { 1e+5, 1e+10, 1e+5 };


        nlopt_opt opter = nlopt_create(NLOPT_LD_SLSQP, 3);      
        nlopt_set_min_objective(opter, ObjFunc, para);
        
        nlopt_set_lower_bounds(opter, lb);
        nlopt_set_upper_bounds(opter, ub);
        nlopt_set_xtol_rel(opter, tol);
        nlopt_set_ftol_abs(opter, tol);


        nlopt_set_maxeval(opter,50);

        nlopt_result result = nlopt_optimize(opter, OptVec, &f_min);
        printf("Maximum utility=%f, OptVec=(%f,%f,%f)\n", f_min, OptVec[0], 
OptVec[1],OptVec[2]);
        nlopt_destroy(opter);

        system("pause");
}






//test-code, kleiner Test für NLopt-SLSQP

//double myfunc(unsigned n, const double *x,double *grad,void *data) {
//      
//      double h = 1e-8;
//
//      grad[0] = (log(x[0] + h) - log(x[0])) / h; 
//      grad[1] = (log(x[1] + h) - log(x[1])) / h;
//
//      //grad[0] = 1.0 / x[0];
//      //grad[1] = 1.0 / x[1];
//      //printf("\ngrad_a[0] is %10f grad_a[1] is %10f\n", grad_a[0], 
grad_a[1]);
//      printf("\ngrad[0] is %10f grad[1] is %10f\n", grad[0], grad[1]);
//      printf("\nx[0] is %10f x[1] is %10f\n",x[0],x[1]);
//      
//      
//      return log(x[0]) + log(x[1]);
//}
//
//double myconstraint(unsigned n, const double *x, double *grad, void*data) {
//      double *a = (double *)data; 
//      grad[0] = a[0];
//      grad[1] = a[1];
//      return x[0] * a[0] + x[1] * a[1] - 5; //NLopt always expects 
constraints to be of the form myconstraint(x) ≤ 0
//}
//
//double myinconstraint(unsigned n, const double *x, double *grad, void *data) {
//
//      grad[0] = 1;
//      grad[1] = -1;
//      return x[0] - x[1];
//}
//
//      int main(){
//
//
//      double f_max = 10000;
//      double tol = 1e-6;
//      double p[2] = { 1,2 };
//      double x[2] = { 1,1 };
//      double lb[2] = { 0.001,0.001 };
//      double ub[2] = { 10000,10000 }; 
//      // nlopt_opt local_opt : member from struct, opter 
//      nlopt_opt opter = nlopt_create(NLOPT_LD_SLSQP, 2);      //Optimizer 
definieren,2 Diemensionen; struct: nlopt_opt_s , struct variable: nlopt_opt
//      nlopt_set_max_objective(opter, myfunc, NULL);// opter steht fuer 
algorithmus
//      
//      nlopt_set_lower_bounds(opter, lb);
//      nlopt_set_upper_bounds(opter, ub);
//      nlopt_add_equality_constraint(opter, myconstraint, p, tol);// p 
parameters 
//      nlopt_add_inequality_constraint(opter, myinconstraint, NULL, tol); //  
Null  no raletive parameter 
//      nlopt_set_xtol_rel(opter, tol);
//      nlopt_set_ftol_abs(opter, tol);
//      nlopt_set_force_stop(opter, tol);
//      
//
//      nlopt_result result = nlopt_optimize(opter, x, &f_max);//?
//
//      if (result)
//              printf("Maximum utility=%f, x=(%f,%f)\n", f_max, x[0], x[1]);
//      // free
//      nlopt_destroy(opter);
//      return 0;
//}



_______________________________________________
NLopt-discuss mailing list
NLopt-discuss@ab-initio.mit.edu
http://ab-initio.mit.edu/cgi-bin/mailman/listinfo/nlopt-discuss

Reply via email to