📄 spdefs.h
字号:
{ (to).Real -= (from_a).Real * (from_b).Real + \
(from_a).Imag * (from_b).Imag; \
(to).Imag -= (from_a).Real * (from_b).Imag - \
(from_a).Imag * (from_b).Real; \
}
/*
* Macro functions that provide complex division.
*/
/* Complex division: to = num / den */
#define CMPLX_DIV(to,num,den) \
{ RealNumber r_, s_; \
if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \
((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
s_ = (den).Real + r_*(den).Imag; \
(to).Real = ((num).Real + r_*(num).Imag)/s_; \
(to).Imag = ((num).Imag - r_*(num).Real)/s_; \
} \
else \
{ r_ = (den).Real / (den).Imag; \
s_ = (den).Imag + r_*(den).Real; \
(to).Real = (r_*(num).Real + (num).Imag)/s_; \
(to).Imag = (r_*(num).Imag - (num).Real)/s_; \
} \
}
/* Complex division and assignment: num /= den */
#define CMPLX_DIV_ASSIGN(num,den) \
{ RealNumber r_, s_, t_; \
if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \
((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
s_ = (den).Real + r_*(den).Imag; \
t_ = ((num).Real + r_*(num).Imag)/s_; \
(num).Imag = ((num).Imag - r_*(num).Real)/s_; \
(num).Real = t_; \
} \
else \
{ r_ = (den).Real / (den).Imag; \
s_ = (den).Imag + r_*(den).Real; \
t_ = (r_*(num).Real + (num).Imag)/s_; \
(num).Imag = (r_*(num).Imag - (num).Real)/s_; \
(num).Real = t_; \
} \
}
/* Complex reciprocation: to = 1.0 / den */
#define CMPLX_RECIPROCAL(to,den) \
{ RealNumber r_; \
if (((den).Real >= (den).Imag AND (den).Real > -(den).Imag) OR \
((den).Real < (den).Imag AND (den).Real <= -(den).Imag)) \
{ r_ = (den).Imag / (den).Real; \
(to).Imag = -r_*((to).Real = 1.0/((den).Real + r_*(den).Imag)); \
} \
else \
{ r_ = (den).Real / (den).Imag; \
(to).Real = -r_*((to).Imag = -1.0/((den).Imag + r_*(den).Real));\
} \
}
/*
* ASSERT and ABORT
*
* Macro used to assert that if the code is working correctly, then
* a condition must be true. If not, then execution is terminated
* and an error message is issued stating that there is an internal
* error and giving the file and line number. These assertions are
* not evaluated unless the DEBUG flag is true.
*/
#if DEBUG
#define ASSERT(condition) \
{ if (NOT(condition)) \
{ (void)fflush(stdout); \
(void)fprintf(stderr, "sparse: internal error detected in file `%s' at line %d.\n assertion `%s' failed.\n",\
__FILE__, __LINE__, spcQUOTE(condition) ); \
(void)fflush(stderr); \
abort(); \
} \
}
#else
#define ASSERT(condition)
#endif
#if DEBUG
#define vASSERT(condition,message) \
{ if (NOT(condition)) \
vABORT(message); \
}
#else
#define vASSERT(condition,message)
#endif
#if DEBUG
#define vABORT(message) \
{ (void)fflush(stdout); \
(void)fprintf(stderr, "sparse: internal error detected in file `%s' at line %d.\n %s.\n", __FILE__, __LINE__, message );\
(void)fflush(stderr); \
abort(); \
}
#define ABORT() \
{ (void)fflush(stdout); \
(void)fprintf(stderr, "sparse: internal error detected in file `%s' at line %d.\n", __FILE__, __LINE__ ); \
(void)fflush(stderr); \
abort(); \
}
#else
#define vABORT(message) abort()
#define ABORT() abort()
#endif
/*
* IMAGINARY VECTORS
*
* The imaginary vectors iRHS and iSolution are only needed when the
* options spCOMPLEX and spSEPARATED_COMPLEX_VECTORS are set. The following
* macro makes it easy to include or exclude these vectors as needed.
*/
#if spCOMPLEX AND spSEPARATED_COMPLEX_VECTORS
#define IMAG_VECTORS , iRHS, iSolution
#define IMAG_RHS , iRHS
#define IMAG_RHS_DECL , RealVector iRHS
#define IMAG_VECT_DECL , RealVector iRHS, RealVector iSolution
#else
#define IMAG_VECTORS
#define IMAG_RHS
#define IMAG_RHS_DECL
#define IMAG_VECT_DECL
#endif
/*
* MEMORY ALLOCATION
*/
spcEXTERN void *malloc(size_t size);
spcEXTERN void *calloc(size_t nmemb, size_t size);
spcEXTERN void *realloc(void *ptr, size_t size);
spcEXTERN void free(void *ptr);
spcEXTERN void abort(void);
#define ALLOC(type,number) ((type *)malloc((unsigned)(sizeof(type)*(number))))
#define REALLOC(ptr,type,number) \
ptr = (type *)realloc((char *)ptr,(unsigned)(sizeof(type)*(number)))
#define FREE(ptr) { if ((ptr) != NULL) free((char *)(ptr)); (ptr) = NULL; }
/* Calloc that properly handles allocating a cleared vector. */
#define CALLOC(ptr,type,number) \
{ int i; ptr = ALLOC(type, number); \
if (ptr != (type *)NULL) \
for (i=(number)-1;i>=0; i--) ptr[i] = (type) 0; \
}
/*
* Utility Functions
*/
/*
* Compute the product of two intergers while avoiding overflow.
* Used when computing Markowitz products.
*/
#define spcMarkoProd(product, op1, op2) \
if (( (op1) > LARGEST_SHORT_INTEGER AND (op2) != 0) OR \
( (op2) > LARGEST_SHORT_INTEGER AND (op1) != 0)) \
{ double fProduct = (double)(op1) * (double)(op2); \
if (fProduct >= LARGEST_LONG_INTEGER) \
(product) = LARGEST_LONG_INTEGER; \
else \
(product) = (long)fProduct; \
} \
else (product) = (op1)*(op2);
/*
* REAL NUMBER
*/
/* Begin `RealNumber'. */
typedef spREAL RealNumber, *RealVector;
/*
* COMPLEX NUMBER DATA STRUCTURE
*
* >>> Structure fields:
* Real (RealNumber)
* The real portion of the number. Real must be the first
* field in this structure.
* Imag (RealNumber)
* The imaginary portion of the number. This field must follow
* immediately after Real.
*/
/* Begin `ComplexNumber'. */
typedef struct
{ RealNumber Real;
RealNumber Imag;
} ComplexNumber, *ComplexVector;
/*
* MATRIX ELEMENT DATA STRUCTURE
*
* Every nonzero element in the matrix is stored in a dynamically allocated
* MatrixElement structure. These structures are linked together in an
* orthogonal linked list. Two different MatrixElement structures exist.
* One is used when only real matrices are expected, it is missing an entry
* for imaginary data. The other is used if complex matrices are expected.
* It contains an entry for imaginary data.
*
* >>> Structure fields:
* Real (RealNumber)
* The real portion of the value of the element. Real must be the first
* field in this structure.
* Imag (RealNumber)
* The imaginary portion of the value of the element. If the matrix
* routines are not compiled to handle complex matrices, then this
* field does not exist. If it exists, it must follow immediately after
* Real.
* Row (int)
* The row number of the element.
* Col (int)
* The column number of the element.
* NextInRow (struct MatrixElement *)
* NextInRow contains a pointer to the next element in the row to the
* right of this element. If this element is the last nonzero in the
* row then NextInRow contains NULL.
* NextInCol (struct MatrixElement *)
* NextInCol contains a pointer to the next element in the column below
* this element. If this element is the last nonzero in the column then
* NextInCol contains NULL.
* pInitInfo (spGenericPtr)
* Pointer to user data used for initialization of the matrix element.
* Initialized to NULL.
*
* >>> Type definitions:
* ElementPtr
* A pointer to a MatrixElement.
* ArrayOfElementPtrs
* An array of ElementPtrs. Used for FirstInRow, FirstInCol and
* Diag pointer arrays.
*/
/* Begin `MatrixElement'. */
struct MatrixElement
{ RealNumber Real;
#if spCOMPLEX
RealNumber Imag;
#endif
int Row;
int Col;
struct MatrixElement *NextInRow;
struct MatrixElement *NextInCol;
#if INITIALIZE
spGenericPtr pInitInfo;
#endif
};
typedef struct MatrixElement *ElementPtr;
typedef ElementPtr *ArrayOfElementPtrs;
/*
* ALLOCATION DATA STRUCTURE
*
* The sparse matrix routines keep track of all memory that is allocated by
* the operating system so the memory can later be freed. This is done by
* saving the pointers to all the chunks of memory that are allocated to a
* particular matrix in an allocation list. That list is organized as a
* linked list so that it can grow without a priori bounds.
*
* >>> Structure fields:
* AllocatedPtr (void *)
* Pointer to chunk of memory that has been allocated for the matrix.
* NextRecord (struct AllocationRecord *)
* Pointer to the next allocation record.
*/
/* Begin `AllocationRecord'. */
struct AllocationRecord
{ void *AllocatedPtr;
struct AllocationRecord *NextRecord;
};
typedef struct AllocationRecord *AllocationListPtr;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -