
Security News
Deno 2.2 Improves Dependency Management and Expands Node.js Compatibility
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
@kkitahara/linear-algebra
Advanced tools
ECMAScript modules for exactly manipulating vectors and matrices of which elements are real or complex numbers of the form (p / q)sqrt(b).
ECMAScript modules for exactly manipulating vectors and matrices of which elements are real or complex 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.
npm install @kkitahara/linear-algebra @kkitahara/complex-algebra @kkitahara/real-algebra
import { ExactRealAlgebra as RealAlgebra } from '@kkitahara/real-algebra'
import { ComplexAlgebra } from '@kkitahara/complex-algebra'
import { LinearAlgebra } from '@kkitahara/linear-algebra'
let r = new RealAlgebra()
let c = new ComplexAlgebra(r)
let l = new LinearAlgebra(c)
let m1, m2, m3
Generate a new matrix (since v2.0.0)
m1 = l.$(1, 0, 0, 1)
m1.toString() // '(1, 0, 0, 1)'
m1 = l.$(r.$(1, 2, 5), c.$(0, 1), c.$(0, -1), 1)
m1.toString() // '((1 / 2)sqrt(5), i(1), i(-1), 1)'
// Some Array methods can be used
m1 = l.$(r.$(1, 2, 5), c.$(0, 1), c.$(0, -1), 1)
m1.push(c.$(3))
m1.toString() // '((1 / 2)sqrt(5), i(1), i(-1), 1, 3)'
Set and get the dimension
m1 = l.$(1, 0, 0, 1)
// 2 x 2 matix
m1.setDim(2, 2)
// number of rows
m1.getDim()[0] // 2
// number of columns
m1.getDim()[1] // 2
// elements are stored in row-major order
m1.toString() // '(1, 0,\n 0, 1)'
// 1 x 4 matix
m1.setDim(1, 4)
m1.getDim()[0] // 1
m1.getDim()[1] // 4
m1.toString() // '(1, 0, 0, 1)'
// 4 x 1 matix
m1.setDim(4, 1)
m1.getDim()[0] // 4
m1.getDim()[1] // 1
m1.toString() // '(1,\n 0,\n 0,\n 1)'
// 3 x 1 matix (inconsistent dimension)
m1.setDim(3, 1)
// throws an Error when getDim is called
m1.getDim() // Error
// 2 x 0 (0 means auto)
m1.setDim(2, 0)
m1.getDim()[0] // 2
m1.getDim()[1] // 2
// 0 x 1 (0 means auto)
m1.setDim(0, 1)
m1.getDim()[0] // 4
m1.getDim()[1] // 1
// 0 x 0 (this is an adaptive matrix, since v2.0.0)
m1.setDim(0, 0)
m1.isAdaptive() // true
m1.getDim() // Error
// matrices are adaptive by default
m1 = l.$(1, 0, 0, 1)
m1.isAdaptive() // true
:warning: matrix elements are stored in row-major order.
Copy (generate a new object)
m1 = l.$(1, 0, 0, 1).setDim(2, 2)
m2 = l.copy(m1)
m2.toString() // '(1, 0,\n 0, 1)'
m2.getDim()[0] // 2
m2.getDim()[1] // 2
Equality
m1 = l.$(1, 0, 0, 1).setDim(2, 2)
m2 = l.$(1, 0, 0, 1).setDim(2, 2)
m3 = l.$(1, 0, 0, -1).setDim(2, 2)
l.eq(m1, m2) // true
l.eq(m1, m3) // false
// matrices of different dimension are considered to be not equal
m1 = l.$(1, 0, 0, 1).setDim(2, 2)
m2 = l.$(1, 0, 0, 1).setDim(1, 4)
l.eq(m1, m2) // false
// here, `m1` is adaptive
m1 = l.$(1, 0, 0, 1)
m2 = l.$(1, 0, 0, 1).setDim(1, 4)
m3 = l.$(1, 0, 0, 1).setDim(4, 1)
l.eq(m1, m2) // true
l.eq(m1, m3) // true
l.eq(m2, m3) // false
Inequality
m1 = l.$(1, 0, 0, 1).setDim(2, 2)
m2 = l.$(1, 0, 0, 1).setDim(2, 2)
m3 = l.$(1, 0, 0, -1).setDim(2, 2)
l.ne(m1, m2) // false
l.ne(m1, m3) // true
// matrices of different dimension are considered to be not equal
m1 = l.$(1, 0, 0, 1).setDim(2, 2)
m2 = l.$(1, 0, 0, 1).setDim(1, 4)
l.ne(m1, m2) // true
// here, `m1` is adaptive
m1 = l.$(1, 0, 0, 1)
m2 = l.$(1, 0, 0, 1).setDim(1, 4)
m3 = l.$(1, 0, 0, 1).setDim(4, 1)
l.ne(m1, m2) // false
l.ne(m1, m3) // false
l.ne(m2, m3) // true
isZero
m1 = l.$(1, 0, 0, 1).setDim(2, 2)
m2 = l.$(0, 0, 0, 0).setDim(2, 2)
l.isZero(m1) // false
l.isZero(m2) // true
isInteger (since v1.1.0)
m1 = l.$(1, r.$(4, 2), -3, 4).setDim(2, 2)
m2 = l.$(1, r.$(1, 2), -3, 4).setDim(2, 2)
l.isInteger(m1) // true
l.isInteger(m2) // false
Element-wise addition
m1 = l.$(1, 2, 3, 4)
m2 = l.$(1, 3, 1, 3)
// new object is generated
m3 = l.add(m1, m2)
m3.toString() // '(2, 5, 4, 7)'
In-place element-wise addition
m1 = l.$(1, 2, 3, 4)
m2 = l.$(1, 3, 1, 3)
// new object is not generated
m1 = l.iadd(m1, m2)
m1.toString() // '(2, 5, 4, 7)'
Element-wise subtraction
m1 = l.$(1, 2, 3, 4)
m2 = l.$(1, 3, 1, 3)
// new object is generated
m3 = l.sub(m1, m2)
m3.toString() // '(0, -1, 2, 1)'
In-place element-wise subtraction
m1 = l.$(1, 2, 3, 4)
m2 = l.$(1, 3, 1, 3)
// new object is not generated
m1 = l.isub(m1, m2)
m1.toString() // '(0, -1, 2, 1)'
Element-wise multiplication
m1 = l.$(1, 2, 3, 4)
m2 = l.$(1, 3, 1, 3)
// new object is generated
m3 = l.mul(m1, m2)
m3.toString() // '(1, 6, 3, 12)'
In-place element-wise multiplication
m1 = l.$(1, 2, 3, 4)
m2 = l.$(1, 3, 1, 3)
// new object is not generated
m1 = l.imul(m1, m2)
m1.toString() // '(1, 6, 3, 12)'
Element-wise division
m1 = l.$(1, 2, 3, 4)
m2 = l.$(1, 3, 1, 3)
// new object is generated
m3 = l.div(m1, m2)
m3.toString() // '(1, 2 / 3, 3, 4 / 3)'
In-place element-wise division
m1 = l.$(1, 2, 3, 4)
m2 = l.$(1, 3, 1, 3)
// new object is not generated
m1 = l.idiv(m1, m2)
m1.toString() // '(1, 2 / 3, 3, 4 / 3)'
Scalar multiplication
m1 = l.$(1, 2, 3, 4)
// new object is generated
m2 = l.smul(m1, r.$(1, 2))
m2.toString() // '(1 / 2, 1, 3 / 2, 2)'
In-place scalar multiplication
m1 = l.$(1, 2, 3, 4)
// new object is not generated
m1 = l.ismul(m1, r.$(1, 2))
m1.toString() // '(1 / 2, 1, 3 / 2, 2)'
Scalar multiplication by -1
m1 = l.$(1, 2, 3, 4)
// new object is generated
m2 = l.neg(m1)
m2.toString() // '(-1, -2, -3, -4)'
In-place scalar multiplication by -1
m1 = l.$(1, 2, 3, 4)
// new object is not generated
m1 = l.ineg(m1)
m1.toString() // '(-1, -2, -3, -4)'
Scalar division (since v2.0.0)
m1 = l.$(1, 2, 3, 4)
// new object is generated
m2 = l.sdiv(m1, 2)
m2.toString() // '(1 / 2, 1, 3 / 2, 2)'
In-place scalar division (since v2.0.0)
m1 = l.$(1, 2, 3, 4)
// new object is not generated
m1 = l.isdiv(m1, 2)
m1.toString() // '(1 / 2, 1, 3 / 2, 2)'
Complex conjugate
m1 = l.$(1, c.$(0, 2), 3, c.$(0, 4))
// new object is generated
m2 = l.cjg(m1)
m2.toString() // '(1, i(-2), 3, i(-4))'
In-place evaluation of the complex conjugate
m1 = l.$(1, c.$(0, 2), 3, c.$(0, 4))
// new object is not generated
m1 = l.icjg(m1)
m1.toString() // '(1, i(-2), 3, i(-4))'
Transpose
m1 = l.$(1, 2, 3, 4).setDim(2, 2)
// new object is generated
m2 = l.transpose(m1)
m2.toString() // '(1, 3,\n 2, 4)'
In-place evaluation of the transpose
m1 = l.$(1, 2, 3, 4).setDim(2, 2)
// new object is not generated
m1 = l.itranspose(m1)
m1.toString() // '(1, 3,\n 2, 4)'
Conjugate transpose (Hermitian transpose)
m1 = l.$(1, c.$(0, 2), 3, c.$(0, 4)).setDim(2, 2)
// new object is generated
m2 = l.cjgTranspose(m1)
m2.toString() // '(1, 3,\n i(-2), i(-4))'
In-place evaluation of the conjugate transpose
m1 = l.$(1, c.$(0, 2), 3, c.$(0, 4)).setDim(2, 2)
// new object is not generated
m1 = l.icjgTranspose(m1)
m1.toString() // '(1, 3,\n i(-2), i(-4))'
Dot product
m1 = l.$(1, c.$(0, 2))
m2 = l.$(c.$(0, 3), 2)
l.dot(m1, m2).toString() // 'i(-1)'
Square of the absolute value (Frobenius norm)
m1 = l.$(1, c.$(0, 2))
let a = l.abs2(m1)
a.toString() // '5'
// return value is not a complex number (but a real number)
a.re // undefined
a.im // undefined
Matrix multiplication
m1 = l.$(1, 2, 3, 4).setDim(2, 2)
m2 = l.$(1, 3, 1, 3).setDim(2, 2)
m3 = l.mmul(m1, m2)
m3.toString() // '(3, 9,\n 7, 21)'
LU-factorisation
m1 = l.$(1, 2, 3, 4).setDim(2, 2)
// new object is generated
m2 = l.lup(m1)
In-place LU-factorisation
m1 = l.$(1, 2, 3, 4).setDim(2, 2)
// new object is not generated
m1 = l.ilup(m1)
Solving a linear equation
m1 = l.$(1, 2, 3, 4).setDim(2, 2)
m2 = l.$(1, 2, 3, 4).setDim(2, 2)
// m1 m3 = m2, new object is generated
m3 = l.solve(l.lup(m1), m2)
m3.toString() // '(1, 0,\n 0, 1)'
// m3 m1 = m2, new object is generated
m3 = l.solve(m2, l.lup(m1))
m3.toString() // '(1, 0,\n 0, 1)'
Solving a linear equation in-place
m1 = l.$(1, 2, 3, 4).setDim(2, 2)
m2 = l.$(1, 2, 3, 4).setDim(2, 2)
// m1 m3 = m2, new object is not generated
m2 = l.isolve(l.lup(m1), m2)
m2.toString() // '(1, 0,\n 0, 1)'
m2 = l.$(1, 2, 3, 4).setDim(2, 2)
// m3 m1 = m2, new object is not generated
m2 = l.isolve(m2, l.lup(m1))
m2.toString() // '(1, 0,\n 0, 1)'
Determinant
m1 = l.$(1, 2, 3, 4).setDim(2, 2)
m2 = l.lup(m1)
// det method supports only LU-factorised matrices
let det = l.det(m2)
det.toString() // '-2'
JSON (stringify and parse)
m1 = l.$(1, r.$(2, 3, 5), 3, c.$(0, r.$(4, 5, 3))).setDim(2, 2)
let str = JSON.stringify(m1)
m2 = JSON.parse(str, l.reviver)
l.eq(m1, m2) // true
If complex numbers are not necessary, you can use RealAlgebra instead of ComplexAlgebra.
import { ExactRealAlgebra as RealAlgebra } from '@kkitahara/real-algebra'
import { LinearAlgebra } from '@kkitahara/linear-algebra'
let r = new RealAlgebra()
let l = new LinearAlgebra(r)
You can work with built-in numbers if you use
import { RealAlgebra } from '@kkitahara/real-algebra'
instead of ExactRealAlgebra. See the documents of @kkitahara/real-algebra for more details.
For more examples, see ESDoc documents:
cd node_modules/@kkitahara/linear-algebra
npm install --only=dev
npm run doc
and open doc/index.html
in your browser.
© 2019 Koichi Kitahara
Apache 2.0
FAQs
ECMAScript modules for exactly manipulating vectors and matrices of which elements are real or complex numbers of the form (p / q)sqrt(b).
The npm package @kkitahara/linear-algebra receives a total of 2 weekly downloads. As such, @kkitahara/linear-algebra popularity was classified as not popular.
We found that @kkitahara/linear-algebra demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Deno 2.2 enhances Node.js compatibility, improves dependency management, adds OpenTelemetry support, and expands linting and task automation for developers.
Security News
React's CRA deprecation announcement sparked community criticism over framework recommendations, leading to quick updates acknowledging build tools like Vite as valid alternatives.
Security News
Ransomware payment rates hit an all-time low in 2024 as law enforcement crackdowns, stronger defenses, and shifting policies make attacks riskier and less profitable.