401 lines
14 KiB
C
401 lines
14 KiB
C
/* ========================================================================== */
|
|
/* === Include/cholmod_internal.h =========================================== */
|
|
/* ========================================================================== */
|
|
|
|
/* -----------------------------------------------------------------------------
|
|
* CHOLMOD/Include/cholmod_internal.h.
|
|
* Copyright (C) 2005-2006, Univ. of Florida. Author: Timothy A. Davis
|
|
* CHOLMOD/Include/cholmod_internal.h is licensed under Version 2.1 of the GNU
|
|
* Lesser General Public License. See lesser.txt for a text of the license.
|
|
* CHOLMOD is also available under other licenses; contact authors for details.
|
|
* http://www.cise.ufl.edu/research/sparse
|
|
* -------------------------------------------------------------------------- */
|
|
|
|
/* CHOLMOD internal include file.
|
|
*
|
|
* This file contains internal definitions for CHOLMOD, not meant to be included
|
|
* in user code. They define macros that are not prefixed with CHOLMOD_. This
|
|
* file can safely #include'd in user code if you want to make use of the
|
|
* macros defined here, and don't mind the possible name conflicts with your
|
|
* code, however.
|
|
*
|
|
* Required by all CHOLMOD routines. Not required by any user routine that
|
|
* uses CHOLMOMD. Unless debugging is enabled, this file does not require any
|
|
* CHOLMOD module (not even the Core module).
|
|
*
|
|
* If debugging is enabled, all CHOLMOD modules require the Check module.
|
|
* Enabling debugging requires that this file be editted. Debugging cannot be
|
|
* enabled with a compiler flag. This is because CHOLMOD is exceedingly slow
|
|
* when debugging is enabled. Debugging is meant for development of CHOLMOD
|
|
* itself, not by users of CHOLMOD.
|
|
*/
|
|
|
|
#ifndef CHOLMOD_INTERNAL_H
|
|
#define CHOLMOD_INTERNAL_H
|
|
|
|
/* ========================================================================== */
|
|
/* === large file I/O ======================================================= */
|
|
/* ========================================================================== */
|
|
|
|
/* Definitions for large file I/O must come before any other #includes. If
|
|
* this causes problems (may not be portable to all platforms), then compile
|
|
* CHOLMOD with -DNLARGEFILE. You must do this for MATLAB 6.5 and earlier,
|
|
* for example. */
|
|
|
|
//#include "cholmod_io64.h"
|
|
|
|
/* ========================================================================== */
|
|
/* === debugging and basic includes ========================================= */
|
|
/* ========================================================================== */
|
|
|
|
/* turn off debugging */
|
|
#ifndef SPQR_NDEBUG
|
|
#define SPQR_NDEBUG
|
|
#endif
|
|
|
|
/* Uncomment this line to enable debugging. CHOLMOD will be very slow.
|
|
#undef SPQR_NDEBUG
|
|
*/
|
|
|
|
#ifdef MATLAB_MEX_FILE
|
|
#include "mex.h"
|
|
#endif
|
|
|
|
#if !defined(NPRINT) || !defined(SPQR_NDEBUG)
|
|
#include <stdio.h>
|
|
#endif
|
|
|
|
#include <stddef.h>
|
|
#include <math.h>
|
|
#include <limits.h>
|
|
#include <float.h>
|
|
#include <stdlib.h>
|
|
|
|
/* ========================================================================== */
|
|
/* === basic definitions ==================================================== */
|
|
/* ========================================================================== */
|
|
|
|
/* Some non-conforming compilers insist on defining TRUE and FALSE. */
|
|
#undef TRUE
|
|
#undef FALSE
|
|
#define TRUE 1
|
|
#define FALSE 0
|
|
#define BOOLEAN(x) ((x) ? TRUE : FALSE)
|
|
|
|
/* NULL should already be defined, but ensure it is here. */
|
|
#ifndef NULL
|
|
#define NULL ((void *) 0)
|
|
#endif
|
|
|
|
/* FLIP is a "negation about -1", and is used to mark an integer i that is
|
|
* normally non-negative. FLIP (EMPTY) is EMPTY. FLIP of a number > EMPTY
|
|
* is negative, and FLIP of a number < EMTPY is positive. FLIP (FLIP (i)) = i
|
|
* for all integers i. UNFLIP (i) is >= EMPTY. */
|
|
#define EMPTY (-1)
|
|
#define FLIP(i) (-(i)-2)
|
|
#define UNFLIP(i) (((i) < EMPTY) ? FLIP (i) : (i))
|
|
|
|
/* MAX and MIN are not safe to use for NaN's */
|
|
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
|
#define MAX3(a,b,c) (((a) > (b)) ? (MAX (a,c)) : (MAX (b,c)))
|
|
#define MAX4(a,b,c,d) (((a) > (b)) ? (MAX3 (a,c,d)) : (MAX3 (b,c,d)))
|
|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
|
|
#define IMPLIES(p,q) (!(p) || (q))
|
|
|
|
/* find the sign: -1 if x < 0, 1 if x > 0, zero otherwise.
|
|
* Not safe for NaN's */
|
|
#define SIGN(x) (((x) < 0) ? (-1) : (((x) > 0) ? 1 : 0))
|
|
|
|
/* round up an integer x to a multiple of s */
|
|
#define ROUNDUP(x,s) ((s) * (((x) + ((s) - 1)) / (s)))
|
|
|
|
#define ERROR(status,msg) \
|
|
CHOLMOD(error) (status, __FILE__, __LINE__, msg, Common)
|
|
|
|
/* Check a pointer and return if null. Set status to invalid, unless the
|
|
* status is already "out of memory" */
|
|
#define RETURN_IF_NULL(A,result) \
|
|
{ \
|
|
if ((A) == NULL) \
|
|
{ \
|
|
if (Common->status != CHOLMOD_OUT_OF_MEMORY) \
|
|
{ \
|
|
ERROR (CHOLMOD_INVALID, "argument missing") ; \
|
|
} \
|
|
return (result) ; \
|
|
} \
|
|
}
|
|
|
|
/* Return if Common is NULL or invalid */
|
|
#define RETURN_IF_NULL_COMMON(result) \
|
|
{ \
|
|
if (Common == NULL) \
|
|
{ \
|
|
return (result) ; \
|
|
} \
|
|
if (Common->itype != ITYPE || Common->dtype != DTYPE) \
|
|
{ \
|
|
Common->status = CHOLMOD_INVALID ; \
|
|
return (result) ; \
|
|
} \
|
|
}
|
|
|
|
#define IS_NAN(x) CHOLMOD_IS_NAN(x)
|
|
#define IS_ZERO(x) CHOLMOD_IS_ZERO(x)
|
|
#define IS_NONZERO(x) CHOLMOD_IS_NONZERO(x)
|
|
#define IS_LT_ZERO(x) CHOLMOD_IS_LT_ZERO(x)
|
|
#define IS_GT_ZERO(x) CHOLMOD_IS_GT_ZERO(x)
|
|
#define IS_LE_ZERO(x) CHOLMOD_IS_LE_ZERO(x)
|
|
|
|
/* 1e308 is a huge number that doesn't take many characters to print in a
|
|
* file, in CHOLMOD/Check/cholmod_read and _write. Numbers larger than this
|
|
* are interpretted as Inf, since sscanf doesn't read in Inf's properly.
|
|
* This assumes IEEE double precision arithmetic. DBL_MAX would be a little
|
|
* better, except that it takes too many digits to print in a file. */
|
|
#define HUGE_DOUBLE 1e308
|
|
|
|
/* ========================================================================== */
|
|
/* === int/UF_long and double/float definitions ============================= */
|
|
/* ========================================================================== */
|
|
|
|
/* CHOLMOD is designed for 3 types of integer variables:
|
|
*
|
|
* (1) all integers are int
|
|
* (2) most integers are int, some are UF_long
|
|
* (3) all integers are UF_long
|
|
*
|
|
* and two kinds of floating-point values:
|
|
*
|
|
* (1) double
|
|
* (2) float
|
|
*
|
|
* the complex types (ANSI-compatible complex, and MATLAB-compatable zomplex)
|
|
* are based on the double or float type, and are not selected here. They
|
|
* are typically selected via template routines.
|
|
*
|
|
* This gives 6 different modes in which CHOLMOD can be compiled (only the
|
|
* first two are currently supported):
|
|
*
|
|
* DINT double, int prefix: cholmod_
|
|
* DLONG double, UF_long prefix: cholmod_l_
|
|
* DMIX double, mixed int/UF_long prefix: cholmod_m_
|
|
* SINT float, int prefix: cholmod_si_
|
|
* SLONG float, UF_long prefix: cholmod_sl_
|
|
* SMIX float, mixed int/log prefix: cholmod_sm_
|
|
*
|
|
* These are selected with compile time flags (-DDLONG, for example). If no
|
|
* flag is selected, the default is DINT.
|
|
*
|
|
* All six versions use the same include files. The user-visible include files
|
|
* are completely independent of which int/UF_long/double/float version is being
|
|
* used. The integer / real types in all data structures (sparse, triplet,
|
|
* dense, common, and triplet) are defined at run-time, not compile-time, so
|
|
* there is only one "cholmod_sparse" data type. Void pointers are used inside
|
|
* that data structure to point to arrays of the proper type. Each data
|
|
* structure has an itype and dtype field which determines the kind of basic
|
|
* types used. These are defined in Include/cholmod_core.h.
|
|
*
|
|
* FUTURE WORK: support all six types (float, and mixed int/UF_long)
|
|
*
|
|
* UF_long is normally defined as long. However, for WIN64 it is __int64.
|
|
* It can also be redefined for other platforms, by modifying UFconfig.h.
|
|
*/
|
|
|
|
#include "UFconfig.h"
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* Size_max: the largest value of size_t */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#define Size_max ((size_t) (-1))
|
|
|
|
/* routines for doing arithmetic on size_t, and checking for overflow */
|
|
size_t cholmod_add_size_t (size_t a, size_t b, int *ok) ;
|
|
size_t cholmod_mult_size_t (size_t a, size_t k, int *ok) ;
|
|
size_t cholmod_l_add_size_t (size_t a, size_t b, int *ok) ;
|
|
size_t cholmod_l_mult_size_t (size_t a, size_t k, int *ok) ;
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* double (also complex double), UF_long */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#ifdef DLONG
|
|
#define Real double
|
|
#define Int UF_long
|
|
#define Int_max UF_long_max
|
|
#define CHOLMOD(name) cholmod_l_ ## name
|
|
#define LONG
|
|
#define DOUBLE
|
|
#define ITYPE CHOLMOD_LONG
|
|
#define DTYPE CHOLMOD_DOUBLE
|
|
#define ID UF_long_id
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* double, int/UF_long */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#elif defined (DMIX)
|
|
#error "mixed int/UF_long not yet supported"
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* single, int */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#elif defined (SINT)
|
|
#error "single-precision not yet supported"
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* single, UF_long */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#elif defined (SLONG)
|
|
#error "single-precision not yet supported"
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* single, int/UF_long */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#elif defined (SMIX)
|
|
#error "single-precision not yet supported"
|
|
|
|
/* -------------------------------------------------------------------------- */
|
|
/* double (also complex double), int: this is the default */
|
|
/* -------------------------------------------------------------------------- */
|
|
|
|
#else
|
|
|
|
#ifndef DINT
|
|
#define DINT
|
|
#endif
|
|
#define INT
|
|
#define DOUBLE
|
|
|
|
#define Real double
|
|
#define Int int
|
|
#define Int_max INT_MAX
|
|
#define CHOLMOD(name) cholmod_ ## name
|
|
#define ITYPE CHOLMOD_INT
|
|
#define DTYPE CHOLMOD_DOUBLE
|
|
#define ID "%d"
|
|
|
|
#endif
|
|
|
|
|
|
/* ========================================================================== */
|
|
/* === real/complex arithmetic ============================================== */
|
|
/* ========================================================================== */
|
|
|
|
//#include "cholmod_complexity.h"
|
|
|
|
/* ========================================================================== */
|
|
/* === Architecture and BLAS ================================================ */
|
|
/* ========================================================================== */
|
|
|
|
#define BLAS_OK Common->blas_ok
|
|
#include "cholmod_blas.h"
|
|
|
|
/* ========================================================================== */
|
|
/* === debugging definitions ================================================ */
|
|
/* ========================================================================== */
|
|
|
|
#ifndef SPQR_NDEBUG
|
|
|
|
#include <assert.h>
|
|
#include "cholmod.h"
|
|
|
|
/* The cholmod_dump routines are in the Check module. No CHOLMOD routine
|
|
* calls the cholmod_check_* or cholmod_print_* routines in the Check module,
|
|
* since they use Common workspace that may already be in use. Instead, they
|
|
* use the cholmod_dump_* routines defined there, which allocate their own
|
|
* workspace if they need it. */
|
|
|
|
#ifndef EXTERN
|
|
#define EXTERN extern
|
|
#endif
|
|
|
|
/* double, int */
|
|
EXTERN int cholmod_dump ;
|
|
EXTERN int cholmod_dump_malloc ;
|
|
UF_long cholmod_dump_sparse (cholmod_sparse *, const char *, cholmod_common *);
|
|
int cholmod_dump_factor (cholmod_factor *, const char *, cholmod_common *) ;
|
|
int cholmod_dump_triplet (cholmod_triplet *, const char *, cholmod_common *) ;
|
|
int cholmod_dump_dense (cholmod_dense *, const char *, cholmod_common *) ;
|
|
int cholmod_dump_subset (int *, size_t, size_t, const char *,
|
|
cholmod_common *) ;
|
|
int cholmod_dump_perm (int *, size_t, size_t, const char *, cholmod_common *) ;
|
|
int cholmod_dump_parent (int *, size_t, const char *, cholmod_common *) ;
|
|
void cholmod_dump_init (const char *, cholmod_common *) ;
|
|
int cholmod_dump_mem (const char *, UF_long, cholmod_common *) ;
|
|
void cholmod_dump_real (const char *, Real *, UF_long, UF_long, int, int,
|
|
cholmod_common *) ;
|
|
void cholmod_dump_super (UF_long, int *, int *, int *, int *, double *, int,
|
|
cholmod_common *) ;
|
|
int cholmod_dump_partition (UF_long, int *, int *, int *, int *, UF_long,
|
|
cholmod_common *) ;
|
|
int cholmod_dump_work(int, int, UF_long, cholmod_common *) ;
|
|
|
|
/* double, UF_long */
|
|
EXTERN int cholmod_l_dump ;
|
|
EXTERN int cholmod_l_dump_malloc ;
|
|
UF_long cholmod_l_dump_sparse (cholmod_sparse *, const char *,
|
|
cholmod_common *) ;
|
|
int cholmod_l_dump_factor (cholmod_factor *, const char *, cholmod_common *) ;
|
|
int cholmod_l_dump_triplet (cholmod_triplet *, const char *, cholmod_common *);
|
|
int cholmod_l_dump_dense (cholmod_dense *, const char *, cholmod_common *) ;
|
|
int cholmod_l_dump_subset (UF_long *, size_t, size_t, const char *,
|
|
cholmod_common *) ;
|
|
int cholmod_l_dump_perm (UF_long *, size_t, size_t, const char *,
|
|
cholmod_common *) ;
|
|
int cholmod_l_dump_parent (UF_long *, size_t, const char *, cholmod_common *) ;
|
|
void cholmod_l_dump_init (const char *, cholmod_common *) ;
|
|
int cholmod_l_dump_mem (const char *, UF_long, cholmod_common *) ;
|
|
void cholmod_l_dump_real (const char *, Real *, UF_long, UF_long, int, int,
|
|
cholmod_common *) ;
|
|
void cholmod_l_dump_super (UF_long, UF_long *, UF_long *, UF_long *, UF_long *,
|
|
double *, int, cholmod_common *) ;
|
|
int cholmod_l_dump_partition (UF_long, UF_long *, UF_long *, UF_long *,
|
|
UF_long *, UF_long, cholmod_common *) ;
|
|
int cholmod_l_dump_work(int, int, UF_long, cholmod_common *) ;
|
|
|
|
#define DEBUG_INIT(s,Common) { CHOLMOD(dump_init)(s, Common) ; }
|
|
#define ASSERT(expression) (assert (expression))
|
|
|
|
#define PRK(k,params) \
|
|
{ \
|
|
if (CHOLMOD(dump) >= (k) && Common->print_function != NULL) \
|
|
{ \
|
|
(Common->print_function) params ; \
|
|
} \
|
|
}
|
|
|
|
#define PRINT0(params) PRK (0, params)
|
|
#define PRINT1(params) PRK (1, params)
|
|
#define PRINT2(params) PRK (2, params)
|
|
#define PRINT3(params) PRK (3, params)
|
|
|
|
#define PRINTM(params) \
|
|
{ \
|
|
if (CHOLMOD(dump_malloc) > 0) \
|
|
{ \
|
|
printf params ; \
|
|
} \
|
|
}
|
|
|
|
#define DEBUG(statement) statement
|
|
|
|
#else
|
|
|
|
/* Debugging disabled (the normal case) */
|
|
#define PRK(k,params)
|
|
#define DEBUG_INIT(s,Common)
|
|
#define PRINT0(params)
|
|
#define PRINT1(params)
|
|
#define PRINT2(params)
|
|
#define PRINT3(params)
|
|
#define PRINTM(params)
|
|
#define ASSERT(expression)
|
|
#define DEBUG(statement)
|
|
#endif
|
|
|
|
#endif
|