14 if (!LD || !sym || !W || !work)
return FAIL;
16 ladel_int start, index_in_pattern, ncol = sym->
ncol, row, index, index2, Wnz, status;
30 if (W->
nz == NULL) Wnz = W->
p[col_in_W+1] - W->
p[col_in_W];
31 else Wnz = W->
nz[col_in_W];
38 row_in_L = LD->
pinv[row_in_L];
44 for (index = W->
p[col_in_W]; index < W->p[col_in_W] + Wnz; index++)
47 l12[row] = W->
x[index];
56 for (index_in_pattern = start; index_in_pattern < ncol; index_in_pattern++)
58 row = sym->
pattern[index_in_pattern];
61 d22 -= temp*temp*Dinv[row];
63 l12[row] *= Dinv[row];
65 for (index = L->
p[row]; index < (L->
p[row] + L->
nz[row]) && L->
i[index] < row_in_L; index++)
67 l12[L->
i[index]] -= L->
x[index]*temp;
71 ladel_set_union(l31_pattern, set_L31, difference, offset, insertions, row_in_L);
72 for (index2 = (L->
p[row] + L->
nz[row] - 1); index2 >= index; index2--)
74 l12[L->
i[index2]] -= L->
x[index2]*temp;
77 L->
i[index2+1] = L->
i[index2];
78 L->
x[index2+1] = L->
x[index2];
81 L->
i[index] = row_in_L;
82 L->
x[index] = l12[row];
85 if (etree[row] ==
NONE || etree[row] > row_in_L) etree[row] = row_in_L;
89 d22 = Dinv[row_in_L] = 1/d22;
93 L->
i[index] = row = l31_pattern->
set[index-L->
p[row_in_L]];
94 L->
x[index] = d22*l12[row];
99 etree[row_in_L] = L->
i[L->
p[row_in_L]];
111 if (LD->
pinv != NULL)
122 if (!LD || !sym || !work)
return FAIL;
123 ladel_int status, index_of_row_in_L, index, found, col,
124 top, bottom, top_row, bottom_row, middle, middle_row;
129 if (LD->
pinv != NULL) row_in_L = LD->
pinv[row_in_L];
132 for (col = 0; col < row_in_L; col++)
134 if (L->
nz[col] == 0)
continue;
138 bottom = L->
p[col] + L->
nz[col] - 1;
139 bottom_row = L->
i[bottom];
142 if (top_row == row_in_L)
144 index_of_row_in_L = top;
146 }
else if (bottom_row == row_in_L)
148 index_of_row_in_L = bottom;
150 }
else if (bottom_row < row_in_L || top_row > row_in_L)
157 middle = (top + bottom)/2;
158 middle_row = L->
i[middle];
159 if (middle_row == row_in_L)
161 index_of_row_in_L = middle;
164 }
else if (middle_row > row_in_L)
173 middle = (top + bottom)/2;
174 middle_row = L->
i[middle];
175 if (middle_row == row_in_L)
177 index_of_row_in_L = middle;
184 for (index = index_of_row_in_L; index < L->
p[col] + L->
nz[col] - 1; index++)
186 L->
i[index] = L->
i[index+1];
187 L->
x[index] = L->
x[index+1];
192 if (etree[col] == row_in_L)
194 if (index_of_row_in_L < L->p[col] + L->
nz[col]) etree[col] = L->
i[index_of_row_in_L];
195 else etree[col] =
NONE;
201 d22_old = 1.0/LD->
Dinv[row_in_L];
202 LD->
Dinv[row_in_L] = 1;
209 etree[row_in_L] =
NONE;
#define NONE
Indicates a root (a node without parent), or an untouched node.
#define TRUE
For booleans.
#define FALSE
For booleans.
#define FAIL
For status returns.
#define LADEL_FOR(index, M, col)
Loop through a column of a sparse matrix.
#define LADEL_ABS(a)
Return the absolute value a number.
ladel_int ladel_row_add(ladel_factor *LD, ladel_symbolics *sym, ladel_int row_in_L, ladel_sparse_matrix *W, ladel_int col_in_W, ladel_double diag, ladel_work *work)
Updates an factorization.
ladel_int ladel_row_del(ladel_factor *LD, ladel_symbolics *sym, ladel_int row_in_L, ladel_work *work)
Updates an factorization.
ladel_int ladel_rank1_update(ladel_factor *LD, ladel_symbolics *sym, ladel_sparse_matrix *W, ladel_int col_in_W, ladel_double factor, ladel_int up_or_down, ladel_work *work)
Updates an factorization.
Constants and macros used in LADEL.
void ladel_int_vector_copy(ladel_int *x, ladel_int size, ladel_int *y)
Copies an integer vector (preallocated)
void ladel_double_vector_copy(ladel_double *x, ladel_int size, ladel_double *y)
Copies a double vector (preallocated)
Routines to print out matrices and vectors.
Memory allocation routines.
void ladel_set_set(ladel_set *set, ladel_int *set_vals, ladel_int size_set, ladel_int max_size_set)
Fill in the fields of the given set.
Routines to compute the pattern of the result of a backsolve.
ladel_int ladel_etree_dfs(ladel_sparse_matrix *W, ladel_symbolics *sym, ladel_int col_in_W, ladel_int maximum_row)
Computes a depth-first search of the given pattern through the elimination tree.
Routines to permute vectors and matrices.
void ladel_permute_sparse_vector(ladel_sparse_matrix *x, ladel_int col, ladel_int *p, ladel_work *work)
Permute x(:,col) in place, such that on output .
Helper routines for the rank1_update function.
ladel_int ladel_set_union(ladel_set *first_set, ladel_set *second_set, ladel_set *difference, ladel_int *offset, ladel_int *insertions, ladel_int threshold)
Computes the set union of two index sets.
Routines for the row add/delete updates to a factorization are defined in ladel_row_mod....
Structures and types used in LADEL routines.
int64_t ladel_int
Type for integer numbers (default: int64_t)
double ladel_double
Type for floating point numbers (default: double)
Sparse matrix in compressed column storage.
ladel_double * x
numerical values (size nzmax)
ladel_int * p
column pointers (size ncol+1)
ladel_int * nz
(optional) number of elements in each column (size ncol)
ladel_int * i
row pointers (size nzmax)
ladel_int * set
List of integers representing the set.
ladel_int size_set
Size of the list.
Factors of an factorization.
ladel_sparse_matrix * L
L in LDL' factorization.
ladel_double * Dinv
D^-1 in LDL' factorization (stored as vector)
ladel_int * pinv
inverse permutation vector
Workspace required for various routines in LADEL.
ladel_int * array_int_ncol2
An array of ncol integers.
ladel_set * set_preallocated2
A preallocated set structure.
ladel_int * array_int_ncol1
An array of ncol integers.
ladel_int * array_int_ncol3
An array of ncol integers.
ladel_set * set_unallocated_values2
An unallocated set structure.
ladel_double * array_double_all_zeros_ncol1
An array of ncol doubles, on input and output this should be all zeros.
ladel_set * set_preallocated1
A preallocated set structure.
ladel_double * array_double_ncol1
An array of ncol doubles.