npm package: @kkitahara/complex-algebra
Description: ECMAScript modules for exactly manipulating complex numbers of which real and imaginary parts are numbers of the form (p / q)sqrt(b).
Author: Koichi Kitahara
Latest version: 1.2.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/complex-algebra.svg)](https://www.apache.org/licenses/LICENSE-2.0)
[![pipeline status](https://gitlab.com/kkitahara/complex-algebra/badges/v1.2.4/pipeline.svg)](https://gitlab.com/kkitahara/complex-algebra/commits/v1.2.4)
[![coverage report](https://gitlab.com/kkitahara/complex-algebra/badges/v1.2.4/coverage.svg)](https://gitlab.com/kkitahara/complex-algebra/commits/v1.2.4)
[![version](https://img.shields.io/npm/v/@kkitahara/complex-algebra/latest.svg)](https://www.npmjs.com/package/@kkitahara/complex-algebra)
[![bundle size](https://img.shields.io/bundlephobia/min/@kkitahara/complex-algebra.svg)](https://www.npmjs.com/package/@kkitahara/complex-algebra)
[![downloads per month](https://img.shields.io/npm/dm/@kkitahara/complex-algebra.svg)](https://www.npmjs.com/package/@kkitahara/complex-algebra)
[![downloads total](https://img.shields.io/npm/dt/@kkitahara/complex-algebra.svg)](https://www.npmjs.com/package/@kkitahara/complex-algebra)

# ComplexAlgebra

ECMAScript modules for exactly manipulating complex numbers
of which real and imaginary parts 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/complex-algebra @kkitahara/real-algebra
```

## Examples
```javascript
import { ExactRealAlgebra as RealAlgebra } from '@kkitahara/real-algebra'
import { ComplexAlgebra } from '@kkitahara/complex-algebra'
let ralg = new RealAlgebra()
let calg = new ComplexAlgebra(ralg)
let z, w, v
```
Generate a new real number
```javascript
z = calg.num(1, 2, 5)
z.toString() // '(1 / 2)sqrt(5)'

z = calg.num(1, 2)
z.toString() // '1 / 2'

z = calg.num(3)
z.toString() // '3'
```
Generate a new imaginary number
```javascript
z = calg.inum(1, 2, 5)
z.toString() // 'i((1 / 2)sqrt(5))'

z = calg.inum(1, 2)
z.toString() // 'i(1 / 2)'

z = calg.inum(3)
z.toString() // 'i(3)'
```
:warning: `num` and `inum` methods do not check if
(the absolute value of) the 3rd parameter is a square-free integer or not
(must be square-free!).

Real and imaginary parts
```javascript
z = calg.num(1, 2, 5)
z.re.toString() // '(1 / 2)sqrt(5)'
z.im.toString() // '0'

z = calg.inum(1, 2, 5)
z.re.toString() // '0'
z.im.toString() // '(1 / 2)sqrt(5)'
```
Generate from two real numbers (since v1.2.0)
```javascript
let a = ralg.$(1, 2, 3)
let b = ralg.$(1, 2, 5)
z = calg.$(a, b)
z.toString() // '(1 / 2)sqrt(3) + i((1 / 2)sqrt(5))'
```
Copy (create a new object)
```javascript
z = calg.inum(1, 2, 5)
w = calg.copy(z)
w.toString() // 'i((1 / 2)sqrt(5))'
```
Equality
```javascript
z = calg.num(1, 2, 5)
w = calg.inum(1, 2, 5)
calg.eq(z, w) // false

w = calg.num(1, 2, 5)
calg.eq(z, w) // true
```
Inequality
```javascript
z = calg.num(1, 2, 5)
w = calg.inum(1, 2, 5)
calg.ne(z, w) // true

w = calg.num(1, 2, 5)
calg.ne(z, w) // false
```
isZero
```javascript
calg.isZero(calg.num(0)) // true
calg.isZero(calg.inum(0)) // true
calg.isZero(calg.num(1, 2, 5)) // false
calg.isZero(calg.inum(1, 2, 5)) // false
calg.isZero(calg.num(-1, 2, 5)) // false
calg.isZero(calg.inum(-1, 2, 5)) // false
```
isInteger (since v1.1.0)
```javascript
calg.isInteger(calg.num(0)) // true
calg.isInteger(calg.inum(0)) // true
calg.isInteger(calg.num(1, 2)) // false
calg.isInteger(calg.inum(1, 2)) // false
calg.isInteger(calg.num(6, 3)) // true
calg.isInteger(calg.inum(6, 3)) // true
calg.isInteger(calg.num(6, 3, 2)) // false
calg.isInteger(calg.inum(6, 3, 2)) // false
```
Addition
```javascript
z = calg.num(1, 2, 5)
w = calg.inum(1, 2)
// new object is generated
v = calg.add(z, w)
v.toString() // '(1 / 2)sqrt(5) + i(1 / 2)'
```
In-place addition
```javascript
z = calg.num(1, 2, 5)
w = calg.inum(1, 2)
// new object is not generated
z = calg.iadd(z, w)
z.toString() // '(1 / 2)sqrt(5) + i(1 / 2)'
```
Subtraction
```javascript
z = calg.num(1, 2, 5)
w = calg.inum(1, 2)
// new object is generated
v = calg.sub(z, w)
v.toString() // '(1 / 2)sqrt(5) + i(-1 / 2)'
```
In-place subtraction
```javascript
z = calg.num(1, 2, 5)
w = calg.inum(1, 2)
// new object is not generated
z = calg.isub(z, w)
z.toString() // '(1 / 2)sqrt(5) + i(-1 / 2)'
```
Multiplication
```javascript
z = calg.inum(1, 2, 5)
w = calg.inum(1, 2)
// new object is generated
v = calg.mul(z, w)
v.toString() // '-(1 / 4)sqrt(5)'
```
In-place multiplication
```javascript
z = calg.inum(1, 2, 5)
w = calg.inum(1, 2)
// new object is not generated
z = calg.imul(z, w)
z.toString() // '-(1 / 4)sqrt(5)'
```
Division
```javascript
z = calg.inum(1, 2, 5)
w = calg.inum(1, 2)
// new object is generated
v = calg.div(z, w)
v.toString() // 'sqrt(5)'
```
In-place division
```javascript
z = calg.inum(1, 2, 5)
w = calg.inum(1, 2)
// new object is not generated
z = calg.idiv(z, w)
z.toString() // 'sqrt(5)'
```
Multiplication by -1
```javascript
z = calg.inum(1, 2, 5)
// new object is generated
w = calg.neg(z)
w.toString() // 'i(-(1 / 2)sqrt(5))'
```
In-place multiplication by -1
```javascript
z = calg.inum(1, 2, 5)
// new object is not generated
z = calg.ineg(z)
z.toString() // 'i(-(1 / 2)sqrt(5))'
```
Complex conjugate
```javascript
z = calg.num(1, 2, 5)
w = calg.inum(1, 2, 5)
// new object is generated
v = calg.cjg(z)
v.toString() // '(1 / 2)sqrt(5)'
v = calg.cjg(w)
v.toString() // 'i(-(1 / 2)sqrt(5))'
```
In-place evaluation of the complex conjugate
```javascript
z = calg.num(1, 2, 5)
w = calg.inum(1, 2, 5)
// new object is not generated
z = calg.icjg(z)
z.toString() // '(1 / 2)sqrt(5)'
w = calg.icjg(w)
w.toString() // 'i(-(1 / 2)sqrt(5))'
```
Square of the absolute value
```javascript
z = calg.iadd(calg.num(3), calg.inum(4))
let a = calg.abs2(z)
a.toString() // '25'
// return value is not a complex number (but a real number)
a.re // undefined
a.im // undefined
```
JSON (stringify and parse)
```javascript
z = calg.iadd(calg.num(1, 2, 5), calg.inum(-1, 2, 7))
let str = JSON.stringify(z)
w = JSON.parse(str, calg.reviver)
calg.eq(z, w) // true
```

### Numerical algebra
The above codes work with built-in numbers if you use
```javascript
import { RealAlgebra } from '@kkitahara/real-algebra'
import { ComplexAlgebra } from '@kkitahara/complex-algebra'
let ralg = new RealAlgebra()
let calg = new ComplexAlgebra(ralg)
```
instead of ExactRealAlgebra.
See the documents of @kkitahara/real-algebra for more details.

### ESDoc documents
For more examples, see ESDoc documents:
```
cd node_modules/@kkitahara/complex-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)