|
@@ -1,10 +1,11 @@
|
|
|
/**
|
|
|
- * Copyright (c) 2018-2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
+ * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
|
|
|
*
|
|
|
* @author Alexander Rose <alexander.rose@weirdbyte.de>
|
|
|
*/
|
|
|
|
|
|
import { NumberArray } from '../../../mol-util/type-helpers';
|
|
|
+import { Vec } from '../3d';
|
|
|
|
|
|
interface Matrix<N extends number = number, M extends number = number> {
|
|
|
data: NumberArray,
|
|
@@ -20,14 +21,30 @@ namespace Matrix {
|
|
|
}
|
|
|
|
|
|
/** Get element assuming data are stored in column-major order */
|
|
|
- export function get(m: Matrix, i: number, j: number) { return m.data[m.rows * j + i]; }
|
|
|
+ export function get(m: Matrix, i: number, j: number) {
|
|
|
+ return m.data[m.rows * j + i];
|
|
|
+ }
|
|
|
+
|
|
|
/** Set element assuming data are stored in column-major order */
|
|
|
- export function set(m: Matrix, i: number, j: number, value: number) { m.data[m.rows * j + i] = value; }
|
|
|
+ export function set<N extends number, M extends number>(m: Matrix<N, M>, i: number, j: number, value: number) {
|
|
|
+ m.data[m.rows * j + i] = value;
|
|
|
+ return m
|
|
|
+ }
|
|
|
+
|
|
|
/** Add to element assuming data are stored in column-major order */
|
|
|
- export function add(m: Matrix, i: number, j: number, value: number) { m.data[m.rows * j + i] += value; }
|
|
|
+ export function add<N extends number, M extends number>(m: Matrix<N, M>, i: number, j: number, value: number) {
|
|
|
+ m.data[m.rows * j + i] += value;
|
|
|
+ return m
|
|
|
+ }
|
|
|
+
|
|
|
/** Zero out the matrix */
|
|
|
- export function makeZero(m: Matrix) {
|
|
|
- for (let i = 0, _l = m.data.length; i < _l; i++) m.data[i] = 0.0;
|
|
|
+ export function makeZero<N extends number, M extends number>(m: Matrix<N, M>) {
|
|
|
+ m.data.fill(0.0)
|
|
|
+ return m
|
|
|
+ }
|
|
|
+
|
|
|
+ export function clone<N extends number, M extends number>(m: Matrix<N, M>): Matrix<N, M> {
|
|
|
+ return { data: m.data.slice(), size: m.size, cols: m.cols, rows: m.rows }
|
|
|
}
|
|
|
|
|
|
export function fromArray<N extends number, M extends number>(data: NumberArray, cols: N, rows: M): Matrix<N, M> {
|
|
@@ -36,8 +53,9 @@ namespace Matrix {
|
|
|
|
|
|
export function transpose<N extends number, M extends number>(out: Matrix<M, N>, mat: Matrix<N, M>): Matrix<M, N> {
|
|
|
const nrows = mat.rows, ncols = mat.cols
|
|
|
+ // TODO add in-place transpose
|
|
|
+ if (out as any === mat) mat = clone(mat)
|
|
|
const md = mat.data, mtd = out.data
|
|
|
-
|
|
|
for (let i = 0, mi = 0, mti = 0; i < nrows; mti += 1, mi += ncols, ++i) {
|
|
|
let ri = mti
|
|
|
for (let j = 0; j < ncols; ri += nrows, j++) mtd[ri] = md[mi + j]
|
|
@@ -46,7 +64,7 @@ namespace Matrix {
|
|
|
}
|
|
|
|
|
|
/** out = matA * matB' */
|
|
|
- export function multiplyABt (out: Matrix, matA: Matrix, matB: Matrix) {
|
|
|
+ export function multiplyABt<NA extends number, NB extends number, M extends number>(out: Matrix<M, M>, matA: Matrix<NA, M>, matB: Matrix<NB, M>): Matrix<M, M> {
|
|
|
const ncols = matA.cols, nrows = matA.rows, mrows = matB.rows
|
|
|
const ad = matA.data, bd = matB.data, cd = out.data
|
|
|
|
|
@@ -64,10 +82,10 @@ namespace Matrix {
|
|
|
}
|
|
|
|
|
|
/** Get the mean of rows in `mat` */
|
|
|
- export function meanRows (mat: Matrix) {
|
|
|
+ export function meanRows<N extends number, M extends number, V extends Vec<N>>(mat: Matrix<N, M>): V {
|
|
|
const nrows = mat.rows, ncols = mat.cols
|
|
|
const md = mat.data
|
|
|
- const mean = new Array(ncols)
|
|
|
+ const mean = new Array(ncols) as V
|
|
|
|
|
|
for (let j = 0; j < ncols; ++j) mean[ j ] = 0.0
|
|
|
for (let i = 0, p = 0; i < nrows; ++i) {
|
|
@@ -79,7 +97,7 @@ namespace Matrix {
|
|
|
}
|
|
|
|
|
|
/** Subtract `row` from all rows in `mat` */
|
|
|
- export function subRows (mat: Matrix, row: NumberArray) {
|
|
|
+ export function subRows<N extends number, M extends number>(mat: Matrix<N, M>, row: NumberArray) {
|
|
|
const nrows = mat.rows, ncols = mat.cols
|
|
|
const md = mat.data
|
|
|
|