[an error occurred while processing this directive] [an error occurred while processing this directive]
[an error occurred while processing this directive] Skip to the content of the web site.The C++ classes Octonion<long double>, Octonion<double>, and Octonion<float> represent floating-point octonions of the form z = a + ib1 + jb2 + kb3 + ub4 + i1b5 + j1b6 + k1b7.
The symbols i, j, k, u1, i1, j1, and k1 follow the multiplication rules shown in Table 1.Table 1. Multiplication rules for octonion symbols.
× | i | j | k | u1 | i1 | j1 | k1 |
i | −1 | k | −j | i1 | −u1 | −k1 | j1 |
j | −k | −1 | i | j1 | k1 | −u1 | −i1 |
k | j | −i | −1 | k1 | −j1 | i1 | −u1 |
u1 | −i1 | −j1 | −k1 | −1 | i | j | k |
i1 | u1 | −k1 | j1 | −i | −1 | −k | j |
j1 | k1 | u1 | −i1 | −j | k | −1 | −i |
k1 | −j1 | i1 | u1 | −k | −j | i | −1 |
This is also shown in Figure 1 where arrows indicate the order of multiplication resulting in a positive product. For example, the lowest edge arrow would indicate that j1i = k1, and consequently, ik1 = j1, and k1j1 = i. These may be confirmed by referring to Table 1.
Figure 1. Multiplication of symbols.
Consequently, multiplication is not associative: (ij)u1 = ku1 = k1, but i(ju1) = ij1 = −k1.
Throughout this document, the variable z is used to represent *this object. The choice of u over e for the additional symbol relates mostly to the special nature of e in printing doubles. The template variable T represents the field of the coefficients.
There are two constructors
Octonion( T a = 0 ); Octonion( T a, T b1, T b2, T b3, T b4, T b5, T b6, T b7 );
which create the octonions a + 0i + 0j + 0k + 0u1 + 0i1 + 0j1 + 0k1 and a + ib1 + jb2 + kb3 + ub4 + i1b5 + j1b6 + k1b7, respectively.
There are nine static constants defined in each class:
There are five static constants defined in each class:
ZERO | 0 |
ONE | 1 |
I | i |
J | j |
K | k |
U1 | u1 |
I1 | i1 |
J1 | j1 |
K1 | k1 |
The constants may be accessed through the array UNITS[8] = {ONE, I, J, K, U1, I1, J1, K1}.
Each of the real-valued member functions has the prototype T f() const; and has a corresponding procedural function T f( const Octonion<T> );.
real | imag_i | imag_j | imag_k | imag_u1 | imag_i1 | imag_j1 |
imag_k1 | csgn | abs | norm | abs_imag | norm_imag | arg |
Descriptions of each of the functions follow:
The function T operator [](int n) const returns the coefficient of the unit UNITS[n] for n = 0, 1, 2, ..., 7.
Each of these octonion-valued member functions has the prototype Octonion<T> f() const; and has a corresponding procedural function Octonion<T> f( const Octonion<T> );.
imag | conj | signum |
Descriptions of each of the functions follow:
Each of the square, square root, and inverse member functions has the prototype Octonion<T> f() const; and has a corresponding procedural function Octonion<T> f( const Octonion<T> );.
sqr | sqrt | inverse |
Descriptions of each of the functions follow:
The member function Octonion<T> rotate( const Octonion<T> w ) const; and its associated procedural function Octonion<T> rotate( const Octonion<T> z, const Octonion<T> w ) calculates wzw*. If w has unit length and z is an imaginary quaternion, then this member function returns vector z rotated 2 arg(w) radians around the line defined by ℑ(w).
The power function is overloaded with two prototypes:
Octonion<T> pow( T ) | Octonion<T> pow( Octonion<T> ) |
Each of the exponential and logarithmic member functions has the prototype Octonion<T> f() const; and has a corresponding procedural function Octonion<T> f( const Octonion<T> );.
exp | log | log10 |
Descriptions of each of the functions follow:
Because of the loss of associativity, unless x and y commute, exp(x + y) ≠ exp(x)exp(y), log(xy) ≠ log(x) + log(y), and log10(xy) ≠ log10(x) + log10(y). For example,
but
Each of the trigonometric, hyperbolic, inverse trigonometric, and inverse hyperbolic member functions has the prototype Octonion<T> f() const; and has a corresponding procedural function Octonion<T> f( const Octonion<T> );.
sin | cos | tan | sec | csc | cot |
sinh | cosh | tanh | sech | csch | coth |
asin | acos | atan | asec | acsc | acot |
asinh | acosh | atanh | asech | acsch | acoth |
For example, the sin function calculates the result of z − z3/3! + z5/5! − z7/7! + z9/9! − z11/11! + ⋅⋅⋅ by using the formula
As with the exponential and logarithmic functions, because of the loss of associativity, the commonly understood trigonmetric identities no longer hold, for example,
but
however, double angle formulas continue to hold: sin(2x) = 2sin(x)cos(x) and cos(2x) = 2cos2(x) − 1.
Bessel functions of the first kind, Jn(z) are implemented for integer values of n. The prototype of the member function is Octonion<T> bessel_J( int ) const; and there is the corresponding procedural function Octonion<T> bessel_J( int, const Octonion<T>) const;.
Because the coefficients of the Taylor series for Bessel functions of the first kind are real, this function is well defined even for the non-commutative octonions.
Each of the integer-valued member functions has the prototype Octonion<T> f() const; and has a corresponding procedural function Octonion<T> f( const Octonion<T> );.
floor | ceil |
In both cases, the floor and ceiling, respectively, are calculated for each component.
The polynomial v0zn − 1 + v1zn − 2 + v2zn − 3 + ⋅⋅⋅ vn − 3z2 + vn − 2z + vn − 1 may be calculated efficiently using Horner's rule. The array v of n entries may be of type T *. The lack of commutativity dictates that the polynomial is not well defined from octonionic coefficients, hence the coefficients are restricted to real values.
Octonion<T> horner( T * v, unsigned int n );
The Newton polynomial with offsets:
v0(z − cn − 1)(z − cn − 2)⋅⋅⋅(z − c3)(z − c2)(z − c1) +
v1(z − cn − 1)(z − cn − 2)⋅⋅⋅(z − c3)(z − c2) +
v2(z − cn − 1)(z − cn − 2)⋅⋅⋅(z − c3) + ⋅⋅⋅ +
vn − 3(z − cn − 1)(z − cn − 2) +
vn − 2(z − cn − 1) +
vn − 1 may also be
calculated efficiently using Horner's rule. The arrays v and c of n entries
must be of type T *.
Octonion<T> horner( T * v, T * c, unsigned int n );
Similarly, due to commutativity, the coefficients and the offsets must be restricted to real values.
Corresponding to each of this functions is a procedural function which takes the variable z as a first argument.
All binary arithmetic operators operator ⋅ have the following prototypes:
operator ⋅ ( const Octonion<T> &, const Octonion<T> & ), operator ⋅ ( T, const Octonion<T> & ), and operator ⋅ ( const Octonion<T> &, T ). The standard operations are:+ | - | * | / |
Note that z/w is defined as zw-1.
The unary arithmetic operator operator - has the prototype operator - ( const Octonion<T> & ) and returns the negative of the octonion.
The assignment operators operator ⋅ have the prototypes operator ⋅ ( const Octonion<T> & ) and operator ⋅ ( T ) and appropriately modifies and returns this octonion. The operations are:
= | += | -= | *= | /= |
The auto increment and auto decrement operators work on the real part of the octonion.
All binary Boolean operators have the following prototypes:
operator ⋅ ( const Octonion<T> &, const Octonion<T> & ), operator ⋅ ( T, const Octonion<T> & ), and operator ⋅ ( const Octonion<T> &, T ). The standard operations are:== | != |
Descriptions of each of the functions follow:
Each of the following member functions has the prototype bool f() const; and returns a value based on the components of this octonion.
is_imaginary | is_inf | is_nan | is_neg_inf |
is_pos_inf | is_real | is_real_inf | is_zero |
Descriptions of each of the functions follow:
Each of the following static factory functions has the prototype static Octonion<T> f() const; and returns a random octonion according to the following definitions:
where rk is a random real value.
The stream operators have been overloaded to print and read octonions.