summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK.hs17
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c29
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h2
4 files changed, 49 insertions, 1 deletions
diff --git a/README b/README
index efb32da..c034e2c 100644
--- a/README
+++ b/README
@@ -217,3 +217,5 @@ in the Haskell mailing lists for their help.
217 217
218- Pedro E. López de Teruel discovered the need of asm("finit") to 218- Pedro E. López de Teruel discovered the need of asm("finit") to
219 avoid the wrong NaNs produced by foreign functions. 219 avoid the wrong NaNs produced by foreign functions.
220
221- Reiner Pope added support for luSolve, based on (d|z)getrs.
diff --git a/lib/Numeric/LinearAlgebra/LAPACK.hs b/lib/Numeric/LinearAlgebra/LAPACK.hs
index 83db901..d78b506 100644
--- a/lib/Numeric/LinearAlgebra/LAPACK.hs
+++ b/lib/Numeric/LinearAlgebra/LAPACK.hs
@@ -19,7 +19,7 @@ module Numeric.LinearAlgebra.LAPACK (
19 linearSolveR, linearSolveC, 19 linearSolveR, linearSolveC,
20 linearSolveLSR, linearSolveLSC, 20 linearSolveLSR, linearSolveLSC,
21 linearSolveSVDR, linearSolveSVDC, 21 linearSolveSVDR, linearSolveSVDC,
22 luR, luC, 22 luR, luC, lusR,
23 cholS, cholH, 23 cholS, cholH,
24 qrR, qrC, 24 qrR, qrC,
25 hessR, hessC, 25 hessR, hessC,
@@ -337,3 +337,18 @@ luAux f st a = unsafePerformIO $ do
337 return (lu, map (pred.round) (toList piv)) 337 return (lu, map (pred.round) (toList piv))
338 where n = rows a 338 where n = rows a
339 m = cols a 339 m = cols a
340
341
342-----------------------------------------------------------------------------------
343foreign import ccall "LAPACK/lapack-aux.h luS_l_R" dgetrs :: TMVMM
344
345lusR :: Matrix Double -> [Int] -> Matrix Double -> Matrix Double
346lusR a piv b = lusR' (fmat a) piv (fmat b)
347
348lusR' a piv b = unsafePerformIO $ do
349 x <- createMatrix ColumnMajor n m
350 app4 dgetrs mat a vec piv' mat b mat x "lusR"
351 return x
352 where n = rows b
353 m = cols b
354 piv' = fromList (map (fromIntegral.succ) piv) :: Vector Double
diff --git a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
index 310f6ee..de3cc98 100644
--- a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
+++ b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
@@ -20,6 +20,9 @@
20#define OK return 0; 20#define OK return 0;
21#endif 21#endif
22 22
23#define TRACEMAT(M) {int q; printf(" %d x %d: ",M##r,M##c); \
24 for(q=0;q<M##r*M##c;q++) printf("%.1f ",M##p[q]); printf("\n");}
25
23#define CHECK(RES,CODE) MACRO(if(RES) return CODE;) 26#define CHECK(RES,CODE) MACRO(if(RES) return CODE;)
24 27
25#define BAD_SIZE 2000 28#define BAD_SIZE 2000
@@ -814,3 +817,29 @@ int lu_l_C(KCMAT(a), DVEC(ipiv), CMAT(r)) {
814 free(auxipiv); 817 free(auxipiv);
815 OK 818 OK
816} 819}
820
821
822//////////////////// LU substitution /////////////////////////
823char charN = 'N';
824
825int luS_l_R(DMAT(a), KDVEC(ipiv), KDMAT(b), DMAT(x)) {
826 integer m = ar;
827 integer n = ac;
828 integer mrhs = br;
829 integer nrhs = bc;
830
831 REQUIRES(m==n && m==mrhs && m==ipivn,BAD_SIZE);
832 integer* auxipiv = (integer*)malloc(n*sizeof(integer));
833 int k;
834 for (k=0; k<n; k++) {
835 auxipiv[k] = (integer)ipivp[k];
836 }
837 integer res;
838 memcpy(xp,bp,mrhs*nrhs*sizeof(double));
839 integer ldb = mrhs;
840 integer lda = n;
841 dgetrs_ (&charN,&n,&nrhs,ap,&lda,auxipiv,xp,&ldb,&res);
842 CHECK(res,res);
843 free(auxipiv);
844 OK
845}
diff --git a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h
index 79e52be..e98e9dc 100644
--- a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h
+++ b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h
@@ -84,3 +84,5 @@ int schur_l_C(KCMAT(a), CMAT(u), CMAT(s));
84 84
85int lu_l_R(KDMAT(a), DVEC(ipiv), DMAT(r)); 85int lu_l_R(KDMAT(a), DVEC(ipiv), DMAT(r));
86int lu_l_C(KCMAT(a), DVEC(ipiv), CMAT(r)); 86int lu_l_C(KCMAT(a), DVEC(ipiv), CMAT(r));
87
88int luS_l_R(DMAT(a), KDVEC(ipiv), KDMAT(b), DMAT(x));