csSymperm.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. import { csCumsum } from './csCumsum.js';
  2. import { factory } from '../../../utils/factory.js';
  3. var name = 'csSymperm';
  4. var dependencies = ['conj', 'SparseMatrix'];
  5. export var createCsSymperm = /* #__PURE__ */factory(name, dependencies, _ref => {
  6. var {
  7. conj,
  8. SparseMatrix
  9. } = _ref;
  10. /**
  11. * Computes the symmetric permutation of matrix A accessing only
  12. * the upper triangular part of A.
  13. *
  14. * C = P * A * P'
  15. *
  16. * @param {Matrix} a The A matrix
  17. * @param {Array} pinv The inverse of permutation vector
  18. * @param {boolean} values Process matrix values (true)
  19. *
  20. * @return {Matrix} The C matrix, C = P * A * P'
  21. *
  22. * Reference: http://faculty.cse.tamu.edu/davis/publications.html
  23. */
  24. return function csSymperm(a, pinv, values) {
  25. // A matrix arrays
  26. var avalues = a._values;
  27. var aindex = a._index;
  28. var aptr = a._ptr;
  29. var asize = a._size;
  30. // columns
  31. var n = asize[1];
  32. // C matrix arrays
  33. var cvalues = values && avalues ? [] : null;
  34. var cindex = []; // (nz)
  35. var cptr = []; // (n + 1)
  36. // variables
  37. var i, i2, j, j2, p, p0, p1;
  38. // create workspace vector
  39. var w = []; // (n)
  40. // count entries in each column of C
  41. for (j = 0; j < n; j++) {
  42. // column j of A is column j2 of C
  43. j2 = pinv ? pinv[j] : j;
  44. // loop values in column j
  45. for (p0 = aptr[j], p1 = aptr[j + 1], p = p0; p < p1; p++) {
  46. // row
  47. i = aindex[p];
  48. // skip lower triangular part of A
  49. if (i > j) {
  50. continue;
  51. }
  52. // row i of A is row i2 of C
  53. i2 = pinv ? pinv[i] : i;
  54. // column count of C
  55. w[Math.max(i2, j2)]++;
  56. }
  57. }
  58. // compute column pointers of C
  59. csCumsum(cptr, w, n);
  60. // loop columns
  61. for (j = 0; j < n; j++) {
  62. // column j of A is column j2 of C
  63. j2 = pinv ? pinv[j] : j;
  64. // loop values in column j
  65. for (p0 = aptr[j], p1 = aptr[j + 1], p = p0; p < p1; p++) {
  66. // row
  67. i = aindex[p];
  68. // skip lower triangular part of A
  69. if (i > j) {
  70. continue;
  71. }
  72. // row i of A is row i2 of C
  73. i2 = pinv ? pinv[i] : i;
  74. // C index for column j2
  75. var q = w[Math.max(i2, j2)]++;
  76. // update C index for entry q
  77. cindex[q] = Math.min(i2, j2);
  78. // check we need to process values
  79. if (cvalues) {
  80. cvalues[q] = i2 <= j2 ? avalues[p] : conj(avalues[p]);
  81. }
  82. }
  83. }
  84. // return C matrix
  85. return new SparseMatrix({
  86. values: cvalues,
  87. index: cindex,
  88. ptr: cptr,
  89. size: [n, n]
  90. });
  91. };
  92. });