Implemented spDeterminant_KLU
This commit is contained in:
parent
4f7a0acb7a
commit
8d53bf8791
|
|
@ -55,6 +55,7 @@ typedef struct sSMPmatrix {
|
|||
#ifdef KLU
|
||||
void SMPmatrix_CSC (SMPmatrix *) ;
|
||||
void SMPnnz (SMPmatrix *) ;
|
||||
void spDeterminant_KLU (SMPmatrix *, int *, double *, double *) ;
|
||||
#endif
|
||||
int SMPaddElt( SMPmatrix *, int , int , double );
|
||||
double * SMPmakeElt( SMPmatrix * , int , int );
|
||||
|
|
|
|||
|
|
@ -540,6 +540,239 @@ SMPgetError (SMPmatrix *Matrix, int *Col, int *Row)
|
|||
}
|
||||
}
|
||||
|
||||
#ifdef KLU
|
||||
void
|
||||
spDeterminant_KLU (SMPmatrix *Matrix, int *pExponent, RealNumber *pDeterminant, RealNumber *piDeterminant)
|
||||
{
|
||||
int I, Size ;
|
||||
RealNumber Norm, nr, ni ;
|
||||
ComplexNumber Pivot, cDeterminant, Udiag ;
|
||||
|
||||
int *P, *Q ;
|
||||
double *Rs, *Ux, *Uz ;
|
||||
unsigned int nSwap ;
|
||||
|
||||
#define NORM(a) (nr = ABS((a).Real), ni = ABS((a).Imag), MAX (nr,ni))
|
||||
|
||||
*pExponent = 0 ;
|
||||
|
||||
if (Matrix->CKTkluCommon->status == KLU_SINGULAR)
|
||||
{
|
||||
*pDeterminant = 0.0 ;
|
||||
if (Matrix->CKTkluMatrixIsComplex == CKTkluMatrixComplex)
|
||||
{
|
||||
*piDeterminant = 0.0 ;
|
||||
}
|
||||
return ;
|
||||
}
|
||||
|
||||
Size = Matrix->CKTkluN ;
|
||||
I = 0 ;
|
||||
|
||||
P = (int *) malloc ((size_t)Matrix->CKTkluN * sizeof (int)) ;
|
||||
Q = (int *) malloc ((size_t)Matrix->CKTkluN * sizeof (int)) ;
|
||||
|
||||
Ux = (double *) malloc ((size_t)Matrix->CKTkluN * sizeof (double)) ;
|
||||
|
||||
Rs = (double *) malloc ((size_t)Matrix->CKTkluN * sizeof (double)) ;
|
||||
|
||||
if (Matrix->CKTkluMatrixIsComplex == CKTkluMatrixComplex) /* Complex Case. */
|
||||
{
|
||||
cDeterminant.Real = 1.0 ;
|
||||
cDeterminant.Imag = 0.0 ;
|
||||
|
||||
Uz = (double *) malloc ((size_t)Matrix->CKTkluN * sizeof (double)) ;
|
||||
/*
|
||||
int *Lp, *Li, *Up, *Ui, *Fp, *Fi, *P, *Q ;
|
||||
double *Lx, *Lz, *Ux, *Uz, *Fx, *Fz, *Rs ;
|
||||
Lp = (int *) malloc (((size_t)Matrix->CKTkluN + 1) * sizeof (int)) ;
|
||||
Li = (int *) malloc ((size_t)Matrix->CKTkluNumeric->lnz * sizeof (int)) ;
|
||||
Lx = (double *) malloc ((size_t)Matrix->CKTkluNumeric->lnz * sizeof (double)) ;
|
||||
Lz = (double *) malloc ((size_t)Matrix->CKTkluNumeric->lnz * sizeof (double)) ;
|
||||
Up = (int *) malloc (((size_t)Matrix->CKTkluN + 1) * sizeof (int)) ;
|
||||
Ui = (int *) malloc ((size_t)Matrix->CKTkluNumeric->unz * sizeof (int)) ;
|
||||
Ux = (double *) malloc ((size_t)Matrix->CKTkluNumeric->unz * sizeof (double)) ;
|
||||
Uz = (double *) malloc ((size_t)Matrix->CKTkluNumeric->unz * sizeof (double)) ;
|
||||
Fp = (int *) malloc (((size_t)Matrix->CKTkluN + 1) * sizeof (int)) ;
|
||||
Fi = (int *) malloc ((size_t)Matrix->CKTkluNumeric->Offp [Matrix->CKTkluN] * sizeof (int)) ;
|
||||
Fx = (double *) malloc ((size_t)Matrix->CKTkluNumeric->Offp [Matrix->CKTkluN] * sizeof (double)) ;
|
||||
Fz = (double *) malloc ((size_t)Matrix->CKTkluNumeric->Offp [Matrix->CKTkluN] * sizeof (double)) ;
|
||||
klu_z_extract (Matrix->CKTkluNumeric, Matrix->CKTkluSymbolic,
|
||||
Lp, Li, Lx, Lz,
|
||||
Up, Ui, Ux, Uz,
|
||||
Fp, Fi, Fx, Fz,
|
||||
P, Q, Rs, NULL,
|
||||
Matrix->CKTkluCommon) ;
|
||||
*/
|
||||
klu_z_extract_Udiag (Matrix->CKTkluNumeric, Matrix->CKTkluSymbolic, Ux, Uz, P, Q, Rs, Matrix->CKTkluCommon) ;
|
||||
/*
|
||||
for (I = 0 ; I < Matrix->CKTkluNumeric->lnz ; I++)
|
||||
{
|
||||
printf ("L - Value: %-.9g\t%-.9g\n", Lx [I], Lz [I]) ;
|
||||
}
|
||||
for (I = 0 ; I < Matrix->CKTkluNumeric->unz ; I++)
|
||||
{
|
||||
printf ("U - Value: %-.9g\t%-.9g\n", Ux [I], Uz [I]) ;
|
||||
}
|
||||
for (I = 0 ; I < Matrix->CKTkluNumeric->Offp [Matrix->CKTkluN] ; I++)
|
||||
{
|
||||
printf ("F - Value: %-.9g\t%-.9g\n", Fx [I], Fz [I]) ;
|
||||
}
|
||||
|
||||
for (I = 0 ; I < Matrix->CKTkluN ; I++)
|
||||
{
|
||||
printf ("U - Value: %-.9g\t%-.9g\n", Ux [I], Uz [I]) ;
|
||||
}
|
||||
*/
|
||||
nSwap = 0 ;
|
||||
for (I = 0 ; I < Matrix->CKTkluN ; I++)
|
||||
{
|
||||
if (P [I] != I || Q [I] != I)
|
||||
{
|
||||
nSwap++ ;
|
||||
}
|
||||
}
|
||||
/*
|
||||
free (Lp) ;
|
||||
free (Li) ;
|
||||
free (Lx) ;
|
||||
free (Lz) ;
|
||||
free (Up) ;
|
||||
free (Ui) ;
|
||||
free (Fp) ;
|
||||
free (Fi) ;
|
||||
free (Fx) ;
|
||||
free (Fz) ;
|
||||
*/
|
||||
I = 0 ;
|
||||
while (I < Size)
|
||||
{
|
||||
Udiag.Real = 1 / (Ux [I] * Rs [I]) ;
|
||||
Udiag.Imag = Uz [I] * Rs [I] ;
|
||||
|
||||
// printf ("Udiag.Real: %-.9g\tUdiag.Imag %-.9g\n", Udiag.Real, Udiag.Imag) ;
|
||||
|
||||
CMPLX_RECIPROCAL (Pivot, Udiag) ;
|
||||
CMPLX_MULT_ASSIGN (cDeterminant, Pivot) ;
|
||||
|
||||
// printf ("cDeterminant.Real: %-.9g\tcDeterminant.Imag %-.9g\n", cDeterminant.Real, cDeterminant.Imag) ;
|
||||
|
||||
/* Scale Determinant. */
|
||||
Norm = NORM (cDeterminant) ;
|
||||
if (Norm != 0.0)
|
||||
{
|
||||
while (Norm >= 1.0e12)
|
||||
{
|
||||
cDeterminant.Real *= 1.0e-12 ;
|
||||
cDeterminant.Imag *= 1.0e-12 ;
|
||||
*pExponent += 12 ;
|
||||
Norm = NORM (cDeterminant) ;
|
||||
}
|
||||
while (Norm < 1.0e-12)
|
||||
{
|
||||
cDeterminant.Real *= 1.0e12 ;
|
||||
cDeterminant.Imag *= 1.0e12 ;
|
||||
*pExponent -= 12 ;
|
||||
Norm = NORM (cDeterminant) ;
|
||||
}
|
||||
}
|
||||
I++ ;
|
||||
}
|
||||
|
||||
/* Scale Determinant again, this time to be between 1.0 <= x < 10.0. */
|
||||
Norm = NORM (cDeterminant) ;
|
||||
if (Norm != 0.0)
|
||||
{
|
||||
while (Norm >= 10.0)
|
||||
{
|
||||
cDeterminant.Real *= 0.1 ;
|
||||
cDeterminant.Imag *= 0.1 ;
|
||||
(*pExponent)++ ;
|
||||
Norm = NORM (cDeterminant) ;
|
||||
}
|
||||
while (Norm < 1.0)
|
||||
{
|
||||
cDeterminant.Real *= 10.0 ;
|
||||
cDeterminant.Imag *= 10.0 ;
|
||||
(*pExponent)-- ;
|
||||
Norm = NORM (cDeterminant) ;
|
||||
}
|
||||
}
|
||||
if (nSwap % 2 != 0)
|
||||
{
|
||||
CMPLX_NEGATE (cDeterminant) ;
|
||||
}
|
||||
|
||||
*pDeterminant = cDeterminant.Real ;
|
||||
*piDeterminant = cDeterminant.Imag ;
|
||||
|
||||
free (Uz) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Real Case. */
|
||||
*pDeterminant = 1.0 ;
|
||||
|
||||
klu_extract_Udiag (Matrix->CKTkluNumeric, Matrix->CKTkluSymbolic, Ux, P, Q, Rs, Matrix->CKTkluCommon) ;
|
||||
|
||||
nSwap = 0 ;
|
||||
for (I = 0 ; I < Matrix->CKTkluN ; I++)
|
||||
{
|
||||
if (P [I] != I || Q [I] != I)
|
||||
{
|
||||
nSwap++ ;
|
||||
}
|
||||
}
|
||||
|
||||
while (I < Size)
|
||||
{
|
||||
*pDeterminant /= Ux [I] ;
|
||||
|
||||
/* Scale Determinant. */
|
||||
if (*pDeterminant != 0.0)
|
||||
{
|
||||
while (ABS(*pDeterminant) >= 1.0e12)
|
||||
{
|
||||
*pDeterminant *= 1.0e-12 ;
|
||||
*pExponent += 12 ;
|
||||
}
|
||||
while (ABS(*pDeterminant) < 1.0e-12)
|
||||
{
|
||||
*pDeterminant *= 1.0e12 ;
|
||||
*pExponent -= 12 ;
|
||||
}
|
||||
}
|
||||
I++ ;
|
||||
}
|
||||
|
||||
/* Scale Determinant again, this time to be between 1.0 <= x <
|
||||
10.0. */
|
||||
if (*pDeterminant != 0.0)
|
||||
{
|
||||
while (ABS(*pDeterminant) >= 10.0)
|
||||
{
|
||||
*pDeterminant *= 0.1 ;
|
||||
(*pExponent)++ ;
|
||||
}
|
||||
while (ABS(*pDeterminant) < 1.0)
|
||||
{
|
||||
*pDeterminant *= 10.0 ;
|
||||
(*pExponent)-- ;
|
||||
}
|
||||
}
|
||||
if (nSwap % 2 != 0)
|
||||
{
|
||||
*pDeterminant = -*pDeterminant ;
|
||||
}
|
||||
}
|
||||
|
||||
free (P) ;
|
||||
free (Q) ;
|
||||
free (Ux) ;
|
||||
free (Rs) ;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* SMPcProdDiag()
|
||||
* note: obsolete for Spice3d2 and later
|
||||
|
|
|
|||
Loading…
Reference in New Issue