Socket
Socket
Sign inDemoInstall

algebra

Package Overview
Dependencies
11
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.12.7 to 1.0.0

coverage/coverage.json

24

index.js
require('strict-mode')(() => {
var Boole = require('./src/Boole')
const Boole = require('./src/Boole.js')
exports.Boole = Boole
var CompositionAlgebra = require('./src/CompositionAlgebra')
const CompositionAlgebra = require('./src/CompositionAlgebra.js')
exports.CompositionAlgebra = CompositionAlgebra
var Cyclic = require('./src/Cyclic')
exports.Cyclic = Cyclic
var Scalar = require('./src/Scalar')
const Scalar = require('./src/Scalar.js')
exports.Scalar = Scalar
var realField = require('./src/realField')
const realField = require('./src/realField.js')
var Real = CompositionAlgebra(realField, 1)
var Complex = CompositionAlgebra(realField, 2)
var Quaternion = CompositionAlgebra(realField, 4)
var Octonion = CompositionAlgebra(realField, 8)
const Real = CompositionAlgebra(realField, 1)
const Complex = CompositionAlgebra(realField, 2)
const Quaternion = CompositionAlgebra(realField, 4)
const Octonion = CompositionAlgebra(realField, 8)

@@ -26,4 +23,4 @@ exports.Real = Real

var VectorSpace = require('./src/VectorSpace')
var MatrixSpace = require('./src/MatrixSpace')
const VectorSpace = require('./src/VectorSpace.js')
const MatrixSpace = require('./src/MatrixSpace.js')

@@ -40,3 +37,2 @@ exports.C = Complex

exports.MatrixSpace = MatrixSpace
exports.TensorSpace = require('./src/TensorSpace')
})
{
"name": "algebra",
"description": "means completeness and balancing, from the Arabic word الجبر",
"version": "0.12.7",
"version": "1.0.0",
"homepage": "http://g14n.info/algebra",

@@ -14,7 +14,3 @@ "author": {

"build": "npm test && npm run browserify && npm run minify && npm run docs; git status",
"browserify": "npm run browserify:dist; npm run browserify:test",
"browserify:dist": "browserify -r ./index.js:${npm_package_name} -o dist/${npm_package_name}.js",
"browserify:test": "browserify test/*.js -o docs/test/bundle.js",
"coverage": "npm run istanbul && npm run coveralls",
"coveralls": "cat ./coverage/lcov.info | coveralls --verbose",
"browserify": "browserify -r ./index.js:${npm_package_name} -o dist/${npm_package_name}.js",
"docs:_data": "for x in package.json tags.json; do npm run docs:_data:$x; done",

@@ -29,3 +25,3 @@ "docs:_data:package.json": "cp package.json docs/_data/",

"lint_test": "cd test; standa --env mocha; cd -",
"minify": "cd dist; uglifyjs ${npm_package_name}.js --source-map --output ${npm_package_name}.min.js --compress --mangle -b beautify=false,preamble='\"// http://g14n.info/algebra\"'; cd -",
"minify": "cd dist; terser ${npm_package_name}.js --source-map --output ${npm_package_name}.min.js --compress --mangle -b beautify=false,preamble='\"// http://g14n.info/algebra\"'; cd -",
"postversion": "git push origin v${npm_package_version}; npm publish",

@@ -55,17 +51,12 @@ "postpublish": "npm run docs:_data; git commit -am ':arrow_up: updated version'; git push origin master",

"devDependencies": {
"browserify": "^16.1.1",
"coveralls": "^3.0.0",
"istanbul": "^0.4.1",
"browserify": "^16.5.0",
"mocha": "^5.2.0",
"mocha-lcov-reporter": "1.3.0",
"pre-commit": "^1.1.2",
"should": "^13.2.3",
"standa": "^12.0.0",
"uglify-es": "^3.3.9"
"standa": "^14.0.0",
"terser": "^4.3.1"
},
"dependencies": {
"algebra-cyclic": "^0.2.4",
"cayley-dickson": "^0.5.4",
"indices-permutations": "^0.2.3",
"inherits": "^2.0.1",
"laplace-determinant": "^0.2.1",

@@ -77,5 +68,4 @@ "matrix-multiplication": "^0.5.2",

"strict-mode": "^1.1.3",
"tensor-contraction": "^0.2.0",
"tensor-product": "^0.2.1"
"tensor-contraction": "^0.2.0"
}
}

@@ -5,13 +5,6 @@ # algebra

> **New**: checkout matrices and vectors made of strings, with [cyclic algebra](#cyclic).
**NOTA BENE** Imagine all code examples below as written in some REPL where expected output is documented as a comment.
[![NPM version](https://badge.fury.io/js/algebra.svg)](http://badge.fury.io/js/algebra)
[![Badge size](https://badge-size.herokuapp.com/fibo/algebra/master/dist/algebra.js)](https://github.com/fibo/algebra/blob/master/dist/algebra.js)
[![Build Status](https://travis-ci.org/fibo/algebra.svg?branch=master)](https://travis-ci.org/fibo/algebra?branch=master)
[![Dependency Status](https://gemnasium.com/fibo/algebra.svg)](https://gemnasium.com/fibo/algebra)
[![Coverage Status](https://coveralls.io/repos/fibo/algebra/badge.svg?branch=master)](https://coveralls.io/r/fibo/algebra?branch=master)
[![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)
[![Test page](https://img.shields.io/badge/test-page-blue.svg)](http://g14n.info/algebra/test)
[![Change log](https://img.shields.io/badge/change-log-blue.svg)](http://g14n.info/algebra/changelog)

@@ -21,8 +14,7 @@

![Algebra](http://g14n.info/algebra/images/Cover-Algebra.png)!
[OnQuaternionsAndOctonions](http://g14n.info/algebra/images/Cover-OnQuaternionsAndOctonions.png)
![Algebra](http://g14n.info/algebra/images/Cover-Algebra.png)
![OnQuaternionsAndOctonions](http://g14n.info/algebra/images/Cover-OnQuaternionsAndOctonions.png)
## Table Of Contents
* [Status](#status)
* [Features](#features)

@@ -36,3 +28,2 @@ * [Installation](#installation)

- [About operators](#about-operators)
- [Cyclic](#cyclic)
- [Composition Algebra](#composition-algebra)

@@ -47,24 +38,4 @@ - [Scalar](#scalar)

- [Matrix](#matrix)
- [Tensor](#tensor)
* [License](#license)
## Status
*algebra* is under development, but API should not change until version **1.0**.
I am currently adding more tests and examples to achieve a stable version.
Many functionalities of previous versions are now in separated atomic packages:
* [algebra-cyclic]
* [algebra-group]
* [algebra-ring]
* [cayley-dickson]
* [indices-permutations]
* [laplace-determinant]
* [matrix-multiplication]
* [multidim-array-index]
* [tensor-contraction]
* [tensor-product]
## Features

@@ -75,3 +46,2 @@

* Expressive syntax.
* Everything is a Tensor.
* [Immutable objects](https://en.wikipedia.org/wiki/Immutable_object).

@@ -90,3 +60,3 @@

```html
<script src="https://cdn.rawgit.com/fibo/algebra/master/dist/algebra.js"></script>
<script src="https://unpkg.com/algebra/dist/algebra.min.js"></script>
```

@@ -98,2 +68,6 @@

**NOTA BENE** Imagine all code examples below as written in some REPL where expected output is documented as a comment.
All code in the examples below should be contained into a single file, like [test/quickStart.js](https://github.com/fibo/algebra/blob/master/test/quickStart.js).
First of all, import *algebra* package.

@@ -105,12 +79,2 @@

### Try it out
All code in the examples below should be contained into a single file, like [test/quickStart.js](https://github.com/fibo/algebra/blob/master/test/quickStart.js).
<ul class="box">
<li class="tonicdev"><a href="https://tonicdev.com/fibo/algebra-quick-start" target="_blank">Test algebra <em>quick start</em> in your browser.</a></li>
</ul>
[![view on requirebin](http://requirebin.com/badge.png)](http://requirebin.com/?gist=345763d95f093b9d9350)
### Scalars

@@ -131,3 +95,3 @@

```javascript
R.add(1, 2, 3) // 1 + 2 + 3 = 6
R.add(1, 2) // 3
```

@@ -138,3 +102,4 @@

```javascript
const x = new R(2)
// x will be overwritten, see below
let x = new R(2)
const y = new R(-2)

@@ -178,3 +143,3 @@ ```

const z1 = new C([1, 2])
let z1 = new C([1, 2])
const z2 = new C([3, 4])

@@ -202,3 +167,3 @@

```javascript
const v1 = new R2([0, 1])
let v1 = new R2([0, 1])
const v2 = new R2([1, -2])

@@ -228,4 +193,4 @@

const m1 = new R3x2([1, 1,
0, 1,
1, 0])
0, 1,
1, 0])
```

@@ -257,7 +222,7 @@

const m2 = new R2x2([1, 0,
0, 2])
let m2 = new R2x2([1, 0,
0, 2])
const m3 = new R2x2([0, -1,
1, 0])
1, 0])

@@ -279,5 +244,5 @@ m2 = m2.mul(m3)

All operators are implemented as static methods and as object methods.
All operators can be implemented as *static methods* and as *object methods*.
In both cases, operands are coerced to raw data.
As an example, consider addition of vectors in a plane.
As an example, consider addition of vectors in a *Cartesian Plane*.

@@ -308,6 +273,6 @@ ```javascript

Operators can be chained and accept multiple arguments when it makes sense.
Operators can be chained when it makes sense.
```javascript
vector1.addition(vector1, vector1).equality([3, 6]) // true
vector1.addition(vector1).equality([2, 4]) // true
```

@@ -321,67 +286,2 @@

### Cyclic
#### `Cyclic(elements)`
Create an algebra cyclic ring, by passing its elements. The elements are provided
as a string or an array, which lenght must be a prime number. This is necessary,
otherwise the result would be a wild land where you can find [zero divisor][zero_divisor] beasts.
Let's create a cyclic ring containing lower case letters, numbers and the blank
char. How many are they? They are 26 + 10 + 1 = 37, that is prime! We like it.
```javascript
const Cyclic = algebra.Cyclic
// The elements String or Array length must be prime.
const elements = ' abcdefghijklmnopqrstuvwyxz0123456789'
const Alphanum = Cyclic(elements)
```
Operators derive from modular arithmetic
```javascript
const a = new Alphanum('a')
Alphanum.addition('a', 'b') // 'c'
```
You can also create element instances, and do any kind of operations.
```javascript
const x = new Alphanum('a')
const y = x.add('c', 'a', 't')
.mul('i', 's')
.add('o', 'n')
.sub('t', 'h', 'e')
.div('t', 'a', 'b', 'l', 'e')
y.data // 's'
```
Yes, they are [scalars](#scalar) so you can build vector or matrix spaces on top of them.
```javascript
const VectorStrings2 = algebra.VectorSpace(Alphanum)(2)
const MatrixStrings2x2 = algebra.MatrixSpace(Alphanum)(2)
const vectorOfStrings = new VectorStrings2(['o', 'k'])
const matrixOfStrings = new MatrixStrings2x2(['c', 'o',
'o', 'l'])
matrixOfStrings.mul(vectorOfStrings).data // ['x', 'y']
```
Note that, in the particular example above, since the matrix is simmetric
it commutes with the vector, hence changing the order of the operands
the result is still the same.
```javascript
vectorOfStrings.mul(matrixOfStrings).data // ['x', 'y']
```
### CompositionAlgebra

@@ -457,7 +357,2 @@

Keeping in mind that *Byte* space defined above is an algebra, i.e. it has
composition laws well defined, you maybe already noticed that, for example
*byte2* could be seen as corresponding to 4, but in this strange structure
we created, 4 * 4 = 2.
You can play around with this structure.

@@ -474,293 +369,211 @@

**NOTA BENE** The color space example in this section is still a *WiP*.
The [scalars](https://en.wikipedia.org/wiki/Scalar_(mathematics)) are the building blocks, they are the elements you can use to create vectors and matrices.
They are the underneath set enriched with a [ring](https://en.wikipedia.org/wiki/Ring_(mathematics)) structure which
consists of two binary operators that generalize the arithmetic operations of addition and multiplication.
A ring that has the commutativity property is called *abelian* (in honour to [Abel](https://en.wikipedia.org/wiki/Niels_Henrik_Abel)) or also a **field**.
The [scalars](https://en.wikipedia.org/wiki/Scalar_(mathematics)) are the building blocks, they are the elements you can use to create vectors,
matrices, tensors. They are the underneath set enriched with a
[ring](https://en.wikipedia.org/wiki/Ring_(mathematics)) structure which
consists of two binary operators that generalize the arithmetic operations of addition and multiplication. A ring that has the commutativity property
is called *abelian* (in honour to [Abel](https://en.wikipedia.org/wiki/Niels_Henrik_Abel)) or also a **field**.
Ok, let's make a simple example. [Real numbers](#real), with common addition and multiplication are a *scalar field*.
Ok, let's make a simple example. [Real numbers](#real), with common addition
and multiplication are a scalar field: see documentation below. The good new
is that you can create any scalar field as long as you provide a set with
two internal operations and related neutral elements that satisfy the ring
axioms. That is why it will be used something maybe you did not expect could
be treated as an algebra: in the examples below during this section we will
play with the color space, giving a ring structure.
The good new is that you can create any *scalar field* as long as you provide a set with two internal operations and related neutral elements that satisfy the ring axioms.
Let's consider the space of html colors in the form
We are going to create a scalar field using `BigInt` elements to implement something similar to a [Rational Number](https://en.wikipedia.org/wiki/Rational_number). The idea is to use a couple of numbers, the first one is the *numerator* and the second one the *denominator*.
> RGB: Red Green Blue
Arguments we need are the same as [algebra-ring]. Let's start by unities; every element is a couple of numbers, the
*numerator* and the *denominator*, hence unitites are:
composed of three hexadecimal values from `00` to `ff`. Let's start
defining a sum operator on hexadecimals.
* zero: `[ BigInt(0), BigInt(1) ]`
* one: `[ BigInt(1), BigInt(1) ]`
Credits and thanks for dec to hex and viceversa conversions goes to [this gist](https://gist.github.com/faisalman/4213592) author.
We need a function that computes the *Great Common Divisor*.
```javascript
const hexSum = (hex1, hex2) => {
const dec1 = parseInt(hex1, 16) % 256
const dec2 = parseInt(hex2, 16) % 256
// Sum modulo 256 and convert to hexadecimal.
const hexResult = parseInt((dec1 + dec2) % 256, 10).toString(16)
// Return left padded result.
return hexResult.padStart(2, '0')
function greatCommonDivisor (a, b) {
if (b === BigInt(0)) {
return a
} else {
return greatCommonDivisor(b, a % b)
}
}
```
Note that it is used modulo 256 cause we need that our set is *closed*
on this operator, it means that the sum of two colors must be another color.
So now we can normalize a rational number, by removing the common divisors of numerator and denominator.
To define color sum we can split a color in an array of three hexadecimals,
and sum componentwise.
```javascript
const splitColor = (color) => {
const r = color.substring(0, 2)
const g = color.substring(2, 4)
const b = color.substring(4, 6)
function normalizeRational ([numerator, denominator]) {
const divisor = greatCommonDivisor(numerator, denominator)
return [r, g, b]
return [numerator / divisor, denominator / divisor]
}
```
For example, white color `ffffff` will be splitted in `['ff', 'ff', 'ff']`.
```javascript
const colorSum = (color1, color2) => {
const [r1, g1, b1] = splitColor(color1)
const [r2, g2, b2] = splitColor(color2)
const Rational = algebra.Scalar({
zero: [BigInt(0), BigInt(1)],
one: [BigInt(1), BigInt(1)],
equality: ([n1, d1], [n2, d2]) => (n1 * d2 === n2 * d1),
contains: ([n, d]) => (typeof n === 'bigint' && typeof d === 'bigint'),
addition: ([n1, d1], [n2, d2]) => normalizeRational([n1 * d2 + n2 * d1, d1 * d2]),
negation: ([n, d]) => ([-n, d]),
multiplication: ([n1, d1], [n2, d2]) => normalizeRational([n1 * n2, d1 * d2]),
inversion: ([n, d]) => ([d, n])
})
```
const r = hexSum(r1, r2)
const g = hexSum(g1, g2)
const b = hexSum(b1, b2)
So far so good, algebra dependencies will do some checks under the hood and will complain if something looks wrong.
return [r, g, b].join('')
}
```
Let's create few rational numbers.
You can check that this sum is *well defined*, and for example, green plus
blue equals cyan.
```javascript
colorSum('00ff00', '0000ff') // '00ffff'
const half = new Rational([BigInt(1), BigInt(2)])
const two = new Rational([BigInt(2), BigInt(1)])
```
The neutral element respect to this operator is *black* (`000000`).
#### `Scalar.one`
To define a scalar field we need another operation to be used as multiplication.
Let's define a multiplication on hexadecimals first.
Is the *neutral element* for [multiplication](#scalar-multiplication) operator.
```javascript
const hexMul = (hex1, hex2) => {
const dec1 = parseInt(hex1, 16) % 256
const dec2 = parseInt(hex2, 16) % 256
Rational.one // [1n, 1n]
```
// Multiply, then divide by 255 and convert to hexadecimal.
const hexResult = parseInt((dec1 * dec2) / 255, 10).toString(16)
#### `Scalar.zero`
// Return left padded result.
return hex.padStart(2, '0')
}
```
Is the *neutral element* for [addition](#scalar-addition) operator.
Then similarly to `colorSum` it is possible to define a `colorMul` that
applies `hexMul` componentwise.
```javascript
const colorMul = (color1, color2) => {
const [r1, g1, b1] = splitColor(color1)
const [r2, g2, b2] = splitColor(color2)
const r = hexMul(r1, r2)
const g = hexMul(g1, g2)
const b = hexMul(b1, b2)
return [r, g, b].join('')
}
Rational.zero // [0n, 1n]
```
The neutral element for this operator is *white* (`ffffff`).
#### `scalar.data`
We are ready to create our scalar field over RGB colors.
Arguments are the same as [algebra-ring].
The *data* attribute holds the raw data underneath our scalar instance.
```javascript
const RGB = algebra.Scalar(
[ '000000', 'ffffff' ],
{
equality: (a, b) => a === b,
contains: (color) => {
const [r, g, b] = splitColor(color)
half.data // [1n, 2n]
```
return (parseInt(r, 16) < 256) && (parseInt(g, 16) < 256) && (parseInt(b, 16) < 256)
},
addition: colorSum,
negation: (color) => {
const [r, g, b] = splitColor(color)
#### `Scalar.contains(scalar)`
const decR = parseInt(r, 16)
const decG = parseInt(g, 16)
const decB = parseInt(b, 16)
Checks a given argument is contained in the scalar field that was defined.
const minusR = decR === 0 ? 0 : 256 - decR
const minusG = decG === 0 ? 0 : 256 - decG
const minusB = decB === 0 ? 0 : 256 - decB
```javascript
Rational.contains(half) // true
Rational.contains([1n, 2n]) // true
```
const hexMinusR = parseInt(minusR, 10).toString(16)
const hexMinusG = parseInt(minusG, 10).toString(16)
const hexMinusB = parseInt(minusB, 10).toString(16)
#### `scalar1.belongsTo(Scalar)`
const paddedMinusR = hexMinusR.padStart(2, '0')
const paddedMinusG = hexMinusG.padStart(2, '0')
const paddedMinusB = hexMinusB.padStart(2, '0')
This is a class method that checks a scalar instance is contained in the given scalar field.
return `${paddedMinusR}${paddedMinusG}${paddedMinusB}`
},
multiplication: colorMul,
inversion: (color) => {
const [r, g, b] = splitColor(color)
```javascript
half.belongsTo(Rational) // true
```
const decR = parseInt(r, 16)
const decG = parseInt(g, 16)
const decB = parseInt(b, 16)
#### `Scalar.equality(scalar1, scalar2)`
const invR = parseInt(255 * 255 / decR, 10).toString(16)
const invG = parseInt(255 * 255 / decG, 10).toString(16)
const invB = parseInt(255 * 255 / decB, 10).toString(16)
Is a static method
const paddedInvR = invR.padStart(2, '0')
const paddedInvG = invG.padStart(2, '0')
const paddedInvB = invB.padStart(2, '0')
return `${paddedInvR}${paddedInvG}${paddedInvB}`
},
}
)
```javascript
Rational.equality(half, [BigInt(5), BigInt(10)])
```
So far so good, algebra dependencies will do some checks under the hood
and complain if something looks wrong. Now we can create color instances
#### `scalar1.equals(scalar2)`
```javascript
const green = new RGB('00ff00')
const blue = new RGB('0000ff')
half.equals([BigInt(2), BigInt(4)])
```
And as you may expect, you can do operations with them
#### `Scalar.disequality(scalar1, scalar2)`
```javascript
const cyan = green.add(blue)
cyan.data // '00ffff'
Rational.disequality(half, two) // true
```
#### Scalar attributes
#### `scalar1.disequality(scalar2)`
##### `Scalar.one`
```javascript
half.disequality(two) // true
```
Is the *neutral element* for [multiplication](#scalar-multiplication) operator.
In our *RGB* example it corrensponds to *white* (`ffffff`).
#### `Scalar.addition(scalar1, scalar2)`
```javascript
RGB.one // 'ffffff'
Rational.addition(half, two) // [5n , 2n]
```
##### `Scalar.zero`
#### `scalar1.addition(scalar2)`
Is the *neutral element* for [addition](#scalar-addition) operator.
In our *RGB* example it corrensponds to *black* (`000000`)
```javascript
RGB.zero // '000000'
half.addition(two) // Scalar { data: [5n, 2n] }
```
#### Scalar order
#### `Scalar.subtraction(scalar1, scalar2)`
It is always 0 for scalars, see also [Tensor order](#tensor-order).
```javascript
Rational.subtraction(two, half) // [3n , 2n]
```
##### `Scalar.order`
#### `scalar1.subtraction(scalar2)`
The *order* is a static attribute.
```javascript
RGB.order // 0
two.multiplication(half) // Scalar { data: [1n, 1n] }
```
##### `scalar.order`
#### `Scalar.multiplication(scalar1, scalar2)`
The *order* is also available as attribute of a Scalar class instance.
```javascript
green.order // 0
Rational.multiplication(half, two) // [1n, 1n]
```
##### `scalar.data`
#### `scalar1.multiplication(scalar2)`
#### Scalar operators
```javascript
half.multiplication(two) // Scalar { data: [1n, 1n] }
```
#### Scalar set operators
#### `Scalar.division(scalar1, scalar2)`
##### `Scalar.contains(scalar1, scalar2[, scalar3, … ])`
```javascript
Rational.division(two, half) // [1n, 4n]
```
##### `scalar1.belongsTo(Scalar)`
#### `scalar1.division(scalar2)`
#### Scalar equality
```javascript
half.division(two) // Scalar { data: [1n, 4n] }
```
##### `Scalar.equality(scalar1, scalar2)`
#### `Scalar.negation(scalar)`
##### `scalar1.equality(scalar2)`
```javascript
Rational.negation(two) // [-2n, 1n]
```
#### Scalar disequality
#### `scalar.negation()`
##### `Scalar.disequality(scalar1, scalar2)`
```javascript
two.negation() // Scalar { data: [-2n, 1n] }
```
##### `scalar1.disequality(scalar2)`
#### `Scalar.inversion(scalar)`
#### Scalar addition
```javascript
Rational.inversion(two) // [1n, 2n]
```
##### `Scalar.addition(scalar1, scalar2[, scalar3, … ])`
#### `scalar.inversion()`
##### `scalar1.addition(scalar2[, scalar3, … ])`
```javascript
two.inversion() // Scalar { data: [1n, 2n] }
```
#### Scalar subtraction
<!-- TODO
#### `Scalar.conjugation(scalar)`
##### `Scalar.subtraction(scalar1, scalar2[, … ])`
#### `scalar.conjugation()`
-->
##### `scalar1.subtraction(scalar2[, scalar3, … ])`
#### Scalar multiplication
##### `Scalar.multiplication(scalar1, scalar2[, scalar3, … ])`
##### `scalar1.multiplication(scalar2[, scalar3, … ])`
#### Scalar division
##### `Scalar.division(scalar1, scalar2[, scalar3, … ])`
##### `scalar1.division(scalar2[, scalar3, … ])`
#### Scalar negation
##### `Scalar.negation(scalar)`
##### `scalar.negation()`
#### Scalar inversion
##### `Scalar.inversion(scalar)`
##### `scalar.inversion()`
#### Scalar conjugation
##### `Scalar.conjugation(scalar)`
##### `scalar.conjugation()`
### Real
Inherits everything from [Scalar](#scalar).
Inherits everything from [Scalar](#scalar). Implements algebra of real numbers.

@@ -796,4 +609,3 @@ ```javascript

![Mandelbrot Set](http://g14n.info/algebra/images/Mandelbrot.gif)
[OnQuaternionsAndOctonions](http://g14n.info/algebra/images/Cover-OnQuaternionsAndOctonions.png)
![Mandelbrot Set](http://g14n.info/algebra/images/Mandelbrot.gif){:.responsive}

@@ -834,3 +646,3 @@ The first thing I noticed when I started to study the Complex numbers is

The real plane.
The *Cartesian Plane*.

@@ -911,4 +723,2 @@ ```javascript

A *Vector* class inherits everything from [Tensor](#tensor).
#### `VectorSpace(Scalar)(dimension)`

@@ -1013,4 +823,2 @@

A *Matrix* class inherits everything from [Tensor](#tensor).
#### `MatrixSpace(Scalar)(numRows[, numCols])`

@@ -1052,97 +860,2 @@

### Tensor
#### `TensorSpace(Scalar)(indices)`
#### `Tensor.one`
#### `Tensor.zero`
#### `tensor.data`
#### Tensor indices
##### `Tensor.indices`
##### `tensor.indices`
#### Tensor order
It represents the number of varying indices.
* A scalar has order 0.
* A vector has order 1.
* A matrix has order 2.
##### `Tensor.order`
##### `tensor.order`
#### `Tensor.contains(tensor1, tensor2[, tensor3, … ])`
#### Tensor equality
```javascript
const T2x2x2 = TensorSpace(Real)([2, 2, 2])
const tensor1 = new T2x2x2([1, 2, 3, 4, 5, 6, 7, 8])
const tensor2 = new T2x2x2([2, 3, 4, 5, 6, 7, 8, 9])
```
##### `Tensor.equality(tensor1, tensor2)`
```javascript
T2x2x2.equality(tensor1, tensor1) // true
T2x2x2.equality(tensor1, tensor2) // false
```
##### `tensor1.equality(tensor2)`
```javascript
tensor1.equality(tensor1) // true
tensor1.equality(tensor2) // false
```
#### Tensor disequality
#### `Tensor.disequality(tensor1, tensor2)`
##### `tensor1.disequality(tensor2)`
#### Tensor addition
##### `Tensor.addition(tensor1, tensor2[, tensor3, … ])`
##### `tensor1.addition(tensor2[, tensor3, … ])`
#### Tensor subtraction
##### `Tensor.subtraction(tensor1, tensor2[, tensor3, … ])`
##### `tensor1.subtraction(tensor2[, tensor3, … ])`
#### Tensor product
##### `Tensor.product(tensor1, tensor2)`
##### `tensor1.product(tensor2)`
#### Tensor contraction
##### `Tensor.contraction()`
##### `tensor.contraction()`
#### Tensor negation
##### `Tensor.negation(tensor1)`
##### `tensor.negation()`
#### Tensor scalar multiplication
##### `Tensor.scalarMultiplication(tensor, scalar)`
##### `tensor.scalarMultiplication(scalar)`
## License

@@ -1149,0 +862,0 @@

const CayleyDickson = require('cayley-dickson')
const createScalar = require('./createScalar')
const no = require('not-defined')
const Ring = require('./Ring.js')
/**

@@ -11,3 +12,3 @@ * A composition algebra is one of ℝ, ℂ, ℍ, O:

*
* @param {Object} field
* @param {Object} ringDefinition
* @param {Number} [num] of CayleyDickson construction iterations. Can be 1, 2, 4 or 8.

@@ -18,3 +19,3 @@ *

function CompositionAlgebra (field, num) {
function CompositionAlgebra (ringDefinition, num) {
if (no(num)) num = 1

@@ -28,5 +29,5 @@

return createScalar(CayleyDickson(field, logBase2))
return Ring(CayleyDickson(ringDefinition, logBase2))
}
module.exports = CompositionAlgebra
const determinant = require('laplace-determinant')
const inherits = require('inherits')
const itemsPool = require('./itemsPool')
const matrixMultiplication = require('matrix-multiplication')
const multiplication = require('matrix-multiplication')
const multiDimArrayIndex = require('multidim-array-index')
const no = require('not-defined')
const operators = require('./operators.json')
const staticProps = require('static-props')
const TensorSpace = require('./TensorSpace')
const tensorContraction = require('tensor-contraction')
const toData = require('./toData')
const itemsPool = require('./itemsPool.js')
const toData = require('./toData.js')
/**

@@ -28,37 +25,85 @@ * Space of m x n matrices

function MatrixSpace (Scalar) {
const contraction = tensorContraction.bind(null, Scalar.addition)
const {
addition,
equality,
subtraction
} = Scalar
const contraction = tensorContraction.bind(null, addition)
const enumerable = true
/**
* @param {Number} numRows
* @param {Number} [numCols] defaults to a square matrix.
* @param {Number} [numCols] if not defined it defaults to a square matrix.
*
* @returns {Function} Matrix
* @returns {class} Matrix
*/
return function (numRows, numCols) {
// numCols defaults to numRows
if (no(numCols)) numCols = numRows
if (typeof numCols === 'undefined') numCols = numRows
const dimension = numRows * numCols
const indices = [numRows, numCols]
const isSquare = (numRows === numCols)
const indices = [numRows, numCols]
const AbstractMatrix = TensorSpace(Scalar)(indices)
/**
* Determinant computation is defined only if it is a square matrix.
*/
function computeDeterminant (matrix) {
const data = toData(matrix)
return determinant(data, Scalar, numRows)
}
/**
* Calculates the matrix trace.
*
* https://en.wikipedia.org/wiki/Trace_(linear_algebra)
*
* @param {Object|Array} matrix
*
* @returns {Object} scalar
* Matrix addition is the scalar addition for every item.
*/
function trace (matrix) {
const matrixData = toData(matrix)
function matrixAddition (matrix1, matrix2) {
const matrixData1 = toData(matrix1)
const matrixData2 = toData(matrix2)
return contraction([0, 1], indices, matrixData)
const result = []
for (let i = 0; i < dimension; i++) {
result.push(addition(matrixData1[i], matrixData2[i]))
}
return result
}
/**
* Matrix equality checks that all elements are equal.
* It also tries to check if numCols and numRows correspond.
*/
function matrixEquality (matrix1, matrix2) {
if (matrix1 instanceof Matrix && matrix2 instanceof Matrix) {
if (matrix1.numCols !== matrix2.numCols) {
return false
}
if (matrix1.numRows !== matrix2.numRows) {
return false
}
}
const matrixData1 = toData(matrix1)
const matrixData2 = toData(matrix2)
if (matrixData1.length !== matrixData2.length) {
return false
}
for (let i = 0; i < dimension; i++) {
if (!equality(matrixData1[i], matrixData2[i])) {
return false
}
}
return true
}
/**
* Multiplies row by column to the right.

@@ -71,7 +116,7 @@ *

function multiplication (leftMatrix, rightMatrix) {
function matrixMultiplication (leftMatrix, rightMatrix) {
const leftMatrixData = toData(leftMatrix)
const rightMatrixData = toData(rightMatrix)
const rowByColumnMultiplication = matrixMultiplication(Scalar)(numCols)
const rowByColumnMultiplication = multiplication(Scalar)(numCols)

@@ -82,2 +127,35 @@ return rowByColumnMultiplication(leftMatrixData, rightMatrixData)

/**
* Matrix subtraction is the scalar subtraction for every item.
*/
function matrixSubtraction (matrix1, matrix2) {
const matrixData1 = toData(matrix1)
const matrixData2 = toData(matrix2)
const result = []
for (let i = 0; i < dimension; i++) {
result.push(subtraction(matrixData1[i], matrixData2[i]))
}
return result
}
/**
* Calculates the matrix trace.
*
* @see {@link https://en.wikipedia.org/wiki/Trace_(linear_algebra)}
*
* @param {Object|Array} matrix
*
* @returns {Object} scalar
*/
function computeTrace (matrix) {
const matrixData = toData(matrix)
return contraction([0, 1], indices, matrixData)
}
/**
* Calculates the transpose of a matrix.

@@ -110,92 +188,108 @@ *

function Matrix (data) {
AbstractMatrix.call(this, data)
staticProps(this)({
numCols,
numRows
})
function computeDeterminant () {
const det = determinant(data, Scalar, numRows)
return new Scalar(det)
}
if (isSquare) {
class Matrix {
constructor (data) {
staticProps(this)({
trace: trace(data)
})
data,
numCols,
numRows
}, enumerable)
staticProps(this)({
determinant: computeDeterminant,
det: computeDeterminant
Scalar,
tr: () => this.transposed
})
}
function transposed () {
const result = transpose(data)
const VectorSpace = itemsPool.get('VectorSpace')
if (isSquare) {
staticProps(this)({
determinant: () => {
const result = computeDeterminant(this)
if (numRows === 1) {
const Vector = VectorSpace(Scalar)(numCols)
return new Vector(result)
} else {
const Matrix = MatrixSpace(Scalar)(numCols, numRows)
return new Matrix(result)
return new Scalar(result)
},
trace: () => {
const result = computeTrace(this)
return new Scalar(result)
}
})
}
}
staticProps(this)({
transposed,
tr: transposed
})
}
equality (matrix) {
return matrixEquality(this, matrix)
}
inherits(Matrix, AbstractMatrix)
get transposed () {
const transposedElements = transpose(this)
if (isSquare) {
Matrix.trace = trace
}
// Get a class matrix in the transposed matrix space.
// Note that numCols and numRows order as arguments is inverted.
const TransposedMatrix = MatrixSpace(Scalar)(numCols, numRows)
Matrix.prototype.multiplication = function (rightMatrix) {
const leftMatrixData = this.data
const result = multiplication(leftMatrixData, rightMatrix)
return new TransposedMatrix(transposedElements)
}
const rightNumRows = numCols
const rightNumCols = result.length / rightNumRows
addition (matrix) {
const result = matrixAddition(this, matrix)
const Matrix = MatrixSpace(Scalar)(rightNumRows, rightNumCols)
return new Matrix(result)
}
return new Matrix(result)
}
multiplication (matrix) {
const result = matrixMultiplication(this, matrix)
// Static operators.
return new Matrix(result)
}
Matrix.multiplication = multiplication
Matrix.transpose = transpose
subtraction (matrix) {
const result = matrixSubtraction(this, matrix)
// Aliases
return new Matrix(result)
}
}
Matrix.tr = Matrix.transpose
Matrix.mul = Matrix.multiplication
// Method aliases.
Matrix.prototype.add = Matrix.prototype.addition
Matrix.prototype.eq = Matrix.prototype.equality
Matrix.prototype.equal = Matrix.prototype.equality
Matrix.prototype.mul = Matrix.prototype.multiplication
Matrix.prototype.sub = Matrix.prototype.subtraction
operators.group.forEach((operator) => {
operators.aliasesOf[operator].forEach((alias) => {
Matrix[alias] = Matrix[operator]
Matrix.prototype[alias] = Matrix.prototype[operator]
})
staticProps(Matrix)({
numCols,
numRows
})
operators.group.forEach((operator) => {
Matrix[operator] = AbstractMatrix[operator]
// Matrix static operators.
staticProps(Matrix)({
addition: () => matrixAddition,
equality: () => matrixEquality,
multiplication: () => matrixMultiplication,
subtraction: () => matrixSubtraction,
transpose: () => transpose
})
staticProps(Matrix)({
numCols,
numRows
add: Matrix.addition,
eq: Matrix.equality,
mul: Matrix.multiplication,
sub: Matrix.subtraction,
tr: Matrix.transpose
})
if (isSquare) {
Matrix.prototype.det = Matrix.prototype.determinant
staticProps(Matrix)({
determinant: () => computeDeterminant,
trace: () => computeTrace
})
staticProps(Matrix)({
det: Matrix.determinant
})
}
return Matrix

@@ -202,0 +296,0 @@ }

@@ -19,7 +19,5 @@ const realField = {

//
// Hence we need to aproximate equality with an epsilon.
// Hence we need to approximate equality with an epsilon.
const epsilon = 0.000000000001
return Math.abs(a - b) < epsilon
return Math.abs(a - b) < Number.EPSILON
},

@@ -26,0 +24,0 @@ addition: (a, b) => a + b,

@@ -1,14 +0,7 @@

const algebraRing = require('algebra-ring')
const createScalar = require('./createScalar')
const CompositionAlgebra = require('./CompositionAlgebra.js')
/**
* Create a Scalar.
*/
function Scalar (neutralElements, operators) {
const ring = algebraRing(neutralElements, operators)
return createScalar(ring)
function Scalar (ringDefinition) {
return CompositionAlgebra(ringDefinition)
}
module.exports = Scalar

@@ -1,7 +0,4 @@

const inherits = require('inherits')
const itemsPool = require('./itemsPool')
const matrixMultiplication = require('matrix-multiplication')
const operators = require('./operators.json')
const staticProps = require('static-props')
const TensorSpace = require('./TensorSpace')
const toData = require('./toData')

@@ -24,6 +21,11 @@

function VectorSpace (Scalar) {
const addition = Scalar.addition
const multiplication = Scalar.multiplication
const subtraction = Scalar.subtraction
const {
addition,
equality,
multiplication,
subtraction
} = Scalar
const enumerable = true
/**

@@ -36,6 +38,2 @@ * @param {Number} dimension

return function (dimension) {
const indices = [dimension]
const AbstractVector = TensorSpace(Scalar)(indices)
/**

@@ -64,3 +62,3 @@ * Computes the cross product of two vectors.

let vector = []
const vector = []

@@ -76,5 +74,6 @@ vector.push(subtraction(multiplication(uy, vz), multiplication(uz, vy)))

* Multiply a column vector by matrix on right side
* @param {Object|Array} vector
*
* @returns {Object} scalar
* @param leftVector
* @param rightMatrix
*/

@@ -118,3 +117,3 @@

*
* https://en.wikipedia.org/wiki/Dot_product
* @see {@link https://en.wikipedia.org/wiki/Dot_product}
*

@@ -128,3 +127,2 @@ * @param {Object|Array} vector1

function scalarProduct (vector1, vector2) {
// TODO use tensor product and then contraction (trace)
const vectorData1 = toData(vector1)

@@ -147,93 +145,173 @@ const vectorData2 = toData(vector2)

/**
* Vector element.
* Vector addition is the scalar addition for every coordinate.
*/
function Vector (data) {
AbstractVector.call(this, data)
function vectorAddition (vector1, vector2) {
const vectorData1 = toData(vector1)
const vectorData2 = toData(vector2)
staticProps(this)({
norm: norm(data),
dimension
})
const result = []
for (let i = 0; i < dimension; i++) {
result.push(addition(vectorData1[i], vectorData2[i]))
}
return result
}
inherits(Vector, AbstractVector)
/**
* Vector equality checks that all coordinates are equal.
*/
staticProps(Vector)({ dimension })
function vectorEquality (vector1, vector2) {
const vectorData1 = toData(vector1)
const vectorData2 = toData(vector2)
Vector.prototype.scalarProduct = function (vector) {
const data = this.data
if (vectorData1.length !== vectorData2.length) {
return false
}
const result = scalarProduct(data, vector)
for (let i = 0; i < dimension; i++) {
if (!equality(vectorData1[i], vectorData2[i])) {
return false
}
}
return new Scalar(result)
return true
}
// Cross product is defined only in dimension 3.
function crossProductMethod (vector) {
const data = this.data
/**
* Vector subtraction is the scalar subtraction for every coordinate.
*/
const result = crossProduct(data, vector)
function vectorSubtraction (vector1, vector2) {
const vectorData1 = toData(vector1)
const vectorData2 = toData(vector2)
return new Vector(result)
}
const result = []
if (dimension === 3) {
Vector.crossProduct = crossProduct
for (let i = 0; i < dimension; i++) {
result.push(subtraction(vectorData1[i], vectorData2[i]))
}
Vector.prototype.crossProduct = crossProductMethod
Vector.prototype.cross = crossProductMethod
return result
}
Vector.prototype.multiplication = function (rightMatrix) {
const MatrixSpace = itemsPool.get('MatrixSpace')
/**
* Vector element.
*/
const leftVectorData = this.data
const result = multiplicationByMatrix(leftVectorData, rightMatrix)
class Vector {
constructor (data) {
staticProps(this)({ data }, enumerable)
// TODO rightNumRows equals dimension
// but the vector should be transposed.
// Add transpose operator for vectors, then use it implicitly.
const rightNumRows = dimension
const rightNumCols = result.length / rightNumRows
staticProps(this)({
norm: norm(data),
dimension,
Scalar
})
const Matrix = MatrixSpace(Scalar)(rightNumRows, rightNumCols)
// Method aliases.
return new Matrix(result)
staticProps(this)({
add: () => this.addition,
eq: () => this.equality,
equals: () => this.equality,
mul: () => this.multiplication,
scalar: () => this.scalarProduct,
sub: () => this.subtraction
})
}
addition (vector) {
const result = vectorAddition(this, vector)
return new Vector(result)
}
equality (vector) {
return vectorEquality(this, vector)
}
/**
* Multiplication of a vector by a right matrix.
*
* Actually the vector it is supposed to be transposed, so it
* becomes a row-vector, while by convention all vectors are column-vectors,
* and after it is transposed, it can be multiplied by a right matrix.
*
* The transposition happens here implicitly.
*
* If you do not know what it means, do not worry. It is part of
* Geometry first course at the first year of University, and you can
* ignore it, since it has no consequences but it is hard to spot.
*
* I would like to thank and remember here in this comment, my awesome
* prof. of Geometry. Thank you, Monti Bragadin.
*/
multiplication (rightMatrix) {
const MatrixSpace = itemsPool.get('MatrixSpace')
const leftVectorData = this.data
const result = multiplicationByMatrix(leftVectorData, rightMatrix)
const rightNumRows = dimension
const rightNumCols = result.length / rightNumRows
const Matrix = MatrixSpace(Scalar)(rightNumRows, rightNumCols)
return new Matrix(result)
}
scalarProduct (vector) {
const result = scalarProduct(this, vector)
return new Scalar(result)
}
subtraction (vector) {
const result = vectorSubtraction(this, vector)
return new Vector(result)
}
}
// Static operators.
staticProps(Vector)({
dimension
}, enumerable)
Vector.multiplication = multiplicationByMatrix
Vector.norm = norm
Vector.scalarProduct = scalarProduct
// Vector static operators.
operators.comparison.forEach((operator) => {
Vector[operator] = AbstractVector[operator]
staticProps(Vector)({
addition: () => vectorAddition,
equality: () => vectorEquality,
norm: () => norm,
scalarProduct: () => scalarProduct,
subtraction: () => vectorSubtraction
})
operators.set.forEach((operator) => {
Vector[operator] = AbstractVector[operator]
staticProps(Vector)({
add: () => Vector.addition,
eq: () => Vector.equality,
scalar: () => Vector.scalarProduct,
sub: () => Vector.subtraction
})
operators.group.forEach((operator) => {
Vector[operator] = AbstractVector[operator]
})
function crossProductMethod (vector) {
const data = this.data
// Aliases
const result = crossProduct(data, vector)
Vector.mul = multiplicationByMatrix
Vector.prototype.mul = Vector.prototype.multiplication
return new Vector(result)
}
const myOperators = ['scalarProduct'].concat(operators.group)
if (dimension === 3) {
Vector.prototype.cross = crossProductMethod
Vector.prototype.crossProduct = crossProductMethod
myOperators.forEach((operator) => {
operators.aliasesOf[operator].forEach((alias) => {
Vector[alias] = Vector[operator]
Vector.prototype[alias] = Vector.prototype[operator]
staticProps(Vector)({
crossProduct: () => crossProduct,
cross: () => crossProduct
})
})
if (dimension === 3) {
Vector.cross = crossProduct
}

@@ -240,0 +318,0 @@

/* eslint-disable indent */
/* eslint-env mocha */
/* global BigInt */
describe('API', () => {
const algebra = require('algebra')
const C = algebra.C
const C2x2 = algebra.C2x2
const Complex = algebra.Complex
const H = algebra.H
const Quaternion = algebra.Quaternion
const R = algebra.R
const R2 = algebra.R2
const R3 = algebra.R3
const R2x2 = algebra.R2x2
const Real = algebra.Real
const CompositionAlgebra = algebra.CompositionAlgebra
const MatrixSpace = algebra.MatrixSpace
const TensorSpace = algebra.TensorSpace
const VectorSpace = algebra.VectorSpace

@@ -36,3 +28,3 @@ const Boole = algebra.Boole

vector1.addition(vector1, vector1).equality([3, 6]).should.be.ok()
vector1.addition(vector1).equality([2, 4]).should.be.ok()

@@ -88,124 +80,35 @@ vector1.data.should.deepEqual([1, 2])

describe('Scalar', () => {
const hexSum = (hex1, hex2) => {
const dec1 = parseInt(hex1, 16) % 256
const dec2 = parseInt(hex2, 16) % 256
const hexResult = parseInt((dec1 + dec2) % 256, 10).toString(16)
return hexResult.padStart(2, '0')
function greatCommonDivisor (a, b) {
if (b === BigInt(0)) {
return a
} else {
return greatCommonDivisor(b, a % b)
}
}
const splitColor = (color) => {
const r = color.substring(0, 2)
const g = color.substring(2, 4)
const b = color.substring(4, 6)
function normalizeRational ([numerator, denominator]) {
const divisor = greatCommonDivisor(numerator, denominator)
return [r, g, b]
return [numerator / divisor, denominator / divisor]
}
const colorSum = (color1, color2) => {
const [r1, g1, b1] = splitColor(color1)
const [r2, g2, b2] = splitColor(color2)
const r = hexSum(r1, r2)
const g = hexSum(g1, g2)
const b = hexSum(b1, b2)
return [r, g, b].join('')
}
const hexMul = (hex1, hex2) => {
const dec1 = parseInt(hex1, 16) % 256
const dec2 = parseInt(hex2, 16) % 256
const hexResult = parseInt((dec1 * dec2) / 255, 10).toString(16)
return hexResult.padStart(2, '0')
}
const colorMul = (color1, color2) => {
const [r1, g1, b1] = splitColor(color1)
const [r2, g2, b2] = splitColor(color2)
const r = hexMul(r1, r2)
const g = hexMul(g1, g2)
const b = hexMul(b1, b2)
return [r, g, b].join('')
}
describe('Color space example', () => {
describe('colorSum()', () => {
it('is well defined', () => {
colorSum('00ff00', '0000ff').should.equal('00ffff')
})
})
const Rational = algebra.Scalar({
zero: [BigInt(0), BigInt(1)],
one: [BigInt(1), BigInt(1)],
equality: ([n1, d1], [n2, d2]) => (n1 * d2 === n2 * d1),
// eslint-disable-next-line
contains: ([n, d]) => (typeof n === 'bigint' && typeof d === 'bigint'),
addition: ([n1, d1], [n2, d2]) => normalizeRational([n1 * d2 + n2 * d1, d1 * d2]),
negation: ([n, d]) => ([-n, d]),
multiplication: ([n1, d1], [n2, d2]) => normalizeRational([n1 * n2, d1 * d2]),
inversion: ([n, d]) => ([d, n])
})
const RGB = algebra.Scalar(
[ '000000', 'ffffff' ],
{
equality: (a, b) => a === b,
contains: (color) => {
const [r, g, b] = splitColor(color)
const half = new Rational([BigInt(1), BigInt(2)])
const two = new Rational([BigInt(2), BigInt(1)])
return (parseInt(r, 16) < 256) && (parseInt(g, 16) < 256) && (parseInt(b, 16) < 256)
},
addition: colorSum,
negation: (color) => {
const [r, g, b] = splitColor(color)
const decR = parseInt(r, 16)
const decG = parseInt(g, 16)
const decB = parseInt(b, 16)
const minusR = decR === 0 ? 0 : 255 - decR
const minusG = decG === 0 ? 0 : 255 - decG
const minusB = decB === 0 ? 0 : 255 - decB
const hexMinusR = parseInt(minusR, 10).toString(16)
const hexMinusG = parseInt(minusG, 10).toString(16)
const hexMinusB = parseInt(minusB, 10).toString(16)
const paddedMinusR = hexMinusR.padStart(2, '0')
const paddedMinusG = hexMinusG.padStart(2, '0')
const paddedMinusB = hexMinusB.padStart(2, '0')
return `${paddedMinusR}${paddedMinusG}${paddedMinusB}`
},
multiplication: colorMul,
inversion: (color) => {
const [r, g, b] = splitColor(color)
const decR = parseInt(r, 16)
const decG = parseInt(g, 16)
const decB = parseInt(b, 16)
const invR = parseInt(255 * 255 / decR, 10).toString(16)
const invG = parseInt(255 * 255 / decG, 10).toString(16)
const invB = parseInt(255 * 255 / decB, 10).toString(16)
const paddedInvR = invR.padStart(2, '0')
const paddedInvG = invG.padStart(2, '0')
const paddedInvB = invB.padStart(2, '0')
return `${paddedInvR}${paddedInvG}${paddedInvB}`
}
}
)
const green = new RGB('00ff00')
const blue = new RGB('0000ff')
const cyan = green.add(blue)
describe('Color instances example', () => {
it('works', () => {
cyan.data.should.be.equal('00ffff')
})
})
describe('Scalar.one', () => {
it('is a static attribute', () => {
RGB.one.should.be.equal('ffffff')
Rational.one[0].should.be.deepEqual(BigInt(1))
Rational.one[1].should.be.deepEqual(BigInt(1))
})

@@ -216,98 +119,157 @@ })

it('is a static attribute', () => {
RGB.zero.should.be.equal('000000')
Rational.zero[0].should.be.equal(BigInt(0))
Rational.zero[1].should.be.equal(BigInt(1))
})
})
describe('Scalar.order', () => {
it('is a static attribute', () => {
RGB.order.should.be.equal(0)
describe('scalar.data', () => {
it('works', () => {
half.data[0].should.be.eql(BigInt(1))
half.data[1].should.be.eql(BigInt(2))
})
})
describe('scalar.order', () => {
it('is an attribute', () => {
green.order.should.eql(0)
describe('Scalar.contains', () => {
it('works', () => {
Rational.contains(half).should.be.ok()
Rational.contains([BigInt(1), BigInt(2)]).should.be.ok()
})
})
describe('data', () => {
it('works')
describe('scalar.belongsTo', () => {
it('works', () => {
half.belongsTo(Rational).should.be.ok()
})
})
describe('contains', () => {
it('works')
describe('Scalar.equality', () => {
it('works', () => {
Rational.equality(half, [BigInt(5), BigInt(10)])
})
})
describe('belongsTo', () => {
it('works')
describe('scalar.equality', () => {
it('works', () => {
half.equality([BigInt(2), BigInt(4)])
})
})
describe('equality', () => {
it('works')
describe('Scalar.disequality', () => {
it('works', () => {
Rational.disequality(half, two).should.be.ok()
})
})
describe('disequality', () => {
it('works')
describe('scalar.disequality', () => {
it('works', () => {
half.disequality(two).should.be.ok()
})
})
describe('addition', () => {
it('works')
describe('Scalar.addition', () => {
it('works', () => {
const result = Rational.addition(half, two)
result[0].should.eql(BigInt(5))
result[1].should.eql(BigInt(2))
})
})
describe('subtraction', () => {
it('works')
describe('scalar.addition', () => {
it('works', () => {
const result = half.addition(two)
result.data[0].should.eql(BigInt(5))
result.data[1].should.eql(BigInt(2))
})
})
describe('multiplication', () => {
it('works')
describe('Scalar.subtraction', () => {
it('works', () => {
const result = Rational.subtraction(two, half)
result[0].should.eql(BigInt(3))
result[1].should.eql(BigInt(2))
})
})
describe('division', () => {
it('works')
describe('scalar.subtraction', () => {
it('works', () => {
const result = two.subtraction(half)
result.data[0].should.eql(BigInt(3))
result.data[1].should.eql(BigInt(2))
})
})
describe('negation', () => {
it('works')
describe('Scalar.multiplication', () => {
it('works', () => {
const result = Rational.multiplication(half, two)
result[0].should.eql(BigInt(1))
result[1].should.eql(BigInt(1))
})
})
describe('inversion', () => {
it('works')
describe('scalar.multiplication', () => {
it('works', () => {
const result = half.multiplication(two)
result.data[0].should.eql(BigInt(1))
result.data[1].should.eql(BigInt(1))
})
})
describe('conjugation', () => {
it('works')
describe('Scalar.division', () => {
it('works', () => {
const result = Rational.division(half, two)
result[0].should.eql(BigInt(1))
result[1].should.eql(BigInt(4))
})
})
})
describe('Cyclic', () => {
it('works', () => {
const Cyclic = algebra.Cyclic
describe('scalar.division', () => {
it('works', () => {
const result = half.division(two)
const elements = ' abcdefghijklmnopqrstuvwyxz0123456789'
result.data[0].should.eql(BigInt(1))
result.data[1].should.eql(BigInt(4))
})
})
const Alphanum = Cyclic(elements)
describe('Scalar.negation', () => {
it('works', () => {
const result = Rational.negation(two)
Alphanum.addition('a', 'b').should.eql('c')
result[0].should.eql(BigInt(-2))
result[1].should.eql(BigInt(1))
})
})
const x = new Alphanum('a')
describe('scalar.negation', () => {
it('works', () => {
const result = two.negation()
const y = x.add('c', 'a', 't')
.mul('i', 's')
.add('o', 'n')
.sub('t', 'h', 'e')
.div('t', 'a', 'b', 'l', 'e')
result.data[0].should.eql(BigInt(-2))
result.data[1].should.eql(BigInt(1))
})
})
y.data.should.eql('s')
describe('Scalar.inversion', () => {
it('works', () => {
const result = Rational.inversion(two)
const VectorStrings2 = algebra.VectorSpace(Alphanum)(2)
const MatrixStrings2x2 = algebra.MatrixSpace(Alphanum)(2)
result[0].should.eql(BigInt(1))
result[1].should.eql(BigInt(2))
})
})
const vectorOfStrings = new VectorStrings2(['o', 'k'])
const matrixOfStrings = new MatrixStrings2x2(['c', 'o',
'o', 'l'])
matrixOfStrings.mul(vectorOfStrings)
.data.should.deepEqual(['x', 'y'])
describe('scalar.inversion', () => {
it('works', () => {
const result = two.inversion()
vectorOfStrings.mul(matrixOfStrings)
.data.should.deepEqual(['x', 'y'])
result.data[0].should.eql(BigInt(1))
result.data[1].should.eql(BigInt(2))
})
})

@@ -346,46 +308,2 @@ })

describe('Common spaces', () => {
describe('R', () => {
it('is an alias of Real', () => {
R.should.be.eql(Real)
})
})
describe('R2', () => {
it('is an alias of VectorSpace(Real)(2)', () => {
R2.should.be.eql(VectorSpace(Real)(2))
})
})
describe('R3', () => {
it('is an alias of VectorSpace(Real)(3)', () => {
R3.should.be.eql(VectorSpace(Real)(3))
})
})
describe('R2x2', () => {
it('is an alias of MatrixSpace(Real)(2)', () => {
R2x2.should.be.eql(MatrixSpace(Real)(2))
})
})
describe('C', () => {
it('is an alias of Complex', () => {
C.should.be.eql(Complex)
})
})
describe('C2x2', () => {
it('is an alias of MatrixSpace(Complex)(2)', () => {
C2x2.should.be.eql(MatrixSpace(Complex)(2))
})
})
describe('H', () => {
it('is an alias of Quaternion', () => {
H.should.be.eql(Quaternion)
})
})
})
describe('Vector', () => {

@@ -447,19 +365,2 @@ describe('Vector.dimension', () => {

})
describe('Tensor', () => {
describe('equality', () => {
it('works', () => {
const T2x2x2 = TensorSpace(Real)([2, 2, 2])
const tensor1 = new T2x2x2([1, 2, 3, 4, 5, 6, 7, 8])
const tensor2 = new T2x2x2([2, 3, 4, 5, 6, 7, 8, 9])
T2x2x2.equality(tensor1, tensor1).should.be.ok()
T2x2x2.equality(tensor1, tensor2).should.not.be.ok()
tensor1.equality(tensor1).should.be.ok()
tensor1.equality(tensor2).should.not.be.ok()
})
})
})
})

@@ -1,13 +0,13 @@

var algebra = require('algebra')
/* eslint-env mocha */
var C = algebra.Complex
const algebra = require('algebra')
var methodBinaryOperator = require('./features/methodBinaryOperator')
var methodUnaryOperator = require('./features/methodUnaryOperator')
var staticBinaryOperator = require('./features/staticBinaryOperator')
var staticUnaryOperator = require('./features/staticUnaryOperator')
const C = algebra.Complex
const methodBinaryOperator = require('./features/methodBinaryOperator')
const methodUnaryOperator = require('./features/methodUnaryOperator')
const staticBinaryOperator = require('./features/staticBinaryOperator')
const staticUnaryOperator = require('./features/staticUnaryOperator')
describe('Complex', () => {
var operator
describe('zero', () => {

@@ -26,3 +26,3 @@ it('is static', () => {

describe('addition', () => {
operator = 'addition'
const operator = 'addition'

@@ -35,3 +35,3 @@ it('is a static method', staticBinaryOperator(C, operator, [2, 1], [2, 3], [4, 4]))

describe('subtraction', () => {
operator = 'subtraction'
const operator = 'subtraction'

@@ -44,3 +44,3 @@ it('is a static method', staticBinaryOperator(C, operator, [2, 1], [2, 3], [0, -2]))

describe('multiplication', () => {
operator = 'multiplication'
const operator = 'multiplication'

@@ -53,3 +53,3 @@ it('is a static method', staticBinaryOperator(C, operator, [2, 1], [2, -1], [5, 0]))

describe('division', () => {
operator = 'division'
const operator = 'division'

@@ -62,3 +62,3 @@ it('is a static method', staticBinaryOperator(C, operator, [2, 4], [2, 0], [1, 2]))

describe('negation', () => {
operator = 'negation'
const operator = 'negation'

@@ -71,3 +71,3 @@ it('is a static method', staticUnaryOperator(C, operator, [-2, 1], [2, -1]))

describe('conjugation', () => {
operator = 'conjugation'
const operator = 'conjugation'

@@ -74,0 +74,0 @@ it('is a static method', staticUnaryOperator(C, operator, [2, 1], [2, -1]))

@@ -1,4 +0,6 @@

var CompositionAlgebra = require('../src/CompositionAlgebra')
var realField = require('../src/realField')
/* eslint-env mocha */
const CompositionAlgebra = require('../src/CompositionAlgebra')
const realField = require('../src/realField')
describe('CompositionAlgebra', () => {

@@ -12,6 +14,6 @@ it('checks n is 1, 2, 4 or 8', () => {

it('has signature (field, num)', () => {
var R = CompositionAlgebra(realField, 1)
var C = CompositionAlgebra(realField, 2)
var H = CompositionAlgebra(realField, 4)
var O = CompositionAlgebra(realField, 8)
const R = CompositionAlgebra(realField, 1)
const C = CompositionAlgebra(realField, 2)
const H = CompositionAlgebra(realField, 4)
const O = CompositionAlgebra(realField, 8)

@@ -25,8 +27,8 @@ R.should.be.instanceOf(Function)

it('returns a Scalar class', () => {
var R = CompositionAlgebra(realField, 1)
var C = CompositionAlgebra(realField, 2)
const R = CompositionAlgebra(realField, 1)
const C = CompositionAlgebra(realField, 2)
R.addition(2, 3).should.be.eql(5)
var x = new R(2)
const x = new R(2)
x.data.should.be.eql(2)

@@ -38,3 +40,3 @@

var z = new C([1, 2])
const z = new C([1, 2])
z.data.should.be.eql([1, 2])

@@ -41,0 +43,0 @@

@@ -17,5 +17,5 @@ /**

return function mutatorBinaryOperatorTest () {
var scalar = new Scalar(operand1)
const scalar = new Scalar(operand1)
var result = scalar[operator](operand2)
const result = scalar[operator](operand2)

@@ -22,0 +22,0 @@ result.data.should.eql(resultData)

@@ -16,5 +16,5 @@ /**

return function mutatorUnaryOperatorTest () {
var scalar = new Scalar(operand)
const scalar = new Scalar(operand)
var result = scalar[operator]()
const result = scalar[operator]()

@@ -21,0 +21,0 @@ result.data.should.eql(resultData)

/* eslint-disable indent */
/* eslint-env mocha */
describe('MatrixSpace', () => {
var algebra = require('algebra')
const algebra = require('algebra')
const notDefined = require('not-defined')
var notDefined = require('not-defined')
const MatrixSpace = algebra.MatrixSpace
const Real = algebra.Real
var MatrixSpace = algebra.MatrixSpace
var Real = algebra.Real
const methodBinaryOperator = require('./features/methodBinaryOperator')
const staticBinaryOperator = require('./features/staticBinaryOperator')
const staticUnaryOperator = require('./features/staticUnaryOperator')
var methodBinaryOperator = require('./features/methodBinaryOperator')
var staticBinaryOperator = require('./features/staticBinaryOperator')
var staticUnaryOperator = require('./features/staticUnaryOperator')
describe('MatrixSpace', () => {
const R2x3 = MatrixSpace(Real)(2, 3)
const R2x2 = MatrixSpace(Real)(2)
const R3x2 = MatrixSpace(Real)(3, 2)
var R1x4 = MatrixSpace(Real)(1, 4)
var R2x3 = MatrixSpace(Real)(2, 3)
var R2x2 = MatrixSpace(Real)(2)
var R3x2 = MatrixSpace(Real)(3, 2)
it('has signature (Scalar)(numRows, numCols)', () => {

@@ -30,12 +29,12 @@ R2x3.numRows.should.be.eql(2)

var matrix1 = new R2x2([ 2, 3,
1, 1 ])
var matrix2 = new R2x2([ 0, 1,
-1, 0 ])
var matrix3 = new R2x3([ 0, 1, 2,
-2, 1, 0 ])
const matrix1 = new R2x2([2, 3,
1, 1])
const matrix2 = new R2x2([0, 1,
-1, 0])
const matrix3 = new R2x3([0, 1, 2,
-2, 1, 0])
describe('data', () => {
it('is enumerable', () => {
matrix1.propertyIsEnumerable('data').should.be.ok()
Object.prototype.propertyIsEnumerable.call(matrix1, 'data').should.be.ok()
})

@@ -79,125 +78,71 @@

describe('addition()', () => {
var operator = 'addition'
const operator = 'addition'
it('is a static method', staticBinaryOperator(R2x2, operator,
[ 2, 3,
1, 1 ],
[ 0, 1,
-1, 0 ],
[ 2, 4,
0, 1 ]
))
[2, 3,
1, 1],
[0, 1,
-1, 0],
[2, 4,
0, 1]
))
it('is a class method', methodBinaryOperator(R2x2, operator,
[ 2, 3,
1, 1 ],
[ 0, 1,
-1, 0 ],
[ 2, 4,
0, 1 ]
[2, 3,
1, 1],
[0, 1,
-1, 0],
[2, 4,
0, 1]
))
it('accepts multiple arguments', () => {
R2x2.addition([ 2, 3,
1, 1 ],
[ 0, 1,
-1, 0 ],
[ -2, -4,
0, -1 ]).should.deepEqual([0, 0,
0, 0])
var matrix = new R2x2([ 2, 3,
1, 1 ])
matrix.addition([ 0, 1,
-1, 0 ],
[ -2, -4,
0, -1 ]).data.should.deepEqual([0, 0,
0, 0])
})
})
describe('subtraction()', () => {
var operator = 'subtraction'
const operator = 'subtraction'
it('is a static method', staticBinaryOperator(R2x2, operator,
[2, 3,
1, 1],
[0, 1,
-1, 0],
[2, 2,
2, 1]
[2, 3,
1, 1],
[0, 1,
-1, 0],
[2, 2,
2, 1]
))
it('is a class method', methodBinaryOperator(R2x2, operator,
[2, 3,
1, 1],
[0, 1,
-1, 0],
[2, 2,
2, 1]
[2, 3,
1, 1],
[0, 1,
-1, 0],
[2, 2,
2, 1]
))
it('accepts multiple arguments', () => {
R2x2.subtraction([2, 3,
1, 1],
[0, 1,
-1, 0],
[2, 4,
0, 1]).should.deepEqual([0, -2,
2, 0])
var matrix = new R2x2([2, 3,
1, 1])
matrix.subtraction([0, 1,
-1, 0],
[2, 4,
0, 1]).data.should.deepEqual([0, -2,
2, 0])
})
})
describe('multiplication()', () => {
var operator = 'multiplication'
const operator = 'multiplication'
it('is a static method', staticBinaryOperator(R3x2, operator,
[2, 3,
1, 1,
1, 1],
[0, 1, 1, 1,
-1, 0, 2, 3],
[-3, 2, 8, 11,
-1, 1, 3, 4,
-1, 1, 3, 4]
[2, 3,
1, 1,
1, 1],
[0, 1, 1, 1,
-1, 0, 2, 3],
[-3, 2, 8, 11,
-1, 1, 3, 4,
-1, 1, 3, 4]
))
it('is a class method', methodBinaryOperator(R2x2, operator,
[2, 3,
1, 1],
[0, 1,
-1, 0],
[-3, 2,
-1, 1]
[2, 3,
1, 1],
[0, 1,
-1, 0],
[-3, 2,
-1, 1]
))
it('accepts multiple arguments', () => {
R2x2.multiplication([1, 2,
3, 4],
[0, 1,
-1, 0],
[-1, 0,
0, 1]).should.deepEqual([-2, 1,
-4, 3])
var matrix = new R2x2([1, 2,
3, 4])
matrix.multiplication([0, 1,
-1, 0],
[-1, 0,
0, 1]).data.should.deepEqual([-2, 1,
-4, 3])
})
})
describe('trace()', () => {
var operator = 'trace'
const operator = 'trace'

@@ -209,3 +154,3 @@ it('is a static method', staticUnaryOperator(R2x2, operator,

it('is not available for no square matrices', () => {
it('is not available if it is not a square matrices', () => {
notDefined(R3x2.trace).should.be.ok()

@@ -217,12 +162,12 @@ })

it('is a static attribute', () => {
var matrix2x2 = new R2x2([1, 2,
5, 6])
const matrix2x2 = new R2x2([1, 2,
5, 6])
matrix2x2.trace.should.be.eql(7)
matrix2x2.trace.data.should.be.eql(7)
})
it('is not available for no square matrices', () => {
var matrix3x2 = new R3x2([1, 2,
3, 4,
5, 6])
const matrix3x2 = new R3x2([1, 2,
3, 4,
5, 6])

@@ -235,7 +180,7 @@ notDefined(matrix3x2.trace).should.be.ok()

it('is a static operator', () => {
var matrix3x2 = new R3x2([1, 2,
3, 4,
5, 6])
const matrix3x2 = new R3x2([1, 2,
3, 4,
5, 6])
var transposed = R3x2.transpose(matrix3x2)
const transposed = R3x2.transpose(matrix3x2)

@@ -249,7 +194,7 @@ transposed.should.deepEqual([1, 3, 5,

it('is a class attribute', () => {
var matrix3x2 = new R3x2([1, 2,
3, 4,
5, 6])
const matrix3x2 = new R3x2([1, 2,
3, 4,
5, 6])
var transposed = matrix3x2.transposed
const transposed = matrix3x2.transposed

@@ -261,4 +206,4 @@ transposed.data.should.deepEqual([1, 3, 5,

it('holds a transposed matrix', () => {
var matrix2x3 = new R2x3([1, 2, 3,
4, 5, 6])
const matrix2x3 = new R2x3([1, 2, 3,
4, 5, 6])

@@ -274,18 +219,9 @@ matrix2x3.transposed.data.should.deepEqual([1, 4,

it('is an involution', () => {
var matrix2x2a = new R2x2([1, 2,
3, 4])
const matrix2x2a = new R2x2([1, 2,
3, 4])
var matrix2x2b = matrix2x2a.transposed.transposed
const matrix2x2b = matrix2x2a.transposed.transposed
matrix2x2a.data.should.deepEqual(matrix2x2b.data)
})
it('returns a vector if the Matrix has one row', () => {
var matrix1x4 = new R1x4([1, 2, 3, 4])
var vector = matrix1x4.transposed
matrix1x4.data.should.deepEqual(vector.data)
vector.dimension.should.be.eql(matrix1x4.numCols)
})
})

@@ -295,22 +231,18 @@

it('is an alias of multiplication()', () => {
R2x2.mul.should.be.eql(R2x2.multiplication)
const matrix2x2 = new R2x2([1, 2,
3, 4])
var matrix2x2 = new R2x2([1, 2,
3, 4])
const matrix3x2 = new R3x2([1, 2,
3, 4,
5, 6])
matrix2x2.multiplication.should.be.eql(matrix2x2.mul)
matrix3x2.multiplication(matrix2x2).data.should.be.deepEqual(matrix3x2.mul(matrix2x2).data)
})
})
describe('tr()', () => {
it('is an alias of transpose()', () => {
R2x2.tr.should.be.eql(R2x2.transpose)
})
})
describe('tr', () => {
it('is an alias of transposed', () => {
var matrix = new R3x2([0, 1,
1, 0,
2, 2])
const matrix = new R3x2([0, 1,
1, 0,
2, 2])

@@ -317,0 +249,0 @@ matrix.tr.data.should.be.eql(matrix.transposed.data)

/* eslint-disable indent */
/* eslint-env mocha */
describe('Quick start', () => {
var algebra = require('algebra')
const algebra = require('algebra')
it('works', () => {
var R = algebra.Real
const R = algebra.Real
R.add(1, 2, 3).should.eql(6)
R.add(1, 2).should.eql(3)
var x = new R(2)
var y = new R(-2)
let x = new R(2)
const y = new R(-2)
var r = x.mul(y)
const r = x.mul(y)
r.data.should.eql(-4)

@@ -25,6 +26,6 @@ x.data.should.eql(2)

var C = algebra.Complex
const C = algebra.Complex
var z1 = new C([1, 2])
var z2 = new C([3, 4])
let z1 = new C([1, 2])
const z2 = new C([3, 4])

@@ -39,6 +40,6 @@ z1 = z1.mul(z2)

var R2 = algebra.VectorSpace(R)(2)
const R2 = algebra.VectorSpace(R)(2)
var v1 = new R2([0, 1])
var v2 = new R2([1, -2])
let v1 = new R2([0, 1])
const v2 = new R2([1, -2])

@@ -49,22 +50,23 @@ v1 = v1.add(v2)

var R3x2 = algebra.MatrixSpace(R)(3, 2)
const R3x2 = algebra.MatrixSpace(R)(3, 2)
var m1 = new R3x2([1, 1,
0, 1,
1, 0])
const m1 = new R3x2([1, 1,
0, 1,
1, 0])
var v3 = m1.mul(v1)
const v3 = m1.mul(v1)
v3.data.should.deepEqual([0, -1, 1])
var R2x2 = algebra.MatrixSpace(R)(2)
const R2x2 = algebra.MatrixSpace(R)(2)
var m2 = new R2x2([1, 0,
let m2 = new R2x2([1, 0,
0, 2])
var m3 = new R2x2([0, -1,
1, 0])
const m3 = new R2x2([0, -1,
1, 0])
m2 = m2.mul(m3)
m2.data.should.deepEqual([0, -1, 2, 0])
m2.data.should.deepEqual([0, -1,
2, 0])

@@ -71,0 +73,0 @@ m2.determinant.data.should.be.eql(2)

@@ -1,10 +0,15 @@

var algebra = require('algebra')
/* eslint-env mocha */
var R = algebra.Real
const algebra = require('algebra')
const assert = require('assert')
var methodBinaryOperator = require('./features/methodBinaryOperator')
var methodUnaryOperator = require('./features/methodUnaryOperator')
var staticBinaryOperator = require('./features/staticBinaryOperator')
var staticUnaryOperator = require('./features/staticUnaryOperator')
const realField = require('../src/realField')
const R = algebra.Real
const methodBinaryOperator = require('./features/methodBinaryOperator')
const methodUnaryOperator = require('./features/methodUnaryOperator')
const staticBinaryOperator = require('./features/staticBinaryOperator')
const staticUnaryOperator = require('./features/staticUnaryOperator')
describe('Real', () => {

@@ -24,3 +29,3 @@ describe('zero', () => {

describe('addition', () => {
var operator = 'addition'
const operator = 'addition'

@@ -30,11 +35,6 @@ it('is a static method', staticBinaryOperator(R, operator, 2, 3, 5))

it('is a class method', methodBinaryOperator(R, operator, 1, 2, 3))
it('accepts many arguments', () => {
var x = new R(1)
x.addition(2, 3, 4).data.should.eql(10)
})
})
describe('subtraction', () => {
var operator = 'subtraction'
const operator = 'subtraction'

@@ -44,11 +44,6 @@ it('is a static method', staticBinaryOperator(R, operator, 2, 3, -1))

it('is a class method', methodBinaryOperator(R, operator, -1, -4, 3))
it('accepts many arguments', () => {
var x = new R(10)
x.subtraction(1, 2, 3).data.should.eql(4)
})
})
describe('multiplication', () => {
var operator = 'multiplication'
const operator = 'multiplication'

@@ -58,11 +53,6 @@ it('is a static method', staticBinaryOperator(R, operator, 8, -2, -16))

it('is a class method', methodBinaryOperator(R, operator, 2, 2, 4))
it('accepts many arguments', () => {
var x = new R(2)
x.multiplication(3, 4, 5).data.should.eql(120)
})
})
describe('division', () => {
var operator = 'division'
const operator = 'division'

@@ -72,11 +62,6 @@ it('is a static method', staticBinaryOperator(R, operator, 8, 2, 4))

it('is a class method', methodBinaryOperator(R, operator, -2, 4, -0.5))
it('accepts many arguments', () => {
var x = new R(120)
x.division(3, 4, 5).data.should.eql(2)
})
})
describe('equality', () => {
var operator = 'equality'
const operator = 'equality'

@@ -86,3 +71,3 @@ it('is a static method', staticBinaryOperator(R, operator, 10, 10, true))

it('is a class method', () => {
var x = new R(10)
const x = new R(10)
x.equality(10).should.be.ok()

@@ -93,3 +78,3 @@ })

describe('disequality', () => {
var operator = 'disequality'
const operator = 'disequality'

@@ -99,3 +84,3 @@ it('is a static method', staticBinaryOperator(R, operator, 10, 20, true))

it('is a class method', () => {
var x = new R(10)
const x = new R(10)
x.disequality(20).should.be.ok()

@@ -106,3 +91,3 @@ })

describe('negation', () => {
var operator = 'negation'
const operator = 'negation'

@@ -114,3 +99,3 @@ it('is a static method', staticUnaryOperator(R, operator, -2, 2))

it('is an involution', () => {
var x = new R(10)
const x = new R(10)
x.negation().negation().data.should.be.eql(10)

@@ -121,3 +106,3 @@ })

describe('inversion', () => {
var operator = 'inversion'
const operator = 'inversion'

@@ -129,6 +114,12 @@ it('is a static method', staticUnaryOperator(R, operator, 2, 0.5))

it('is an involution', () => {
var x = new R(10)
const x = new R(10)
x.inversion().inversion().data.should.be.eql(10)
})
})
describe('realField', () => {
it('epsilon', () => {
assert(realField.equality(0.2 + 0.1, 0.3))
})
})
})

@@ -1,12 +0,14 @@

var CompositionAlgebra = require('algebra').CompositionAlgebra
var realField = require('../src/realField')
/* eslint-env mocha */
var R = CompositionAlgebra(realField)
const CompositionAlgebra = require('algebra').CompositionAlgebra
const realField = require('../src/realField')
const R = CompositionAlgebra(realField)
describe('CompositionAlgebra', () => {
describe('data', () => {
var pi = new R(Math.PI)
const pi = new R(Math.PI)
it('is enumerable', () => {
pi.propertyIsEnumerable('data').should.be.ok()
Object.prototype.propertyIsEnumerable.call(pi, 'data').should.be.ok()
})

@@ -13,0 +15,0 @@

@@ -1,20 +0,22 @@

var algebra = require('algebra')
var notDefined = require('not-defined')
/* eslint-env mocha */
var Real = algebra.Real
var VectorSpace = algebra.VectorSpace
const algebra = require('algebra')
const notDefined = require('not-defined')
var methodBinaryOperator = require('./features/methodBinaryOperator')
var staticBinaryOperator = require('./features/staticBinaryOperator')
var staticUnaryOperator = require('./features/staticUnaryOperator')
const Real = algebra.Real
const VectorSpace = algebra.VectorSpace
var R2 = VectorSpace(Real)(2)
var R3 = VectorSpace(Real)(3)
const methodBinaryOperator = require('./features/methodBinaryOperator')
const staticBinaryOperator = require('./features/staticBinaryOperator')
const staticUnaryOperator = require('./features/staticUnaryOperator')
const R2 = VectorSpace(Real)(2)
const R3 = VectorSpace(Real)(3)
describe('VectorSpace', () => {
describe('data', () => {
var v = new R2([0, 1])
const vector = new R2([0, 1])
it('is enumerable', () => {
v.propertyIsEnumerable('data').should.be.ok()
Object.prototype.propertyIsEnumerable.call(vector, 'data').should.be.ok()
})

@@ -25,3 +27,3 @@

'use strict'
v.data = [2, 1]
vector.data = [2, 1]
}).should.throwError()

@@ -32,3 +34,3 @@ })

describe('addition()', () => {
var operator = 'addition'
const operator = 'addition'

@@ -38,13 +40,6 @@ it('is a static method', staticBinaryOperator(R2, operator, [0, 2], [-1, 3], [-1, 5]))

it('is a class method', methodBinaryOperator(R2, operator, [0, 1], [1, 1], [1, 2]))
it('accepts multiple arguments', () => {
R2.addition([1, -1], [2, -2], [3, -3]).should.deepEqual([6, -6])
var vector = new R2([1, -1])
vector.addition([2, -2], [3, -3]).data.should.eql([6, -6])
})
})
describe('subtraction()', () => {
var operator = 'subtraction'
const operator = 'subtraction'

@@ -54,9 +49,2 @@ it('is a static method', staticBinaryOperator(R2, operator, [0, 2], [-1, 3], [1, -1]))

it('is a class method', methodBinaryOperator(R2, operator, [0, 1], [1, 1], [-1, 0]))
it('accepts multiple arguments', () => {
R2.subtraction([6, -6], [2, -2], [3, -3]).should.deepEqual([1, -1])
var vector = new R2([6, -6])
vector.subtraction([2, -2], [3, -3]).data.should.eql([1, -1])
})
})

@@ -66,3 +54,3 @@

it('is a static operator', () => {
var data = R2.scalarProduct([0, 1], [1, 1])
const data = R2.scalarProduct([0, 1], [1, 1])

@@ -73,6 +61,6 @@ data.should.eql(1)

it('is a class method', () => {
var vector1 = new R2([0, 1])
var vector2 = new R2([1, 1])
const vector1 = new R2([0, 1])
const vector2 = new R2([1, 1])
var scalar = vector1.scalarProduct(vector2)
const scalar = vector1.scalarProduct(vector2)

@@ -83,6 +71,6 @@ scalar.data.should.be.eql(1)

it('is returns a scalar', () => {
var vector1 = new R2([0, 1])
var vector2 = new R2([1, 1])
const vector1 = new R2([0, 1])
const vector2 = new R2([1, 1])
var scalar = vector1.scalarProduct(vector2)
const scalar = vector1.scalarProduct(vector2)

@@ -93,24 +81,6 @@ scalar.data.should.be.eql(1)

describe('dotProduct()', () => {
it('is an alias of scalarProduct()', () => {
R2.scalarProduct.should.be.eql(R2.dotProduct)
var vector = new R2([0, 1])
vector.scalarProduct.should.be.eql(vector.dotProduct)
})
})
describe('dot()', () => {
it('is an alias of scalarProduct()', () => {
R2.scalarProduct.should.be.eql(R2.dot)
var vector = new R2([0, 1])
vector.scalarProduct.should.be.eql(vector.dot)
})
})
describe('dimension', () => {
it('is a static attribute', () => {
var vector1 = new R2([0, 1])
var vector2 = new R3([1, 1, 2])
const vector1 = new R2([0, 1])
const vector2 = new R3([1, 1, 2])

@@ -127,4 +97,4 @@ vector1.dimension.should.be.eql(2)

it('is an attribute holding a scalar', () => {
var vector1 = new R2([0, 1])
var vector2 = new R3([1, 1, 2])
const vector1 = new R2([0, 1])
const vector2 = new R3([1, 1, 2])

@@ -137,3 +107,3 @@ vector1.norm.data.should.be.eql(1)

describe('norm()', () => {
var operator = 'norm'
const operator = 'norm'

@@ -147,3 +117,3 @@ it('is a static method', () => {

describe('crossProduct()', () => {
var operator = 'crossProduct'
const operator = 'crossProduct'

@@ -159,6 +129,6 @@ it('is a static method', () => {

it('is defined only in dimension 3', () => {
notDefined(R2.cross).should.be.ok()
notDefined(R2.crossProduct).should.be.ok()
var vector = new R2([1, 0])
notDefined(vector.cross).should.be.ok()
const vector = new R2([1, 0])
notDefined(vector.crossProduct).should.be.ok()
})

@@ -171,3 +141,3 @@ })

var vector = new R3([1, 0, 1])
const vector = new R3([1, 0, 1])
vector.crossProduct.should.be.eql(vector.cross)

@@ -174,0 +144,0 @@ })

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc