/* ========================================================================== */ /* === klu include file ================================================= */ /* ========================================================================== */ /* Include file for user programs that call klu_* routines */ #ifndef _KLU_H #define _KLU_H /* make it easy for C++ programs to include KLU */ #ifdef __cplusplus extern "C" { #endif #include "amd.h" #include "colamd.h" #include "btf.h" /* -------------------------------------------------------------------------- */ /* Symbolic object - contains the pre-ordering computed by klu_analyze */ /* -------------------------------------------------------------------------- */ typedef struct { /* A (P,Q) is in upper block triangular form. The kth block goes from * row/col index R [k] to R [k+1]-1. The estimated number of nonzeros * in the L factor of the kth block is Lnz [k]. */ /* only computed if the AMD ordering is chosen: */ double symmetry ; /* symmetry of largest block */ double est_flops ; /* est. factorization flop count */ double lnz, unz ; /* estimated nz in L and U, including diagonals */ double *Lnz ; /* size n, but only Lnz [0..nblocks-1] is used */ /* computed for all orderings: */ int n, /* input matrix A is n-by-n */ nz, /* # entries in input matrix */ *P, /* size n */ *Q, /* size n */ *R, /* size n+1, but only R [0..nblocks] is used */ nzoff, /* nz in off-diagonal blocks */ nblocks, /* number of blocks */ maxblock, /* size of largest block */ ordering, /* ordering used (AMD, COLAMD, or GIVEN) */ do_btf ; /* whether or not BTF preordering was requested */ /* only computed if BTF preordering requested */ int structural_rank ; /* 0 to n-1 if the matrix is structurally rank * deficient. -1 if not computed. n if the matrix has * full structural rank */ } klu_symbolic ; /* -------------------------------------------------------------------------- */ /* Numeric object - contains the factors computed by klu_factor */ /* -------------------------------------------------------------------------- */ typedef struct { /* LU factors of each block, the pivot row permutation, and the * entries in the off-diagonal blocks */ int nblocks ; /* number of diagonal blocks */ int lnz ; /* actual nz in L, including diagonal */ int unz ; /* actual nz in U, including diagonal */ int max_lnz_block ; /* max actual nz in L in any one block, incl. diag */ int max_unz_block ; /* max actual nz in U in any one block, incl. diag */ int *Pnum ; /* size n. final pivot permutation */ int *Pinv ; /* size n. inverse of final pivot permutation */ /* LU factors of each block */ int **Lbip ; /* TODO describe */ int **Ubip ; /* TODO describe */ int **Lblen ; /* TODO describe */ int **Ublen ; /* TODO describe */ void **LUbx ; /* L and U indices and entries (excl. diagonal of U) */ void **Udiag ; /* diagonal of U */ void *Singleton ; /* singleton values */ double *Rs ; /* size n. row scaling factors, NULL if no scaling */ /* permanent workspace for factorization and solve */ size_t worksize ; /* size (in bytes) of Work */ void *Work ; /* workspace */ void *Xwork ; /* alias into Numeric->Work */ int *Iwork ; /* alias into Numeric->Work */ /* off-diagonal entries */ int *Offp ; /* TODO describe */ int *Offi ; /* TODO describe */ void *Offx ; /* TODO describe */ } klu_numeric ; /* -------------------------------------------------------------------------- */ /* KLU control parameters and statistics */ /* -------------------------------------------------------------------------- */ /* return values of klu */ #define KLU_OK 0 #define KLU_SINGULAR (1) /* status > 0 is a warning, not an error */ #define KLU_OUT_OF_MEMORY (-2) #define KLU_INVALID (-3) #define KLU_TOO_LARGE (-4) /* integer overflow has occured */ typedef struct { /* ---------------------------------------------------------------------- */ /* parameters */ /* ---------------------------------------------------------------------- */ double tol ; /* pivot tolerance for diagonal preference */ double growth ; /* realloc growth size */ double initmem_amd ; /* init. memory size with AMD: c*nnz(L) + n */ double initmem ; /* init. memory size: c*nnz(A) + n */ int btf ; /* use BTF pre-ordering, or not */ int ordering ; /* 0: AMD, 1: COLAMD, 2: user P and Q, * 3: user function */ int scale ; /* row scaling: -1: none (and no error check), * 0: none, 1: sum, 2: max */ /* memory management routines */ void *(*malloc_memory) (size_t) ; /* pointer to malloc */ void *(*realloc_memory) (void *, size_t) ; /* pointer to realloc */ void (*free_memory) (void *) ; /* pointer to free */ void *(*calloc_memory) (size_t, size_t) ; /* pointer to calloc */ /* pointer to user ordering function */ int (*user_order) (int, int *, int *, int *, void *) ; /* pointer to user data, passed unchanged as the last parameter to the * user ordering function (optional, the user function need not use this * information). */ void *user_data ; int halt_if_singular ; /* how to handle a singular matrix: * FALSE: keep going. Return a Numeric object with a zero U(k,k). A * divide-by-zero may occur when computing L(:,k). The Numeric object * can be passed to klu_solve (a divide-by-zero will occur). It can * also be safely passed to klu_refactor. * TRUE: stop quickly. klu_factor will free the partially-constructed * Numeric object. klu_refactor will not free it, but will leave the * numerical values only partially defined. This is the default. */ /* ---------------------------------------------------------------------- */ /* statistics */ /* ---------------------------------------------------------------------- */ int status ; /* KLU_OK if OK, < 0 if error */ int nrealloc ; /* # of reallocations of L and U */ int structural_rank ; /* 0 to n-1 if the matrix is structurally rank * deficient (as determined by maxtrans). -1 if not computed. n if the * matrix has full structural rank. This is computed by klu_analyze * if a BTF preordering is requested. */ int numerical_rank ; /* First k for which a zero U(k,k) was found, * if the matrix was singular (in the range 0 to n-1). n if the matrix * has full rank. This is not a true rank-estimation. It just reports * where the first zero pivot was found. -1 if not computed. * Computed by klu_factor and klu_refactor. */ int singular_col ; /* n if the matrix is not singular. If in the * range 0 to n-1, this is the column index of the original matrix A that * corresponds to the column of U that contains a zero diagonal entry. * -1 if not computed. Computed by klu_factor and klu_refactor. */ int noffdiag ; /* # of off-diagonal pivots, -1 if not computed */ /* statistic determined in klu_flops: */ double flops ; /* actual factorization flop count */ } klu_common ; /* -------------------------------------------------------------------------- */ /* klu_analyze: pre-orderings and analyzes a matrix with BTF and AMD */ /* -------------------------------------------------------------------------- */ /* Order the matrix with BTF (or not), then order each block with AMD, COLAMD, * a natural ordering, or with a user-provided ordering function */ klu_symbolic *klu_analyze ( /* inputs, not modified */ int n, /* A is n-by-n */ int Ap [ ], /* size n+1, column pointers */ int Ai [ ], /* size nz, row indices */ klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_analyze_given: analyzes a matrix using given P and Q */ /* -------------------------------------------------------------------------- */ /* Order the matrix with BTF (or not), then use natural or given ordering * Puser and Quser on the blocks. Puser and Quser are interpretted as identity * if NULL. */ klu_symbolic *klu_analyze_given ( /* inputs, not modified */ int n, /* A is n-by-n */ int Ap [ ], /* size n+1, column pointers */ int Ai [ ], /* size nz, row indices */ int Puser [ ], /* size n, user's row permutation (may be NULL) */ int Quser [ ], /* size n, user's column permutation (may be NULL) */ klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_factor: factors a matrix using the klu_analyze results */ /* -------------------------------------------------------------------------- */ klu_numeric *klu_factor /* returns KLU_OK if OK, < 0 if error */ ( /* inputs, not modified */ int Ap [ ], /* size n+1, column pointers */ int Ai [ ], /* size nz, row indices */ double Ax [ ], klu_symbolic *Symbolic, klu_common *Common ) ; klu_numeric *klu_z_factor /* returns KLU_OK if OK, < 0 if error */ ( /* inputs, not modified */ int Ap [ ], /* size n+1, column pointers */ int Ai [ ], /* size nz, row indices */ double Ax [ ], klu_symbolic *Symbolic, klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_free_symbolic: destroys the Symbolic object */ /* -------------------------------------------------------------------------- */ int klu_free_symbolic ( klu_symbolic **Symbolic, klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_free_numeric: destroys the Numeric object */ /* -------------------------------------------------------------------------- */ int klu_free_numeric ( klu_numeric **Numeric, klu_common *Common ) ; int klu_z_free_numeric ( klu_numeric **Numeric, klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_solve: solves Ax=b using the Symbolic and Numeric objects */ /* -------------------------------------------------------------------------- */ int klu_solve ( /* inputs, not modified */ klu_symbolic *Symbolic, klu_numeric *Numeric, int ldim, /* leading dimension of B */ int nrhs, /* number of right-hand-sides */ /* right-hand-side on input, overwritten with solution to Ax=b on output */ double B [ ], klu_common *Common ) ; int klu_z_solve ( /* inputs, not modified */ klu_symbolic *Symbolic, klu_numeric *Numeric, int ldim, /* leading dimension of B */ int nrhs, /* number of right-hand-sides */ /* right-hand-side on input, overwritten with solution to Ax=b on output */ double B [ ], klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_tsolve: solves A'x=b using the Symbolic and Numeric objects */ /* -------------------------------------------------------------------------- */ int klu_tsolve ( /* inputs, not modified */ klu_symbolic *Symbolic, klu_numeric *Numeric, int ldim, /* leading dimension of B */ int nrhs, /* number of right-hand-sides */ /* right-hand-side on input, overwritten with solution to Ax=b on output */ double B [ ], klu_common *Common ) ; int klu_z_tsolve ( /* inputs, not modified */ klu_symbolic *Symbolic, klu_numeric *Numeric, int ldim, /* leading dimension of B */ int nrhs, /* number of right-hand-sides */ /* right-hand-side on input, overwritten with solution to Ax=b on output */ double B [ ], int conj_solve, /* TRUE: conjugate solve, FALSE: solve A.'x=b */ klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_refactor: refactorizes matrix with same ordering as klu_factor */ /* -------------------------------------------------------------------------- */ int klu_refactor /* return TRUE if successful, FALSE otherwise */ ( /* inputs, not modified */ int Ap [ ], /* size n+1, column pointers */ int Ai [ ], /* size nz, row indices */ double Ax [ ], klu_symbolic *Symbolic, /* input, and numerical values modified on output */ klu_numeric *Numeric, klu_common *Common ) ; int klu_z_refactor /* return TRUE if successful, FALSE otherwise */ ( /* inputs, not modified */ int Ap [ ], /* size n+1, column pointers */ int Ai [ ], /* size nz, row indices */ double Ax [ ], klu_symbolic *Symbolic, /* input, and numerical values modified on output */ klu_numeric *Numeric, klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_sort: sorts the columns of the LU factorization */ /* -------------------------------------------------------------------------- */ int klu_sort ( /* inputs, not modified */ klu_symbolic *Symbolic, /* input/output */ klu_numeric *Numeric, klu_common *Common ) ; int klu_z_sort ( /* inputs, not modified */ klu_symbolic *Symbolic, /* input/output */ klu_numeric *Numeric, klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_flops: determines # of flops performed in numeric factorzation */ /* -------------------------------------------------------------------------- */ int klu_flops ( /* inputs, not modified */ klu_symbolic *Symbolic, klu_numeric *Numeric, /* input/output */ klu_common *Common ) ; int klu_z_flops ( /* inputs, not modified */ klu_symbolic *Symbolic, klu_numeric *Numeric, /* input/output */ klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_defaults: sets default control parameters */ /* -------------------------------------------------------------------------- */ int klu_defaults ( klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_growth */ /* -------------------------------------------------------------------------- */ int klu_growth ( int Ap [ ], int Ai [ ], double Ax [ ], klu_symbolic *Symbolic, klu_numeric *Numeric, double *growth, /* reciprocal pivot growth */ klu_common *Common ) ; int klu_z_growth ( int Ap [ ], int Ai [ ], double Ax [ ], klu_symbolic *Symbolic, klu_numeric *Numeric, double *growth, /* reciprocal pivot growth */ klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_condest */ /* -------------------------------------------------------------------------- */ int klu_condest ( int Ap [ ], double Ax [ ], klu_symbolic *Symbolic, klu_numeric *Numeric, double *condest, /* Output parameter : condition number */ klu_common *Common ) ; int klu_z_condest ( int Ap [ ], double Ax [ ], klu_symbolic *Symbolic, klu_numeric *Numeric, double *condest, /* Output parameter : condition number */ klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_scale */ /* -------------------------------------------------------------------------- */ int klu_scale /* return TRUE if successful, FALSE otherwise */ ( /* inputs, not modified */ int scale, /* <0: none, no error check; 0: none, 1: sum, 2: max */ int n, int Ap [ ], /* size n+1, column pointers */ int Ai [ ], /* size nz, row indices */ double Ax [ ], /* outputs, not defined on input */ double Rs [ ], /* workspace, not defined on input or output */ int W [ ], /* size n, can be NULL */ klu_common *Common ) ; int klu_z_scale /* return TRUE if successful, FALSE otherwise */ ( /* inputs, not modified */ int scale, /* <0: none, no error check; 0: none, 1: sum, 2: max */ int n, int Ap [ ], /* size n+1, column pointers */ int Ai [ ], /* size nz, row indices */ double Ax [ ], /* outputs, not defined on input */ double Rs [ ], /* workspace, not defined on input or output */ int W [ ], /* size n, can be NULL */ klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_extract */ /* -------------------------------------------------------------------------- */ int klu_extract /* returns TRUE if successful, FALSE otherwise */ ( /* inputs: */ klu_numeric *Numeric, klu_symbolic *Symbolic, /* outputs, all of which must be allocated on input */ /* L */ int *Lp, /* size n+1 */ int *Li, /* size nnz(L) */ double *Lx, /* size nnz(L) */ /* U */ int *Up, /* size n+1 */ int *Ui, /* size nnz(U) */ double *Ux, /* size nnz(U) */ /* F */ int *Fp, /* size n+1 */ int *Fi, /* size nnz(F) */ double *Fx, /* size nnz(F) */ /* P, row permutation */ int *P, /* size n */ /* Q, column permutation */ int *Q, /* size n */ /* Rs, scale factors */ double *Rs, /* size n */ /* R, block boundaries */ int *R /* size nblocks+1 */ ) ; int klu_z_extract /* returns TRUE if successful, FALSE otherwise */ ( /* inputs: */ klu_numeric *Numeric, klu_symbolic *Symbolic, /* outputs, all of which must be allocated on input */ /* L */ int *Lp, /* size n+1 */ int *Li, /* size nnz(L) */ double *Lx, /* size nnz(L) */ #ifdef COMPLEX double *Lz, /* size nnz(L) for the complex case, ignored if real */ #endif /* U */ int *Up, /* size n+1 */ int *Ui, /* size nnz(U) */ double *Ux, /* size nnz(U) */ #ifdef COMPLEX double *Uz, /* size nnz(U) for the complex case, ignored if real */ #endif /* F */ int *Fp, /* size n+1 */ int *Fi, /* size nnz(F) */ double *Fx, /* size nnz(F) */ #ifdef COMPLEX double *Fz, /* size nnz(F) for the complex case, ignored if real */ #endif /* P, row permutation */ int *P, /* size n */ /* Q, column permutation */ int *Q, /* size n */ /* Rs, scale factors */ double *Rs, /* size n */ /* R, block boundaries */ int *R /* size nblocks+1 */ ) ; /* -------------------------------------------------------------------------- */ /* KLU memory management routines */ /* -------------------------------------------------------------------------- */ void *klu_malloc /* returns pointer to the newly malloc'd block */ ( /* ---- input ---- */ size_t n, /* number of items */ size_t size, /* size of each item */ /* --------------- */ klu_common *Common ) ; void *klu_free /* always returns NULL */ ( /* ---- in/out --- */ void *p, /* block of memory to free */ /* --------------- */ klu_common *Common ) ; void *klu_realloc /* returns pointer to reallocated block */ ( /* ---- input ---- */ size_t nnew, /* requested # of items in reallocated block */ size_t size, /* size of each item */ /* ---- in/out --- */ void *p, /* block of memory to realloc */ /* --------------- */ klu_common *Common ) ; /* -------------------------------------------------------------------------- */ /* klu_rcond: compute min(abs(diag(U))) / max(abs(diag(U))) */ /* -------------------------------------------------------------------------- */ int klu_rcond ( klu_symbolic *Symbolic, /* input, not modified */ klu_numeric *Numeric, /* input, not modified */ double *rcond, /* output (pointer to a scalar) */ klu_common *Common ) ; int klu_z_rcond ( klu_symbolic *Symbolic, /* input, not modified */ klu_numeric *Numeric, /* input, not modified */ double *rcond, /* output (pointer to a scalar) */ klu_common *Common ) ; /* ========================================================================== */ /* === KLU version ========================================================== */ /* ========================================================================== */ /* All versions of KLU include these definitions. * As an example, to test if the version you are using is 1.2 or later: * * if (KLU_VERSION >= KLU_VERSION_CODE (1,2)) ... * * This also works during compile-time: * * #if (KLU >= KLU_VERSION_CODE (1,2)) * printf ("This is version 1.2 or later\n") ; * #else * printf ("This is an early version\n") ; * #endif */ #define KLU_DATE "Dec 12, 2006" #define KLU_VERSION_CODE(main,sub) ((main) * 1000 + (sub)) #define KLU_MAIN_VERSION 0 #define KLU_SUB_VERSION 11 #define KLU_VERSION KLU_VERSION_CODE(KLU_MAIN_VERSION,KLU_SUB_VERSION) #ifdef __cplusplus } #endif #endif