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