Beispiel #1
0
static void yprime(
		   double	yp[],
		   double	*t,
 		   double	y[]
		   )
{
    double	r1,r2;
    
    (void) t;     /* unused parameter */

    r1 = sqrt((y[0]+mu)*(y[0]+mu) + y[2]*y[2]); 
    r2 = sqrt((y[0]-mus)*(y[0]-mus) + y[2]*y[2]);

    /* Print warning if dividing by zero. */    
    if (r1 == 0.0 || r2 == 0.0 ){
        mexWarnMsgIdAndTxt( "MATLAB:yprime:divideByZero", 
                "Division by zero!\n");
    }
    
    yp[0] = y[1];
    yp[1] = 2*y[3]+y[0]-mus*(y[0]+mu)/(r1*r1*r1)-mu*(y[0]-mus)/(r2*r2*r2);
    yp[2] = y[3];
    yp[3] = -2*y[1] + y[2] - mus*y[2]/(r1*r1*r1) - mu*y[2]/(r2*r2*r2);
    return;
}
Beispiel #2
0
int 
ann_mex_t::annkFRSearch(					// approx fixed-radius kNN search
            const mxArray*	mxQ,			// query point
            ANNdist         sqRad,			// squared radius of query ball
            int				k,				// number of near neighbors to return
            mxArray**		mxIdx,			// nearest neighbor array (modified)
            mxArray**       mxDst,			// dist to near neighbors (modified)
            double			eps)		// error bound
{
    index_t j(0);
    
    if ( ! IsGood() )
        mexErrMsgIdAndTxt("annmex:annkFRSearch","Class integrity check failed");
    
    // check input point(s)
    // dimension of points
    if (m_idim != mxGetM(mxQ))
        mexErrMsgIdAndTxt("annmex:annkFRSearch","point dimension does not match");
    
    if ( mxGetN(mxQ) != 1 )
        mexErrMsgIdAndTxt("annmex:annkFRSearch","FR search can be done for a single point at each time");
    
    if ( k <= 0 )
        mexErrMsgIdAndTxt("annmex:annkFRSearch","k must be positive");
    
    if ( k > m_inpoints ) {
        // generate warning
        mexWarnMsgIdAndTxt("annmex:annkFRSearch","searching for more points than in tree - returning only %d",m_inpoints);
        k = m_inpoints;
    }
    if ( sqRad < 0 )
       mexErrMsgIdAndTxt("annmex:annkFRSearch","radius must be positive");
    
    ANNpoint pp   = (ANNpoint)mxGetData(mxQ);
    
    ANNidx* tmpidx = new ANNidx[k];
    ANNdist* tmpdist = new ANNdist[k];
    if ( tmpidx == NULL || tmpdist == NULL )
        mexErrMsgIdAndTxt("annmex:annkFRSearch","cannot allocate memory for outputs");
    
    int gotp = m_pTree->annkFRSearch(pp, sqRad, k, tmpidx, tmpdist, eps);
    
    // allocate space for outputs
    *mxIdx = mxCreateNumericMatrix(1, min(gotp,k), mxIDX_CLASS, mxREAL);
    *mxDst = mxCreateNumericMatrix(1, min(gotp,k), mxDIST_CLASS, mxREAL);
    if ( *mxIdx == NULL || *mxDst == NULL ) 
        mexErrMsgIdAndTxt("annmex:annkPriSearch","cannot allocate memory for outputs");
    
    ANNidx * pidx = (ANNidx*)mxGetData(*mxIdx);
    ANNdist* pdist= (ANNdist*)mxGetData(*mxDst);
    
    for ( j = 0 ; j < min(gotp,k) ; j++ ) {
        pidx[j] = tmpidx[j];
        pdist[j] = tmpdist[j];
    }
    delete [] tmpidx;
    delete [] tmpdist;   
    return gotp; // how many points in range
}
Beispiel #3
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;
}
Beispiel #4
0
void ReadOptionsDirectTimeRange(struct options_direct *opts,struct input *X)
{
  if(opts->t_start_flag==0)
    {
      opts->t_start = GetStartTime(X);
      opts->t_start_flag=1;
      mexWarnMsgIdAndTxt("STAToolkit:ReadOptionsTimeRange:missingParameter","Missing parameter start_time. Extracting from input: %f.\n",opts->t_start);
    }

  if(opts->t_end_flag==0)
    {
      opts->t_end = GetEndTime(X);
      opts->t_end_flag=1;
      mexWarnMsgIdAndTxt("STAToolkit:ReadOptionsTimeRange:missingParameter","Missing parameter end_time. Extracting from input: %f.\n",opts->t_end);
    }

  if((opts->t_start)>(opts->t_end))
      mexErrMsgIdAndTxt("STAToolkit:ReadOptionsTimeRange:badRange","Lower limit greater than upper limit for start_time and end_time.\n");
}
Beispiel #5
0
void GB_mx_mxArray_to_array    // convert mxArray to array
(
    const mxArray *Xmatlab,     // input MATLAB array
    // output:
    void **X,                   // pointer to numerical values
    int64_t *nrows,             // number of rows of X
    int64_t *ncols,             // number of columns of X
    mxClassID *xclass,          // MATLAB class of X
    GrB_Type *xtype             // GraphBLAS type of X, NULL if error
)
{

    *X = NULL ;
    *nrows = 0 ;
    *ncols = 0 ;
    *xclass = mxUNKNOWN_CLASS ;
    *xtype = NULL ;

    if (!(mxIsNumeric (Xmatlab) || mxIsLogical (Xmatlab)))
    {
        mexWarnMsgIdAndTxt ("GB:warn","input must be numeric or logical array");
    }
    if (mxIsSparse (Xmatlab))
    {
        mexWarnMsgIdAndTxt ("GB:warn","input cannot be sparse") ;
    }

    if (mxIsComplex (Xmatlab))
    {
        // user-defined Complex type
        // make a deep copy of the MATLAB complex dense matrix
        int64_t nel = mxGetNumberOfElements (Xmatlab) ;
        GB_MALLOC_MEMORY (double *XX, nel+1, sizeof (double complex)) ;
        GB_mx_complex_merge (nel, XX, Xmatlab) ;
        *X = XX ;
        *xclass = mxDOUBLE_CLASS ;
        *xtype = Complex ;
    }
    else
    {
Beispiel #6
0
void 
ann_mex_t::annkPriSearch( 				// priority k near neighbor search
            const mxArray*	mxQ,			// query point
            int				k,				// number of near neighbors to return
            mxArray**		mxIdx,			// nearest neighbor array (modified)
            mxArray**       mxDst,			// dist to near neighbors (modified)
            double			eps)		// error bound
{
    index_t j(0);
    int nqp(0); // number of query points
    
    if ( ! IsGood() )
        mexErrMsgIdAndTxt("annmex:annkPriSearch","Class integrity check failed");
    
    // check input point(s)
    // dimension of points
    if (m_idim != mxGetM(mxQ))
        mexErrMsgIdAndTxt("annmex:annkPriSearch","point dimension does not match");

    nqp = mxGetN(mxQ);
    if (nqp <= 0) 
        mexErrMsgIdAndTxt("annmex:annkPriSearch","need at least one query point");

    if ( k <= 0 )
        mexErrMsgIdAndTxt("annmex:annkPriSearch","k must be positive");
    
    if ( k > m_inpoints ) {
        // generate warning
        mexWarnMsgIdAndTxt("annmex:annkPriSearch","searching for more points than in tree - returning only %d",m_inpoints);
        k = m_inpoints;
    }
        
    // allocate space for outputs
    *mxIdx = mxCreateNumericMatrix(k, nqp, mxIDX_CLASS, mxREAL);
    *mxDst = mxCreateNumericMatrix(k, nqp, mxDIST_CLASS, mxREAL);
    if ( *mxIdx == NULL || *mxDst == NULL ) 
        mexErrMsgIdAndTxt("annmex:annkPriSearch","cannot allocate memory for outputs");
    
    ANNidx * pidx = (ANNidx*)mxGetData(*mxIdx);
    ANNdist* pdist= (ANNdist*)mxGetData(*mxDst);
    ANNpoint pp   = (ANNpoint)mxGetData(mxQ);
    
    for ( j = 0 ; j < nqp ; j++ ) {
        m_pTree->annkPriSearch(pp, k, pidx, pdist, eps);
        pp += m_idim;
        pidx += k;
        pdist += k;
    }
   
}
Beispiel #7
0
void read_options_entropy_bub(const mxArray *in,struct options_entropy *opts)
{
	opts->bub_possible_words_strategy_flag = ReadOptionsIntMember(in,"bub_possible_words_strategy",&(opts->bub_possible_words_strategy));
	opts->bub_lambda_0_flag = ReadOptionsDoubleMember(in,"bub_lambda_0",&(opts->bub_lambda_0));
	opts->bub_K_flag = ReadOptionsIntMember(in,"bub_K",&(opts->bub_K));
	opts->bub_compat_flag = ReadOptionsIntMember(in,"bub_compat",&(opts->bub_compat));

	if(opts->possible_words_flag==0)
	{
		if(opts->bub_possible_words_strategy_flag==0)
		{
			opts->possible_words = (double)DEFAULT_POSSIBLE_WORDS;
			opts->possible_words_flag = 1;
			mexWarnMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:missingParameter","Missing possible_words. Using default value \"recommended\".\n");
		}
		else
		{
			mexWarnMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:deprecatedUsage","Using deprecated option bub_possible_words_strategy. Recommended to use possible_words instead.\n");
			if((opts->bub_possible_words_strategy!=0) && (opts->bub_possible_words_strategy!=1) && (opts->bub_possible_words_strategy!=2))
				mexErrMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:invalidValue","bub_possible_words_strategy must be 0, 1, or 2. The current value is %d.\n",(*opts).bub_possible_words_strategy);
		}
	}
	else if(opts->bub_possible_words_strategy_flag!=0)
		mexWarnMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:deprecatedUsage","Ignoring deprecated option bub_possible_words_strategy. Using possible_words.\n");

	if(opts->bub_lambda_0_flag==0)
		{
			opts->bub_lambda_0 = (double)DEFAULT_BUB_LAMBDA_0;
			opts->bub_lambda_0_flag=1;
			mexWarnMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:missingParameter","Missing bub_lambda_0. Using default value %f.\n",(*opts).bub_lambda_0);
		}
	
	if(opts->bub_lambda_0<0)
		mexErrMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:invalidValue","bub_lambda_0 must be greater than or equal to zero. The current value is %d.\n",opts->bub_lambda_0);
	
	if(opts->bub_K_flag==0)
		{
			opts->bub_K = (int)DEFAULT_BUB_K;
			opts->bub_K_flag=1;
			mexWarnMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:missingParameter","Missing parameter bub_K. Using default value %d.\n",(*opts).bub_K);
		}
	
	if(opts->bub_K<=0)
		mexErrMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:invalidValue","bub_K must be positive. The current value is %d.\n",opts->bub_K);
	
	if(opts->bub_compat_flag==0)
		{
			opts->bub_compat = (int)DEFAULT_BUB_COMPAT;
			opts->bub_compat_flag=1;
			mexWarnMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:missingParameter","Missing parameter bub_compat. Using default value %d.\n",(*opts).bub_compat);
		}
	
	if((opts->bub_compat_flag!=0) & (opts->bub_compat_flag!=1))
		{
			mexErrMsgIdAndTxt("STAToolkit:ReadOptionsEntropy:invalidValue","bub_compat must be 0 or 1. The current value is %d.\n",(*opts).bub_compat);
		}
}
Beispiel #8
0
/**
 * @brief Interfaces C and Matlab data.
 * This function is the MEX-file gateway routine. Please see the Matlab
 * MEX-file documentation (http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_external/f43721.html)
 * for more information.
 */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{

  /* allocate variables */
  struct histcond *in;
  struct options_entropy *opts;
  int status;

  /* check number of inputs (nargin) and outputs (nargout) */
  if((nrhs<1) | (nrhs>2))
    mexErrMsgIdAndTxt("STAToolkit:infocond:numArgs","1 or 2 input arguments required.");
  if((nlhs<1) | (nlhs>2))
    mexErrMsgIdAndTxt("STAToolkit:infocond:numArgs","1 or 2 outputs argument required.");

  /* get or set options */
  if(nrhs<2)
    opts = ReadOptionsEntropy(mxCreateEmptyStruct());
  else if(mxIsEmpty(prhs[1]))
    opts = ReadOptionsEntropy(mxCreateEmptyStruct());
  else
    opts = ReadOptionsEntropy(prhs[1]);

  plhs[0] = mxDuplicateArray(prhs[0]);

  in = ReadHistCond(plhs[0],opts);

  status = InfoCondComp(in,opts);
  if(status!=EXIT_SUCCESS)
    mexWarnMsgIdAndTxt("STAToolkit:infocond:failure","Function infocond returned with errors. Please check messages.");

  /* Augment the mx histogram with the new info */
  WriteHistCondAgain(in,plhs[0]);

  /* output options used */
  if(nrhs<2)
    plhs[1] = WriteOptionsEntropy(mxCreateEmptyStruct(),opts);
  else if(mxIsEmpty(prhs[1]))
    plhs[1] = WriteOptionsEntropy(mxCreateEmptyStruct(),opts);
  else
    plhs[1] = WriteOptionsEntropy(prhs[1],opts);

  mxFree(in);

  return;
}
void
_copyMexToCFloat32Array(const mxArray * const inArray, astra::float32 * const out)
{
	const long long tot_size = mxGetNumberOfElements(inArray);
	const long long block = 32;
	const long long totRoundedPixels = ROUND_DOWN(tot_size, block);

	if (mxIsDouble(inArray)) {
		const double * const pdMatlabData = mxGetPr(inArray);

#pragma omp for nowait
		for (long long count = 0; count < totRoundedPixels; count += block) {
			STORE_64F_32F_CORE8(pdMatlabData, out, count,  0);
			STORE_64F_32F_CORE8(pdMatlabData, out, count,  8);
			STORE_64F_32F_CORE8(pdMatlabData, out, count, 16);
			STORE_64F_32F_CORE8(pdMatlabData, out, count, 24);
		}
#pragma omp for nowait
		for (long long count = totRoundedPixels; count < tot_size; count++) {
			out[count] = pdMatlabData[count];
		}
	}
	else if (mxIsSingle(inArray)) {
		const float * const pfMatlabData = (const float *)mxGetData(inArray);

#pragma omp for nowait
		for (long long count = 0; count < totRoundedPixels; count += block) {
			STORE_32F_32F_CORE8(pfMatlabData, out, count,  0);
			STORE_32F_32F_CORE8(pfMatlabData, out, count,  8);
			STORE_32F_32F_CORE8(pfMatlabData, out, count, 16);
			STORE_32F_32F_CORE8(pfMatlabData, out, count, 24);
		}
#pragma omp for nowait
		for (long long count = totRoundedPixels; count < tot_size; count++) {
			out[count] = pfMatlabData[count];
		}
	}
	else {
#pragma omp single nowait
		mexWarnMsgIdAndTxt("ASTRA_MEX:wrong_datatype", warnDataTypeNotSupported);
	}
}
void
_copyCFloat32ArrayToMex(const astra::float32 * const in, mxArray * const outArray)
{
	const long long tot_size = mxGetNumberOfElements(outArray);
	const long long block = 32;
	const long long tot_rounded_size = ROUND_DOWN(tot_size, block);

	if (mxIsDouble(outArray)) {
		double * const pdMatlabData = mxGetPr(outArray);

#pragma omp for nowait
		for (long long count = 0; count < tot_rounded_size; count += block) {
			STORE_32F_64F_CORE8(in, pdMatlabData, count,  0);
			STORE_32F_64F_CORE8(in, pdMatlabData, count,  8);
			STORE_32F_64F_CORE8(in, pdMatlabData, count, 16);
			STORE_32F_64F_CORE8(in, pdMatlabData, count, 24);
		}
#pragma omp for nowait
		for (long long count = tot_rounded_size; count < tot_size; count++) {
			pdMatlabData[count] = in[count];
		}
	}
	else if (mxIsSingle(outArray)) {
		float * const pfMatlabData = (float *) mxGetData(outArray);

#pragma omp for nowait
		for (long long count = 0; count < tot_rounded_size; count += block) {
			STORE_32F_32F_CORE8(in, pfMatlabData, count,  0);
			STORE_32F_32F_CORE8(in, pfMatlabData, count,  8);
			STORE_32F_32F_CORE8(in, pfMatlabData, count, 16);
			STORE_32F_32F_CORE8(in, pfMatlabData, count, 24);
		}
#pragma omp for nowait
		for (long long count = tot_rounded_size; count < tot_size; count++) {
			pfMatlabData[count] = in[count];
		}
	}
	else {
#pragma omp single nowait
		mexWarnMsgIdAndTxt("ASTRA_MEX:wrong_datatype", warnDataTypeNotSupported);
	}
}
Beispiel #11
0
/* Determine the category (class) of the input array_ptr, and then
   branch to the appropriate analysis routine. */
mxClassID analyze_class(const mxArray *array_ptr)
{
    mxClassID  category;
    
    category = mxGetClassID(array_ptr);
    
    if (mxIsSparse(array_ptr)) {
       analyze_sparse(array_ptr);
    } else {
       switch (category) {
          case mxLOGICAL_CLASS: analyze_logical(array_ptr);    break;
          case mxCHAR_CLASS:    analyze_string(array_ptr);     break;
          case mxSTRUCT_CLASS:  analyze_structure(array_ptr);  break;
          case mxCELL_CLASS:    analyze_cell(array_ptr);       break;
          case mxUNKNOWN_CLASS: 
              mexWarnMsgIdAndTxt("MATLAB:explore:unknownClass", 
                      "Unknown class.");                       break;
          default:              analyze_full(array_ptr);       break;
       }
    }
    
    return(category);
}
Beispiel #12
0
/** Check the cut identified against the flow value calculated.
 * 
 * Run through the edges and compute the sum of edges crossing the cut
 * and make sure this is the same as the value of the maximum flow.
 *
 * This function will flag issues with incorrect rounding.
 *
 * @param flow the computed flow value
 * @param pimincut the min cut vector (-1 for side 1, 1 for side 2)
 * @param n, ia, pja, a, the graph structure
 */
void test_cut(int flow, int* pimincut, 
    mbglIndex n, mbglIndex *ia, mbglIndex *pja, double *a)
{
    double cv=0.0; 
    mbglIndex i, j, k;
    for (j=0; j<n; j++) {
        for (k=pja[j]; k<pja[j+1]; k++) {
            i=ia[k];
            /* the source side is 1, and sink side is -1, so we get
             * a source to sink edge if cut[i]>cut[j]. */
            if (pimincut[i]>pimincut[j]) {
                /* mexPrintf("%i -> %i : +%i\n", i+1,j+1,(int)a[k]); */
                cv += a[k];
            }
        }
    }
    if ((int)cv != flow) {
        mexWarnMsgIdAndTxt("max_flow_mex:cutValueNotFlowValue",
          "The rounded (unrounded) value of the minimum cut is %i (%g),"
          "but the value of the max-flow is %i.  These values should be equal",
          (int)cv,cv,flow);
    }
}
/**************************************************************************
 * input : struct_arrary ( a  pointer to Matlab structure )
 * input : index ( index of an element in structure )
 * input : fieldName ( name of the element )
 * input : classIdExpected ( expected class id of the element)
 * output : pointer to the corresponding structure element
 *
 * This function takes the above input arguments checks the validity of
 * the structure element and if everything is fine then returns a pointer.
 **************************************************************************/
mxArray* getFieldPointer(const mxArray *struct_array, int index,
		const char* fieldName, mxClassID classIdExpected)
{
	mxArray *fieldPointer = NULL;
	//mexPrintf("executing getFieldPointer..");
	fieldPointer = mxGetField(struct_array, index, fieldName);
	if (fieldPointer == NULL || mxIsEmpty(fieldPointer))
	{
		mexPrintf("Field %s is empty \n", fieldName);
		mexWarnMsgIdAndTxt("SSA:programOptions:StructElementEmpty",
				"The element in the structure is empty,default value will be assigned \n");

		return NULL;
	}
	mexPrintf("The class of field :   %s is : %d\n", fieldName,
			mxGetClassID(fieldPointer));
	if (mxGetClassID(fieldPointer) != classIdExpected)
	{

		mexErrMsgIdAndTxt("SSA:programOptions:inputNotStruct",
				"Given class Id does not match with the expected class id");
	}
	return fieldPointer;
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
  if (nrhs < 1) 
    mexErrMsgTxt("One input required.");
  else if (nrhs > 2)
    mexErrMsgTxt("Too many input arguments.");
  if (nlhs > 1)
    mexErrMsgTxt("Too many output arguments.");

  if (nrhs == 2)
    if ((mxGetClassID(prhs[1]) != mxDOUBLE_CLASS) || (mxGetNumberOfElements(prhs[1]) != 1))
      mexErrMsgTxt("Second input argument must be a real (double) value.");

  // Redirection of the btk::Logger::Warning stream.
  btk::MEXWarnLogToWarnMsgTxt warnRedir = btk::MEXWarnLogToWarnMsgTxt("btk:GetGroundReactionWrenches");

  // First output
  btk::Acquisition::Pointer acq = btk_MOH_get_object<btk::Acquisition>(prhs[0]);
  btk::ForcePlatformsExtractor::Pointer fpExtractor = btk::ForcePlatformsExtractor::New();
  fpExtractor->SetInput(acq);
  btk::GroundReactionWrenchFilter::Pointer grwFilter = btk::GroundReactionWrenchFilter::New();
  if (nrhs == 2)
  {
    grwFilter->SetThresholdState(true);
    grwFilter->SetThresholdValue(mxGetScalar(prhs[1]));
  }
  grwFilter->SetInput(fpExtractor->GetOutput());
  btk::WrenchCollection::Pointer grws = grwFilter->GetOutput();
  grws->Update();

  const char* fieldnames[] = {"P", "F", "M"};
  int numberOfFields =  sizeof(fieldnames) / sizeof(char*);
  int numberOfForcePlates = grws->GetItemNumber();
  
  plhs[0] = mxCreateStructMatrix(numberOfForcePlates, 1, numberOfFields, fieldnames);
  btk::WrenchCollection::ConstIterator itWrench = grws->Begin();
  for (int i = 0 ; i < numberOfForcePlates ; ++i)
  {
    if (itWrench->get() != 0)
    {
      int numberOfFrames = (*itWrench)->GetPosition()->GetFrameNumber();
      // Position
      mxArray* position = mxCreateDoubleMatrix(numberOfFrames, 3, mxREAL);
      memcpy(mxGetPr(position), (*itWrench)->GetPosition()->GetValues().data(), mxGetNumberOfElements(position) * sizeof(double));
      mxSetFieldByNumber(plhs[0], i, 0, position);
      // Force
      mxArray* force = mxCreateDoubleMatrix(numberOfFrames, 3, mxREAL);
      memcpy(mxGetPr(force), (*itWrench)->GetForce()->GetValues().data(), mxGetNumberOfElements(force) * sizeof(double));
      mxSetFieldByNumber(plhs[0], i, 1, force);
      // Moment
      mxArray* moment = mxCreateDoubleMatrix(numberOfFrames, 3, mxREAL);
      memcpy(mxGetPr(moment), (*itWrench)->GetMoment()->GetValues().data(), mxGetNumberOfElements(moment) * sizeof(double));
      mxSetFieldByNumber(plhs[0], i, 2, moment);
    }
    else
    {
      std::string warnText = "Ground reaction wrench #" + btk::ToString(i) + " is empty. Send an email to BTK developers to inform them.";
      mexWarnMsgIdAndTxt("btk:GetGroundReactionWrenches", warnText.c_str());
    }
    ++itWrench;
  }
};
Beispiel #15
0
void mexFunction
(
    int nargout,
    mxArray *pargout [ ],
    int nargin,
    const mxArray *pargin [ ]
)
{
    Int *Bp, *Bi ;
    double *Ax, *Bx, dummy ;
    Int m, n, k, bncols, p, i, rank, A_complex, B_complex, is_complex,
        anz, bnz ;
    spqr_mx_options opts ;
    cholmod_sparse *A, Amatrix, *Xsparse ; 
    cholmod_dense *Xdense ;
    cholmod_common Common, *cc ;
    char msg [LEN+1] ;

#ifdef TIMING
    double t0 = (nargout > 1) ? spqr_time ( ) : 0 ;
#endif

    // -------------------------------------------------------------------------
    // start CHOLMOD and set parameters
    // -------------------------------------------------------------------------

    cc = &Common ;
    cholmod_l_start (cc) ;
    spqr_mx_config (SPUMONI, cc) ;

    // -------------------------------------------------------------------------
    // check inputs
    // -------------------------------------------------------------------------

    if (nargout > 2)
    {
        mexErrMsgIdAndTxt ("MATLAB:maxlhs", "Too many output arguments") ;
    }
    if (nargin < 2)
    {
        mexErrMsgIdAndTxt ("MATLAB:minrhs", "Not enough input arguments") ;
    }
    if (nargin > 3)
    {
        mexErrMsgIdAndTxt ("MATLAB:maxrhs", "Too many input arguments") ;
    }

    // -------------------------------------------------------------------------
    // get the input matrix A (must be sparse)
    // -------------------------------------------------------------------------

    if (!mxIsSparse (pargin [0]))
    {
        mexErrMsgIdAndTxt ("QR:invalidInput", "A must be sparse") ;
    }

    A = spqr_mx_get_sparse (pargin [0], &Amatrix, &dummy) ;
    m = A->nrow ;
    n = A->ncol ;
    A_complex = mxIsComplex (pargin [0]) ;

    B_complex = mxIsComplex (pargin [1]) ;
    is_complex = (A_complex || B_complex) ;
    Ax = spqr_mx_merge_if_complex (pargin [0], is_complex, &anz, cc) ; 
    if (is_complex)
    {
        // A has been converted from real or zomplex to complex
        A->x = Ax ;
        A->z = NULL ;
        A->xtype = CHOLMOD_COMPLEX ;
    }

    // -------------------------------------------------------------------------
    // determine usage and parameters
    // -------------------------------------------------------------------------

    spqr_mx_get_options ((nargin < 3) ? NULL : pargin [2], &opts, m, 3, cc) ;

    opts.Qformat = SPQR_Q_DISCARD ;
    opts.econ = 0 ;
    opts.permvector = TRUE ;
    opts.haveB = TRUE ;

    // -------------------------------------------------------------------------
    // get the input matrix B (sparse or dense)
    // -------------------------------------------------------------------------

    if (!mxIsNumeric (pargin [1]))
    {
        mexErrMsgIdAndTxt ("QR:invalidInput", "invalid non-numeric B") ;
    }
    if (mxGetM (pargin [1]) != m)
    {
        mexErrMsgIdAndTxt ("QR:invalidInput",
            "A and B must have the same number of rows") ;
    }

    cholmod_sparse Bsmatrix, *Bsparse ;
    cholmod_dense  Bdmatrix, *Bdense ;

    // convert from real or zomplex to complex
    Bx = spqr_mx_merge_if_complex (pargin [1], is_complex, &bnz, cc) ;

    int B_is_sparse = mxIsSparse (pargin [1]) ;
    if (B_is_sparse)
    {
        Bsparse = spqr_mx_get_sparse (pargin [1], &Bsmatrix, &dummy) ;
        Bdense = NULL ;
        if (is_complex)
        {
            // Bsparse has been converted from real or zomplex to complex
            Bsparse->x = Bx ;
            Bsparse->z = NULL ;
            Bsparse->xtype = CHOLMOD_COMPLEX ;
        }
    }
    else
    {
        Bsparse = NULL ;
        Bdense = spqr_mx_get_dense (pargin [1], &Bdmatrix, &dummy) ;
        if (is_complex)
        {
            // Bdense has been converted from real or zomplex to complex
            Bdense->x = Bx ;
            Bdense->z = NULL ;
            Bdense->xtype = CHOLMOD_COMPLEX ;
        }
    }

    // -------------------------------------------------------------------------
    // X = A\B
    // -------------------------------------------------------------------------

    if (opts.min2norm && m < n)
    {
#ifndef NEXPERT
        // This requires SuiteSparseQR_expert.cpp
        if (is_complex)
        {
            if (B_is_sparse)
            {
                // X and B are both sparse and complex
                Xsparse = SuiteSparseQR_min2norm <Complex> (opts.ordering,
                    opts.tol, A, Bsparse, cc) ;
                pargout [0] = spqr_mx_put_sparse (&Xsparse, cc) ;
            }
            else
            {
                // X and B are both dense and complex
                Xdense = SuiteSparseQR_min2norm <Complex> (opts.ordering,
                    opts.tol, A, Bdense, cc) ;
                pargout [0] = spqr_mx_put_dense (&Xdense, cc) ;
            }
        }
        else
        {
            if (B_is_sparse)
            {
                // X and B are both sparse and real
                Xsparse = SuiteSparseQR_min2norm <double> (opts.ordering,
                    opts.tol, A, Bsparse, cc) ;
                pargout [0] = spqr_mx_put_sparse (&Xsparse, cc) ;
            }
            else
            {
                // X and B are both dense and real
                Xdense = SuiteSparseQR_min2norm <double> (opts.ordering,
                    opts.tol, A, Bdense, cc) ;
                pargout [0] = spqr_mx_put_dense (&Xdense, cc) ;
            }
        }
#else
        mexErrMsgIdAndTxt ("QR:notInstalled", "min2norm method not installed") ;
#endif

    }
    else
    {

        if (is_complex)
        {
            if (B_is_sparse)
            {
                // X and B are both sparse and complex
                Xsparse = SuiteSparseQR <Complex> (opts.ordering, opts.tol,
                    A, Bsparse, cc) ;
                pargout [0] = spqr_mx_put_sparse (&Xsparse, cc) ;
            }
            else
            {
                // X and B are both dense and complex
                Xdense = SuiteSparseQR <Complex> (opts.ordering, opts.tol,
                    A, Bdense, cc) ;
                pargout [0] = spqr_mx_put_dense (&Xdense, cc) ;
            }
        }
        else
        {
            if (B_is_sparse)
            {
                // X and B are both sparse and real
                Xsparse = SuiteSparseQR <double> (opts.ordering, opts.tol,
                    A, Bsparse, cc) ;
                pargout [0] = spqr_mx_put_sparse (&Xsparse, cc) ;
            }
            else
            {
                // X and B are both dense and real
                Xdense = SuiteSparseQR <double> (opts.ordering, opts.tol,
                    A, Bdense, cc) ;
                pargout [0] = spqr_mx_put_dense (&Xdense, cc) ;
            }
        }
    }

    // -------------------------------------------------------------------------
    // info output
    // -------------------------------------------------------------------------

    if (nargout > 1)
    {
#ifdef TIMING
        double flops = cc->other1 [0] ;
        double t = spqr_time ( ) - t0 ;
#else
        double flops = -1 ;
        double t = -1 ;
#endif
        pargout [1] = spqr_mx_info (cc, t, flops) ;
    }

    // -------------------------------------------------------------------------
    // warn if rank deficient
    // -------------------------------------------------------------------------

    rank = cc->SPQR_istat [4] ;
    if (rank < MIN (m,n))
    {
        // snprintf would be safer, but Windows is oblivious to safety ...
        // (Visual Studio C++ 2008 does not recognize snprintf!)
        sprintf (msg, "rank deficient. rank = %ld tol = %g\n", rank,
            cc->SPQR_xstat [1]) ;
        mexWarnMsgIdAndTxt ("MATLAB:rankDeficientMatrix", msg) ;
    }

    if (is_complex)
    {
        // free the merged complex copies of A and B
        cholmod_l_free (anz, sizeof (Complex), Ax, cc) ;
        cholmod_l_free (bnz, sizeof (Complex), Bx, cc) ;
    }

    cholmod_l_finish (cc) ;
    if (opts.spumoni > 0) spqr_mx_spumoni (&opts, is_complex, cc) ;
}
Beispiel #16
0
void mexFunction( int nlhs, mxArray *plhs[],
		  int nrhs, const mxArray*prhs[] )

{
    // Check for proper number of arguments
    if (nrhs != 5) {
	    mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:invalidNumInputs",
                "Five input arguments required.");
    }
    if (nlhs > 1) {
	    mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:maxlhs",
                "Too many output arguments. One allowed.");
    }

    // Check if key and lags are column vectors
    if (!checkRealColumnVector(KEY_IN))
	{
	    mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:invalidY",
                "previousOccurancesMEX requires that key be a column vector.");
    }

    if (!checkRealColumnVector(LAGS_IN))
	{
	    mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:invalidY",
                "previousOccurancesMEX requires that lags be a column vector.");
    }

	if (!checkRealScalar(NKINDS_IN))
	{
	    mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:invalidY",
                "previousOccurancesMEX requires that nKinds be a scalar.");
    }

    if (!checkRealScalar(MAXLAGS_IN))
	{
	    mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:invalidY",
                "previousOccurancesMEX requires that maxLags be a scalar.");
    }

    if (!checkRealColumnVector(C_IN))
	{
	    mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:invalidY",
                "previousOccurancesMEX requires that C be a column vector.");
    }

    double * const key = mxGetPr(KEY_IN);
    double * const lags = mxGetPr(LAGS_IN);
    size_t nKinds = static_cast<size_t>(mxGetScalar(NKINDS_IN));
    int const maxLags = static_cast<int>(mxGetScalar(MAXLAGS_IN));
	double * const C = mxGetPr(C_IN);
	size_t const cRows = mxGetM(C_IN);

	// Get NAN from Matlab
	mxArray *pNanValue = mxCreateDoubleScalar(mxGetNaN());
	double const nanValue = mxGetScalar(pNanValue);

	//[a,b] = size(key);
	size_t const a = mxGetM(KEY_IN);
	size_t const nLags = mxGetM(LAGS_IN);

    // Create a matrix for the return argument
	// I = nan(a,length(lags));
    I_OUT = mxCreateDoubleMatrix( static_cast<mwSize>(a), static_cast<mwSize>(nLags), mxREAL);
    // Assign pointer to the output parameter
    double * const I = mxGetPr(I_OUT);
	for (int el = 0; el < a*nLags; ++el)
		I[el] = nanValue;
	// Filling in is done column-wise, i.e. I[0]=I(1,1), I[1]=I(2,1) etc...

	//prevI = nan(nKinds,maxLags);
	double * prevI = new double[nKinds*maxLags];
	if (prevI == NULL)
	{	// Catch Null pointer = Out of memory
		mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:OutOfMemory",
			"Out-of-memory while allocating prevI with %d elements", nKinds);
	}
	for (int el = 0; el < nKinds*maxLags; ++el)
		prevI[el] = nanValue;

	double * const l_ = new double[maxLags-1];

	// for k=1:a,
	for (int k = 0; k < a; ++k)
	{
		#if DEBUG_VERBOSITY
		mexWarnMsgIdAndTxt("MATLAB:table_indexing_previousOccurancesMEX:Debug",
			"[DEBUG] k = %d", k);
		#endif // DEBUG_VERBOSITY

		unsigned int key_k = static_cast<unsigned int>( key[k] ) -1; // -1 to correct from Matlab to C index
		if (key_k >= cRows)
		{	// catch index out of bounds
			mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:IndexOutOfBounds",
				"Attempted to access C[%d] (C-style indexing); index out of bounds because numel(C)=%d", key_k,cRows);
		}
		unsigned int C_key_k = static_cast<unsigned int>( C[key_k] ) -1; // -1 to correct from Matlab to C index

		// if key(k)>size(prevI,1),
		if (key_k >= nKinds)
		{	// prevI = [prevI;nan(key(k)+10-size(prevI,1),maxLags)]; % expand lookup if necessary
			unsigned int newNrows = key_k+10;

			#if DEBUG_VERBOSITY
			mexWarnMsgIdAndTxt("MATLAB:table_indexing_previousOccurancesMEX:Debug",
				"[DEBUG] Expanding from %d to %d", nKinds, newNrows);
			#endif // DEBUG_VERBOSITY

			double * biggerPrevI = new double[newNrows*maxLags];
			if (biggerPrevI == NULL)
			{	// Catch Null pointer = Out of memory
				mexErrMsgIdAndTxt( "MATLAB:table_indexing_previousOccurancesMEX:OutOfMemory",
					"Out-of-memory while expanding prevI from %d to %d elements", nKinds, newNrows);
			}
			for (int r = 0; r < newNrows ; ++r)
			{
				for (int c = 0 ; c < maxLags ; ++c)
				{
					if (r < nKinds)
						biggerPrevI[r + c*newNrows] = prevI[r + c*nKinds];
					else
						biggerPrevI[r + c*newNrows] = nanValue;
				}
			}
			delete prevI;
			prevI = biggerPrevI;
			nKinds = newNrows;
		}

		#if DEBUG_VERBOSITY
		mexWarnMsgIdAndTxt("MATLAB:table_indexing_previousOccurancesMEX:Debug",
			"[DEBUG] key[k] = %d | C[key[k]] = %d", key_k, C_key_k);
		#endif // DEBUG_VERBOSITY

		// I(k,:) = prevI(C(key(k)),lags);
		for (int col = 0; col < nLags; ++col)
			I[k + col*a] = prevI[C_key_k + (static_cast<unsigned int>(lags[col])-1)*nKinds] +1; // -1/+1 to correct between Matlab & C indexing

		// l_ = prevI(key(k),1:(maxLags-1));
		for (int col = 0; col < maxLags-1; ++col)
			l_[col] = prevI[key_k + col*nKinds];

		// prevI(key(k),2:maxLags) = l_;
		for (int col = 1; col < maxLags;  ++col)
			prevI[key_k + col*nKinds] = l_[col-1];

		// prevI(key(k),1) = k;
		prevI[key_k] = k;
	}

    return;
}
Beispiel #17
0
void mexFunction(int nlhs,mxArray *plhs[],int nrhs, const mxArray *prhs[])
{
    // From input
    // Units of time are arbitrary but should all be the same
    double *ptrigger;   //Pointer to the triggers in ML workspace
    double *pspikes;    //Pointer to the spike in ML workspace
    double binwidth;    // Binwidth
    int nsweeps;        // Number of sweeps per correlation
    double duration;    // Total duration
    double pretime;     // Pretime
    
    // Pointer to buffer for result
    mxArray *temp;
    
    // Local variables
    double *r;
    double d;
    int rdim, thissweep, nrows, ncols;
    int idxs, idxt, idxt1, idxt2, sstart;
    int ntrig=0, nspikes=0, bin=0, count;
    
    if (nrhs<6)
        mexErrMsgTxt("eventcorr mex file: Too few input arguments\n");
    
	// Get Input arguments
    ptrigger=mxGetPr(prhs[0]);
    pspikes=mxGetPr(prhs[1]);
    binwidth=mxGetScalar(prhs[2]);
    if (binwidth<=0)
        mexErrMsgTxt("eventcorr mex file: Binwidth must be positive");
    nsweeps=(int) mxGetScalar(prhs[3]);
    duration=mxGetScalar(prhs[4]);
    if (duration<=0)
        mexErrMsgTxt("eventcorr mex file: Duration must be positive");
    pretime=mxGetScalar(prhs[5]);
    if (pretime<0)
        mexErrMsgTxt("eventcorr mex file: Pretime should be positive");

	// Floating point warnings: User can switch these off in MATLAB
	if (fmod(binwidth,1)!=0 || fmod(duration,1)!=0 || fmod(pretime,1)!=0)
		mexWarnMsgIdAndTxt("sigtool:eventcorr:tolwarn", "eventcorr mex file:\nTo avoid floating point rounding issues, binwidth duration and pretime should be whole numbers\nValues: [%20.10f %20.10f %20.10f]\n", binwidth, duration, pretime);

	if (fmod(pretime/binwidth,1)!=0)
		mexWarnMsgIdAndTxt("sigTOOL:eventcorr:pretime", "eventcorr mex file:\nPretime is not an exact multiple of the binwidth\nValues: [%20.10f %20.10f]", pretime, binwidth);
    
    
    // Size of input vectors
    ntrig=(int)*mxGetDimensions(prhs[0]);
    nspikes=(int)*mxGetDimensions(prhs[1]);
    if (ntrig==1 || nspikes==1)
        mexErrMsgTxt("eventcorr mex file: Timestamps must be supplied as column vectors");
    
    // Set up buffer for correlation
    // NB work with n*m matrices, transpose to m*n at end using MATLAB
    ncols=(int)(duration/binwidth);
    if (nsweeps==0 || ntrig<nsweeps)
    {
        // Single result
        nrows=1;
        temp=mxCreateDoubleMatrix(ncols, 1, mxREAL);
    }
    else
    {
        // Multiple
        nrows=ntrig/nsweeps;
        temp=mxCreateDoubleMatrix(ncols, nrows, mxREAL);
    }
    
    // Return timebase if required
    if (nlhs>1)
    {
        plhs[1]=mxCreateDoubleMatrix (1, ncols, mxREAL);
        r=mxGetPr(plhs[1]);
        for (bin=0; bin<ncols; bin++){
            r[bin]=-pretime+(bin*binwidth);
        }
    }
    
    // Now calculate the correlation
    r=mxGetPr(temp);
    if (r==NULL)
        mexErrMsgTxt("eventcorr mex file: mxGetPr returned NULL");
    
    sstart=0;
    count=0;
    thissweep=0;
    if (nsweeps==0)
    {
        // Use all available triggers
        for (idxt=0; idxt<ntrig; idxt++)
        {
            for (idxs=sstart; idxs<nspikes; idxs++)
            {
                d=pspikes[idxs]-(ptrigger[idxt]-pretime);
                if (d<0)
                    //ignore this spike for subsequent triggers
                    sstart=idxs;
                else
                {
                    // d positive or zero - no need for floor here
                    bin=(int)(d/binwidth);
                    if (bin<ncols)
                    {
                        // spike in range
                        r[bin]++;
                        count++;
                    }
                    else
                        // too late: no more spikes for this trigger
                        break;
                    
                }
            }
        }
    }
    else
    {    // Use nsweeps triggers per correlation
        for (idxt1=0; idxt1<ntrig-nsweeps; idxt1=idxt1+nsweeps)
        {
            for (idxt2=idxt1; idxt2<idxt1+nsweeps; idxt2++)
            {
                for (idxs=sstart; idxs<nspikes; idxs++)
                {
                    d=pspikes[idxs]-(ptrigger[idxt2]-pretime);
                    if (d<0)
                        sstart=idxs;
                    else
                    {
                        bin=(int)(d/binwidth);
                        if (bin<ncols)
                        {
                            // Add offset into matrix: Remember this is C
                            // so we are presently working with a transposed
                            // copy relative to MATLAB
                            rdim=thissweep*ncols;
                            r[bin+rdim]++;
                            count++;
                        }
                        else
                            break;
                    }
                }
            }
            thissweep++;
        }
    }
    
    // Transpose temp and return on LHS using MATLAB
    mexCallMATLAB(1,&plhs[0],1,&temp,"transpose");
    // Free buffer memory
    mxDestroyArray(temp);
    
    
}//EOF
Beispiel #18
0
void 
ann_mex_t::annkFRSearch(					// approx fixed-radius kNN search
            const mxArray*	mxQ,			// query points
            const mxArray*  mxRad,			// radius of query ball (a scalar or array of size N)
            int				k,				// number of near neighbors to return
            mxArray**		mxIdx,			// nearest neighbor array (modified)
            mxArray**       mxDst,			// dist to near neighbors (modified)
            mxArray**       mxInr,          // number of points within r of each point
            double			eps)		// error bound
{
    index_t j(0);
    
    if ( ! IsGood() )
        mexErrMsgIdAndTxt("annmex:annkFRSearch","Class integrity check failed");
    
    // check input point(s)
    // dimension of points
    if (m_idim != mxGetM(mxQ))
        mexErrMsgIdAndTxt("annmex:annkFRSearch","points dimension does not match");

    // number of query point(s)
    int nqp = mxGetN(mxQ);
   
    if ( k <= 0 )
        mexErrMsgIdAndTxt("annmex:annkFRSearch","k must be positive");
    
    if ( k > m_inpoints ) {
        // generate warning
        mexWarnMsgIdAndTxt("annmex:annkFRSearch","searching for more points than in tree - returning only %d",m_inpoints);
        k = m_inpoints;
    }
    
    int rad_array_inc = 1;
    if ( mxGetNumberOfElements(mxRad) == 1 )
        rad_array_inc = 0;
    else if ( mxGetNumberOfElements(mxRad) != nqp )
        mexErrMsgIdAndTxt("annmex:annkFRSearch","R must be either a scalar or array of size N");
    
    ANNdist* prad = new ANNdist[mxGetNumberOfElements(mxRad)];
    GetArrSq<ANNdist>(mxRad, prad);

   
    // allocate space for outputs
    *mxIdx = mxCreateNumericMatrix(k, nqp, mxIDX_CLASS, mxREAL);
    *mxDst = mxCreateNumericMatrix(k, nqp, mxDIST_CLASS, mxREAL);
    *mxInr = mxCreateNumericMatrix(1, nqp, mxINT32_CLASS, mxREAL);
    if ( *mxIdx == NULL || *mxDst == NULL || mxInr == NULL) 
        mexErrMsgIdAndTxt("annmex:annkPriSearch","cannot allocate memory for outputs");
    
    ANNidx * pidx = (ANNidx*)mxGetData(*mxIdx);
    ANNdist* pdist= (ANNdist*)mxGetData(*mxDst);
    int *    pinr = (int*)mxGetData(*mxInr);
    
    ANNpoint pp   = (ANNpoint)mxGetData(mxQ);
    
    for ( j = 0 ; j < nqp ; j++ ) {
        *pinr = m_pTree->annkFRSearch(pp, prad[rad_array_inc*j], k, pidx, pdist, eps);
        pp += m_idim;
        pidx += k;
        pdist += k;
        pinr ++;
    }
    delete [] prad; 
}
Beispiel #19
0
void mexFunction(int nlhs, mxArray *plhs[], 
    int nrhs, const mxArray *prhs[])
{
	MATLAB_ASSERT( nrhs == 2, "graphCutMex: Wrong number of input parameters: expected 2");
    MATLAB_ASSERT( nlhs <= 2, "graphCutMex: Too many output arguments: expected 2 or less");
	
	//Fix input parameter order:
	const mxArray *uInPtr = (nrhs >= 1) ? prhs[0] : NULL; //unary
	const mxArray *pInPtr = (nrhs >= 2) ? prhs[1] : NULL; //pairwise
	
	//Fix output parameter order:
	mxArray **cOutPtr = (nlhs >= 1) ? &plhs[0] : NULL; //cut
	mxArray **lOutPtr = (nlhs >= 2) ? &plhs[1] : NULL; //labels

	 //node number
	int numNodes;
    
	// get unary potentials
	MATLAB_ASSERT(mxGetNumberOfDimensions(uInPtr) == 2, "graphCutMex: The first paramater is not 2-dimensional");
	MATLAB_ASSERT(mxGetClassID(uInPtr) == MATLAB_ENERGYTERM_TYPE, "graphCutMex: Unary potentials are of wrong type");
	MATLAB_ASSERT(mxGetPi(uInPtr) == NULL, "graphCutMex: Unary potentials should not be complex");
	
	numNodes = mxGetM(uInPtr);
	
	MATLAB_ASSERT(numNodes >= 1, "graphCutMex: The number of nodes is not positive");
	MATLAB_ASSERT(mxGetN(uInPtr) == 2, "graphCutMex: The first paramater is not of size #nodes x 2");
	
	EnergyTermType* termW = (EnergyTermType*)mxGetData(uInPtr);

	//get pairwise potentials
	MATLAB_ASSERT(mxGetNumberOfDimensions(pInPtr) == 2, "graphCutMex: The second paramater is not 2-dimensional");
	
	mwSize numEdges = mxGetM(pInPtr);

	MATLAB_ASSERT( mxGetN(pInPtr) == 4, "graphCutMex: The second paramater is not of size #edges x 4");
	MATLAB_ASSERT(mxGetClassID(pInPtr) == MATLAB_ENERGYTERM_TYPE, "graphCutMex: Pairwise potentials are of wrong type");

	EnergyTermType* edges = (EnergyTermType*)mxGetData(pInPtr);
	for(int i = 0; i < numEdges; i++)
	{
		MATLAB_ASSERT(1 <= round(edges[i]) && round(edges[i]) <= numNodes, "graphCutMex: error in pairwise terms array: wrong vertex index");
		MATLAB_ASSERT(isInteger(edges[i]), "graphCutMex: error in pairwise terms array: wrong vertex index");
		MATLAB_ASSERT(1 <= round(edges[i + numEdges]) && round(edges[i + numEdges]) <= numNodes, "graphCutMex: error in pairwise terms array: wrong vertex index");
		MATLAB_ASSERT(isInteger(edges[i + numEdges]), "graphCutMex: error in pairwise terms array: wrong vertex index");
		MATLAB_ASSERT(edges[i + 2 * numEdges] + edges[i + 3 * numEdges] >= 0, "graphCutMex: error in pairwise terms array: nonsubmodular edge");
	}


	// start computing
	if (nlhs == 0){
		return;
	}

	//prepare graph
	GraphType *g = new GraphType( numNodes, numEdges); 
	
	for(int i = 0; i < numNodes; i++)
	{
		g -> add_node(); 
		g -> add_tweights( i, termW[i], termW[numNodes + i]); 
	}
	
	for(int i = 0; i < numEdges; i++)
		if(edges[i] < 1 || edges[i] > numNodes || edges[numEdges + i] < 1 || edges[numEdges + i] > numNodes || edges[i] == edges[numEdges + i] || !isInteger(edges[i]) || !isInteger(edges[numEdges + i])){
			mexWarnMsgIdAndTxt("graphCutMex:pairwisePotentials", "Some edge has invalid vertex numbers and therefore it is ignored");
		}
		else
			if(edges[2 * numEdges + i] + edges[3 * numEdges + i] < 0){
				mexWarnMsgIdAndTxt("graphCutMex:pairwisePotentials", "Some edge is non-submodular and therefore it is ignored");
			}
			else
			{
				if (edges[2 * numEdges + i] >= 0 && edges[3 * numEdges + i] >= 0)
					g -> add_edge((GraphType::node_id)round(edges[i] - 1), (GraphType::node_id)round(edges[numEdges + i] - 1), edges[2 * numEdges + i], edges[3 * numEdges + i]);
				else
					if (edges[2 * numEdges + i] <= 0 && edges[3 * numEdges + i] >= 0)
					{
						g -> add_edge((GraphType::node_id)round(edges[i] - 1), (GraphType::node_id)round(edges[numEdges + i] - 1), 0, edges[3 * numEdges + i] + edges[2 * numEdges + i]);
						g -> add_tweights((GraphType::node_id)round(edges[i] - 1), 0, edges[2 * numEdges + i]); 
						g -> add_tweights((GraphType::node_id)round(edges[numEdges + i] - 1),0 , -edges[2 * numEdges + i]); 
					}
					else
						if (edges[2 * numEdges + i] >= 0 && edges[3 * numEdges + i] <= 0)
						{
							g -> add_edge((GraphType::node_id)round(edges[i] - 1), (GraphType::node_id)round(edges[numEdges + i] - 1), edges[3 * numEdges + i] + edges[2 * numEdges + i], 0);
							g -> add_tweights((GraphType::node_id)round(edges[i] - 1),0 , -edges[3 * numEdges + i]); 
							g -> add_tweights((GraphType::node_id)round(edges[numEdges + i] - 1), 0, edges[3 * numEdges + i]); 
						}
						else
							mexWarnMsgIdAndTxt("graphCutMex:pairwisePotentials", "Something strange with an edge and therefore it is ignored");
			}

	//compute flow
	EnergyType flow = g -> maxflow();

	//output minimum value
	if (cOutPtr != NULL){
		*cOutPtr = mxCreateNumericMatrix(1, 1, MATLAB_ENERGY_TYPE, mxREAL);
		*(EnergyType*)mxGetData(*cOutPtr) = (EnergyType)flow;
	}

	//output minimum cut
	if (lOutPtr != NULL){
		*lOutPtr = mxCreateNumericMatrix(numNodes, 1, MATLAB_LABEL_TYPE, mxREAL);
		LabelType* segment = (LabelType*)mxGetData(*lOutPtr);
		for(int i = 0; i < numNodes; i++)
			segment[i] = g -> what_segment(i);
	}
    
    delete g;
}
Beispiel #20
0
/**
 * @brief Interfaces C and Matlab data.
 * This function is the MEX-file gateway routine. Please see the Matlab
 * MEX-file documentation (http://www.mathworks.com/access/helpdesk/help/techdoc/matlab_external/f43721.html)
 * for more information.
 */
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{

  /* allocate variables */
  struct input *X;
  struct options_direct *opts;
  int m,p,n,z;
  int p_total,P_total;
  int W;
  int *P_vec;
  mxArray *mxbinned;
  int **binned,*binned_temp;
  int cur_P;
  int status;
  int temp_N;

  /* check number of inputs (nargin) and outputs (nargout) */
  if((nrhs<1) | (nrhs>2))
    mexErrMsgIdAndTxt("STAToolkit:directbin:numArgs","1 or 2 input arguments required.");
  if((nlhs<1) | (nlhs>2))
    mexErrMsgIdAndTxt("STAToolkit:directbin:numArgs","1 or 2 output arguments required.");

  X = ReadInput(prhs[0]);

  /* get or set options */
  if(nrhs<2)
    opts = ReadOptionsDirect(mxCreateEmptyStruct());
  else if(mxIsEmpty(prhs[1]))
    opts = ReadOptionsDirect(mxCreateEmptyStruct());
  else
    opts = ReadOptionsDirect(prhs[1]);

  /* Read in time range */
  ReadOptionsDirectTimeRange(opts,X);
  
  /* check options */
  if(opts->Delta_flag==0)
    {
      opts[0].Delta = (*opts).t_end-(*opts).t_start;
      opts[0].Delta_flag=1;
      mexWarnMsgIdAndTxt("STAToolkit:directbin:missingParameter","Missing parameter counting_bin_size. Using default value end_time-start_time=%f.\n",opts[0].Delta);
    }
  
  if(opts->Delta <= 0)
    {
      mxFree(opts);
      mxFreeInput(X); 
      mexErrMsgIdAndTxt("STAToolkit:directbin:invalidValue","counting_bin_size must be positive. It is currently set to %f.\n",opts[0].Delta);
    }

  if(opts->words_per_train_flag==0)
    {
      opts[0].words_per_train = (int)DEFAULT_WORDS_PER_TRAIN;
      opts[0].words_per_train_flag=1;
      mexWarnMsgIdAndTxt("STAToolkit:directbin:missingParameter","Missing parameter words_per_train. Using default value %d.\n",opts[0].words_per_train);
    }

  if(opts->words_per_train <= 0)
    {
      mxFree(opts);
      mxFreeInput(X); 
      mexErrMsgIdAndTxt("STAToolkit:directbin:invalidValue","words_per_train must be positive. It is currently set to %d.\n",opts[0].words_per_train);
    }

 if(opts->legacy_binning_flag==0)
    {
      opts[0].legacy_binning = (int)DEFAULT_LEGACY_BINNING;
      opts[0].legacy_binning_flag=1;
      mexWarnMsgIdAndTxt("STAToolkit:directbin:missingParameter","Missing parameter legacy_binning. Using default value %d.\n",opts[0].legacy_binning);
    }

  if((opts->legacy_binning!=0) & (opts->legacy_binning!=1))
    {
      mxFree(opts);
      mxFreeInput(X); 
      mexErrMsgIdAndTxt("STAToolkit:directbin:invalidValue","Option legacy_binning set to an invalid value. Must be 0 or 1. It is currently set to %d.\n",opts[0].legacy_binning);
    }

 if(opts->letter_cap_flag==0)
    {
      opts[0].letter_cap = (int)DEFAULT_LETTER_CAP;
      opts[0].letter_cap_flag=1;
      mexWarnMsgIdAndTxt("STAToolkit:directbin:missingParameter","Missing parameter letter_cap. Using default value %d.\n",opts[0].letter_cap);
    }

  if(opts->letter_cap<0)
    {
      mxFree(opts);
      mxFreeInput(X); 
      mexErrMsgIdAndTxt("STAToolkit:directbin:invalidValue","Option letter_cap set to an invalid value. Must be a positive integer or Inf. It is currently set to %d.\n",opts[0].letter_cap);
    }

  if((*X).N>1)
    {
      if(opts->sum_spike_trains_flag==0)
	{
	  opts[0].sum_spike_trains = (int)DEFAULT_SUM_SPIKE_TRAINS;
	  opts[0].sum_spike_trains_flag=1;
	  mexWarnMsgIdAndTxt("STAToolkit:directbin:missingParameter","Missing parameter sum_spike_trains. Using default value %d.\n",opts[0].sum_spike_trains);
	}

      if((opts->sum_spike_trains!=0) & (opts->sum_spike_trains!=1))
        {
          mxFree(opts);
          mxFreeInput(X); 
	  mexErrMsgIdAndTxt("STAToolkit:directbin:invalidValue","Option sum_spike_trains set to an invalid value. Must be 0 or 1. It is currently set to %d.\n",(*opts).sum_spike_trains);
        }
      
      if(opts->permute_spike_trains_flag==0)
	{
	  opts[0].permute_spike_trains = (int)DEFAULT_PERMUTE_SPIKE_TRAINS;
	  opts[0].permute_spike_trains_flag=1;
	  mexWarnMsgIdAndTxt("STAToolkit:directbin:missingParameter","Missing parameter permute_spike_trains. Using default value %d.\n",opts[0].permute_spike_trains);
	}

      if((opts->permute_spike_trains!=0) & (opts->permute_spike_trains!=1))
        {
          mxFree(opts);
          mxFreeInput(X); 
	  mexErrMsgIdAndTxt("STAToolkit:directbin:invalidValue","Option permute_spike_trains set to an invalid value. Must be 0 or 1. It is currently set to %d.\n",(*opts).permute_spike_trains);
        }
    }

  P_total = GetNumTrials(X);
  /* W is the number of letters in a word */
  W=GetWindowSize(opts);

  /* Allocate memory for pointers to pointers */
  if(opts[0].sum_spike_trains)
    temp_N = 1;
  else
    temp_N = X[0].N;
  binned = mxMatrixInt((*opts).words_per_train*P_total,temp_N*W);

  /* Allocate memory for P_vec */
  P_vec = (int *)mxMalloc((*X).M*sizeof(int));

  /* Do computation */
  status = DirectBinComp(X,opts,(*opts).words_per_train*P_total,W,P_vec,binned);
  if(status==EXIT_FAILURE)
    {
      mxFree(opts);
      mxFreeInput(X); 
      mxFreeMatrixInt(binned);
      mxFree(P_vec);
      mexErrMsgIdAndTxt("STAToolkit:directbin:failure","directbin failed.");
    }

  /* Create binned cell array */
  plhs[0] = mxCreateCellMatrix((*X).M,(*opts).words_per_train);
  p_total = 0;

  for(m=0;m<(*X).M;m++)
    {
      cur_P = (*X).categories[m].P;
      for(z=0;z<(*opts).words_per_train;z++)
	{
	  /* vectorize and transpose this matrix */
	  binned_temp = (int *)mxMalloc(W*temp_N*cur_P*sizeof(int));
	  
	  for(p=0;p<cur_P;p++)
	    for(n=0;n<temp_N*W;n++)
	      binned_temp[n*cur_P + p]=binned[p_total+p][n];
	  
	  p_total += cur_P;
      
	  mxbinned = mxCreateNumericMatrix(cur_P,temp_N*W,mxINT32_CLASS,mxREAL);
	  memcpy(mxGetData(mxbinned),binned_temp,cur_P*temp_N*W*sizeof(int));

	  mxSetCell(plhs[0],z*(*X).M+m,mxbinned);
	  
	  mxFree(binned_temp);
	}
    }

  /* output options used */
  if(nrhs<2)
    plhs[1] = WriteOptionsDirect(mxCreateEmptyStruct(),opts);
  else if(mxIsEmpty(prhs[1]))
    plhs[1] = WriteOptionsDirect(mxCreateEmptyStruct(),opts);
  else
    plhs[1] = WriteOptionsDirect(prhs[1],opts);

  /* free memory */
  mxFreeInput(X); 
  mxFreeMatrixInt(binned);
  mxFree(P_vec);

  return;
}
//parse the matlab struct to get all the options for training
CvRTParams* parse_struct_to_forest_config(const mxArray *trainingOptions) {
    int numFields = 0;
    if (trainingOptions != NULL) {
        numFields = mxGetNumberOfFields(trainingOptions);
    }

    mexPrintf("%d training fields provided\n", numFields);

    //these should be the default values that we would get from instantiating
    //a CvRTParams object.
    int maxDepth = DEFAULT_MAX_DEPTH;
    int minSampleCount = DEFAULT_MIN_SAMPLE_COUNT;
    float regressionAccuracy = DEFAULT_REGRESSION_ACCURACY;
    bool useSurrogates = DEFAULT_USE_SURROGATES;
    int maxCategories = DEFAULT_MAX_CATEGORIES;
    float* priors = DEFAULT_PRIORS;
    bool calcVarImportance = DEFAULT_CALC_VAR_IMPORTANCE;
    int numActiveVars = DEFAULT_NUM_ACTIVE_VARS;
    int maxTreeCount = DEFAULT_MAX_TREE_COUNT;
    float forestAccuracy = DEFAULT_FOREST_ACCURACY;
    int termCriteriaType = DEFAULT_TERM_CRITERIA_TYPE;

    for (int i=0; i < numFields; i++) {
        const char *name = mxGetFieldNameByNumber(trainingOptions, i);
        mexPrintf("field %d is %s\n",i,name);
        mxArray *field = mxGetFieldByNumber(trainingOptions, 0, i);
        if (num_elements(field) != 1) { 
            mexWarnMsgIdAndTxt("train_random_forest:non_scalar_option", 
                               "field is not a scalar! cannot parse into Random Forest options.");
            continue;
        }
        
        //now need to compare against all the names we recognise
        if (strcmp(name, "max_depth") == 0) {
            if (mxIsInt32(field)) {
                maxDepth = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","max_depth field must be a int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "min_sample_count") == 0) {
            if (mxIsInt32(field)) {
                minSampleCount = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","min_sample_count field must be a int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "regression_accuracy") == 0) {
            if (mxIsDouble(field)) {
                regressionAccuracy = (float)SCALAR_GET_DOUBLE(field);
            }
            else if (mxIsSingle(field)) {
                regressionAccuracy = SCALAR_GET_SINGLE(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_float","regression_accuracy field must be a single or double. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "use_surrogates") == 0) {
            if (mxIsLogicalScalar(field)) {
                useSurrogates = mxIsLogicalScalarTrue(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_bool","use_surrogates field must be a boolean/logical. skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "max_categories") == 0) {
            if (mxIsInt32(field)) {
                maxCategories = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","max_categories field must be an int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "calc_var_importance") == 0) {
            if (mxIsLogicalScalar(field)) {
                calcVarImportance = mxIsLogicalScalarTrue(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_bool","calc_var_importance field must be a boolean/logical. skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "num_active_vars") == 0) {
            if (mxIsInt32(field)) {
                numActiveVars = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","num_active_vars field must be an int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "max_tree_count") == 0) {
            if (mxIsInt32(field)) {
                maxTreeCount = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","max_tree_count field must be an int32. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "forest_accuracy") == 0) {
            if (mxIsDouble(field)) {
                forestAccuracy = (float)SCALAR_GET_DOUBLE(field);
            }
            else if (mxIsSingle(field)) {
                forestAccuracy = SCALAR_GET_SINGLE(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_float","forest_accuracy field must be a float. Skipping...\n");
            }
            continue;
        }
        else if (strcmp(name, "term_criteria_type") == 0) {
            if (mxIsInt32(field)) {
                termCriteriaType = SCALAR_GET_SINT32(field);
            }
            else {
                mexWarnMsgIdAndTxt("train_random_forest:not_int32","term_critera_type field must be an int32. Skipping...\n");
            }
            continue;
        }
        else {
            char msgbuf[ERR_MSG_SIZE];
            sprintf(msgbuf,"field provided was not recognised: %s",name);
            mexWarnMsgIdAndTxt("train_random_forest:unrecognised_field",msgbuf);
        }
    }

    return new CvRTParams(maxDepth, minSampleCount, regressionAccuracy,
                          useSurrogates, maxCategories, priors,
                          calcVarImportance, numActiveVars, maxTreeCount,
                          forestAccuracy, termCriteriaType);
}
Beispiel #22
0
bool GB_mx_mxArray_to_indices       // true if successful, false otherwise
(
    GrB_Index **handle,             // index array returned
    const mxArray *I_matlab,        // MATLAB mxArray to get
    GrB_Index *ni,                  // length of I, or special
    GrB_Index Icolon [3],           // for all but GB_LIST
    bool *I_is_list                 // true if GB_LIST
)
{

    (*handle) = NULL ;

    mxArray *X ;
    GrB_Index *I ;

    if (I_matlab == NULL || mxIsEmpty (I_matlab))
    {
        I = (GrB_Index *) GrB_ALL ;       // like the ":" in C=A(:,j)
        (*ni) = 0 ;
        (*handle) = I ;
        (*I_is_list) = false ;
        // Icolon not used
        // printf ("got index (:)\n") ;
    }
    else
    {
        if (mxIsStruct (I_matlab))
        {
            // a struct with 3 integers: I.begin, I.inc, I.end
            (*I_is_list) = false ;

            // look for I.begin (required)
            int fieldnumber = mxGetFieldNumber (I_matlab, "begin") ;
            if (fieldnumber < 0)
            {
                mexWarnMsgIdAndTxt ("GB:warn","I.begin missing") ;
                return (false) ;
            }
            X = mxGetFieldByNumber (I_matlab, 0, fieldnumber) ;
            Icolon [GxB_BEGIN] = (int64_t) mxGetScalar (X) ;

            // look for I.end (required)
            fieldnumber = mxGetFieldNumber (I_matlab, "end") ;
            if (fieldnumber < 0)
            {
                mexWarnMsgIdAndTxt ("GB:warn","I.end missing") ;
                return (false) ;
            }
            mxArray *X ;
            X = mxGetFieldByNumber (I_matlab, 0, fieldnumber) ;
            Icolon [GxB_END] = (int64_t) mxGetScalar (X) ;

            // look for I.inc (optional)
            fieldnumber = mxGetFieldNumber (I_matlab, "inc") ;
            if (fieldnumber < 0)
            {
                (*ni) = GxB_RANGE ;
                Icolon [GxB_INC] = 1 ;
                // printf ("got range ("GBd":"GBd")\n",
                //     Icolon [GxB_BEGIN], Icolon [GxB_END]) ;
            }
            else
            {
                // 
                X = mxGetFieldByNumber (I_matlab, 0, fieldnumber) ;
                int64_t iinc = (int64_t) mxGetScalar (X) ;
                if (iinc == 0)
                {
                    // this can be either a stride, or backwards.  Either 
                    // one works the same, but try a mixture, just for testing.
                    (*ni) = (Icolon [GxB_BEGIN] % 2) ?
                        GxB_STRIDE : GxB_BACKWARDS ;
                    Icolon [GxB_INC] = 0 ;
                }
                else if (iinc > 0)
                {
                    (*ni) = GxB_STRIDE ;
                    Icolon [GxB_INC] = iinc ;
                }
                else
                {
                    // GraphBLAS must be given the magnitude of the stride
                    (*ni) = GxB_BACKWARDS ;
                    Icolon [GxB_INC] = -iinc ;
                }
                // printf ("got stride ("GBd":"GBd":"GBd")\n",
                //     Icolon [GxB_BEGIN], Icolon [GxB_INC], Icolon [GxB_END]) ;
            }
            (*handle) = Icolon ;

        }
        else
        {
            if (!mxIsClass (I_matlab, "uint64"))
            {
                mexWarnMsgIdAndTxt ("GB:warn","indices must be uint64") ;
                return (false) ;
            }

            (*I_is_list) = true ;
            I = mxGetData (I_matlab) ;
            (*ni) = (uint64_t) mxGetNumberOfElements (I_matlab) ;
            (*handle) = I ;
            // printf ("got index list, size "GBd"\n", (int64_t) (*ni)) ;
        }
    }

    return (true) ;
}
Beispiel #23
0
void mexFunction(int nlhs, mxArray *plhs[],
      int nrhs, const mxArray *prhs[])
{
	int cid=-1;  // Handle of the current connection (invalid until we identify)
	int jarg=0;  // Number of first string arg: becomes 1 if id is specified

	/*********************************************************************/
	// Parse the first argument to see if it is a specific database handle
	if ( nrhs>0 && mxIsNumeric(prhs[0]) )
		{ if ( mxGetM(prhs[0])!=1 || mxGetN(prhs[0])!=1 )
			{ showusage();
			  mexPrintf("First argument is array %d x %d, but it should be a scalar\n",
			      mxGetM(prhs[0]),mxGetN(prhs[0]) );
			  mexErrMsgTxt("Invalid connection handle"); }
		  double xid = *mxGetPr(prhs[0]);
		  cid = int(xid);
		  if ( double(cid)!=xid || cid<0 || cid>=MAXCONN )
			{ showusage();
			  mexPrintf("dbHandle = %g -- Must be integer between 0 and %d\n",
			      xid,MAXCONN-1);
			  mexErrMsgTxt("Invalid connection handle"); }
		  jarg = 1;
		  if (debug) mexPrintf("| Explicit  cid = %d\n",cid); }

	/*********************************************************************/
	//  Check that the remaining arguments are all character strings
	{ for ( int j=jarg ; j<nrhs ; j++ )
		{ if (!mxIsChar(prhs[j]))
			{ showusage();
			  mexErrMsgTxt("All args must be strings, except dbHandle"); }}}

	/*********************************************************************/
	//  Identify what action he wants to do

	enum querytype { OPEN, CLOSE, CLOSEALL, USENAMED, USE,
	                     STATUS, STATSALL, QUOTE, CMD } q;
	char *query = NULL;

	if (nrhs<=jarg)   q = STATSALL;
	else
		{ query = mxArrayToString(prhs[jarg]);
		  if (streq(query,"open"))          q = OPEN;
		  else if (streq(query,"close"))    q = CLOSE;
		  else if (streq(query,"closeall")) q = CLOSEALL;
		  else if (streq(query,"use"))      q = USENAMED;
		  else if (streq(query,"use",3))    q = USE;
		  else if (streq(query,"status"))   q = STATUS;
		  else if (streq(query,"quote"))    q = QUOTE;
		  else q = CMD; }

	if (debug)
		{ switch(q)
			{ case OPEN:     mexPrintf("| q = OPEN\n");     break;
			  case CLOSE:    mexPrintf("| q = CLOSE\n");    break;
			  case CLOSEALL: mexPrintf("| q = CLOSEALL\n"); break;
			  case USENAMED: mexPrintf("| q = USENAMED\n"); break;
			  case USE:      mexPrintf("| q = USE\n");      break;
			  case STATUS:   mexPrintf("| q = STATUS\n");   break;
			  case STATSALL: mexPrintf("| q = STATSALL\n"); break;
			  case QUOTE:    mexPrintf("| q = QUOTE\n");    break;
			  case CMD:      mexPrintf("| q = CMD\n");      break;
			                 mexPrintf("| q = ??\n");              }}

	/*********************************************************************/
	//  If he did not specify the handle, choose the appropriate one
	//  If there are no previous connections, then we will still have
	//     cid=-1, and this will be handled in the appropriate place.
	if (jarg==0)
		{
		if (q==OPEN)
			{ for ( cid=0 ; cid<MAXCONN & c[cid].isopen ; cid++ );
			  if (cid>=MAXCONN) mexErrMsgTxt("Can\'t find free handle"); }
		else if (ncid>0)
			cid=prevcid[ncid-1];
		}

	if (debug) mexPrintf("| cid = %d\n",cid);

	//  Shorthand notation so we don't need to write c[cid]...
	//  These values must not be used if  cid<0
	mp dummyconn;     mp &conn = (cid>=0) ? c[cid].conn : dummyconn;
	bool dummyisopen; bool &isopen = (cid>=0) ? c[cid].isopen : dummyisopen;

	if (q==OPEN)
		{
		if (cid<0)
			{ mexPrintf("cid = %d !\n",cid);
			  mexErrMsgTxt("Internal code error\n"); }
		//  Close connection if it is open
		if (isopen)
			{ mexWarnMsgIdAndTxt("mysql:ConnectionAlreadyOpen",
			    "Connection %d has been closed and overwritten",cid);
			  mysql_close(conn);
			  conn=NULL;  isopen=false;  stackdelete(cid); }

		//  Extract information from input arguments
		char *host=NULL;   if (nrhs>=jarg+2)  host = mxArrayToString(prhs[jarg+1]);
		char *user=NULL;   if (nrhs>=jarg+3)  user = mxArrayToString(prhs[jarg+2]);
		char *pass=NULL;   if (nrhs>=jarg+4)  pass = mxArrayToString(prhs[jarg+3]);
		int port = hostport(host);  // returns zero if there is no port

		if (nlhs<1)
			{ mexPrintf("Connecting to  host=%s", (host) ? host : "localhost" );
			  if (port) mexPrintf("  port=%d",port);
			  if (user) mexPrintf("  user=%s",user);
			  if (pass) mexPrintf("  password=%s",pass);
			  mexPrintf("\n"); }

		//  Establish and test the connection
		//  If this fails, then conn is still set, but isopen stays false
		if (!(conn=mysql_init(conn)))
			mexErrMsgTxt("Couldn\'t initialize MySQL connection object");
		if (!mysql_real_connect( conn, host, user, pass, NULL,port,NULL,0 ))
			mexErrMsgTxt(mysql_error(conn));
		const char *c=mysql_stat(conn);
		if (c)  { if (nlhs<1) mexPrintf("%s\n",c); }
		else    mexErrMsgTxt(mysql_error(conn));

		isopen=true;
		ncid++;
		if (ncid>MAXCONN)
			{ mexPrintf("ncid = %d ?\n",ncid);
			  mexErrMsgTxt("Internal logic error\n"); }
		prevcid[ncid-1] = cid;

		if (debug) stackprint();

		//  Now we are OK -- return the connection handle opened.
		setScalarReturn(nlhs,plhs,cid);
		}

	else if (q==CLOSE)
		{
		if ( cid>=0 && isopen )
			{ if (debug) mexPrintf("| Closing %d\n",cid);
			  mysql_close(conn);
			  conn = NULL; isopen=false;  stackdelete(cid); }
		if (debug) stackprint();
		}

	else if (q==CLOSEALL)
		{ while (ncid>0)
			{ if (debug) stackprint();
			  cid = prevcid[ncid-1];
			  if (debug) mexPrintf("| Closing %d\n",cid);
			  if (!(c[cid].isopen))
				{ mexPrintf("Connection %d is not marked open!\n",cid);
				  mexErrMsgTxt("Internal logic error"); }
			  mysql_close(c[cid].conn);
			  c[cid].conn=NULL;  c[cid].isopen=false;  ncid--; }}

	else if ( q==USE || q==USENAMED )
		{
		if ( cid<0 || !isopen ) mexErrMsgTxt("Not connected");
		if (mysql_ping(conn))
			{ stackdelete(cid);  isopen=false;
			  mexPrintf(mysql_error(conn));
			  mexPrintf("\nClosing connection %d\n",cid);
			  mexErrMsgTxt("Use command failed"); }
		char *db=NULL;
		if (q==USENAMED)
			{ if (nrhs>=2) db=mxArrayToString(prhs[jarg+1]);
			  else         mexErrMsgTxt("Must specify a database to use"); }
		else
			{ db = query + 3;
			  while ( *db==' ' || *db=='\t' ) db++; }
		if (mysql_select_db(conn,db))  mexErrMsgTxt(mysql_error(conn));
		if (nlhs<1) mexPrintf("Current database is \"%s\"\n",db); 
		else        setScalarReturn(nlhs,plhs,1.);
		}

	else if (q==STATUS)
		{
		if (nlhs<1)  //  He wants a report
			{ // print connection handle only if multiple connections
			  char idstr[10];  idstr[0]=0;
			  if ( cid>=0 && ncid>1 )  sprintf(idstr,"(%d) ",cid);
			  if ( cid<0 || !isopen )
			   { mexPrintf("%sNot connected\n",idstr,cid);  return; }
			  if (mysql_ping(conn))
				{ mexErrMsgTxt(mysql_error(conn)); }
			  mexPrintf("%s%-30s   Server version %s\n",
			    idstr, mysql_get_host_info(conn), mysql_get_server_info(conn) ); }
		else         //  He wants a return value for this connection
			{ double *pr=setScalarReturn(nlhs,plhs,0.);
			  if ( cid<0 || !isopen ) { *pr=1.; return; }
			  if (mysql_ping(conn))   { *pr=2.; return; }}
		}

	else if (q==STATSALL)
		{
		if (debug) stackprint();
		if (ncid==0)      mexPrintf("No connections open\n");
		else if (ncid==1) mexPrintf("1 connection open\n");
		else              mexPrintf("%d connections open\n",ncid);
		for ( int j=0 ; j<ncid ; j++ )
			{ cid = prevcid[j];
			  if (mysql_ping(c[cid].conn))
				  mexPrintf("%2d:  %s\n",cid,mysql_error(conn));
			  else
				  mexPrintf("%2d:  %-30s   Server version %s\n",
				        cid, mysql_get_host_info(c[cid].conn),
				        mysql_get_server_info(c[cid].conn) ); }
		}

	// Quote the second string argument and return it (Chris Rodgers)
	else if (q==QUOTE)
		{
		if ((nrhs-jarg)!=2)
			mexErrMsgTxt("mysql('quote','string_to_quote') takes two string arguments!");

		//  Check that we have a valid connection
		if ( cid<0 || !isopen ) mexErrMsgTxt("No connection open");
		if (mysql_ping(conn))
			{ stackdelete(cid);  isopen=false;
			  mexErrMsgTxt(mysql_error(conn)); }

		const mxArray *a = prhs[jarg+1];
		int llen = mxGetM(a)*mxGetN(a)*sizeof(mxChar);
		char *from = (char *) mxCalloc(llen+1,sizeof(char));
		if (mxGetString(a,from,llen)) mexErrMsgTxt("Can\'t copy string");
		int l = strlen(from);

		/* Allocate memory for input and output strings. */
		char *to = (char*) mxCalloc( llen*2+3, sizeof(char));

		/* Call the C subroutine. */
		to[0] = '\'';
		int n = mysql_real_escape_string( conn, to+1, from, l );
		to[n+1] = '\'';

		/* Set C-style string output_buf to MATLAB mexFunction output*/
		plhs[0] = mxCreateString(to);

		mxFree(from);  mxFree(to);  // just in case Matlab forgets
		}

	else if (q==CMD)
		{
		//  Check that we have a valid connection
		if ( cid<0 || !isopen ) mexErrMsgTxt("No connection open");
		if (mysql_ping(conn))
			{ stackdelete(cid);  isopen=false;
			  mexPrintf(mysql_error(conn));
			  mexPrintf("Closing connection %d\n",cid);
			  mexErrMsgTxt("Query failed"); }

		//  Execute the query (data stays on server)
		if (mysql_query(conn,query))  mexErrMsgTxt(mysql_error(conn));

		//  Download the data from server into our memory
		//     We need to be careful to deallocate res before returning.
		//  Matlab's allocation routines return instantly if there is not
		//  enough free space, without giving us time to dealloc res.
		//  This is a potential memory leak but I don't see how to fix it.
		MYSQL_RES *res = mysql_store_result(conn);

		//  As recommended in Paul DuBois' MySQL book (New Riders, 1999):
		//  A NULL result set after the query can indicate either
		//    (1) the query was an INSERT, DELETE, REPLACE, or UPDATE, that
		//        affect rows in the table but do not return a result set; or
		//    (2) an error, if the query was a SELECT, SHOW, or EXPLAIN
		//        that should return a result set but didn't.
		//  Distinguish between the two by checking mysql_field_count()
		//  We return in either case, either correctly or with an error
		if (!res)
			{
			if (!mysql_field_count(conn))
				{ unsigned long nrows=mysql_affected_rows(conn);
				  if (nlhs<1)
					{ mexPrintf("%u rows affected\n",nrows);
					  return; }
				  else
					{ setScalarReturn(nlhs,plhs,nrows);
					  return; }}
			else
				  mexErrMsgTxt(mysql_error(conn));
			}

		unsigned long nrow=mysql_num_rows(res), nfield=mysql_num_fields(res);

		//  If he didn't ask for any output (nlhs=0),
		//       then display the output and return
		if ( nlhs<1 )
			{ fancyprint(res);
			  mysql_free_result(res);
			  return; }

		//  If we are here, he wants output
		//  He must give exactly the right number of output arguments
// 		if ( nlhs != nfield )
// 			{ mysql_free_result(res);
// 			  mexPrintf("You specified %d output arguments, "
// 			         "and got %d columns of data\n",nlhs,nfield);
// 			  mexErrMsgTxt("Must give one output argument for each column"); }
        
        if(nlhs > 1) mexErrMsgIdAndTxt( "MYSQL query: ",
                        "Too many output arguments.");

		//  Fix the column types to fix MySQL C API sloppiness
		MYSQL_FIELD *f = mysql_fetch_fields(res);
		fix_types( f, res );

		//  Create the Matlab arrays for output
// 		double **pr = (double **) mxMalloc( nfield * sizeof(double *) );
// 		{ for ( int j=0 ; j<nfield ; j++ )
// 			{ if ( can_convert(f[j].type) )
// 				{ if (!( plhs[j] = mxCreateDoubleMatrix( nrow, 1, mxREAL ) ))
// 					{ mysql_free_result(res);
// 					  mexErrMsgTxt("Unable to create numeric matrix for output"); }
// 				  pr[j] = mxGetPr(plhs[j]); }
// 			  else
// 				{ if (!( plhs[j] = mxCreateCellMatrix( nrow, 1 ) ))
// 					{ mysql_free_result(res);
// 					  mexErrMsgTxt("Unable to create cell matrix for output"); }
// 				  pr[j] = NULL; }}}
        
         if (!( plhs[0] = mxCreateCellMatrix( nrow, nfield ) )){
					 mysql_free_result(res);
                     mexErrMsgTxt("Unable to create cell matrix for output");                 
         }

		//  Load the data into the cells
		mysql_data_seek(res,0);
		for ( int i=0 ; i<nrow ; i++ ){ 
			  MYSQL_ROW row = mysql_fetch_row(res);
			  if (!row) { 
				mexPrintf("Scanning row %d for data extraction\n",i+1);
				  mexErrMsgTxt("Internal error:  Failed to get a row"); }
// 			  for ( int j=0 ; j<nfield ; j++ ){ 
//                   if (can_convert(f[j].type)) { 
// 					pr[j][i] = field2num(row[j],f[j].type); 
//                   }
// 				  else {
// 					 mxArray *c = mxCreateString(row[j]);
// 					  mxSetCell(plhs[j],i,c); 
//                   }
//               }
             for ( int j=0 ; j <nfield ; j++ ){
                 mxArray *c = mxCreateString(row[j]);
 					  mxSetCell(plhs[0],j*nrow + i,c); 
             }
        }
		mysql_free_result(res);
		}
	else
		{ mexPrintf("Unknown query type q = %d\n",q);
		  mexErrMsgTxt("Internal code error"); }
}
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{

	/* Declare Inputs*/
	double *xCurr;
	double *parameters;
	double *timepoints;
	int numTimepts;

	/* Load input values from prhs */
	xCurr = mxGetPr(prhs[0]);
	parameters = mxGetPr(prhs[1]);

	/* Get the program related options
	 * from the structure.
	 */
	char *panicFileName = NULL;
	//char defaultPanicFileName[] = "panic_log.txt";

	char *periodicFileName = NULL;
	//char defaultperiodicFileName[] = "periodic_log.txt";
	long long unsigned *maxHistory = NULL;
	long long unsigned *period = NULL;
	bool assignedDefault[NUM_OF_FIELDS] =
	{ false };
	/* pointer to field names */
	const char **fnames;

	int numFields;
	mwSize NStructElems;
	mxArray *fields[MAX_FIELDS];

	const mxArray *struct_array = prhs[2];
	mxClassID classIDflags[] =
	{ mxCHAR_CLASS, mxCHAR_CLASS, mxUINT64_CLASS, mxUINT64_CLASS };

	/* check if the input in struct_array is a structure */
	if (mxIsStruct(struct_array) == false)
	{
		mexErrMsgIdAndTxt("SSA:programOptions:inputNotStruct",
				"Input must be a structure.");
	}

	/* get number of elements in structure */
	numFields = mxGetNumberOfFields(struct_array);
	mexPrintf("Number of fields provided in structure %d \n", numFields);
	if (numFields != NUM_OF_FIELDS)
	{
		mexWarnMsgIdAndTxt("SSA:programOptions:NumOfStructElementMismatch",
				"The expected number of elements in structure does not match with the provided\n");
		mexPrintf("Expected vs Provided : %d  %d\n", NUM_OF_FIELDS, numFields);
	}

	NStructElems = mxGetNumberOfElements(struct_array);
	mexPrintf("Number of elements in structure %d \n", NStructElems);
	/* allocate memory  for storing pointers */
	fnames = (const char**) mxCalloc(numFields, sizeof(*fnames));

	/* get field name pointers */
	for (int i = 0; i < numFields; i++)
	{
		fnames[i] = mxGetFieldNameByNumber(struct_array, i);

	}

	/* get the panic file name*/
	mxArray *panic_file = getFieldPointer(struct_array, 0,
			fnames[PANIC_FILE_INDEX], classIDflags[0]);
	if (panic_file != NULL)
	{

		panicFileName = mxArrayToString(panic_file);
		mexPrintf("panic file name %s \n", panicFileName);

	}
	else
	{
		int buflen = strlen(DEFAULT_PANIC_FILE) + 1;
		panicFileName = (char *) mxCalloc(buflen, sizeof(char));
		strcpy(panicFileName, DEFAULT_PANIC_FILE);
		mexPrintf("default panic file name %s \n", panicFileName);
		assignedDefault[PANIC_FILE_INDEX] = true;
	}

	/* get the periodic file name*/
	mxArray *periodic_file = getFieldPointer(struct_array, 0,
			fnames[PERIODIC_FILE_INDEX], classIDflags[1]);
	if (periodic_file != NULL)
	{

		periodicFileName = mxArrayToString(periodic_file);
		mexPrintf("periodic file name %s \n", periodicFileName);

	}
	else
	{
		int buflen = strlen(DEFAULT_PERIODIC_FILE) + 1;
		periodicFileName = (char *) mxCalloc(buflen, sizeof(char));
		strcpy(periodicFileName, DEFAULT_PERIODIC_FILE);
		mexPrintf("default periodic file name %s \n", periodicFileName);
		assignedDefault[PERIODIC_FILE_INDEX] = true;

	}

	/* get the max history value */
	mxArray *max_history_pointer = getFieldPointer(struct_array, 0,
			fnames[MAX_HISTORY_INDEX], classIDflags[2]);

	if (max_history_pointer != NULL)
	{

		maxHistory = (long long unsigned*) mxGetData(max_history_pointer);
		mexPrintf("max history value %llu \n", *maxHistory);
	}
	else
	{
		maxHistory = (long long unsigned *) mxCalloc(1,
				sizeof(long long unsigned));
		*maxHistory = DEFAULT_MAX_HISTORY;
		mexPrintf("default max history value %llu \n", *maxHistory);
		assignedDefault[MAX_HISTORY_INDEX] = true;
	}

	/* get the period value */
	mxArray *period_pointer = getFieldPointer(struct_array, 0,
			fnames[PERIOD_INDEX], classIDflags[3]);

	if (period_pointer != NULL)
	{

		period = (long long unsigned *) mxGetPr(period_pointer);
		mexPrintf("period value %llu \n", *period);
	}
	else
	{
		period = (long long unsigned *) mxCalloc(1, sizeof(long long unsigned));
		*period = DEFAULT_PERIOD;
		mexPrintf("default period value %llu \n", *period);
		assignedDefault[PERIOD_INDEX] = true;
	}

	/* free the memory */
	mxFree((void *) fnames);

	timepoints = mxGetPr(prhs[3]);
	numTimepts = (int) mxGetScalar(prhs[4]);

	/* Declare IMs*/
	double cumProps[SSA_NumReactions];
	int reactionIndex;
	int iTime;
	double tCurr;
	double tNext;

	/* Declare Outputs*/
	double* timecourse;

	/* Create Outputs I */
	plhs[0] = mxCreateDoubleMatrix(SSA_NumStates * numTimepts, 1, mxREAL);
	timecourse = mxGetPr(plhs[0]);

#ifdef LOGGING
	/* Panic log file name */
	std::string panic_file_name(panicFileName);
	std::ofstream panic_fstream;

	/* periodic log file */
	std::string periodic_file_name(periodicFileName);
	std::ofstream periodic_fstream;
	openOutputStream(periodic_file_name, periodic_fstream);

	//std::cout<<"logging enabled...\n"<<std::endl;

	LOGLEVEL level;

#ifdef LEVEL_ALL

	/* memory allocation of variables */
	double logRandOne[MAX_HISTORY];
	double logRandTwo[MAX_HISTORY];
	double logTCurr[MAX_HISTORY];
	double logTNext[MAX_HISTORY];
	double logCurrentStates [MAX_HISTORY][SSA_NumStates];
	double logPropensities [MAX_HISTORY][SSA_NumReactions];
	double logChosenPropensity [MAX_HISTORY];
	double logChosenReactionIndex [MAX_HISTORY];

	/* set level */
	level = ALL;

#elif LEVEL_DEBUG

	/* memory allocation of variables */
	double *logRandOne = NULL;
	double *logRandTwo = NULL;
	double logTCurr[MAX_HISTORY];
	double logTNext[MAX_HISTORY];
	double logCurrentStates [MAX_HISTORY][SSA_NumStates];
	double logPropensities [MAX_HISTORY][SSA_NumReactions];
	double *logChosenPropensity = NULL;
	double logChosenReactionIndex [MAX_HISTORY];

	/* set level */
	level = DEBUG;

#elif LEVEL_INFO

	/* memory allocation of variables */
	double *logRandOne = NULL;
	double *logRandTwo = NULL;
	double *logTCurr = NULL;
	double *logTNext = NULL;
	double logCurrentStates [MAX_HISTORY][SSA_NumStates];
	double logPropensities [MAX_HISTORY][SSA_NumReactions];
	double *logChosenPropensity = NULL;
	double logChosenReactionIndex [MAX_HISTORY];
	/* set level */
	level = INFO;

#else

	/* memory allocation of variables */
	double *logRandOne = NULL;
	double *logRandTwo = NULL;
	double *logTCurr = NULL;
	double *logTNext = NULL;
	double *logCurrentStates = NULL;
	double *logPropensities = NULL;
	double *logChosenPropensity = NULL;
	double *logChosenReactionIndex = NULL;

	/* set level */
	level = OFF;
	/* As level is off disable the logging */

#endif

	/*definition of log levels */
	/* INFO - { STATES,PROPENSITIES, REACTION_INDICIES} */
	/* DEBUG - {T_CURR ,T_NEXT , CHOOSEN_PROPENSITY }  + INFO */
	/* ALL - {RAND_ONE , RAND_TWO } + DEBUG */

	int log_level_of_var[NUM_VARS];

	log_level_of_var[RAND_ONE] = 0;
	log_level_of_var[RAND_TWO] = 0;
	log_level_of_var[T_CURR] = 1;
	log_level_of_var[T_NEXT] = 1;
	log_level_of_var[STATES] = 2;
	log_level_of_var[PROPENSITIES] = 2;
	log_level_of_var[CHOSEN_PROPENSITY] = 1;
	log_level_of_var[REACTION_INDEX] = 2;

	/* initialize the logging flag for variables */
	bool logging_flag_of_var[NUM_VARS];
	initializeLoggingFlags(level,log_level_of_var,logging_flag_of_var);

#endif

	/* Write initial conditions to output */
	iTime = 0;
	for (int i = 0; i < SSA_NumStates; i++)
	{
		timecourse[iTime * SSA_NumStates + i] = xCurr[i];
	}
	iTime++;
	tNext = timepoints[iTime];

	/* Start iteration*/
	tCurr = timepoints[0];
	tNext = timepoints[iTime];
	long long unsigned globalCounter = 0;
	long long unsigned historyCounts = 0;

	while (tCurr < timepoints[numTimepts - 1])
	{
		// Debugging info - massive performance decrease
		double rand1 = std::max(1.0, (double) rand()) / (double) RAND_MAX;
		double rand2 = std::max(1.0, (double) rand()) / (double) RAND_MAX;

		/* Calculate cumulative propensities in one step*/
		int retVal = calculateCumProps(cumProps, xCurr, parameters);
		//retVal = -1;
		if (retVal == -1)
		{
#ifdef LOGGING
			if(level < OFF)
			{

				openOutputStream(panic_file_name, panic_fstream);
				writeLastNSteps(FILE_OUTPUT,panic_fstream, historyCounts, *maxHistory,level, logging_flag_of_var, logRandOne,
						logRandTwo, logTCurr,logTNext,
						logCurrentStates,
						logPropensities,
						logChosenPropensity, logChosenReactionIndex);
			}

#endif
			mexErrMsgIdAndTxt("SSA:InvalidPropensity",
					"Propensity can not be negative");
		}

		/* Sample reaction time*/
		double temp = cumProps[SSA_NumReactions - 1] * log(1 / rand1);
		if (temp <= 0)
		{
#ifdef LOGGING

			if(level < OFF)
			{

				openOutputStream(panic_file_name, panic_fstream);
				writeLastNSteps(FILE_OUTPUT,panic_fstream, historyCounts, *maxHistory,level, logging_flag_of_var, logRandOne,
						logRandTwo, logTCurr,logTNext,
						logCurrentStates,
						logPropensities,
						logChosenPropensity, logChosenReactionIndex);
			}

#endif
			mexErrMsgIdAndTxt("SSA:InvalidTcurr",
					"Value of tCurr can not be negative");
		}
		tCurr = tCurr + 1 / temp;

		/* If time > time out, write next datapoint to output*/
		while (tCurr >= tNext && iTime < numTimepts)
		{

			// this will save the repeated calculation
			int cIndex = iTime * SSA_NumStates;
			for (int i = 0; i < SSA_NumStates; i++)
			{

				timecourse[cIndex + i] = xCurr[i];
				//   mexPrintf(" %d",xCurr[i]);
			}
			//mexPrintf("\n");
			iTime++;
			tNext = timepoints[iTime];
		}

		/* Sample reaction index*/
		double chosenProp = rand2 * cumProps[SSA_NumReactions - 1];
		reactionIndex = 1;
		for (int i = 1; cumProps[i - 1] <= chosenProp; i++)
			reactionIndex = i + 1;

		//std::cout<<"updating logs...\n"<<std::endl;
		globalCounter = globalCounter + 1;
#ifdef  LOGGING
		/* this call store the parameters of simulation which can used to print
		 * at later stage in case of any error
		 */
		historyCounts = historyCounts + 1;
		if (historyCounts > *maxHistory)
		{
			historyCounts = 0;
		}
		if(level < OFF)
		{
			//std::cout<<"updating logs...\n"<<std::endl;
			update_logRotation(historyCounts,level, logging_flag_of_var, logRandOne,
					logRandTwo, logTCurr,logTNext,
					logCurrentStates,
					logPropensities,
					logChosenPropensity, logChosenReactionIndex,
					rand1, rand2, tCurr,
					tNext, xCurr,
					cumProps,
					chosenProp ,reactionIndex);
		}

		//std::cout<<"global count: "<<globalCounter<<"\n";

		if (globalCounter % *period == 0)
		{

			//mexPrintf("printing logs..");
			writeOneStep(FILE_OUTPUT,periodic_fstream,globalCounter, level, logging_flag_of_var, rand1,
					rand2, tCurr,tNext,
					xCurr,cumProps,
					chosenProp, reactionIndex);

		}
#endif
	}
#ifdef LOGGING
	panic_fstream.close();
	periodic_fstream.close();
#endif

	/*free the allocated memory */
	if (assignedDefault[PANIC_FILE_INDEX] == true)
	{
		mxFree((void*) panicFileName);
	}
	if (assignedDefault[PERIODIC_FILE_INDEX] == true)
	{
		mxFree((void*) periodicFileName);
	}
	if (assignedDefault[MAX_HISTORY_INDEX] == true)
	{
		mxFree((void*) maxHistory);
	}
	if (assignedDefault[PERIOD_INDEX] == true)
	{
		mxFree((void *) period);
	}
}
Beispiel #25
0
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
  mwSize subs[2];
  mxArray *trowmajor;
  char *zsql, *strbuf;
  int i, j, k, iret, istep, irow=0, nrow_alloc=0, ncol, kval, nval, kk, iargbind=4;
  int isnumeric=1,  ldestroy=1, coltyp, classid;

  int n_par_tobind=0, n_val_tobind=1;
  const mxArray *mxBindPar=NULL;

  strcat(errmsgstr1, "select:");

/* check for proper number of arguments */
  if( nrhs<2)
    ERRABORT("nrhs", "at least two input arguments are needed.");

  /* Make sure that input arguments 2...2nd last are strings: */
  for( k=2; k<nrhs-1; k++ )
    if( !mxIsChar(prhs[k]) )
      ERRABORT("notChar", "After the 2nd argument only string input is expected.");

/* if the first argument is a string, then open a database connection  */
  if( mxIsChar(prhs[0]) ) {
    mexCallMATLAB(1, &mxppDb, 1, (mxArray **) &prhs[0], "sql_open");
    ppDb = *((sqlite3 **) mxGetData(mxppDb));
  } else
    ppDb = *((sqlite3 **) mxGetData(prhs[0]));

  zsql = getzsql(nrhs, prhs, &iargbind);
  /* mexPrintf("zsql = %s\n", zsql); */

  /* Prepare the SQL library for the select statement: */
  iret = sqlite3_prepare_v2(ppDb, zsql, strlen(zsql), &ppStmt, NULL);
  /* mexPrintf("sqlite3_prepare_v2 returned %d\n", iret); */

  /* Return the statement in the second optional output argument*/
  if( nlhs>=2 )
    plhs[1] = mxCreateString(zsql);
  else
    mxFree(zsql);

  if( iret!=SQLITE_OK ) {
    char errmsgbuf[strlen(sqlite3_errmsg(ppDb))+1];
    strcpy(errmsgbuf, sqlite3_errmsg(ppDb));
    CLOSE_DB;
    ERRABORT("prepare", errmsgbuf);
  }

  /* If there are parameters to bind, check the matlab variables
     and find out how many parameters/values: */
  bind_m2sql(ppStmt, iargbind, prhs, &n_par_tobind, &n_val_tobind);

  /* How many columns? */
  ncol = sqlite3_column_count(ppStmt);
  /* mexPrintf("sqlite3_column_count returned %d\n", ncol); */

  /* The numbers of rows is not known at this point. Therefore
     the elements are first stored row-by-row in a temporary cell array,
     so that memory can be reallocated as database rows are added. */
  trowmajor = mxCreateCellMatrix(ncol, 0);

  /* Loop over the values that need to be bound to parameters, 
     if no parameters to bind n_val_tobind=1 and the loop is executed once: */
  for( kval=0; kval<n_val_tobind; kval++ ) {
    BIND_MATPAR(MEXFUN)

    /* Step along the selected rows: */
    while( (istep = sqlite3_step(ppStmt))==SQLITE_ROW ) {
      /* A row is available,
	 if needed then enlarge the output cell array: */
      if( irow>=nrow_alloc ) {
	/* mexPrintf("irow = %d, nrow_alloc = %d\n", irow, nrow_alloc);*/
	if( nrow_alloc==0 )  /* The first row is found */
	  nrow_alloc++;
	else
	  nrow_alloc *= 2;
	mxSetData(trowmajor,
		  mxRealloc(mxGetData(trowmajor),
			    sizeof(mxArray *)*nrow_alloc*ncol));
	/* mexPrintf("%d bytes reallocated\n", sizeof(mtype)*nrow_alloc*ncol); */
      }
      /* Increment the nr of columns of the output matrix by one: */ 
      mxSetN(trowmajor, mxGetN(trowmajor)+1);
      /* mexPrintf("plhs enlarged to %d %d\n",
	 mxGetM(trowmajor), mxGetN(trowmajor)); */
      
      subs[1] = irow++;
      for( k=0; k<ncol; k++ ) {
	subs[0] = k;
	coltyp = sqlite3_column_type(ppStmt, k);
	/* mexPrintf("subs = %d %d, coltyp = %d, mxCalcSingleSubscript = %d\n",
		  subs[0], subs[1], coltyp,
		  mxCalcSingleSubscript(trowmajor, 2, subs)); */
	
	switch( coltyp) {
	  mxArray *rnum;
	  int nblob;
	case SQLITE_NULL: /* NULL values are mapped in Matlab to empty cells: */
	  /* mexPrintf("NULL selected at ncol = %d and irow %d\n", subs[0], subs[1]); */
	  rnum = mxCreateDoubleMatrix(0, 1, mxREAL);
	  mxSetCell(trowmajor, 
		    mxCalcSingleSubscript(trowmajor, 2, subs), rnum);
	  isnumeric = 0;
	  break;
	case SQLITE_TEXT:
	  mxSetCell(trowmajor, 
		    mxCalcSingleSubscript(trowmajor, 2, subs),
		    mxCreateString(sqlite3_column_text(ppStmt, k)));
	  isnumeric = 0;
	  break;
	case SQLITE_BLOB:
	  nblob = sqlite3_column_bytes(ppStmt, k);
	  mxArray *blob = mxCreateNumericMatrix(1, nblob, mxUINT8_CLASS, mxREAL);
	  memcpy(mxGetPr(blob), sqlite3_column_blob(ppStmt, k), nblob);
	  mxSetCell(trowmajor, 
		    mxCalcSingleSubscript(trowmajor, 2, subs), blob);
	  isnumeric = 0;
	  break;
	case SQLITE_FLOAT:
	  rnum = mxCreateDoubleMatrix(1, 1, mxREAL);
	  *mxGetPr(rnum) = sqlite3_column_double(ppStmt, k);
	  mxSetCell(trowmajor, 
		    mxCalcSingleSubscript(trowmajor, 2, subs), rnum);
	  break;
	default:
	  sqlite3_finalize(ppStmt);
	  CLOSE_DB;
	  ERRABORT("column_type", "db should not have this column type");
	}
      }
    }
    /* mexPrintf("last return from sqlite3_step was %d\n", istep); */
    if( istep!=SQLITE_DONE ) {
      char errmsgbuf[strlen(sqlite3_errmsg(ppDb))+1];
      strcpy(errmsgbuf, sqlite3_errmsg(ppDb));
      sqlite3_finalize(ppStmt);
      CLOSE_DB;
      ERRABORT("done", sqlite3_errmsg(ppDb));
    }

    iret = sqlite3_reset(ppStmt);
    if( iret!=SQLITE_OK )
      mexWarnMsgIdAndTxt("Sqlite4m:sql_insert:reset", sqlite3_errmsg(ppDb));
  }
  TRY_SQLFUN(sqlite3_finalize(ppStmt), select, finalize);
  /* Release memory to the actual nr of db rows/matlab columns: */
  mxSetData(trowmajor,
	    mxRealloc(mxGetData(trowmajor),
		      sizeof(mxArray *)*mxGetN(trowmajor)*ncol));
  /* mexPrintf("final allocation is %d bytes\n", sizeof(mtype)*mxGetN(plhs[0])*ncol); */

  /* if the first argument was a string, then close the database connection  */
  CLOSE_DB;

  /* Transpose the row-by-row cell array into a double matrix
     if all elements are numeric: */
  /* if( isnumeric ) { */
  /*   plhs[0] = mxCreateDoubleMatrix(mxGetN(trowmajor), */
  /* 				   mxGetM(trowmajor), mxREAL); */
  /*   /\* Traverse the temporary row major array column by column, */
  /*      then the output array can be filled linearly: *\/ */
  /*   k = 0; */
  /*   for( i=0; i<mxGetM(trowmajor); i++ ) { */
  /*     subs[0] = i; */
  /*     for( j=0; j<mxGetN(trowmajor); j++ ) { */
  /* 	subs[1] = j; */
  /* 	mxGetPr(plhs[0])[k++] = */
  /* 	  *mxGetPr(mxGetCell(trowmajor, */
  /* 			     mxCalcSingleSubscript(trowmajor, 2, subs))); */
  /*     } */
  /*   } */
  /*   mxDestroyArray(trowmajor); */
  /* /\*  or else use Matlab transpose to copy into the output cell array, */
  /*       if at least one element is text or a blob: *\/ */
  /* } else */
    mexCallMATLAB(1, plhs, 1, &trowmajor, "transpose");
}
Beispiel #26
0
void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] )
{
  struct options_binless *opts;
  struct options_entropy *opts_ent;
  double **embedded,*embedded_temp;
  int *n_vec,*a_vec;
  int N,R,S;
  int n,r;
  struct estimate *I_part,*I_count,*I_total;
  double *I_cont;
  int status;
  mxArray *temp;

  if( (nrhs<4) | (nrhs>5) )
    mexErrMsgIdAndTxt("STAToolkit:binlessinfo:numArgs","4 or 5 input arguments required.");
  if((nlhs<4) | (nlhs>5))
    mexErrMsgIdAndTxt("STAToolkit:binlessinfo:numArgs","4 or 5 output arguments required.");

  if(nrhs<5)
    {
      opts = ReadOptionsBinless(mxCreateEmptyStruct());
      opts_ent = ReadOptionsEntropy(mxCreateEmptyStruct());
    }  
  else if(mxIsEmpty(prhs[4]))
    {
      opts = ReadOptionsBinless(mxCreateEmptyStruct());
      opts_ent = ReadOptionsEntropy(mxCreateEmptyStruct());
    }
  else
    {
      opts = ReadOptionsBinless(prhs[4]);
      opts_ent = ReadOptionsEntropy(prhs[4]);
    }

  ReadOptionsEmbedRange(opts);

  /* SINGLETON */
  if(opts[0].single_strat_flag==0)
    {
      (*opts).single_strat = (int)DEFAULT_SINGLETON_STRATEGY;
      (*opts).single_strat_flag = 1;
      mexWarnMsgIdAndTxt("STAToolkit:binlessinfo:missingParameter","Missing parameter singleton_strategy. Using default value %d.",(*opts).single_strat);
    }

  if( ((*opts).single_strat!=0) & ((*opts).single_strat!=1) )
    {
      (*opts).single_strat = (int)DEFAULT_SINGLETON_STRATEGY;
      (*opts).single_strat_flag = 1;
      mexWarnMsgIdAndTxt("STAToolkit:binlessinfo:invalidValue","Option singleton_strategy set to an invalid value. Must be 0 or 1. Using default value %d.",(*opts).single_strat);
    }

  /* STRATIFICATION */
  if(opts[0].strat_strat_flag==0)
    {
      (*opts).strat_strat = (opts->rec_tag_flag && (opts->rec_tag==1)) ? 0 : (int)DEFAULT_STRATIFICATION_STRATEGY;
      (*opts).strat_strat_flag = 1;
      mexWarnMsgIdAndTxt("STAToolkit:binlessinfo:missingParameter","Missing parameter stratification_strategy. Using default value %d.",(*opts).strat_strat);
    }

  if( ((*opts).strat_strat!=0) & ((*opts).strat_strat!=1) & ((*opts).strat_strat!=2) )
    {
      (*opts).strat_strat = (opts->rec_tag_flag && (opts->rec_tag==1)) ? 0 : (int)DEFAULT_STRATIFICATION_STRATEGY;
      (*opts).strat_strat_flag = 1;
      mexWarnMsgIdAndTxt("STAToolkit:binlessinfo:invalidValue","Option stratification_strategy set to an invalid value. Must be 0, 1, or 2. Using default value %d.",(*opts).strat_strat);
    }

  /* USEALL */
  if(opts_ent[0].useall_flag==0)
    {
      (*opts_ent).useall=(int) DEFAULT_UNOCCUPIED_BINS_STRATEGY;
      opts_ent[0].useall_flag=1;
      mexWarnMsgIdAndTxt("STAToolkit:matrix2hist2d:missingOption","Missing option unoccupied_bins_strategy. Using default value %d.\n",(*opts_ent).useall);
    }

  if( (opts_ent[0].useall!=-1) & (opts_ent[0].useall!=0) & (opts_ent[0].useall!=1) )
   {
     (*opts_ent).useall=(int) DEFAULT_UNOCCUPIED_BINS_STRATEGY;
      opts_ent[0].useall_flag=1;
      mexWarnMsgIdAndTxt("STAToolkit:matrix2hist2d:invalidValue","Option unoccupied_bins_strategy set to an invalid value. Must be -1, 0, or 1. Using default value %d.\n",(*opts_ent).useall);
   }

  /* Estimates */
  if(opts_ent->E==0)
    {
      opts_ent->E=1;
      opts_ent->ent_est_meth[0] = 1;
    }

  N = mxGetM(prhs[0]);
  R = mxGetN(prhs[0]);
  embedded_temp = mxGetData(prhs[0]);
  embedded = mxMatrixDouble(N,R);
  for(n=0;n<N;n++)
    for(r=0;r<R;r++)
      embedded[n][r] = embedded_temp[r*N+n];
  
  if(mxGetNumberOfElements(prhs[1])!=N)
    {
      mxFree(opts);
      if((opts_ent->E)>0) 
        mxFree(opts_ent->ent_est_meth);
      if((opts_ent->var_est_meth_flag)>0) 
        mxFreeMatrixInt(opts_ent->var_est_meth);
      mxFree(opts_ent->V);
      mxFree(opts_ent);
      mxFree(embedded);
      mexErrMsgIdAndTxt("STAToolkit:binlessinfo:sizeMismatch","The number of elements in COUNTS must match the number of rows in X.");
    }

  if(mxIsClass(prhs[1],"int32")==0)
    mexWarnMsgIdAndTxt("STAToolkit:binlessinfo:wrongType","COUNTS is not int32.");
  n_vec = (int *)mxMalloc(N*sizeof(int));
  memcpy(n_vec,mxGetPr(prhs[1]),N*sizeof(int));

  if(mxGetNumberOfElements(prhs[2])!=N)
    {
      mxFree(opts);
      if((opts_ent->E)>0) 
        mxFree(opts_ent->ent_est_meth);
      if((opts_ent->var_est_meth_flag)>0) 
        mxFreeMatrixInt(opts_ent->var_est_meth);
      mxFree(opts_ent->V);
      mxFree(opts_ent);
      mxFree(embedded);
      mxFree(n_vec);
      mexErrMsgIdAndTxt("STAToolkit:binlessinfo:sizeMismatch","The number of elements in CATEGORIES must match the number of rows in X.");
    }

  if(mxIsClass(prhs[2],"int32")==0)
    mexWarnMsgIdAndTxt("STAToolkit:binlessinfo:wrongType","CATEGORIES is not int32.");
  a_vec = (int *)mxGetPr(prhs[2]);

  /* Have to put in a check about the number of categories not exceeding M */

  if(mxIsClass(prhs[3],"int32")==0)
    mexWarnMsgIdAndTxt("STAToolkit:binlessinfo:wrongType","M is not int32.");
  S = (int)mxGetScalar(prhs[3]);

  I_part = (struct estimate *)mxMalloc((*opts_ent).E*sizeof(struct estimate));
  plhs[0] = AllocEst(I_part,opts_ent);

  plhs[1] = mxCreateDoubleMatrix(1,1,mxREAL);
  I_cont = mxGetData(plhs[1]);

  I_count = (struct estimate *)mxMalloc((*opts_ent).E*sizeof(struct estimate));
  plhs[2] = AllocEst(I_count,opts_ent);

  I_total = (struct estimate *)mxMalloc((*opts_ent).E*sizeof(struct estimate));
  plhs[3] = AllocEst(I_total,opts_ent);

  /* Do computation */
  status = BinlessInfoComp(opts,opts_ent,embedded,N,S,n_vec,a_vec,I_part,I_cont,I_count,I_total);

  WriteEst(I_part,plhs[0]);
  mxFree(I_part);

  WriteEst(I_count,plhs[2]);
  mxFree(I_count);

  WriteEst(I_total,plhs[3]);
  mxFree(I_total);

  if(nrhs<5)
    temp = WriteOptionsBinless(mxCreateEmptyStruct(),opts);
  else if(mxIsEmpty(prhs[4]))
    temp = WriteOptionsBinless(mxCreateEmptyStruct(),opts);
  else
    temp = WriteOptionsBinless(prhs[4],opts);
  plhs[4] = WriteOptionsEntropy(temp,opts_ent);

  mxFree(embedded);
  mxFree(n_vec);

  return;
}
void EstimateDElevByFluvialProcessBySDS(
    double * dSedimentThick,
    double * dBedrockElev,
    double * dChanBedSed,
    double * inputFlux,
    double * outputFlux,
    double * inputFloodedRegion,
    mxLogical * isFilled,
    double dX,
    double consideringCellsNo,
    double * mexSortedIndicies,
    double * mexSDSNbrIndicies,
    double * flood,
    double * floodedRegionCellsNo,
    double * floodedRegionStorageVolume,
    double * bankfullWidth,
    double * transportCapacity,
    double * bedrockIncision,
    double * chanBedSed,
    double * sedimentThick,
    mxLogical * hillslope,
    double * transportCapacityForShallow,
    double * bedrockElev)
{
    /* 임시 변수 선언 */
    mwIndex ithCell,ithCellIdx,outlet,next;
    double excessTransportCapacity,tmpBedElev,outputFluxToNext;
    
    const double FLOODED = 2; /* flooded region */
    const double CELL_AREA = dX * dX;
            
    /* (높은 고도 순으로) 하천작용에 의한 퇴적물 두께 및 기반암 고도 변화율을 구함 */
    for (ithCell=0;ithCell<consideringCellsNo;ithCell++)
    {        
        /* 1. i번째 셀 및 다음 셀의 색인
         * *  주의: MATLAB 배열 선형 색인을 위해 '-1'을 수행함 */
        ithCellIdx = (mwIndex) mexSortedIndicies[ithCell] - 1;
        next = (mwIndex) mexSDSNbrIndicies[ithCellIdx] - 1;

        /* 2. i번재 셀의 유출율을 구하고, 이를 유향을 따라 다음 셀에 분배함 */
        /* 1) i번째 셀이 flooded region의 유출구인지를 확인함 */
        if ((mwSize) floodedRegionCellsNo[ithCellIdx] == 0)
        {
            /* (1) flooded region으로의 퇴적물 유입량이 flooded region의
             *     저장량을 초과하는지 확인함 */
            if (inputFloodedRegion[ithCellIdx] 
                    > floodedRegionStorageVolume[ithCellIdx])
            {
                /* A. 초과할 경우, 초과량을 유출구의 유입율에 더함 */
                inputFlux[ithCellIdx] = inputFlux[ithCellIdx]
                    + (inputFloodedRegion[ithCellIdx]
                    - floodedRegionStorageVolume[ithCellIdx]);

                /* B. flooded region이 유입한 퇴적물로 채워졌다고 표시함 */
                isFilled[ithCellIdx] = true;
            }
        }
            
        /* 2) i번째 셀이 사면인지를 확인함 */
        if (hillslope[ithCellIdx] == true)                
        {
        
            /* (1) 사면이라면, 지표유출에 의한 침식률을 구함 */
            outputFlux[ithCellIdx] = transportCapacityForShallow[ithCellIdx];                
            dSedimentThick[ithCellIdx] 
                    = (inputFlux[ithCellIdx] - outputFlux[ithCellIdx]) / CELL_AREA;
            
            /* to do: 기반암 고도에는 영향을 주지 않는 것으로 처리함 */
            if ((sedimentThick[ithCellIdx] + dSedimentThick[ithCellIdx]) < 0)
            {
                dSedimentThick[ithCellIdx] = - sedimentThick[ithCellIdx];
                outputFlux[ithCellIdx] = sedimentThick[ithCellIdx] * CELL_AREA;
            }            
        }            
        else
        {
            /* (2) 하천이라면, 하천에 의한 유출률을 구하고 이를 다음 셀에 분배함 */

            /* A. 퇴적물 운반능력[m^3/subDT]이 하도 내 하상 퇴적물보다 큰 지를 확인함 */
            excessTransportCapacity /* 유입량 제외 퇴적물 운반능력 [m^3/subDT] */
                = transportCapacity[ithCellIdx] - inputFlux[ithCellIdx];
            if (excessTransportCapacity <= chanBedSed[ithCellIdx])
            {
                /* (A) 퇴적물 운반능력이 하상 퇴적물보다 작다면, 운반제어환경임 */
                /* a. 다음 셀로의 유출률 [m^3/subDT] */
                outputFlux[ithCellIdx] = transportCapacity[ithCellIdx];
                /* b. 퇴적층 두께 변화율 [m/subDT] */
                dSedimentThick[ithCellIdx] 
                    = (inputFlux[ithCellIdx] - outputFlux[ithCellIdx]) / CELL_AREA;
                /* c. 하도 내 하상 퇴적층 부피 [m^3] */
                dChanBedSed[ithCellIdx] = dSedimentThick[ithCellIdx] * CELL_AREA;

                /* for debug */
                if (sedimentThick[ithCellIdx] + dSedimentThick[ithCellIdx] < 0)
                {
                    mexErrMsgIdAndTxt("EstimateDElevByFluvialProcess_m:negativeSedimentThick","negative sediment thickness");
                }
                if (outputFlux[ithCellIdx] < 0)
                {
                    mexErrMsgIdAndTxt("EstimateDElevByFluvialProcess_m:negativeOutputFlux","negative output flux");
                }
            }
            else
            {
                /* (B) 퇴적물 운반능력이 하상 퇴적물보다 크면 분리제어환경임 */
                /* 기반암 하식률 [m/subDT] */
                /* * 주의: 다음 셀의 기반암 하상 고도를 고려하여 기반암 하식률을 산정하는 것을 추가함 */
                dBedrockElev[ithCellIdx] = - (bedrockIncision[ithCellIdx] / CELL_AREA);
                /* prevent bedrock elevation from being lowered compared to downstream node */
                tmpBedElev = bedrockElev[ithCellIdx] + dBedrockElev[ithCellIdx];
                if (tmpBedElev < bedrockElev[next])
                {
                    dBedrockElev[ithCellIdx] = bedrockElev[next] - bedrockElev[ithCellIdx];
                    
                    /* for warning and debug */
                    if (dBedrockElev[ithCellIdx] > 0)
                    {
                        /* for the intitial condition in which upstream bedrock
                         * elevation is lower than its downstream */
                        if (bedrockElev[ithCellIdx] < bedrockElev[next])
                        {
                            mexWarnMsgIdAndTxt("EstimateDElevByFluvialProcess_m:negativeDBedrockElev"
                                ,"reversed dBedrockElev: diff with next, %f"
                                ,bedrockElev[next] - bedrockElev[ithCellIdx]);
                            dBedrockElev[ithCellIdx] = 0;
                        }
                        else
                        {
                            /* for debug */                                
                            mexErrMsgIdAndTxt("EstimateDElevByFluvialProcess_m:negativeDBedrockElev"
                                    ,"negative dBedrockElev");
                        }                        
                    }
                }   

                /* 다음 셀로의 유출율 [m^3/subDT] */
                outputFlux[ithCellIdx] = inputFlux[ithCellIdx] + chanBedSed[ithCellIdx]
                        - (dBedrockElev[ithCellIdx] * CELL_AREA);
                /* don't include flux due to bedrock incision */
                dSedimentThick[ithCellIdx] = - (inputFlux[ithCellIdx] + chanBedSed[ithCellIdx])
                                                / CELL_AREA;
                if (sedimentThick[ithCellIdx] + dSedimentThick[ithCellIdx] < 0)
                {
                    dSedimentThick[ithCellIdx] = - sedimentThick[ithCellIdx];
                    outputFlux[ithCellIdx]
                            = - (dSedimentThick[ithCellIdx] + dBedrockElev[ithCellIdx]) * CELL_AREA;
                } 
                /* 하도 내 하상 퇴적물 변화율 [m^3/subDT] */
                dChanBedSed[ithCellIdx] = dSedimentThick[ithCellIdx] * CELL_AREA;
                
                /* for debug */
                if (outputFlux[ithCellIdx] < 0)
                {
                    mexErrMsgIdAndTxt("EstimateDElevByFluvialProcess_m:negativeOutputFlux","negative output flux");
                }
            }
        }

        /* 3. SDS 유향을 따라 다음 셀의 유입율에 유출율을 더함 */
        /* A. 다음 셀에 운반될 퇴적물 유출율 [m^3/subDT]*/
        outputFluxToNext = outputFlux[ithCellIdx];
        /* B) 다음 셀이 flooded region이라면 inputFloodedRegion에
         *    유출율을 반영하고 그렇지 않다면 다음 셀에 직접 반영함 */
        if ((mwSize) flood[next] == FLOODED)
        {
            /* * 주의: MATLAB 배열 색인을 위해 '-1'을 수행함 */
            outlet = (mwIndex) mexSDSNbrIndicies[next] - 1;
            inputFloodedRegion[outlet] /* [m^3/subDT] */
                = inputFloodedRegion[outlet] + outputFluxToNext;
        }
        else /* flood[next] ~= FLOODED */
        {
            inputFlux[next] = inputFlux[next] + outputFluxToNext;
        }

    } /* for ithCell=1:consideringCellsNo */        
} /* void ForFluvialProcess */