transpose.js (4243B)
1 import { clone } from '../../utils/object.js'; 2 import { format } from '../../utils/string.js'; 3 import { factory } from '../../utils/factory.js'; 4 var name = 'transpose'; 5 var dependencies = ['typed', 'matrix']; 6 export var createTranspose = /* #__PURE__ */factory(name, dependencies, _ref => { 7 var { 8 typed, 9 matrix 10 } = _ref; 11 12 /** 13 * Transpose a matrix. All values of the matrix are reflected over its 14 * main diagonal. Only applicable to two dimensional matrices containing 15 * a vector (i.e. having size `[1,n]` or `[n,1]`). One dimensional 16 * vectors and scalars return the input unchanged. 17 * 18 * Syntax: 19 * 20 * math.transpose(x) 21 * 22 * Examples: 23 * 24 * const A = [[1, 2, 3], [4, 5, 6]] 25 * math.transpose(A) // returns [[1, 4], [2, 5], [3, 6]] 26 * 27 * See also: 28 * 29 * diag, inv, subset, squeeze 30 * 31 * @param {Array | Matrix} x Matrix to be transposed 32 * @return {Array | Matrix} The transposed matrix 33 */ 34 return typed('transpose', { 35 Array: function Array(x) { 36 // use dense matrix implementation 37 return this(matrix(x)).valueOf(); 38 }, 39 Matrix: function Matrix(x) { 40 // matrix size 41 var size = x.size(); // result 42 43 var c; // process dimensions 44 45 switch (size.length) { 46 case 1: 47 // vector 48 c = x.clone(); 49 break; 50 51 case 2: 52 { 53 // rows and columns 54 var rows = size[0]; 55 var columns = size[1]; // check columns 56 57 if (columns === 0) { 58 // throw exception 59 throw new RangeError('Cannot transpose a 2D matrix with no columns (size: ' + format(size) + ')'); 60 } // process storage format 61 62 63 switch (x.storage()) { 64 case 'dense': 65 c = _denseTranspose(x, rows, columns); 66 break; 67 68 case 'sparse': 69 c = _sparseTranspose(x, rows, columns); 70 break; 71 } 72 } 73 break; 74 75 default: 76 // multi dimensional 77 throw new RangeError('Matrix must be a vector or two dimensional (size: ' + format(this._size) + ')'); 78 } 79 80 return c; 81 }, 82 // scalars 83 any: function any(x) { 84 return clone(x); 85 } 86 }); 87 88 function _denseTranspose(m, rows, columns) { 89 // matrix array 90 var data = m._data; // transposed matrix data 91 92 var transposed = []; 93 var transposedRow; // loop columns 94 95 for (var j = 0; j < columns; j++) { 96 // initialize row 97 transposedRow = transposed[j] = []; // loop rows 98 99 for (var i = 0; i < rows; i++) { 100 // set data 101 transposedRow[i] = clone(data[i][j]); 102 } 103 } // return matrix 104 105 106 return m.createDenseMatrix({ 107 data: transposed, 108 size: [columns, rows], 109 datatype: m._datatype 110 }); 111 } 112 113 function _sparseTranspose(m, rows, columns) { 114 // matrix arrays 115 var values = m._values; 116 var index = m._index; 117 var ptr = m._ptr; // result matrices 118 119 var cvalues = values ? [] : undefined; 120 var cindex = []; 121 var cptr = []; // row counts 122 123 var w = []; 124 125 for (var x = 0; x < rows; x++) { 126 w[x] = 0; 127 } // vars 128 129 130 var p, l, j; // loop values in matrix 131 132 for (p = 0, l = index.length; p < l; p++) { 133 // number of values in row 134 w[index[p]]++; 135 } // cumulative sum 136 137 138 var sum = 0; // initialize cptr with the cummulative sum of row counts 139 140 for (var i = 0; i < rows; i++) { 141 // update cptr 142 cptr.push(sum); // update sum 143 144 sum += w[i]; // update w 145 146 w[i] = cptr[i]; 147 } // update cptr 148 149 150 cptr.push(sum); // loop columns 151 152 for (j = 0; j < columns; j++) { 153 // values & index in column 154 for (var k0 = ptr[j], k1 = ptr[j + 1], k = k0; k < k1; k++) { 155 // C values & index 156 var q = w[index[k]]++; // C[j, i] = A[i, j] 157 158 cindex[q] = j; // check we need to process values (pattern matrix) 159 160 if (values) { 161 cvalues[q] = clone(values[k]); 162 } 163 } 164 } // return matrix 165 166 167 return m.createSparseMatrix({ 168 values: cvalues, 169 index: cindex, 170 ptr: cptr, 171 size: [columns, rows], 172 datatype: m._datatype 173 }); 174 } 175 });