fptr F77_FUNC(ipcreate,IPCREATE)
(fint* N,
 fdouble* X_L,
 fdouble* X_U,
 fint* M,
 fdouble* G_L,
 fdouble* G_U,
 fint* NELE_JAC,
 fint* NELE_HESS,
 fint* IDX_STY,
 FEval_F_CB EVAL_F,
 FEval_G_CB EVAL_G,
 FEval_Grad_F_CB EVAL_GRAD_F,
 FEval_Jac_G_CB EVAL_JAC_G,
 FEval_Hess_CB EVAL_HESS)
{
  Index n = *N;
  Index m = *M;
  Index nele_jac = *NELE_JAC;
  Index nele_hess = *NELE_HESS;
  Index index_style = *IDX_STY;

  FUserData* fuser_data;

  fuser_data = (FUserData*) malloc(sizeof(FUserData));

  /* First create a new IpoptProblem object; if that fails return 0 */
  fuser_data->Problem =
    CreateIpoptProblem(n, X_L, X_U, m, G_L, G_U, nele_jac, nele_hess, 
		       index_style, eval_f, eval_g, eval_grad_f, 
		       eval_jac_g, eval_h);
  if (fuser_data->Problem == NULL) {
    free(fuser_data);
    return (fptr)NULL;
  }

  /* Store the information for the callback function */
  fuser_data->EVAL_F = EVAL_F;
  fuser_data->EVAL_G = EVAL_G;
  fuser_data->EVAL_GRAD_F = EVAL_GRAD_F;
  fuser_data->EVAL_JAC_G = EVAL_JAC_G;
  fuser_data->EVAL_HESS = EVAL_HESS;
  fuser_data->INTERMEDIATE_CB = NULL;

  return (fptr)fuser_data;
}
Example #2
0
/*!
 *  run optimization with ipopt
 *  author: Vitalij Ruge
 **/
static inline void optimizationWithIpopt(OptData*optData) {
    IpoptProblem nlp = NULL;

    const int NV = optData->dim.NV;
    const int NRes = optData->dim.NRes;
    const int nsi = optData->dim.nsi;
    const int np = optData->dim.np;
    const int nx = optData->dim.nx;
    const int NJ = optData->dim.nJderx;
    const int NJf = optData->dim.nJfderx;
    const int nH0 = optData->dim.nH0_;
    const int nH1 = optData->dim.nH1_;
    const int njac = np*(NJ*nsi + nx*(np*nsi - 1)) + NJf;
    const int nhess = (nsi*np-1)*nH0+nH1;

    Number * Vmin = optData->bounds.Vmin;
    Number * Vmax = optData->bounds.Vmax;
    Number * gmin = optData->ipop.gmin;
    Number * gmax = optData->ipop.gmax;
    Number * vopt = optData->ipop.vopt;
    Number * mult_g = optData->ipop.mult_g;
    Number * mult_x_L = optData->ipop.mult_x_L;
    Number * mult_x_U = optData->ipop.mult_x_U;
    Number obj;

    char *cflags;
    int max_iter = 5000;
    int res = 0;

    nlp = CreateIpoptProblem(NV, Vmin, Vmax,
                             NRes, gmin, gmax, njac, nhess, 0, &evalfF,
                             &evalfG, &evalfDiffF, &evalfDiffG, &ipopt_h);

    /********************************************************************/
    /*******************       ipopt flags       ************************/
    /********************************************************************/

    /*tol */
    AddIpoptNumOption(nlp, "tol", optData->data->simulationInfo.tolerance);
    AddIpoptStrOption(nlp, "evaluate_orig_obj_at_resto_trial", "yes");

    /* print level */
    if(ACTIVE_STREAM(LOG_IPOPT_FULL)) {
        AddIpoptIntOption(nlp, "print_level", 7);
    } else if(ACTIVE_STREAM(LOG_IPOPT)) {
        AddIpoptIntOption(nlp, "print_level", 5);
    } else if(ACTIVE_STREAM(LOG_STATS)) {
        AddIpoptIntOption(nlp, "print_level", 3);
    } else {
        AddIpoptIntOption(nlp, "print_level", 2);
    }
    AddIpoptIntOption(nlp, "file_print_level", 0);

    /* derivative_test */
    if(ACTIVE_STREAM(LOG_IPOPT_JAC) && ACTIVE_STREAM(LOG_IPOPT_HESSE)) {
        AddIpoptIntOption(nlp, "print_level", 4);
        AddIpoptStrOption(nlp, "derivative_test", "second-order");
    } else if(ACTIVE_STREAM(LOG_IPOPT_JAC)) {
        AddIpoptIntOption(nlp, "print_level", 4);
        AddIpoptStrOption(nlp, "derivative_test", "first-order");
    } else if(ACTIVE_STREAM(LOG_IPOPT_HESSE)) {
        AddIpoptIntOption(nlp, "print_level", 4);
        AddIpoptStrOption(nlp, "derivative_test", "only-second-order");
    } else {
        AddIpoptStrOption(nlp, "derivative_test", "none");
    }


    cflags = (char*)omc_flagValue[FLAG_IPOPT_HESSE];
    if(cflags) {
        if(!strcmp(cflags,"BFGS"))
            AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory");
        else if(!strcmp(cflags,"const") || !strcmp(cflags,"CONST"))
            AddIpoptStrOption(nlp, "hessian_constant", "yes");
        else if(!(!strcmp(cflags,"num") || !strcmp(cflags,"NUM")))
            warningStreamPrint(LOG_STDOUT, 0, "not support ipopt_hesse=%s",cflags);
    }

    /*linear_solver e.g. mumps, MA27, MA57,...
     * be sure HSL solver are installed if your try HSL solver*/
    cflags = (char*)omc_flagValue[FLAG_LS_IPOPT];
    if(cflags)
        AddIpoptStrOption(nlp, "linear_solver", cflags);
    AddIpoptNumOption(nlp,"mumps_pivtolmax",1e-5);


    /* max iter */
    cflags = (char*)omc_flagValue[FLAG_IPOPT_MAX_ITER];
    if(cflags) {
        char buffer[100];
        char c;
        int index_e = -1, i = 0;
        strcpy(buffer,cflags);

        while(buffer[i] != '\0') {
            if(buffer[i] == 'e') {
                index_e = i;
                break;
            }
            ++i;
        }

        if(index_e < 0) {
            max_iter = atoi(cflags);
            if(max_iter >= 0)
                AddIpoptIntOption(nlp, "max_iter", max_iter);
            printf("\nmax_iter = %i",atoi(cflags));

        } else {
            max_iter =  (atoi(cflags)*pow(10.0, (double)atoi(cflags+index_e+1)));
            if(max_iter >= 0)
                AddIpoptIntOption(nlp, "max_iter", (int)max_iter);
            printf("\nmax_iter = (int) %i | (double) %g",(int)max_iter, atoi(cflags)*pow(10.0, (double)atoi(cflags+index_e+1)));
        }
    } else
        AddIpoptIntOption(nlp, "max_iter", 5000);

    /*heuristic optition */
    {
        int ws = 0;
        cflags = (char*)omc_flagValue[FLAG_IPOPT_WARM_START];
        if(cflags) {
            ws = atoi(cflags);
        }

        if(ws > 0) {
            double shift = pow(10,-1.0*ws);
            AddIpoptNumOption(nlp,"mu_init",shift);
            AddIpoptNumOption(nlp,"bound_mult_init_val",shift);
            AddIpoptStrOption(nlp,"mu_strategy", "monotone");
            AddIpoptNumOption(nlp,"bound_push", 1e-5);
            AddIpoptNumOption(nlp,"bound_frac", 1e-5);
            AddIpoptNumOption(nlp,"slack_bound_push", 1e-5);
            AddIpoptNumOption(nlp,"constr_mult_init_max", 1e-5);
            AddIpoptStrOption(nlp,"bound_mult_init_method","mu-based");
        } else {
            AddIpoptStrOption(nlp,"mu_strategy","adaptive");
            AddIpoptStrOption(nlp,"bound_mult_init_method","constant");
        }
        AddIpoptStrOption(nlp,"fixed_variable_treatment","make_parameter");
        AddIpoptStrOption(nlp,"dependency_detection_with_rhs","yes");
        AddIpoptNumOption(nlp,"nu_init",1e-9);
        AddIpoptNumOption(nlp,"eta_phi",1e-10);
    }

    /********************************************************************/


    if(max_iter >=0) {
        optData->iter_ = 0.0;
        optData->index = 1;
        res = IpoptSolve(nlp, vopt, NULL, &obj, mult_g, mult_x_L, mult_x_U, (void*)optData);
    }
    if(res != 0 && !ACTIVE_STREAM(LOG_IPOPT))
        warningStreamPrint(LOG_STDOUT, 0, "No optimal solution found!\nUse -lv=LOG_IPOPT for more information.");
    FreeIpoptProblem(nlp);
}
Example #3
0
static PyObject *create(PyObject * obj, PyObject * args)
{
	PyObject *f = NULL;
	PyObject *gradf = NULL;
	PyObject *g = NULL;
	PyObject *jacg = NULL;
	PyObject *h = NULL;
	PyObject *applynew = NULL;

	DispatchData myowndata;

	/*
	 * I have to create a new python object here, return this python
	 * object
	 */

	int n;			/* Number of var */
	PyArrayObject *xL = NULL;
	PyArrayObject *xU = NULL;
	int m;			/* Number of con */
	PyArrayObject *gL = NULL;
	PyArrayObject *gU = NULL;

	problem *object = NULL;

	int nele_jac;
	int nele_hess;

	Number *x_L = NULL;	/* lower bounds on x */
	Number *x_U = NULL;	/* upper bounds on x */
	Number *g_L = NULL;	/* lower bounds on g */
	Number *g_U = NULL;	/* upper bounds on g */

	double *xldata, *xudata;
	double *gldata, *gudata;

	int i;

	DispatchData *dp = NULL;

	PyObject *retval = NULL;

	/* Init the myowndata field */
	myowndata.eval_f_python = NULL;
	myowndata.eval_grad_f_python = NULL;
	myowndata.eval_g_python = NULL;
	myowndata.eval_jac_g_python = NULL;
	myowndata.eval_h_python = NULL;
	myowndata.apply_new_python = NULL;
	myowndata.userdata = NULL;

	/* "O!", &PyArray_Type &a_x  */
	if (!PyArg_ParseTuple(args, "iO!O!iO!O!iiOOOO|OO:pyipoptcreate",
			      &n, &PyArray_Type, &xL,
			      &PyArray_Type, &xU,
			      &m,
			      &PyArray_Type, &gL,
			      &PyArray_Type, &gU,
			      &nele_jac, &nele_hess,
			      &f, &gradf, &g, &jacg, &h, &applynew)) {
		retval = NULL;
		SAFE_FREE(x_L);
		SAFE_FREE(x_U);
		SAFE_FREE(g_L);
		SAFE_FREE(g_U);
		return retval;
	}
	if (!PyCallable_Check(f) ||
	    !PyCallable_Check(gradf) ||
	    !PyCallable_Check(g) || !PyCallable_Check(jacg)) {
		PyErr_SetString(PyExc_TypeError,
				"Need a callable object for callback functions");
		retval = NULL;
		SAFE_FREE(x_L);
		SAFE_FREE(x_U);
		SAFE_FREE(g_L);
		SAFE_FREE(g_U);
		return retval;
	}
	myowndata.eval_f_python = f;
	myowndata.eval_grad_f_python = gradf;
	myowndata.eval_g_python = g;
	myowndata.eval_jac_g_python = jacg;

	if (h != NULL) {
		if (PyCallable_Check(h)) {
			myowndata.eval_h_python = h;
		} else {
			PyErr_SetString(PyExc_TypeError,
					"Need a callable object for function h.");
			retval = NULL;
			SAFE_FREE(x_L);
			SAFE_FREE(x_U);
			SAFE_FREE(g_L);
			SAFE_FREE(g_U);
			return retval;
		}
	} else {
		logger("[PyIPOPT] Ipopt will use Hessian approximation.\n");
	}

	if (applynew != NULL) {
		if (PyCallable_Check(applynew)) {
			myowndata.apply_new_python = applynew;
		} else {
			PyErr_SetString(PyExc_TypeError,
					"Need a callable object for function applynew.");
			retval = NULL;
			SAFE_FREE(x_L);
			SAFE_FREE(x_U);
			SAFE_FREE(g_L);
			SAFE_FREE(g_U);
			return retval;
		}
	}
	if (m < 0 || n < 0) {
		PyErr_SetString(PyExc_TypeError, "m or n can't be negative");
		retval = NULL;
		SAFE_FREE(x_L);
		SAFE_FREE(x_U);
		SAFE_FREE(g_L);
		SAFE_FREE(g_U);
		return retval;
	}
	x_L = (Number *) malloc(sizeof(Number) * n);
	x_U = (Number *) malloc(sizeof(Number) * n);
	if (!x_L || !x_U) {
		retval = PyErr_NoMemory();
		SAFE_FREE(x_L);
		SAFE_FREE(x_U);
		SAFE_FREE(g_L);
		SAFE_FREE(g_U);
		return retval;
	}
	xldata = (double *)xL->data;
	xudata = (double *)xU->data;
	for (i = 0; i < n; i++) {
		x_L[i] = xldata[i];
		x_U[i] = xudata[i];
	}

	g_L = (Number *) malloc(sizeof(Number) * m);
	g_U = (Number *) malloc(sizeof(Number) * m);
	if (!g_L || !g_U)
		PyErr_NoMemory();

	gldata = (double *)gL->data;
	gudata = (double *)gU->data;

	for (i = 0; i < m; i++) {
		g_L[i] = gldata[i];
		g_U[i] = gudata[i];
	}

	/* create the Ipopt Problem */

	int C_indexstyle = 0;
	IpoptProblem thisnlp = CreateIpoptProblem(n,
						  x_L, x_U, m, g_L, g_U,
						  nele_jac, nele_hess,
						  C_indexstyle,
						  &eval_f, &eval_g,
						  &eval_grad_f,
						  &eval_jac_g, &eval_h);
	logger("[PyIPOPT] Problem created");
	if (!thisnlp) {
		PyErr_SetString(PyExc_MemoryError,
				"Cannot create IpoptProblem instance");
		retval = NULL;
		SAFE_FREE(x_L);
		SAFE_FREE(x_U);
		SAFE_FREE(g_L);
		SAFE_FREE(g_U);
		return retval;
	}
	object = PyObject_NEW(problem, &IpoptProblemType);

	if (object != NULL) {
		object->n_variables = n;
		object->m_constraints = m;
		object->nlp = thisnlp;
		dp = (DispatchData *) malloc(sizeof(DispatchData));
		if (!dp) {
			retval = PyErr_NoMemory();
			SAFE_FREE(x_L);
			SAFE_FREE(x_U);
			SAFE_FREE(g_L);
			SAFE_FREE(g_U);
			return retval;
		}
		memcpy((void *)dp, (void *)&myowndata, sizeof(DispatchData));
		object->data = dp;
		retval = (PyObject *) object;
		SAFE_FREE(x_L);
		SAFE_FREE(x_U);
		SAFE_FREE(g_L);
		SAFE_FREE(g_U);
		return retval;
	} else {
		PyErr_SetString(PyExc_MemoryError,
				"Can't create a new Problem instance");
		retval = NULL;
		SAFE_FREE(x_L);
		SAFE_FREE(x_U);
		SAFE_FREE(g_L);
		SAFE_FREE(g_U);
		return retval;
	}
}
Example #4
0
/* Main Program */
int main()
{
  Index n=-1;                          /* number of variables */
  Index m=-1;                          /* number of constraints */
  Number* x_L = NULL;                  /* lower bounds on x */
  Number* x_U = NULL;                  /* upper bounds on x */
  Number* g_L = NULL;                  /* lower bounds on g */
  Number* g_U = NULL;                  /* upper bounds on g */
  IpoptProblem nlp = NULL;             /* IpoptProblem */
  enum ApplicationReturnStatus status; /* Solve return code */
  Number* x = NULL;                    /* starting point and solution vector */
  Number* mult_x_L = NULL;             /* lower bound multipliers
  					  at the solution */
  Number* mult_x_U = NULL;             /* upper bound multipliers
  					  at the solution */
  Number obj;                          /* objective value */
  Index i;                             /* generic counter */

  /* Number of nonzeros in the Jacobian of the constraints */
  Index nele_jac = 8;
  /* Number of nonzeros in the Hessian of the Lagrangian (lower or
     upper triangual part only) */
  Index nele_hess = 10;
  /* indexing style for matrices */
  Index index_style = 0; /* C-style; start counting of rows and column
  			    indices at 0 */

  /* set the number of variables and allocate space for the bounds */
  n=4;
  x_L = (Number*)malloc(sizeof(Number)*n);
  x_U = (Number*)malloc(sizeof(Number)*n);
  /* set the values for the variable bounds */
  for (i=0; i<n; i++) {
    x_L[i] = 1.0;
    x_U[i] = 5.0;
  }

  /* set the number of constraints and allocate space for the bounds */
  m=2;
  g_L = (Number*)malloc(sizeof(Number)*m);
  g_U = (Number*)malloc(sizeof(Number)*m);
  /* set the values of the constraint bounds */
  g_L[0] = 25;
  g_U[0] = 2e19;
  g_L[1] = 40;
  g_U[1] = 40;

  /* create the IpoptProblem */
  nlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, nele_hess,
                           index_style, &eval_f, &eval_g, &eval_grad_f,
                           &eval_jac_g, &eval_h);

  /* We can free the memory now - the values for the bounds have been
     copied internally in CreateIpoptProblem */
  free(x_L);
  free(x_U);
  free(g_L);
  free(g_U);

  /* Set some options.  Note the following ones are only examples,
     they might not be suitable for your problem. */
  AddIpoptNumOption(nlp, "tol", 1e-7);
  AddIpoptStrOption(nlp, "mu_strategy", "adaptive");
  AddIpoptStrOption(nlp, "output_file", "ipopt.out");

  /* allocate space for the initial point and set the values */
  x = (Number*)malloc(sizeof(Number)*n);
  x[0] = 1.0;
  x[1] = 5.0;
  x[2] = 5.0;
  x[3] = 1.0;

  /* allocate space to store the bound multipliers at the solution */
  mult_x_L = (Number*)malloc(sizeof(Number)*n);
  mult_x_U = (Number*)malloc(sizeof(Number)*n);

  /* solve the problem */
  status = IpoptSolve(nlp, x, NULL, &obj, NULL, mult_x_L, mult_x_U, NULL);

  if (status == Solve_Succeeded) {
    printf("\n\nSolution of the primal variables, x\n");
    for (i=0; i<n; i++) {
      printf("x[%d] = %e\n", i, x[i]);
    }

    printf("\n\nSolution of the bound multipliers, z_L and z_U\n");
    for (i=0; i<n; i++) {
      printf("z_L[%d] = %e\n", i, mult_x_L[i]);
    }
    for (i=0; i<n; i++) {
      printf("z_U[%d] = %e\n", i, mult_x_U[i]);
    }

    printf("\n\nObjective value\n");
    printf("f(x*) = %e\n", obj);
  }

  /* free allocated memory */
  FreeIpoptProblem(nlp);
  free(x);
  free(mult_x_L);
  free(mult_x_U);

  return 0;
}
Example #5
0
/* Main Program */
int main()
{
  Index n=-1;                          /* number of variables */
  Index m=-1;                          /* number of constraints */
  Index nele_jac;                      /* number of nonzeros in Jacobian */
  Index nele_hess;                     /* number of nonzeros in Hessian */
  Index index_style;                   /* indexing style for matrices */
  Number* x_L = NULL;                  /* lower bounds on x */
  Number* x_U = NULL;                  /* upper bounds on x */
  Number* g_L = NULL;                  /* lower bounds on g */
  Number* g_U = NULL;                  /* upper bounds on g */
  IpoptProblem nlp = NULL;             /* IpoptProblem */
  enum ApplicationReturnStatus status; /* Solve return code */
  Number* x = NULL;                    /* starting point and solution vector */
  Number* mult_x_L = NULL;             /* lower bound multipliers
  					  at the solution */
  Number* mult_x_U = NULL;             /* upper bound multipliers
  					  at the solution */
  Number obj;                          /* objective value */
  Index i;                             /* generic counter */

  int size;                            /* Size of the problem */
  ProblemData PD;                      /* Pointer to structure with problem data */

  /* Specify size of the problem */
  size = 100;

  /* Set the problem data */
  PD = (ProblemData)malloc(sizeof(struct _ProblemData));
  PD->N = size;
  PD->a = malloc(sizeof(double)*(size-2));
  for (i=0; i<size-2; i++) {
    PD->a[i] = ((double)(i+2))/(double)size;
  }

  /* set the number of variables and allocate space for the bounds */
  n=size;
  x_L = (Number*)malloc(sizeof(Number)*n);
  x_U = (Number*)malloc(sizeof(Number)*n);
  /* set the values for the variable bounds */
  for (i=0; i<n; i++) {
    x_L[i] = -1.5;
    x_U[i] = 0.;
  }

  /* set the number of constraints and allocate space for the bounds */
  m=size-2;
  g_L = (Number*)malloc(sizeof(Number)*m);
  g_U = (Number*)malloc(sizeof(Number)*m);
  /* set the values of the constraint bounds */
  for (i=0; i<m; i++) {
    g_L[i] = 0.;
    g_U[i] = 0.;
  }
  
  /* Number of nonzeros in the Jacobian of the constraints
     each constraint has three nonzeros */
  nele_jac = 3*m;

  /* Number of nonzeros in the Hessian of the Lagrangian (lower or
     upper triangual part only)
     We have the full diagonal, and the first off-diagonal except for
     the first and last variable */
  nele_hess = n + (n-2);

  /* indexing style for matrices */
  index_style = 0; /* C-style; start counting of rows and column
  			    indices at 0 */

  /* create the IpoptProblem */
  nlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, nele_hess,
                           index_style, &eval_f, &eval_g, &eval_grad_f,
                           &eval_jac_g, &eval_h);

  /* We can free the memory now - the values for the bounds have been
     copied internally in CreateIpoptProblem */
  free(x_L);
  free(x_U);
  free(g_L);
  free(g_U);

  /* Set some options.  Note the following ones are only examples,
     they might not be suitable for your problem. */
  AddIpoptNumOption(nlp, "tol", 1e-7);
  AddIpoptStrOption(nlp, "mu_strategy", "adaptive");
  AddIpoptStrOption(nlp, "output_file", "ipopt.out");

  /* allocate space for the initial point and set the values */
  x = (Number*)malloc(sizeof(Number)*n);
  for (i=0; i<n; i++) {
    x[i] = -0.5;
  }

#ifdef skip_me
  /* If checking derivatives, if is useful to choose different values */
  for (i=0; i<n; i++) {
    x[i] = -0.5+0.1*i/n;
  }
#endif

  /* allocate space to store the bound multipliers at the solution */
  mult_x_L = (Number*)malloc(sizeof(Number)*n);
  mult_x_U = (Number*)malloc(sizeof(Number)*n);

  /* solve the problem */
  status = IpoptSolve(nlp, x, NULL, &obj, NULL, mult_x_L, mult_x_U, (void*)PD);

  if (status == Solve_Succeeded) {
    printf("\n\nSolution of the primal variables, x\n");
    for (i=0; i<n; i++) {
      printf("x[%d] = %e\n", i, x[i]);
    }

    printf("\n\nSolution of the bound multipliers, z_L and z_U\n");
    for (i=0; i<n; i++) {
      printf("z_L[%d] = %e\n", i, mult_x_L[i]);
    }
    for (i=0; i<n; i++) {
      printf("z_U[%d] = %e\n", i, mult_x_U[i]);
    }

    printf("\n\nObjective value\n");
    printf("f(x*) = %e\n", obj);
  }

  /* free allocated memory */
  FreeIpoptProblem(nlp);
  free(x);
  free(mult_x_L);
  free(mult_x_U);

  /* also for our user data */
  free(PD->a);
  free(PD);

  return 0;
}
  /*! \fn ipopt_initialization
   *
   *  This function is used if ipopt is choosen for initialization.
   *
   *  \param [ref] [data]
   *  \param [ref] [initData]
   *  \param [in]  [useScaling]
   *
   *  \author lochel
   */
  int ipopt_initialization(DATA *data, INIT_DATA *initData, int useScaling)
  {
    int n = initData->nz;                /* number of variables */
    int m = (initData->nInitResiduals > initData->nz) ? 0 : initData->nInitResiduals;    /* number of constraints */
    double* x_L = NULL;                  /* lower bounds on x */
    double* x_U = NULL;                  /* upper bounds on x */
    double* g_L = NULL;                  /* lower bounds on g */
    double* g_U = NULL;                  /* upper bounds on g */

    double* x = NULL;                    /* starting point and solution vector */
    double* mult_g = NULL;               /* constraint multipliers at the solution */
    double* mult_x_L = NULL;             /* lower bound multipliers at the solution */
    double* mult_x_U = NULL;             /* upper bound multipliers at the solution */
    double obj;                          /* objective value */
    int i;                               /* generic counter */

    int nele_jac = n*m;                  /* number of nonzeros in the Jacobian of the constraints */
    int nele_hess = 0;                   /* number of nonzeros in the Hessian of the Lagrangian (lower or upper triangual part only) */

    IpoptProblem nlp = NULL;             /* ipopt-problem */
    enum ApplicationReturnStatus status; /* solve return code */

    IPOPT_DATA ipopt_data;

    ipopt_data.data = data;
    ipopt_data.initData = initData;
    ipopt_data.useScaling = useScaling;
    ipopt_data.useSymbolic = (initialAnalyticJacobianG(data) == 0 ? 1 : 0);

    if(ipopt_data.useSymbolic == 1)
    {
      nele_jac = data->simulationInfo.analyticJacobians[INDEX_JAC_G].sparsePattern.leadindex[n-1]; // sparse
      DEBUG_INFO1(LOG_INIT, "number of zeros in the Jacobian of the constraints (jac_g):    %d", n*m-nele_jac);
      DEBUG_INFO1(LOG_INIT, "number of nonzeros in the Jacobian of the constraints (jac_g): %d", nele_jac);
    }

    /* allocate space for the variable bounds */
    x_L = (double*)malloc(n * sizeof(double));
    x_U = (double*)malloc(n * sizeof(double));

    /* allocate space for the constraint bounds */
    g_L = (double*)malloc(m * sizeof(double));
    g_U = (double*)malloc(m * sizeof(double));

    /* allocate space for the initial point */
    x = (double*)malloc(n * sizeof(double));

    /* set values of optimization variable bounds */
    for(i=0; i<n; ++i)
    {
      x[i] = initData->start[i];
      x_L[i] = initData->min[i];
      x_U[i] = initData->max[i];
    }

    /* set values of constraint bounds */
    for(i=0; i<m; ++i)
    {
      g_L[i] = 0.0;
      g_U[i] = 0.0;
    }

    /* create the IpoptProblem */
    nlp = CreateIpoptProblem(
        n,              /* Number of optimization variables */
        x_L,            /* Lower bounds on variables */
        x_U,            /* Upper bounds on variables */
        m,              /* Number of constraints */
        g_L,            /* Lower bounds on constraints */
        g_U,            /* Upper bounds on constraints */
        nele_jac,       /* Number of non-zero elements in constraint Jacobian */
        nele_hess,      /* Number of non-zero elements in Hessian of Lagrangian */
        0,              /* indexing style for iRow & jCol; 0 for C style, 1 for Fortran style */
        &ipopt_f,       /* Callback function for evaluating objective function */
        &ipopt_g,       /* Callback function for evaluating constraint functions */
        &ipopt_grad_f,  /* Callback function for evaluating gradient of objective function */
        &ipopt_jac_g,   /* Callback function for evaluating Jacobian of constraint functions */
        &ipopt_h);      /* Callback function for evaluating Hessian of Lagrangian function */

    ASSERT(nlp, "creating of ipopt problem has failed");

    /* We can free the memory now - the values for the bounds have been
       copied internally in CreateIpoptProblem */
    free(x_L);
    free(x_U);
    free(g_L);
    free(g_U);

    /* Set some options. Note the following ones are only examples,
       they might not be suitable for your problem. */
    AddIpoptNumOption(nlp, "tol", 1e-7);

    AddIpoptIntOption(nlp, "print_level", DEBUG_FLAG(LOG_INIT) ? 5 : 0);
    AddIpoptIntOption(nlp, "max_iter", 5000);

    AddIpoptStrOption(nlp, "mu_strategy", "adaptive");
    AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory");

    /* allocate space to store the bound multipliers at the solution */
    mult_g = (double*)malloc(m*sizeof(double));
    mult_x_L = (double*)malloc(n*sizeof(double));
    mult_x_U = (double*)malloc(n*sizeof(double));

    /* solve the problem */
    status = IpoptSolve(
        nlp,            /* Problem that is to be optimized */
        x,              /* Input: Starting point; Output: Optimal solution */
        NULL,           /* Values of constraint at final point */
        &obj,           /* Final value of objective function */
        mult_g,         /* Final multipliers for constraints */
        mult_x_L,       /* Final multipliers for lower variable bounds */
        mult_x_U,       /* Final multipliers for upper variable bounds */
        &ipopt_data);   /* Pointer to user data */

    setZ(initData, x);

    /* free allocated memory */
    FreeIpoptProblem(nlp);
    free(x);
    free(mult_g);
    free(mult_x_L);
    free(mult_x_U);

    /* debug output */
    DEBUG_INFO1(LOG_INIT, "ending with funcValue = %g", obj);
    DEBUG_INFO_AL(LOG_INIT, "| unfixed variables");
    for(i=0; i<initData->nz; i++)
      DEBUG_INFO_AL4(LOG_INIT, "| | [%ld] %s = %g [scaled: %g]", i+1, initData->name[i], initData->z[i], initData->zScaled[i]);
    DEBUG_INFO_AL(LOG_INIT, "| residuals (> 0.001)");
    for(i=0; i<data->modelData.nInitResiduals; i++)
      if(fabs(initData->initialResiduals[i]) > 1e-3)
        DEBUG_INFO_AL3(LOG_INIT, "| | [%ld] %g [scaled: %g]", i+1, initData->initialResiduals[i], (initData->residualScalingCoefficients[i] != 0.0) ? initData->initialResiduals[i]/initData->residualScalingCoefficients[i] : 0.0);

    if(status != Solve_Succeeded && status != Solved_To_Acceptable_Level)
      THROW("ipopt failed. see last warning. use [-lv LOG_INIT] for more output.");

    return (int)status;
  }
Example #7
0
/*!
 *  start main optimization step
 *  author: Vitalij Ruge
 **/
int startIpopt(DATA* data, SOLVER_INFO* solverInfo, int flag)
{
  int i;
  int j,k,l;
  double obj;
  int res;
  char *cflags;

  IpoptProblem nlp = NULL;
  IPOPT_DATA_ *iData = ((IPOPT_DATA_*)solverInfo->solverData);
  iData->current_var = 0;
  iData->current_time = 0;
  iData->data = data;
  iData->mayer = mayer(data, &obj);
  iData->lagrange = lagrange(data, &obj);
  iData->numObject = 2 - iData->mayer -iData->lagrange;

  iData->matrixA = initialAnalyticJacobianA((void*) iData->data);
  iData->matrixB = initialAnalyticJacobianB((void*) iData->data);
  /*
  iData->matrixC = initialAnalyticJacobianC((void*) iData->data);
  iData->matrixD = initialAnalyticJacobianD((void*) iData->data);
  */

  loadDAEmodel(data, iData);
  iData->index_debug_iter=0;
  iData->degub_step =  10;
  iData->index_debug_next=0;

    cflags = omc_flagValue[FLAG_LS_IPOPT];
    if(!cflags)
      cflags = "mumps";

  /*ToDo*/
  for(i=0; i<(*iData).nx; i++)
  {
    iData->Vmin[i] = (*iData).Vmax[i] = (*iData).x0[i]*iData->scalVar[i];
    iData->v[i] = iData->Vmin[i];

    if(ACTIVE_STREAM(LOG_IPOPT))
    {
      printf("\nx[%i] = %s = %g",i, iData->data->modelData.realVarsData[i].info.name,iData->v[i]);
    }
  }
  initial_guess_ipopt(iData,solverInfo);

  if(ACTIVE_STREAM(LOG_IPOPT))
  {
    for(; i<iData->nv; ++i)
      printf("\nu[%i] = %s = %g",i, iData->data->modelData.realVarsData[iData->index_u + i-iData->nx].info.name,iData->v[i]);
  }

  ipoptDebuge(iData,iData->v);

  if(flag == 5)
  {
     nlp = CreateIpoptProblem((*iData).NV, (*iData).Vmin, (*iData).Vmax,
         (*iData).NRes, (*iData).gmin, (*iData).gmax, (*iData).njac, NULL, 0, &evalfF,
                  &evalfG, &evalfDiffF, &evalfDiffG, &ipopt_h);

    AddIpoptNumOption(nlp, "tol", iData->data->simulationInfo.tolerance);

    if(ACTIVE_STREAM(LOG_IPOPT))
    {
      AddIpoptIntOption(nlp, "print_level", 5);
      AddIpoptIntOption(nlp, "file_print_level", 0);
    }
    else if(ACTIVE_STREAM(LOG_STATS))
    {
      AddIpoptIntOption(nlp, "print_level", 3);
      AddIpoptIntOption(nlp, "file_print_level", 0);
    }
    else
    {
      AddIpoptIntOption(nlp, "print_level", 2);
      AddIpoptIntOption(nlp, "file_print_level", 0);
    }

    AddIpoptStrOption(nlp, "mu_strategy", "adaptive");
    AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory");

    if(cflags)
      AddIpoptStrOption(nlp, "linear_solver", cflags);
    else
      AddIpoptStrOption(nlp, "linear_solver", "mumps");

    /* AddIpoptStrOption(nlp, "derivative_test", "second-order"); */
    /* AddIpoptStrOption(nlp, "derivative_test_print_all", "yes"); */
    /* AddIpoptNumOption(nlp,"derivative_test_perturbation",1e-6); */
    AddIpoptIntOption(nlp, "max_iter", 5000);

    res = IpoptSolve(nlp, (*iData).v, NULL, &obj, (*iData).mult_g, (*iData).mult_x_L, (*iData).mult_x_U, (void*)iData);
    FreeIpoptProblem(nlp);

    if(ACTIVE_STREAM(LOG_IPOPT))
    {
      for(i =0; i<iData->nv;i++)
        if(iData->pFile[i])
          fclose(iData->pFile[i]);
      if(iData->pFile)
        free(iData->pFile);
    }

    iData->current_var = 0;
    res2file(iData,solverInfo);
  }
  return 0;
}
    SimTK::Real InteriorPointOptimizer::optimize(  Vector &results ) {

        int n = getOptimizerSystem().getNumParameters();
        int m = getOptimizerSystem().getNumConstraints();

        Index index_style = 0; /* C-style; start counting of rows and column indices at 0 */
        Index nele_hess = 0;
        Index nele_jac = n*m; /* always assume dense */

        // Parameter limits
        Number *x_L = NULL, *x_U = NULL;
        if( getOptimizerSystem().getHasLimits() ) {
           getOptimizerSystem().getParameterLimits( &x_L, &x_U);
        } else {
           x_U = new Number[n];
           x_L = new Number[n];
           for(int i=0;i<n;i++) {
              x_U[i] = SimTK::Real(POSITIVE_INF);
              x_L[i] = SimTK::Real(NEGATIVE_INF);
           }
        }

        SimTK::Real *x = &results[0];

        IpoptProblem nlp = CreateIpoptProblem(n, x_L, x_U, m, g_L, g_U, nele_jac, 
                           nele_hess, index_style, objectiveFuncWrapper, constraintFuncWrapper, 
                           gradientFuncWrapper, constraintJacobianWrapper, hessianWrapper);

        // If you want to verify which options are getting set in the optimizer, you can create a file ipopt.opt
        // with "print_user_options yes", and set print_level to (at least 1).  It will then print the options to the screen.
        
        // sherm 100302: you have to set all of these tolerances to get IpOpt to change
        // its convergence criteria; see OptimalityErrorConvergenceCheck::CheckConvergence().
        // We'll set acceptable tolerances to the same value to disable them.
        AddIpoptNumOption(nlp, "tol", convergenceTolerance);
        AddIpoptNumOption(nlp, "dual_inf_tol", convergenceTolerance);
        AddIpoptNumOption(nlp, "constr_viol_tol", constraintTolerance);
        AddIpoptNumOption(nlp, "compl_inf_tol", convergenceTolerance);
        AddIpoptNumOption(nlp, "acceptable_tol", convergenceTolerance);
        AddIpoptNumOption(nlp, "acceptable_dual_inf_tol", convergenceTolerance);
        AddIpoptNumOption(nlp, "acceptable_constr_viol_tol", constraintTolerance);
        AddIpoptNumOption(nlp, "acceptable_compl_inf_tol", convergenceTolerance);


        AddIpoptIntOption(nlp, "max_iter", maxIterations);
        AddIpoptStrOption(nlp, "mu_strategy", "adaptive");
        AddIpoptStrOption(nlp, "hessian_approximation", "limited-memory"); // needs to be limited-memory unless you have explicit hessians
        AddIpoptIntOption(nlp, "limited_memory_max_history", limitedMemoryHistory);
        AddIpoptIntOption(nlp, "print_level", diagnosticsLevel); // default is 4

        int i;
        static const char *advancedRealOptions[] = {
                                                    "compl_inf_tol", 
                                                    "dual_inf_tol", 
                                                    "constr_viol_tol", 
                                                    "acceptable_tol", 
                                                    "acceptable_compl_inf_tol", 
                                                    "acceptable_constr_viol_tol", 
                                                    "acceptable_dual_inf_tol", 
                                                    "diverging_iterates_tol", 
                                                    "barrier_tol_factor", 
                                                    "obj_scaling_factor", 
                                                    "nlp_scaling_max_gradient", 
                                                    "bounds_relax_factor", 
                                                    "recalc_y_feas_tol", 
                                                    "mu_init", 
                                                    "mu_max_fact", 
                                                    "mu_max", 
                                                    "mu_min", 
                                                    "mu_linear_decrease_factor", 
                                                    "mu_superlinear_decrease_factor", 
                                                    "bound_frac", 
                                                    "bound_push", 
                                                    "bound_mult_init_val", 
                                                    "constr_mult_init_max", 
                                                    "constr_mult_init_val", 
                                                    "warm_start_bound_push", 
                                                    "warm_start_bound_frac", 
                                                    "warm_start_mult_bound_push", 
                                                    "warm_start_mult_init_max", 
                                                    "recalc_y_feas_tol", 
                                                    "expect_infeasible_problem_ctol", 
                                                    "soft_resto_pderror_reduction_factor", 
                                                    "required_infeasibility_reduction", 
                                                    "bound_mult_reset_threshold", 
                                                    "constr_mult_reset_threshold", 
                                                    "max_hessian_perturbation", 
                                                    "min_hessian_perturbation", 
                                                    "first_hessian_perturbation", 
                                                    "perturb_inc_fact_first", 
                                                    "perturb_inc_fact", 
                                                    "perturb_dec_fact", 
                                                    "jacobian_reqularization_value", 
                                                    "derivative_test_perturbation", 
                                                    "derivative_test_tol", 
                                                    0}; 
        Real value;
        for(i=0;advancedRealOptions[i];i++) {
            if(getAdvancedRealOption(advancedRealOptions[i],value))
                AddIpoptNumOption(nlp, advancedRealOptions[i], value);
        }

        static const std::string advancedStrOptions[] = {"nlp_scaling_method",
                                                         "honor_original_bounds", 
                                                         "check_derivatives_for_naninf", 
                                                         "mu_strategy", 
                                                         "mu_oracle", 
                                                         "fixed_mu_oracle", 
                                                         "alpha_for_y", 
                                                         "recalc_y", 
                                                         "expect_infeasible_problem", 
                                                         "print_options_documentation", 
                                                         "print_user_options", 
                                                         "start_with_resto", 
                                                         "evaluate_orig_obj_at_resto_trial", 
                                                         "hessian_approximation", 
                                                         "derivative_test", 
                                                         ""}; 
        std::string svalue;
        for(i=0;!advancedStrOptions[i].empty();i++) {
            if(getAdvancedStrOption(advancedStrOptions[i], svalue))
                AddIpoptStrOption(nlp, advancedStrOptions[i].c_str(), svalue.c_str());
        }

        static const char*  advancedIntOptions[] = {"quality_function_max_section_steps",
                                                         "max_soc",
                                                         "watchdog_shorted_iter_trigger",
                                                         "watchdog_trial_iter_max",
                                                         "max_refinement_steps",
                                                         "min_refinement_steps",
                                                         "limited_memory_max_history",
                                                         "limited_memory_max_skipping",
                                                         "derivative_test_print_all",
                                                         0}; 
        int ivalue;
        for(i=0;advancedIntOptions[i];i++) {
            if(getAdvancedIntOption(advancedIntOptions[i], ivalue))
                AddIpoptIntOption(nlp, advancedIntOptions[i], ivalue);
        }

        // Only makes sense to do a warm start if this is not the first call to optimize() (since we need 
        // reasonable starting multiplier values)
        bool use_warm_start=false;
        if(getAdvancedBoolOption("warm_start", use_warm_start) && use_warm_start && !firstOptimization) {
            AddIpoptStrOption(nlp, "warm_start_init_point", "yes");
            AddIpoptStrOption(nlp, "warm_start_entire_iterate", "yes");
            //AddIpoptStrOption(nlp, "warm_start_same_structure", "yes"); // couldn't get this one to work
        } 

        SimTK::Real obj;

        int status = IpoptSolve(nlp, x, NULL, &obj, mult_g, mult_x_L, mult_x_U, (void *)this );

        FreeIpoptProblem(nlp); 

        // Only delete these if they aren't pointing to existing parameter limits
        if( !getOptimizerSystem().getHasLimits() ) {
           delete [] x_U;
           delete [] x_L;
        }

        if(status == Solved_To_Acceptable_Level) {
            std::cout << "Ipopt: Solved to acceptable level" << std::endl;
        } else if (status != Solve_Succeeded) {
            if( status != NonIpopt_Exception_Thrown) {
                char buf[1024];
                sprintf(buf, "Ipopt: %s (status %d)",applicationReturnStatusToString(status).c_str(),status);
                SimTK_THROW1(SimTK::Exception::OptimizerFailed, SimTK::String(buf));
            }
        }

        firstOptimization = false;

        return(obj);
    }