## reb Class QH

```Object
reb:QH
```

`class Object:QH`

Functions for Quaternion and Hypercomplex operations.

For quaternions, multiplication is not commutative and division is always defined.

For hypercomplex, multiplication is commutative and division is not always defined. The inverses which are not defined lieon two orthogonal 4D hyperplanes.

The hypercomplex code is based upon the complex number methods of Clyde Davenport using his complex/complex model.

H1 = [a1,a2]

where a1 and a2 are both complex numbers. This is the method used in Fractint. a1 and a2 are converted to two new complex numbers:

fa1 = a1 - conj(flip(a2))
fa2 = a1 + conj(flip(a2))

These new complex numbers (and correspondingly fb1 and fb2) can be used for ordinary complex math, including multiplication, division, trancendental functions, powers, etc. For example, sqrt:

fa1 = sqrt(fa1)
fa2 = sqrt(fa2)

A second conversion is done at the end of the operation(s):

c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))

H2 = [c1, c2]

Ultra Fractal Source
``` Class QH {
import "common.ulb"
; Functions for Quaternion and Hypercomplex operations. <br>
; <p>
; For quaternions, multiplication is not commutative and division is always
; defined.
; <p>
; For hypercomplex, multiplication is commutative and division is not always
; defined. The inverses which are not defined lieon two orthogonal
; 4D hyperplanes.
; <p>
; The hypercomplex code is based upon the complex number methods of Clyde
; Davenport using his complex/complex model.
; <p>
;   <a href="http://home.comcast.net/~cmdaven/bhyprcpx.htm">Davenport's Website</a><br>
; <p>
;   H1 = [a1,a2] <br>
; <p>
; where a1 and a2 are both complex numbers.  This is the method used in Fractint.
; a1 and a2 are converted to two new complex numbers:
; <p>
;   fa1 = a1 - conj(flip(a2)) <br>
;   fa2 = a1 + conj(flip(a2)) <br>
; <p>
; These new complex numbers (and correspondingly fb1 and fb2) can be used for
; ordinary complex math, including multiplication, division, trancendental
; functions, powers, etc. For example, sqrt:
; <p>
;   fa1 = sqrt(fa1) <br>
;   fa2 = sqrt(fa2) <br>
; <p>
; A second conversion is done at the end of the operation(s):
;  <p>
;   c1 = 0.5*(fa1+fa2)<br>
;   c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))<br>
;  <p>
;   H2 = [c1, c2] <br>
; public:

; Quaternian multiplication
static func Qmul(Vector a, Vector b, Vector c)
; Q1*Q2 = [r1*r2 - V1.V2, r2*V1 + r1*V2 + V1xV2]
; calc V . V
float dot = a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w
; calc V x V
c.m_y = a.m_z*b.m_w - b.m_z*a.m_w
c.m_z = -(a.m_y*b.m_w - b.m_y*a.m_w)
c.m_w = a.m_y*b.m_z - b.m_y*a.m_z

c.m_x = a.m_x*b.m_x-dot
c.m_y = c.m_y + a.m_x*b.m_y + b.m_x*a.m_y
c.m_z = c.m_z + a.m_x*b.m_z + b.m_x*a.m_z
c.m_w = c.m_w + a.m_x*b.m_w + b.m_x*a.m_w
endfunc

; Quaternian division calculated as Q2*(1/Q1)
static func Qdiv(Vector a, Vector b, Vector c)
; 1/Q = [r, -V]/(r*r + V.V)
; then calculate Q2*(1/Q1) as for QMul
float denom = 1/(b.m_x*b.m_x + b.m_y*b.m_y + b.m_z*b.m_z + b.m_w*b.m_w)
; calc V . V
float dot = -(a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w)
; calc V x V
c.m_y = -a.m_z*b.m_w + b.m_z*a.m_w
c.m_z = a.m_y*b.m_w - b.m_y*a.m_w
c.m_w = -a.m_y*b.m_z + b.m_y*a.m_z

c.m_x = (a.m_x*b.m_x-dot)*denom
c.m_y = (c.m_y - a.m_x*b.m_y + b.m_x*a.m_y)*denom
c.m_z = (c.m_z - a.m_x*b.m_z + b.m_x*a.m_z)*denom
c.m_w = (c.m_w - a.m_x*b.m_w + b.m_x*a.m_w)*denom
endfunc

; Quaternian division calculated as 1/Q1)*Q2
static func Qdiv2(Vector a, Vector b, Vector c)
; 1/Q = [r, -V]/(r*r + V.V)
; then calculate (1/Q1)*Q2 as for QMul
float denom = 1/(b.m_x*b.m_x + b.m_y*b.m_y + b.m_z*b.m_z + b.m_w*b.m_w)
; calc V . V
float dot = -(a.m_y*b.m_y + a.m_z*b.m_z + a.m_w*b.m_w)
; calc V x V
c.m_y = -b.m_z*a.m_w + a.m_z*b.m_w
c.m_z = b.m_y*a.m_w - a.m_y*b.m_w
c.m_w = -b.m_y*a.m_z + a.m_y*b.m_z

c.m_x = (a.m_x*b.m_x-dot)*denom
c.m_y = (c.m_y + b.m_x*a.m_y - a.m_x*b.m_y)*denom
c.m_z = (c.m_z + b.m_x*a.m_z - a.m_x*b.m_z)*denom
c.m_w = (c.m_w + b.m_x*a.m_w - a.m_x*b.m_w)*denom
endfunc

; Quaternian square
static func Qsqr(Vector a, Vector b)
; Q*Q = [r*r-V.V, 2*r*V]
; calc V . V
float dot = a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w
if dot == 0
dot = 1e-100
endif
b.m_x = a.m_x*a.m_x-dot
b.m_y = 2*a.m_x*a.m_y
b.m_z = 2*a.m_x*a.m_z
b.m_w = 2*a.m_x*a.m_w
endfunc

; Quaternian square root
static func Qsqrt(Vector a, Vector b)
; derived from the inverse of the equations for Qsqr
float sdot = a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w
if sdot == 0
sdot = 1e-100
endif
b.m_x = sqrt((a.m_x + sqrt(a.m_x^2 + sdot))/2)
float factor = 1/(2*b.m_x)
b.m_y = a.m_y*factor
b.m_z = a.m_z*factor
b.m_w = a.m_w*factor
endfunc

; Quaternian reciprocal or inverse
static func Qrecip(Vector a, Vector b)
; 1/Q = [r, -V]/(r*r + V.V)
float denom = 1/(a.m_x*a.m_x + a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
b.m_x = a.m_x*denom
b.m_y = -a.m_y*denom
b.m_z = -a.m_z*denom
b.m_w = -a.m_w*denom
endfunc

; Quaternian natural log
static func Qlog(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = log(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian exponential
static func Qexp(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = exp(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian power calculated as exp(ln(Q1)*Q2)
static func Qpower(Vector a, Vector b, Vector c)
;    Q1^Q2 = exp(ln(Q1)*Q2)
;   Find the log of Q1
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = log(z)
float at = imag(z)/norm
float x1 = real(z)
float y1 = at*a.m_y
float z1 = at*a.m_z
float w1 = at*a.m_w
;   Multiply log by Q2
float dot = y1*b.m_y + z1*b.m_z + w1*b.m_w
; calc V x V
float y2 = z1*b.m_w - b.m_z*w1
float z2 = -(y1*b.m_w - b.m_y*w1)
float w2 = y1*b.m_z - b.m_y*z1

float x2 = x1*b.m_x-dot
y2 = y2 + x1*b.m_y + b.m_x*y1
z2 = z2 + x1*b.m_z + b.m_x*z1
w2 = w2 + x1*b.m_w + b.m_x*w1
;   Take the exponential
norm = sqrt(y2*y2 + z2*z2 + w2*w2)
if norm == 0
norm = 1e-100
endif
z = x2 + flip(norm)
z = exp(z)
at = imag(z)/norm
c.m_x = real(z)
c.m_y = at*y2
c.m_z = at*z2
c.m_w = at*w2
endfunc

; Quaternian power calculated as exp(Q2*ln(Q1))
static func Qpower2(Vector a, Vector b, Vector c)
;    Q1^Q2 = exp(Q2*ln(Q1))
;   Find the log of Q1
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = log(z)
float at = imag(z)/norm
float x1 = real(z)
float y1 = at*a.m_y
float z1 = at*a.m_z
float w1 = at*a.m_w
;   Multiply log by Q2
float dot = y1*b.m_y + z1*b.m_z + w1*b.m_w
; calc V x V
float y2 = -z1*b.m_w + b.m_z*w1
float z2 = (y1*b.m_w - b.m_y*w1)
float w2 = -y1*b.m_z + b.m_y*z1

float x2 = x1*b.m_x-dot
y2 = y2 + x1*b.m_y + b.m_x*y1
z2 = z2 + x1*b.m_z + b.m_x*z1
w2 = w2 + x1*b.m_w + b.m_x*w1

;   Take the exponential
norm = sqrt(y2*y2 + z2*z2 + w2*w2)
if norm == 0
norm = 1e-100
endif
z = x2 + flip(norm)
z = exp(z)
at = imag(z)/norm
c.m_x = real(z)
c.m_y = at*y2
c.m_z = at*z2
c.m_w = at*w2
endfunc

; Quaternian sine
static func Qsin(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = sin(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian arcsine
static func Qasin(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = asin(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian cosine
static func Qcos(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = cos(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian arccosine
static func Qacos(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = acos(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian tangent
static func Qtan(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = tan(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic tangent
static func Qtanh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = tanh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic arctangent
static func Qatanh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = atanh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian arctangent
static func Qatan(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = atan(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian conjugate
static func Qconj(Vector a, Vector b)
; conj(Q) = [r,-V]
b.m_x = a.m_x
b.m_y = -a.m_y
b.m_z = -a.m_z
b.m_w = -a.m_w
endfunc

; Quaternian hyperbolic sine
static func Qsinh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = sinh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic cosine
static func Qcosh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = cosh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic arcsine
static func Qasinh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = asinh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic arccosine
static func Qacosh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = acosh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian cotangent
static func Qcotan(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = cotan(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Quaternian hyperbolic cotangent
static func Qcotanh(Vector a, Vector b)
float norm = sqrt(a.m_y*a.m_y + a.m_z*a.m_z + a.m_w*a.m_w)
if norm == 0
norm = 1e-100
endif
complex z = a.m_x + flip(norm)
z = cotanh(z)
float at = imag(z)/norm
b.m_x = real(z)
b.m_y = at*a.m_y
b.m_z = at*a.m_z
b.m_w = at*a.m_w
endfunc

; Hypercomplex multiplication
static func Hmul(Vector a, Vector b, Vector c)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex b1 = b.m_x + flip(b.m_y)
complex b2 = b.m_z + flip(b.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
complex fb1 = b1 - conj(flip(b2))
complex fb2 = b1 + conj(flip(b2))
fa1 = fa1*fb1
fa2 = fa2*fb2
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
c.m_x = real(c1)
c.m_y = imag(c1)
c.m_z = real(c2)
c.m_w = imag(c2)
endfunc

; Hypercomplex division
static func Hdiv(Vector a, Vector b, Vector c)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex b1 = b.m_x + flip(b.m_y)
complex b2 = b.m_z + flip(b.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
complex fb1 = b1 - conj(flip(b2))
complex fb2 = b1 + conj(flip(b2))
fa1 = fa1/fb1
fa2 = fa2/fb2
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
c.m_x = real(c1)
c.m_y = imag(c1)
c.m_z = real(c2)
c.m_w = imag(c2)
endfunc

; Hypercomplex square
static func Hsqr(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = fa1*fa1
fa2 = fa2*fa2
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex square root
static func Hsqrt(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = sqrt(fa1)
fa2 = sqrt(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex reciprocal or inverse
static func Hrecip(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = 1/fa1
fa2 = 1/fa2
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex natural log
static func Hlog(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = log(fa1)
fa2 = log(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex exponential
static func Hexp(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = exp(fa1)
fa2 = exp(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex power
static func Hpower(Vector a, Vector b, Vector c)
;    Q1^Q2 = exp(ln(Q1)*Q2)
;
; Find the log of Q1
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex b1 = b.m_x + flip(b.m_y)
complex b2 = b.m_z + flip(b.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
complex fb1 = b1 - conj(flip(b2))
complex fb2 = b1 + conj(flip(b2))
fa1 = log(fa1)
fa2 = log(fa2)
;
; Multiply log by Q2
fa1 =  fa1*fb1
fa2 =  fa2*fb2
;
; Take exponential
fa1 = exp(fa1)
fa2 = exp(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
c.m_x = real(c1)
c.m_y = imag(c1)
c.m_z = real(c2)
c.m_w = imag(c2)
endfunc

static func Hsin(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = sin(fa1)
fa2 = sin(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex cosine
static func Hcos(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = cos(fa1)
fa2 = cos(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic sine
static func Hsinh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = sinh(fa1)
fa2 = sinh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic cosine
static func Hcosh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = cosh(fa1)
fa2 = cosh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex conjugate
static func Hconj(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = conj(fa1)
fa2 = conj(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex tangent
static func Htan(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = tan(fa1)
fa2 = tan(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex arcsine
static func Hasin(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = asin(fa1)
fa2 = asin(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex arccosine
static func Hacos(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = acos(fa1)
fa2 = acos(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex arctangent
static func Hatan(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = atan(fa1)
fa2 = atan(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic tangent
static func Htanh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = tanh(fa1)
fa2 = tanh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic arcsine
static func Hasinh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = asinh(fa1)
fa2 = asinh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic arccosine
static func Hacosh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = acosh(fa1)
fa2 = acosh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic arctangent
static func Hatanh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = atanh(fa1)
fa2 = atanh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex cotangent
static func Hcotan(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = cotan(fa1)
fa2 = cotan(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

; Hypercomplex hyperbolic cotangent
static func Hcotanh(Vector a, Vector b)
complex a1 = a.m_x + flip(a.m_y)
complex a2 = a.m_z + flip(a.m_w)
complex fa1 = a1 - conj(flip(a2))
complex fa2 = a1 + conj(flip(a2))
fa1 = cotanh(fa1)
fa2 = cotanh(fa2)
c1 = 0.5*(fa1+fa2)
c2 = 0.5*(conj(flip(fa1)) - conj(flip(fa2)))
b.m_x = real(c1)
b.m_y = imag(c1)
b.m_z = real(c2)
b.m_w = imag(c2)
endfunc

default:
title = "Quat Hyper Methods"
int param v_quathyper
caption = "Version (Quat Hyper Methods)"
default = 100
hint = "This version parameter is used to detect when a change has been made to the formula that is incompatible with the previous version. When that happens, this field will reflect the old version number to alert you to the fact that an alternate rendering is being used."
visible = @v_quathyper < 100
endparam
}
```

Constructor Summary
`QH()`

Method Summary
`static void` ```Hacos(Vector a, Vector b)```
Hypercomplex arccosine
`static void` ```Hacosh(Vector a, Vector b)```
Hypercomplex hyperbolic arccosine
`static void` ```Hasin(Vector a, Vector b)```
Hypercomplex arcsine
`static void` ```Hasinh(Vector a, Vector b)```
Hypercomplex hyperbolic arcsine
`static void` ```Hatan(Vector a, Vector b)```
Hypercomplex arctangent
`static void` ```Hatanh(Vector a, Vector b)```
Hypercomplex hyperbolic arctangent
`static void` ```Hconj(Vector a, Vector b)```
Hypercomplex conjugate
`static void` ```Hcos(Vector a, Vector b)```
Hypercomplex cosine
`static void` ```Hcosh(Vector a, Vector b)```
Hypercomplex hyperbolic cosine
`static void` ```Hcotan(Vector a, Vector b)```
Hypercomplex cotangent
`static void` ```Hcotanh(Vector a, Vector b)```
Hypercomplex hyperbolic cotangent
`static void` ```Hdiv(Vector a, Vector b, Vector c)```
Hypercomplex division
`static void` ```Hexp(Vector a, Vector b)```
Hypercomplex exponential
`static void` ```Hlog(Vector a, Vector b)```
Hypercomplex natural log
`static void` ```Hmul(Vector a, Vector b, Vector c)```
Hypercomplex multiplication
`static void` ```Hpower(Vector a, Vector b, Vector c)```
Hypercomplex power
`static void` ```Hrecip(Vector a, Vector b)```
Hypercomplex reciprocal or inverse
`static void` ```Hsin(Vector a, Vector b)```

`static void` ```Hsinh(Vector a, Vector b)```
Hypercomplex hyperbolic sine
`static void` ```Hsqr(Vector a, Vector b)```
Hypercomplex square
`static void` ```Hsqrt(Vector a, Vector b)```
Hypercomplex square root
`static void` ```Htan(Vector a, Vector b)```
Hypercomplex tangent
`static void` ```Htanh(Vector a, Vector b)```
Hypercomplex hyperbolic tangent
`static void` ```Qacos(Vector a, Vector b)```
Quaternian arccosine
`static void` ```Qacosh(Vector a, Vector b)```
Quaternian hyperbolic arccosine
`static void` ```Qasin(Vector a, Vector b)```
Quaternian arcsine
`static void` ```Qasinh(Vector a, Vector b)```
Quaternian hyperbolic arcsine
`static void` ```Qatan(Vector a, Vector b)```
Quaternian arctangent
`static void` ```Qatanh(Vector a, Vector b)```
Quaternian hyperbolic arctangent
`static void` ```Qconj(Vector a, Vector b)```
Quaternian conjugate
`static void` ```Qcos(Vector a, Vector b)```
Quaternian cosine
`static void` ```Qcosh(Vector a, Vector b)```
Quaternian hyperbolic cosine
`static void` ```Qcotan(Vector a, Vector b)```
Quaternian cotangent
`static void` ```Qcotanh(Vector a, Vector b)```
Quaternian hyperbolic cotangent
`static void` ```Qdiv(Vector a, Vector b, Vector c)```
Quaternian division calculated as Q2*(1/Q1)
`static void` ```Qdiv2(Vector a, Vector b, Vector c)```
Quaternian division calculated as 1/Q1)*Q2
`static void` ```Qexp(Vector a, Vector b)```
Quaternian exponential
`static void` ```Qlog(Vector a, Vector b)```
Quaternian natural log
`static void` ```Qmul(Vector a, Vector b, Vector c)```
Quaternian multiplication
`static void` ```Qpower(Vector a, Vector b, Vector c)```
Quaternian power calculated as exp(ln(Q1)*Q2)
`static void` ```Qpower2(Vector a, Vector b, Vector c)```
Quaternian power calculated as exp(Q2*ln(Q1))
`static void` ```Qrecip(Vector a, Vector b)```
Quaternian reciprocal or inverse
`static void` ```Qsin(Vector a, Vector b)```
Quaternian sine
`static void` ```Qsinh(Vector a, Vector b)```
Quaternian hyperbolic sine
`static void` ```Qsqr(Vector a, Vector b)```
Quaternian square
`static void` ```Qsqrt(Vector a, Vector b)```
Quaternian square root
`static void` ```Qtan(Vector a, Vector b)```
Quaternian tangent
`static void` ```Qtanh(Vector a, Vector b)```
Quaternian hyperbolic tangent

Methods inherited from class Object

Constructor Detail

### QH

`public QH()`
Method Detail

### Qmul

```public static void Qmul(Vector a,
Vector b,
Vector c)```
Quaternian multiplication

### Qdiv

```public static void Qdiv(Vector a,
Vector b,
Vector c)```
Quaternian division calculated as Q2*(1/Q1)

### Qdiv2

```public static void Qdiv2(Vector a,
Vector b,
Vector c)```
Quaternian division calculated as 1/Q1)*Q2

### Qsqr

```public static void Qsqr(Vector a,
Vector b)```
Quaternian square

### Qsqrt

```public static void Qsqrt(Vector a,
Vector b)```
Quaternian square root

### Qrecip

```public static void Qrecip(Vector a,
Vector b)```
Quaternian reciprocal or inverse

### Qlog

```public static void Qlog(Vector a,
Vector b)```
Quaternian natural log

### Qexp

```public static void Qexp(Vector a,
Vector b)```
Quaternian exponential

### Qpower

```public static void Qpower(Vector a,
Vector b,
Vector c)```
Quaternian power calculated as exp(ln(Q1)*Q2)

### Qpower2

```public static void Qpower2(Vector a,
Vector b,
Vector c)```
Quaternian power calculated as exp(Q2*ln(Q1))

### Qsin

```public static void Qsin(Vector a,
Vector b)```
Quaternian sine

### Qasin

```public static void Qasin(Vector a,
Vector b)```
Quaternian arcsine

### Qcos

```public static void Qcos(Vector a,
Vector b)```
Quaternian cosine

### Qacos

```public static void Qacos(Vector a,
Vector b)```
Quaternian arccosine

### Qtan

```public static void Qtan(Vector a,
Vector b)```
Quaternian tangent

### Qtanh

```public static void Qtanh(Vector a,
Vector b)```
Quaternian hyperbolic tangent

### Qatanh

```public static void Qatanh(Vector a,
Vector b)```
Quaternian hyperbolic arctangent

### Qatan

```public static void Qatan(Vector a,
Vector b)```
Quaternian arctangent

### Qconj

```public static void Qconj(Vector a,
Vector b)```
Quaternian conjugate

### Qsinh

```public static void Qsinh(Vector a,
Vector b)```
Quaternian hyperbolic sine

### Qcosh

```public static void Qcosh(Vector a,
Vector b)```
Quaternian hyperbolic cosine

### Qasinh

```public static void Qasinh(Vector a,
Vector b)```
Quaternian hyperbolic arcsine

### Qacosh

```public static void Qacosh(Vector a,
Vector b)```
Quaternian hyperbolic arccosine

### Qcotan

```public static void Qcotan(Vector a,
Vector b)```
Quaternian cotangent

### Qcotanh

```public static void Qcotanh(Vector a,
Vector b)```
Quaternian hyperbolic cotangent

### Hmul

```public static void Hmul(Vector a,
Vector b,
Vector c)```
Hypercomplex multiplication

### Hdiv

```public static void Hdiv(Vector a,
Vector b,
Vector c)```
Hypercomplex division

### Hsqr

```public static void Hsqr(Vector a,
Vector b)```
Hypercomplex square

### Hsqrt

```public static void Hsqrt(Vector a,
Vector b)```
Hypercomplex square root

### Hrecip

```public static void Hrecip(Vector a,
Vector b)```
Hypercomplex reciprocal or inverse

### Hlog

```public static void Hlog(Vector a,
Vector b)```
Hypercomplex natural log

### Hexp

```public static void Hexp(Vector a,
Vector b)```
Hypercomplex exponential

### Hpower

```public static void Hpower(Vector a,
Vector b,
Vector c)```
Hypercomplex power

### Hsin

```public static void Hsin(Vector a,
Vector b)```

### Hcos

```public static void Hcos(Vector a,
Vector b)```
Hypercomplex cosine

### Hsinh

```public static void Hsinh(Vector a,
Vector b)```
Hypercomplex hyperbolic sine

### Hcosh

```public static void Hcosh(Vector a,
Vector b)```
Hypercomplex hyperbolic cosine

### Hconj

```public static void Hconj(Vector a,
Vector b)```
Hypercomplex conjugate

### Htan

```public static void Htan(Vector a,
Vector b)```
Hypercomplex tangent

### Hasin

```public static void Hasin(Vector a,
Vector b)```
Hypercomplex arcsine

### Hacos

```public static void Hacos(Vector a,
Vector b)```
Hypercomplex arccosine

### Hatan

```public static void Hatan(Vector a,
Vector b)```
Hypercomplex arctangent

### Htanh

```public static void Htanh(Vector a,
Vector b)```
Hypercomplex hyperbolic tangent

### Hasinh

```public static void Hasinh(Vector a,
Vector b)```
Hypercomplex hyperbolic arcsine

### Hacosh

```public static void Hacosh(Vector a,
Vector b)```
Hypercomplex hyperbolic arccosine

### Hatanh

```public static void Hatanh(Vector a,
Vector b)```
Hypercomplex hyperbolic arctangent

### Hcotan

```public static void Hcotan(Vector a,
Vector b)```
Hypercomplex cotangent

### Hcotanh

```public static void Hcotanh(Vector a,
Vector b)```
Hypercomplex hyperbolic cotangent