8#define SUBSEQUENT_LEAF 2
15 if (subtree_root <= node || first_descendant[node] <= max_first_descendant[subtree_root])
21 max_first_descendant[subtree_root] = first_descendant[node];
23 ladel_int last_leaf = prev_leaf[subtree_root];
24 prev_leaf[subtree_root] = node;
25 if (last_leaf ==
NONE)
34 for (lca = last_leaf; lca != ancestor[lca]; lca = ancestor[lca]);
36 ladel_int last_path_node, ancestor_of_last_path_node;
37 for (last_path_node = last_leaf; last_path_node != lca; last_path_node = ancestor_of_last_path_node)
39 ancestor_of_last_path_node = ancestor[last_path_node];
40 ancestor[last_path_node] = lca;
64 if (!M_lower)
return FAIL;
66 for (index = 0; index < ncol; index++) prev_leaf[index] =
NONE;
67 for (index = 0; index < ncol; index++) first_descendant[index] =
NONE;
68 for (index = 0; index < ncol; index++) max_first_descendant[index] =
NONE;
69 for (index = 0; index < ncol; index++) ancestor[index] = index;
71 for (node = 0; node < ncol; node++)
73 post_node = postorder[node];
74 if (first_descendant[post_node] ==
NONE)
75 col_counts[post_node] = 1;
77 col_counts[post_node] = 0;
78 for (; post_node !=
NONE && first_descendant[post_node] ==
NONE; post_node = etree[post_node])
79 first_descendant[post_node] = node;
81 for (node = 0; node < ncol; node++)
83 post_node = postorder[node];
84 if (!
IS_ROOT(post_node, etree)) col_counts[etree[post_node]]--;
87 subtree_root = M_lower->
i[index];
88 lca =
ladel_least_common_ancestor(subtree_root, post_node, first_descendant, max_first_descendant, prev_leaf, ancestor, &type_of_leaf);
89 if (type_of_leaf !=
NOT_A_LEAF) col_counts[post_node]++;
92 if (!
IS_ROOT(post_node, etree)) ancestor[post_node] = etree[post_node];
94 for (node = 0; node < ncol; node++)
95 if (!
IS_ROOT(node, etree)) col_counts[etree[node]] += col_counts[node];
97 for (node = 1; node < ncol; node++)
99 col_counts[node] += --col_counts[node-1];
101 col_counts[ncol-1]--;
104 return col_counts[ncol-1];
#define NONE
Indicates a root (a node without parent), or an untouched node.
#define FALSE
For booleans.
#define LOWER
Use only lower part of matrix.
#define UPPER
Use only upper part of matrix.
#define FAIL
For status returns.
#define LADEL_FOR(index, M, col)
Loop through a column of a sparse matrix.
#define IS_ROOT(col, etree)
Check whether a node is a root (i.e.
ladel_int ladel_least_common_ancestor(ladel_int subtree_root, ladel_int node, ladel_int *first_descendant, ladel_int *max_first_descendant, ladel_int *prev_leaf, ladel_int *ancestor, ladel_int *node_type_of_leaf)
ladel_int ladel_col_counts(ladel_sparse_matrix *M, ladel_symbolics *sym, ladel_work *work)
Computes the column counts of the factor.
Constants and macros used in LADEL.
Routines to print out matrices and vectors.
Memory allocation routines.
ladel_sparse_matrix * ladel_sparse_free(ladel_sparse_matrix *M)
Free a sparse matrix (and return NULL).
Routine to compute the transpose of a matrix.
ladel_sparse_matrix * ladel_transpose(ladel_sparse_matrix *M, ladel_int values, ladel_work *work)
Returns the transpose of a matrix, that is .
Structures and types used in LADEL routines.
int64_t ladel_int
Type for integer numbers (default: int64_t)
Sparse matrix in compressed column storage.
ladel_int symmetry
type of symmetry (UNSYMMETRIC, UPPER or LOWER)
ladel_int ncol
number of columns
ladel_int * i
row pointers (size nzmax)
Workspace required for various routines in LADEL.
ladel_int * array_int_ncol2
An array of ncol integers.
ladel_int * array_int_ncol1
An array of ncol integers.
ladel_int * array_int_ncol3
An array of ncol integers.
ladel_int * array_int_ncol4
An array of ncol integers.