示例#1
0
文件: options.cpp 项目: ZiiCee/OPTI
void Options::loadMultipliers (int n, int m, const mxArray* ptr, 
			       double*& zl, double*& zu, double*& lambda) {
  const mxArray* p;
  
  // Load the Lagrange multipliers associated with the lower bounds.
  p = mxGetField(ptr,0,"zl");
  if (p) {
    if (!mxIsDouble(p) || (int) mxGetNumberOfElements(p) != n)
      throw MatlabException("The initial point for the Lagrange multipliers associated with the lower bounds must be a double-precision array with one element for each optimization variable");
    zl = mxGetPr(p);
  } else
    zl = 0;

  // Load the Lagrange multipliers associated with the upper bounds.
  p = mxGetField(ptr,0,"zu");
  if (p) {
    if (!mxIsDouble(p) || (int) mxGetNumberOfElements(p) != n)
      throw MatlabException("The initial point for the Lagrange multipliers associated with the upper bounds must be a double-precision array with one element for each optimization variable");
    zu = mxGetPr(p);
  } else
    zu = 0;

  // Load the Lagrange multipliers associated with the equality and
  // inequality constraints.
  p = mxGetField(ptr,0,"lambda");
  if (p) {
    if (m>0 && (!mxIsDouble(p) || (int) mxGetNumberOfElements(p) != m) )
      throw MatlabException("The initial point for the Lagrange multipliers associated with the constraints must be a double-precision array with one element for each constraint");
    lambda = mxGetPr(p);
  } else
    lambda = 0;
}
示例#2
0
//Vertical Concatentation of two sparse matrices into a new matrix
void SparseMatrix::VertConcatenate(const SparseMatrix *obj, SparseMatrix *SpCat) {
    size_t ind = 0, i = 0, j = 0, k = 0;
    //Check dims
    if(this->w != obj->w)
        throw MatlabException("To vertically concatenate sparse matrices both must have the same number of columns");
    
    //Save Sizes
    int N = this->w;
    int M1 = this->h;
    int M2 = obj->h;
    
    //Check sizes
    if(height(*SpCat) != M1+M2)
        throw MatlabException("Wrong number of rows in resulting matrix after concatenation");
    if(width(*SpCat) != N)
        throw MatlabException("Wrong number of columns in resulting matrix after concatenation");
    if(SpCat->numelems() != this->numelems()+obj->numelems())
        throw MatlabException("Wrong number of nnzs in resulting matrix after concatenation");
    
    //Concatenate into new matrix
    SpCat->jc[0] = 0;
    for(i = 1; i <= (size_t)N; i++) {
        SpCat->jc[i] = this->jc[i] + obj->jc[i];
        for(j = 0; j < this->jc[i]-this->jc[i-1]; j++) {
            ind = this->jc[i-1]+j;
            SpCat->ir[k] = this->ir[ind];
            SpCat->x[k++] = this->x[ind];
        }
        for(j = 0; j < obj->jc[i]-obj->jc[i-1]; j++) {
            ind = obj->jc[i-1]+j;
            SpCat->ir[k] = obj->ir[ind]+M1;
            SpCat->x[k++] = obj->x[ind];
        }
    }
}
示例#3
0
文件: options.cpp 项目: ZiiCee/OPTI
TNLP::LinearityType* Options::loadVariableLinearity(int n, const mxArray *ptr)
{
    TNLP::LinearityType*   varlin = new TNLP::LinearityType[n];    //The return value
    const mxArray*         p = mxGetField(ptr,0,"var_lin");
    double*                types;
    
    if(p) {
        if (!mxIsDouble(p) || (mxGetNumberOfElements(p) != n))
            throw MatlabException("The var_lin array must be a double-precision array with n elements");
        
        //Get The Variable Types
        types = mxGetPr(p);
        //Assign them to TMINLP types
        for(int i = 0; i < n; i++) {
            switch((int)types[i])
            {
                case 0:
                    varlin[i] = TNLP::NON_LINEAR;
                    break;
                case 1:
                    varlin[i] = TNLP::LINEAR;
                    break;
                default:
                    throw MatlabException("The var_lin array must only contain 0 (nonlinear), or 1 (linear)!");
                    break;
            }
        } 
    }
    else {
        for(int i = 0; i < n; i++)
            varlin[i] = TNLP::NON_LINEAR; //assume all nonlinear
    }
        
    return varlin;
}
示例#4
0
// Function definitions.
// -----------------------------------------------------------------
double* getMatlabMatrixDouble (const mxArray* ptr) {
  if (mxGetNumberOfDimensions(ptr) != 2)
    throw MatlabException("Matlab array must be a matrix");
  if (!mxIsDouble(ptr))
    throw MatlabException("Matlab array must be of type double");
  return mxGetPr(ptr);
}
示例#5
0
  void MatlabJournal::PrintfImpl (EJournalCategory category, 
				  EJournalLevel level, const char* pformat, 
				  va_list ap) {
    const int maxStrLen = 1024;
    char      s[maxStrLen];
#ifdef HAVE_VSNPRINTF
# ifdef HAVE_VA_COPY
    va_list apcopy;
    va_copy(apcopy, ap);
    if (vsnprintf(s,maxStrLen,pformat,apcopy) >= maxStrLen)
      throw MatlabException("String buffer it too short for all the characters to be printed to MATLAB console");
    va_end(apcopy);
# else
    if (vsnprintf(s,maxStrLen,pformat,ap) >= maxStrLen)
      throw MatlabException("String buffer it too short for all the characters to be printed to MATLAB console");
# endif
#else
# ifdef HAVE__VSNPRINTF
#  ifdef HAVE_VA_COPY
    va_list apcopy;
    va_copy(apcopy, ap);
    if (_vsnprintf(s,maxStrLen,pformat,apcopy) >= maxStrLen)
      throw MatlabException("String buffer it too short for all the characters to be printed to MATLAB console");
    va_end(apcopy);
#  else
    if (_vsnprintf(s,maxStrLen,pformat,ap) >= maxStrLen)
      throw MatlabException("String buffer it too short for all the characters to be printed to MATLAB console");
#  endif
# else
    vsprintf(s,pformat,ap);
# endif
#endif
    mexPrintf(s);
    mexEvalString("drawnow;"); //flush draw buffer
  }
示例#6
0
// Function definitions for class MatlabString.
// -----------------------------------------------------------------
MatlabString::MatlabString (const mxArray* ptr) {
  s = 0;

  // Check to make sure the Matlab array is a string.
  if (!mxIsChar(ptr))
    throw MatlabException("Matlab array must be a string (of type CHAR)");
  
  // Get the string passed as a Matlab array.
  s = mxArrayToString(ptr);
  if (s == 0)
    throw MatlabException("Unable to obtain string from Matlab array");
}
示例#7
0
// Function definitions for clas Multipliers.
// -----------------------------------------------------------------
Multipliers::Multipliers (const mxArray*& ptr) {
  mxArray* p;

  // First check to see whether the MATLAB array is a structure
  // array. If not, throw an exception.
  if (!mxIsStruct(ptr))
    throw MatlabException("Matlab array must be a structure array");
    
  // Get the multipliers corresponding to the lower bounds on the
  // optimization variables.
  p = mxGetField(ptr,0,lowerBoundMultipliersLabel);
  if (p == 0)
    throw MatlabException("MATLAB multipliers input does not have the \
correct fields");
  zl = new Matrix(p);

  // Get the multipliers corresponding to the upper bounds on the
  // optimization variables.
  p = mxGetField(ptr,0,upperBoundMultipliersLabel);
  if (p == 0)
    throw MatlabException("MATLAB multipliers input does not have the \
correct fields");
  zu = new Matrix(p);  

  // Get the multipliers corresponding to the upper bounds on the
  // optimization variables.
  p = mxGetField(ptr,0,constraintMultipliersLabel);
  if (p == 0)
    throw MatlabException("MATLAB multipliers input does not have the \
correct fields");
  lambda = new Matrix(p);    
}
示例#8
0
文件: options.cpp 项目: ZiiCee/OPTI
double* Options::loadUpperBounds(int n, const mxArray* ptr, double posinfty) {
  double* ub;  // The return value.

  // Load the upper bounds on the variables.
  const mxArray* p = mxGetField(ptr,0,"ub");
  if (p) {

    // Load the upper bounds and check to make sure they are valid.
    int N = Iterate::getMatlabData(p,ub);
    if (N != n)
      throw MatlabException("Upper bounds array must have one element for each optimization variable");

    // Convert MATLAB's convention of infinity to BONMIN's convention
    // of infinity.
    for (int i = 0; i < n; i++)
      if (mxIsInf(ub[i]))
	ub[i] = posinfty;
  } else {

    // If the upper bounds have not been specified, set them to
    // positive infinity.
    ub = new double[n];
    for (int i = 0; i < n; i++)
      ub[i] = posinfty;
  }

  return ub;
}
示例#9
0
文件: options.cpp 项目: ZiiCee/OPTI
TNLP::LinearityType* Options::loadConstraintLinearity(int m, int nlin, int nnlin, const mxArray *ptr)
{
    TNLP::LinearityType*   conslin = new TNLP::LinearityType[m];    //The return value
    const mxArray*         p = mxGetField(ptr,0,"cons_lin");
    double*                types;
    
    if(m != (nlin+nnlin))
        throw MatlabException("The total number of constraints does not equal #lin + #nlin");
    
    if(p) {
        if (!mxIsDouble(p) || (mxGetNumberOfElements(p) != m))
            throw MatlabException("The cons_lin array must be a double-precision array with m elements");
        
        //Get The Variable Types
        types = mxGetPr(p);
        //Assign them to TMINLP types
        for(int i = 0; i < m; i++) {
            //Let the user decide for callback constraints what is nonlinear and linear
            if(i < nnlin) {
                switch((int)types[i])
                {
                    case 0:
                        conslin[i] = TNLP::NON_LINEAR;
                        break;
                    case 1:
                        conslin[i] = TNLP::LINEAR;
                        break;
                    default:
                        throw MatlabException("The cons_lin array must only contain 0 (nonlinear), or 1 (linear)!");
                        break;
                }
            }
            else
                conslin[i] = TNLP::LINEAR; //force linear constraints (via A) to be identified as linear
        } 
    }
    else {
        //Fill in based on nlin and nnlin (noting nonlinear constraints come first based on our concatenation)
        for(int i = 0; i < nnlin; i++)
            conslin[i] = TNLP::NON_LINEAR; 
        for(int i = nnlin; i < (nnlin + nlin); i++)
            conslin[i] = TNLP::LINEAR;
    }
        
    return conslin;
}
示例#10
0
文件: options.cpp 项目: ZiiCee/OPTI
TMINLP::VariableType* Options::loadVariableTypes(int n, const mxArray *ptr)
{
    TMINLP::VariableType*   vartype = new TMINLP::VariableType[n];    //The return value
    const mxArray*          p = mxGetField(ptr,0,"var_type");
    double*                 types;
    
    if(p) {
        if (!mxIsDouble(p) || (mxGetNumberOfElements(p) != n))
            throw MatlabException("The var_type array must be a double-precision array with n elements");
        
        //Get The Variable Types
        types = mxGetPr(p);
        //Assign them to TMINLP types
        for(int i = 0; i < n; i++) {
            switch((int)types[i])
            {
                case -1:
                    vartype[i] = TMINLP::BINARY; //doesn't seem to work?
                    break;
                case 0:
                    vartype[i] = TMINLP::CONTINUOUS;
                    break;
                case 1:
                    vartype[i] = TMINLP::INTEGER;
                    break;
                default:
                    throw MatlabException("The var_type array must only contain -1 (binary), 0 (continous) or 1 (integer)!");
                    break;
            }
        } 
    }
    else {
        for(int i = 0; i < n; i++)
            vartype[i] = TMINLP::CONTINUOUS; //assume all continuous
    }
        
    return vartype;
}
示例#11
0
文件: iterate.cpp 项目: ZiiCee/OPTI
// Function definitions for class Iterate.
// -----------------------------------------------------------------
Iterate::Iterate (mxArray* ptr) 
  : nv(0), ptr(ptr) {
  const mxArray* p = 0;  // Pointer to a MATLAB array.

  // Compute the number of optimization variables.
  if (mxIsCell(ptr)) {

    // The MATLAB array is a cell array. Repeat for each cell.
    int n = mxGetNumberOfElements(ptr);
    for (int i = 0; i < n; i++) {
      p = mxGetCell(ptr,i);  // Get the ith cell.
      if (!mxIsDouble(p) || mxIsComplex(ptr) || mxIsSparse(ptr))
        throw MatlabException("The initial iterate must be either a REAL DENSE array in DOUBLE precision, or a cell array in which each cell is a REAL DENSE array in DOUBLE precision");     
      nv += mxGetNumberOfElements(p);
    }
  } else {
    
    // The MATLAB array should be a numeric array.
    if (!mxIsDouble(ptr) || mxIsComplex(ptr) || mxIsSparse(ptr))
        throw MatlabException("The initial iterate must be either a REAL DENSE array in DOUBLE precision, or a cell array in which each cell is a REAL DENSE array in DOUBLE precision");
    nv = mxGetNumberOfElements(ptr);
  }
}
示例#12
0
//Sparse Matrix*Vector using MATLAB (assumes constant structure as per linear A)
void SparseMatrix::SpMatrixVec(const Iterate& xin, double *c) {
    //Sizes
    int M = this->h;
    int N = this->w;
    //Check dims    
    if(w != numvars(xin))
        throw MatlabException("To multiply a sparse matrix by a vector the number of columns in the matrix must equal the number of rows in the vector");
    
    if(linA == NULL)
        throw MatlabException("Error with sparse matrix linear A memory");
    
    //Check if existing vec_c memory exists, if not, create it and assign pointers at the same time
    if(vec_c == NULL) {    
        prhs[0] = this->linA;
        prhs[1] = mxCreateDoubleMatrix(N,1,mxREAL);
        vec_c = mxCreateDoubleMatrix(M,1,mxREAL);
    }
    //Copy in current x iterate to MATLAB memory
    xin.copyto(mxGetPr(prhs[1]));
    //Call Matlab to evaluate sparse Matrix * Vector
    try {
        mexCallMATLAB(1,&vec_c,2,prhs,"mtimes");
    }
    catch (std::exception ME) {
        const char* what = ME.what();
        if (what) {
            mexPrintf("Matlab exception:\n%s", what);      
            throw MatlabException("There was an error when executing the linear constraints");
        }
    }
    catch (...) {
        throw MatlabException("There was an error when executing the linear constraints");
    }
    //Copy results to output c pointer
    memcpy(c,mxGetPr(vec_c),M*sizeof(double));
}
示例#13
0
文件: options.cpp 项目: ZiiCee/OPTI
int Options::loadConstraintBounds (const mxArray* ptr, double*& cl, 
				   double*& cu, double neginfty,
				   double posinfty, int &lin, int &nlin) {
  int m = 0;  // The return value is the number of constraints.
  int tm;
  //Defaults
  lin = 0; nlin = 0;

  // LOAD CONSTRAINT BOUNDS.
  // If the user has specified constraints bounds, then she must
  // specify *both* the lower and upper bounds.
  const mxArray* pl = mxGetField(ptr,0,"cl");
  const mxArray* pu = mxGetField(ptr,0,"cu");
  const mxArray* prl = mxGetField(ptr,0,"rl"); //linear constraint bounds
  const mxArray* pru = mxGetField(ptr,0,"ru");
  if (pl || pu || prl || pru) {

    // Check to make sure the constraint bounds are valid.
    if ((!pl ^ !pu) || (!prl ^ !pru))
      throw MatlabException("You must specify both lower and upper bounds on the constraints");
    if (pl && (!mxIsDouble(pl) || !mxIsDouble(pu) || (mxGetNumberOfElements(pl) != mxGetNumberOfElements(pu))))
      throw MatlabException("The nonlinear constraints lower and upper bounds must both be double-precision arrays with the same number of elements");
    if (prl && (!mxIsDouble(prl) || !mxIsDouble(pru) || (mxGetNumberOfElements(prl) != mxGetNumberOfElements(pru))))
      throw MatlabException("The linear constraints lower and upper bounds must both be double-precision arrays with the same number of elements");
    // Get the number of constraints.
    if(pl && prl) {
        lin = (int)mxGetNumberOfElements(prl);
        nlin = (int)mxGetNumberOfElements(pl);
        m = lin+nlin;
    }
    else if(pl) {
        lin = 0;
        nlin = (int)mxGetNumberOfElements(pl);
        m = nlin;        
    }
    else {
        lin = (int)mxGetNumberOfElements(prl);
        nlin = 0;
        m = lin;
    }

    // Load the lower bounds on the constraints and convert MATLAB's
    // convention of infinity to IPOPT's convention of infinity.
    cl = new double[m];
    cu = new double[m];
    if(pl && prl) {
        tm = (int)mxGetNumberOfElements(pl);
        copymemory(mxGetPr(pl),cl,tm);
        copymemory(mxGetPr(pu),cu,tm);
        copymemory(mxGetPr(prl),&cl[tm],(int)mxGetNumberOfElements(prl));
        copymemory(mxGetPr(pru),&cu[tm],(int)mxGetNumberOfElements(pru));
    }
    else if(pl) {
        copymemory(mxGetPr(pl),cl,m);
        copymemory(mxGetPr(pu),cu,m);
    }
    else {
        copymemory(mxGetPr(prl),cl,m);
        copymemory(mxGetPr(pru),cu,m);
    }

    // Convert MATLAB's convention of infinity to IPOPT's convention
    // of infinity.
    for (int i = 0; i < m; i++) {
      if (mxIsInf(cl[i])) cl[i] = neginfty;
      if (mxIsInf(cu[i])) cu[i] = posinfty;
    }
  }

  return m;
}
示例#14
0
// Function definitions. 
// -----------------------------------------------------------------
void mexFunction (int nlhs, mxArray *plhs[], 
		  int nrhs, const mxArray *prhs[]) 
  try {

    // Check to see if we have the correct number of input and output
    // arguments.
    if (nrhs < minNumInputArgs)
      throw MatlabException("Incorrect number of input arguments");

    // Get the starting point for the variables. This is specified in
    // the first input argument. The variables must be either a single
    // matrix or a cell array of matrices.
    int k = 0;  // The index of the current input argument.
    ArrayOfMatrices x0(prhs[k++]);

    // Create the output, which stores the solution obtained from
    // running IPOPT. There should be as many output arguments as cell
    // entries in X.
    if (nlhs != x0.length())
      throw MatlabException("Incorrect number of output arguments");
    ArrayOfMatrices x(plhs,x0);

    // Load the lower and upper bounds on the variables as
    // ArrayOfMatrices objects. They should have the same structure as
    // the ArrayOfMatrices object "x".
    ArrayOfMatrices lb(prhs[k++]);
    ArrayOfMatrices ub(prhs[k++]);

    // Check to make sure the bounds make sense.
    if (lb != x || ub != x)
      throw MatlabException("Input arguments LB and UB must have the same \
structure as X");

    // Get the Matlab callback functions.
    MatlabString objFunc(prhs[k++]);
    MatlabString gradFunc(prhs[k++]);

    // Get the auxiliary data.
    const mxArray* auxData;
    const mxArray* ptr = prhs[k++];
    if (nrhs > 5) {
      if (mxIsEmpty(ptr))
	auxData = 0;
      else
	auxData = ptr;
    }
    else
      auxData = 0;

    // Get the intermediate callback function.
    MatlabString* iterFunc;
    ptr = prhs[k++];
    if (nrhs > 6) {
      if (mxIsEmpty(ptr))
	iterFunc = 0;
      else
	iterFunc = new MatlabString(ptr);
    }
    else
      iterFunc = 0;

    // Set the options for the L-BFGS algorithm to their defaults.
    int    maxiter = defaultmaxiter;
    int    m       = defaultm;
    double factr   = defaultfactr;
    double pgtol   = defaultpgtol;

    // Process the remaining input arguments, which set options for
    // the IPOPT algorithm.
    while (k < nrhs) {

      // Get the option label from the Matlab input argument.
      MatlabString optionLabel(prhs[k++]);

      if (k < nrhs) {

	// Get the option value from the Matlab input argument.
	MatlabScalar optionValue(prhs[k++]);
	double       value = optionValue;

	if (!strcmp(optionLabel,"maxiter"))
	  maxiter = (int) value;
	else if (!strcmp(optionLabel,"m"))
	  m = (int) value;
	else if (!strcmp(optionLabel,"factr"))
	  factr = value / mxGetEps();
	else if (!strcmp(optionLabel,"pgtol"))
	  pgtol = value;
	else {
	  if (iterFunc) delete iterFunc;
	  throw MatlabException("Nonexistent option");
	}
      }
    }    

    // Create a new instance of the optimization problem.
    x = x0;
    MatlabProgram program(x,lb,ub,&objFunc,&gradFunc,iterFunc,
			  (mxArray*) auxData,m,maxiter,factr,pgtol);    

    // Run the L-BFGS-B solver.
    SolverExitStatus exitStatus = program.runSolver();
    if (exitStatus == abnormalTermination) {
      if (iterFunc) delete iterFunc;
      throw MatlabException("Solver unable to satisfy convergence \
criteria due to abnormal termination");
    }
    else if (exitStatus == errorOnInput) {