annotate _FullBNT/BNT/potentials/genops.c @ 9:4ea6619cb3f5 tip

removed log files
author matthiasm
date Fri, 11 Apr 2014 15:55:11 +0100
parents b5b38998ef3b
children
rev   line source
matthiasm@8 1 /*
matthiasm@8 2
matthiasm@8 3 GENOPS.C
matthiasm@8 4 Generalized arithmetic operators overloading built-in functions.
matthiasm@8 5
matthiasm@8 6 written by Douglas M. Schwarz
matthiasm@8 7 schwarz@servtech.com
matthiasm@8 8 26 December 1998
matthiasm@8 9 Last modified: 2 April 1999
matthiasm@8 10
matthiasm@8 11 Copyright 1998-1999 by Douglas M. Schwarz. All rights reserved.
matthiasm@8 12
matthiasm@8 13 */
matthiasm@8 14
matthiasm@8 15
matthiasm@8 16 /*
matthiasm@8 17
matthiasm@8 18 Build MEX file by entering the appropriate command at the MATLAB prompt
matthiasm@8 19 (-D<name> option is equivalent to #define <name> in source file):
matthiasm@8 20
matthiasm@8 21 mex genops.c -DPLUS_MEX -output plus
matthiasm@8 22 mex genops.c -DMINUS_MEX -output minus
matthiasm@8 23 mex genops.c -DTIMES_MEX -output times
matthiasm@8 24 mex genops.c -DRDIVIDE_MEX -output rdivide
matthiasm@8 25 mex genops.c -DLDIVIDE_MEX -output ldivide
matthiasm@8 26 mex genops.c -DPOWER_MEX -output power
matthiasm@8 27 mex genops.c -DEQ_MEX -output eq
matthiasm@8 28 mex genops.c -DNE_MEX -output ne
matthiasm@8 29 mex genops.c -DLT_MEX -output lt
matthiasm@8 30 mex genops.c -DGT_MEX -output gt
matthiasm@8 31 mex genops.c -DLE_MEX -output le
matthiasm@8 32 mex genops.c -DGE_MEX -output ge
matthiasm@8 33
matthiasm@8 34 */
matthiasm@8 35
matthiasm@8 36 /* This file has been formatted for a tab equal to 4 spaces. */
matthiasm@8 37
matthiasm@8 38 #if defined(EQ_MEX) || defined(NE_MEX) || defined(LT_MEX) || defined(GT_MEX) \
matthiasm@8 39 || defined(LE_MEX) || defined(GE_MEX)
matthiasm@8 40 #define RELOP_MEX
matthiasm@8 41 #endif
matthiasm@8 42
matthiasm@8 43 #include "mex.h"
matthiasm@8 44 #include "matrix.h"
matthiasm@8 45 #ifdef POWER_MEX
matthiasm@8 46 #include <math.h>
matthiasm@8 47 #define PI 3.141592653589793
matthiasm@8 48 #endif
matthiasm@8 49
matthiasm@8 50 bool allequal(int, const int *, const int *);
matthiasm@8 51 void removeZeroImag(double *, double *, int, const int *, int, mxArray **);
matthiasm@8 52
matthiasm@8 53 #define xMat prhs[0]
matthiasm@8 54 #define yMat prhs[1]
matthiasm@8 55 #define zMat plhs[0]
matthiasm@8 56
matthiasm@8 57 #define min(A,B) ((A) < (B) ? (A) : (B))
matthiasm@8 58 #define max(A,B) ((A) > (B) ? (A) : (B))
matthiasm@8 59
matthiasm@8 60 void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
matthiasm@8 61 {
matthiasm@8 62 double *xrp, *xip, *yrp, *yip;
matthiasm@8 63 #ifndef RELOP_MEX
matthiasm@8 64 double *zr, *zi, *zip;
matthiasm@8 65 #endif
matthiasm@8 66 double *zrp, *zrend;
matthiasm@8 67 int xnd, ynd, numElements = 1;
matthiasm@8 68 const int *xdim, *ydim;
matthiasm@8 69 bool xcmplx, ycmplx;
matthiasm@8 70 mxClassID yclass;
matthiasm@8 71 int *s, ndim, *sx, *sy, i, *cpsx, *cpsy;
matthiasm@8 72 int *subs, *s1, *cpsx2, *cpsy2;
matthiasm@8 73 int ix = 0, iy = 0;
matthiasm@8 74 mxArray *args[3], *result[1];
matthiasm@8 75 #if defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
matthiasm@8 76 double denom;
matthiasm@8 77 #endif
matthiasm@8 78 #ifdef POWER_MEX
matthiasm@8 79 double mag, theta, phi, magx;
matthiasm@8 80 int flops = 0;
matthiasm@8 81 #endif
matthiasm@8 82
matthiasm@8 83
matthiasm@8 84 if (nrhs != 2)
matthiasm@8 85 mexErrMsgTxt("Incorrect number of inputs.");
matthiasm@8 86
matthiasm@8 87 if (nlhs > 1)
matthiasm@8 88 mexErrMsgTxt("Too many output arguments.");
matthiasm@8 89
matthiasm@8 90 xnd = mxGetNumberOfDimensions(xMat);
matthiasm@8 91 ynd = mxGetNumberOfDimensions(yMat);
matthiasm@8 92 xdim = mxGetDimensions(xMat);
matthiasm@8 93 ydim = mxGetDimensions(yMat);
matthiasm@8 94
matthiasm@8 95 yclass = mxGetClassID(yMat);
matthiasm@8 96
matthiasm@8 97 /* If the built-in function in MATLAB can handle the arguments
matthiasm@8 98 then use that. */
matthiasm@8 99 if (yclass != mxDOUBLE_CLASS ||
matthiasm@8 100 (xnd == 2 && xdim[0] == 1 && xdim[1] == 1) ||
matthiasm@8 101 (ynd == 2 && ydim[0] == 1 && ydim[1] == 1) ||
matthiasm@8 102 (xnd == ynd && allequal(xnd,xdim,ydim)))
matthiasm@8 103 {
matthiasm@8 104 #ifdef PLUS_MEX
matthiasm@8 105 args[0] = mxCreateString("plus");
matthiasm@8 106 #elif defined(MINUS_MEX)
matthiasm@8 107 args[0] = mxCreateString("minus");
matthiasm@8 108 #elif defined(TIMES_MEX)
matthiasm@8 109 args[0] = mxCreateString("times");
matthiasm@8 110 #elif defined(RDIVIDE_MEX)
matthiasm@8 111 args[0] = mxCreateString("rdivide");
matthiasm@8 112 #elif defined(LDIVIDE_MEX)
matthiasm@8 113 args[0] = mxCreateString("ldivide");
matthiasm@8 114 #elif defined(POWER_MEX)
matthiasm@8 115 args[0] = mxCreateString("power");
matthiasm@8 116 #elif defined(EQ_MEX)
matthiasm@8 117 args[0] = mxCreateString("eq");
matthiasm@8 118 #elif defined(NE_MEX)
matthiasm@8 119 args[0] = mxCreateString("ne");
matthiasm@8 120 #elif defined(LT_MEX)
matthiasm@8 121 args[0] = mxCreateString("lt");
matthiasm@8 122 #elif defined(GT_MEX)
matthiasm@8 123 args[0] = mxCreateString("gt");
matthiasm@8 124 #elif defined(LE_MEX)
matthiasm@8 125 args[0] = mxCreateString("le");
matthiasm@8 126 #elif defined(GE_MEX)
matthiasm@8 127 args[0] = mxCreateString("ge");
matthiasm@8 128 #endif
matthiasm@8 129 args[1] = (mxArray *)xMat;
matthiasm@8 130 args[2] = (mxArray *)yMat;
matthiasm@8 131 mexCallMATLAB(1, result, 3, args, "builtin");
matthiasm@8 132 mxDestroyArray(args[0]);
matthiasm@8 133 zMat = result[0];
matthiasm@8 134 }
matthiasm@8 135 else /* X and Y are both N-D and different dimensionality. */
matthiasm@8 136 {
matthiasm@8 137 ndim = max(xnd,ynd);
matthiasm@8 138 sx = (int *)mxMalloc(sizeof(int)*ndim);
matthiasm@8 139 sy = (int *)mxMalloc(sizeof(int)*ndim);
matthiasm@8 140 s = (int *)mxMalloc(sizeof(int)*ndim);
matthiasm@8 141 s1 = (int *)mxMalloc(sizeof(int)*ndim);
matthiasm@8 142 *(cpsx = (int *)mxMalloc(sizeof(int)*ndim)) = 1;
matthiasm@8 143 *(cpsy = (int *)mxMalloc(sizeof(int)*ndim)) = 1;
matthiasm@8 144 subs = (int *)mxMalloc(sizeof(int)*ndim);
matthiasm@8 145 cpsx2 = (int *)mxMalloc(sizeof(int)*ndim);
matthiasm@8 146 cpsy2 = (int *)mxMalloc(sizeof(int)*ndim);
matthiasm@8 147 for (i = 0; i < ndim; i++)
matthiasm@8 148 {
matthiasm@8 149 subs[i] = 0;
matthiasm@8 150 sx[i] = (i < xnd) ? xdim[i] : 1;
matthiasm@8 151 sy[i] = (i < ynd) ? ydim[i] : 1;
matthiasm@8 152 if (sx[i] == sy[i])
matthiasm@8 153 s[i] = sx[i];
matthiasm@8 154 else if (sx[i] == 1)
matthiasm@8 155 s[i] = sy[i];
matthiasm@8 156 else if (sy[i] == 1)
matthiasm@8 157 s[i] = sx[i];
matthiasm@8 158 else
matthiasm@8 159 {
matthiasm@8 160 mxFree(sx);
matthiasm@8 161 mxFree(sy);
matthiasm@8 162 mxFree(s);
matthiasm@8 163 mxFree(s1);
matthiasm@8 164 mxFree(cpsx);
matthiasm@8 165 mxFree(cpsy);
matthiasm@8 166 mxFree(subs);
matthiasm@8 167 mxFree(cpsx2);
matthiasm@8 168 mxFree(cpsy2);
matthiasm@8 169 mexErrMsgTxt("Array dimensions are not appropriate.");
matthiasm@8 170 }
matthiasm@8 171 s1[i] = s[i] - 1;
matthiasm@8 172 numElements *= s[i];
matthiasm@8 173 }
matthiasm@8 174
matthiasm@8 175 for (i = 0; i < ndim-1; i++)
matthiasm@8 176 {
matthiasm@8 177 cpsx[i+1] = cpsx[i]*sx[i]--;
matthiasm@8 178 cpsy[i+1] = cpsy[i]*sy[i]--;
matthiasm@8 179 cpsx2[i] = cpsx[i]*sx[i];
matthiasm@8 180 cpsy2[i] = cpsy[i]*sy[i];
matthiasm@8 181 }
matthiasm@8 182 cpsx2[ndim-1] = cpsx[ndim-1]*(--sx[ndim-1]);
matthiasm@8 183 cpsy2[ndim-1] = cpsy[ndim-1]*(--sy[ndim-1]);
matthiasm@8 184
matthiasm@8 185 xcmplx = mxIsComplex(xMat);
matthiasm@8 186 ycmplx = mxIsComplex(yMat);
matthiasm@8 187
matthiasm@8 188 if (!xcmplx && !ycmplx) /* X and Y both N-D, both real. */
matthiasm@8 189 {
matthiasm@8 190 #ifdef POWER_MEX
matthiasm@8 191 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
matthiasm@8 192 zrp = zr = mxGetPr(zMat);
matthiasm@8 193 zip = zi = mxGetPi(zMat);
matthiasm@8 194 #elif defined(RELOP_MEX)
matthiasm@8 195 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
matthiasm@8 196 mxSetLogical(zMat);
matthiasm@8 197 zrp = mxGetPr(zMat);
matthiasm@8 198 #else
matthiasm@8 199 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
matthiasm@8 200 zrp = mxGetPr(zMat);
matthiasm@8 201 #endif
matthiasm@8 202 xrp = mxGetPr(xMat);
matthiasm@8 203 yrp = mxGetPr(yMat);
matthiasm@8 204 zrend = zrp + numElements;
matthiasm@8 205 while (zrp < zrend)
matthiasm@8 206 {
matthiasm@8 207 #ifdef PLUS_MEX
matthiasm@8 208 *zrp++ = *xrp + *yrp;
matthiasm@8 209 #elif defined(MINUS_MEX)
matthiasm@8 210 *zrp++ = *xrp - *yrp;
matthiasm@8 211 #elif defined(TIMES_MEX)
matthiasm@8 212 *zrp++ = *xrp * *yrp;
matthiasm@8 213 #elif defined(RDIVIDE_MEX)
matthiasm@8 214 *zrp++ = *xrp / *yrp;
matthiasm@8 215 #elif defined(LDIVIDE_MEX)
matthiasm@8 216 *zrp++ = *yrp / *xrp;
matthiasm@8 217 #elif defined(POWER_MEX)
matthiasm@8 218 if (*xrp < 0.0 && *yrp != floor(*yrp))
matthiasm@8 219 {
matthiasm@8 220 mag = pow(-*xrp,*yrp);
matthiasm@8 221 theta = PI * *yrp;
matthiasm@8 222 *zrp++ = mag*cos(theta);
matthiasm@8 223 *zip++ = mag*sin(theta);
matthiasm@8 224 flops += 18;
matthiasm@8 225 }
matthiasm@8 226 else
matthiasm@8 227 {
matthiasm@8 228 *zrp++ = pow(*xrp,*yrp);
matthiasm@8 229 *zip++ = 0.0;
matthiasm@8 230 flops++;
matthiasm@8 231 }
matthiasm@8 232 #elif defined(EQ_MEX)
matthiasm@8 233 *zrp++ = (*xrp == *yrp);
matthiasm@8 234 #elif defined(NE_MEX)
matthiasm@8 235 *zrp++ = (*xrp != *yrp);
matthiasm@8 236 #elif defined(LT_MEX)
matthiasm@8 237 *zrp++ = (*xrp < *yrp);
matthiasm@8 238 #elif defined(GT_MEX)
matthiasm@8 239 *zrp++ = (*xrp > *yrp);
matthiasm@8 240 #elif defined(LE_MEX)
matthiasm@8 241 *zrp++ = (*xrp <= *yrp);
matthiasm@8 242 #elif defined(GE_MEX)
matthiasm@8 243 *zrp++ = (*xrp >= *yrp);
matthiasm@8 244 #endif
matthiasm@8 245 for (i = 0; i < ndim; i++)
matthiasm@8 246 {
matthiasm@8 247 if (subs[i] == s1[i])
matthiasm@8 248 {
matthiasm@8 249 subs[i] = 0;
matthiasm@8 250 if (sx[i])
matthiasm@8 251 xrp -= cpsx2[i];
matthiasm@8 252 if (sy[i])
matthiasm@8 253 yrp -= cpsy2[i];
matthiasm@8 254 }
matthiasm@8 255 else
matthiasm@8 256 {
matthiasm@8 257 subs[i]++;
matthiasm@8 258 if (sx[i])
matthiasm@8 259 xrp += cpsx[i];
matthiasm@8 260 if (sy[i])
matthiasm@8 261 yrp += cpsy[i];
matthiasm@8 262 break;
matthiasm@8 263 }
matthiasm@8 264 }
matthiasm@8 265 }
matthiasm@8 266 #ifdef POWER_MEX
matthiasm@8 267 mexAddFlops(flops);
matthiasm@8 268 removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
matthiasm@8 269 #elif !defined(RELOP_MEX)
matthiasm@8 270 mexAddFlops(numElements);
matthiasm@8 271 #endif
matthiasm@8 272 }
matthiasm@8 273 else if (!xcmplx && ycmplx) /* X and Y both N-D, X real, Y complex. */
matthiasm@8 274 {
matthiasm@8 275 #ifdef POWER_MEX
matthiasm@8 276 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
matthiasm@8 277 zrp = zr = mxGetPr(zMat);
matthiasm@8 278 zip = zi = mxGetPi(zMat);
matthiasm@8 279 #elif defined(RELOP_MEX)
matthiasm@8 280 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
matthiasm@8 281 mxSetLogical(zMat);
matthiasm@8 282 zrp = mxGetPr(zMat);
matthiasm@8 283 #else
matthiasm@8 284 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
matthiasm@8 285 zrp = mxGetPr(zMat);
matthiasm@8 286 zip = mxGetPi(zMat);
matthiasm@8 287 #endif
matthiasm@8 288 xrp = mxGetPr(xMat);
matthiasm@8 289 yrp = mxGetPr(yMat);
matthiasm@8 290 yip = mxGetPi(yMat);
matthiasm@8 291 zrend = zrp + numElements;
matthiasm@8 292 while (zrp < zrend)
matthiasm@8 293 {
matthiasm@8 294 #ifdef PLUS_MEX
matthiasm@8 295 *zrp++ = *xrp + *yrp;
matthiasm@8 296 *zip++ = *yip;
matthiasm@8 297 #elif defined(MINUS_MEX)
matthiasm@8 298 *zrp++ = *xrp - *yrp;
matthiasm@8 299 *zip++ = -*yip;
matthiasm@8 300 #elif defined(TIMES_MEX)
matthiasm@8 301 *zrp++ = *xrp * *yrp;
matthiasm@8 302 *zip++ = *xrp * *yip;
matthiasm@8 303 #elif defined(RDIVIDE_MEX)
matthiasm@8 304 denom = *yrp * *yrp + *yip * *yip;
matthiasm@8 305 *zrp++ = (*xrp * *yrp)/denom;
matthiasm@8 306 *zip++ = (-*xrp * *yip)/denom;
matthiasm@8 307 #elif defined(LDIVIDE_MEX)
matthiasm@8 308 *zrp++ = *yrp / *xrp;
matthiasm@8 309 *zip++ = *yip / *xrp;
matthiasm@8 310 #elif defined(POWER_MEX)
matthiasm@8 311 if (*yip == 0.0)
matthiasm@8 312 {
matthiasm@8 313 if (*xrp < 0.0 && *yrp != floor(*yrp))
matthiasm@8 314 {
matthiasm@8 315 mag = pow(-*xrp,*yrp);
matthiasm@8 316 theta = PI * *yrp;
matthiasm@8 317 *zrp++ = mag*cos(theta);
matthiasm@8 318 *zip++ = mag*sin(theta);
matthiasm@8 319 flops += 18;
matthiasm@8 320 }
matthiasm@8 321 else
matthiasm@8 322 {
matthiasm@8 323 *zrp++ = pow(*xrp,*yrp);
matthiasm@8 324 *zip++ = 0.0;
matthiasm@8 325 flops++;
matthiasm@8 326 }
matthiasm@8 327 }
matthiasm@8 328 else
matthiasm@8 329 {
matthiasm@8 330 if (*xrp < 0.0)
matthiasm@8 331 {
matthiasm@8 332 mag = pow(-*xrp,*yrp)*exp(-PI * *yip);
matthiasm@8 333 theta = *yip * log(-*xrp) + PI * *yrp;
matthiasm@8 334 *zrp++ = mag*cos(theta);
matthiasm@8 335 *zip++ = mag*sin(theta);
matthiasm@8 336 flops += 18;
matthiasm@8 337 }
matthiasm@8 338 else
matthiasm@8 339 {
matthiasm@8 340 mag = pow(*xrp,*yrp);
matthiasm@8 341 theta = *yip * log(*xrp);
matthiasm@8 342 *zrp++ = mag*cos(theta);
matthiasm@8 343 *zip++ = mag*sin(theta);
matthiasm@8 344 flops += 13;
matthiasm@8 345 }
matthiasm@8 346 }
matthiasm@8 347 #elif defined(EQ_MEX)
matthiasm@8 348 *zrp++ = (*xrp == *yrp) && (*yip == 0.0);
matthiasm@8 349 #elif defined(NE_MEX)
matthiasm@8 350 *zrp++ = (*xrp != *yrp) || (*yip != 0.0);
matthiasm@8 351 #elif defined(LT_MEX)
matthiasm@8 352 *zrp++ = (*xrp < *yrp);
matthiasm@8 353 #elif defined(GT_MEX)
matthiasm@8 354 *zrp++ = (*xrp > *yrp);
matthiasm@8 355 #elif defined(LE_MEX)
matthiasm@8 356 *zrp++ = (*xrp <= *yrp);
matthiasm@8 357 #elif defined(GE_MEX)
matthiasm@8 358 *zrp++ = (*xrp >= *yrp);
matthiasm@8 359 #endif
matthiasm@8 360 for (i = 0; i < ndim; i++)
matthiasm@8 361 {
matthiasm@8 362 if (subs[i] == s1[i])
matthiasm@8 363 {
matthiasm@8 364 subs[i] = 0;
matthiasm@8 365 if (sx[i])
matthiasm@8 366 xrp -= cpsx2[i];
matthiasm@8 367 if (sy[i])
matthiasm@8 368 {
matthiasm@8 369 yrp -= cpsy2[i];
matthiasm@8 370 yip -= cpsy2[i];
matthiasm@8 371 }
matthiasm@8 372 }
matthiasm@8 373 else
matthiasm@8 374 {
matthiasm@8 375 subs[i]++;
matthiasm@8 376 if (sx[i])
matthiasm@8 377 xrp += cpsx[i];
matthiasm@8 378 if (sy[i])
matthiasm@8 379 {
matthiasm@8 380 yrp += cpsy[i];
matthiasm@8 381 yip += cpsy[i];
matthiasm@8 382 }
matthiasm@8 383 break;
matthiasm@8 384 }
matthiasm@8 385 }
matthiasm@8 386 }
matthiasm@8 387 #if defined(PLUS_MEX) || defined(MINUS_MEX)
matthiasm@8 388 mexAddFlops(2*numElements);
matthiasm@8 389 #elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
matthiasm@8 390 mexAddFlops(6*numElements);
matthiasm@8 391 #elif defined(POWER_MEX)
matthiasm@8 392 mexAddFlops(flops);
matthiasm@8 393 removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
matthiasm@8 394 #endif
matthiasm@8 395 }
matthiasm@8 396 else if (xcmplx && !ycmplx) /* X and Y both N-D, X complex, Y real. */
matthiasm@8 397 {
matthiasm@8 398 #ifdef POWER_MEX
matthiasm@8 399 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
matthiasm@8 400 zrp = zr = mxGetPr(zMat);
matthiasm@8 401 zip = zi = mxGetPi(zMat);
matthiasm@8 402 #elif defined(RELOP_MEX)
matthiasm@8 403 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
matthiasm@8 404 mxSetLogical(zMat);
matthiasm@8 405 zrp = mxGetPr(zMat);
matthiasm@8 406 #else
matthiasm@8 407 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
matthiasm@8 408 zrp = mxGetPr(zMat);
matthiasm@8 409 zip = mxGetPi(zMat);
matthiasm@8 410 #endif
matthiasm@8 411 xrp = mxGetPr(xMat);
matthiasm@8 412 xip = mxGetPi(xMat);
matthiasm@8 413 yrp = mxGetPr(yMat);
matthiasm@8 414 zrend = zrp + numElements;
matthiasm@8 415 while (zrp < zrend)
matthiasm@8 416 {
matthiasm@8 417 #ifdef PLUS_MEX
matthiasm@8 418 *zrp++ = *xrp + *yrp;
matthiasm@8 419 *zip++ = *xip;
matthiasm@8 420 #elif defined(MINUS_MEX)
matthiasm@8 421 *zrp++ = *xrp - *yrp;
matthiasm@8 422 *zip++ = *xip;
matthiasm@8 423 #elif defined(TIMES_MEX)
matthiasm@8 424 *zrp++ = *xrp * *yrp;
matthiasm@8 425 *zip++ = *xip * *yrp;
matthiasm@8 426 #elif defined(RDIVIDE_MEX)
matthiasm@8 427 *zrp++ = *xrp / *yrp;
matthiasm@8 428 *zip++ = *xip / *yrp;
matthiasm@8 429 #elif defined(LDIVIDE_MEX)
matthiasm@8 430 denom = *xrp * *xrp + *xip * *xip;
matthiasm@8 431 *zrp++ = (*xrp * *yrp)/denom;
matthiasm@8 432 *zip++ = (-*xip * *yrp)/denom;
matthiasm@8 433 #elif defined(POWER_MEX)
matthiasm@8 434 if (*xip == 0.0)
matthiasm@8 435 {
matthiasm@8 436 if (*xrp < 0.0 && *yrp != floor(*yrp))
matthiasm@8 437 {
matthiasm@8 438 mag = pow(-*xrp,*yrp);
matthiasm@8 439 theta = PI * *yrp;
matthiasm@8 440 *zrp++ = mag*cos(theta);
matthiasm@8 441 *zip++ = mag*sin(theta);
matthiasm@8 442 flops += 18;
matthiasm@8 443 }
matthiasm@8 444 else
matthiasm@8 445 {
matthiasm@8 446 *zrp++ = pow(*xrp,*yrp);
matthiasm@8 447 *zip++ = 0.0;
matthiasm@8 448 flops++;
matthiasm@8 449 }
matthiasm@8 450 }
matthiasm@8 451 else
matthiasm@8 452 {
matthiasm@8 453 mag = pow(*xrp * *xrp + *xip * *xip,0.5 * *yrp);
matthiasm@8 454 theta = *yrp*atan2(*xip,*xrp);
matthiasm@8 455 *zrp++ = mag*cos(theta);
matthiasm@8 456 *zip++ = mag*sin(theta);
matthiasm@8 457 flops += 18;
matthiasm@8 458 }
matthiasm@8 459 #elif defined(EQ_MEX)
matthiasm@8 460 *zrp++ = (*xrp == *yrp) && (*xip == 0.0);
matthiasm@8 461 #elif defined(NE_MEX)
matthiasm@8 462 *zrp++ = (*xrp != *yrp) || (*xip != 0.0);
matthiasm@8 463 #elif defined(LT_MEX)
matthiasm@8 464 *zrp++ = (*xrp < *yrp);
matthiasm@8 465 #elif defined(GT_MEX)
matthiasm@8 466 *zrp++ = (*xrp > *yrp);
matthiasm@8 467 #elif defined(LE_MEX)
matthiasm@8 468 *zrp++ = (*xrp <= *yrp);
matthiasm@8 469 #elif defined(GE_MEX)
matthiasm@8 470 *zrp++ = (*xrp >= *yrp);
matthiasm@8 471 #endif
matthiasm@8 472 for (i = 0; i < ndim; i++)
matthiasm@8 473 {
matthiasm@8 474 if (subs[i] == s1[i])
matthiasm@8 475 {
matthiasm@8 476 subs[i] = 0;
matthiasm@8 477 if (sx[i])
matthiasm@8 478 {
matthiasm@8 479 xrp -= cpsx2[i];
matthiasm@8 480 xip -= cpsx2[i];
matthiasm@8 481 }
matthiasm@8 482 if (sy[i])
matthiasm@8 483 yrp -= cpsy2[i];
matthiasm@8 484 }
matthiasm@8 485 else
matthiasm@8 486 {
matthiasm@8 487 subs[i]++;
matthiasm@8 488 if (sx[i])
matthiasm@8 489 {
matthiasm@8 490 xrp += cpsx[i];
matthiasm@8 491 xip += cpsx[i];
matthiasm@8 492 }
matthiasm@8 493 if (sy[i])
matthiasm@8 494 yrp += cpsy[i];
matthiasm@8 495 break;
matthiasm@8 496 }
matthiasm@8 497 }
matthiasm@8 498 }
matthiasm@8 499 #if defined(PLUS_MEX) || defined(MINUS_MEX)
matthiasm@8 500 mexAddFlops(2*numElements);
matthiasm@8 501 #elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
matthiasm@8 502 mexAddFlops(6*numElements);
matthiasm@8 503 #elif defined(POWER_MEX)
matthiasm@8 504 mexAddFlops(flops);
matthiasm@8 505 removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
matthiasm@8 506 #endif
matthiasm@8 507 }
matthiasm@8 508 else if (xcmplx && ycmplx) /* X and Y both N-D, both complex. */
matthiasm@8 509 {
matthiasm@8 510 #if defined(RELOP_MEX)
matthiasm@8 511 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
matthiasm@8 512 mxSetLogical(zMat);
matthiasm@8 513 zrp = mxGetPr(zMat);
matthiasm@8 514 #else
matthiasm@8 515 zMat = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxCOMPLEX);
matthiasm@8 516 zrp = zr = mxGetPr(zMat);
matthiasm@8 517 zip = zi = mxGetPi(zMat);
matthiasm@8 518 #endif
matthiasm@8 519 xrp = mxGetPr(xMat);
matthiasm@8 520 xip = mxGetPi(xMat);
matthiasm@8 521 yrp = mxGetPr(yMat);
matthiasm@8 522 yip = mxGetPi(yMat);
matthiasm@8 523 zrend = zrp + numElements;
matthiasm@8 524 while (zrp < zrend)
matthiasm@8 525 {
matthiasm@8 526 #ifdef PLUS_MEX
matthiasm@8 527 *zrp++ = *xrp + *yrp;
matthiasm@8 528 *zip++ = *xip + *yip;
matthiasm@8 529 #elif defined(MINUS_MEX)
matthiasm@8 530 *zrp++ = *xrp - *yrp;
matthiasm@8 531 *zip++ = *xip - *yip;
matthiasm@8 532 #elif defined(TIMES_MEX)
matthiasm@8 533 *zrp++ = *xrp * *yrp - *xip * *yip;
matthiasm@8 534 *zip++ = *xip * *yrp + *xrp * *yip;
matthiasm@8 535 #elif defined(RDIVIDE_MEX)
matthiasm@8 536 denom = *yrp * *yrp + *yip * *yip;
matthiasm@8 537 *zrp++ = (*xrp * *yrp + *xip * *yip)/denom;
matthiasm@8 538 *zip++ = (*xip * *yrp - *xrp * *yip)/denom;
matthiasm@8 539 #elif defined(LDIVIDE_MEX)
matthiasm@8 540 denom = *xrp * *xrp + *xip * *xip;
matthiasm@8 541 *zrp++ = (*xrp * *yrp + *xip * *yip)/denom;
matthiasm@8 542 *zip++ = (*xrp * *yip - *xip * *yrp)/denom;
matthiasm@8 543 #elif defined(POWER_MEX)
matthiasm@8 544 if (*xip == 0.0 && *yip == 0.0)
matthiasm@8 545 {
matthiasm@8 546 if (*xrp < 0.0 && *yrp != floor(*yrp))
matthiasm@8 547 {
matthiasm@8 548 mag = pow(-*xrp,*yrp);
matthiasm@8 549 theta = PI * *yrp;
matthiasm@8 550 *zrp++ = mag*cos(theta);
matthiasm@8 551 *zip++ = mag*sin(theta);
matthiasm@8 552 flops += 18;
matthiasm@8 553 }
matthiasm@8 554 else
matthiasm@8 555 {
matthiasm@8 556 *zrp++ = pow(*xrp,*yrp);
matthiasm@8 557 *zip++ = 0.0;
matthiasm@8 558 flops++;
matthiasm@8 559 }
matthiasm@8 560 }
matthiasm@8 561 else if (*xip == 0.0)
matthiasm@8 562 {
matthiasm@8 563 if (*xrp < 0.0)
matthiasm@8 564 {
matthiasm@8 565 mag = pow(-*xrp,*yrp)*exp(-PI * *yip);
matthiasm@8 566 theta = *yip * log(-*xrp) + PI * *yrp;
matthiasm@8 567 *zrp++ = mag*cos(theta);
matthiasm@8 568 *zip++ = mag*sin(theta);
matthiasm@8 569 flops += 18;
matthiasm@8 570 }
matthiasm@8 571 else
matthiasm@8 572 {
matthiasm@8 573 mag = pow(*xrp,*yrp);
matthiasm@8 574 theta = *yip * log(*xrp);
matthiasm@8 575 *zrp++ = mag*cos(theta);
matthiasm@8 576 *zip++ = mag*sin(theta);
matthiasm@8 577 flops += 13;
matthiasm@8 578 }
matthiasm@8 579 }
matthiasm@8 580 else if (*yip == 0.0)
matthiasm@8 581 {
matthiasm@8 582 mag = pow(*xrp * *xrp + *xip * *xip,0.5 * *yrp);
matthiasm@8 583 theta = *yrp * atan2(*xip,*xrp);
matthiasm@8 584 *zrp++ = mag*cos(theta);
matthiasm@8 585 *zip++ = mag*sin(theta);
matthiasm@8 586 flops += 18;
matthiasm@8 587 }
matthiasm@8 588 else
matthiasm@8 589 {
matthiasm@8 590 magx = sqrt(*xrp * *xrp + *xip * *xip);
matthiasm@8 591 phi = atan2(*xip,*xrp);
matthiasm@8 592 mag = pow(magx,*yrp)*exp(-*yip * phi);
matthiasm@8 593 theta = *yip * log(magx) + *yrp * phi;
matthiasm@8 594 *zrp++ = mag*cos(theta);
matthiasm@8 595 *zip++ = mag*sin(theta);
matthiasm@8 596 flops += 18;
matthiasm@8 597 }
matthiasm@8 598 #elif defined(EQ_MEX)
matthiasm@8 599 *zrp++ = (*xrp == *yrp) && (*xip == *yip);
matthiasm@8 600 #elif defined(NE_MEX)
matthiasm@8 601 *zrp++ = (*xrp != *yrp) || (*xip != *yip);
matthiasm@8 602 #elif defined(LT_MEX)
matthiasm@8 603 *zrp++ = (*xrp < *yrp);
matthiasm@8 604 #elif defined(GT_MEX)
matthiasm@8 605 *zrp++ = (*xrp > *yrp);
matthiasm@8 606 #elif defined(LE_MEX)
matthiasm@8 607 *zrp++ = (*xrp <= *yrp);
matthiasm@8 608 #elif defined(GE_MEX)
matthiasm@8 609 *zrp++ = (*xrp >= *yrp);
matthiasm@8 610 #endif
matthiasm@8 611 for (i = 0; i < ndim; i++)
matthiasm@8 612 {
matthiasm@8 613 if (subs[i] == s1[i])
matthiasm@8 614 {
matthiasm@8 615 subs[i] = 0;
matthiasm@8 616 if (sx[i])
matthiasm@8 617 {
matthiasm@8 618 xrp -= cpsx2[i];
matthiasm@8 619 xip -= cpsx2[i];
matthiasm@8 620 }
matthiasm@8 621 if (sy[i])
matthiasm@8 622 {
matthiasm@8 623 yrp -= cpsy2[i];
matthiasm@8 624 yip -= cpsy2[i];
matthiasm@8 625 }
matthiasm@8 626 }
matthiasm@8 627 else
matthiasm@8 628 {
matthiasm@8 629 subs[i]++;
matthiasm@8 630 if (sx[i])
matthiasm@8 631 {
matthiasm@8 632 xrp += cpsx[i];
matthiasm@8 633 xip += cpsx[i];
matthiasm@8 634 }
matthiasm@8 635 if (sy[i])
matthiasm@8 636 {
matthiasm@8 637 yrp += cpsy[i];
matthiasm@8 638 yip += cpsy[i];
matthiasm@8 639 }
matthiasm@8 640 break;
matthiasm@8 641 }
matthiasm@8 642 }
matthiasm@8 643 }
matthiasm@8 644 #if defined(PLUS_MEX) || defined(MINUS_MEX)
matthiasm@8 645 mexAddFlops(2*numElements);
matthiasm@8 646 #elif defined(TIMES_MEX) || defined(RDIVIDE_MEX) || defined(LDIVIDE_MEX)
matthiasm@8 647 mexAddFlops(6*numElements);
matthiasm@8 648 #elif defined(POWER_MEX)
matthiasm@8 649 mexAddFlops(flops);
matthiasm@8 650 #endif
matthiasm@8 651 #ifndef RELOP_MEX
matthiasm@8 652 removeZeroImag(zr, zi, ndim, (const int *)s, numElements, &zMat);
matthiasm@8 653 #endif
matthiasm@8 654 }
matthiasm@8 655 }
matthiasm@8 656 }
matthiasm@8 657
matthiasm@8 658
matthiasm@8 659 /***********************************************************
matthiasm@8 660 * *
matthiasm@8 661 * Tests to see if the vectors xdim and ydim are equal. *
matthiasm@8 662 * *
matthiasm@8 663 ***********************************************************/
matthiasm@8 664 bool allequal(int ndim, const int *xdim, const int *ydim)
matthiasm@8 665 {
matthiasm@8 666 int i;
matthiasm@8 667 bool result = true;
matthiasm@8 668
matthiasm@8 669 for (i = 0; i < ndim; i++)
matthiasm@8 670 result = result && (xdim[i] == ydim[i]);
matthiasm@8 671
matthiasm@8 672 return(result);
matthiasm@8 673 }
matthiasm@8 674
matthiasm@8 675
matthiasm@8 676 /******************************************************************************
matthiasm@8 677 * *
matthiasm@8 678 * Tests to see if every imaginary element is identically zero and, if so, *
matthiasm@8 679 * creates a new array which is real and copies the real elements to it. *
matthiasm@8 680 * *
matthiasm@8 681 ******************************************************************************/
matthiasm@8 682 void removeZeroImag(double *zr, double *zi, int ndim, const int *s,
matthiasm@8 683 int numElements, mxArray *plhs[])
matthiasm@8 684 {
matthiasm@8 685 double *zrend, *ziend, *zip, *z1p, *z2p;
matthiasm@8 686 bool allImZero = true;
matthiasm@8 687 mxArray *temp;
matthiasm@8 688
matthiasm@8 689 zip = zi;
matthiasm@8 690 ziend = zi + numElements;
matthiasm@8 691 while (zip < ziend)
matthiasm@8 692 {
matthiasm@8 693 allImZero = allImZero && (*zip++ == 0.0);
matthiasm@8 694 if (!allImZero)
matthiasm@8 695 return;
matthiasm@8 696 }
matthiasm@8 697
matthiasm@8 698 temp = mxCreateNumericArray(ndim, s, mxDOUBLE_CLASS, mxREAL);
matthiasm@8 699 z1p = zr;
matthiasm@8 700 z2p = mxGetPr(temp);
matthiasm@8 701 zrend = z1p + numElements;
matthiasm@8 702 while (z1p < zrend)
matthiasm@8 703 *z2p++ = *z1p++;
matthiasm@8 704 mxDestroyArray(plhs[0]);
matthiasm@8 705 plhs[0] = temp;
matthiasm@8 706 return;
matthiasm@8 707 }