npm package: @kkitahara/quaternion-algebra
Description: ECMAScript modules for exactly manipulating quaternions of which coefficients are numbers of the form (p / q)sqrt(b).
Author: Koichi Kitahara
Latest version: 1.0.4

[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![license](https://img.shields.io/npm/l/@kkitahara/quaternion-algebra.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![pipeline status](https://gitlab.com/kkitahara/quaternion-algebra/badges/v1.0.4/pipeline.svg)](https://gitlab.com/kkitahara/quaternion-algebra/commits/v1.0.4)
[![coverage report](https://gitlab.com/kkitahara/quaternion-algebra/badges/v1.0.4/coverage.svg)](https://gitlab.com/kkitahara/quaternion-algebra/commits/v1.0.4)
[![version](https://img.shields.io/npm/v/@kkitahara/quaternion-algebra/latest.svg)](https://www.npmjs.com/package/@kkitahara/quaternion-algebra)
[![bundle size](https://img.shields.io/bundlephobia/min/@kkitahara/quaternion-algebra.svg)](https://www.npmjs.com/package/@kkitahara/quaternion-algebra)
[![downloads per month](https://img.shields.io/npm/dm/@kkitahara/quaternion-algebra.svg)](https://www.npmjs.com/package/@kkitahara/quaternion-algebra)
[![downloads total](https://img.shields.io/npm/dt/@kkitahara/quaternion-algebra.svg)](https://www.npmjs.com/package/@kkitahara/quaternion-algebra)

# QuaternionAlgebra

ECMAScript modules for exactly manipulating quaternions
of which coefficients are numbers of the form
(*p* / *q*)sqrt(*b*),
where *p* is an integer, *q* is a positive (non-zero) integer,
and *b* is a positive, square-free integer.

## Installation
```
npm install @kkitahara/quaternion-algebra @kkitahara/real-algebra
```

## Examples
```javascript
import { ExactRealAlgebra as RealAlgebra } from '@kkitahara/real-algebra'
import { QuaternionAlgebra } from '@kkitahara/quaternion-algebra'
let r = new RealAlgebra()
let h = new QuaternionAlgebra(r)
let q1, q2, q3
```
Generate a new quaternion
```javascript
q1 = h.$(1, 2, 3, 4)
q1.toString() // '1 + i(2) + j(3) + k(4)'

q1 = h.$(0, 0, 0, r.$(1, 2, 5))
q1.toString() // 'k((1 / 2)sqrt(5))'
```
Real and imaginary parts
```javascript
q1 = h.$(1, 2, 3, 4)
q1.re.toString() // '1'
q1.im instanceof Array // true
q1.im[0].toString() // '2'
q1.im[1].toString() // '3'
q1.im[2].toString() // '4'
```
Copy (create a new object)
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.copy(q1)
q2.toString() // '1 + i(2) + j(3) + k(4)'
```
Equality
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, -2, 3, 4)
h.eq(q1, q2) // false

q2 = h.$(1, 2, 3, 4)
h.eq(q1, q2) // true
```
Inequality
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, -2, 3, 4)
h.ne(q1, q2) // true

q2 = h.$(1, 2, 3, 4)
h.ne(q1, q2) // false
```
isZero
```javascript
h.isZero(h.$(0, 0, 0, 0)) // true
h.isZero(h.$(1, 0, 0, 0)) // false
h.isZero(h.$(0, 1, 0, 0)) // false
h.isZero(h.$(0, 0, 1, 0)) // false
h.isZero(h.$(0, 0, 0, 1)) // false
```
isInteger
```javascript
h.isInteger(h.$(1, 2, 3, 4)) // true
h.isInteger(h.$(1, r.$(2, 3), 3, 4)) // false
h.isInteger(h.$(1, r.$(4, 2), 3, 4)) // true
```
Addition
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, 1, 2, 1)
// new object is generated
q3 = h.add(q1, q2)
q3.toString() // '2 + i(3) + j(5) + k(5)'
```
In-place addition
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, 1, 2, 1)
// new object is not generated
q1 = h.iadd(q1, q2)
q1.toString() // '2 + i(3) + j(5) + k(5)'
```
Subtraction
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, 1, 2, 1)
// new object is generated
q3 = h.sub(q1, q2)
q3.toString() // 'i(1) + j(1) + k(3)'
```
In-place subtraction
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, 1, 2, 1)
// new object is not generated
q1 = h.isub(q1, q2)
q1.toString() // 'i(1) + j(1) + k(3)'
```
Maltiplication
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, -2, -3, -4)
// new object is generated
q3 = h.mul(q1, q2)
q3.toString() // '30'

// some fundametal products
h.mul(h.$(1, 0, 0, 0), h.$(0, 1, 0, 0)).toString() // 'i(1)'
h.mul(h.$(0, 1, 0, 0), h.$(1, 0, 0, 0)).toString() // 'i(1)'
h.mul(h.$(1, 0, 0, 0), h.$(0, 0, 1, 0)).toString() // 'j(1)'
h.mul(h.$(0, 0, 1, 0), h.$(1, 0, 0, 0)).toString() // 'j(1)'
h.mul(h.$(1, 0, 0, 0), h.$(0, 0, 0, 1)).toString() // 'k(1)'
h.mul(h.$(0, 0, 0, 1), h.$(1, 0, 0, 0)).toString() // 'k(1)'
h.mul(h.$(1, 0, 0, 0), h.$(1, 0, 0, 0)).toString() // '1'
h.mul(h.$(0, 1, 0, 0), h.$(0, 1, 0, 0)).toString() // '-1'
h.mul(h.$(0, 0, 1, 0), h.$(0, 0, 1, 0)).toString() // '-1'
h.mul(h.$(0, 0, 0, 1), h.$(0, 0, 0, 1)).toString() // '-1'
h.mul(h.$(0, 1, 0, 0), h.$(0, 0, 1, 0)).toString() // 'k(1)'
h.mul(h.$(0, 0, 1, 0), h.$(0, 1, 0, 0)).toString() // 'k(-1)'
h.mul(h.$(0, 0, 1, 0), h.$(0, 0, 0, 1)).toString() // 'i(1)'
h.mul(h.$(0, 0, 0, 1), h.$(0, 0, 1, 0)).toString() // 'i(-1)'
h.mul(h.$(0, 0, 0, 1), h.$(0, 1, 0, 0)).toString() // 'j(1)'
h.mul(h.$(0, 1, 0, 0), h.$(0, 0, 0, 1)).toString() // 'j(-1)'
```
In-place multiplication
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, -2, -3, -4)
// new object is not generated
q1 = h.imul(q1, q2)
q1.toString() // '30'
```
Division
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, 2, 3, 4)
// new object is generated
q3 = h.div(q1, q2)
q3.toString() // '1'
```
In-place division
```javascript
q1 = h.$(1, 2, 3, 4)
q2 = h.$(1, 2, 3, 4)
// new object is not generated
q1 = h.idiv(q1, q2)
q1.toString() // '1'
```
Multiplication by -1
```javascript
q1 = h.$(1, 2, 3, 4)
// new object is generated
q2 = h.neg(q1)
q2.toString() // '-1 + i(-2) + j(-3) + k(-4)'
```
In-place multiplication by -1
```javascript
q1 = h.$(1, 2, 3, 4)
// new object is not generated
q1 = h.ineg(q1)
q1.toString() // '-1 + i(-2) + j(-3) + k(-4)'
```
Conjugate
```javascript
q1 = h.$(1, 2, 3, 4)
// new object is generated
q2 = h.cjg(q1)
q2.toString() // '1 + i(-2) + j(-3) + k(-4)'
```
In-place evaluation of the conjugate
```javascript
q1 = h.$(1, 2, 3, 4)
// new object is not generated
q1 = h.icjg(q1)
q1.toString() // '1 + i(-2) + j(-3) + k(-4)'
```
Square of the absolute value
```javascript
q1 = h.$(1, 2, 3, 4)
let a = h.abs2(q1)
a.toString() // '30'
// return value is not a quaternion (but a real number)
a.re // undefined
a.im // undefined
```
JSON (stringify and parse)
```javascript
q1 = h.$(1, 2, 3, 4)
let str = JSON.stringify(q1)
q2 = JSON.parse(str, h.reviver)
h.eq(q1, q2) // true
```
 
### ESDoc documents
For more examples, see ESDoc documents:
```
cd node_modules/@kkitahara/quaternion-algebra
npm install --only=dev
npm run doc
```
and open `doc/index.html` in your browser.

## LICENSE
&copy; 2019 Koichi Kitahara  
[Apache 2.0](LICENSE)