398 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
			
		
		
	
	
			398 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
// =============================================================================
 | 
						|
// === spqr.hpp ================================================================
 | 
						|
// =============================================================================
 | 
						|
 | 
						|
// Internal definitions and non-user-callable routines.  This should not be
 | 
						|
// included in the user's code.
 | 
						|
 | 
						|
#ifndef SPQR_INTERNAL_H
 | 
						|
#define SPQR_INTERNAL_H
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// include files
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
#include "UFconfig.h"
 | 
						|
extern "C" {
 | 
						|
#include "cholmod_core.h"
 | 
						|
#include "cholmod_blas.h"
 | 
						|
}
 | 
						|
#include "SuiteSparseQR_definitions.h"
 | 
						|
#include <stdlib.h>
 | 
						|
#include <math.h>
 | 
						|
#include <float.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <cstring>
 | 
						|
 | 
						|
#include <complex>
 | 
						|
typedef std::complex<double> Complex ;
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// debugging and printing control
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
// force debugging off
 | 
						|
#ifndef NDEBUG
 | 
						|
#define NDEBUG
 | 
						|
#endif
 | 
						|
 | 
						|
// force printing off
 | 
						|
#ifndef NPRINT
 | 
						|
#define NPRINT
 | 
						|
#endif
 | 
						|
 | 
						|
// uncomment the following line to turn on debugging (SPQR will be slow!)
 | 
						|
/*
 | 
						|
#undef NDEBUG
 | 
						|
*/
 | 
						|
 | 
						|
// uncomment the following line to turn on printing (LOTS of output!)
 | 
						|
/*
 | 
						|
#undef NPRINT
 | 
						|
*/
 | 
						|
 | 
						|
// uncomment the following line to turn on expensive debugging (very slow!)
 | 
						|
/*
 | 
						|
#define DEBUG_EXPENSIVE
 | 
						|
*/
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// Int is defined at UF_long, from UFconfig.h
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
#define Int UF_long
 | 
						|
#define Int_max UF_long_max
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// basic macros
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
#define MIN(a,b) (((a) < (b)) ? (a) : (b))
 | 
						|
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
 | 
						|
#define EMPTY (-1)
 | 
						|
#define TRUE 1
 | 
						|
#define FALSE 0 
 | 
						|
#define IMPLIES(p,q) (!(p) || (q))
 | 
						|
 | 
						|
// NULL should already be defined, but ensure it is here.
 | 
						|
#ifndef NULL
 | 
						|
#define NULL ((void *) 0)
 | 
						|
#endif
 | 
						|
 | 
						|
// column-major indexing; A[i,j] is A (INDEX (i,j,lda))
 | 
						|
#define INDEX(i,j,lda) ((i) + ((j)*(lda)))
 | 
						|
 | 
						|
// 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))
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// additional include files
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
#ifdef MATLAB_MEX_FILE
 | 
						|
#include "mex.h"
 | 
						|
#endif
 | 
						|
 | 
						|
#define ITYPE CHOLMOD_LONG
 | 
						|
#define DTYPE CHOLMOD_DOUBLE
 | 
						|
#define ID UF_long_id
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
#define ERROR(status,msg) \
 | 
						|
    printf ("CHOLMOD error: %s\n",msg) // Kai: disable cholmod_l_error to prevent from including tons of files
 | 
						|
 | 
						|
// 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 (cc->status != CHOLMOD_OUT_OF_MEMORY) \
 | 
						|
	{ \
 | 
						|
	    ERROR (CHOLMOD_INVALID, NULL) ; \
 | 
						|
	} \
 | 
						|
	return (result) ; \
 | 
						|
    } \
 | 
						|
}
 | 
						|
 | 
						|
// Return if Common is NULL or invalid
 | 
						|
#define RETURN_IF_NULL_COMMON(result) \
 | 
						|
{ \
 | 
						|
    if (cc == NULL) \
 | 
						|
    { \
 | 
						|
	return (result) ; \
 | 
						|
    } \
 | 
						|
    if (cc->itype != ITYPE || cc->dtype != DTYPE) \
 | 
						|
    { \
 | 
						|
	cc->status = CHOLMOD_INVALID ; \
 | 
						|
	return (result) ; \
 | 
						|
    } \
 | 
						|
}
 | 
						|
 | 
						|
#define RETURN_IF_XTYPE_INVALID(A,result) \
 | 
						|
{ \
 | 
						|
    if (A->xtype != xtype) \
 | 
						|
    { \
 | 
						|
        ERROR (CHOLMOD_INVALID, "invalid xtype") ; \
 | 
						|
        return (result) ; \
 | 
						|
    } \
 | 
						|
}
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// debugging and printing macros
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
#ifndef NDEBUG
 | 
						|
 | 
						|
    #ifdef MATLAB_MEX_FILE
 | 
						|
 | 
						|
        // #define ASSERT(e) mxAssert (e, "error: ")
 | 
						|
 | 
						|
        extern char spqr_mx_debug_string [200] ;
 | 
						|
        char *spqr_mx_id (int line) ;
 | 
						|
 | 
						|
        #define ASSERT(e) \
 | 
						|
            ((e) ? (void) 0 : \
 | 
						|
            mexErrMsgIdAndTxt (spqr_mx_id (__LINE__), \
 | 
						|
            "assert: (" #e ") file:"  __FILE__ ))
 | 
						|
 | 
						|
    #else
 | 
						|
 | 
						|
        #include <assert.h>
 | 
						|
        #define ASSERT(e) assert (e)
 | 
						|
 | 
						|
    #endif
 | 
						|
 | 
						|
    #define DEBUG(e) e
 | 
						|
    #ifdef DEBUG_EXPENSIVE
 | 
						|
        #define DEBUG2(e) e
 | 
						|
        #define ASSERT2(e) ASSERT(e)
 | 
						|
    #else
 | 
						|
        #define DEBUG2(e)
 | 
						|
        #define ASSERT2(e)
 | 
						|
    #endif
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
    #define ASSERT(e)
 | 
						|
    #define ASSERT2(e)
 | 
						|
    #define DEBUG(e)
 | 
						|
    #define DEBUG2(e)
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef NPRINT
 | 
						|
 | 
						|
    #ifdef MATLAB_MEX_FILE
 | 
						|
        #define PR(e) mexPrintf e
 | 
						|
    #else
 | 
						|
        #define PR(e) printf e
 | 
						|
    #endif
 | 
						|
 | 
						|
    #define PRVAL(e) spqrDebug_print (e)
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
    #define PR(e)
 | 
						|
    #define PRVAL(e)
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
// For counting flops; disabled if TBB is used or timing not enabled
 | 
						|
// -----------------------------------------------------------------------------
 | 
						|
 | 
						|
#if defined(TIMING)
 | 
						|
#define FLOP_COUNT(f) { if (cc->SPQR_grain <= 1) cc->other1 [0] += (f) ; }
 | 
						|
#else
 | 
						|
#define FLOP_COUNT(f)
 | 
						|
#endif
 | 
						|
 | 
						|
template <typename Entry> void spqr_larftb
 | 
						|
(
 | 
						|
		// inputs, not modified (V is modified and then restored on output)
 | 
						|
		int method,     // 0,1,2,3
 | 
						|
		Int m,          // C is m-by-n
 | 
						|
		Int n,
 | 
						|
		Int k,          // V is v-by-k
 | 
						|
										// for methods 0 and 1, v = m,
 | 
						|
										// for methods 2 and 3, v = n
 | 
						|
		Int ldc,        // leading dimension of C
 | 
						|
		Int ldv,        // leading dimension of V
 | 
						|
		Entry *V,       // V is v-by-k, unit lower triangular (diag not stored)
 | 
						|
		Entry *Tau,     // size k, the k Householder coefficients
 | 
						|
 | 
						|
		// input/output
 | 
						|
		Entry *C,       // C is m-by-n, with leading dimension ldc
 | 
						|
 | 
						|
		// workspace, not defined on input or output
 | 
						|
		Entry *W,       // for methods 0,1: size k*k + n*k
 | 
						|
										// for methods 2,3: size k*k + m*k
 | 
						|
		cholmod_common *cc
 | 
						|
) ;
 | 
						|
 | 
						|
// returns rank of F, or 0 on error
 | 
						|
template <typename Entry> Int spqr_front
 | 
						|
(
 | 
						|
    // input, not modified
 | 
						|
    Int m,              // F is m-by-n with leading dimension m
 | 
						|
    Int n,
 | 
						|
    Int npiv,           // number of pivot columns
 | 
						|
    double tol,         // a column is flagged as dead if its norm is <= tol
 | 
						|
    Int ntol,           // apply tol only to first ntol pivot columns
 | 
						|
    Int fchunk,         // block size for compact WY Householder reflections,
 | 
						|
                        // treated as 1 if fchunk <= 1
 | 
						|
 | 
						|
    // input/output
 | 
						|
    Entry *F,           // frontal matrix F of size m-by-n
 | 
						|
    Int *Stair,         // size n, entries F (Stair[k]:m-1, k) are all zero,
 | 
						|
                        // and remain zero on output.
 | 
						|
    char *Rdead,        // size npiv; all zero on input.  If k is dead,
 | 
						|
                        // Rdead [k] is set to 1
 | 
						|
 | 
						|
    // output, not defined on input
 | 
						|
    Entry *Tau,         // size n, Householder coefficients
 | 
						|
 | 
						|
    // workspace, undefined on input and output
 | 
						|
    Entry *W,           // size b*(n+b), where b = min (fchunk,n,m)
 | 
						|
 | 
						|
    // input/output
 | 
						|
    double *wscale,
 | 
						|
    double *wssq,
 | 
						|
 | 
						|
    cholmod_common *cc  // for cc->hypotenuse function
 | 
						|
) ;
 | 
						|
 | 
						|
 | 
						|
// =============================================================================
 | 
						|
// === spqr_conj ===============================================================
 | 
						|
// =============================================================================
 | 
						|
 | 
						|
inline double spqr_conj (double x)
 | 
						|
{
 | 
						|
    return (x) ;
 | 
						|
}
 | 
						|
 | 
						|
inline Complex spqr_conj (Complex x)
 | 
						|
{
 | 
						|
    return (std::conj (x)) ;
 | 
						|
}
 | 
						|
 | 
						|
// =============================================================================
 | 
						|
// === spqr_abs ================================================================
 | 
						|
// =============================================================================
 | 
						|
 | 
						|
inline double spqr_abs (double x, cholmod_common *cc)       // cc is unused
 | 
						|
{
 | 
						|
    return (fabs (x)) ;
 | 
						|
}
 | 
						|
 | 
						|
inline double spqr_abs (Complex x, cholmod_common *cc)
 | 
						|
{
 | 
						|
    return (cc->hypotenuse (x.real ( ), x.imag ( ))) ;
 | 
						|
}
 | 
						|
 | 
						|
// =============================================================================
 | 
						|
// === BLAS interface ==========================================================
 | 
						|
// =============================================================================
 | 
						|
 | 
						|
// To compile SuiteSparseQR with 64-bit BLAS, use -DBLAS64.  See also
 | 
						|
// CHOLMOD/Include/cholmod_blas.h
 | 
						|
 | 
						|
extern "C" {
 | 
						|
#include "cholmod_blas.h"
 | 
						|
}
 | 
						|
 | 
						|
#ifdef SUN64
 | 
						|
 | 
						|
#define BLAS_DNRM2    dnrm2_64_
 | 
						|
#define LAPACK_DLARF  dlarf_64_
 | 
						|
#define LAPACK_DLARFG dlarfg_64_
 | 
						|
#define LAPACK_DLARFT dlarft_64_
 | 
						|
#define LAPACK_DLARFB dlarfb_64_
 | 
						|
 | 
						|
#define BLAS_DZNRM2   dznrm2_64_
 | 
						|
#define LAPACK_ZLARF  zlarf_64_
 | 
						|
#define LAPACK_ZLARFG zlarfg_64_
 | 
						|
#define LAPACK_ZLARFT zlarft_64_
 | 
						|
#define LAPACK_ZLARFB zlarfb_64_
 | 
						|
 | 
						|
#elif defined (BLAS_NO_UNDERSCORE)
 | 
						|
 | 
						|
#define BLAS_DNRM2    dnrm2
 | 
						|
#define LAPACK_DLARF  dlarf
 | 
						|
#define LAPACK_DLARFG dlarfg
 | 
						|
#define LAPACK_DLARFT dlarft
 | 
						|
#define LAPACK_DLARFB dlarfb
 | 
						|
 | 
						|
#define BLAS_DZNRM2   dznrm2
 | 
						|
#define LAPACK_ZLARF  zlarf
 | 
						|
#define LAPACK_ZLARFG zlarfg
 | 
						|
#define LAPACK_ZLARFT zlarft
 | 
						|
#define LAPACK_ZLARFB zlarfb
 | 
						|
 | 
						|
#else
 | 
						|
 | 
						|
#define BLAS_DNRM2    dnrm2_
 | 
						|
#define LAPACK_DLARF  dlarf_
 | 
						|
#define LAPACK_DLARFG dlarfg_
 | 
						|
#define LAPACK_DLARFT dlarft_
 | 
						|
#define LAPACK_DLARFB dlarfb_
 | 
						|
 | 
						|
#define BLAS_DZNRM2   dznrm2_
 | 
						|
#define LAPACK_ZLARF  zlarf_
 | 
						|
#define LAPACK_ZLARFG zlarfg_
 | 
						|
#define LAPACK_ZLARFT zlarft_
 | 
						|
#define LAPACK_ZLARFB zlarfb_
 | 
						|
 | 
						|
#endif
 | 
						|
 | 
						|
// =============================================================================
 | 
						|
// === BLAS and LAPACK prototypes ==============================================
 | 
						|
// =============================================================================
 | 
						|
 | 
						|
extern "C"
 | 
						|
{
 | 
						|
 | 
						|
void LAPACK_DLARFT (char *direct, char *storev, BLAS_INT *n, BLAS_INT *k,
 | 
						|
    double *V, BLAS_INT *ldv, double *Tau, double *T, BLAS_INT *ldt) ;
 | 
						|
 | 
						|
void LAPACK_ZLARFT (char *direct, char *storev, BLAS_INT *n, BLAS_INT *k,
 | 
						|
    Complex *V, BLAS_INT *ldv, Complex *Tau, Complex *T, BLAS_INT *ldt) ;
 | 
						|
 | 
						|
void LAPACK_DLARFB (char *side, char *trans, char *direct, char *storev,
 | 
						|
    BLAS_INT *m, BLAS_INT *n, BLAS_INT *k, double *V, BLAS_INT *ldv,
 | 
						|
    double *T, BLAS_INT *ldt, double *C, BLAS_INT *ldc, double *Work,
 | 
						|
    BLAS_INT *ldwork) ;
 | 
						|
 | 
						|
void LAPACK_ZLARFB (char *side, char *trans, char *direct, char *storev,
 | 
						|
    BLAS_INT *m, BLAS_INT *n, BLAS_INT *k, Complex *V, BLAS_INT *ldv,
 | 
						|
    Complex *T, BLAS_INT *ldt, Complex *C, BLAS_INT *ldc, Complex *Work,
 | 
						|
    BLAS_INT *ldwork) ;
 | 
						|
 | 
						|
double BLAS_DNRM2 (BLAS_INT *n, double *X, BLAS_INT *incx) ;
 | 
						|
 | 
						|
double BLAS_DZNRM2 (BLAS_INT *n, Complex *X, BLAS_INT *incx) ;
 | 
						|
 | 
						|
void LAPACK_DLARFG (BLAS_INT *n, double *alpha, double *X, BLAS_INT *incx,
 | 
						|
    double *tau) ;
 | 
						|
 | 
						|
void LAPACK_ZLARFG (BLAS_INT *n, Complex *alpha, Complex *X, BLAS_INT *incx,
 | 
						|
    Complex *tau) ;
 | 
						|
 | 
						|
void LAPACK_DLARF (char *side, BLAS_INT *m, BLAS_INT *n, double *V,
 | 
						|
    BLAS_INT *incv, double *tau, double *C, BLAS_INT *ldc, double *Work) ;
 | 
						|
 | 
						|
void LAPACK_ZLARF (char *side, BLAS_INT *m, BLAS_INT *n, Complex *V,
 | 
						|
    BLAS_INT *incv, Complex *tau, Complex *C, BLAS_INT *ldc, Complex *Work) ;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
#endif
 |