summaryrefslogtreecommitdiff
path: root/sci_gateway/cpp/sci_minconNLP.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sci_gateway/cpp/sci_minconNLP.cpp')
-rw-r--r--sci_gateway/cpp/sci_minconNLP.cpp797
1 files changed, 797 insertions, 0 deletions
diff --git a/sci_gateway/cpp/sci_minconNLP.cpp b/sci_gateway/cpp/sci_minconNLP.cpp
new file mode 100644
index 0000000..2c6d6af
--- /dev/null
+++ b/sci_gateway/cpp/sci_minconNLP.cpp
@@ -0,0 +1,797 @@
+// Copyright (C) 2015 - IIT Bombay - FOSSEE
+//
+// Author: R.Vidyadhar & Vignesh Kannan
+// Organization: FOSSEE, IIT Bombay
+// Email: rvidhyadar@gmail.com & vignesh2496@gmail.com
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution. The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+
+
+#include "minconNLP.hpp"
+#include "IpIpoptData.hpp"
+#include "sci_iofunc.hpp"
+
+extern "C"
+{
+
+#include <api_scilab.h>
+#include <Scierror.h>
+#include <BOOL.h>
+#include <localization.h>
+#include <sciprint.h>
+#include <string.h>
+#include <assert.h>
+#include <iostream>
+
+using namespace std;
+using namespace Ipopt;
+
+minconNLP::~minconNLP()
+{
+ free(finalX_);
+ free(finalGradient_);
+ free(finalHessian_);
+ free(finalZu_);
+ free(finalZl_);
+ free(finalLambda_);
+}
+
+//get NLP info such as number of variables,constraints,no.of elements in jacobian and hessian to allocate memory
+bool minconNLP::get_nlp_info(Index& n, Index& m, Index& nnz_jac_g, Index& nnz_h_lag, IndexStyleEnum& index_style)
+{
+ finalGradient_ = (double*)malloc(sizeof(double) * numVars_ * 1);
+ finalHessian_ = (double*)malloc(sizeof(double) * numVars_ * numVars_);
+
+ n=numVars_; // Number of variables
+ m=numConstr_; // Number of constraints
+
+ nnz_jac_g = n*m; // No. of elements in Jacobian of constraints
+ nnz_h_lag = n*(n+1)/2; // No. of elements in lower traingle of Hessian of the Lagrangian.
+
+ index_style=C_STYLE; // Index style of matrices
+ return true;
+}
+
+//get variable and constraint bound info
+bool minconNLP::get_bounds_info(Index n, Number* x_l, Number* x_u, Index m, Number* g_l, Number* g_u)
+{
+ unsigned int i;
+
+ //assigning bounds for the variables
+ for(i=0;i<n;i++)
+ {
+ x_l[i]=varLB_[i];
+ x_u[i]=varUB_[i];
+ }
+
+ if(m==0)
+ {
+ g_l=NULL;
+ g_u=NULL;
+ }
+
+ else
+ {
+ unsigned int c=0;
+
+ //bounds of non-linear inequality constraints
+ for(i=0;i<nonlinIneqCon_;i++)
+ {
+ g_l[c]=-1.0e19;
+ g_u[c]=0;
+ c++;
+ }
+
+ //bounds of non-linear equality constraints
+ for(i=0;i<nonlinCon_-nonlinIneqCon_;i++)
+ {
+ g_l[c]=g_u[c]=0;
+ c++;
+ }
+
+ //bounds of linear equality constraints
+ for(i=0;i<Aeqrows_;i++)
+ {
+ g_l[c]=g_u[c]=beq_[i];
+ c++;
+ }
+
+ //bounds of linear inequality constraints
+ for(i=0;i<Arows_;i++)
+ {
+ g_l[c]=-1.0e19;
+ g_u[c]=b_[i];
+
+ c++;
+ }
+
+ }
+
+ return true;
+}
+
+// return the value of the constraints: g(x)
+bool minconNLP::eval_g(Index n, const Number* x, bool new_x, Index m, Number* g)
+{
+ // return the value of the constraints: g(x)
+
+ unsigned int i;
+ unsigned int j;
+
+ if(m==0)
+ g=NULL;
+
+ else
+ {
+ unsigned int c=0;
+
+ //value of non-linear constraints
+ if(nonlinCon_!=0)
+ {
+ int* constr=NULL;
+ if(getFunctionFromScilab(11,&constr))
+ {
+ return 1;
+ }
+ char name[20]="addnlc1";
+ double *xNew=x;
+ double check;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 1;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *constr;
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+
+ double* resc;
+ int xC_rows,xC_cols;
+ if(getDoubleFromScilab(19,&check))
+ {
+ return true;
+ }
+ if (check==1)
+ {
+ return true;
+ }
+ else
+ {
+ if(getDoubleMatrixFromScilab(18, &xC_rows, &xC_cols, &resc))
+ {
+ sciprint("No results");
+ return 1;
+
+ }
+
+ for(i=0;i<nonlinCon_;i++)
+ {
+ g[c]=resc[i];
+ c++;
+ }
+ }
+ }
+
+ //value of linear equality constraints
+ for(i=0;i<Aeqrows_;i++)
+ {
+ g[c]=0;
+ for(j=0;j<Aeqcols_;j++)
+ g[c] += Aeq_[j*Aeqrows_+i]*x[j];
+ c++;
+ }
+
+ //value of linear inequality constraints
+ for(i=0;i<Arows_;i++)
+ {
+ g[c]=0;
+ for(j=0;j<Acols_;j++)
+ g[c] += A_[j*Arows_+i]*x[j];
+ c++;
+ }
+
+ }
+
+ return true;
+}
+
+// return the structure or values of the jacobian
+bool minconNLP::eval_jac_g(Index n, const Number* x, bool new_x,Index m, Index nele_jac, Index* iRow, Index *jCol,Number* values)
+{
+ if (values == NULL)
+ {
+ if(m==0)// return the structure of the jacobian of the constraints
+ {
+ iRow=NULL;
+ jCol=NULL;
+ }
+
+ else
+ {
+ unsigned int i,j,idx=0;
+ for(int i=0;i<m;i++)
+ for(j=0;j<n;j++)
+ {
+ iRow[idx]=i;
+ jCol[idx]=j;
+ idx++;
+ }
+ }
+ }
+
+ else
+ {
+ if(m==0)
+ values=NULL;
+
+ else
+ {
+ unsigned int i,j,c=0;
+ double check;
+ //jacobian of non-linear constraints
+ if(nonlinCon_!=0)
+ {
+ if(flag3_==0)
+ {
+ int* gradhessptr=NULL;
+ if(getFunctionFromScilab(2,&gradhessptr))
+ {
+ return 1;
+ }
+ double *xNew=x;
+ double t=3;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ createScalarDouble(pvApiCtx, 19,t);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 2;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *gradhessptr;
+ char name[20]="gradhess";
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+
+ double* resj;
+ int xJ_rows,xJ_cols;
+ if(getDoubleFromScilab(19,&check))
+ {
+ return true;
+ }
+ if (check==1)
+ {
+ return true;
+ }
+ else
+ {
+ if(getDoubleMatrixFromScilab(18, &xJ_rows, &xJ_cols, &resj))
+ {
+ sciprint("No results");
+ return 1;
+ }
+
+ for(i=0;i<nonlinCon_;i++)
+ {
+ for(j=0;j<n;j++)
+ {
+ values[c] = resj[j*(int)nonlinCon_+i];
+ c++;
+ }
+ }
+ }
+ }
+
+ else
+ {
+ int* jacptr=NULL;
+ if(getFunctionFromScilab(17,&jacptr))
+ {
+ return 1;
+ }
+
+ double *xNew=x;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 1;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *jacptr;
+ char name[20]="addcGrad1";
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+
+ double* resj;
+ int xJ_rows,xJ_cols;
+ if(getDoubleFromScilab(19,&check))
+ {
+ return true;
+ }
+ if (check==1)
+ {
+ return true;
+ }
+ else
+ {
+ if(getDoubleMatrixFromScilab(18, &xJ_rows, &xJ_cols, &resj))
+ {
+ sciprint("No results");
+ return 1;
+ }
+
+ for(i=0;i<nonlinCon_;i++)
+ for(j=0;j<n;j++)
+ {
+ values[c] = resj[j*(int)nonlinCon_+i];
+ c++;
+ }
+ }
+ }
+ }
+
+ //jacobian of linear equality constraints
+ for(i=0;i<Aeqrows_;i++)
+ {
+ for(j=0;j<Aeqcols_;j++)
+ {
+ values[c] = Aeq_[j*Aeqrows_+i];
+ c++;
+ }
+ }
+
+ //jacobian of linear inequality constraints
+ for(i=0;i<Arows_;i++)
+ {
+ for(j=0;j<Acols_;j++)
+ {
+ values[c] = A_[j*Arows_+i];
+ c++;
+ }
+ }
+
+ }
+ }
+
+ return true;
+}
+
+//get value of objective function at vector x
+bool minconNLP::eval_f(Index n, const Number* x, bool new_x, Number& obj_value)
+{
+ int* funptr=NULL;
+ if(getFunctionFromScilab(1,&funptr))
+ {
+ return 1;
+ }
+ char name[20]="f";
+ double obj=0;
+ double *xNew=x;
+ double check;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 1;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *funptr;
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+
+ if(getDoubleFromScilab(19,&check))
+ {
+ return true;
+ }
+ if (check==1)
+ {
+ return true;
+ }
+ else
+ {
+ if(getDoubleFromScilab(18,&obj))
+ {
+ sciprint("No obj value");
+ return 1;
+ }
+ obj_value=obj;
+
+ return true;
+ }
+}
+
+//get value of gradient of objective function at vector x.
+bool minconNLP::eval_grad_f(Index n, const Number* x, bool new_x, Number* grad_f)
+{
+ if (flag1_==0)
+ {
+ int* gradhessptr=NULL;
+ if(getFunctionFromScilab(2,&gradhessptr))
+ {
+ return 1;
+ }
+ double *xNew=x;
+ double t=1;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ createScalarDouble(pvApiCtx, 19,t);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 2;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *gradhessptr;
+ char name[20]="gradhess";
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+ }
+
+ else
+ {
+ int* gradptr=NULL;
+ if(getFunctionFromScilab(13,&gradptr))
+ {
+ return 1;
+ }
+ double *xNew=x;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 1;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *gradptr;
+ char name[20]="fGrad1";
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+ }
+
+ double* resg;
+ double check;
+ int x0_rows,x0_cols;
+ if(getDoubleFromScilab(19,&check))
+ {
+ return true;
+ }
+ if (check==1)
+ {
+ return true;
+ }
+ else
+ {
+ if(getDoubleMatrixFromScilab(18, &x0_rows, &x0_cols, &resg))
+ {
+ sciprint("No results");
+ return 1;
+ }
+
+
+ Index i;
+ for(i=0;i<numVars_;i++)
+ {
+ grad_f[i]=resg[i];
+ finalGradient_[i]=resg[i];
+ }
+ }
+ return true;
+}
+
+// This method sets initial values for required vectors . For now we are assuming 0 to all values.
+bool minconNLP::get_starting_point(Index n, bool init_x, Number* x,bool init_z, Number* z_L, Number* z_U,Index m, bool init_lambda,Number* lambda)
+{
+ assert(init_x == true);
+ assert(init_z == false);
+ assert(init_lambda == false);
+ if (init_x == true)
+ { //we need to set initial values for vector x
+ for (Index var=0;var<n;var++)
+ x[var]=varGuess_[var];
+ }
+
+ return true;
+}
+
+/*
+ * Return either the sparsity structure of the Hessian of the Lagrangian,
+ * or the values of the Hessian of the Lagrangian for the given values for
+ * x,lambda,obj_factor.
+*/
+
+bool minconNLP::eval_h(Index n, const Number* x, bool new_x,Number obj_factor, Index m, const Number* lambda,bool new_lambda, Index nele_hess, Index* iRow,Index* jCol, Number* values)
+{
+ if (values==NULL)
+ {
+ Index idx=0;
+ for (Index row = 0; row < numVars_; row++)
+ {
+ for (Index col = 0; col <= row; col++)
+ {
+ iRow[idx] = row;
+ jCol[idx] = col;
+ idx++;
+ }
+ }
+ }
+
+ else
+ {
+ double check;
+ //hessian of the objective function
+ if(flag2_==0)
+ {
+ int* gradhessptr=NULL;
+ if(getFunctionFromScilab(2,&gradhessptr))
+ {
+ return 1;
+ }
+ double *xNew=x;
+ double t=2;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ createScalarDouble(pvApiCtx, 19,t);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 2;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *gradhessptr;
+ char name[20]="gradhess";
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+
+ double* resTemph;
+ int x0_rows,x0_cols;
+ if(getDoubleFromScilab(19,&check))
+ {
+ return true;
+ }
+ if (check==1)
+ {
+ return true;
+ }
+ else
+ {
+ if(getDoubleMatrixFromScilab(18, &x0_rows, &x0_cols, &resTemph))
+ {
+ sciprint("No results");
+ return 1;
+ }
+
+ double* resh=(double*)malloc(sizeof(double)*n*n);
+ Index i;
+ for(i=0;i<numVars_*numVars_;i++)
+ {
+ resh[i]=resTemph[i];
+ }
+
+ //sum of hessians of constraints each multiplied by its own lambda factor
+ double* sum=(double*)malloc(sizeof(double)*n*n);
+ if(nonlinCon_!=0)
+ {
+
+ int* gradhessptr=NULL;
+ if(getFunctionFromScilab(2,&gradhessptr))
+ {
+ return 1;
+ }
+
+ double *xNew=x;
+ double t=4;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ createScalarDouble(pvApiCtx, 19,t);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 2;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *gradhessptr;
+ char name[20]="gradhess";
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+
+ double* resCh;
+ int xCh_rows,xCh_cols;
+ if(getDoubleFromScilab(19,&check))
+ {
+ return true;
+ }
+ if (check==1)
+ {
+ return true;
+ }
+ else
+ {
+ if(getDoubleMatrixFromScilab(18, &xCh_rows, &xCh_cols, &resCh))
+ {
+ sciprint("No results");
+ return 1;
+ }
+
+ Index j;
+
+ for(i=0;i<numVars_*numVars_;i++)
+ {
+ sum[i]=0;
+ for(j=0;j<nonlinCon_;j++)
+ sum[i]+=lambda[j]*resCh[i*(int)nonlinCon_+j];
+ }
+ }
+ }
+
+ else
+ {
+ for(i=0;i<numVars_*numVars_;i++)
+ sum[i]=0;
+ }
+
+ //computing the lagrangian
+ Index index=0;
+ for (Index row=0;row < numVars_ ;++row)
+ {
+ for (Index col=0; col <= row; ++col)
+ {
+ values[index++]=obj_factor*(resh[numVars_*row+col])+sum[numVars_*row+col];
+ }
+ }
+
+ free(resh);
+ free(sum);
+ }
+ }
+ else
+ {
+ int* hessptr=NULL;
+ if(getFunctionFromScilab(15,&hessptr))
+ {
+ return 1;
+ }
+ double *xNew=x;
+ double *lambdaNew=lambda;
+ double objfac=obj_factor;
+ createMatrixOfDouble(pvApiCtx, 18, 1, numVars_, xNew);
+ createScalarDouble(pvApiCtx, 19,objfac);
+ createMatrixOfDouble(pvApiCtx, 20, 1, numConstr_, lambdaNew);
+ int positionFirstElementOnStackForScilabFunction = 18;
+ int numberOfRhsOnScilabFunction = 3;
+ int numberOfLhsOnScilabFunction = 2;
+ int pointerOnScilabFunction = *hessptr;
+ char name[20]="lHess1";
+
+ C2F(scistring)(&positionFirstElementOnStackForScilabFunction,name,
+ &numberOfLhsOnScilabFunction,
+ &numberOfRhsOnScilabFunction,(unsigned long)strlen(name));
+
+ double* resCh;
+ int xCh_rows,xCh_cols;
+ if(getDoubleFromScilab(19,&check))
+ {
+ return true;
+ }
+ if (check==1)
+ {
+ return true;
+ }
+ else
+ {
+ if(getDoubleMatrixFromScilab(18, &xCh_rows, &xCh_cols, &resCh))
+ {
+ sciprint("No results");
+ return 1;
+ }
+
+ Index index=0;
+ for (Index row=0;row < numVars_ ;++row)
+ {
+ for (Index col=0; col <= row; ++col)
+ {
+ values[index++]=resCh[numVars_*row+col];
+ }
+ }
+ }
+ }
+
+
+ Index index=0;
+ for (Index row=0;row < numVars_ ;++row)
+ {
+ for (Index col=0; col <= row; ++col)
+ {
+ finalHessian_[n*row+col]=values[index++];
+ }
+ }
+
+ index=0;
+ for (Index col=0;col < numVars_ ;++col)
+ {
+ for (Index row=0; row <= col; ++row)
+ {
+ finalHessian_[n*row+col]=values[index++];
+ }
+ }
+ }
+
+ return true;
+}
+
+//returning the results
+void minconNLP::finalize_solution(SolverReturn status,Index n, const Number* x, const Number* z_L, const Number* z_U,Index m, const Number* g, const Number* lambda, Number obj_value,const IpoptData* ip_data,IpoptCalculatedQuantities* ip_cq)
+{
+ finalX_ = (double*)malloc(sizeof(double) * numVars_ * 1);
+ for (Index i=0; i<numVars_; i++)
+ {
+ finalX_[i] = x[i];
+ }
+
+ finalZl_ = (double*)malloc(sizeof(double) * numVars_ * 1);
+ for (Index i=0; i<n; i++)
+ {
+ finalZl_[i] = z_L[i];
+ }
+
+ finalZu_ = (double*)malloc(sizeof(double) * numVars_ * 1);
+ for (Index i=0; i<n; i++)
+ {
+ finalZu_[i] = z_U[i];
+ }
+
+ finalLambda_ = (double*)malloc(sizeof(double) * numConstr_ * 1);
+ for (Index i=0; i<m; i++)
+ {
+ finalLambda_[i] = lambda[i];
+ }
+
+ finalObjVal_ = obj_value;
+ status_ = status;
+ iter_ = ip_data->iter_count();
+}
+
+
+const double * minconNLP::getX()
+{
+ return finalX_;
+}
+
+const double * minconNLP::getGrad()
+{
+ return finalGradient_;
+}
+
+const double * minconNLP::getHess()
+{
+ return finalHessian_;
+}
+
+const double * minconNLP::getZl()
+{
+ return finalZl_;
+}
+
+const double * minconNLP::getZu()
+{
+ return finalZu_;
+}
+
+const double * minconNLP::getLambda()
+{
+ return finalLambda_;
+}
+
+double minconNLP::getObjVal()
+{
+ return finalObjVal_;
+}
+
+double minconNLP::iterCount()
+{
+ return (double)iter_;
+}
+
+int minconNLP::returnStatus()
+{
+ return status_;
+}
+
+}
+
+
+