Beispiel #1
0
/* Function: mdlInitializeConditions ========================================
 * Abstract:
 * Initialize states to zeros.
 */
static void mdlInitializeConditions(SimStruct *S)
{
	int_T  i;
	InputRealPtrsType M, q;
	
	/* checks the input matrices for NaN and Inf */ 

	/* checking M */
	M = ssGetInputPortRealSignalPtrs(S,0);
	for (i=0; i<NSTATES(S)*NSTATES(S); i++) {
		if ( !mxIsFinite(*M[i])  ) {
			ssSetErrorStatus(S, "lcp_sfun: No 'NaN' or 'Inf' terms are allowed in input matrix M.");
			return;
		}
	}
	/* checking q */
	q = ssGetInputPortRealSignalPtrs(S,1);
	for (i=0; i<NSTATES(S); i++) {
		if ( !mxIsFinite(*q[i]) ) {
			ssSetErrorStatus(S, "lcp_sfun: No 'NaN' or 'Inf' terms are allowed in input vector q.");
			return;
		}
	}

}
void assignmentsuboptimal2(double *assignment, double *cost, double *distMatrixIn, int nOfRows, int nOfColumns)
{
	int n, row, col, tmpRow, tmpCol, nOfElements;
	double value, minValue, *distMatrix, inf;

	inf = mxGetInf();
	
	/* make working copy of distance Matrix */
	nOfElements   = nOfRows * nOfColumns;
	distMatrix    = (double *)mxMalloc(nOfElements * sizeof(double));
	for(n=0; n<nOfElements; n++)
		distMatrix[n] = distMatrixIn[n];
	
	/* initialization */
	*cost = 0;
	for(row=0; row<nOfRows; row++)
#ifdef ONE_INDEXING
		assignment[row] =  0.0;
#else
		assignment[row] = -1.0;
#endif
	
	/* recursively search for the minimum element and do the assignment */
	while(true)
	{
		/* find minimum distance observation-to-track pair */
		minValue = inf;
		for(row=0; row<nOfRows; row++)
			for(col=0; col<nOfColumns; col++)
			{
				value = distMatrix[row + nOfRows*col];
				if(mxIsFinite(value) && (value < minValue))
				{
					minValue = value;
					tmpRow   = row;
					tmpCol   = col;
				}
			}
		
		if(mxIsFinite(minValue))
		{
#ifdef ONE_INDEXING
			assignment[tmpRow] = tmpCol+ 1;
#else
			assignment[tmpRow] = tmpCol;
#endif
			*cost += minValue;
			for(n=0; n<nOfRows; n++)
				distMatrix[n + nOfRows*tmpCol] = inf;
			for(n=0; n<nOfColumns; n++)
				distMatrix[tmpRow + nOfRows*n] = inf;			
		}
		else
			break;
			
	} /* while(true) */
	
}
Beispiel #3
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
	int i, j, m, n;
	double s1=0.0, s2=0.0;
	double *dat;
	MAPTYPE *map, *get_maps();
	static double M[] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1};

	if (nrhs != 1 || nlhs > 1)
	{
		mexErrMsgTxt("Incorrect usage.");
	}

	map = get_maps(prhs[0], &j);

	if (j != 1)
	{
		free_maps(map, j);
		mexErrMsgTxt("Incorrect usage.");
	}
	n = (map->dim[0])*(map->dim[1]);
	dat = (double *)mxCalloc(n, sizeof(double));

	s1 = 0.0;
	m = 0;
	for (i=0; i<map->dim[2]; i++)
	{
		M[14] = i+1;
		slice(M, dat, map->dim[0],map->dim[1], map, 0,0);
		for(j=0;j<n; j++)
			if (mxIsFinite(dat[j]))
			{
				s1 += dat[j];
				m ++;
			}
	}
	s1/=(8.0*m);

	s2=0.0;
	m =0;
	for (i=0; i<map->dim[2]; i++)
	{
		M[14] = i+1;
		slice(M, dat, map->dim[0],map->dim[1], map, 0,0);
		for(j=0;j<n; j++)
			if (mxIsFinite(dat[j]) && dat[j]>s1)
			{
				m++;
				s2+=dat[j];
			}
	}
	s2/=m;

	plhs[0] = mxCreateDoubleMatrix(1,1,mxREAL);
	mxGetPr(plhs[0])[0]=s2;
	free_maps(map, 1);
}
Beispiel #4
0
static void mdlRTW(SimStruct *S){
   int_T type     = P_TYPE;
   int_T id       = P_ID;
   DTypeId  dataType = ssGetInputPortDataType(S,0);
   int_T length   =ssGetDataTypeSize(S,dataType) * ssGetInputPortWidth(S,0); 
   int32_T       endian     = P_ENDIAN;

   /* -- Write Invariant Parameter Settings -- */
   ssWriteRTWParamSettings(S,4,
         SSWRITE_VALUE_DTYPE_NUM, "TYPE",
         &type,
         DTINFO(SS_UINT32,0),

         SSWRITE_VALUE_DTYPE_NUM, "ID",
         &id,
         DTINFO(SS_UINT32,0),

         SSWRITE_VALUE_DTYPE_NUM, "LENGTH",
         &length,
         DTINFO(SS_UINT16,0),

         SSWRITE_VALUE_DTYPE_NUM, "Endian",
         &endian,
         DTINFO(SS_UINT32,0)
      );

   /* -- Write Invariant Signal Settings -- */
   if ( !mxIsFinite( ssGetSampleTime( S, 0 ) ) ) {
      CAN_FRAME * frame = (CAN_FRAME *) ssGetOutputPortSignal(S,0);
      CAN_write_rtw_frame(S,frame);
   }

}
Beispiel #5
0
void computeassignmentcost(double *assignment, double *cost, double *distMatrix, int nOfRows)
{
	int row, col;
#ifdef CHECK_FOR_INF
	double value;
#endif
	
	for(row=0; row<nOfRows; row++)
	{
#ifdef ONE_INDEXING
		col = assignment[row]-1; /* MATLAB-Indexing */
#else
		col = assignment[row];
#endif

		if(col >= 0)
		{
#ifdef CHECK_FOR_INF
			value = distMatrix[row + nOfRows*col];
			if(mxIsFinite(value))
				*cost += value;
			else
#ifdef ONE_INDEXING
				assignment[row] =  0.0;
#else
				assignment[row] = -1.0;
#endif

#else
			*cost += distMatrix[row + nOfRows*col];
#endif
		}
	}
}
void QuadLinearPass(double *r, double le, double kv, double *T1, double *T2, double *R1, double *R2, int num_particles)
{	int c;
	double *r6;
	bool useT1, useT2, useR1, useR2;
	
	if(T1==NULL)
	    useT1=false;
	else 
	    useT1=true;  
	    
    if(T2==NULL)
	    useT2=false; 
	else 
	    useT2=true;  
	
	if(R1==NULL)
	    useR1=false; 
	else 
	    useR1=true;  
	    
    if(R2==NULL)
	    useR2=false;
	else 
	    useR2=true;
	    

	for(c = 0;c<num_particles;c++)
		{	r6 = r+c*6;
		    if(!mxIsNaN(r6[0]) & mxIsFinite(r6[4]))
		    /* 
		       function quad6 internally calculates the square root
			   of the energy deviation of the particle 
			   To protect against DOMAIN and OVERFLOW error, check if the
			   fifth component of the phase spacevector r6[4] is finite
			*/
		    {
			/* Misalignment at entrance */
	        if(useT1)
			    ATaddvv(r6,T1);
			if(useR1)
			    ATmultmv(r6,R1);
			
			
			quad6(r6,le,kv);
			
			/* Misalignment at exit */	
			if(useR2)
			    ATmultmv(r6,R2);
		    if(useT2)   
			    ATaddvv(r6,T2);
			}
			
		}		
}
Beispiel #7
0
/* Compute the inverse deformation field within a single cube */
static void invert_it(int x0, int x1, int x2, float *y0, float *y1, float *y2,
	int dim_f[3], float *iy0, float *iy1, float *iy2, REAL U[4][3], REAL V[4][3])
{
	int i, j, k, vox[MAXV][3], nvox;
	REAL Y0[4][3], Y[4][3], M[4][3], IM[4][3];

	/* Determine tetrahedral arrangement */
        k = (x0%2)==(x1%2)==(x2%2);
 
	for(i=0; i<5; i++) /* Five tetrahedra within a cube */
	{
		/* Find the vertices (in mm space) */
		Y0[0][0] = y0[off[k][0][i]]; Y0[0][1] = y1[off[k][0][i]]; Y0[0][2] = y2[off[k][0][i]];
		Y0[1][0] = y0[off[k][1][i]]; Y0[1][1] = y1[off[k][1][i]]; Y0[1][2] = y2[off[k][1][i]];
		Y0[2][0] = y0[off[k][2][i]]; Y0[2][1] = y1[off[k][2][i]]; Y0[2][2] = y2[off[k][2][i]];
		Y0[3][0] = y0[off[k][3][i]]; Y0[3][1] = y1[off[k][3][i]]; Y0[3][2] = y2[off[k][3][i]];

		/* Convert vertex co-ordinates to voxels */
		mulMX(Y, U, Y0);

		/* Compute affine transform mapping vertices together */
		getM(Y, ix[k][i], M, x0, x1, x2);

		if (mxIsFinite(M[0][0])) /* Prevent from bombing out when NaNs are encountered */
		{
			/* Find integer co-ordinates within tetrahedron */
			scan_tetrahedron(Y, &nvox, vox, MAXV);

			if (nvox>0)
			{
				/* Invert the affine mapping */
				invertM(M, IM);

				/* Convert the mapping from voxels to mm */
				mulMM(M, V, IM);

				/* Insert the new mappings into each voxel within the tetrahedron */
				for(j=0; j<nvox; j++)
				{
					if ((vox[j][0]>=1) && (vox[j][0]<=dim_f[0]) &&
				 	    (vox[j][1]>=1) && (vox[j][1]<=dim_f[1]) &&
					    (vox[j][2]>=1) && (vox[j][2]<=dim_f[2]))
					{
						int o  = vox[j][0]+dim_f[0]*(vox[j][1]+dim_f[1]*vox[j][2]);

						iy0[o] = M[0][0]*vox[j][0] + M[1][0]*vox[j][1] + M[2][0]*vox[j][2] + M[3][0];
						iy1[o] = M[0][1]*vox[j][0] + M[1][1]*vox[j][1] + M[2][1]*vox[j][2] + M[3][1];
						iy2[o] = M[0][2]*vox[j][0] + M[1][2]*vox[j][1] + M[2][2]*vox[j][2] + M[3][2];
					}
				}
			}
		}
	}
}
Beispiel #8
0
  /* Function: mdlCheckParameters =============================================
   * Abstract:
   *    Validate our parameters to verify they are okay.
   */
  static void mdlCheckParameters(SimStruct *S)
  {
      int  i;
      bool badParam = false;

      /* All parameters must be positive non-zero integers */
      for (i = 0; i < ssGetSFcnParamsCount(S); i++) {
          const mxArray *m = ssGetSFcnParam(S,i);

          if (mxGetNumberOfElements(m) != 1 ||
              !mxIsNumeric(m) || !mxIsDouble(m) || mxIsLogical(m) ||
              mxIsComplex(m) || mxIsSparse(m) || !mxIsFinite(mxGetPr(m)[0])) {
              badParam = true;
              break;
          }
          if (i < NKPARAMS) {
              int ival;
              if (((ival=(int_T)mxGetPr(m)[0]) <= 0) ||
                  (real_T)ival != mxGetPr(m)[0]) {
                  badParam = true;
                  break;
              }
          } else if (mxGetPr(m)[0] <= 0.0) {
              badParam = true;
              break;
          }
      }

      if (badParam) {
          ssSetErrorStatus(S,"All parameters must be positive non-zero "
                           "values. First three must be integers and the "
                           "optional fourth must be a discrete sample "
                           "time");
          return;
      }
  }
Beispiel #9
0
/***************************************************************************************
Deconvolve the B-spline basis functions from the image volume
	vol - a handle for the volume to deconvolve
	c - the coefficients (arising from the deconvolution)
	d - the spline degree
	splinc0, splinc1, splinc2	- functions for 1D deconvolutions
*/
static int vol_coeffs(MAPTYPE *vol, double c[], int d[], void (*splinc[])())
{
	double	p[4], *cp;
	int	np;
	int	i, j, k, n;
	double f[10240];

	/* Check that dimensions don't exceed size of f */
	if (vol->dim[1]>10240 ||vol->dim[2]>10240)
		return(1);

	/* Do a straight copy */
	cp = c;
	for(k=0; k<vol->dim[2]; k++)
	{
		double dk = k+1;
		for(j=0; j<vol->dim[1]; j++)
		{
			double dj = j+1;
			for(i=0;i<vol->dim[0];i++, cp++)
			{
				double di = i+1;
				resample(1,vol,cp,&di,&dj,&dk,0, 0.0);

				/* Not sure how best to handle NaNs */
				if (!mxIsFinite(*cp)) *cp = 0.0;
			}
		}
	}

	/* Deconvolve along the fastest dimension (X) */
	if (d[0]>1 && vol->dim[0]>1)
	{
		if (get_poles(d[0], &np, p)) return(1);
		for(k=0; k<vol->dim[2]; k++)
		{
			/* double dk = k+1; */
			for(j=0; j<vol->dim[1]; j++)
			{
				cp = &c[vol->dim[0]*(j+vol->dim[1]*k)];
				splinc[0](cp, vol->dim[0], p, np);
			}
		}
	}

	/* Deconvolve along the middle dimension (Y) */
	if (d[1]>1 && vol->dim[1]>1)
	{
		if (get_poles(d[1], &np, p)) return(1);
		n =vol->dim[0];
		for(k=0; k<vol->dim[2]; k++)
		{
			for(i=0;i<vol->dim[0];i++)
			{
				cp = &c[i+vol->dim[0]*vol->dim[1]*k];
				for(j=0; j<vol->dim[1]; j++, cp+=n)
					f[j] = *cp;
				splinc[1](f, vol->dim[1], p, np);
				cp = &c[i+vol->dim[0]*vol->dim[1]*k];
				for(j=0; j<vol->dim[1]; j++, cp+=n)
					*cp = f[j];
			}
		}
	}

	/* Deconvolve along the slowest dimension (Z) */
	if (d[2]>1 && vol->dim[2]>1)
	{
		if (get_poles(d[2], &np, p)) return(1);
		n = vol->dim[0]*vol->dim[1];
		for(j=0; j<vol->dim[1]; j++)
		{
			for(i=0;i<vol->dim[0];i++)
			{
				cp = &c[i+vol->dim[0]*j];
				for(k=0; k<vol->dim[2]; k++, cp+=n)
					f[k] = *cp;
				splinc[2](f, vol->dim[2], p, np);
				cp = &c[i+vol->dim[0]*j];
				for(k=0; k<vol->dim[2]; k++, cp+=n)
					*cp = f[k];
			}
		}
	}
	return(0);
}
void assignmentsuboptimal1(double *assignment, double *cost, double *distMatrixIn, int nOfRows, int nOfColumns)
{
	bool infiniteValueFound, finiteValueFound, repeatSteps, allSinglyValidated, singleValidationFound;
	int n, row, col, tmpRow, tmpCol, nOfElements;
	int *nOfValidObservations, *nOfValidTracks;
	double value, minValue, *distMatrix, inf;
	
	inf = mxGetInf();
	
	/* make working copy of distance Matrix */
	nOfElements   = nOfRows * nOfColumns;
	distMatrix    = (double *)mxMalloc(nOfElements * sizeof(double));
	for(n=0; n<nOfElements; n++)
		distMatrix[n] = distMatrixIn[n];
	
	/* initialization */
	*cost = 0;
#ifdef ONE_INDEXING
	for(row=0; row<nOfRows; row++)
		assignment[row] =  0.0;
#else
	for(row=0; row<nOfRows; row++)
		assignment[row] = -1.0;
#endif
	
	/* allocate memory */
	nOfValidObservations  = (int *)mxCalloc(nOfRows,    sizeof(int));
	nOfValidTracks        = (int *)mxCalloc(nOfColumns, sizeof(int));
		
	/* compute number of validations */
	infiniteValueFound = false;
	finiteValueFound  = false;
	for(row=0; row<nOfRows; row++)
		for(col=0; col<nOfColumns; col++)
			if(mxIsFinite(distMatrix[row + nOfRows*col]))
			{
				nOfValidTracks[col]       += 1;
				nOfValidObservations[row] += 1;
				finiteValueFound = true;
			}
			else
				infiniteValueFound = true;
				
	if(infiniteValueFound)
	{
		if(!finiteValueFound)
			return;
			
		repeatSteps = true;
		
		while(repeatSteps)
		{
			repeatSteps = false;

			/* step 1: reject assignments of multiply validated tracks to singly validated observations		 */
			for(col=0; col<nOfColumns; col++)
			{
				singleValidationFound = false;
				for(row=0; row<nOfRows; row++)
					if(mxIsFinite(distMatrix[row + nOfRows*col]) && (nOfValidObservations[row] == 1))
					{
						singleValidationFound = true;
						break;
					}
					
				if(singleValidationFound)
				{
					for(row=0; row<nOfRows; row++)
						if((nOfValidObservations[row] > 1) && mxIsFinite(distMatrix[row + nOfRows*col]))
						{
							distMatrix[row + nOfRows*col] = inf;
							nOfValidObservations[row] -= 1;							
							nOfValidTracks[col]       -= 1;	
							repeatSteps = true;				
						}
					}
			}
			
			/* step 2: reject assignments of multiply validated observations to singly validated tracks */
			if(nOfColumns > 1)			
			{	
				for(row=0; row<nOfRows; row++)
				{
					singleValidationFound = false;
					for(col=0; col<nOfColumns; col++)
						if(mxIsFinite(distMatrix[row + nOfRows*col]) && (nOfValidTracks[col] == 1))
						{
							singleValidationFound = true;
							break;
						}
						
					if(singleValidationFound)
					{
						for(col=0; col<nOfColumns; col++)
							if((nOfValidTracks[col] > 1) && mxIsFinite(distMatrix[row + nOfRows*col]))
							{
								distMatrix[row + nOfRows*col] = inf;
								nOfValidObservations[row] -= 1;
								nOfValidTracks[col]       -= 1;
								repeatSteps = true;								
							}
						}
				}
			}
		} /* while(repeatSteps) */
	
		/* for each multiply validated track that validates only with singly validated  */
		/* observations, choose the observation with minimum distance */
		for(row=0; row<nOfRows; row++)
		{
			if(nOfValidObservations[row] > 1)
			{
				allSinglyValidated = true;
				minValue = inf;
				for(col=0; col<nOfColumns; col++)
				{
					value = distMatrix[row + nOfRows*col];
					if(mxIsFinite(value))
					{
						if(nOfValidTracks[col] > 1)
						{
							allSinglyValidated = false;
							break;
						}
						else if((nOfValidTracks[col] == 1) && (value < minValue))
						{
							tmpCol   = col;
							minValue = value;
						}
					}
				}
				
				if(allSinglyValidated)
				{
	#ifdef ONE_INDEXING
					assignment[row] = tmpCol + 1;
	#else
					assignment[row] = tmpCol;
	#endif
					*cost += minValue;
					for(n=0; n<nOfRows; n++)
						distMatrix[n + nOfRows*tmpCol] = inf;
					for(n=0; n<nOfColumns; n++)
						distMatrix[row + nOfRows*n] = inf;
				}
			}
		}

		/* for each multiply validated observation that validates only with singly validated  */
		/* track, choose the track with minimum distance */
		for(col=0; col<nOfColumns; col++)
		{
			if(nOfValidTracks[col] > 1)
			{
				allSinglyValidated = true;
				minValue = inf;
				for(row=0; row<nOfRows; row++)
				{
					value = distMatrix[row + nOfRows*col];
					if(mxIsFinite(value))
					{
						if(nOfValidObservations[row] > 1)
						{
							allSinglyValidated = false;
							break;
						}
						else if((nOfValidObservations[row] == 1) && (value < minValue))
						{
							tmpRow   = row;
							minValue = value;
						}
					}
				}
				
				if(allSinglyValidated)
				{
	#ifdef ONE_INDEXING
					assignment[tmpRow] = col + 1;
	#else
					assignment[tmpRow] = col;
	#endif
					*cost += minValue;
					for(n=0; n<nOfRows; n++)
						distMatrix[n + nOfRows*col] = inf;
					for(n=0; n<nOfColumns; n++)
						distMatrix[tmpRow + nOfRows*n] = inf;
				}
			}
		}	
	} /* if(infiniteValueFound) */
	
	
	/* now, recursively search for the minimum element and do the assignment */
	while(true)
	{
		/* find minimum distance observation-to-track pair */
		minValue = inf;
		for(row=0; row<nOfRows; row++)
			for(col=0; col<nOfColumns; col++)
			{
				value = distMatrix[row + nOfRows*col];
				if(mxIsFinite(value) && (value < minValue))
				{
					minValue = value;
					tmpRow   = row;
					tmpCol   = col;
				}
			}
		
		if(mxIsFinite(minValue))
		{
#ifdef ONE_INDEXING
			assignment[tmpRow] = tmpCol+ 1;
#else
			assignment[tmpRow] = tmpCol;
#endif
			*cost += minValue;
			for(n=0; n<nOfRows; n++)
				distMatrix[n + nOfRows*tmpCol] = inf;
			for(n=0; n<nOfColumns; n++)
				distMatrix[tmpRow + nOfRows*n] = inf;			
		}
		else
			break;
			
	} /* while(true) */
	
	/* free allocated memory */
	mxFree(nOfValidObservations);
	mxFree(nOfValidTracks);


}
Beispiel #11
0
void mrqminbd(double	x[],		// x values of dataset
			  double	y[],		// y values of dataset
			  double	sig[],		// individual std. deviations
			  int		npts,		// number of data points
			  double	p[],		// function parameters p
			  double	lb[],		// lower bounds on function parameters
			  double	ub[],		// upper bounds on function parameters
			  int		npar,		// number of function parameters
			  int		ip[],		// indices of parameters to fit
			  int		nfit,		// number of parameters to fit
			  double	**covar,	// returned covariance matrix
			  double	**alpha,	// returned curvature matrix
			  double	beta[],		// returned chi^2 partials matrix
			  double	*chisq,		// returned chi^2 value
			  double	(*funcs)(double,	// function x value, returns f(p, x)
								 double [],	// function parameters p
								 double [],	// returned df/dp values
								 int),		// number of parameters
			  double	*lambda) {	// returned curvature diagonal scaling factor

	// declare variables
	// some are static because of repeated calls

	static double	ochisq;		// old chi^2
	static double	*ptry;		// function parameters to test
	static double	*dp;		// parameter increments
	int				inverr;		// matrix inversion error
	int				j, k;		// loop counters

	// first call has scaling < 0 for initialization

	if (*lambda < 0.0) {
		ptry = (double *) mxCalloc(npar, sizeof(double));
		dp = (double *) mxCalloc(npar, sizeof(double));

		// assign initial parameters

		for (j = 0; j < npar; j++) {
			ptry[j] = p[j];
		}

		// return initial chi^2, curvature & chi^2 partial derivatives

		*lambda = FIRST_ALAMBDA;
		mrqcof(x, y, sig, npts, ptry, npar, ip, nfit, alpha, beta, chisq, funcs);
		ochisq = (*chisq);
		return;
	}

	// augment diagonal curvature values with lambda

	for (j = 0; j < nfit; j++) {
		for (k = 0; k < nfit; k++) {
			covar[j][k] = alpha[j][k];
		}
		covar[j][j] *= 1.0 + (*lambda);
		dp[j] = beta[j];
	}

	// solve for covariance & parameter increments
	// trial is unsuccessful if matrix inversion error

	inverr = gaussj(covar, dp, nfit);
	if (inverr < 0) {
		*lambda *= INC_ALAMBDA;
		return;
	}

	// last call has lambda = 0
	// rearrange matrices & free allocated space

	if (*lambda == 0.0) {
		if (nfit < npar) {
			ArrangeFixed(alpha, beta, npar, ip, nfit, SORT_BKWD);
			ArrangeFixed(covar, dp, npar, ip, nfit, SORT_BKWD);
		}
		mxFree((void *) dp);
		mxFree((void *) ptry);
		return;
	}

	// increment parameters to see if trial succeeded
	// trial is unsuccessful if bounds are exceeded

	for (j = 0; j < nfit; j++) {
		ptry[ip[j]] = p[ip[j]] + dp[j];
		if (mxIsFinite(lb[ip[j]]) && (ptry[ip[j]] <= lb[ip[j]])) {
			*lambda *= INC_ALAMBDA;
			return;
		}
		else if (mxIsFinite(ub[ip[j]]) && (ptry[ip[j]] >= ub[ip[j]])) {
			*lambda *= INC_ALAMBDA;
			return;
		}
	}

	// obtain updated chi^2, curvature & chi^2 partial derivatives
	// note that covar & dp are used to preserve alpha & beta if step fails

	mrqcof(x, y, sig, npts, ptry, npar, ip, nfit, covar, dp, chisq, funcs);

	// if successful, accept new parameters
	// decrease lambda

	if (*chisq < ochisq) {
		*lambda *= DEC_ALAMBDA;
		ochisq = (*chisq);
		for (j = 0; j < nfit; j++) {
			for (k = 0; k < nfit; k++) {
				alpha[j][k] = covar[j][k];
			}
			beta[j] = dp[j];
			p[ip[j]] = ptry[ip[j]];
		}
	}

	// otherwise reject new parameters
	// increase lambda

	else {
		*lambda *= INC_ALAMBDA;
		*chisq = ochisq;
	}
}
Beispiel #12
0
void assignmentoptimal(double *assignment, double *cost, double *distMatrixIn, int nOfRows, int nOfColumns)
{
	double *distMatrix, *distMatrixTemp, *distMatrixEnd, *columnEnd, value, minValue;
	bool *coveredColumns, *coveredRows, *starMatrix, *newStarMatrix, *primeMatrix;
	int nOfElements, minDim, row, col;
#ifdef CHECK_FOR_INF
	bool infiniteValueFound;
	double maxFiniteValue, infValue;
#endif
	
	/* initialization */
	*cost = 0;
	for(row=0; row<nOfRows; row++)
#ifdef ONE_INDEXING
		assignment[row] =  0.0;
#else
		assignment[row] = -1.0;
#endif
	
	/* generate working copy of distance Matrix */
	/* check if all matrix elements are positive */
	nOfElements   = nOfRows * nOfColumns;
	distMatrix    = (double *)mxMalloc(nOfElements * sizeof(double));
	distMatrixEnd = distMatrix + nOfElements;
	for(row=0; row<nOfElements; row++)
	{
		value = distMatrixIn[row];
		if(mxIsFinite(value) && (value < 0))
			mexErrMsgTxt("All matrix elements have to be non-negative.");
		distMatrix[row] = value;
	}

#ifdef CHECK_FOR_INF
	/* check for infinite values */
	maxFiniteValue     = -1;
	infiniteValueFound = false;
	
	distMatrixTemp = distMatrix;
	while(distMatrixTemp < distMatrixEnd)
	{
		value = *distMatrixTemp++;
		if(mxIsFinite(value))
		{
			if(value > maxFiniteValue)
				maxFiniteValue = value;
		}
		else
			infiniteValueFound = true;
	}
	if(infiniteValueFound)
	{
		if(maxFiniteValue == -1) /* all elements are infinite */
			return;
		
		/* set all infinite elements to big finite value */
		if(maxFiniteValue > 0)
			infValue = 10 * maxFiniteValue * nOfElements;
		else
			infValue = 10;
		distMatrixTemp = distMatrix;
		while(distMatrixTemp < distMatrixEnd)
			if(mxIsInf(*distMatrixTemp++))
				*(distMatrixTemp-1) = infValue;
	}
#endif
				
	/* memory allocation */
	coveredColumns = (bool *)mxCalloc(nOfColumns,  sizeof(bool));
	coveredRows    = (bool *)mxCalloc(nOfRows,     sizeof(bool));
	starMatrix     = (bool *)mxCalloc(nOfElements, sizeof(bool));
	primeMatrix    = (bool *)mxCalloc(nOfElements, sizeof(bool));
	newStarMatrix  = (bool *)mxCalloc(nOfElements, sizeof(bool)); /* used in step4 */

	/* preliminary steps */
	if(nOfRows <= nOfColumns)
	{
		minDim = nOfRows;
		
		for(row=0; row<nOfRows; row++)
		{
			/* find the smallest element in the row */
			distMatrixTemp = distMatrix + row;
			minValue = *distMatrixTemp;
			distMatrixTemp += nOfRows;			
			while(distMatrixTemp < distMatrixEnd)
			{
				value = *distMatrixTemp;
				if(value < minValue)
					minValue = value;
				distMatrixTemp += nOfRows;
			}
			
			/* subtract the smallest element from each element of the row */
			distMatrixTemp = distMatrix + row;
			while(distMatrixTemp < distMatrixEnd)
			{
				*distMatrixTemp -= minValue;
				distMatrixTemp += nOfRows;
			}
		}
		
		/* Steps 1 and 2a */
		for(row=0; row<nOfRows; row++)
			for(col=0; col<nOfColumns; col++)
				if(distMatrix[row + nOfRows*col] == 0)
					if(!coveredColumns[col])
					{
						starMatrix[row + nOfRows*col] = true;
						coveredColumns[col]           = true;
						break;
					}
	}
	else /* if(nOfRows > nOfColumns) */
	{
		minDim = nOfColumns;
		
		for(col=0; col<nOfColumns; col++)
		{
			/* find the smallest element in the column */
			distMatrixTemp = distMatrix     + nOfRows*col;
			columnEnd      = distMatrixTemp + nOfRows;
			
			minValue = *distMatrixTemp++;			
			while(distMatrixTemp < columnEnd)
			{
				value = *distMatrixTemp++;
				if(value < minValue)
					minValue = value;
			}
			
			/* subtract the smallest element from each element of the column */
			distMatrixTemp = distMatrix + nOfRows*col;
			while(distMatrixTemp < columnEnd)
				*distMatrixTemp++ -= minValue;
		}
		
		/* Steps 1 and 2a */
		for(col=0; col<nOfColumns; col++)
			for(row=0; row<nOfRows; row++)
				if(distMatrix[row + nOfRows*col] == 0)
					if(!coveredRows[row])
					{
						starMatrix[row + nOfRows*col] = true;
						coveredColumns[col]           = true;
						coveredRows[row]              = true;
						break;
					}
		for(row=0; row<nOfRows; row++)
			coveredRows[row] = false;
		
	}	
	
	/* move to step 2b */
	step2b(assignment, distMatrix, starMatrix, newStarMatrix, primeMatrix, coveredColumns, coveredRows, nOfRows, nOfColumns, minDim);

	/* compute cost and remove invalid assignments */
	computeassignmentcost(assignment, cost, distMatrixIn, nOfRows);
	
	/* free allocated memory */
	mxFree(distMatrix);
	mxFree(coveredColumns);
	mxFree(coveredRows);
	mxFree(starMatrix);
	mxFree(primeMatrix);
	mxFree(newStarMatrix);

	return;
}
Beispiel #13
0
/*this function does the job of averaging.*/
void doaveraging(const double *data, const double *dataerr,
		 const double energy, const double dist,
		 const double xresol, const double yresol,
		 const double bcx, const double bcy, const mxLogical *mask,
		 const double *q, double *I, double *E, double *A,
		 const mwSize M, const mwSize N, const mwSize Noutput,
		 const double par1, const double par2)
  
/* Directions:
 * +-----------------------------------------> Y
 * | 1,1    1,2    1,3    1,4    ...    1,N
 * | 2,1    2,2    2,3    2,4    ...    1,N
 * | 3,1    3,2    3,3    3,4    ...    1,N
 * | 4,1    4,2    4,3    4,4    ...    1,N
 * |  .      .      .      .     .       .
 * |  .      .      .      .      .      .
 * |  .      .      .      .       .     .
 * | M,1    M,2    M,3    M,4    ...    M,N
 * |
 * | X
 * v 
 *
 */         
  
{
  mwIndex i,j,k;
#if INT_MODE==ASIM
  double rmin, rmax;
  double *phi0, *dphi;
  double dmax2,dmin2; /*dmax and dmin to the second, this is used for TEST2*/
#else /*for both RAD and SECTOR*/
  double *rmin,*rmax; /*rmin and rmax: distances from the origin
			corresponding to the current q-ring*/
  double *dmax2,*dmin2; /*dmax and dmin to the second, this is used for TEST2*/
#  if INT_MODE==SECTOR
  double phi0, dphi; /*phi0 is the beginning angle of the sector, dphi is
		       the length of it. Both are expressed in radians.*/
#  endif
#endif
  double xc,yc,x0,y0,x1,y1; /*for each pixel, xc,yc is its center,
			      x0,y0,x1,y1 are the coordinates for the
			      corners*/
  double x,y;       /*loop variables for subpixel resolution*/
  unsigned long n;  /*counter for subpixel resolution*/
  double p;         /*used for subpixel resolution*/
  double avgresol=sqrt(xresol*xresol+yresol*yresol);  /*the average resolution*/
  
  /*"decode" par1 and par2*/
#if INT_MODE==ASIM
  /*these are the distances from the origin, corresponding to the lower and
    high bounds of the q-ring for azimuthal averaging.*/
  rmin=tan(asin(par1*HC/energy/4/M_PI)*2)*dist; 
  rmax=tan(asin(par2*HC/energy/4/M_PI)*2)*dist;
  /*limits for TEST2*/
  dmax2=pow(rmax+avgresol,2);
  dmin2=pow(((rmin-avgresol)<0)?0:(rmin-avgresol),2);
  phi0=mxMalloc(sizeof(double)*Noutput);
  dphi=mxMalloc(sizeof(double)*Noutput);
#else /*RAD or SECTOR*/
  rmin=mxMalloc(sizeof(double)*Noutput);
  rmax=mxMalloc(sizeof(double)*Noutput);
  dmax2=mxMalloc(sizeof(double)*Noutput);
  dmin2=mxMalloc(sizeof(double)*Noutput);
#  if INT_MODE==SECTOR
  phi0=par1;  /*these are now in radians*/
  dphi=par2;
#  endif /*INT_MODE==SECTOR*/
#endif /*INT_MODE==ASIM*/
  
  for (i=0; i<Noutput; i++) /*this loop cleans all the q-bins and
			      initializes rmin,rmax or phi0,dphi
			      depending on the mode. The
			      initialization of those array seems to
			      be a better idea than calculating these
			      values in every q-bin, as this is done
			      once, that would be done about M*N
			      times. Think about a 1024x1024 matrix...*/
    {
      double q1,q2; /*the left and right hand side of the i-th q-bin.*/
      A[i]=0; /*clear the bin*/
      I[i]=0;
      E[i]=0;
	    
      /********************************************************************
       *  Bin borders (marked by "x"):
       *
       *  x    x        x          x                           x         x     
       *  |         |        |            |           |                  |
       * q[0]      q[1]     q[2]         q[3] ...  q[Noutput-2]     q[Noutput-1]
       *
       *
       ********************************************************************/
      if (i>0) /*if this is not the first bin*/
	q1=0.5*(q[i-1]+q[i]);
      else /*if this is the first*/
	q1=q[0];
      if (i<(Noutput-1))  /*if this is not the last bin*/
	q2=0.5*(q[i]+q[i+1]);
      else /*if this is the last bin*/
	q2=q[Noutput-1];
	    
#if INT_MODE==ASIM
      /*the starting angle and the length of the bin. Note, that
	for angles, not the min-max interval method is used, as for q-s,
	as problems can occur around 2*pi.*/
      phi0[i]=q1;
      dphi[i]=fmod((q2-q1)+10*M_PI,2*M_PI);
      /*rmin, rmax, dmax2 and dmin2 are already defined, and they are SCALARS.*/
#else /*RADINT and SECTORINT*/
      /*find the minimal and the maximal radius for the given q-bin.
	For ASIMINT, it was done outside the q-loop*/
      /*phi0 and dphi is already defined for SECTORINT, as scalars. They are
	not used for RADINT*/
      rmin[i]=tan(asin(q1*HC/energy/4/M_PI)*2)*dist;
      rmax[i]=tan(asin(q2*HC/energy/4/M_PI)*2)*dist;
      dmax2[i]=(rmax[i]+avgresol)*(rmax[i]+avgresol);
      dmin2[i]=(((rmin[i]-avgresol)<0)?0:(rmin[i]-avgresol))*
	(((rmin[i]-avgresol)<0)?0:(rmin[i]-avgresol));
#endif
    }
  
  /*go through the pixels.*/
  for(j=0; j<M; j++) /*rows*/
    for(k=0; k<N; k++) /*columns*/
      {
	double d1,d2,d3,d4; /*these contain the SQUARES of the distances of
			      the corners of the current pixel, from the 
			      origin*/
#if INT_MODE==ASIM || INT_MODE==SECTOR        
        double phi1,phi2,phi3,phi4; /*these contain the polar angles of the
				      corners of the current pixel, with
				      respect to angle 0 (axis x, which is
				      downwards).*/
#endif
	unsigned long proportion_added=0; /*this counts how much
					    sub-pixels were
					    distributed to q-bins. If
					    this reaches
					    NSUBDIVX*NSUBDIVY, the
					    q-loop is terminated.*/
	/*the next two arrays are used in the subpixel loops.*/
	double rr[NSUBDIVX*NSUBDIVY]; /*radius to the second for each
					sub-pixel*/
	double phi[NSUBDIVX*NSUBDIVY]; /*polar angle for each sub-pixel*/
	/*TASK #1: eliminate unneeded pixels.*/
	
	/*the current pixel is data[k*M+j] as Octave and Matlab
	  represents the matrices column-wise, as Fortran.*/
	if (mask[k*M+j]!=0) /*if the pixel is masked, continue with
			      the next one.*/
	  continue;
	/*if the pixel data or error is NaN or infinite, disregard
	  that pixel as well.*/
	if (!mxIsFinite(data[k*M+j]) || !mxIsFinite(dataerr[k*M+j]))
	  continue;

	/*TASK #2: calculate pixel coordinates and all the data which
	  have to be calculated here, not inside the q-loop.*/

	/*now calculate the coordinates. All coordinates are
	  relative to the beam-center!*/
	xc=(j-(bcx-1))*xresol; /*the coordinates of the center of
				 the pixel.*/
	yc=(k-(bcy-1))*yresol;
	/*the coordinates of the corners*/
	x0=xc-xresol*0.5;  y0=yc-yresol*0.5;
	x1=xc+xresol*0.5;  y1=yc+yresol*0.5;
	/*the squared distances of the corners from the origin.*/
	d1=x0*x0+y0*y0;  d2=x0*x0+y1*y1;
	d3=x1*x1+y1*y1;  d4=x1*x1+y0*y0;
#if (INT_MODE==SECTOR) || (INT_MODE==ASIM)        
        /*the polar angles of the corners, with respect to the +x axis*/
        phi1=atan2(y0,x0);    	phi2=atan2(y1,x0);
    	phi3=atan2(y1,x1);    	phi4=atan2(y0,x1);
#endif
	/*TASK #3: throw away pixels which for sure fall outside the
	  integration range. This means the sector for SECTORINT
	  (defined by phi0 and dphi) and the ring for ASIMINT (given
	  by rmin and rmax).*/

#if (INT_MODE==SECTOR)
        /*for sector integration only, because for azimuthal integration,
	  this is carried out inside the a-loop.*/
        /*TEST 3: For sector and asimuthal averaging methods. If neither
	  of the lines defining the sector intersects none of the edges
	  of the pixel, ignore the pixel. For an edge and a line, the
	  condition of intersection is when the following equation is
	  true for the angle of the line and one end of the edge (a1),
	  the angle of the line and the other end of the edge (a2) and
	  the angle of the two ends of the edge (b):
	  a1<b and a2<b
	  By "angle of two objects" I mean the smallest possible
	  positive angle between 0 and pi/2.*/
        if (!test3intersect(phi1,phi2,phi0) && 
            !test3intersect(phi2,phi3,phi0) && 
            !test3intersect(phi3,phi4,phi0) &&
            !test3intersect(phi4,phi1,phi0) &&
            !test3intersect(phi1,phi2,phi0+dphi) && 
            !test3intersect(phi2,phi3,phi0+dphi) && 
            !test3intersect(phi3,phi4,phi0+dphi) &&
            !test3intersect(phi4,phi1,phi0+dphi))
	  continue;
#elif (INT_MODE==ASIM)
	/*For ASIMINT, we already have all the parameters needed to perform
	  TEST1 and TEST2. */
	/*TEST 1: Eliminate pixels, for which the distance of all
	  four corners from the origin is greater than
	  rmax+sqrt(xresol^2+yresol^2). Thus these pixels fall entirely
          outside the given q-range.
	*/
	if (d1>dmax2 && d2>dmax2 && d3>dmax2 && d4>dmax2)
	  continue;
        /*TEST 2: The same as above, except for rmin.*/
    	if (d1<dmin2 && d2<dmin2 && d3<dmin2 && d4<dmin2)
	  continue;
#endif
	/*TASK #4: if we reached here, we should try to fit the pixel
	  into q-ranges.*/
	/*TASK #4a: calculate rr and phi values for each sub-pixel.*/
	n=0; /*this indexes the rr and phi arrays*/
	for (x=x0+0.5*xresol/(double)NSUBDIVX; x<x1;
	     x+=xresol/(double)NSUBDIVX)
	  for (y=y0+0.5*yresol/(double)NSUBDIVY; y<y1;
	       y+=yresol/(double)NSUBDIVY)
	    {
	      rr[n]=x*x+y*y; /*the squared distance of the
			       subdivision point from the
			       beam-center*/
	      phi[n]=atan2(y,x); /*the angle of the subdivision
				   point. 0 is the +x axis (pointing
				   down), positive
				   counterclockwise. This phi is in
				   [-pi,pi]*/
	      n++;
	    }
	
	proportion_added=0;
        for (i=0;
	     ((i<Noutput) && (proportion_added<NSUBDIVX*NSUBDIVY));
	     i++) /*this is the q-loop, which goes through all points
		    of the independent value (q or angle). The
		    independent value is called "q", even for
		    asimuthal integration. Thus we can use the same
		    lines of code.*/
          {
	    unsigned long l; /*loop variable*/
	    /*TASK #4b: in the current q-bin, we can eliminate other
	      pixels, which were not eliminated before this.*/
#if INT_MODE==RAD || INT_MODE==SECTOR
            /*We perform TEST1 and TEST2 ONLY FOR RADINT and SECTORINT!
	      Because for ASIMINT, it is done outside the q-loop.*/
            
            /*TEST 1: Eliminate pixels, for which the distance of all
    	      four corners from the origin is greater than
    	      rmax+sqrt(xresol^2+yresol^2). Thus these pixels fall entirely
              outside the given q-range.
    	    */
	    
    	    if (d1>dmax2[i] && d2>dmax2[i] && d3>dmax2[i] && d4>dmax2[i])
              continue; /*next q-bin*/
	    
    	    /*TEST 2: The same as above, except for rmin.*/
    	    if (d1<dmin2[i] && d2<dmin2[i] && d3<dmin2[i] && d4<dmin2[i])
    	      continue; /*next q-bin*/
#elif (INT_MODE==ASIM)
            /*for azimuthal integration only, because for sector integration,
	      this has already been carried out outside the q-loop.*/
            /*TEST 3: For sector and asimuthal averaging methods. If neither
              of the lines defining the sector intersects none of the edges
              of the pixel, ignore the pixel. For an edge and a line, the
              condition of intersection is when the following equation is
              true for the angle of the line and one end of the edge (a1),
              the angle of the line and the other end of the edge (a2) and
              the angle of the two ends of the edge (b):
	      a1<b and a2<b
	      By "angle of two objects" I mean the smallest possible
	      positive angle between 0 and pi/2.*/
            if (!test3intersect(phi1,phi2,phi0[i]) && 
                !test3intersect(phi2,phi3,phi0[i]) && 
                !test3intersect(phi3,phi4,phi0[i]) &&
                !test3intersect(phi4,phi1,phi0[i]) &&
                !test3intersect(phi1,phi2,phi0[i]+dphi[i]) && 
                !test3intersect(phi2,phi3,phi0[i]+dphi[i]) && 
                !test3intersect(phi3,phi4,phi0[i]+dphi[i]) &&
                !test3intersect(phi4,phi1,phi0[i]+dphi[i]))
	      continue; /*next q-bin*/
#endif

	    /*TASK #4c: subdividing.*/

    	    n=0; /*this will contain the number of hits, ie. the number of
		   subpixels falling into the current q-bin*/
    	    for (l=0; l<NSUBDIVX*NSUBDIVY; l++)
	      {
		/*now decide if hit or not. The subdivision point
		  should be counted, if it is between the two
		  circles and:
		  
		  1. for RADINT, no other properties needed
		  
		  2. in SECTORINT and ASIMINT modes, the angle
		  difference of the point (phi) and the beginning of
		  the sector (phi0) should be less than dphi.*/
#if INT_MODE==RAD
		if (rr[l]>rmin[i]*rmin[i] && rr[l]<=rmax[i]*rmax[i])
		    n++;
#elif INT_MODE==SECTOR
		  if ((rr[l]>rmin[i]*rmin[i] && rr[l]<=rmax[i]*rmax[i]) && 
		      (fmod(phi[l]-phi0+10*M_PI,2*M_PI)<dphi))
		    n++;
#elif INT_MODE==ASIM
		  if ((rr[l]>rmin*rmin && rr[l]<=rmax*rmax) && 
		      (fmod(phi[l]-phi0[i]+10*M_PI,2*M_PI)<dphi[i]))
		    n++;
#endif
	      }
	    proportion_added+=n;
	    /*TASK #4d: add the intensity to the bin*/
            p=n/(double)(NSUBDIVX*NSUBDIVY); /*this is the proportion
					       of the intensity in the
                                               current pixel, which
                                               should be added to the
					       current bin.*/
            A[i]+=p;                         /*count the area. Its
                                     	       dimension is pixels.*/
            I[i]+=data[k*M+j]*p;             /*add that part of intensity*/
            /*the squares of the errors are summed. At the end, a
	      square-root will be taken.*/
            E[i]+=(dataerr[k*M+j]*p)*(dataerr[k*M+j]*p);
	  } /*end of q-loop*/
	/*next pixel*/
      } /*end of double loop for pixels*/

  /*TASK #5: post-processing of the averaged data: normalizing by
    effective area*/
  for (i=0; i<Noutput; i++)
    {
      if (A[i]!=0) /*if the area for this q is not zero, divide, thus
		     making an average from the integral.*/
	{
	  I[i]/=A[i];
	  /*	  E[i]/=A[i]*A[i];*/ /*eliminated on suggestion of Ulla Vainio*/
	  /*	  E[i]=sqrt(E[i]);*/
	  E[i]=sqrt(E[i])/A[i]; /*this is definitely faster. Thanks.*/
	}
    }
  /*TASK #6: cleanup*/
#if INT_MODE==ASIM
  mxFree(phi0);
  mxFree(dphi);
#else /*RAD or SECTOR*/
  mxFree(rmin);
  mxFree(rmax);
  mxFree(dmax2);
  mxFree(dmin2);
#endif
}
Beispiel #14
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{
    MAPTYPE *map, *get_maps();
    mwSize m,n,k;
    mwIndex i;
    int nn, E[3], F[3], P, C;
    double *R, r[3], *img;
    int *curr, *prev, *tmpp;

    if (nrhs != 2 || nlhs > 1)
    {
        mexErrMsgTxt("Incorrect usage.");
    }

    map = get_maps(prhs[0], &nn);
    if (nn!=1)
    {
        free_maps(map, nn);
        mexErrMsgTxt("Bad image handle dimensions.");
    }

    if (!mxIsNumeric(prhs[1]) || mxIsComplex(prhs[1]) || !mxIsDouble(prhs[1]))
    {
        free_maps(map, 1);
        mexErrMsgTxt("Second argument must be numeric, real, full and double.");
    }

    if (mxGetM(prhs[1])*mxGetN(prhs[1]) != 3)
    {
        free_maps(map, nn);
        mexErrMsgTxt("Second argument must contain three elements.");
    }

    r[0] = 1.0/mxGetPr(prhs[1])[0];
    r[1] = 1.0/mxGetPr(prhs[1])[1];
    r[2] = 1.0/mxGetPr(prhs[1])[2];

    plhs[0] = mxCreateDoubleMatrix(4,1,mxREAL);
    R       = mxGetPr(plhs[0]);

    m = map->dim[0];
    n = map->dim[1];
    k = map->dim[2];

    curr = (int *)mxCalloc((m+1)*(n+1),sizeof(int)); /* current plane */
    prev = (int *)mxCalloc((m+1)*(n+1),sizeof(int)); /* previous plane */
    img  = (double *)mxCalloc((m+1)*(n+1),sizeof(double));

    P = C = E[0] = E[1] = E[2] = F[0] = F[1] = F[2] = 0;
    for(i=0; i<k; i++)
    {
        int i1, j1;
        static double mat[16] = {
            1.0, 0.0, 0.0, 0.0,
            0.0, 1.0, 0.0, 0.0,
            0.0, 0.0, 1.0, 0.0,
            0.0, 0.0, 0.0, 1.0};
        mat[14] = i+1.0;
        slice(mat, img, m, n, map, 0, 0);
        for(i1=0;i1<m; i1++)
            for(j1=0; j1<n; j1++)
                if (mxIsFinite(img[i1+m*j1]) && img[i1+m*j1])
                    curr[i1+1+(m+1)*(j1+1)] = 1;
                else
                    curr[i1+1+(m+1)*(j1+1)] = 0;

        /* count edges, faces etc */
        resel_fun(curr,prev,m+1,n+1, &P, E, F, &C);

        /* make current plane previous */
        tmpp = prev; prev = curr; curr = tmpp;
    }

    (void)mxFree((char *)curr);
    (void)mxFree((char *)prev);
    (void)mxFree((char *)img);
    free_maps(map, 1);

    R[0] = P - (E[0]+E[1]+E[2])+(F[0]+F[1]+F[2])-C;
    R[1] = (E[0]-F[0]-F[1]+C)*r[0] + (E[1]-F[0]-F[2]+C)*r[1] + (E[2]-F[1]-F[2]+C)*r[2];
    R[2] = (F[0]-C)*r[0]*r[1] + (F[1]-C)*r[0]*r[2] + (F[2]-C)*r[1]*r[2];
    R[3] = C*r[0]*r[1]*r[2];
}