annotate toolboxes/FullBNT-1.0.7/bnt/potentials/genops.c @ 0:cc4b1211e677 tip

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