summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README20
-rw-r--r--hmatrix.cabal13
-rw-r--r--lib/Data/Packed/Internal/Common.hs5
-rw-r--r--lib/Data/Packed/Internal/auxi.c6
-rw-r--r--lib/Data/Packed/Internal/auxi.h2
-rw-r--r--lib/Numeric/LinearAlgebra/Algorithms.hs54
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c78
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h6
8 files changed, 19 insertions, 165 deletions
diff --git a/README b/README
index 3a260a4..efb32da 100644
--- a/README
+++ b/README
@@ -96,10 +96,6 @@ A number of illustrative programs are included in the examples folder.
96 96
97KNOWN PROBLEMS / BUGS ------------------------------- 97KNOWN PROBLEMS / BUGS -------------------------------
98 98
99- Compilation with -O -fasm on 32-bit machines produces strange
100 NaN's results on certain foreign calls. More info at
101 http://www.hmatrix.googlepages.com/bugs
102
103- On 64-bit machines the example "minimize.hs", when run from ghci, 99- On 64-bit machines the example "minimize.hs", when run from ghci,
104 produces a segmentation fault. It happens in the call to 100 produces a segmentation fault. It happens in the call to
105 gsl_multimin_fdfminimizer_alloc, inside the C wrapper. 101 gsl_multimin_fdfminimizer_alloc, inside the C wrapper.
@@ -108,17 +104,8 @@ KNOWN PROBLEMS / BUGS -------------------------------
108 program seems to work perfectly well. 104 program seems to work perfectly well.
109 105
110- On Ubuntu 6.06 LTS (Dapper) atlas3-sse2-dev (3.6.0-20) 106- On Ubuntu 6.06 LTS (Dapper) atlas3-sse2-dev (3.6.0-20)
111 produces segmentation faults when working with big matrices 107 produced segmentation faults when working with big matrices
112 on compiled programs. To expose the problem: 108 on compiled programs.
113
114 $ cd examples
115 $ ghc --make -O -fvia-C tests.hs
116 $ ./tests --big
117
118 If this crashes, just uninstall atlas3-sse2 and use atlas3-base-dev instead.
119 Fortunately, atlas3-sse2-dev seems to work well on Ubuntu 7.10 Gutsy.
120 A similar problem was reported at:
121 http://article.gmane.org/gmane.linux.debian.devel.bugs.general/323065
122 109
123- On distributions with old GSL versions you should comment out a couple of functions 110- On distributions with old GSL versions you should comment out a couple of functions
124 in the export lists of Ellint.hs and Debye.hs 111 in the export lists of Ellint.hs and Debye.hs
@@ -227,3 +214,6 @@ in the Haskell mailing lists for their help.
227 214
228- Dylan Alex Simon improved the numeric instances to allow optimized 215- Dylan Alex Simon improved the numeric instances to allow optimized
229 implementations of signum and abs on Vectors. 216 implementations of signum and abs on Vectors.
217
218- Pedro E. López de Teruel discovered the need of asm("finit") to
219 avoid the wrong NaNs produced by foreign functions.
diff --git a/hmatrix.cabal b/hmatrix.cabal
index 1ffcd4d..6bffaf9 100644
--- a/hmatrix.cabal
+++ b/hmatrix.cabal
@@ -29,13 +29,6 @@ flag unsafe
29 description: Compile the library with bound checking disabled. 29 description: Compile the library with bound checking disabled.
30 default: False 30 default: False
31 31
32flag no-workaround
33 description: Expose the NaN problem
34 default: False
35
36flag expose-bug
37 description: Expose the NaN problem with debug information
38 default: False
39 32
40library 33library
41 if flag(splitBase) 34 if flag(splitBase)
@@ -113,12 +106,6 @@ library
113 if flag(unsafe) 106 if flag(unsafe)
114 cpp-options: -DUNSAFE 107 cpp-options: -DUNSAFE
115 108
116 if arch(i386) && !flag(no-workaround) && !flag(expose-bug) && !flag(mkl)
117 cpp-options: -DWORKAROUND
118
119 if flag(expose-bug)
120 cpp-options: -DEXPOSEBUG
121
122 109
123 if flag(mkl) 110 if flag(mkl)
124 if arch(x86_64) 111 if arch(x86_64)
diff --git a/lib/Data/Packed/Internal/Common.hs b/lib/Data/Packed/Internal/Common.hs
index 3609bc2..bce9922 100644
--- a/lib/Data/Packed/Internal/Common.hs
+++ b/lib/Data/Packed/Internal/Common.hs
@@ -80,9 +80,14 @@ errorCode 2006 = "the input matrix is not positive definite"
80errorCode 2007 = "not yet supported in this OS" 80errorCode 2007 = "not yet supported in this OS"
81errorCode n = "code "++show n 81errorCode n = "code "++show n
82 82
83
84-- | clear the fpu
85foreign import ccall "auxi.h asm_finit" finit :: IO ()
86
83-- | check the error code 87-- | check the error code
84check :: String -> IO CInt -> IO () 88check :: String -> IO CInt -> IO ()
85check msg f = do 89check msg f = do
90 finit
86 err <- f 91 err <- f
87 when (err/=0) $ if err > 1024 92 when (err/=0) $ if err > 1024
88 then (error (msg++": "++errorCode err)) -- our errors 93 then (error (msg++": "++errorCode err)) -- our errors
diff --git a/lib/Data/Packed/Internal/auxi.c b/lib/Data/Packed/Internal/auxi.c
index 04dc7ad..bbb8cd4 100644
--- a/lib/Data/Packed/Internal/auxi.c
+++ b/lib/Data/Packed/Internal/auxi.c
@@ -149,3 +149,9 @@ int conjugate(KCVEC(x),CVEC(t)) {
149 } 149 }
150 OK 150 OK
151} 151}
152
153//---------------------------------------
154void asm_finit() {
155 asm("finit");
156}
157//---------------------------------------
diff --git a/lib/Data/Packed/Internal/auxi.h b/lib/Data/Packed/Internal/auxi.h
index 377a4a1..507a30d 100644
--- a/lib/Data/Packed/Internal/auxi.h
+++ b/lib/Data/Packed/Internal/auxi.h
@@ -26,3 +26,5 @@ const char * gsl_strerror (const int gsl_errno);
26int matrix_fscanf(char*filename, RMAT(a)); 26int matrix_fscanf(char*filename, RMAT(a));
27 27
28int conjugate(KCVEC(x),CVEC(t)); 28int conjugate(KCVEC(x),CVEC(t));
29
30void asm_finit();
diff --git a/lib/Numeric/LinearAlgebra/Algorithms.hs b/lib/Numeric/LinearAlgebra/Algorithms.hs
index 45298b5..e2fec9d 100644
--- a/lib/Numeric/LinearAlgebra/Algorithms.hs
+++ b/lib/Numeric/LinearAlgebra/Algorithms.hs
@@ -139,16 +139,8 @@ instance Field (Complex Double) where
139 qr = unpackQR . qrC 139 qr = unpackQR . qrC
140 hess = unpackHess hessC 140 hess = unpackHess hessC
141 schur = schurC 141 schur = schurC
142
143#if defined(WORKAROUND)
144 multiply = mulCW
145#else
146#if defined(EXPOSEBUG)
147 multiply = multiplyC
148#else
149 multiply = multiplyC3 142 multiply = multiplyC3
150#endif 143
151#endif
152 144
153-- | Eigenvalues and Eigenvectors of a complex hermitian or real symmetric matrix using lapack's dsyev or zheev. 145-- | Eigenvalues and Eigenvectors of a complex hermitian or real symmetric matrix using lapack's dsyev or zheev.
154-- 146--
@@ -639,47 +631,3 @@ multiplyC3 x y = unsafePerformIO $ multiply3 zgemm "cblas_zgemm" (fmat x) (fmat
639 return s 631 return s
640 -- if toLists s== toLists s then return s else error $ "HORROR " ++ (show (toLists s)) 632 -- if toLists s== toLists s then return s else error $ "HORROR " ++ (show (toLists s))
641 | otherwise = error $ st ++ " (matrix product) of nonconformant matrices" 633 | otherwise = error $ st ++ " (matrix product) of nonconformant matrices"
642
643-----------------------------------------------------------------------------------
644-- BLAS via auxiliary C
645-----------------------------------------------------------------------------------
646
647-- foreign import ccall "multiply.h multiplyR2" dgemmc :: TMMM
648-- foreign import ccall "multiply.h multiplyC2" zgemmc :: TCMCMCM
649--
650-- multiply2 f st a b
651-- | cols a == rows b = unsafePerformIO $ do
652-- s <- createMatrix ColumnMajor (rows a) (cols b)
653-- app3 f mat a mat b mat s st
654-- if toLists s== toLists s then return s else error $ "AYYY " ++ (show (toLists s))
655-- | otherwise = error $ st ++ " (matrix product) of nonconformant matrices"
656--
657-- multiplyR2 :: Matrix Double -> Matrix Double -> Matrix Double
658-- multiplyR2 a b = multiply2 dgemmc "dgemmc" (fmat a) (fmat b)
659--
660-- multiplyC2 :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
661-- multiplyC2 a b = multiply2 zgemmc "zgemmc" (fmat a) (fmat b)
662
663-----------------------------------------------------------------------------------
664-- direct C multiplication, to expose the NaN bug
665-----------------------------------------------------------------------------------
666
667-- foreign import ccall "multiply.h multiplyR" cmultiplyR :: TMMM
668foreign import ccall "multiply.h multiplyC" cmultiplyC :: TCMCMCM
669
670cmultiply f st a b
671-- | cols a == rows b =
672 = unsafePerformIO $ do
673 s <- createMatrix RowMajor (rows a) (cols b)
674 app3 f mat a mat b mat s st
675 if toLists s== toLists s
676 then return s
677 else error $ "NaN FOUND!! " ++ (show (toLists s))
678 -- return s
679-- | otherwise = error $ st ++ " (matrix product) of nonconformant matrices"
680
681-- multiplyR :: Matrix Double -> Matrix Double -> Matrix Double
682-- multiplyR a b = cmultiply cmultiplyR "cmultiplyR" (cmat a) (cmat b)
683
684multiplyC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
685multiplyC a b = cmultiply cmultiplyC "cmultiplyR" (cmat a) (cmat b)
diff --git a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
index 61cb002..310f6ee 100644
--- a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
+++ b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
@@ -814,81 +814,3 @@ int lu_l_C(KCMAT(a), DVEC(ipiv), CMAT(r)) {
814 free(auxipiv); 814 free(auxipiv);
815 OK 815 OK
816} 816}
817
818////////////////////////////////////////////////////////////
819
820// int multiplyR(KDMAT(a),KDMAT(b),DMAT(r)) {
821// REQUIRES(ac==br && ar==rr && bc==rc,BAD_SIZE);
822// int i,j,k;
823// for (i=0;i<ar;i++) {
824// for(j=0;j<bc;j++) {
825// double temp = 0;
826// for(k=0;k<ac;k++) {
827// temp += ap[i*ac+k]*bp[k*bc+j];
828// }
829// rp[i*rc+j] = temp;
830// }
831// }
832// OK
833// }
834
835
836int multiplyC(KCMAT(a),KCMAT(b),CMAT(r)) {
837 REQUIRES(ac==br && ar==rr && bc==rc,BAD_SIZE);
838 int i,j,k;
839 for (i=0;i<ar;i++) {
840 for(j=0;j<bc;j++) {
841 doublecomplex temp = {0,0};
842 for(k=0;k<ac;k++) {
843 doublecomplex A = ((doublecomplex*)ap)[i*ac+k];
844 doublecomplex B = ((doublecomplex*)bp)[k*bc+j];
845 double w = A.r * B.r - A.i * B.i;
846 double w1 = A.r * B.r;
847 double w2 = A.i * B.i;
848 if(w != w) {
849 printf("at : %d %d %d\n",i,j,k);
850 printf("%f %f %f\n",A.i,B.i, A.i * B.i);
851 printf("%f %f %f\n",A.i,B.i, w2);
852 exit(1);
853 }
854 temp.r += (w + w1-w2)/2;
855 //temp.r += w;
856 temp.i += A.r * B.i + A.i * B.r;
857 }
858 ((doublecomplex*)rp)[i*rc+j] = temp;
859 }
860 }
861 OK
862}
863
864// void dgemm_(char *, char *, integer *, integer *, integer *,
865// double *, const double *, integer *, const double *,
866// integer *, double *, double *, integer *);
867//
868// void zgemm_(char *, char *, integer *, integer *, integer *,
869// doublecomplex *, const doublecomplex *, integer *, const doublecomplex *,
870// integer *, doublecomplex *, doublecomplex *, integer *);
871//
872//
873// int multiplyR2(KDMAT(a),KDMAT(b),DMAT(r)) {
874// REQUIRES(ac==br && ar==rr && bc==rc,BAD_SIZE);
875// double alpha = 1;
876// double beta = 0;
877// integer m = ar;
878// integer n = bc;
879// integer k = ac;
880// int i,j;
881// dgemm_("N","N",&m,&n,&k,&alpha,ap,&m,bp,&k,&beta,rp,&m);
882// OK
883// }
884//
885// int multiplyC2(KCMAT(a),KCMAT(b),CMAT(r)) {
886// REQUIRES(ac==br && ar==rr && bc==rc,BAD_SIZE);
887// integer m = ar;
888// integer n = bc;
889// integer k = ac;
890// doublecomplex alpha = {1,0};
891// doublecomplex beta = {0,0};
892// zgemm_("N","N",&m,&n,&k,&alpha,(doublecomplex*)ap,&m,(doublecomplex*)bp,&k,&beta,(doublecomplex*)rp,&m);
893// OK
894// }
diff --git a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h
index e8cba30..79e52be 100644
--- a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h
+++ b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h
@@ -84,9 +84,3 @@ 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
88// int multiplyR(KDMAT(a),KDMAT(b),DMAT(r));
89// int multiplyC(KCMAT(a),KCMAT(b),CMAT(r));
90
91// int multiplyR2(KDMAT(a),KDMAT(b),DMAT(r));
92int multiplyC2(KCMAT(a),KCMAT(b),CMAT(r));