csEreach.js 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { csMark } from './csMark.js';
  2. import { csMarked } from './csMarked.js';
  3. /**
  4. * Find nonzero pattern of Cholesky L(k,1:k-1) using etree and triu(A(:,k))
  5. *
  6. * @param {Matrix} a The A matrix
  7. * @param {Number} k The kth column in A
  8. * @param {Array} parent The parent vector from the symbolic analysis result
  9. * @param {Array} w The nonzero pattern xi[top] .. xi[n - 1], an array of size = 2 * n
  10. * The first n entries is the nonzero pattern, the last n entries is the stack
  11. *
  12. * @return {Number} The index for the nonzero pattern
  13. *
  14. * Reference: http://faculty.cse.tamu.edu/davis/publications.html
  15. */
  16. export function csEreach(a, k, parent, w) {
  17. // a arrays
  18. var aindex = a._index;
  19. var aptr = a._ptr;
  20. var asize = a._size;
  21. // columns
  22. var n = asize[1];
  23. // initialize top
  24. var top = n;
  25. // vars
  26. var p, p0, p1, len;
  27. // mark node k as visited
  28. csMark(w, k);
  29. // loop values & index for column k
  30. for (p0 = aptr[k], p1 = aptr[k + 1], p = p0; p < p1; p++) {
  31. // A(i,k) is nonzero
  32. var i = aindex[p];
  33. // only use upper triangular part of A
  34. if (i > k) {
  35. continue;
  36. }
  37. // traverse up etree
  38. for (len = 0; !csMarked(w, i); i = parent[i]) {
  39. // L(k,i) is nonzero, last n entries in w
  40. w[n + len++] = i;
  41. // mark i as visited
  42. csMark(w, i);
  43. }
  44. while (len > 0) {
  45. // decrement top & len
  46. --top;
  47. --len;
  48. // push path onto stack, last n entries in w
  49. w[n + top] = w[n + len];
  50. }
  51. }
  52. // unmark all nodes
  53. for (p = top; p < n; p++) {
  54. // use stack value, last n entries in w
  55. csMark(w, w[n + p]);
  56. }
  57. // unmark node k
  58. csMark(w, k);
  59. // s[top..n-1] contains pattern of L(k,:)
  60. return top;
  61. }