Exemplo n.º 1
0
/* Function CheckInputSampleTimes ==============================================
 * Abstract:
 *	We know both input sample times, now verify that the make sense
 *	(see top of file).
 */
static void CheckInputSampleTimes(SimStruct *S)
{
    real_T enableTs = ssGetInputPortSampleTime(S, ENABLE_IPORT);
    real_T signalTs = ssGetInputPortSampleTime(S, SIGNAL_IPORT);
    int   enableTid = ssGetInputPortSampleTimeIndex(S,ENABLE_IPORT);

    if (enableTs != CONTINUOUS_SAMPLE_TIME) {
        /* signal must be a multiple of the enable */
        real_T k        = floor(signalTs/enableTs+0.5);
        
        if (k < 1.0 ||
            fabs(k - signalTs/enableTs) > mxGetEps()*128.0) {
            ssSetErrorStatus(S, "Sample time of source signal (port 2) "
                             "must be a positive multiple of enable "
                             "(port 1) signal");
            return;
        }
    } 

    if (enableTid == CONSTANT_TID) {
        ssSetErrorStatus(S, "Constant sample time is not allowed "
                         "at enable port (port 1)");
        return;
    }

} /* end CheckInputSampleTimes */
Exemplo n.º 2
0
// Function definitions for class L-BFGS-B Program.
// -----------------------------------------------------------------
lbfgsb_program::lbfgsb_program (user_function_data *fun, user_function_data *grad, iter_fun_data *iterF, size_t ndec,
                                double *in_lb, double *in_ub, double *in_x0, double *xfinal,
                                double *fval, double *iter, int printLevel, int maxIter, int maxFeval, double maxtime, double ftol, int m, double pgtol)

    : Program((int)ndec,0,0,0,0,m,maxIter,maxFeval,maxtime,ftol/mxGetEps(),pgtol) //Program Constructor
{
    //Create local copies of input args (we will change them)
    x     = new double[ndec];
    lb    = new double[ndec];
    ub    = new double[ndec];
    for(int i = 0; i < ndec; i++) {
        lb[i] = in_lb[i];
        ub[i] = in_ub[i];
        x[i] = in_x0[i];
    }
    //Solver bound types
    btype = new int[ndec];
    // Set the bound types.
    for (int i = 0; i < ndec; i++)
        btype[i] = getBoundType(lb[i],ub[i]);
    //Save size
    this->ndec = ndec;
    //Save print stuff
    this->printLevel = printLevel;

    //Save Function Information
    this->fun = fun;
    this->grad = grad;
    this->iterF = iterF;

    //Assign Output Variables
    this->xfinal = xfinal;

    this->noFevals = 0;
}
Exemplo n.º 3
0
/*************************************************************************
 * main
 *************************************************************************/
void dijkstra1( long int n, long int s, double *D1, double *P1, double *Gpr, int *Gir, int *Gjc) {
  int      finished;
  long int i, startInd, endInd, whichNeigh, nDone, closest;
  double   closestD, arcLength, INF, SMALL, oldDist;
  HeapNode *A, *hnMin, hnTmp; FibHeap *heap;
  INF=mxGetInf(); SMALL=mxGetEps();
  
  // setup heap
  if ((heap = new FibHeap) == NULL || (A = new HeapNode[n+1]) == NULL )
    mexErrMsgTxt( "Memory allocation failed-- ABORTING.\n" );
  heap->ClearHeapOwnership();
  
  // initialize
  for (i=0; i<n; i++) {
    if (i!=s) A[ i ] = (double) INF; else A[ i ] = (double) SMALL;
    if (i!=s) D1[ i ] = (double) INF; else D1[ i ] = (double) SMALL;
    P1[ i ] = -1;
    heap->Insert( &A[i] );
    A[ i ].SetIndexValue( (long int) i );
  }
  
  // Insert 0 then extract it, which will balance heap
  heap->Insert(&hnTmp); heap->ExtractMin();
  
  // loop over nonreached nodes
  finished = nDone = 0;
  while ((finished==0) && (nDone < n)) {
    hnMin = (HeapNode *) heap->ExtractMin();
    closest  = hnMin->GetIndexValue();
    closestD = hnMin->GetKeyValue();
    if ((closest<0) || (closest>=n))
      mexErrMsgTxt( "Minimum Index out of bound..." );
    D1[ closest ] = closestD;
    if (closestD == INF) finished=1; else {
      // relax all nodes adjacent to closest
      nDone++;
      startInd = Gjc[ closest   ];
      endInd   = Gjc[ closest+1 ] - 1;
      if( startInd!=endInd+1 )
        for( i=startInd; i<=endInd; i++ ) {
        whichNeigh = Gir[ i ];
        arcLength = Gpr[ i ];
        oldDist = D1[ whichNeigh ];
        if ( oldDist > ( closestD + arcLength )) {
          D1[ whichNeigh ] = closestD + arcLength;
          P1[ whichNeigh ] = closest + 1;
          hnTmp = A[ whichNeigh ];
          hnTmp.SetKeyValue( closestD + arcLength );
          heap->DecreaseKey( &A[ whichNeigh ], hnTmp );
        }
        }
    }
  }
  
  // cleanup
  delete heap; delete[] A;
}
Exemplo n.º 4
0
/**
 * @brief Read in the option possible_words.
 * Reads the option possible_words, converting string data into its numerical
 * representation, and returning a flag to indicate the status.
 */
int ReadOptionPossibleWords(const mxArray *in,const char *field_name,double *member)
{
  /* declare local variables */
  mxArray *tmp;
  double num;
  int stringLength, flag, i;
  char *str;

  tmp = mxGetField(in,0,field_name);
  if((tmp==NULL) || mxIsEmpty(tmp)) /* field is empty */
    flag = 0;
  else
  {
    if(mxIsChar(tmp)) /* field is string */
    {
      /* copy string and set to lowercase */
      stringLength = mxGetNumberOfElements(tmp) + 1;
      str = mxCalloc(stringLength,sizeof(char));
      if(mxGetString(tmp,str,stringLength)!=0)
        mexErrMsgIdAndTxt("STAToolkit:ReadOptionPossibleWords:invalidValue","Could not convert string data.");
      for(i=0;str[i];i++)
        str[i] = tolower(str[i]);

      /* use string to set member value */
      flag = 1;
      if(strcmp(str,"recommended")==0)
        *member = (double)(-1.0);
      else if(strcmp(str,"unique")==0)
        *member = (double)(-2.0);
      else if(strcmp(str,"total")==0)
        *member = (double)(-3.0);
      else if(strcmp(str,"possible")==0)
        *member = (double)(-4.0);
      else if(strcmp(str,"min_tot_pos")==0)
        *member = (double)(-5.0);
      else if(strcmp(str,"min_lim_tot_pos")==0)
        *member = (double)(-6.0);
      else
      {
        mexWarnMsgIdAndTxt("STAToolkit:ReadOptionPossibleWords:invalidValue","Unrecognized option \"%s\" for possible_words. Using default \"recommended\".",str);
        *member = (double)(-1.0);
      }
    }
    else /* field is scalar */
    {
      flag = 2;
      num = mxGetScalar(tmp);
      if(num==mxGetInf())
        *member = (double)(0.0);
      else if((num<1.0) || (fmod(num,1.0)>mxGetEps()))
        mexErrMsgIdAndTxt("STAToolkit:ReadOptionPossibleWords:invalidValue","possible_words must be a positive integer. Current value is %f.",num);
      else
        *member = num;
    }
  }
  return flag;
}
Exemplo n.º 5
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  size_t NN, X_sum, P, D, Lp1;
  mwSize K;
  double *X_inds, *X_vals;
  double *lPhi, *lTheta, *lPsi, *W;
  mxArray *Km;
  double *inds, *vals, *num_nz;
  double eps;

  if(nlhs != NOUTPUTS)
    mexErrMsgTxt("Usage: see \"help sample_Xpn_kernel_meat\"");
  if(nrhs != NINPUTS)
    mexErrMsgTxt("Usage: see \"help sample_Xpn_kernel_meat\"");

  // Grab inputs
  X_inds = mxGetPr(prhs[0]);
  X_vals = mxGetPr(prhs[1]);
  lPhi = mxGetPr(prhs[2]);
  lTheta = mxGetPr(prhs[3]);
  lPsi = mxGetPr(prhs[4]);
  W = mxGetPr(prhs[6]);
  X_sum = mxGetScalar(prhs[7]);
  Km = (mxArray*)prhs[5]; // Cell array

  NN = mxGetM(prhs[0]);
  P = mxGetM(prhs[2]);
  K = mxGetN(prhs[2]);
  D = mxGetN(prhs[4]);
  Lp1 = mxGetM(prhs[6]);
  
  eps = mxGetEps();
  
  // Allocate output
  plhs[0] = mxCreateDoubleMatrix(X_sum, 3, mxREAL);
  plhs[1] = mxCreateDoubleMatrix(X_sum, 1, mxREAL);
  plhs[2] = mxCreateDoubleMatrix(1, 1, mxREAL);
  inds = mxGetPr(plhs[0]);
  vals = mxGetPr(plhs[1]);
  num_nz = mxGetPr(plhs[2]);
  
  // Pre-allocate scratch arrays
  unsigned int topic_sz = K*sizeof(double);
  double *zeta = (double*)mxMalloc(topic_sz);
  double *cump_scr = (double*)mxMalloc(topic_sz);
  double *mnr = (double*)mxMalloc(topic_sz);
  
  // log-thinning activation function, not Phi as in the topics
  // Change this to just a double*
  //mxArray *lphi = mxCreateDoubleMatrix(D, K, mxREAL);
  //mxArray *res;
  double *A, *lphi;
  char *chn = "N";  // don't transpose for dgemv
  double onef = 1.0, zerof = 0.0; // alpha, beta in dgemv
  size_t onei = 1; // incx in dgemv
  
  lphi = mxMalloc(D*K*sizeof(double));
  //lphi_ptr = mxGetPr(lphi);
  
  //printf("Computing lphi...\n");
  //printf(" K: %d\n", K);
  
  // Compute phi{k} = p(Znk = 1) for all k here (Each one is a matrix)
  for (int k = 0; k < K; k++)
  {
    //printf("k: %d ", k);
    A = mxGetPr(mxGetCell(Km, k));
    //printf("Before dgemv..");
    dgemv(chn, &D, &Lp1, &onef, A, &D, &W[k*Lp1], &onei, &zerof, &lphi[k*D], &onei); 
    //dgemv(chn, &D, &Lp1, &onef, A, &D, &W[k*Lp1], &onei, &zerof, &lphi_ptr[k*D], &onei); 
    //printf("after dgemv\n");
  }
  
  //printf("Sampling...\n");
  // Probit each entry and take log
  normcdf(lphi, D*K);
  for (int ii = 0; ii < D*K; ii++)              
    lphi[ii] = log(lphi[ii] + eps);
  
  // main loop
  unsigned int cur_idx = 0;
  unsigned int noff = X_sum;
  unsigned int koff = 2*X_sum;
  for(int ii = 0; ii < NN; ii++)
  {

    // Get indices and data (convert to 0-based)
    unsigned int p = X_inds[ii] - 1;
    unsigned int n = X_inds[ii + NN] - 1; // These arrays have NN rows
    unsigned int xx = X_vals[ii];

    // Construct probability
    double zeta_max = DBL_MIN;
    memset(zeta,0,topic_sz);
    for(int k = 0; k < K; k++)
    {
      // When we say N we mean D
      // lZnk is NxK and lPsi is KxN so we index them backwards
      // lphi is NxK and contains the log-thinning probabilities
      //zeta[k] = lPhi[p + k*P] + lTheta[k] + lZnk[n + k*D] + lPsi[k + n*K];
      zeta[k] = lPhi[p + k*P] + lTheta[k] + lphi[n + k*D] + lPsi[k + n*K];
      if(zeta[k] > zeta_max)
        zeta_max = zeta[k];
    }
    for(int k = 0; k < K; k++)
    {
      zeta[k] -= zeta_max;
      zeta[k] = exp(zeta[k]);
    }
    double zeta_sum = sum(zeta, K);
    for(int k = 0; k < K; k++)
      zeta[k] /= zeta_sum;

//     for(int k = 0; k < K; k++)
//       printf("%.2f,", zeta[k]);
//     printf("\n");
    
    // Split up observed counts into topics and add to output
    if(xx > 1)
    {
      multirnd(mnr, xx, zeta, K, cump_scr, eps);
      for(int k = 0; k < K; k++)
      {
        if(mnr[k] > 0)
        {
          inds[cur_idx] = p + 1;
          inds[cur_idx + noff] = n + 1;
          inds[cur_idx + koff] = k + 1; // +1 b/c k is index
          vals[cur_idx] = mnr[k];
          cur_idx++;
        }
      }
    }
    else
    {
      // Result of below is 1-based, so don't add 1 to kk below
      double kk = discrnd(zeta, K, cump_scr, eps);
      inds[cur_idx] = p + 1;
      inds[cur_idx + noff] = n + 1;
      inds[cur_idx + koff] = kk;
      vals[cur_idx] = 1;
      cur_idx++;
    }

  }

  // Free scratch memory
  mxFree(zeta);
  mxFree(cump_scr);
  mxFree(mnr);
  mxFree(lphi);

  *num_nz = cur_idx; // cur_idx has been incr. 1 beyond already

}
Exemplo n.º 6
0
void dodijk_sparse( 
             long int M,
             long int N,
             long int S,
             double   *D,
             double   *sr,
             int      *irs,
             int      *jcs,
             HeapNode *A,
             FibHeap  *theHeap  )
{
   int      finished;
   long int i,startind,endind,whichneighbor,ndone,index,switchwith,closest,closesti;
   long int *INDICES;
   double   closestD,arclength; 
   double   INF,SMALL,olddist;
   HeapNode *Min;
   HeapNode Temp;

   INF   = mxGetInf();
   SMALL = mxGetEps();

   /* initialize */
   for (i=0; i<M; i++) 
   {
      if (i!=S) A[ i ] = (double) INF; else A[ i ] = (double) SMALL;
      if (i!=S) D[ i ] = (double) INF; else D[ i ] = (double) SMALL;
	  theHeap->Insert( &A[i] );
      A[ i ].SetIndexValue( (long int) i );
   }
   

   // Insert 0 then extract it.  This will cause the
   // Fibonacci heap to get balanced.

   theHeap->Insert(&Temp);
   theHeap->ExtractMin();

   /*theHeap->Print();
   for (i=0; i<M; i++)
   {
      closest = A[ i ].GetIndexValue();
      closestD = A[ i ].GetKeyValue();
      mexPrintf( "Index at i=%d =%d  value=%f\n" , i , closest , closestD );
   }*/   

   /* loop over nonreached nodes */
   finished = 0;
   ndone    = 0;
   while ((finished==0) && (ndone < M))
   {
      //if ((ndone % 100) == 0) mexPrintf( "Done with node %d\n" , ndone );

      Min = (HeapNode *) theHeap->ExtractMin();
      closest  = Min->GetIndexValue();
      closestD = Min->GetKeyValue();

      if ((closest<0) || (closest>=M)) mexErrMsgTxt( "Minimum Index out of bound..." );

      //theHeap->Print();
      //mexPrintf( "EXTRACTED MINIMUM  NDone=%d S=%d closest=%d closestD=%f\n" , ndone , S , closest , closestD );
      //mexErrMsgTxt( "Exiting..." );

      D[ closest ] = closestD;

      if (closestD == INF) finished=1; else
      {
         /* add the closest to the determined list */
         ndone++;         
          
         /* relax all nodes adjacent to closest */
         startind = jcs[ closest   ];
         endind   = jcs[ closest+1 ] - 1;

         if (startind!=endind+1)
         for (i=startind; i<=endind; i++)
         {
            whichneighbor = irs[ i ];
            arclength = sr[ i ];
            olddist   = D[ whichneighbor ];

            //mexPrintf( "INSPECT NEIGHBOR #%d  olddist=%f newdist=%f\n" , whichneighbor , olddist , closestD+arclength );            

            if ( olddist > ( closestD + arclength ))
            {
               D[ whichneighbor ] = closestD + arclength;

	           Temp = A[ whichneighbor ];
	           Temp.SetKeyValue( closestD + arclength );
               theHeap->DecreaseKey( &A[ whichneighbor ], Temp );

               //mexPrintf( "UPDATING NODE #%d  olddist=%f newdist=%f\n" , whichneighbor , olddist , closestD+arclength );
            }
         }

      }
      
   }
}
Exemplo n.º 7
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	/* Declare Variables */
	char *ch1 = "V", *ch2 = "I", *ch3 = "L";	
	void *A, *W, *Z, *work;
	double ABSTOLD = 0.0, VLD = 0.0, VUD = 0.0;
	float ABSTOLF = 0.0, VLF = 0.0, VUF = 0.0;
	
#ifdef MWSIZE
	mwSize N, *iwork, *ifail, info = 0, numElem, optional, IL, IU, M, num_eigs, isDouble = 1;
#else
	int N, *iwork, *ifail, info = 0, numElem, optional, IL, IU, M, num_eigs, isDouble = 1;
#endif	

	/****** Do Error check *************/
	if (nrhs != 4) 
	{
		mexErrMsgTxt("icatb_eig_symm_sel function accepts four input arguments.\nThe usage of the function is [eigen_vectors, eigen_values] = icatb_eig_symm_sel(A, N, num_eigs, opt);\nwhere A is the lower triangular matrix without zeros entered as a vector, N is the original dimension, num_eigs is the number of eigen values and opt is parameter to operate on copy of the matrix or the original array.");
	}
	
#ifdef MWSIZE	
	/* Inputs Matrix (A), order (N), number of eigen values (num_eigs), parameter (opt) to operate on copy or original matrix*/   
	numElem = (mwSize) mxGetNumberOfElements(prhs[0]);  
	N = (mwSize) mxGetScalar(prhs[1]); 
	num_eigs = (mwSize) mxGetScalar(prhs[2]);	
	/* Parameter for using the copy or original array to do operations*/	
	optional = (mwSize) mxGetScalar(prhs[3]);
#else
	numElem = (int) mxGetNumberOfElements(prhs[0]);
	N = (int) mxGetScalar(prhs[1]);
	num_eigs = (int) mxGetScalar(prhs[2]);	
	optional = (int) mxGetScalar(prhs[3]);	
#endif	
		
	
	if (numElem != (N*(N + 1)/2))
	{
		mexErrMsgTxt("Number of elements of input matrix (A) must be equal to N*(N+1)/2"); 
	}
		
	
	if (num_eigs > N)
	{
		mexErrMsgTxt("Number of eigen values desired is greater than the number of rows of matrix");
	}
	
	if (nlhs > 2) 
	{
		mexErrMsgTxt("Maximum allowed output arguments is 2."); 
	}    
	/********* End for doing error check *********/
	
	/* Eigen values desired */
	IL = N - num_eigs + 1;
	IU = N; 	
	
	/* Check isdouble */
	if (mxIsDouble(prhs[0]))
	{		
		isDouble = 1;
		
		if (optional == 1) 
		{			
			A = (void *) mxCalloc(numElem, sizeof(double));
			memcpy(A, mxGetData(prhs[0]), numElem*sizeof(double));   			
		}
		else
		{
			A = mxGetData(prhs[0]);
		}		
		
		A = (double *) A;
		
		/* Pointer to work */
		work = (double *) mxCalloc(8*N, sizeof(double));		
		
		/* Pointer to eigen vectors */
		plhs[0] = mxCreateDoubleMatrix(N, num_eigs, mxREAL);
		Z = mxGetPr(plhs[0]);			
		
		/* Pointer to eigen values */
		plhs[1] = mxCreateDoubleMatrix(1, num_eigs, mxREAL);
		W = mxGetPr(plhs[1]);		

		/* Tolerance */		
		ABSTOLD = mxGetEps();		
	}
	else
	{
		isDouble = 0;
		
		if (optional == 1) 
		{
			A = (void *) mxCalloc(numElem, sizeof(float));
			memcpy(A, mxGetData(prhs[0]), numElem*sizeof(float));   
		}
		else
		{
			A = mxGetData(prhs[0]);
		}
		
		A = (float *) A;
		
		/* Pointer to work */
		work = (float *) mxCalloc(8*N, sizeof(float));
		
		/* Pointer to eigen vectors */
		plhs[0] = mxCreateNumericMatrix(N, num_eigs, mxSINGLE_CLASS, mxREAL);	
		Z = (float *) mxGetData(plhs[0]);			
		
		/* Pointer to eigen values */
		plhs[1] = mxCreateNumericMatrix(1, num_eigs, mxSINGLE_CLASS, mxREAL);	
		W = (float *) mxGetData(plhs[1]); 
		
		ABSTOLF = (float) mxGetEps();		
	}		

	
#ifdef MWSIZE
	/* Pointer to iwork */
	iwork = (mwSize *) mxCalloc(5*N, sizeof(mwSize)); 	
	/* Pointer to ifail */
	ifail = (mwSize *) mxCalloc(N, sizeof(mwSize));		
#else	
	/* Pointer to iwork */
	iwork = (int *) mxCalloc(5*N, sizeof(int)); 	
	/* Pointer to ifail */
	ifail = (int *) mxCalloc(N, sizeof(int));		
#endif	
	
	/* Call subroutine to find eigen values and vectors */
#ifdef PC	
	/* Handle Windows */
	if (isDouble == 1)
	{	
		/* Double precision */
		dspevx(ch1, ch2, ch3, &N, A, &VLD, &VUD, &IL, &IU, &ABSTOLD, &M, W, Z, &N, work, iwork, ifail, &info);	
	}
	else
	{
		/* Use single precision routine */
#ifdef SINGLE_SUPPORT		
		sspevx(ch1, ch2, ch3, &N, A, &VLF, &VUF, &IL, &IU, &ABSTOLF, &M, W, Z, &N, work, iwork, ifail, &info);			
#else
		mexErrMsgTxt("Error executing sspevx function on this MATLAB version.\nUse double precision to solve eigen value problem");
#endif
	}
	/* End for handling Windows */
#else
	/* Handle other OS */
	if (isDouble == 1)
	{
		dspevx_(ch1, ch2, ch3, &N, A, &VLD, &VUD, &IL, &IU, &ABSTOLD, &M, W, Z, &N, work, iwork, ifail, &info);	
	}
	else
	{
		/* Use single precision routine */
#ifdef SINGLE_SUPPORT
		sspevx_(ch1, ch2, ch3, &N, A, &VLF, &VUF, &IL, &IU, &ABSTOLF, &M, W, Z, &N, work, iwork, ifail, &info);	
#else
		mexErrMsgTxt("Error executing sspevx_ function on this MATLAB version.\nUse double precision to solve eigen value problem");
#endif
	}
	/* End for handling other OS */
#endif
	/* End for calling subroutine to find eigen values and vectors */
	
	if (M != num_eigs)
	{
		mexPrintf("%s%d\t%s%d\n", "No. of eigen values estimated: ", M, "No. of eigen values desired: ", num_eigs);
		mexErrMsgTxt("Error executing dspevx function\n");
	}
	
	if (info == 1) 
	{
		mexErrMsgTxt("Error executing dspevx/sspevx function.");
	}
	
	/* Free memory */
	if (optional == 1) 
	{
		mxFree(A);
	}	
	mxFree(work);
	mxFree(iwork);
	mxFree(ifail);

}
Exemplo n.º 8
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) {
Exemplo n.º 9
0
void
mexFunction (int nlhs, mxArray * plhs[], int nrhs, const mxArray * prhs[])
{
  mxArray *lf;
  double tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, eps, alpha, beta, A, B, C;
  double r[3], u[3], d[3];
  double *lf_p, *rm_p, *um_p, *R;
  int nchan, i;
  char str[256];

  if (nrhs<3)
    mexErrMsgTxt("Not enough input arguments");
  if (nrhs>3)
    mexErrMsgTxt("Too many input arguments");

  if (mxGetM(prhs[0])!=1 || mxGetN(prhs[0])!=3)
    mexErrMsgTxt ("Invalid dimension for input argument 1");
  if (mxGetN(prhs[1])!=3)
    mexErrMsgTxt ("Invalid dimension for input argument 2");
  if (mxGetN(prhs[2])!=3)
    mexErrMsgTxt ("Invalid dimension for input argument 3");
  nchan = mxGetM(prhs[1]);
  if (mxGetM(prhs[2])!=nchan)
    mexErrMsgTxt ("Number of channels does not match between argument 2 and 3");

  lf = mxCreateDoubleMatrix(nchan, 3, mxREAL);
  lf_p = mxGetData(lf);
  R    = mxGetData(prhs[0]);
  rm_p = mxGetData(prhs[1]);
  um_p = mxGetData(prhs[2]);
  eps  = mxGetEps();

  tmp2 = sqrt(R[0]*R[0] + R[1]*R[1] + R[2]*R[2]);	/* norm(R) */

  for (i=0; i<nchan; i++)
  {
    /* get the position of this single channel */
    r[0] = rm_p[i];
    r[1] = rm_p[i+nchan];
    r[2] = rm_p[i+nchan+nchan];
    /* get the orientation of this single channel */
    u[0] = um_p[i];
    u[1] = um_p[i+nchan];
    u[2] = um_p[i+nchan+nchan];

    /* compute the difference between this channel and the dipole position */
    d[0] = r[0] - R[0];
    d[1] = r[1] - R[1];
    d[2] = r[2] - R[2];

    tmp1 = sqrt(r[0]*r[0] + r[1]*r[1] + r[2]*r[2]);	/* norm(r) */
    /* tmp2 = sqrt(R[0]*R[0] + R[1]*R[1] + R[2]*R[2]); */
    tmp3 = sqrt(d[0]*d[0] + d[1]*d[1] + d[2]*d[2]);	/* norm(d) */
    tmp4 = r[0]*R[0] + r[1]*R[1] + r[2]*R[2];		/* dot(r, R) */
    tmp5 = r[0]*d[0] + r[1]*d[1] + r[2]*d[2];		/* dot(r, d) */
    tmp6 = R[0]*d[0] + R[1]*d[1] + R[2]*d[2];		/* dot(R, d) */
    tmp7 = tmp1*tmp2*tmp1*tmp2 - tmp4*tmp4;		/* norm(cross(r,R))^2 */

    alpha = 1 / (-tmp3 * (tmp1*tmp3+tmp5));
    A = 1/tmp3 - 2*alpha*tmp2*tmp2 - 1/tmp1;
    B = 2*alpha*tmp4;
    C = -tmp6/(tmp3*tmp3*tmp3);
    
    if (tmp7<eps)
      beta = 0;
    else
      beta = ((A*r[0] + B*R[0] + C*d[0])*u[0] +
              (A*r[1] + B*R[1] + C*d[1])*u[1] +
              (A*r[2] + B*R[2] + C*d[2])*u[2]) / tmp7;

    /* re-use the temporary array d for something else */
    d[0] = alpha*u[0] + beta*r[0];
    d[1] = alpha*u[1] + beta*r[1];
    d[2] = alpha*u[2] + beta*r[2];

    /* lf(i,:) = 1e-7 * cross(alpha*u  + beta*r, R) */
    lf_p[i            ] = (d[1]*R[2] - d[2]*R[1])*1e-7; 
    lf_p[i+nchan      ] = (d[2]*R[0] - d[0]*R[2])*1e-7; 
    lf_p[i+nchan+nchan] = (d[0]*R[1] - d[1]*R[0])*1e-7; 
  }

  /* assign the output parameter */
  plhs[0] = lf;

  return;
}
Exemplo n.º 10
0
// Function definitions. 
// -----------------------------------------------------------------
void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 
{
    //Outputs Args
    double *x, *fval, *exitflag, *iter;
    
    //Internal Vars
    double *mptr;
    size_t ndec, ndat;   
    int i, havJac = 0;
    
    //LMDIF + LMDER Vars
    int m;                  //len data
    int n;                  //len x
    double *x0;             //initial guess + sol
    double *fvec;           //final fvec
    double ftol = 1e-7;     //function tolerance
    double xtol = 1e-7;     //iterate tolerance
    double gtol = 1e-7;     //gradient tolerance
    int maxfev = 1500;      //max fevals
    double epsfcn = mxGetEps(); //FD max error
    double *diag;           //scaling (ignored in mode 1)   
    int mode = 1;           //internal scaling
    double factor = 100;    //used for initial step bound
    int nprint = -1;        //no printing
    int info = 0;           //output status
    int nfev = 0;           //number of fevals
    int njev = 0;           //number of jevals
    double *fjac;           //final jacobian
    int ldfjac;             //ld of jac
    int *ipvt;              //permutation
    double *qtf;            //qt * fvec    
    double *wa1, *wa2, *wa3, *wa4;  //work vectors

    if (nrhs < 1) {
        if(nlhs < 1)
            printSolverInfo();
        else
            plhs[0] = mxCreateString("");  //no version info? 
        return;
    }

    //Check user inputs
    checkInputs(prhs,nrhs);
    
    //Set Defaults
    citer = 1;
    printLevel = 0;
    iterF.enabled = false;
    maxtime = 1000;

    //Get Sizes
    ndec = mxGetNumberOfElements(prhs[2]);
    ndat = mxGetNumberOfElements(prhs[3]);
    //Get Objective Function Handle
    if (mxIsChar(prhs[0])) {
        CHECK(mxGetString(prhs[0], fun.f, FLEN) == 0,"error reading objective name string");
        fun.nrhs = 1;
        fun.xrhs = 0;
    } else {
        fun.prhs[0] = (mxArray*)prhs[0];
        strcpy(fun.f, "feval");
        fun.nrhs = 2;
        fun.xrhs = 1;
    }
    fun.prhs[fun.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x0
    //Check and Get Gradient Function Handle
    if(!mxIsEmpty(prhs[1])) {  
        havJac = 1;
        if (mxIsChar(prhs[1])) {
            CHECK(mxGetString(prhs[1], grad.f, FLEN) == 0,"error reading gradient name string");
            grad.nrhs = 1;
            grad.xrhs = 0;
        } else {
            grad.prhs[0] = (mxArray*)prhs[1];
            strcpy(grad.f, "feval");
            grad.nrhs = 2;
            grad.xrhs = 1;
        }   
        grad.prhs[grad.xrhs] = mxCreateDoubleMatrix(ndec, 1, mxREAL); //x0
    }

    //Get x0 + data
    x0 = mxGetPr(prhs[2]);
    ydata = mxGetPr(prhs[3]);        
    
    //Get Options if specified
    if(nrhs > 4) {
        if(mxGetField(prhs[4],0,"display"))
            printLevel = (int)*mxGetPr(mxGetField(prhs[4],0,"display"));
        if(mxGetField(prhs[4],0,"maxfeval"))
            maxfev = (int)*mxGetPr(mxGetField(prhs[4],0,"maxfeval"));
        if(mxGetField(prhs[4],0,"maxtime"))
            maxtime = *mxGetPr(mxGetField(prhs[4],0,"maxtime"));
        if(mxGetField(prhs[4],0,"tolrfun"))
            ftol = *mxGetPr(mxGetField(prhs[4],0,"tolrfun"));
        if(mxGetField(prhs[4],0,"iterfun") && !mxIsEmpty(mxGetField(prhs[4],0,"iterfun")))
        {
            iterF.prhs[0] = (mxArray*)mxGetField(prhs[4],0,"iterfun");
            strcpy(iterF.f, "feval");
            iterF.enabled = true;  
            iterF.prhs[1] = mxCreateNumericMatrix(1,1,mxINT32_CLASS,mxREAL);
            iterF.prhs[2] = mxCreateDoubleMatrix(1,1,mxREAL);
            iterF.prhs[3] = mxCreateDoubleMatrix(ndec,1,mxREAL);
        }
    }       
    
    //Create Outputs
    plhs[0] = mxCreateDoubleMatrix(ndec,1, mxREAL);
    plhs[1] = mxCreateDoubleMatrix(1,1, mxREAL);
    plhs[2] = mxCreateDoubleMatrix(1,1, mxREAL);
    plhs[3] = mxCreateDoubleMatrix(1,1, mxREAL);
    x = mxGetPr(plhs[0]); 
    fval = mxGetPr(plhs[1]); 
    exitflag = mxGetPr(plhs[2]);    
    iter = mxGetPr(plhs[3]);
    
    //Copy initial guess to x
    memcpy(x,x0,ndec*sizeof(double));
    
    //Print Header
    if(printLevel) {
        mexPrintf("\n------------------------------------------------------------------\n");
        if(havJac)
            mexPrintf(" This is LM_DER\n");
        else
            mexPrintf(" This is LM_DIF\n");
            
        mexPrintf(" Authors: Burton S. Garbow, Kenneth E. Hillstrom, Jorge J. More\n MEX Interface J. Currie 2011\n\n");
        mexPrintf(" Problem Properties:\n");
        mexPrintf(" # Decision Variables:     %4d\n",ndec);
        mexPrintf(" # Data Points:            %4d\n",ndat);

        mexPrintf("------------------------------------------------------------------\n");
    }
    
    //Assign Arguments
    m = (int)ndat; ldfjac = m;
    n = (int)ndec;
    diag = mxCalloc(ndec,sizeof(double));
    fvec = mxCalloc(ndat,sizeof(double));
    fjac = mxCalloc(ndec*ndat,sizeof(double));
    ipvt = mxCalloc(ndec,sizeof(int));
    qtf = mxCalloc(ndec,sizeof(double));   
    //Get Work Memory
    mptr = mxCalloc(3*ndec+ndat,sizeof(double)); i = 0;
    wa1 = &mptr[i]; i += (int)ndec;
    wa2 = &mptr[i]; i += (int)ndec;
    wa3 = &mptr[i]; i += (int)ndec;
    wa4 = &mptr[i];
    
    //Start Timer
    start = clock();
    
    //Call Algorithm based on Derivatives
    if(havJac)
        LMDER(jacfunc,&m,&n,x,fvec,fjac,&ldfjac,&ftol,&xtol,&gtol,&maxfev,diag,&mode,&factor,&nprint,&info,&nfev,&njev,ipvt,qtf,wa1,wa2,wa3,wa4);
    else
        LMDIF(func,&m,&n,x,fvec,&ftol,&xtol,&gtol,&maxfev,&epsfcn,diag,&mode,&factor,&nprint,&info,&nfev,fjac,&ldfjac,ipvt,qtf,wa1,wa2,wa3,wa4);
    
    //Calculate final Rnorm
    *fval = 0;
    for(i=0;i<m;i++)
        *fval += fvec[i]*fvec[i];
    
    //Check if maxtime exceeded
    if(((double)(end-start))/CLOCKS_PER_SEC > maxtime)
        info = 15;
    
    //Save Status & Iterations
    *exitflag = getStatus(info);
    *iter = (double)nfev;
    
    //Print Header
    if(printLevel){            
        //Termination Detected
        switch((int)info)
        {
            //Success
            case 1:
                mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** Both actual and predicted relative reductions in the sum of squares are at most ftol ***\n"); break;
            case 2:
                mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** Relative error between two consecutive iterates is at most xtol ***\n"); break;
            case 3:
                mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** Reductions in the sum of squares are at most ftol AND relative error between two consecutive iterates is at most xtol ***\n"); break;
            case 4:
                mexPrintf("\n *** SUCCESSFUL TERMINATION ***\n *** The cosine of the angle between fvec and any column of the jacobian is at most gtol in absolute value ***\n"); break;
            //Error
            case 0:
                mexPrintf("\n *** ERROR: IMPROPER INPUT PARAMETERS ***\n"); break;
            case 5:
                mexPrintf("\n *** MAXIMUM FUNCTION EVALUATIONS REACHED ***\n"); break;
            case 15:
                mexPrintf("\n *** MAXIMUM TIME REACHED ***\n"); break;
            //Early Exit
            case 6:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: ftol is too small (OPTI setting tolfun). No further improvement in the sum of squares is possible ***\n"); break;
            case 7:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: xtol is too small (OPTI hard-codes 1e-7). No further improvement in the approximate solution x is possible ***\n"); break;
            case 8:
                mexPrintf("\n *** TERMINATION: EARLY EXIT ***\n *** CAUSE: gtol is too small (OPTI hard-codes 1e-7). Fvec is orthogonal to the columns of the jacobian to machine precision ***\n"); break;
            case -1:
                mexPrintf("\n *** TERMINATION: USER EXITED ***\n"); break;
        }

        if(*exitflag==1)
            mexPrintf("\n Final SSE: %12.5g\n In %3.0f function evaluations\n",*fval,*iter);

        mexPrintf("------------------------------------------------------------------\n\n");
    }
    
    //Free Memory
    if(diag) mxFree(diag);
    if(fvec) mxFree(fvec);
    if(fjac) mxFree(fjac);
    if(ipvt) mxFree(ipvt);
    if(qtf)  mxFree(qtf);
    if(mptr) mxFree(mptr);
}