/* Copyright (C) 1992 by Thomas Glen Smith. All Rights Reserved. */ /* powerx APL2 V1.0.0 ************************************************* * Power for complex numbers. * ***********************************************************************/ #define INCLUDES MATH+TRIGKEYS #include "includes.h" #define ABS(v) ((v) > 0e0 ? (v) : -(v)) void powerx(left,rite,ret) double *left,*rite,*ret; { Circular; Circulax; Dabsx; Dividex; Mod; Power; Powerx; Timesx; extern int aplerr; extern double fuzz; double absval,n,neg,wrka[2],wrkb[2],wrkc[2]; int i; if (ABS(*(rite+1)) > fuzz) { /* rite complex? */ *wrka = *rite; *(wrka+1) = 0e0; powerx(left,wrka,wrkb); /* wrkb = left * a */ *wrka = circular(COS,*(left+1)); *(wrka+1) = circular(SIN,*(left+1)); /*wrka=cos(b)+iXsin(b)*/ timesx(wrkb,wrka,ret); return; } /* control reaches here only if rite is a real number */ if (*(left+1) <= fuzz && *(left+1) >= fuzz) { /* left real? */ *(ret+1) = 0e0; *ret = power(*left,*rite); return; } else { /* left is complex */ neg = (*rite < 0e0) ? -1.0 : 1.0; absval = neg * *rite; if (mod(absval, 1.0) > fuzz) { /* Is it non-integer power? */ /* a*1%n = magnitude:(|a}*1%n, angle:alpha%n */ n = 1.0 / absval; if (mod(n, 1.0) > fuzz) { /* non-integer n in 1%n? */ aplerr = 996; /* non-integer powers of complex numbers */ return; } dabsx(left,wrka); /* Get magnitude: |a. */ *wrkb = power(*wrka,absval); /* Get (|a)*1%n. */ *(wrkb+1) = atan2(*(left+1),*left) / n; *wrka = *wrkb * cos(*(wrkb+1)); *(wrka + 1) = *wrkb * sin(*(wrkb+1)); } else { /* right is approximate integer */ i = absval; /* absolute integer value of rite */ XFR(wrka,left) /* copy left to wrka */ while(--i) { timesx(wrka,left,wrkb); XFR(wrka,wrkb) /* copy wrkb to wrka */ } } if (neg == -1.0) { *wrkb = 1.0; *(wrkb+1) = 0.0; dividex(wrkb,wrka,ret); } else XFR(ret,wrka); } }