Application Center - Maplesoft

App Preview:

Quaternions, Octonions and Sedenions

You can switch back to the summary page by clicking here.

Learn about Maple
Download Application




Hypercomplex Numbers from the Quaternions to the Sedenions

by Michael Tyrone Browning Carter

Purdue University, West Lafayette

January 18, 2010

 

Good mathematics is when you let the math guide you rather than you guiding the math. -- Michael T. Carter;

 

Description

This Hypercomplex package provides the algebra of the quaternion, octonion and sedenion hypercomplex numbers.;

``

Disclaimer

Feel free to utilize this package for academic, business, or personal use according to Maplesoft's license agreement. However, neither Maplesoft nor I are liable for any errors that may come from this package.  All I ask is that you give me credit.  Please do not reverse engineer this package; it is the ethical thing to do.

 

``

Introduction

``

In the universe, we are aware that invisible entities exist that we want to learn.  Knowledge about these invisible entities add to our universal jigsaw puzzle.  Unfortunately, we currently only describe our universe with six properties:  Energies, Forces, Spaces, Times, Motions, and Matter. Any remaining properties remain inaccessible, and thus have eluded our metaphoric puzzle.   For the six currently known components, physicists have studied classical and modern physics of the universe at length. Einstein and Newton used mathematics (their seeing-eye dog) to help them understand the forces in our universe--in particular, gravity.  

 

Newton unified the heavens and the earth by showing that gravity is universal.  Einstein unified space and time by showing that gravity is the result of mass bending the local space-time continuum.    In addition to gravity, we know have quantum mechanical forces. Following Einstein and Newton, a mathematical understanding of these quantum mechanical forces would significantly increase our knowledge.  

 

The Cayley-Dickson hypercomplex numbers may be the mathematical 'seeing-eye dog' that leads to an understanding of quantum mechanical forces.  Already, The Pauli Spin Matrices and Maxwell equations have been defined in terms of quaternions.

``

There is something interesting about the rotational operator "-1".  Multiplying a real number with "-1" rotates the 1-D vector either left or right.  Multiplying by -1 an even number of times willl rotate the 1-D vector right and will rotate left for an odd number of multiplications. Complex numbers will change both the direction and magnitude of 1-D vectors using phasors.  

 

In addition, we can use vectors on a 2-D space of 1-D vectors through a stereographic projection from the Riemann sphere.    I indicated earlier that there was something interesting about the "-1" rotation.  We are also interested in derivations of "-1".  It is very `naïve` to represent the imaginary component as the square root of negative one.  In quaternions, the components of i, j, and k are not equal to each other, though squaring any one of them will result in "-1".  If one look at a double or dual complex numbers, we do not see these `naïve` representations, such as the square root of zero or the square root of one.  Nevertheless, students have been taught that the square root of negative one is a true exact representation of the imaginary component we called "i".  We cannot represent the exactly of the transcendental number pi, instead we use a symbol.  Therefore, we will do the same for imaginary components of hypercomplex numbers.  The only exception to this rule is their matrix representations.   

 

In another situation engineers explore quaternions to eliminate only gimbal lock (ex. satellites and space shuttles).  Graphic programmers also use quaternions for eliminating gimbal locks.  In abstract algebra, the quaternions are studied en passant only as a non-abelian group.  However, little credit is given to the fact that the Pauli Spin Matrices are actually derivations of quaternions.  Einstein studied tensors for his unification of General Relativity with Electro-Magnetism, but limited them to 360-degree rotation.  

 

However, in quantum mechanics, we need to represent intrinsic spin with a maximum of 720 degrees.  We cannot do this without the use of quaternions.  This also applies to the quaternionic 2-vector of the Dirac equations.  To resolve these difficuites, and upgrade the mathematical toolset of the scientific community, we pose the question:  how can physics and other sciences take advantage of the Cayley-Dickson Construction Hypercomplex Numbers"?

 

One of the major obstacles is simply "informing" the scientific community about this mathematical technique the apparent obstacle of the successive loss of mathematical properties as complexity is increased. This obstacle could be overcome by simply seeing that each lost property provides "power" in usage, instead of the opposite.  This is evident in a direct analogy when doing integration on Reals vs. ordinary complex numbers; ordinary complex numbers lose the properties of order, trichotomy, and self-conjugation. Despite this, there is more "power" in integration of the complex field than integrating over the Reals."  There are two reasons why quaternions were not embraced at the time of their discovery.    

 

1) Hamilton skills to promote the quaternions was not as good as Gibbs' and Heaviside's skills in promoting vectors analysis.

 

2) Gauss has proven that the fundamental theorem of Algebra only requires the use of ordinary complex numbers.    

 

Hamilton was simply ahead of his time.  Relativity was so new and different at this time that many scientists dismissed Einstein's theories.  Moreover, quantum mechanics was so strange to Einstein that he dismisses it with this quote, "I, at any rate, am convinced that He [God] does not throw dice."  In addition, the Cayley-Dickson Constructions Hypercomplex Numbers were so strange to many scientists that they dismissed them as mathematical novelties, as they did with fractals.   

 

I hypothesize that this largely unexplored branch of mathematics may be the tool needed for unification. We discovered general relativity via an old pure mathematical entity--Riemannian's geometry utilizing tensor analysis. We discovered String Theory via an old pure mathematical entity--Euler's beta function.  Similarly, I believe that we will discover future physics via an old pure mathematical entity--the Cayley-Dickson Construction Hypercomplex numbers.

;

There are higher dimensional numbers besides complex numbers.  There are also hypercomplex numbers, such as, quaternions (4D), octonions (8D), sedenions (16D), pathions (32D), chingons (64D), routons (128D), and voudons (256D).  These names were coined by Robert P.C. de Marrais and Tony Smith.  It is an alternate naming system providing relief from the difficult Latin names, such as: trigintaduonions (32D), sexagintaquattuornions (64D), centumduodetrigintanions (128D), and ducentiquinquagintasexions (256D).

 

 

Quaternions

 

A Hamilton Quaternion is a hypercomplex number with one Real part (the scalar) and three imaginary parts (the vector).

 

This is an extension of the concept of numbers.  We have found that a Real number is a one-part number that can be represented on a number line, and a complex number is a two-part number that can be represented on a plane.  Extending that logic, we have also found that we can produce more numbers by doubling the parts.     

Quaternion --> a + b*i + c*j + d*k, where the coefficients a, b, c, d are real numbers

 

The hypercomplex number-quaternion-is a non-commutative division ring.  This is what we call a four-dimensional number.  Here is an example of a quaternion:  5 + 2i + 3j + 4k.  The first term is called the scalar term; it is simply a real number.  The other terms consisting of, i, j, k. are called the imaginary terms.  As a group, they are called the vector of the quaternion.  Vector algebra uses the same name vector as the quaternion number, but with a different meaning.  Although vector algebra is an offspring of quaternions, vectors are not numbers.  Starting with complex numbers, we lose the permanence of trichotomy.  The permanencies we lose with quaternion numbers are the trichotomy property and the commutative property under multiplication. Additionally the imaginary units are anti-commutative under multiplication.  Anti-commutative means the sign of the imaginary unit changes when we transpose the two operands under multiplication, e.g., i*j = -(j*i).  The imaginary elements, i, j, and k, give cyclic permutations with each other.

 

If we set the coefficients of the imaginary elements j and k to zero, the quaternion number becomes an ordinary complex number.  We can create all of the other algebraic numbers and the transcendental numbers from the quaternions simply by setting all the coefficients of the imaginary elements to zero.

 

History


Sir William Rowan Hamilton was born in Dublin, Ireland either on August 3rd or August 4th, 1805. He was born at midnight, so there is some confusion about his birthday.  Hamilton was considered a prodigy.  For some years, he lived in Trim with his uncle, Reverend James Hamilton.  By the age of five, it is claimed that Hamilton knew Latin, Greek, and Hebrew, which he learned from his uncle.  Hamilton was exposed to mathematics at age twelve by an American, Zerah Colburn.  Colburn was able to impress Hamilton by performing amazing mental arithmetic operations.

By age 13, Hamilton studied the algebra of the mathematician Alexis Claude Clairaut (Paris, France; 1713 - 1765).  Clairaut's Théorie de la Figure de la Terra (1743), a treatise dealing with the shape of rotating solid bodies, might have been the driving force for Hamilton's direction toward quaternions.  At age 17, Hamilton discovered an error in Laplace's Méchanique Céleste, which brought Hamilton a lot of recognition.  At age 18, Hamilton became a student at Trinity College, Dublin.  He earned an award called Optime in Classics--awarded once every twenty years.
   
Hamilton married Helen Maria Bayly in Ireland, and together they had two sons and a daughter.  In his publication Theory of System of Rays (1832), he predicted conical refraction via the characteristic function on Fresnel's wave surface.  Hamilton received great fame after Humphrey Lloyd, his physics professor, confirmed experimentally this theoretical prediction.  In 1835, Hamilton was knighted.
   
The Royal Irish Academy provided an audience for Hamilton's paper on complex numbers as algebraic couples (ordered pairs of Real numbers).  His paper was considered very difficult to understand; this was a curse that plagued all of Hamilton's publications.  However, his focus was expanding the algebra of the complex numbers to triplets.  He could add and subtract triplets, but could not multiply them.  For years his obsession even caught the attention of his children who would ask him every morning, "Well, Papa can you multiply triplets?"  On Monday, October 16, 1843, while Hamilton and his wife were walking along the Royal Canal on his way to a meeting with the Royal Irish Academy, the idea of the quaternions sparked in his mind.  He carved the idea on the surface of the Brougham Bridge:       
i^2 = j^2 = k^2 = ijk = -1.


Hamilton felt that his discovery of the quaternions in the 19th century was just as important as the fluxions (the calculus) were in the 17th century.  The rest of his life was devoted to elucidating the algebra of the quaternions. However, being plagued with alcoholism and cursed with the inability to communicate his ideas clearly, may have been why quaternions were not taken seriously.  The mathematician, William Thomson (Ireland; 1824 - 1907) wrote:  


                                         Quaternions came from Hamilton after his really good work had been
                                         done, and  though beautifully ingenious, have been an unmixed evil

                                         to those who have touched them in any way.

Applications

Rotating objects are probably quaternion numbers' most practical application.  We have an alternate way of rotating objects with another non-commutative algebra, called matrix algebra.  However, matrix algebra, coupled with trigonometric functions, has a defect.  Sometimes we get what one calls a singular matrix.      Mechanical devices, such as gyroscopes, tracking, robot arms, etc., cannot afford to have a singular matrix in the software.  A singular matrix can cause gimbal (or robot) lock.   Gimbal lock occurs when the mechanical device simply locks up (stops working) because one degree of freedom, among the three axes, is lost.  This would be very hazardous for an air force fighter navigation system!

 

In addition, it could be very costly for an automobile factory that uses robotic arms.  Rotations, via quaternion numbers, do not exhibit the problem of gimbal lock.  Quaternion numbers also will require fewer programming steps than matrix rotation.  Fewer programming steps equate to faster, more efficient and more cost-effective software.
   
Rotation is also used in computer animation.  As computers become faster, consumers need incentives to purchase the more expensive machines.  Video games offer strong incentives for those who take their leisure seriously.  Interactive video games need effective methods of rotating virtual objects.  For example, the three video games of Tomb Raider I, II, & III take advantage of quaternions.  

 

Matrix algebra utilizes Euler angles.  Euler angles are the rotation angles of the Euclidean (rectangular) coordinate system.  Euler angles specify the rotation of the X, Y, and Z rotation axes.  The Euler angle is the culprit of the singularities in matrix algebra.  In addition, Euler angles produce a jerky and unnatural type of movement.  With quaternions, the rotations are smooth and natural.  This is why Microsoft's programming development software offers software engineers quaternion tools.  Remember quaternions are four dimensions; this is the reason quaternions are more effective and efficient than matrices.  Euler angles only work with the three dimensions of height, length, and width.  However, quaternions have the super ability to produce a rotation on any, of the infinite, axes of a sphere.  A matrix rotation of two axes, requires several operations and only one with quaternions.
   
Quaternions are also utilized in MRI (Magnetic Resonance Images) and CAT (Computed Axial Tomography), also known as CT (Computed Tomography).  MRI technology utilizes magnetic energy and radio waves in order to produce cross-sectional slice images of the human body.  CAT technology utilizes the x-ray principal.  As x-rays pass through the body, they are attenuated at different levels; this produces a profile of different slices.  MRI and CAT scans perform rigid transformations that are represented by quaternions.  Each quaternion is iterated as an interpolated change that is computed for position and orientation.  In addition, the interpolated rotation is a small-angle approximation of a rotation quaternion that is linear in three parameters.

Availabe Quaternion Functions

NULL

type/quaternion
*

+

-

^

Qabs

Qadd

Qamplitude

Qangle

Qarccos

Qarccosh

Qarccot

Qarccoth

Qarccsc

Qarccsch

Qarcsec

Qarcsech

Qarcsin

Qarcsinh

Qarctan

Qarctanh
Qargument

 

Qaxial

Qceil

Qcolatitude

Qconjugate
QconvertToFrac

Qcos

Qcosh

Qcot

Qcoth

Qcsc

Qcsch

Qdefine

QdivLeft

QdivRight

Qdot

Qeval

Qsec

Qsech

Qsignum
Qsin

Qsinh

Qsqrt

Qsubtract

 

Qexp

Qfloor

Qfrac

Qicoeff

Qinverse

QisCommutable

QisEqual

QisPure

QisScalar

Qjcoeff

Qkcoeff

Qlength

Qln

Qlongitude

Qmagnitude

Qmodulus

 

QmuPart

Qmult

Qnorm

Qnormalize
QphiPart

QpolarPart

QpolarToRect

Qpower
QpsiPart

Qrand

QrectToPolar

Qround
Qscalar


Qtan

Qtanh

QthetaPart

QtoMatrices
QtoMatrix

Qtrunc

Qunit

QunitVector
Qvector

 

 

 

``

Getting Started

Getting Started

Here is one way to tell Maple where the package library is located.  This does not affect Maple's system library.  If you have an apple you will not have a C: drive.

In addition, you will use the forward slash and not two double back-slashes.

restart;

HypercomplexLib :=`C:\\Hypercomplex\\Hypercomplex.mla`;

libname:=HypercomplexLib,libname; ### now Maple will find the lib

 

`C:\Hypercomplex\Hypercomplex.mla`

"C:\Hypercomplex\Hypercomplex.mla", "C:/inttypes", "C:\Program Files\Maple 15/lib", "C:\Program Files\Maple 15\toolbox\NAG\lib"

(1)

Here we load the package.  Notice that the semi-colon is on the end of the command. The semi-colon forces the command to be verbosed.  If you do not want the verbose mode then use a colon for quiet mode for the command.

 

The package is displaying all functions available to the user.  In addition, the operators *, +, -, and ^ are overloaded by the package.  The user will know this by seeing the operators being displayed.

 

 

 

 

with(Hypercomplex);

[`*`, `+`, `-`, Oadd, Oalgebra, Oconjugate, Odefine, OdivLeft, OdivRight, Odot, Oeval, Oinverse, Omult, Orand, Oscalar, Osubtract, OtoMatrices, OtoMatrix, OunitVector, Ovector, Qabs, Qadd, Qalgebra, Qamplitude, Qaxial, Qceil, Qconjugate, QconvertToFrac, Qdefine, QdivLeft, QdivRight, Qdot, Qeval, Qexp, Qfloor, Qfrac, Qicoeff, Qinverse, QisCommutable, QisEqual, QisNZscalar, QisNZscalarOne, QisPure, QisScalar, Qjcoeff, Qkcoeff, Qlength, Qln, Qmagnitude, Qmodulus, Qmult, Qnorm, Qnormalize, Qpower, Qrand, Qround, Qscalar, Qsignum, Qsqrt, Qsubtract, QtoMatrices, QtoMatrix, Qtrunc, Qunit, QunitVector, Qvector, Sadd, Salgebra, Scalar, Sconjugate, Sdefine, Sdot, Seval, Sinverse, Smult, Srand, Sscalar, Ssubtract, StoMatrix, SunitVector, Svector, `^`, eval, getHypercomplex, init, op, print, setHypercomplex, unprotect]

(2)

``

Quaternion Lesson

Quaternions Lession

The quaternions have four components. u, i, j and k.  These components are protected by the package so that the package can properly work.  

You will get an error message if you try to assign values to these components.

 

Be advised that you will lose the values to your variables if you have values assigned to these components.

setHypercomplex(quaternion);

quaternion

(3)

getHypercomplex();

quaternion

(4)

i := 5;

Error, attempting to assign to `i` which is protected

 

j := 5;

Error, attempting to assign to `j` which is protected

NULL

k := 5;

Error, attempting to assign to `k` which is protected

The u component is the scalar component.  The i, j, and k components are the imaginary components.

 

You do not have to use the u component.  You may just use the Reals, instead.

 

  

u*u;

1

(5)

i*i;

-1

(6)

j*j;

-1

(7)

k*k;

-1

(8)

The   u, scalar, component is always multiplicative commutative with the other components.  However, all three imaginary components are not multiplicative commutative.  In fact, they are anti-commutative.  Anti-commutative means when we change the order the sign will change.

 

In addition, noticed that the imaginary components are cyclic.  When we multiply i*j we get k.  When we multiply j*k we get i.  And, when we multiply k*i we get j.

 

  

 

u*i;

i

(9)

i*u;

i

(10)

i*j;

k

(11)

j*i;

-k

(12)

j*k;

i

(13)

k*j;

-i

(14)

k*i;

j

(15)

i*k;

-j

(16)

QisCommutable(2,-5);

true

(17)

QisCommutable(i,-17);

true

(18)

QisCommutable(i,j);

false

(19)

QisCommutable(u,k);

true

(20)

QisCommutable(4+5*i+6*j+10*k, Qconjugate(4+5*i+6*j+10*k));

true

(21)

 

Another way to see that the imaginary components are cyclic, is to raise then each to an increased power.  The scalar component behaves like the number one.  Raisng one to any power is still one. We can interchange the u component with the number one, eventhough the calculations do not show it. The u remains there.  The pretty print is just converting it to number one.

 

When we are working only with one imaginary component at a time notice, that when you raised the imaginary component to zero it is equal to one, but, for every mutiple of 4*n power it will also be one.  For ever 4*n + 1 power we will always get the positve imaginary component back.  For ever 4*n+2 power we will get aways get the -1 back.  Finally, for evey power 4*n+3 we will always get the negative imaginary component back.

 

  

NULL

u^0; i^0; j^0; k^0;

1

1

1

1

(22)

u^1; i^1; j^1; k^1;

u

i

j

k

(23)

u^2; i^2; j^2; k^2;

1

-1

-1

-1

(24)

u^3; i^3; j^3; k^3;

1

-i

-j

-k

(25)

u^4; i^4; j^4; k^4;

1

1

1

1

(26)

u^5; i^5; j^5; k^5;

1

i

j

k

(27)

u^6; i^6; j^6; k^6;

1

-1

-1

-1

(28)

u^7; i^7; j^7; k^7;

1

-i

-j

-k

(29)

u^8; i^8; j^8; k^8;

1

1

1

1

(30)

We can take any quaternion and make our own special component.  This is called the unit vector.  The unit vector is also cyclic.  Except for the precision error, we are also getting a similar cyclic behavior that we were receiving with the indiviual imaginary components.

NULL

q  := 1*u + 2*i + 3*j + 4*k;

1+2*i+3*j+4*k

(31)

qu := QunitVector(q);

(2/29)*29^(1/2)*i+(3/29)*29^(1/2)*j+(4/29)*29^(1/2)*k

(32)

QconvertToFrac(qu^1);

(2/29)*29^(1/2)*i+(3/29)*29^(1/2)*j+(4/29)*29^(1/2)*k

(33)

QconvertToFrac(qu^2);

-1

(34)

QconvertToFrac(qu^3);

-(17081/45992)*i-(54883/98518)*j-(17081/22996)*k

(35)

QconvertToFrac(qu^4);

1

(36)

QconvertToFrac(qu^5);

(17081/45992)*i+(54883/98518)*j+(17081/22996)*k

(37)

Another example to see anti-commutative is noticed when we multiply the imaginary unit i by a unit vector of obitrary quaternion--notice that the sign on the scalar does not change.  However, on the imaginary components, their signs reverse when we reverse the order of multiplication.

 

 

NULL

q  := 1*u + 2*i + 3*j + 4*k;

1+2*i+3*j+4*k

(38)

qu := QunitVector(q);

(2/29)*29^(1/2)*i+(3/29)*29^(1/2)*j+(4/29)*29^(1/2)*k

(39)

i*qu;

-(2/29)*29^(1/2)-(4/29)*29^(1/2)*j+(3/29)*29^(1/2)*k

(40)

``

qu*i;

-(2/29)*29^(1/2)+(4/29)*29^(1/2)*j-(3/29)*29^(1/2)*k

(41)

Here, we are only testing the ln and exp functions.  We are checking to see if the results make good sense.

I*3;

3*I

(42)

I+3*I;

4*i

(43)

q := Qrand(-100,100);

-21/8+7*i+(95/8)*j-(43/4)*k

(44)

Qexp(Qln(q));

-82031242/31249997+7*i+(74218738/6249999)*j-(134374989/12499999)*k

(45)

Qln(Qexp(q));

-21/8-(17153/31295)*i-(25082/26975)*j+(25029/29735)*k

(46)

If we used only one scalar and one imaginary unit,   these components will behave like the ordinary complex numbers.  The ordinary complex numbers are comutative.

 

However, if we treat them as quaternions, we cannot use the division symbol.  Division is different for left division or for right division for quaternions.  It is this way because quaternions are not commutative.

 

 

 

complexI := 1/(23.5 + 15*I);

94/3109-(60/3109)*i

(47)

complexi := 1/(23.5 + 15*i);

94/3109-(60/3109)*i

(48)

complexj := 1/(23 + 15*j);

579246/18989195-(596336/29975823)*j

(49)

complexk := 1/(23 + 15*k);

579246/18989195-(596336/29975823)*k

(50)

QdivLeft(complexi,complexj);

(13612281/18989195)*u+(1737738/3797839)*i-(14013896/29975823)*j-(2981680/9991941)*k

(51)

QdivRight(complexi,complexj);

(232262818229676998418461913555/333998658765490171814650776469)*u-(148252862699793828777741646950/333998658765490171814650776469)*i+(151475751029293954809492094200/333998658765490171814650776469)*j-(96686649593166354133718358000/333998658765490171814650776469)*k

(52)

Qinverse(eval(complexi))*complexj;

13612281/18989195+(1737738/3797839)*i-(14013896/29975823)*j-(2981680/9991941)*k

(53)

complexi*Qinverse(eval(complexj));

232262818229676998418461913555/333998658765490171814650776469-(148252862699793828777741646950/333998658765490171814650776469)*i+(151475751029293954809492094200/333998658765490171814650776469)*j-(96686649593166354133718358000/333998658765490171814650776469)*k

(54)

``

Here, we are testing to see if the imaginary components make good sense.

NULL

i*j*k;

-1

(55)

(i*j)*k;

-1

(56)

i*(j*k);

-1

(57)

j*k*i;

-1

(58)

k*i*j;

-1

(59)

(2+i+j)*(3-j+k)*(-4+i+25*j+12*k);

-44-34*i+128*j+180*k

(60)

((2+i+j)*(3-j+k))*(-4+i+25*j+12*k);

-44-34*i+128*j+180*k

(61)

(2+i+j)*((3+j+k)*(-4+i+25*j+12*k));

-160-38*i+64*j+144*k

(62)

i*j*k;

-1

(63)

k*j*i;

1

(64)

In maple you can test to see what type an element is.  

Here,we test to see what a quaternion is.

NULL

type(2,complex);

true

(65)

type(I,complex);

true

(66)

type(2+I,complex);

false

(67)

type(2, quaternion);

true

(68)

type(I, quaternion);

true

(69)

type(2+I+j+k, quaternion);

true

(70)

type(2+i+j+k, quaternion);

true

(71)

type(2+i+j+k, complex);

false

(72)

type([1,2,3],quaternion);

false

(73)

type({1,2,3}, quaternion);

false

(74)

type(2*u, quaternion);

true

(75)

type(2, quaternion);

true

(76)

type(i, complex);

false

(77)

type(j, complex);

false

(78)

type(1-k, complex);

false

(79)

type(VARIABLE, quaternion);

false

(80)

type(QtoMatrix(i), quaternion);

true

(81)

type( Qeval(QtoMatrix(i)), quaternion);

true

(82)

variable := Qln(1 + 15*i + 23.5*j + 16*k);

111941/32253+(65572/91263)*i+(14684/13045)*j+(70319/91753)*k

(83)

type(variable,quaternion);

true

(84)

is(5-i+2*j-8*k, quaternion);

true

(85)

is(5+i+2*j+8*k, quaternion);

true

(86)

Now it is time to look under the hood.  What does a quaternion look like in matrix form?

NULL

q := Qrand(-50,100);

-7+(13/7)*i+(24/7)*j-(45/7)*k

(87)

qm := QtoMatrix(q);

qm := Matrix(4, 4, {(1, 1) = -7, (1, 2) = 13/7, (1, 3) = 45/7, (1, 4) = -24/7, (2, 1) = -13/7, (2, 2) = -7, (2, 3) = -24/7, (2, 4) = -45/7, (3, 1) = -45/7, (3, 2) = 24/7, (3, 3) = -7, (3, 4) = 13/7, (4, 1) = 24/7, (4, 2) = 45/7, (4, 3) = -13/7, (4, 4) = -7})

(88)

Qeval(qm);

-7*u+(13/7)*i+(24/7)*j-(45/7)*k

(89)

Qconjugate(q);

-7*u-(13/7)*i-(24/7)*j+(45/7)*k

(90)

QtoMatrix( Qconjugate(q));

Matrix(4, 4, {(1, 1) = -7, (1, 2) = -13/7, (1, 3) = -45/7, (1, 4) = 24/7, (2, 1) = 13/7, (2, 2) = -7, (2, 3) = 24/7, (2, 4) = 45/7, (3, 1) = 45/7, (3, 2) = -24/7, (3, 3) = -7, (3, 4) = -13/7, (4, 1) = -24/7, (4, 2) = -45/7, (4, 3) = 13/7, (4, 4) = -7})

(91)

Qeval( QtoMatrix( Qconjugate(q)));

-7*u-(13/7)*i-(24/7)*j+(45/7)*k

(92)

q;

-7+(13/7)*i+(24/7)*j-(45/7)*k

(93)

QtoMatrices(q);

-7*(Matrix(4, 4, {(1, 1) = 1, (1, 2) = 0, (1, 3) = 0, (1, 4) = 0, (2, 1) = 0, (2, 2) = 1, (2, 3) = 0, (2, 4) = 0, (3, 1) = 0, (3, 2) = 0, (3, 3) = 1, (3, 4) = 0, (4, 1) = 0, (4, 2) = 0, (4, 3) = 0, (4, 4) = 1}))+Typesetting[delayDotProduct](13/7, Matrix(4, 4, {(1, 1) = 0, (1, 2) = 1, (1, 3) = 0, (1, 4) = 0, (2, 1) = -1, (2, 2) = 0, (2, 3) = 0, (2, 4) = 0, (3, 1) = 0, (3, 2) = 0, (3, 3) = 0, (3, 4) = 1, (4, 1) = 0, (4, 2) = 0, (4, 3) = -1, (4, 4) = 0}), true)+Typesetting[delayDotProduct](24/7, Matrix(4, 4, {(1, 1) = 0, (1, 2) = 0, (1, 3) = 0, (1, 4) = -1, (2, 1) = 0, (2, 2) = 0, (2, 3) = -1, (2, 4) = 0, (3, 1) = 0, (3, 2) = 1, (3, 3) = 0, (3, 4) = 0, (4, 1) = 1, (4, 2) = 0, (4, 3) = 0, (4, 4) = 0}), true)-Typesetting[delayDotProduct](45/7, Matrix(4, 4, {(1, 1) = 0, (1, 2) = 0, (1, 3) = -1, (1, 4) = 0, (2, 1) = 0, (2, 2) = 0, (2, 3) = 0, (2, 4) = 1, (3, 1) = 1, (3, 2) = 0, (3, 3) = 0, (3, 4) = 0, (4, 1) = 0, (4, 2) = -1, (4, 3) = 0, (4, 4) = 0}), true)

(94)

Finally, we need to test to see if the trigonmetric functions for quaternions make good sense.  Note, because quaternions are not commutative, we can get different values.  It is always better to do a test to see which composite function is the correct solution.  In this case, the compositive of cos with arccos and sin with arcsin are the correct solutions.

NULL

q := Qdefine(23.45, 72.45, 98.3, 0.5);

23.45+72.45*i+98.3*j+.5*k

(95)

q := QconvertToFrac(q);

469/20+(1449/20)*i+(983/10)*j+(1/2)*k

(96)

Qsin(Qarcsin(q));

Qsin(Qarcsin(469/20+(1449/20)*i+(983/10)*j+(1/2)*k))

(97)

Qarcsin(Qsin(q));

Qarcsin(Qsin(469/20+(1449/20)*i+(983/10)*j+(1/2)*k))

(98)

Qcos(Qarccos(q));

Qcos(Qarccos(469/20+(1449/20)*i+(983/10)*j+(1/2)*k))

(99)

Qarccos(Qcos(q));

Qarccos(Qcos(469/20+(1449/20)*i+(983/10)*j+(1/2)*k))

(100)

Qsqrt(q);

643828/74895+(36139/8576)*i+(45174/7901)*j+(529/18190)*k

(101)

evalf(Qsqrt(q)*Qsqrt(q));

23.45000014+72.44999994*i+98.29999969*j+.4999999993*k

(102)

``

 

Octonions

 

 

Availabe Octonion Functions

The following octonion operators and functions are defined in this hypercomplex package

type/octonion
*

+

-Ovector   

  Oadd
Oconjugate
Odefine
OdivLeft
OdivRight
Orand

Oeval
Oinverse
Omult
Osubtract
OtoMatrices
OtoMatrix
Oscalar

``

Octonion Lession

We have components that are protected.  These components are:

i0, i1, i2, i3, i4, i5, i6, and i7.

These are the components that represent the octonions.

i0 := 2;

Error, attempting to assign to `i0` which is protected

i0 := 2;

Error, attempting to assign to `i0` which is protected

i1 := 2;

Error, attempting to assign to `i1` which is protected

i7 := 2;

Error, attempting to assign to `i7` which is protected

You must be in octonion mode before you can caculate with octonions.

i2*i7;

Error, (in *) Trying to multiply an (octonion or sedenion) in quaternion mode.

setHypercomplex(octonion);

octonion

(103)

i2*i7;

-i5

(104)

3*i0;

3

(105)

i0;

i0

(106)

5*4*i0;

20

(107)

5*4;

20

(108)

 

Notice that the octonions are also cyclic in sets, just like the quaternions.  By being cyclic, it assures that each system is a closed system.

i1*i2; i2*i1;

i3

-i3

(109)

i2*i3; i3*i2;

i1

-i1

(110)

i3*i1; i1*i3;

i2

-i2

(111)

i1*i2; -i1*i2; i1*(-i2);

i3

-i3

-i3

(112)

i4*i5; i5*i4;

i1

-i1

(113)

 

 

 

 

It is a requirement that all Cayley-Dickson imaginary units equal -1 when squared.

i0*i0;

1

(114)

i1*i1;

-1

(115)

i2*i2;

-1

(116)

i3*i3;

-1

(117)

i4*i4;

-1

(118)

i5*i5;

-1

(119)

i6*i6;

-1

(120)

i7*i7;

-1

(121)

Just like the Reals, ordinary complex numbers, quaternions, and the octonions are all division algebras.  

 

When you multiply an octonion by its inverse you will get 1.

 

However, because octonion division is also non-commuative, we have both a left and right division.

i2*Oinverse(i2);

1

(122)

Oinverse(i2)*i2;

1

(123)

OdivLeft(i2,i2);

1

(124)

OdivRight(i2,i2);

1

(125)

OdivRight(i2,i3);

-i1

(126)

OdivLeft(i2,i3);

-i1

(127)

OdivLeft(2,3);

3/2

(128)

OdivRight(2,3);

2/3

(129)

4*Oinverse(5);

4/5

(130)

Oinverse(5)*4;

4/5

(131)

  Here, we are testing the dot product.  The dot product is made from multiplication, addition and conjugate operators.

 

The dot product has a longer delay.

``

Odot(2,3);

6

(132)

Odot(i2,i3);

-1

(133)

Odot(i2,i2);

1

(134)

o1 := Orand(-100,100);

(11/84)*i0-(61/84)*i1+(83/84)*i2-(79/84)*i3+(15/28)*i4-(5/6)*i5+(3/14)*i6+(19/21)*i7

(135)

Odot(o1,o1);

3333/784

(136)

evalf( Odot(o1,o1) );

4.251275510

(137)

o2 := Orand(1,1);

i0+i1+i2+i3+i4+i5+i6+i7

(138)

Odot(o2,o2);

8

(139)

Now, it is time to look under the hood.  The octonions are hypermatrices. The members are not scalars, but quaternions.

o3 := Odefine(1,2,3,4, 5,6,7,8);

i0+2*i1+3*i2+4*i3+5*i4+6*i5+7*i6+8*i7

(140)

OtoMatrix(o3);

Matrix(2, 2, {(1, 1) = u+2*i+3*j+4*k, (1, 2) = 5*u+6*i+7*j+8*k, (2, 1) = 5*u+6*i+7*j+8*k, (2, 2) = u+2*i+3*j+4*k})

(141)

OtoMatrices(o3);

(Matrix(2, 2, {(1, 1) = u, (1, 2) = 0, (2, 1) = 0, (2, 2) = u}))+2*(Matrix(2, 2, {(1, 1) = i, (1, 2) = 0, (2, 1) = 0, (2, 2) = i}))+3*(Matrix(2, 2, {(1, 1) = j, (1, 2) = 0, (2, 1) = 0, (2, 2) = j}))+4*(Matrix(2, 2, {(1, 1) = k, (1, 2) = 0, (2, 1) = 0, (2, 2) = k}))+5*(Matrix(2, 2, {(1, 1) = 0, (1, 2) = u, (2, 1) = u, (2, 2) = 0}))+6*(Matrix(2, 2, {(1, 1) = 0, (1, 2) = i, (2, 1) = i, (2, 2) = 0}))+7*(Matrix(2, 2, {(1, 1) = 0, (1, 2) = j, (2, 1) = j, (2, 2) = 0}))+8*(Matrix(2, 2, {(1, 1) = 0, (1, 2) = k, (2, 1) = k, (2, 2) = 0}))

(142)

o4 := Orand(-10,10);

(7/3)*i0+(4/3)*i1-i2-(1/3)*i3+i4+(1/3)*i5-(2/3)*i6+(2/3)*i7

(143)

OtoMatrix(o4);

Matrix(2, 2, {(1, 1) = (7/3)*u+(4/3)*i-j-(1/3)*k, (1, 2) = u+(1/3)*i-(2/3)*j+(2/3)*k, (2, 1) = u+(1/3)*i-(2/3)*j+(2/3)*k, (2, 2) = (7/3)*u+(4/3)*i-j-(1/3)*k})

(144)

OtoMatrices(o4);

(Matrix(2, 2, {(1, 1) = (7/3)*u, (1, 2) = 0, (2, 1) = 0, (2, 2) = (7/3)*u}))+Typesetting[delayDotProduct](4/3, Matrix(2, 2, {(1, 1) = i, (1, 2) = 0, (2, 1) = 0, (2, 2) = i}), true)-(Matrix(2, 2, {(1, 1) = j, (1, 2) = 0, (2, 1) = 0, (2, 2) = j}))-Typesetting[delayDotProduct](1/3, Matrix(2, 2, {(1, 1) = k, (1, 2) = 0, (2, 1) = 0, (2, 2) = k}), true)+(Matrix(2, 2, {(1, 1) = 0, (1, 2) = u, (2, 1) = u, (2, 2) = 0}))+Typesetting[delayDotProduct](1/3, Matrix(2, 2, {(1, 1) = 0, (1, 2) = i, (2, 1) = i, (2, 2) = 0}), true)-Typesetting[delayDotProduct](2/3, Matrix(2, 2, {(1, 1) = 0, (1, 2) = j, (2, 1) = j, (2, 2) = 0}), true)+Typesetting[delayDotProduct](2/3, Matrix(2, 2, {(1, 1) = 0, (1, 2) = k, (2, 1) = k, (2, 2) = 0}), true)

(145)

OtoMatrices( Oconjugate(o4) );

(Matrix(2, 2, {(1, 1) = (7/3)*u, (1, 2) = 0, (2, 1) = 0, (2, 2) = (7/3)*u}))-Typesetting[delayDotProduct](4/3, Matrix(2, 2, {(1, 1) = i, (1, 2) = 0, (2, 1) = 0, (2, 2) = i}), true)+(Matrix(2, 2, {(1, 1) = j, (1, 2) = 0, (2, 1) = 0, (2, 2) = j}))+Typesetting[delayDotProduct](1/3, Matrix(2, 2, {(1, 1) = k, (1, 2) = 0, (2, 1) = 0, (2, 2) = k}), true)-(Matrix(2, 2, {(1, 1) = 0, (1, 2) = u, (2, 1) = u, (2, 2) = 0}))-Typesetting[delayDotProduct](1/3, Matrix(2, 2, {(1, 1) = 0, (1, 2) = i, (2, 1) = i, (2, 2) = 0}), true)+Typesetting[delayDotProduct](2/3, Matrix(2, 2, {(1, 1) = 0, (1, 2) = j, (2, 1) = j, (2, 2) = 0}), true)-Typesetting[delayDotProduct](2/3, Matrix(2, 2, {(1, 1) = 0, (1, 2) = k, (2, 1) = k, (2, 2) = 0}), true)

(146)

Octonions also have a type.

type(4,octonion);

true

(147)

type(i2, octonion);

true

(148)

type(-3*i7, octonion);

true

(149)

type(j, octonion);

false

(150)

type(i8, octonion);

false

(151)

type(e15, octonion);

false

(152)

type(I, octonion);

false

(153)

Octonions are not generally commutative like the quaternions, but, they are also not generally associative unlike the quaternions.  Notice, that it is possible to get a different value based on how we grouped our multiplication.

i1*i2*i3;

-1

(154)

i1*(i2*i3);

-1

(155)

(i1*i2)*i3;

-1

(156)

i1*(i4*i7);

-i2

(157)

(i1*i4)*i7;

i2

(158)

i1*i4*i7;

i2

(159)

We have the ability to isolate the scalar value and vector value from an octonion.  The quaternion has means to isolate all four components.  In this package, we can only isolate the scalar value and the vector value of an octonion at this time.

o5 := Orand(-10000,10000);

-(3640/3371)*i0+(7499/6742)*i1-(670/3371)*i2-(1885/6742)*i3+(2421/3371)*i4+(4277/6742)*i5-(2459/3371)*i6-(3417/3371)*i7

(160)

Oscalar(o5);

-3640/3371

(161)

Ovector(o5);

(7499/6742)*i1-(670/3371)*i2-(1885/6742)*i3+(2421/3371)*i4+(4277/6742)*i5-(2459/3371)*i6-(3417/3371)*i7

(162)

 

``

Sedenions

Availabe Sedenion Functions

The following octonion operators and functions are defined in this hypercomplex package

type/sedenion
*

+

-

Svector

Sadd
Sconjugate
Sdefine
Sdot
Srand

Seval
Smult
Ssubtract
StoMatrix
Sscalar

 

Sedenion Lession

Components e0 to e15 and O are protected.  In addition, for future work components e0r to e15r are also protected and held reserved.  

O := 2;

Error, attempting to assign to `O` which is protected

e0 := 4;

Error, attempting to assign to `e0` which is protected

e7 := 15;

Error, attempting to assign to `e7` which is protected

e15 := 23;

Error, attempting to assign to `e15` which is protected

You must be in sedenion mode before you can caculate with the sedenions.

e3*e7;

Error, (in *) Trying to multiply a (quaternion or sedenion) in octonion mode.

setHypercomplex(sedenion);

sedenion

(163)

e3*e7; e7*e3;

-e4

e4

(164)

e15*e7; e7*e15;

e8

-e8

(165)

e15*e8; e8*e15;

-e7

e7

(166)

e15*e9; e9*e15;

e6

-e6

(167)

e15*e10; e10*e15;

-e5

e5

(168)

e15*e11; e11*e15;

-e4

e4

(169)

e15*e12; e12*e15;

e3

-e3

(170)

-(e7*e3); e7*(-e3);

-e4

-e4

(171)

e1*e2*e3;

-1

(172)

e3*e2*e1;

1

(173)

s1 := Srand(-5,5);

(1/3)*e0+e1-(2/3)*e2-(4/3)*e3+e4+(5/3)*e5+(5/3)*e6+e7+(1/3)*e8+(1/3)*e9-(4/3)*e10-(4/3)*e11-(4/3)*e12-(5/3)*e13+(4/3)*e14-(2/3)*e15

(174)

s1 + (1/5)*e15;

1/3+e1-(2/3)*e2-(4/3)*e3+e4+(5/3)*e5+(5/3)*e6+e7+(1/3)*e8+(1/3)*e9-(4/3)*e10-(4/3)*e11-(4/3)*e12-(5/3)*e13+(4/3)*e14-(7/15)*e15

(175)

e0 is the component that represents 1, however, it is in matrix form.  Hence, e0 is the same as 1 and 5*e0 is the same as 5.

 

The square of the imaginary units is equal to negative one.

e0*e0;

1

(176)

e1*e1;

-1

(177)

e2*e2;

-1

(178)

e3*e3;

-1

(179)

e4*e4;

-1

(180)

e5*e5;

-1

(181)

e6*e6;

-1

(182)

e7*e7;

-1

(183)

e8*e8;

-1

(184)

e9*e9;

-1

(185)

e10*e10;

-1

(186)

e11*e11;

-1

(187)

e12*e12;

-1

(188)

e13*e13;

-1

(189)

e14*e14;

-1

(190)

e15*e15;

-1

(191)

The sedenion is not a divsion algerba.  It is that way because it has zero-divisors.  A zero divsior  is when a does not equal zero and b does not equal zero; however, a times b may be equal to zero.  See the two trivial examples.

(e2+e7)*(e4-e14);

-e3+e6+e9-e12

(192)

(e3 + e10)*(e6 - e15);

0

(193)

(e1 + e10)*(e13 - e6);

0

(194)

a := e3 + e10;

e3+e10

(195)

b := e6 - e15;

e6-e15

(196)

evalb(a = 0);

false

(197)

evalb(b = 0);

false

(198)

evalb(a*b = 0);

true

(199)

Here, we are testing the dot product function.

 

The dot product has a longer delay.  You may now have that coffee-break.

NULL

s1 := Srand(1,1);

e0+e1+e2+e3+e4+e5+e6+e7+e8+e9+e10+e11+e12+e13+e14+e15

(200)

sconj := Sconjugate(s1);

e0-e1-e2-e3-e4-e5-e6-e7-e8-e9-e10-e11-e12-e13-e14-e15

(201)

Sdot(s1,s1);

16

(202)

Sdot(sconj,sconj);

16

(203)

Here, we are testing the scalar and vector functions.

s2 := Srand(-100,100);

(29/15)*e0-(28/15)*e1-(16/15)*e2-4*e3-(97/15)*e4+(71/15)*e5-(88/15)*e6+(46/15)*e7-(91/15)*e8+(14/5)*e9+(91/15)*e10-(92/15)*e11-(89/15)*e12-(49/15)*e13+(52/15)*e14-(29/15)*e15

(204)

Sscalar(s2);

29/15

(205)

Svector(s2);

-(28/15)*e1-(16/15)*e2-4*e3-(97/15)*e4+(71/15)*e5-(88/15)*e6+(46/15)*e7-(91/15)*e8+(14/5)*e9+(91/15)*e10-(92/15)*e11-(89/15)*e12-(49/15)*e13+(52/15)*e14-(29/15)*e15

(206)

Let us look under the hood.  Here, we see that matrices are the elements of the sedenions' hypermatrix.  Actually, we are using octonions for the elements.  But, it is difficult to see this from the current hypermatrix representation.

s3 := Srand(-100,100);

3*e0-(11/4)*e1-(83/4)*e2+(35/2)*e3+(15/4)*e4+(41/2)*e5+2*e6-(61/4)*e7-21*e8+(97/4)*e9-(49/4)*e10-5*e11+(61/4)*e12+9*e13+e14+(95/4)*e15

(207)

StoMatrix(s3);

Matrix(2, 2, {(1, 1) = 3*i0-(11/4)*i1-(83/4)*i2+(35/2)*i3+(15/4)*i4+(41/2)*i5+2*i6-(61/4)*i7, (1, 2) = -21*i0+(97/4)*i1-(49/4)*i2-5*i3+(61/4)*i4+9*i5+i6+(95/4)*i7, (2, 1) = 21*i0+(97/4)*i1-(49/4)*i2-5*i3+(61/4)*i4+9*i5+i6+(95/4)*i7, (2, 2) = 3*i0+(11/4)*i1+(83/4)*i2-(35/2)*i3-(15/4)*i4-(41/2)*i5-2*i6+(61/4)*i7})

(208)

s4 := Srand(1,1);

e0+e1+e2+e3+e4+e5+e6+e7+e8+e9+e10+e11+e12+e13+e14+e15

(209)

StoMatrix(s4);

Matrix(2, 2, {(1, 1) = i0+i1+i2+i3+i4+i5+i6+i7, (1, 2) = i0+i1+i2+i3+i4+i5+i6+i7, (2, 1) = -i0+i1+i2+i3+i4+i5+i6+i7, (2, 2) = i0-i1-i2-i3-i4-i5-i6-i7})

(210)

Yes, the sedenion has a type as well.

s4 := Srand(-100,100);

-(4/3)*e0-5*e1+(1/18)*e2-(97/18)*e3+(65/18)*e4-(7/2)*e5+(91/18)*e6+(61/18)*e7+(35/18)*e8+(7/9)*e9-(43/18)*e10+(1/6)*e11-(35/9)*e12+(8/3)*e13+(20/9)*e14+3*e15

(211)

type(s4,sedenion);

true

(212)

type(5,sedenion);

true

(213)

type(5*e0, sedenion);

true

(214)

type(4*e1 - 18*e15,sedenion);

true

(215)

 

 

References

 

Maxfield, John E., and Maxfield, Margaret W.  Abstract Algebra and Solution by Radicals.  New York:  Dover, 1971.
   
Meserve, Bruce E.  Fundamental Concepts Of Algebra.  New York:  Dover, 1981.
   
Parker, Sybil P.  Dictionary of Mathematics.  New York:  McGraw, 1997.
   
Rucker, Rudy.  The Fourth Dimension:  A Guided Tour of the Higher Universes.   Boston:          Houghton, 1984.
   
Russell, Bertrand.  Introduction to Mathematical Philosophy.  New York:  Dover, 1933.
   
Sanchez, Julio, and Maria Canton.  DirectX 3D Graphics Programming Bible.  Foster City, CA:  IDG Books Worldwide, 2000.
                
Shapiro, Max S.  Mathematics Encyclopedia.  Garden City:  Doubleday, 1977.
   
Smith, D. E.  History of Mathematics.  2 vols.  New York:  Dover, 1958.
   
Sweetser, Doug.  Doing Physics with Quaternions.  n.p., n.d.  Online.  Internet.  12 December 2000.
Available http://world.std.com/~sweetester/quarternions/qindex.html.
   
Taylor, Edwin F., and John Archibald Wheeler.  Spacetime Physics:  Introduction to Special Relativity.  2nd ed.  New York:  W. H. Freeman, 1996.
   
Wright, Richard S., Jr., and Sweet, Michael.  OpenGL Super Bible.  2nd ed.  Indianapolis:  Waite Group, 2000.
   
Wunsch, David A.  Complex Variables with Applications.  2nd ed.  Massachusetts: Addison-Wesley, 1994.

 

Culbert, Craig.  Cayley-Dickson algebras and loops.  Journal of Generalized Lie Theory and Applications.  Vo1. 1, No. 1, 1-17, 2007.

 

de Marrais, Robert P. C.  Flying Higher Than a Box-Kite:  

Kite-Chain Middens, Sand Mandalas, and Zero-Divisor Patterns in the 2n-ions Beyond the Sedenions. 0207003.pdf

 

About the Author

School:.........................Purdue University, West Lafayette  

Department:.................Computer Science  

Course:........................CS-590 - Visualization of Cayley-Dickson Hypercomplex Numbers  

Professor:....................Xavier Tricoche, PhD  

Student:........................Michael Tyrone Carter  

Project:........................Hypercomplex Package  

Computer Algebra:......Maple 13  

Date:............................Monday, January 18, 2010  

Purpose:......................To gain more knowledge on hypercomlex algebra  

Email:..........................Laureice@wideopenwest.com

 

``

 

I received a bachelor of science in biology (minor in chemistry) from Lewis University, and am now pursuing a PhD. in Computer Science at Purdue University West Lafayette.  Years ago, I received a certificate in computer programming from the College of Automation in Chicago.  In addition, I received a post-bachelor certificate in information systems, with the programming option, at Purdue University Calumet.  I have completed several projects.  To name a few, I designed an assembler language computer emulator as two applications--one in C/C++ and the other in C#`.  Here, I coded both the assembler and the emulator. Next, I designed an animated mechanical man in Java3D (using quaternions).  Finally, in two of my courses, I had to design a linear programming package and a grammar analyzer package, both of which were written in C#.  I was exposed to quaternions, octonions, and sedenions at the University of Aalborg in Denmark a few years back.  During the spring of 2003, I enrolled in a Maple programming course, and designated quaternions as my project.  The quaternion package was originally written for Maple 8.  Two years later I updated it to Maple 9.5.  My favorite languages are Microsoft Macro Assembler, C#, Java, python, C/C++ with OpenGL and the Maple programming language.  My current hypercomplex package is the first of two projects for a visualization course, which is an independent study that lasted over a year.  It is now completed.

 

 

NULL