committed by
Holger Vogt
7 changed files with 599 additions and 17 deletions
-
75src/include/ngspice/klu.h
-
8src/maths/KLU/Makefile.am
-
155src/maths/KLU/klu_multiply.c
-
132src/maths/KLU/klu_utils.c
-
6src/maths/KLU/klu_version.h
-
48src/maths/KLU/klusmp.c
-
192src/spicelib/analysis/cktsens.c
@ -0,0 +1,155 @@ |
|||||
|
#include "klu_internal.h" |
||||
|
|
||||
|
Int KLU_constant_multiply /* return TRUE if successful, FALSE otherwise */ |
||||
|
( |
||||
|
Int *Ap, |
||||
|
double *Ax, |
||||
|
Int n, |
||||
|
KLU_common *Common, |
||||
|
double constant |
||||
|
) |
||||
|
{ |
||||
|
Entry *Az ; |
||||
|
int i, j ; |
||||
|
|
||||
|
/* ---------------------------------------------------------------------- */ |
||||
|
/* check inputs */ |
||||
|
/* ---------------------------------------------------------------------- */ |
||||
|
|
||||
|
if (Common == NULL) |
||||
|
{ |
||||
|
return (FALSE) ; |
||||
|
} |
||||
|
|
||||
|
if (Ap == NULL || Ax == NULL) |
||||
|
{ |
||||
|
Common->status = KLU_INVALID ; |
||||
|
return (FALSE) ; |
||||
|
} |
||||
|
|
||||
|
Common->status = KLU_OK ; |
||||
|
|
||||
|
Az = (Entry *)Ax ; |
||||
|
|
||||
|
for (i = 0 ; i < n ; i++) |
||||
|
{ |
||||
|
for (j = Ap [i] ; j < Ap [i + 1] ; j++) |
||||
|
{ |
||||
|
|
||||
|
#ifdef COMPLEX |
||||
|
Az [j].Real *= constant ; |
||||
|
Az [j].Imag *= constant ; |
||||
|
#else |
||||
|
Az [j] *= constant ; |
||||
|
#endif |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return (TRUE) ; |
||||
|
} |
||||
|
|
||||
|
/* Macro function that multiplies two complex numbers and then adds them |
||||
|
* to another. to += mult_a * mult_b */ |
||||
|
#define CMPLX_MULT_ADD_ASSIGN(to,from_a,from_b) \ |
||||
|
{ (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; \ |
||||
|
} |
||||
|
|
||||
|
Int KLU_matrix_vector_multiply /* return TRUE if successful, FALSE otherwise */ |
||||
|
( |
||||
|
Int *Ap, /* CSR */ |
||||
|
Int *Ai, /* CSR */ |
||||
|
double *Ax, /* CSR */ |
||||
|
double *RHS, |
||||
|
double *Solution, |
||||
|
#ifdef COMPLEX |
||||
|
double *iRHS, |
||||
|
double *iSolution, |
||||
|
#endif |
||||
|
Int *IntToExtRowMap, |
||||
|
Int *IntToExtColMap, |
||||
|
Int n, |
||||
|
KLU_common *Common |
||||
|
) |
||||
|
{ |
||||
|
Entry *Az, *Intermediate, Sum ; |
||||
|
Int i, j, *pExtOrder ; |
||||
|
|
||||
|
/* ---------------------------------------------------------------------- */ |
||||
|
/* check inputs */ |
||||
|
/* ---------------------------------------------------------------------- */ |
||||
|
|
||||
|
if (Common == NULL) |
||||
|
{ |
||||
|
return (FALSE) ; |
||||
|
} |
||||
|
|
||||
|
if (Ap == NULL || Ai == NULL || Ax == NULL || RHS == NULL || Solution == NULL |
||||
|
|
||||
|
#ifdef COMPLEX |
||||
|
|| iRHS == NULL || iSolution == NULL |
||||
|
#endif |
||||
|
|
||||
|
) |
||||
|
{ |
||||
|
Common->status = KLU_INVALID ; |
||||
|
return (FALSE) ; |
||||
|
} |
||||
|
|
||||
|
Common->status = KLU_OK ; |
||||
|
|
||||
|
|
||||
|
Intermediate = (Entry *) malloc ((size_t)n * sizeof (Entry)) ; |
||||
|
|
||||
|
Az = (Entry *)Ax ; |
||||
|
|
||||
|
pExtOrder = &IntToExtColMap [n] ; |
||||
|
for (i = n - 1 ; i >= 0 ; i--) |
||||
|
{ |
||||
|
|
||||
|
#ifdef COMPLEX |
||||
|
Intermediate [i].Real = Solution [*(pExtOrder)] ; |
||||
|
Intermediate [i].Imag = iSolution [*(pExtOrder--)] ; |
||||
|
#else |
||||
|
Intermediate [i] = Solution [*(pExtOrder--)] ; |
||||
|
#endif |
||||
|
} |
||||
|
|
||||
|
pExtOrder = &IntToExtRowMap [n] ; |
||||
|
for (i = n - 1 ; i >= 0 ; i--) |
||||
|
{ |
||||
|
|
||||
|
#ifdef COMPLEX |
||||
|
Sum.Real = 0.0 ; |
||||
|
Sum.Imag = 0.0 ; |
||||
|
#else |
||||
|
Sum = 0.0 ; |
||||
|
#endif |
||||
|
|
||||
|
for (j = Ap [i] ; j < Ap [i + 1] ; j++) |
||||
|
{ |
||||
|
|
||||
|
#ifdef COMPLEX |
||||
|
CMPLX_MULT_ADD_ASSIGN (Sum, Az [j], Intermediate [Ai [j]]) ; |
||||
|
#else |
||||
|
Sum += Az [j] * Intermediate [Ai [j]] ; |
||||
|
#endif |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#ifdef COMPLEX |
||||
|
RHS [*(pExtOrder)] = Sum.Real ; |
||||
|
iRHS [*(pExtOrder--)] = Sum.Imag ; |
||||
|
#else |
||||
|
RHS [*(pExtOrder--)] = Sum ; |
||||
|
#endif |
||||
|
|
||||
|
} |
||||
|
|
||||
|
free (Intermediate) ; |
||||
|
|
||||
|
return (TRUE) ; |
||||
|
} |
||||
@ -0,0 +1,132 @@ |
|||||
|
#include "klu_internal.h" |
||||
|
|
||||
|
typedef struct sElement { |
||||
|
Int row ; |
||||
|
Int col ; |
||||
|
Entry val ; |
||||
|
} Element ; |
||||
|
|
||||
|
static int |
||||
|
CompareRow (const void *a, const void *b) |
||||
|
{ |
||||
|
Element *A = (Element *) a ; |
||||
|
Element *B = (Element *) b ; |
||||
|
|
||||
|
return |
||||
|
(A->row > B->row) ? 1 : |
||||
|
(A->row < B->row) ? -1 : |
||||
|
0 ; |
||||
|
} |
||||
|
|
||||
|
static void |
||||
|
Compress (Int *Ai, Int *Bp, int num_rows, int n_COO) |
||||
|
{ |
||||
|
int i, j ; |
||||
|
|
||||
|
for (i = 0 ; i <= Ai [0] ; i++) |
||||
|
Bp [i] = 0 ; |
||||
|
|
||||
|
j = Ai [0] + 1 ; |
||||
|
for (i = 1 ; i < n_COO ; i++) |
||||
|
{ |
||||
|
if (Ai [i] == Ai [i - 1] + 1) |
||||
|
{ |
||||
|
Bp [j] = i ; |
||||
|
j++ ; |
||||
|
} |
||||
|
else if (Ai [i] > Ai [i - 1] + 1) |
||||
|
{ |
||||
|
for ( ; j <= Ai [i] ; j++) |
||||
|
Bp [j] = i ; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
for ( ; j <= num_rows ; j++) |
||||
|
Bp [j] = i ; |
||||
|
} |
||||
|
|
||||
|
Int |
||||
|
KLU_convert_matrix_in_CSR /* return TRUE if successful, FALSE otherwise */ |
||||
|
( |
||||
|
Int *Ap_CSC, /* CSC */ |
||||
|
Int *Ai_CSC, /* CSC */ |
||||
|
double *Ax_CSC, /* CSC */ |
||||
|
Int *Ap_CSR, /* CSR */ |
||||
|
Int *Ai_CSR, /* CSR */ |
||||
|
double *Ax_CSR, /* CSR */ |
||||
|
Int n, |
||||
|
Int nz, |
||||
|
KLU_common *Common |
||||
|
) |
||||
|
{ |
||||
|
Element *MatrixCOO ; |
||||
|
Entry *Az_CSC, *Az_CSR ; |
||||
|
Int *Ap_COO, i, j, k ; |
||||
|
|
||||
|
/* ---------------------------------------------------------------------- */ |
||||
|
/* check inputs */ |
||||
|
/* ---------------------------------------------------------------------- */ |
||||
|
|
||||
|
if (Common == NULL) |
||||
|
{ |
||||
|
return (FALSE) ; |
||||
|
} |
||||
|
|
||||
|
if (Ap_CSC == NULL || Ai_CSC == NULL || Ax_CSC == NULL || Ap_CSR == NULL || Ai_CSR == NULL || Ax_CSR == NULL) |
||||
|
{ |
||||
|
Common->status = KLU_INVALID ; |
||||
|
return (FALSE) ; |
||||
|
} |
||||
|
|
||||
|
Common->status = KLU_OK ; |
||||
|
|
||||
|
|
||||
|
MatrixCOO = (Element *) malloc ((size_t)nz * sizeof (Element)) ; |
||||
|
Ap_COO = (Int *) malloc ((size_t)nz * sizeof (Int)) ; |
||||
|
|
||||
|
Az_CSC = (Entry *)Ax_CSC ; |
||||
|
Az_CSR = (Entry *)Ax_CSR ; |
||||
|
|
||||
|
k = 0 ; |
||||
|
for (i = 0 ; i < n ; i++) |
||||
|
{ |
||||
|
for (j = Ap_CSC [i] ; j < Ap_CSC [i + 1] ; j++) |
||||
|
{ |
||||
|
MatrixCOO [k].row = Ai_CSC [j] ; |
||||
|
MatrixCOO [k].col = i ; |
||||
|
|
||||
|
#ifdef COMPLEX |
||||
|
MatrixCOO [k].val.Real = Az_CSC [j].Real ; |
||||
|
MatrixCOO [k].val.Imag = Az_CSC [j].Imag ; |
||||
|
#else |
||||
|
MatrixCOO [k].val = Az_CSC [j] ; |
||||
|
#endif |
||||
|
|
||||
|
k++ ; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* Order the MatrixCOO along the rows */ |
||||
|
qsort (MatrixCOO, (size_t)nz, sizeof(Element), CompareRow) ; |
||||
|
|
||||
|
for (i = 0 ; i < nz ; i++) |
||||
|
{ |
||||
|
Ap_COO [i] = MatrixCOO [i].row ; |
||||
|
Ai_CSR [i] = MatrixCOO [i].col ; |
||||
|
|
||||
|
#ifdef COMPLEX |
||||
|
Az_CSR [i].Real = MatrixCOO [i].val.Real ; |
||||
|
Az_CSR [i].Imag = MatrixCOO [i].val.Imag ; |
||||
|
#else |
||||
|
Az_CSR [i] = MatrixCOO [i].val ; |
||||
|
#endif |
||||
|
|
||||
|
} |
||||
|
|
||||
|
Compress (Ap_COO, Ap_CSR, n, nz) ; |
||||
|
|
||||
|
free (MatrixCOO) ; |
||||
|
free (Ap_COO) ; |
||||
|
|
||||
|
return (TRUE) ; |
||||
|
} |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue