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