123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- import { clone } from '../../utils/object.js';
- import { format } from '../../utils/string.js';
- import { factory } from '../../utils/factory.js';
- var name = 'transpose';
- var dependencies = ['typed', 'matrix'];
- export var createTranspose = /* #__PURE__ */factory(name, dependencies, _ref => {
- var {
- typed,
- matrix
- } = _ref;
- /**
- * Transpose a matrix. All values of the matrix are reflected over its
- * main diagonal. Only applicable to two dimensional matrices containing
- * a vector (i.e. having size `[1,n]` or `[n,1]`). One dimensional
- * vectors and scalars return the input unchanged.
- *
- * Syntax:
- *
- * math.transpose(x)
- *
- * Examples:
- *
- * const A = [[1, 2, 3], [4, 5, 6]]
- * math.transpose(A) // returns [[1, 4], [2, 5], [3, 6]]
- *
- * See also:
- *
- * diag, inv, subset, squeeze
- *
- * @param {Array | Matrix} x Matrix to be transposed
- * @return {Array | Matrix} The transposed matrix
- */
- return typed(name, {
- Array: x => transposeMatrix(matrix(x)).valueOf(),
- Matrix: transposeMatrix,
- any: clone // scalars
- });
- function transposeMatrix(x) {
- // matrix size
- var size = x.size();
- // result
- var c;
- // process dimensions
- switch (size.length) {
- case 1:
- // vector
- c = x.clone();
- break;
- case 2:
- {
- // rows and columns
- var rows = size[0];
- var columns = size[1];
- // check columns
- if (columns === 0) {
- // throw exception
- throw new RangeError('Cannot transpose a 2D matrix with no columns (size: ' + format(size) + ')');
- }
- // process storage format
- switch (x.storage()) {
- case 'dense':
- c = _denseTranspose(x, rows, columns);
- break;
- case 'sparse':
- c = _sparseTranspose(x, rows, columns);
- break;
- }
- }
- break;
- default:
- // multi dimensional
- throw new RangeError('Matrix must be a vector or two dimensional (size: ' + format(size) + ')');
- }
- return c;
- }
- function _denseTranspose(m, rows, columns) {
- // matrix array
- var data = m._data;
- // transposed matrix data
- var transposed = [];
- var transposedRow;
- // loop columns
- for (var j = 0; j < columns; j++) {
- // initialize row
- transposedRow = transposed[j] = [];
- // loop rows
- for (var i = 0; i < rows; i++) {
- // set data
- transposedRow[i] = clone(data[i][j]);
- }
- }
- // return matrix
- return m.createDenseMatrix({
- data: transposed,
- size: [columns, rows],
- datatype: m._datatype
- });
- }
- function _sparseTranspose(m, rows, columns) {
- // matrix arrays
- var values = m._values;
- var index = m._index;
- var ptr = m._ptr;
- // result matrices
- var cvalues = values ? [] : undefined;
- var cindex = [];
- var cptr = [];
- // row counts
- var w = [];
- for (var x = 0; x < rows; x++) {
- w[x] = 0;
- }
- // vars
- var p, l, j;
- // loop values in matrix
- for (p = 0, l = index.length; p < l; p++) {
- // number of values in row
- w[index[p]]++;
- }
- // cumulative sum
- var sum = 0;
- // initialize cptr with the cummulative sum of row counts
- for (var i = 0; i < rows; i++) {
- // update cptr
- cptr.push(sum);
- // update sum
- sum += w[i];
- // update w
- w[i] = cptr[i];
- }
- // update cptr
- cptr.push(sum);
- // loop columns
- for (j = 0; j < columns; j++) {
- // values & index in column
- for (var k0 = ptr[j], k1 = ptr[j + 1], k = k0; k < k1; k++) {
- // C values & index
- var q = w[index[k]]++;
- // C[j, i] = A[i, j]
- cindex[q] = j;
- // check we need to process values (pattern matrix)
- if (values) {
- cvalues[q] = clone(values[k]);
- }
- }
- }
- // return matrix
- return m.createSparseMatrix({
- values: cvalues,
- index: cindex,
- ptr: cptr,
- size: [columns, rows],
- datatype: m._datatype
- });
- }
- });
|