comparison toolboxes/FullBNT-1.0.7/bnt/potentials/genops.c @ 0:e9a9cd732c1e tip

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