about summary refs log tree commit diff
path: root/sourcecodes/bnt-master/BNT/potentials/genops.c
diff options
context:
space:
mode:
authorziejd22017-09-28 15:04:40 -0500
committerziejd22017-09-28 15:04:40 -0500
commit8070dc963753142bb86c4ed698d91fd623ed28e7 (patch)
treed0f6dd8fc46a49b819aa55c1a90faa14d8448883 /sourcecodes/bnt-master/BNT/potentials/genops.c
parent7cc31810d53176e805532b2789955f4eedbce6bb (diff)
downloadBNW-8070dc963753142bb86c4ed698d91fd623ed28e7.tar.gz
BNW using Octave instead of Matlab.
This version of BNW should perform the same as the original version. The only difference is that it uses Octave instead of Matlab when running BayesNet Toolbox during parameter learning.

I am calling this BNW_1.02. It can be accessed at:
compbio.uthsc.edu/BNW_1.02
Diffstat (limited to 'sourcecodes/bnt-master/BNT/potentials/genops.c')
-rw-r--r--sourcecodes/bnt-master/BNT/potentials/genops.c707
1 files changed, 707 insertions, 0 deletions
diff --git a/sourcecodes/bnt-master/BNT/potentials/genops.c b/sourcecodes/bnt-master/BNT/potentials/genops.c
new file mode 100644
index 00000000..0416ff68
--- /dev/null
+++ b/sourcecodes/bnt-master/BNT/potentials/genops.c
@@ -0,0 +1,707 @@
+/*
+
+	GENOPS.C
+		Generalized arithmetic operators overloading built-in functions.
+
+	written by Douglas M. Schwarz
+	schwarz@servtech.com
+	26 December 1998
+	Last modified: 2 April 1999
+
+	Copyright 1998-1999 by Douglas M. Schwarz.  All rights reserved.
+
+*/
+
+
+/*
+
+Build MEX file by entering the appropriate command at the MATLAB prompt
+(-D<name> option is equivalent to #define <name> in source file):
+
+mex genops.c -DPLUS_MEX -output plus
+mex genops.c -DMINUS_MEX -output minus
+mex genops.c -DTIMES_MEX -output times
+mex genops.c -DRDIVIDE_MEX -output rdivide
+mex genops.c -DLDIVIDE_MEX -output ldivide
+mex genops.c -DPOWER_MEX -output power
+mex genops.c -DEQ_MEX -output eq
+mex genops.c -DNE_MEX -output ne
+mex genops.c -DLT_MEX -output lt
+mex genops.c -DGT_MEX -output gt
+mex genops.c -DLE_MEX -output le
+mex genops.c -DGE_MEX -output ge
+
+*/
+
+/*	This file has been formatted for a tab equal to 4 spaces. */
+
+#if defined(EQ_MEX) || defined(NE_MEX) || defined(LT_MEX) || defined(GT_MEX) \
+		|| defined(LE_MEX) || defined(GE_MEX)
+#define	RELOP_MEX
+#endif
+
+#include "mex.h"
+#include "matrix.h"
+#ifdef POWER_MEX
+#include <math.h>
+#define PI 3.141592653589793
+#endif
+
+bool allequal(int, const int *, const int *);
+void removeZeroImag(double *, double *, int, const int *, int, mxArray **);
+
+#define	xMat  prhs[0]
+#define	yMat  prhs[1]
+#define	zMat  plhs[0]
+
+#define	min(A,B)  ((A) < (B) ? (A) : (B))
+#define	max(A,B)  ((A) > (B) ? (A) : (B))
+
+void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
+{
+	double		*xrp, *xip, *yrp, *yip;
+#ifndef RELOP_MEX
+	double		*zr, *zi, *zip;
+#endif
+	double		*zrp, *zrend;
+	int			xnd, ynd, numElements = 1;
+	const int	*xdim, *ydim;
+	bool		xcmplx, ycmplx;
+	mxClassID	yclass;
+	int			*s, ndim, *sx, *sy, i, *cpsx, *cpsy;
+	int			*subs, *s1, *cpsx2, *cpsy2;
+	int			ix = 0, iy = 0;
+	mxArray		*args[3], *result[1];
+#if defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
+	double		denom;
+#endif
+#ifdef POWER_MEX
+	double		mag, theta, phi, magx;
+	int			flops = 0;
+#endif
+	
+	
+	if (nrhs != 2)
+		mexErrMsgTxt("Incorrect number of inputs.");
+	
+	if (nlhs > 1)
+		mexErrMsgTxt("Too many output arguments.");
+	
+	xnd = mxGetNumberOfDimensions(xMat);
+	ynd = mxGetNumberOfDimensions(yMat);
+	xdim = mxGetDimensions(xMat);
+	ydim = mxGetDimensions(yMat);
+	
+	yclass = mxGetClassID(yMat);
+	
+/*	If the built-in function in MATLAB can handle the arguments
+	then use that. */
+	if (yclass != mxDOUBLE_CLASS || 
+		(xnd == 2  &&  xdim[0] == 1  &&  xdim[1] == 1) || 
+		(ynd == 2  &&  ydim[0] == 1  &&  ydim[1] == 1) || 
+		(xnd == ynd  &&  allequal(xnd,xdim,ydim)))
+	{
+#ifdef PLUS_MEX
+		args[0] = mxCreateString("plus");
+#elif defined(MINUS_MEX)
+		args[0] = mxCreateString("minus");
+#elif defined(TIMES_MEX)
+		args[0] = mxCreateString("times");
+#elif defined(RDIVIDE_MEX)
+		args[0] = mxCreateString("rdivide");
+#elif defined(LDIVIDE_MEX)
+		args[0] = mxCreateString("ldivide");
+#elif defined(POWER_MEX)
+		args[0] = mxCreateString("power");
+#elif defined(EQ_MEX)
+		args[0] = mxCreateString("eq");
+#elif defined(NE_MEX)
+		args[0] = mxCreateString("ne");
+#elif defined(LT_MEX)
+		args[0] = mxCreateString("lt");
+#elif defined(GT_MEX)
+		args[0] = mxCreateString("gt");
+#elif defined(LE_MEX)
+		args[0] = mxCreateString("le");
+#elif defined(GE_MEX)
+		args[0] = mxCreateString("ge");
+#endif
+		args[1] = (mxArray *)xMat;
+		args[2] = (mxArray *)yMat;
+		mexCallMATLAB(1, result, 3, args, "builtin");
+		mxDestroyArray(args[0]);
+		zMat = result[0];
+	}
+	else  /* X and Y are both N-D and different dimensionality. */
+	{
+		ndim = max(xnd,ynd);
+		sx = (int *)mxMalloc(sizeof(int)*ndim);
+		sy = (int *)mxMalloc(sizeof(int)*ndim);
+		s =  (int *)mxMalloc(sizeof(int)*ndim);
+		s1 = (int *)mxMalloc(sizeof(int)*ndim);
+		*(cpsx = (int *)mxMalloc(sizeof(int)*ndim)) = 1;
+		*(cpsy = (int *)mxMalloc(sizeof(int)*ndim)) = 1;
+		subs =   (int *)mxMalloc(sizeof(int)*ndim);
+		cpsx2 =  (int *)mxMalloc(sizeof(int)*ndim);
+		cpsy2 =  (int *)mxMalloc(sizeof(int)*ndim);
+		for (i = 0; i < ndim; i++)
+		{
+			subs[i] = 0;
+			sx[i] = (i < xnd) ? xdim[i] : 1;
+			sy[i] = (i < ynd) ? ydim[i] : 1;
+			if (sx[i] == sy[i])
+				s[i] = sx[i];
+			else if (sx[i] == 1)
+				s[i] = sy[i];
+			else if (sy[i] == 1)
+				s[i] = sx[i];
+			else
+			{
+				mxFree(sx);
+				mxFree(sy);
+				mxFree(s);
+				mxFree(s1);
+				mxFree(cpsx);
+				mxFree(cpsy);
+				mxFree(subs);
+				mxFree(cpsx2);
+				mxFree(cpsy2);
+				mexErrMsgTxt("Array dimensions are not appropriate.");
+			}
+			s1[i] = s[i] - 1;
+			numElements *= s[i];
+		}
+				
+		for (i = 0; i < ndim-1; i++)
+		{
+			cpsx[i+1] = cpsx[i]*sx[i]--;
+			cpsy[i+1] = cpsy[i]*sy[i]--;
+			cpsx2[i] = cpsx[i]*sx[i];
+			cpsy2[i] = cpsy[i]*sy[i];
+		}
+		cpsx2[ndim-1] = cpsx[ndim-1]*(--sx[ndim-1]);
+		cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
+		
+		xcmplx = mxIsComplex(xMat);
+		ycmplx = mxIsComplex(yMat);
+		
+		if (!xcmplx && !ycmplx)  /* X and Y both N-D, both real. */
+		{
+#ifdef POWER_MEX
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = zr = mxGetPr(zMat);
+			zip = zi = mxGetPi(zMat);
+#elif defined(RELOP_MEX)
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			mxSetLogical(zMat);
+			zrp = mxGetPr(zMat);
+#else
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			zrp = mxGetPr(zMat);
+#endif
+			xrp = mxGetPr(xMat);
+			yrp = mxGetPr(yMat);
+			zrend = zrp + numElements;
+			while (zrp < zrend)
+			{
+#ifdef PLUS_MEX
+				*zrp++ = *xrp + *yrp;
+#elif defined(MINUS_MEX)
+				*zrp++ = *xrp - *yrp;
+#elif defined(TIMES_MEX)
+				*zrp++ = *xrp * *yrp;
+#elif defined(RDIVIDE_MEX)
+				*zrp++ = *xrp / *yrp;
+#elif defined(LDIVIDE_MEX)
+				*zrp++ = *yrp / *xrp;
+#elif defined(POWER_MEX)
+				if (*xrp < 0.0 && *yrp != floor(*yrp))
+				{
+					mag = pow(-*xrp,*yrp);
+					theta = PI * *yrp;
+					*zrp++ = mag*cos(theta);
+					*zip++ = mag*sin(theta);
+					flops += 18;
+				}
+				else
+				{
+					*zrp++ = pow(*xrp,*yrp);
+					*zip++ = 0.0;
+					flops++;
+				}
+#elif defined(EQ_MEX)
+				*zrp++ = (*xrp == *yrp);
+#elif defined(NE_MEX)
+				*zrp++ = (*xrp != *yrp);
+#elif defined(LT_MEX)
+				*zrp++ = (*xrp < *yrp);
+#elif defined(GT_MEX)
+				*zrp++ = (*xrp > *yrp);
+#elif defined(LE_MEX)
+				*zrp++ = (*xrp <= *yrp);
+#elif defined(GE_MEX)
+				*zrp++ = (*xrp >= *yrp);
+#endif
+				for (i = 0; i < ndim; i++)
+				{
+					if (subs[i] == s1[i])
+					{
+						subs[i] = 0;
+						if (sx[i])
+							xrp -= cpsx2[i];
+						if (sy[i])
+							yrp -= cpsy2[i];
+					}
+					else
+					{
+						subs[i]++;
+						if (sx[i])
+							xrp += cpsx[i];
+						if (sy[i])
+							yrp += cpsy[i];
+						break;
+					}
+				}
+			}
+#ifdef POWER_MEX
+			mexAddFlops(flops);
+			removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
+#elif !defined(RELOP_MEX)
+			mexAddFlops(numElements);
+#endif
+		}
+		else if (!xcmplx && ycmplx)  /* X and Y both N-D, X real, Y complex. */
+		{
+#ifdef POWER_MEX
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = zr = mxGetPr(zMat);
+			zip = zi = mxGetPi(zMat);
+#elif defined(RELOP_MEX)
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			mxSetLogical(zMat);
+			zrp = mxGetPr(zMat);
+#else
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = mxGetPr(zMat);
+			zip = mxGetPi(zMat);
+#endif
+			xrp = mxGetPr(xMat);
+			yrp = mxGetPr(yMat);
+			yip = mxGetPi(yMat);
+			zrend = zrp + numElements;
+			while (zrp < zrend)
+			{
+#ifdef PLUS_MEX
+				*zrp++ = *xrp + *yrp;
+				*zip++ = *yip;
+#elif defined(MINUS_MEX)
+				*zrp++ = *xrp - *yrp;
+				*zip++ = -*yip;
+#elif defined(TIMES_MEX)
+				*zrp++ = *xrp * *yrp;
+				*zip++ = *xrp * *yip;
+#elif defined(RDIVIDE_MEX)
+				denom = *yrp * *yrp + *yip * *yip;
+				*zrp++ = (*xrp * *yrp)/denom;
+				*zip++ = (-*xrp * *yip)/denom;
+#elif defined(LDIVIDE_MEX)
+				*zrp++ = *yrp / *xrp;
+				*zip++ = *yip / *xrp;
+#elif defined(POWER_MEX)
+				if (*yip == 0.0)
+				{
+					if (*xrp < 0.0 && *yrp != floor(*yrp))
+					{
+						mag = pow(-*xrp,*yrp);
+						theta = PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						*zrp++ = pow(*xrp,*yrp);
+						*zip++ = 0.0;
+						flops++;
+					}
+				}
+				else
+				{
+					if (*xrp < 0.0)
+					{
+						mag = pow(-*xrp,*yrp)*exp(-PI * *yip);
+						theta = *yip * log(-*xrp) + PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						mag = pow(*xrp,*yrp);
+						theta = *yip * log(*xrp);
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 13;
+					}
+				}
+#elif defined(EQ_MEX)
+				*zrp++ = (*xrp == *yrp) && (*yip == 0.0);
+#elif defined(NE_MEX)
+				*zrp++ = (*xrp != *yrp) || (*yip != 0.0);
+#elif defined(LT_MEX)
+				*zrp++ = (*xrp < *yrp);
+#elif defined(GT_MEX)
+				*zrp++ = (*xrp > *yrp);
+#elif defined(LE_MEX)
+				*zrp++ = (*xrp <= *yrp);
+#elif defined(GE_MEX)
+				*zrp++ = (*xrp >= *yrp);
+#endif
+				for (i = 0; i < ndim; i++)
+				{
+					if (subs[i] == s1[i])
+					{
+						subs[i] = 0;
+						if (sx[i])
+							xrp -= cpsx2[i];
+						if (sy[i])
+						{
+							yrp -= cpsy2[i];
+							yip -= cpsy2[i];
+						}
+					}
+					else
+					{
+						subs[i]++;
+						if (sx[i])
+							xrp += cpsx[i];
+						if (sy[i])
+						{
+							yrp += cpsy[i];
+							yip += cpsy[i];
+						}
+						break;
+					}
+				}
+			}
+#if defined(PLUS_MEX) || defined(MINUS_MEX)
+			mexAddFlops(2*numElements);
+#elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
+			mexAddFlops(6*numElements);
+#elif defined(POWER_MEX)
+			mexAddFlops(flops);
+			removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
+#endif
+		}
+		else if (xcmplx && !ycmplx)  /* X and Y both N-D, X complex, Y real. */
+		{
+#ifdef POWER_MEX
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = zr = mxGetPr(zMat);
+			zip = zi = mxGetPi(zMat);
+#elif defined(RELOP_MEX)
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			mxSetLogical(zMat);
+			zrp = mxGetPr(zMat);
+#else
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = mxGetPr(zMat);
+			zip = mxGetPi(zMat);
+#endif
+			xrp = mxGetPr(xMat);
+			xip = mxGetPi(xMat);
+			yrp = mxGetPr(yMat);
+			zrend = zrp + numElements;
+			while (zrp < zrend)
+			{
+#ifdef PLUS_MEX
+				*zrp++ = *xrp + *yrp;
+				*zip++ = *xip;
+#elif defined(MINUS_MEX)
+				*zrp++ = *xrp - *yrp;
+				*zip++ = *xip;
+#elif defined(TIMES_MEX)
+				*zrp++ = *xrp * *yrp;
+				*zip++ = *xip * *yrp;
+#elif defined(RDIVIDE_MEX)
+				*zrp++ = *xrp / *yrp;
+				*zip++ = *xip / *yrp;
+#elif defined(LDIVIDE_MEX)
+				denom = *xrp * *xrp + *xip * *xip;
+				*zrp++ = (*xrp * *yrp)/denom;
+				*zip++ = (-*xip * *yrp)/denom;
+#elif defined(POWER_MEX)
+				if (*xip == 0.0)
+				{
+					if (*xrp < 0.0 && *yrp != floor(*yrp))
+					{
+						mag = pow(-*xrp,*yrp);
+						theta = PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						*zrp++ = pow(*xrp,*yrp);
+						*zip++ = 0.0;
+						flops++;
+					}
+				}
+				else
+				{
+					mag = pow(*xrp * *xrp + *xip * *xip,0.5 * *yrp);
+					theta = *yrp*atan2(*xip,*xrp);
+					*zrp++ = mag*cos(theta);
+					*zip++ = mag*sin(theta);
+					flops += 18;
+				}
+#elif defined(EQ_MEX)
+				*zrp++ = (*xrp == *yrp) && (*xip == 0.0);
+#elif defined(NE_MEX)
+				*zrp++ = (*xrp != *yrp) || (*xip != 0.0);
+#elif defined(LT_MEX)
+				*zrp++ = (*xrp < *yrp);
+#elif defined(GT_MEX)
+				*zrp++ = (*xrp > *yrp);
+#elif defined(LE_MEX)
+				*zrp++ = (*xrp <= *yrp);
+#elif defined(GE_MEX)
+				*zrp++ = (*xrp >= *yrp);
+#endif
+				for (i = 0; i < ndim; i++)
+				{
+					if (subs[i] == s1[i])
+					{
+						subs[i] = 0;
+						if (sx[i])
+						{
+							xrp -= cpsx2[i];
+							xip -= cpsx2[i];
+						}
+						if (sy[i])
+							yrp -= cpsy2[i];
+					}
+					else
+					{
+						subs[i]++;
+						if (sx[i])
+						{
+							xrp += cpsx[i];
+							xip += cpsx[i];
+						}
+						if (sy[i])
+							yrp += cpsy[i];
+						break;
+					}
+				}
+			}
+#if defined(PLUS_MEX) || defined(MINUS_MEX)
+			mexAddFlops(2*numElements);
+#elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
+			mexAddFlops(6*numElements);
+#elif defined(POWER_MEX)
+			mexAddFlops(flops);
+			removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
+#endif
+		}
+		else if (xcmplx && ycmplx)  /* X and Y both N-D, both complex. */
+		{
+#if defined(RELOP_MEX)
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+			mxSetLogical(zMat);
+			zrp = mxGetPr(zMat);
+#else
+			zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
+			zrp = zr = mxGetPr(zMat);
+			zip = zi = mxGetPi(zMat);
+#endif
+			xrp = mxGetPr(xMat);
+			xip = mxGetPi(xMat);
+			yrp = mxGetPr(yMat);
+			yip = mxGetPi(yMat);
+			zrend = zrp + numElements;
+			while (zrp < zrend)
+			{
+#ifdef PLUS_MEX
+				*zrp++ = *xrp + *yrp;
+				*zip++ = *xip + *yip;
+#elif defined(MINUS_MEX)
+				*zrp++ = *xrp - *yrp;
+				*zip++ = *xip - *yip;
+#elif defined(TIMES_MEX)
+				*zrp++ = *xrp * *yrp - *xip * *yip;
+				*zip++ = *xip * *yrp + *xrp * *yip;
+#elif defined(RDIVIDE_MEX)
+				denom = *yrp * *yrp + *yip * *yip;
+				*zrp++ = (*xrp * *yrp + *xip * *yip)/denom;
+				*zip++ = (*xip * *yrp - *xrp * *yip)/denom;
+#elif defined(LDIVIDE_MEX)
+				denom = *xrp * *xrp + *xip * *xip;
+				*zrp++ = (*xrp * *yrp + *xip * *yip)/denom;
+				*zip++ = (*xrp * *yip - *xip * *yrp)/denom;
+#elif defined(POWER_MEX)
+				if (*xip == 0.0 && *yip == 0.0)
+				{
+					if (*xrp < 0.0 && *yrp != floor(*yrp))
+					{
+						mag = pow(-*xrp,*yrp);
+						theta = PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						*zrp++ = pow(*xrp,*yrp);
+						*zip++ = 0.0;
+						flops++;
+					}
+				}
+				else if (*xip == 0.0)
+				{
+					if (*xrp < 0.0)
+					{
+						mag = pow(-*xrp,*yrp)*exp(-PI * *yip);
+						theta = *yip * log(-*xrp) + PI * *yrp;
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 18;
+					}
+					else
+					{
+						mag = pow(*xrp,*yrp);
+						theta = *yip * log(*xrp);
+						*zrp++ = mag*cos(theta);
+						*zip++ = mag*sin(theta);
+						flops += 13;
+					}
+				}
+				else if (*yip == 0.0)
+				{
+					mag = pow(*xrp * *xrp + *xip * *xip,0.5 * *yrp);
+					theta = *yrp * atan2(*xip,*xrp);
+					*zrp++ = mag*cos(theta);
+					*zip++ = mag*sin(theta);
+					flops += 18;
+				}
+				else
+				{
+					magx = sqrt(*xrp * *xrp + *xip * *xip);
+					phi = atan2(*xip,*xrp);
+					mag = pow(magx,*yrp)*exp(-*yip * phi);
+					theta = *yip * log(magx) + *yrp * phi;
+					*zrp++ = mag*cos(theta);
+					*zip++ = mag*sin(theta);
+					flops += 18;
+				}
+#elif defined(EQ_MEX)
+				*zrp++ = (*xrp == *yrp) && (*xip == *yip);
+#elif defined(NE_MEX)
+				*zrp++ = (*xrp != *yrp) || (*xip != *yip);
+#elif defined(LT_MEX)
+				*zrp++ = (*xrp < *yrp);
+#elif defined(GT_MEX)
+				*zrp++ = (*xrp > *yrp);
+#elif defined(LE_MEX)
+				*zrp++ = (*xrp <= *yrp);
+#elif defined(GE_MEX)
+				*zrp++ = (*xrp >= *yrp);
+#endif
+				for (i = 0; i < ndim; i++)
+				{
+					if (subs[i] == s1[i])
+					{
+						subs[i] = 0;
+						if (sx[i])
+						{
+							xrp -= cpsx2[i];
+							xip -= cpsx2[i];
+						}
+						if (sy[i])
+						{
+							yrp -= cpsy2[i];
+							yip -= cpsy2[i];
+						}
+					}
+					else
+					{
+						subs[i]++;
+						if (sx[i])
+						{
+							xrp += cpsx[i];
+							xip += cpsx[i];
+						}
+						if (sy[i])
+						{
+							yrp += cpsy[i];
+							yip += cpsy[i];
+						}
+						break;
+					}
+				}
+			}
+#if defined(PLUS_MEX) || defined(MINUS_MEX)
+			mexAddFlops(2*numElements);
+#elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
+			mexAddFlops(6*numElements);
+#elif defined(POWER_MEX)
+			mexAddFlops(flops);
+#endif
+#ifndef RELOP_MEX
+			removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
+#endif
+		}
+	}
+}
+
+
+/***********************************************************
+*                                                          *
+*   Tests to see if the vectors xdim and ydim are equal.   *
+*                                                          *
+***********************************************************/
+bool allequal(int ndim, const int *xdim, const int *ydim)
+{
+	int		i;
+	bool	result = true;
+	
+	for (i = 0; i < ndim; i++)
+		result = result && (xdim[i] == ydim[i]);
+	
+	return(result);
+}
+
+
+/******************************************************************************
+*                                                                             *
+*   Tests to see if every imaginary element is identically zero and, if so,   *
+*   creates a new array which is real and copies the real elements to it.     *
+*                                                                             *
+******************************************************************************/
+void removeZeroImag(double *zr, double *zi, int ndim, const int *s,
+					int numElements, mxArray *plhs[])
+{
+	double			*zrend, *ziend, *zip, *z1p, *z2p;
+	bool			allImZero = true;
+	mxArray			*temp;
+	
+	zip = zi;
+	ziend = zi + numElements;
+	while (zip < ziend)
+	{
+		allImZero = allImZero && (*zip++ == 0.0);
+		if (!allImZero)
+			return;
+	}
+	
+	temp = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
+	z1p = zr;
+	z2p = mxGetPr(temp);
+	zrend = z1p + numElements;
+	while (z1p < zrend)
+		*z2p++ = *z1p++;
+	mxDestroyArray(plhs[0]);
+	plhs[0] = temp;
+	return;
+}