csCounts.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.createCsCounts = void 0;
  6. var _factory = require("../../../utils/factory.js");
  7. var _csLeaf = require("./csLeaf.js");
  8. var name = 'csCounts';
  9. var dependencies = ['transpose'];
  10. var createCsCounts = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
  11. var transpose = _ref.transpose;
  12. /**
  13. * Computes the column counts using the upper triangular part of A.
  14. * It transposes A internally, none of the input parameters are modified.
  15. *
  16. * @param {Matrix} a The sparse matrix A
  17. *
  18. * @param {Matrix} ata Count the columns of A'A instead
  19. *
  20. * @return An array of size n of the column counts or null on error
  21. *
  22. * Reference: http://faculty.cse.tamu.edu/davis/publications.html
  23. */
  24. return function (a, parent, post, ata) {
  25. // check inputs
  26. if (!a || !parent || !post) {
  27. return null;
  28. }
  29. // a matrix arrays
  30. var asize = a._size;
  31. // rows and columns
  32. var m = asize[0];
  33. var n = asize[1];
  34. // variables
  35. var i, j, k, J, p, p0, p1;
  36. // workspace size
  37. var s = 4 * n + (ata ? n + m + 1 : 0);
  38. // allocate workspace
  39. var w = []; // (s)
  40. var ancestor = 0; // first n entries
  41. var maxfirst = n; // next n entries
  42. var prevleaf = 2 * n; // next n entries
  43. var first = 3 * n; // next n entries
  44. var head = 4 * n; // next n + 1 entries (used when ata is true)
  45. var next = 5 * n + 1; // last entries in workspace
  46. // clear workspace w[0..s-1]
  47. for (k = 0; k < s; k++) {
  48. w[k] = -1;
  49. }
  50. // allocate result
  51. var colcount = []; // (n)
  52. // AT = A'
  53. var at = transpose(a);
  54. // at arrays
  55. var tindex = at._index;
  56. var tptr = at._ptr;
  57. // find w[first + j]
  58. for (k = 0; k < n; k++) {
  59. j = post[k];
  60. // colcount[j]=1 if j is a leaf
  61. colcount[j] = w[first + j] === -1 ? 1 : 0;
  62. for (; j !== -1 && w[first + j] === -1; j = parent[j]) {
  63. w[first + j] = k;
  64. }
  65. }
  66. // initialize ata if needed
  67. if (ata) {
  68. // invert post
  69. for (k = 0; k < n; k++) {
  70. w[post[k]] = k;
  71. }
  72. // loop rows (columns in AT)
  73. for (i = 0; i < m; i++) {
  74. // values in column i of AT
  75. for (k = n, p0 = tptr[i], p1 = tptr[i + 1], p = p0; p < p1; p++) {
  76. k = Math.min(k, w[tindex[p]]);
  77. }
  78. // place row i in linked list k
  79. w[next + i] = w[head + k];
  80. w[head + k] = i;
  81. }
  82. }
  83. // each node in its own set
  84. for (i = 0; i < n; i++) {
  85. w[ancestor + i] = i;
  86. }
  87. for (k = 0; k < n; k++) {
  88. // j is the kth node in postordered etree
  89. j = post[k];
  90. // check j is not a root
  91. if (parent[j] !== -1) {
  92. colcount[parent[j]]--;
  93. }
  94. // J=j for LL'=A case
  95. for (J = ata ? w[head + k] : j; J !== -1; J = ata ? w[next + J] : -1) {
  96. for (p = tptr[J]; p < tptr[J + 1]; p++) {
  97. i = tindex[p];
  98. var r = (0, _csLeaf.csLeaf)(i, j, w, first, maxfirst, prevleaf, ancestor);
  99. // check A(i,j) is in skeleton
  100. if (r.jleaf >= 1) {
  101. colcount[j]++;
  102. }
  103. // check account for overlap in q
  104. if (r.jleaf === 2) {
  105. colcount[r.q]--;
  106. }
  107. }
  108. }
  109. if (parent[j] !== -1) {
  110. w[ancestor + j] = parent[j];
  111. }
  112. }
  113. // sum up colcount's of each child
  114. for (j = 0; j < n; j++) {
  115. if (parent[j] !== -1) {
  116. colcount[parent[j]] += colcount[j];
  117. }
  118. }
  119. return colcount;
  120. };
  121. });
  122. exports.createCsCounts = createCsCounts;