123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import { clone } from '../../utils/object.js';
- import { format } from '../../utils/string.js';
- import { factory } from '../../utils/factory.js';
- var name = 'trace';
- var dependencies = ['typed', 'matrix', 'add'];
- export var createTrace = /* #__PURE__ */factory(name, dependencies, _ref => {
- var {
- typed,
- matrix,
- add
- } = _ref;
- /**
- * Calculate the trace of a matrix: the sum of the elements on the main
- * diagonal of a square matrix.
- *
- * Syntax:
- *
- * math.trace(x)
- *
- * Examples:
- *
- * math.trace([[1, 2], [3, 4]]) // returns 5
- *
- * const A = [
- * [1, 2, 3],
- * [-1, 2, 3],
- * [2, 0, 3]
- * ]
- * math.trace(A) // returns 6
- *
- * See also:
- *
- * diag
- *
- * @param {Array | Matrix} x A matrix
- *
- * @return {number} The trace of `x`
- */
- return typed('trace', {
- Array: function _arrayTrace(x) {
- // use dense matrix implementation
- return _denseTrace(matrix(x));
- },
- SparseMatrix: _sparseTrace,
- DenseMatrix: _denseTrace,
- any: clone
- });
- function _denseTrace(m) {
- // matrix size & data
- var size = m._size;
- var data = m._data;
- // process dimensions
- switch (size.length) {
- case 1:
- // vector
- if (size[0] === 1) {
- // return data[0]
- return clone(data[0]);
- }
- throw new RangeError('Matrix must be square (size: ' + format(size) + ')');
- case 2:
- {
- // two dimensional
- var rows = size[0];
- var cols = size[1];
- if (rows === cols) {
- // calulate sum
- var sum = 0;
- // loop diagonal
- for (var i = 0; i < rows; i++) {
- sum = add(sum, data[i][i]);
- }
- // return trace
- return sum;
- } else {
- throw new RangeError('Matrix must be square (size: ' + format(size) + ')');
- }
- }
- default:
- // multi dimensional
- throw new RangeError('Matrix must be two dimensional (size: ' + format(size) + ')');
- }
- }
- function _sparseTrace(m) {
- // matrix arrays
- var values = m._values;
- var index = m._index;
- var ptr = m._ptr;
- var size = m._size;
- // check dimensions
- var rows = size[0];
- var columns = size[1];
- // matrix must be square
- if (rows === columns) {
- // calulate sum
- var sum = 0;
- // check we have data (avoid looping columns)
- if (values.length > 0) {
- // loop columns
- for (var j = 0; j < columns; j++) {
- // k0 <= k < k1 where k0 = _ptr[j] && k1 = _ptr[j+1]
- var k0 = ptr[j];
- var k1 = ptr[j + 1];
- // loop k within [k0, k1[
- for (var k = k0; k < k1; k++) {
- // row index
- var i = index[k];
- // check row
- if (i === j) {
- // accumulate value
- sum = add(sum, values[k]);
- // exit loop
- break;
- }
- if (i > j) {
- // exit loop, no value on the diagonal for column j
- break;
- }
- }
- }
- }
- // return trace
- return sum;
- }
- throw new RangeError('Matrix must be square (size: ' + format(size) + ')');
- }
- });
|