File: common\hcmplx.c

    1 /* some hyper complex functions */
    2   /* see Fractint.c for a description of the "include"  hierarchy */
    3 #include "port.h"
    4 #include "prototyp.h"
    5 
    6 void HComplexMult(_HCMPLX *arg1, _HCMPLX *arg2, _HCMPLX *out)
    7 {
    8     /* it is possible to reoganize this code and reduce the multiplies
    9         from 16 to 10, but on my 486 it is SLOWER !!! so I left it
   10         like this - Tim Wegner */
   11     out->x = arg1->x * arg2->x - arg1->y * arg2->y
   12            - arg1->z * arg2->z + arg1->t * arg2->t;
   13     out->y = arg1->y * arg2->x + arg1->x * arg2->y
   14            - arg1->t * arg2->z - arg1->z * arg2->t;
   15     out->z = arg1->z * arg2->x - arg1->t * arg2->y
   16            + arg1->x * arg2->z - arg1->y * arg2->t;
   17     out->t = arg1->t * arg2->x + arg1->z * arg2->y
   18            + arg1->y * arg2->z + arg1->x * arg2->t;
   19 }
   20 
   21 void HComplexSqr(_HCMPLX *arg, _HCMPLX *out)
   22 {
   23     out->x = arg->x * arg->x - arg->y * arg->y
   24            - arg->z * arg->z + arg->t * arg->t;
   25     out->y = 2 * arg->x * arg->y - 2 * arg->z * arg->t;
   26     out->z = 2 * arg->z * arg->x - 2 * arg->t * arg->y;
   27     out->t = 2 * arg->t * arg->x + 2 * arg->z * arg->y;
   28 }
   29 
   30 int HComplexInv(_HCMPLX *arg, _HCMPLX *out)
   31 {
   32    double det, mod, xt_minus_yz;
   33 
   34    det = (sqr(arg->x - arg->t) + sqr(arg->y + arg->z))*
   35            (sqr(arg->x + arg->t) + sqr(arg->y - arg->z));
   36 
   37    if(det == 0.0)
   38       return(-1);
   39    mod = sqr(arg->x) + sqr(arg->y) + sqr(arg->z) + sqr(arg->t);
   40    xt_minus_yz = arg->x * arg->t - arg->y * arg->z;
   41 
   42    out->x = ( arg->x * mod - 2 * arg->t * xt_minus_yz)/det;
   43    out->y = (-arg->y * mod - 2 * arg->z * xt_minus_yz)/det;
   44    out->z = (-arg->z * mod - 2 * arg->y * xt_minus_yz)/det;
   45    out->t = ( arg->t * mod - 2 * arg->x * xt_minus_yz)/det;
   46    return(0);
   47 }
   48 
   49 void HComplexAdd(_HCMPLX *arg1, _HCMPLX *arg2, _HCMPLX *out)
   50 {
   51     out->x = arg1->x + arg2->x;
   52     out->y = arg1->y + arg2->y;
   53     out->z = arg1->z + arg2->z;
   54     out->t = arg1->t + arg2->t;
   55 }
   56 
   57 void HComplexSub(_HCMPLX *arg1, _HCMPLX *arg2, _HCMPLX *out)
   58 {
   59     out->x = arg1->x - arg2->x;
   60     out->y = arg1->y - arg2->y;
   61     out->z = arg1->z - arg2->z;
   62     out->t = arg1->t - arg2->t;
   63 }
   64 
   65 void HComplexMinus(_HCMPLX *arg1, _HCMPLX *out)
   66 {
   67     out->x = -arg1->x;
   68     out->y = -arg1->y;
   69     out->z = -arg1->z;
   70     out->t = -arg1->t;
   71 }
   72 
   73 /* extends the unary function f to *h1 */
   74 void HComplexTrig0(_HCMPLX *h, _HCMPLX *out)
   75 {
   76     /* This is the whole beauty of Hypercomplex numbers - *ANY* unary
   77        complex valued function of a complex variable can easily
   78        be generalized to hypercomplex numbers */
   79 
   80     _CMPLX a,b, resulta,resultb;
   81 
   82     /* convert to duplex form */
   83     a.x = h->x - h->t;
   84     a.y = h->y + h->z;
   85     b.x = h->x + h->t;
   86     b.y = h->y - h->z;
   87 
   88     /* apply function to each part */
   89     CMPLXtrig0(a,resulta);
   90     CMPLXtrig0(b,resultb);
   91 
   92     /* convert back */
   93     out->x =  (resulta.x + resultb.x)/2;
   94     out->y =  (resulta.y + resultb.y)/2;
   95     out->z =  (resulta.y - resultb.y)/2;
   96     out->t =  (resultb.x - resulta.x)/2;
   97 }
   98