170 lines
6.2 KiB
C
170 lines
6.2 KiB
C
|
|
#ifndef QDLDL_H
|
||
|
|
#define QDLDL_H
|
||
|
|
|
||
|
|
// Include qdldl type options
|
||
|
|
#include "qdldl_types.h"
|
||
|
|
|
||
|
|
# ifdef __cplusplus
|
||
|
|
extern "C" {
|
||
|
|
# endif // ifdef __cplusplus
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Compute the elimination tree for a quasidefinite matrix
|
||
|
|
* in compressed sparse column form, where the input matrix is
|
||
|
|
* assumed to contain data for the upper triangular part of A only,
|
||
|
|
* and there are no duplicate indices.
|
||
|
|
*
|
||
|
|
* Returns an elimination tree for the factorization A = LDL^T and a
|
||
|
|
* count of the nonzeros in each column of L that are strictly below the
|
||
|
|
* diagonal.
|
||
|
|
*
|
||
|
|
* Does not use MALLOC. It is assumed that the arrays work, Lnz, and
|
||
|
|
* etree will be allocated with a number of elements equal to n.
|
||
|
|
*
|
||
|
|
* The data in (n,Ap,Ai) are from a square matrix A in CSC format, and
|
||
|
|
* should include the upper triangular part of A only.
|
||
|
|
*
|
||
|
|
* This function is only intended for factorisation of QD matrices specified
|
||
|
|
* by their upper triangular part. An error is returned if any column has
|
||
|
|
* data below the diagonal or s completely empty.
|
||
|
|
*
|
||
|
|
* For matrices with a non-empty column but a zero on the corresponding diagonal,
|
||
|
|
* this function will *not* return an error, as it may still be possible to factor
|
||
|
|
* such a matrix in LDL form. No promises are made in this case though...
|
||
|
|
*
|
||
|
|
* @param n number of columns in CSC matrix A (assumed square)
|
||
|
|
* @param Ap column pointers (size n+1) for columns of A
|
||
|
|
* @param Ai row indices of A. Has Ap[n] elements
|
||
|
|
* @param work work vector (size n) (no meaning on return)
|
||
|
|
* @param Lnz count of nonzeros in each column of L (size n) below diagonal
|
||
|
|
* @param etree elimination tree (size n)
|
||
|
|
* @return total sum of Lnz (i.e. total nonzeros in L below diagonal).
|
||
|
|
* Returns -1 if the input is not triu or has an empty column.
|
||
|
|
* Returns -2 if the return value overflows QDLDL_int.
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
QDLDL_int QDLDL_etree(const QDLDL_int n,
|
||
|
|
const QDLDL_int* Ap,
|
||
|
|
const QDLDL_int* Ai,
|
||
|
|
QDLDL_int* work,
|
||
|
|
QDLDL_int* Lnz,
|
||
|
|
QDLDL_int* etree);
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Compute an LDL decomposition for a quasidefinite matrix
|
||
|
|
* in compressed sparse column form, where the input matrix is
|
||
|
|
* assumed to contain data for the upper triangular part of A only,
|
||
|
|
* and there are no duplicate indices.
|
||
|
|
*
|
||
|
|
* Returns factors L, D and Dinv = 1./D.
|
||
|
|
*
|
||
|
|
* Does not use MALLOC. It is assumed that L will be a compressed
|
||
|
|
* sparse column matrix with data (n,Lp,Li,Lx) with sufficient space
|
||
|
|
* allocated, with a number of nonzeros equal to the count given
|
||
|
|
* as a return value by QDLDL_etree
|
||
|
|
*
|
||
|
|
* @param n number of columns in L and A (both square)
|
||
|
|
* @param Ap column pointers (size n+1) for columns of A (not modified)
|
||
|
|
* @param Ai row indices of A. Has Ap[n] elements (not modified)
|
||
|
|
* @param Ax data of A. Has Ap[n] elements (not modified)
|
||
|
|
* @param Lp column pointers (size n+1) for columns of L
|
||
|
|
* @param Li row indices of L. Has Lp[n] elements
|
||
|
|
* @param Lx data of L. Has Lp[n] elements
|
||
|
|
* @param D vectorized factor D. Length is n
|
||
|
|
* @param Dinv reciprocal of D. Length is n
|
||
|
|
* @param Lnz count of nonzeros in each column of L below diagonal,
|
||
|
|
* as given by QDLDL_etree (not modified)
|
||
|
|
* @param etree elimination tree as as given by QDLDL_etree (not modified)
|
||
|
|
* @param bwork working array of bools. Length is n
|
||
|
|
* @param iwork working array of integers. Length is 3*n
|
||
|
|
* @param fwork working array of floats. Length is n
|
||
|
|
* @return Returns a count of the number of positive elements
|
||
|
|
* in D. Returns -1 and exits immediately if any element
|
||
|
|
* of D evaluates exactly to zero (matrix is not quasidefinite
|
||
|
|
* or otherwise LDL factorisable)
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
QDLDL_int QDLDL_factor(const QDLDL_int n,
|
||
|
|
const QDLDL_int* Ap,
|
||
|
|
const QDLDL_int* Ai,
|
||
|
|
const QDLDL_float* Ax,
|
||
|
|
QDLDL_int* Lp,
|
||
|
|
QDLDL_int* Li,
|
||
|
|
QDLDL_float* Lx,
|
||
|
|
QDLDL_float* D,
|
||
|
|
QDLDL_float* Dinv,
|
||
|
|
const QDLDL_int* Lnz,
|
||
|
|
const QDLDL_int* etree,
|
||
|
|
QDLDL_bool* bwork,
|
||
|
|
QDLDL_int* iwork,
|
||
|
|
QDLDL_float* fwork);
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Solves LDL'x = b
|
||
|
|
*
|
||
|
|
* It is assumed that L will be a compressed
|
||
|
|
* sparse column matrix with data (n,Lp,Li,Lx).
|
||
|
|
*
|
||
|
|
* @param n number of columns in L
|
||
|
|
* @param Lp column pointers (size n+1) for columns of L
|
||
|
|
* @param Li row indices of L. Has Lp[n] elements
|
||
|
|
* @param Lx data of L. Has Lp[n] elements
|
||
|
|
* @param Dinv reciprocal of D. Length is n
|
||
|
|
* @param x initialized to b. Equal to x on return
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
void QDLDL_solve(const QDLDL_int n,
|
||
|
|
const QDLDL_int* Lp,
|
||
|
|
const QDLDL_int* Li,
|
||
|
|
const QDLDL_float* Lx,
|
||
|
|
const QDLDL_float* Dinv,
|
||
|
|
QDLDL_float* x);
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Solves (L+I)x = b
|
||
|
|
*
|
||
|
|
* It is assumed that L will be a compressed
|
||
|
|
* sparse column matrix with data (n,Lp,Li,Lx).
|
||
|
|
*
|
||
|
|
* @param n number of columns in L
|
||
|
|
* @param Lp column pointers (size n+1) for columns of L
|
||
|
|
* @param Li row indices of L. Has Lp[n] elements
|
||
|
|
* @param Lx data of L. Has Lp[n] elements
|
||
|
|
* @param x initialized to b. Equal to x on return
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
void QDLDL_Lsolve(const QDLDL_int n,
|
||
|
|
const QDLDL_int* Lp,
|
||
|
|
const QDLDL_int* Li,
|
||
|
|
const QDLDL_float* Lx,
|
||
|
|
QDLDL_float* x);
|
||
|
|
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Solves (L+I)'x = b
|
||
|
|
*
|
||
|
|
* It is assumed that L will be a compressed
|
||
|
|
* sparse column matrix with data (n,Lp,Li,Lx).
|
||
|
|
*
|
||
|
|
* @param n number of columns in L
|
||
|
|
* @param Lp column pointers (size n+1) for columns of L
|
||
|
|
* @param Li row indices of L. Has Lp[n] elements
|
||
|
|
* @param Lx data of L. Has Lp[n] elements
|
||
|
|
* @param x initialized to b. Equal to x on return
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
void QDLDL_Ltsolve(const QDLDL_int n,
|
||
|
|
const QDLDL_int* Lp,
|
||
|
|
const QDLDL_int* Li,
|
||
|
|
const QDLDL_float* Lx,
|
||
|
|
QDLDL_float* x);
|
||
|
|
|
||
|
|
# ifdef __cplusplus
|
||
|
|
}
|
||
|
|
# endif // ifdef __cplusplus
|
||
|
|
|
||
|
|
#endif // ifndef QDLDL_H
|