transpose.js 4.1 KB

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