packages feed

linear-algebra-cblas (empty) → 0.1

raw patch · 66 files changed

+18371/−0 lines, 66 filesdep +QuickCheckdep +basedep +ieee754setup-changed

Dependencies added: QuickCheck, base, ieee754, storable-complex, test-framework, test-framework-quickcheck2, vector

Files

+ COPYING view
@@ -0,0 +1,30 @@+Copyright (c) Patrick Perry <patperry@gmail.com> 2010+Copyright (c) Carter Schonwald <carter atsign wellposed dot com> 2012+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions+are met:++1. Redistributions of source code must retain the above copyright+   notice, this list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright+   notice, this list of conditions and the following disclaimer in the+   documentation and/or other materials provided with the distribution.++3. Neither the name of the author nor the names of his contributors+   may be used to endorse or promote products derived from this software+   without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE+ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF+SUCH DAMAGE.
+ NEWS view
@@ -0,0 +1,100 @@+Changes in 0.8.0.1++Changes in 0.8:++* Use GADTs to and remove the element type from the typeclasses.  This+  makes the function signatures a lot nicer to read and write.+  +* Put structural operations ( swap, copy, vconj ) in Elem.  This removes the+  BLAS1 constraint from the structural functions like getRow.+  +* Allowing reading from immutable types in arbitrary monads.+  +* Add binding to "ger".++* Add functional dependency m -> a in Write{Vector,Matrix,Banded} a m+  +* Add test coverage for all code paths in matrix multiplication and solve+  routines.  Fix bugs in bindings to gemv and hemm.+  +* Specialize multiplication and solve routines for Doubles so that they+  ignore complex conjugacy information.+  +Changes in 0.7.6:++* Fix a memory-trashing segfault.++Changes in 0.7.5:++* Export all unsafe functions in Unsafe.BLAS.++* Use enumerations instead of Bools in data types.++Changes in 0.7:++* Get rid of most functional dependencies in favor of type families.+  There is one remaining functional dependency that cannot be gotten+  rid of until GHC implements equality constraints in superclass+  contexts.++* Put the right superclass constraints in  ReadMatrix/ReadBanded.++* Fix freeze/thaw functions.++* Fix a bug in getting a row view of a banded matrix.++* Make sure no NaNs/Infinities/Denormals are used when testing.++* Documentation.++* Export functions for writing QuickCheck tests.++* Remove Perm and Diag.  These will be in the LAPACK bindings.++* Get rid of "UnsafeIOToM" type class.++* Lots of INLINE everywhere.  This should improve performance.++* Switch to autoconf for build system.++* Massive code cleanup.+++Changes in 0.6:++* Massive overhaul of the types.  It is now possible to do mutable operations+  in the ST monad.  Access control is done via type classes now instead of+  phantom types.+  +* No more orphan instances.++* Change some function names.  You should never have to "import qualified"+  anything now.+  +* Put row/col operations in the Matrix type classes.  Generic matrix types+  now provide access to rows and columns.+  ++Changes in 0.5:++* Add Banded matrix data type, as well as Tri Banded and Herm Banded.++* Add support for trapezoidal dense matrices (Tri Matrix (m,n) e, where+  m is not the same as n).  Note that trapezoidal banded matrices are+  *NOT* supported.++* Add Diag matrix data type for diagonal matrices.++* Add Perm matrix data type, for permutation matrices.++* Enhance the RMatrix and RSolve type classes with an API that allows +  specifying where to store the result of a computation.+  +* Enhance the IMatrix, RMatrix, ISolve, and RSolve type classes to add+  "scale and multiply" operations.+  +* Remove the scale parameter for Tri and Herm matrix data types.++* Flatten the data types for DVector and DMatrix.++* Some inlining and unpacking performance improvements.
+ README view
@@ -0,0 +1,17 @@++To build the package, there is no need to run the configure script.  Just+use the standard cabal commands:++    runhaskell Setup.lhs configure+    runhaskell Setup.lhs build+    runhaskell Setup.lhs install+    +The package uses a script to find what BLAS and LAPACK libraries to link with.+To link with a custom BLAS or LAPACK, add the "--with-blas=<lib>" +or "--with-lapack=<lib>" argument to --configure-option.  For example,++    runhaskell Setup.lhs configure --configure-option="--with-blas=<lib>"++To build this package from the git repository, first run+    aclocal -I m4+    autoreconf
+ Setup.lhs view
@@ -0,0 +1,14 @@+#!/usr/bin/env runhaskell+> import Distribution.Simple+> import Distribution.Simple.LocalBuildInfo+> import Distribution.PackageDescription+> import System.Cmd+> import System.FilePath+>+> main = defaultMainWithHooks autoconfUserHooks { runTests = runTests' }+>+> runTests' :: Args -> Bool -> PackageDescription -> LocalBuildInfo -> IO ()+> runTests' _ _ _ lbi = system testprog >> return ()+>   where testprog = (buildDir lbi)+>                        </> "test-hs-linear-algebra"+>                        </> "test-hs-linear-algebra"
+ TODO view
@@ -0,0 +1,67 @@++One great way to help is just to use the library, and give me feedback from+your experience.  What do you like?  What don't you like?  What is fast?+What is slow?  This stuff is really important for me to know.++If you are interested in hacking on the library, there is tons of work to do.+Here is a partial list.  Let me know what you would like to work on, and I can+give you some guidance on the best way to approach the task.++Small projects+--------------++* Write tests.  Look at the HPC output (from `make hpc` in the `tests` +  directory), to find what functions are not being tested.++* Write benchmarks, especially ones that allow comparisons with C or Fortran.  +  The LU decomposition in the examples directory is a good starting point.++* Write a tutorial or blog post about the library.++* The tests for solving triangular systems fail when an ill-conditioned +  matrix gets generated.  I have investigated some of the failing cases+  in R, and have determined this isn't a bug.  Ideally, we should only+  test with well-conditioned systems. ++* Add conversions from Herm Matrix to Matrix.++* Add conversions from Tri Matrix to Matrix.++* investigate test failure+  weightedMeanVector (equal weights): [OK, passed 100 tests]+VectorList 1 [fromList [0.0] :: Data.Vector.Storable.Vector]+fromList [0.0] :: Data.Vector.Storable.Vector+UnbiasedCov+  covMatrix: [Failed]++* Check arguments in shiftDiagWithScale (Matrix)++* Don't use conjugateTo with same argument in conjTransTo++* Optimize unsafeGetRow (use BLAS1)++Medium projects+---------------++* I haven't really tested it, but probably the library doesn't build on+  Windows.  See if it is possible to build the library on windows.  If+  not, figure out how to do so.  This may involve using something other+  than autoconf on windows.++* Write tests for STBanded.  The easiest way to do this is to mimic what is+  done in the STMatrix tests.+++Big Projects+------------++* Support for packed storage of symmetric and triangular matrices.  +  Add a Data.Matrix.Packed class with a heirarchy similar to +  Data.Matrix.Banded. Provide MMatrix/IMatrix instances for +  Tri Packed and Herm Packed.++* Switch over from error calls to extensible exceptions from base-4.0;+  Throw "dimension mismatch" exceptions rather than just calling+  error.  This allows for better reporting.  In particular, the covariance+  match computations should catch any dimension mismatch exceptions and then+  provide a more user-friendly message.
+ aclocal.m4 view
@@ -0,0 +1,16 @@+# generated automatically by aclocal 1.13.1 -*- Autoconf -*-++# Copyright (C) 1996-2012 Free Software Foundation, Inc.++# This file is free software; the Free Software Foundation+# gives unlimited permission to copy and/or distribute it,+# with or without modifications, as long as this notice is preserved.++# This program is distributed in the hope that it will be useful,+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A+# PARTICULAR PURPOSE.++m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])+m4_include([m4/ax_check_blas.m4])+m4_include([m4/ax_check_lapack.m4])
+ cbits/config.h.in view
@@ -0,0 +1,31 @@+/* cbits/config.h.in.  Generated from configure.ac by autoheader.  */++/* Define to a macro mangling the given Fortan function name */+#undef F77_FUNC++/* Define if you have a BLAS library. */+#undef HAVE_BLAS++/* Define if you have LAPACK library. */+#undef HAVE_LAPACK++/* Define to 1 if you have the `m' library (-lm). */+#undef HAVE_LIBM++/* Define to the address where bug reports for this package should be sent. */+#undef PACKAGE_BUGREPORT++/* Define to the full name of this package. */+#undef PACKAGE_NAME++/* Define to the full name and version of this package. */+#undef PACKAGE_STRING++/* Define to the one symbol short name of this package. */+#undef PACKAGE_TARNAME++/* Define to the home page for this package. */+#undef PACKAGE_URL++/* Define to the version of this package. */+#undef PACKAGE_VERSION
+ cbits/vmath-double.c view
@@ -0,0 +1,342 @@++#include "config.h"+#include <math.h>+#include <string.h>+#include "vmath.h"++#define la_int int++extern void+F77_FUNC(daxpy) (const la_int *n, const double *da, const double *dx,+	         const la_int *incx, double *dy, const la_int *incy);++++static void+vdClear (int n, double *z)+{+        memset(z, 0, n * sizeof(double));+}++static void+vdCopy (int n, const double *x, double *z)+{+        if (x != z) {+                memcpy(z, x, n * sizeof(double));+        }+}++void+vdScale (int n, double alpha, const double *x, double *z)+{+        if (alpha == 1) {+                vdCopy(n, x, z);+        } else if (alpha == 0) {+                vdClear(n, z);+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = alpha * x[i];+                }+        }+        +        /* Note: Using dscal sometimes gives differences in the least+         * significant bit of the answer */+}++void+vdShift (int n, double alpha, const double *x, double *z)+{+        if (alpha == 0) {+                vdCopy(n, x, z);+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = alpha + x[i];+                }+        }+}++void+vdNeg (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = -x[i];+        }+}++void+vdAbs (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = fabs(x[i]);+        }+}++static double+dsgn (double x)+{+        if (x == 0 || isnan(x)) {+                return x;+        } else {+                return copysign(1, x);+        }+}++void+vdSgn (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = dsgn(x[i]);+        }+}++void+vdInv (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = 1.0 / x[i];+        }+}++static void+vdAxpy (int n, double alpha, const double *x, const double *y, double *z)+{+        la_int one = 1;+        double done = 1.0;+        +        if (alpha == 0) {+                vdCopy(n, y, z);+        } else if (y == z) {+                F77_FUNC(daxpy) (&n, &alpha, x, &one, z, &one);+        } else if (alpha == 1 && x == z) {+                F77_FUNC(daxpy) (&n, &done, y, &one, z, &one);+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = alpha * x[i] + y[i];+                }+        }+}++void+vdAxpby (int n, double alpha, const double *x, double beta, const double *y, double *z)+{+        if (alpha == 0) {+                vdScale(n, beta, y, z);+        } else if (alpha == 1) {+                vdAxpy(n, beta, y, x, z);+        } else if (beta == 0) {+                vdScale(n, alpha, x, z);+        } else if (beta == 1) {+                vdAxpy(n, alpha, x, y, z);+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = alpha * x[i] + beta * y[i];+                }+        }+}++void+vdAdd (int n, const double *x, const double *y, double *z)+{+        vdAxpy(n, 1, x, y, z);+}++void vdSub (int n, const double *x, const double *y, double *z)+{+        vdAxpy(n, -1, y, x, z);+}++void+vdMul (int n, const double *x, const double *y, double *z)+{+        /* Note: using dtbmv sometimes gives different answers in the lower+         * bits of precision */+        +        /*if (y == z) {+                blas_dtbmv(BlasUpper, BlasNoTrans, BlasNonUnit, n, 0, x, 1,+                           z, 1);+        } else if (x == z) {+                blas_dtbmv(BlasUpper, BlasNoTrans, BlasNonUnit, n, 0, y, 1,+                           z, 1);+        } else { */+                +        int i;+        for (i = 0; i < n; i++) {+                z[i] = x[i] * y[i];+        }+}++void+vdDiv (int n, const double *x, const double *y, double *z)+{+        /* Note: using dtbsv gives slightly different answers+         */+        /*if (y == z) {+                blas_dtbsv(BlasUpper, BlasNoTrans, BlasNonUnit, n, 0, x, 1,+                           z, 1);+        } else */+        +        if (x == z) {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = z[i] / y[i];+                }+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = x[i] / y[i];+                }+        }+}++void+vdExp (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = exp(x[i]);+        }+}++void+vdSqrt (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = sqrt(x[i]);+        }+}++void+vdLog (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = log(x[i]);+        }        +}++void+vdPow (int n, const double *x, const double *y, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = pow(x[i], y[i]);+        }        +}++void+vdSin (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = sin(x[i]);+        }                +}++void+vdCos (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = cos(x[i]);+        }                        +}++void+vdTan (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = tan(x[i]);+        }                                +}++void+vdASin (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = asin(x[i]);+        }                                        +}++void+vdACos (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = acos(x[i]);+        }                                                +}++void+vdATan (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = atan(x[i]);+        }+}++void+vdSinh (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = sinh(x[i]);+        }                +}++void+vdCosh (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = cosh(x[i]);+        }                        +}++void+vdTanh (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = tanh(x[i]);+        }                                +}++void+vdASinh (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = asinh(x[i]);+        }                                        +}++void+vdACosh (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = acosh(x[i]);+        }                                                +}++void+vdATanh (int n, const double *x, double *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = atanh(x[i]);+        }+}+
+ cbits/vmath-zomplex.c view
@@ -0,0 +1,369 @@++#include "config.h"+#include <complex.h>+#include <string.h>+#include "vmath.h"++#define la_int int++extern void+F77_FUNC(zaxpy) (const la_int *n, const void *za, const void *zx,+	         const la_int *incx, void *zy, const la_int *incy);+++static double complex+complex_mul (double complex x, double complex y)+{+	double xr = creal(x), xi = cimag(x);+	double yr = creal(y), yi = cimag(y);+	double zr = xr * yr - xi * yi;+	double zi = xr * yi + xi * yr;+        double complex z = zr + I * zi;	+	return z;+}+++static void+vzClear (int n, double complex *z)+{+        memset(z, 0, n * 2 * sizeof(double));+}++static void+vzCopy (int n, const double complex *x, double complex *z)+{+        if (x != z) {+                memcpy(z, x, n * 2 * sizeof(double));+        }+}++void+vzConj (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = conj(x[i]);+        }+}++void+vzScale (int n, const double complex *palpha, const double complex *x, double complex *z)+{+        double complex alpha = *palpha;+        +        if (alpha == 1) {+                vzCopy(n, x, z);+        } else if (alpha == 0) {+                vzClear(n, z);+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = complex_mul(alpha, x[i]);+                }+        }+        +        /* Note: Using zscal sometimes gives differences in the least+         * significant bit of the answer */+}++void+vzShift (int n, const double complex *palpha, const double complex *x, double complex *z)+{+        double complex alpha = *palpha;+        +        if (alpha == 0) {+                vzCopy(n, x, z);+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = alpha + x[i];+                }+        }+}++void+vzNeg (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = -x[i];+        }+}++void+vzAbs (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = cabs(x[i]) + 0*I;+        }+}++static void+zsgn (const double complex x, double complex *z)+{+        if (x == 0) {+                *z = x;+        } else {+                double r = cabs(x);+                *z = creal(x)/r + cimag(x)/r*I;+        }+}++void+vzSgn (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                zsgn(x[i], &(z[i]));+        }+}++void+vzInv (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = 1.0 / x[i];+        }+}++static void+vzAxpy (int n, const double complex *palpha, const double complex *x, const double complex *y, double complex *z)+{+        double complex alpha = *palpha;+        la_int one = 1;+        +        if (alpha == 0) {+                vzCopy(n, y, z);+        } else if (y == z) {+                F77_FUNC(zaxpy) (&n, palpha, x, &one, z, &one);+        } else if (alpha == 1 && x == z) {+                F77_FUNC(zaxpy) (&n, palpha, y, &one, z, &one);+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = alpha * x[i] + y[i];+                }+        }+}++void+vzAxpby (int n, const double complex *palpha, const double complex *x, const double complex *pbeta, const double complex *y, double complex *z)+{+        double complex alpha = *palpha;+        double complex beta = *pbeta;        +                +        if (alpha == 0) {+                vzScale(n, pbeta, y, z);+        } else if (alpha == 1) {+                vzAxpy(n, pbeta, y, x, z);+        } else if (beta == 0) {+                vzScale(n, palpha, x, z);+        } else if (beta == 1) {+                vzAxpy(n, palpha, x, y, z);+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = alpha * x[i] + beta * y[i];+                }+        }+}++void+vzAdd (int n, const double complex *x, const double complex *y, double complex *z)+{+        vdAdd(2 * n, (const double *)x, (const double *)y, (double *)z);+}++void vzSub (int n, const double complex *x, const double complex *y, double complex *z)+{+        vdSub(2 * n, (const double *)x, (const double *)y, (double *)z);+}++void+vzMul (int n, const double complex *x, const double complex *y, double complex *z)+{+        /* Note: using ztbmv sometimes gives different answers in the lower+         * bits of precision */+        /*+        if (y == z) {+                blas_ztbmv(BlasUpper, BlasNoTrans, BlasNonUnit, n, 0, x, 1,+                           z, 1);+        } else if (x == z) {+                blas_ztbmv(BlasUpper, BlasNoTrans, BlasNonUnit, n, 0, y, 1,+                           z, 1);+        } */+        int i;+        for (i = 0; i < n; i++) {+                z[i] = complex_mul(x[i], y[i]);+        }+}++void+vzDiv (int n, const double complex *x, const double complex *y, double complex *z)+{+        /* Note: using dtbsv gives slightly different answers+         */+        /*+        if (y == z) {+                blas_ztbsv(BlasUpper, BlasNoTrans, BlasNonUnit, n, 0, x, 1,+                           z, 1);+        } else */+        if (x == z) {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = z[i] / y[i];+                }+        } else {+                int i;+                for (i = 0; i < n; i++) {+                        z[i] = x[i] / y[i];+                }+        }+}++void+vzExp (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = cexp(x[i]);+        }+}++void+vzSqrt (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = csqrt(x[i]);+        }+}++void+vzLog (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = clog(x[i]);+        }        +}++void+vzPow (int n, const double complex *x, const double complex *y, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = cpow(x[i], y[i]);+        }        +}++void+vzSin (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = csin(x[i]);+        }                +}++void+vzCos (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = ccos(x[i]);+        }                        +}++void+vzTan (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = ctan(x[i]);+        }                                +}++void+vzASin (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = casin(x[i]);+        }                                        +}++void+vzACos (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = cacos(x[i]);+        }                                                +}++void+vzATan (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = catan(x[i]);+        }+}++void+vzSinh (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = csinh(x[i]);+        }                +}++void+vzCosh (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = ccosh(x[i]);+        }                        +}++void+vzTanh (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = ctanh(x[i]);+        }                                +}++void+vzASinh (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = casinh(x[i]);+        }                                        +}++void+vzACosh (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = cacosh(x[i]);+        }                                                +}++void+vzATanh (int n, const double complex *x, double complex *z)+{+        int i;+        for (i = 0; i < n; i++) {+                z[i] = catanh(x[i]);+        }+}+
+ configure view
@@ -0,0 +1,5684 @@+#! /bin/sh+# Guess values for system-dependent variables and create Makefiles.+# Generated by GNU Autoconf 2.69 for Haskell Linear Algebra 0.8.+#+# Report bugs to <patperry@gmail.com>.+#+#+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.+#+#+# This configure script is free software; the Free Software Foundation+# gives unlimited permission to copy, distribute and modify it.+## -------------------- ##+## M4sh Initialization. ##+## -------------------- ##++# Be more Bourne compatible+DUALCASE=1; export DUALCASE # for MKS sh+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '${1+"$@"}'='"$@"'+  setopt NO_GLOB_SUBST+else+  case `(set -o) 2>/dev/null` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac+fi+++as_nl='+'+export as_nl+# Printing a long string crashes Solaris 7 /usr/bin/printf.+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo+# Prefer a ksh shell builtin over an external printf program on Solaris,+# but without wasting forks for bash or zsh.+if test -z "$BASH_VERSION$ZSH_VERSION" \+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then+  as_echo='print -r --'+  as_echo_n='print -rn --'+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then+  as_echo='printf %s\n'+  as_echo_n='printf %s'+else+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'+    as_echo_n='/usr/ucb/echo -n'+  else+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'+    as_echo_n_body='eval+      arg=$1;+      case $arg in #(+      *"$as_nl"*)+	expr "X$arg" : "X\\(.*\\)$as_nl";+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;+      esac;+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"+    '+    export as_echo_n_body+    as_echo_n='sh -c $as_echo_n_body as_echo'+  fi+  export as_echo_body+  as_echo='sh -c $as_echo_body as_echo'+fi++# The user is always right.+if test "${PATH_SEPARATOR+set}" != set; then+  PATH_SEPARATOR=:+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+      PATH_SEPARATOR=';'+  }+fi+++# IFS+# We need space, tab and new line, in precisely that order.  Quoting is+# there to prevent editors from complaining about space-tab.+# (If _AS_PATH_WALK were called with IFS unset, it would disable word+# splitting by setting IFS to empty value.)+IFS=" ""	$as_nl"++# Find who we are.  Look in the path if we contain no directory separator.+as_myself=+case $0 in #((+  *[\\/]* ) as_myself=$0 ;;+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break+  done+IFS=$as_save_IFS++     ;;+esac+# We did not find ourselves, most probably we were run as `sh COMMAND'+# in which case we are not to be found in the path.+if test "x$as_myself" = x; then+  as_myself=$0+fi+if test ! -f "$as_myself"; then+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2+  exit 1+fi++# Unset variables that we do not need and which cause bugs (e.g. in+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"+# suppresses any "Segmentation fault" message there.  '((' could+# trigger a bug in pdksh 5.2.14.+for as_var in BASH_ENV ENV MAIL MAILPATH+do eval test x\${$as_var+set} = xset \+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :+done+PS1='$ '+PS2='> '+PS4='+ '++# NLS nuisances.+LC_ALL=C+export LC_ALL+LANGUAGE=C+export LANGUAGE++# CDPATH.+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH++# Use a proper internal environment variable to ensure we don't fall+  # into an infinite loop, continuously re-executing ourselves.+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then+    _as_can_reexec=no; export _as_can_reexec;+    # We cannot yet assume a decent shell, so we have to provide a+# neutralization value for shells without unset; and this also+# works around shells that cannot unset nonexistent variables.+# Preserve -v and -x to the replacement shell.+BASH_ENV=/dev/null+ENV=/dev/null+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV+case $- in # ((((+  *v*x* | *x*v* ) as_opts=-vx ;;+  *v* ) as_opts=-v ;;+  *x* ) as_opts=-x ;;+  * ) as_opts= ;;+esac+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}+# Admittedly, this is quite paranoid, since all the known shells bail+# out after a failed `exec'.+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2+as_fn_exit 255+  fi+  # We don't want this to propagate to other subprocesses.+          { _as_can_reexec=; unset _as_can_reexec;}+if test "x$CONFIG_SHELL" = x; then+  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '\${1+\"\$@\"}'='\"\$@\"'+  setopt NO_GLOB_SUBST+else+  case \`(set -o) 2>/dev/null\` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac+fi+"+  as_required="as_fn_return () { (exit \$1); }+as_fn_success () { as_fn_return 0; }+as_fn_failure () { as_fn_return 1; }+as_fn_ret_success () { return 0; }+as_fn_ret_failure () { return 1; }++exitcode=0+as_fn_success || { exitcode=1; echo as_fn_success failed.; }+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :++else+  exitcode=1; echo positional parameters were not saved.+fi+test x\$exitcode = x0 || exit 1+test -x / || exit 1"+  as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO+  as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO+  eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"+  if (eval "$as_required") 2>/dev/null; then :+  as_have_required=yes+else+  as_have_required=no+fi+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :++else+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+as_found=false+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+  as_found=:+  case $as_dir in #(+	 /*)+	   for as_base in sh bash ksh sh5; do+	     # Try only shells that exist, to save several forks.+	     as_shell=$as_dir/$as_base+	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&+		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :+  CONFIG_SHELL=$as_shell as_have_required=yes+		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :+  break 2+fi+fi+	   done;;+       esac+  as_found=false+done+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&+	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :+  CONFIG_SHELL=$SHELL as_have_required=yes+fi; }+IFS=$as_save_IFS+++      if test "x$CONFIG_SHELL" != x; then :+  export CONFIG_SHELL+             # We cannot yet assume a decent shell, so we have to provide a+# neutralization value for shells without unset; and this also+# works around shells that cannot unset nonexistent variables.+# Preserve -v and -x to the replacement shell.+BASH_ENV=/dev/null+ENV=/dev/null+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV+case $- in # ((((+  *v*x* | *x*v* ) as_opts=-vx ;;+  *v* ) as_opts=-v ;;+  *x* ) as_opts=-x ;;+  * ) as_opts= ;;+esac+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}+# Admittedly, this is quite paranoid, since all the known shells bail+# out after a failed `exec'.+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2+exit 255+fi++    if test x$as_have_required = xno; then :+  $as_echo "$0: This script requires a shell more modern than all"+  $as_echo "$0: the shells that I found on your system."+  if test x${ZSH_VERSION+set} = xset ; then+    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"+    $as_echo "$0: be upgraded to zsh 4.3.4 or later."+  else+    $as_echo "$0: Please tell bug-autoconf@gnu.org and patperry@gmail.com+$0: about your system, including any error possibly output+$0: before this message. Then install a modern shell, or+$0: manually run the script under such a shell if you do+$0: have one."+  fi+  exit 1+fi+fi+fi+SHELL=${CONFIG_SHELL-/bin/sh}+export SHELL+# Unset more variables known to interfere with behavior of common tools.+CLICOLOR_FORCE= GREP_OPTIONS=+unset CLICOLOR_FORCE GREP_OPTIONS++## --------------------- ##+## M4sh Shell Functions. ##+## --------------------- ##+# as_fn_unset VAR+# ---------------+# Portably unset VAR.+as_fn_unset ()+{+  { eval $1=; unset $1;}+}+as_unset=as_fn_unset++# as_fn_set_status STATUS+# -----------------------+# Set $? to STATUS, without forking.+as_fn_set_status ()+{+  return $1+} # as_fn_set_status++# as_fn_exit STATUS+# -----------------+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.+as_fn_exit ()+{+  set +e+  as_fn_set_status $1+  exit $1+} # as_fn_exit++# as_fn_mkdir_p+# -------------+# Create "$as_dir" as a directory, including parents if necessary.+as_fn_mkdir_p ()+{++  case $as_dir in #(+  -*) as_dir=./$as_dir;;+  esac+  test -d "$as_dir" || eval $as_mkdir_p || {+    as_dirs=+    while :; do+      case $as_dir in #(+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(+      *) as_qdir=$as_dir;;+      esac+      as_dirs="'$as_qdir' $as_dirs"+      as_dir=`$as_dirname -- "$as_dir" ||+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_dir" : 'X\(//\)[^/]' \| \+	 X"$as_dir" : 'X\(//\)$' \| \+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$as_dir" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+      test -d "$as_dir" && break+    done+    test -z "$as_dirs" || eval "mkdir $as_dirs"+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"+++} # as_fn_mkdir_p++# as_fn_executable_p FILE+# -----------------------+# Test if FILE is an executable regular file.+as_fn_executable_p ()+{+  test -f "$1" && test -x "$1"+} # as_fn_executable_p+# as_fn_append VAR VALUE+# ----------------------+# Append the text in VALUE to the end of the definition contained in VAR. Take+# advantage of any shell optimizations that allow amortized linear growth over+# repeated appends, instead of the typical quadratic growth present in naive+# implementations.+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :+  eval 'as_fn_append ()+  {+    eval $1+=\$2+  }'+else+  as_fn_append ()+  {+    eval $1=\$$1\$2+  }+fi # as_fn_append++# as_fn_arith ARG...+# ------------------+# Perform arithmetic evaluation on the ARGs, and store the result in the+# global $as_val. Take advantage of shells that can avoid forks. The arguments+# must be portable across $(()) and expr.+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :+  eval 'as_fn_arith ()+  {+    as_val=$(( $* ))+  }'+else+  as_fn_arith ()+  {+    as_val=`expr "$@" || test $? -eq 1`+  }+fi # as_fn_arith+++# as_fn_error STATUS ERROR [LINENO LOG_FD]+# ----------------------------------------+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the+# script with STATUS, using 1 if that was 0.+as_fn_error ()+{+  as_status=$1; test $as_status -eq 0 && as_status=1+  if test "$4"; then+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4+  fi+  $as_echo "$as_me: error: $2" >&2+  as_fn_exit $as_status+} # as_fn_error++if expr a : '\(a\)' >/dev/null 2>&1 &&+   test "X`expr 00001 : '.*\(...\)'`" = X001; then+  as_expr=expr+else+  as_expr=false+fi++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then+  as_basename=basename+else+  as_basename=false+fi++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then+  as_dirname=dirname+else+  as_dirname=false+fi++as_me=`$as_basename -- "$0" ||+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \+	 X"$0" : 'X\(//\)$' \| \+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X/"$0" |+    sed '/^.*\/\([^/][^/]*\)\/*$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`++# Avoid depending upon Character Ranges.+as_cr_letters='abcdefghijklmnopqrstuvwxyz'+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+as_cr_Letters=$as_cr_letters$as_cr_LETTERS+as_cr_digits='0123456789'+as_cr_alnum=$as_cr_Letters$as_cr_digits+++  as_lineno_1=$LINENO as_lineno_1a=$LINENO+  as_lineno_2=$LINENO as_lineno_2a=$LINENO+  eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&+  test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {+  # Blame Lee E. McMahon (1931-1989) for sed's syntax.  :-)+  sed -n '+    p+    /[$]LINENO/=+  ' <$as_myself |+    sed '+      s/[$]LINENO.*/&-/+      t lineno+      b+      :lineno+      N+      :loop+      s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/+      t loop+      s/-\n.*//+    ' >$as_me.lineno &&+  chmod +x "$as_me.lineno" ||+    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }++  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have+  # already done that, so ensure we don't try to do so again and fall+  # in an infinite loop.  This has already happened in practice.+  _as_can_reexec=no; export _as_can_reexec+  # Don't try to exec as it changes $[0], causing all sort of problems+  # (the dirname of $[0] is not the place where we might find the+  # original and so on.  Autoconf is especially sensitive to this).+  . "./$as_me.lineno"+  # Exit status is that of the last command.+  exit+}++ECHO_C= ECHO_N= ECHO_T=+case `echo -n x` in #(((((+-n*)+  case `echo 'xy\c'` in+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.+  xy)  ECHO_C='\c';;+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null+       ECHO_T='	';;+  esac;;+*)+  ECHO_N='-n';;+esac++rm -f conf$$ conf$$.exe conf$$.file+if test -d conf$$.dir; then+  rm -f conf$$.dir/conf$$.file+else+  rm -f conf$$.dir+  mkdir conf$$.dir 2>/dev/null+fi+if (echo >conf$$.file) 2>/dev/null; then+  if ln -s conf$$.file conf$$ 2>/dev/null; then+    as_ln_s='ln -s'+    # ... but there are two gotchas:+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.+    # In both cases, we have to default to `cp -pR'.+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||+      as_ln_s='cp -pR'+  elif ln conf$$.file conf$$ 2>/dev/null; then+    as_ln_s=ln+  else+    as_ln_s='cp -pR'+  fi+else+  as_ln_s='cp -pR'+fi+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file+rmdir conf$$.dir 2>/dev/null++if mkdir -p . 2>/dev/null; then+  as_mkdir_p='mkdir -p "$as_dir"'+else+  test -d ./-p && rmdir ./-p+  as_mkdir_p=false+fi++as_test_x='test -x'+as_executable_p=as_fn_executable_p++# Sed expression to map a string onto a valid CPP name.+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"++# Sed expression to map a string onto a valid variable name.+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"+++test -n "$DJDIR" || exec 7<&0 </dev/null+exec 6>&1++# Name of the host.+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,+# so uname gets run too.+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`++#+# Initializations.+#+ac_default_prefix=/usr/local+ac_clean_files=+ac_config_libobj_dir=.+LIBOBJS=+cross_compiling=no+subdirs=+MFLAGS=+MAKEFLAGS=++# Identity of this package.+PACKAGE_NAME='Haskell Linear Algebra'+PACKAGE_TARNAME='haskell-linear-algebra'+PACKAGE_VERSION='0.8'+PACKAGE_STRING='Haskell Linear Algebra 0.8'+PACKAGE_BUGREPORT='patperry@gmail.com'+PACKAGE_URL=''++ac_unique_file="linear-algebra.cabal"+ac_subst_vars='LTLIBOBJS+LIBOBJS+BUILD_PACKAGE_BOOL+LAPACK_LIBS+BLAS_LIBS+OBJEXT+EXEEXT+ac_ct_CC+CPPFLAGS+LDFLAGS+CFLAGS+CC+target_alias+host_alias+build_alias+LIBS+ECHO_T+ECHO_N+ECHO_C+DEFS+mandir+localedir+libdir+psdir+pdfdir+dvidir+htmldir+infodir+docdir+oldincludedir+includedir+localstatedir+sharedstatedir+sysconfdir+datadir+datarootdir+libexecdir+sbindir+bindir+program_transform_name+prefix+exec_prefix+PACKAGE_URL+PACKAGE_BUGREPORT+PACKAGE_STRING+PACKAGE_VERSION+PACKAGE_TARNAME+PACKAGE_NAME+PATH_SEPARATOR+SHELL'+ac_subst_files=''+ac_user_opts='+enable_option_checking+with_compiler+with_blas+with_lapack+'+      ac_precious_vars='build_alias+host_alias+target_alias+CC+CFLAGS+LDFLAGS+LIBS+CPPFLAGS'+++# Initialize some variables set by options.+ac_init_help=+ac_init_version=false+ac_unrecognized_opts=+ac_unrecognized_sep=+# The variables have the same names as the options, with+# dashes changed to underlines.+cache_file=/dev/null+exec_prefix=NONE+no_create=+no_recursion=+prefix=NONE+program_prefix=NONE+program_suffix=NONE+program_transform_name=s,x,x,+silent=+site=+srcdir=+verbose=+x_includes=NONE+x_libraries=NONE++# Installation directory options.+# These are left unexpanded so users can "make install exec_prefix=/foo"+# and all the variables that are supposed to be based on exec_prefix+# by default will actually change.+# Use braces instead of parens because sh, perl, etc. also accept them.+# (The list follows the same order as the GNU Coding Standards.)+bindir='${exec_prefix}/bin'+sbindir='${exec_prefix}/sbin'+libexecdir='${exec_prefix}/libexec'+datarootdir='${prefix}/share'+datadir='${datarootdir}'+sysconfdir='${prefix}/etc'+sharedstatedir='${prefix}/com'+localstatedir='${prefix}/var'+includedir='${prefix}/include'+oldincludedir='/usr/include'+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'+infodir='${datarootdir}/info'+htmldir='${docdir}'+dvidir='${docdir}'+pdfdir='${docdir}'+psdir='${docdir}'+libdir='${exec_prefix}/lib'+localedir='${datarootdir}/locale'+mandir='${datarootdir}/man'++ac_prev=+ac_dashdash=+for ac_option+do+  # If the previous option needs an argument, assign it.+  if test -n "$ac_prev"; then+    eval $ac_prev=\$ac_option+    ac_prev=+    continue+  fi++  case $ac_option in+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;+  *=)   ac_optarg= ;;+  *)    ac_optarg=yes ;;+  esac++  # Accept the important Cygnus configure options, so we can diagnose typos.++  case $ac_dashdash$ac_option in+  --)+    ac_dashdash=yes ;;++  -bindir | --bindir | --bindi | --bind | --bin | --bi)+    ac_prev=bindir ;;+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)+    bindir=$ac_optarg ;;++  -build | --build | --buil | --bui | --bu)+    ac_prev=build_alias ;;+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)+    build_alias=$ac_optarg ;;++  -cache-file | --cache-file | --cache-fil | --cache-fi \+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)+    ac_prev=cache_file ;;+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)+    cache_file=$ac_optarg ;;++  --config-cache | -C)+    cache_file=config.cache ;;++  -datadir | --datadir | --datadi | --datad)+    ac_prev=datadir ;;+  -datadir=* | --datadir=* | --datadi=* | --datad=*)+    datadir=$ac_optarg ;;++  -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \+  | --dataroo | --dataro | --datar)+    ac_prev=datarootdir ;;+  -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \+  | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)+    datarootdir=$ac_optarg ;;++  -disable-* | --disable-*)+    ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid feature name: $ac_useropt"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"enable_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval enable_$ac_useropt=no ;;++  -docdir | --docdir | --docdi | --doc | --do)+    ac_prev=docdir ;;+  -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)+    docdir=$ac_optarg ;;++  -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)+    ac_prev=dvidir ;;+  -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)+    dvidir=$ac_optarg ;;++  -enable-* | --enable-*)+    ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid feature name: $ac_useropt"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"enable_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval enable_$ac_useropt=\$ac_optarg ;;++  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \+  | --exec | --exe | --ex)+    ac_prev=exec_prefix ;;+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \+  | --exec=* | --exe=* | --ex=*)+    exec_prefix=$ac_optarg ;;++  -gas | --gas | --ga | --g)+    # Obsolete; use --with-gas.+    with_gas=yes ;;++  -help | --help | --hel | --he | -h)+    ac_init_help=long ;;+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)+    ac_init_help=recursive ;;+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)+    ac_init_help=short ;;++  -host | --host | --hos | --ho)+    ac_prev=host_alias ;;+  -host=* | --host=* | --hos=* | --ho=*)+    host_alias=$ac_optarg ;;++  -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)+    ac_prev=htmldir ;;+  -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \+  | --ht=*)+    htmldir=$ac_optarg ;;++  -includedir | --includedir | --includedi | --included | --include \+  | --includ | --inclu | --incl | --inc)+    ac_prev=includedir ;;+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \+  | --includ=* | --inclu=* | --incl=* | --inc=*)+    includedir=$ac_optarg ;;++  -infodir | --infodir | --infodi | --infod | --info | --inf)+    ac_prev=infodir ;;+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)+    infodir=$ac_optarg ;;++  -libdir | --libdir | --libdi | --libd)+    ac_prev=libdir ;;+  -libdir=* | --libdir=* | --libdi=* | --libd=*)+    libdir=$ac_optarg ;;++  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \+  | --libexe | --libex | --libe)+    ac_prev=libexecdir ;;+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \+  | --libexe=* | --libex=* | --libe=*)+    libexecdir=$ac_optarg ;;++  -localedir | --localedir | --localedi | --localed | --locale)+    ac_prev=localedir ;;+  -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)+    localedir=$ac_optarg ;;++  -localstatedir | --localstatedir | --localstatedi | --localstated \+  | --localstate | --localstat | --localsta | --localst | --locals)+    ac_prev=localstatedir ;;+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \+  | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)+    localstatedir=$ac_optarg ;;++  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)+    ac_prev=mandir ;;+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)+    mandir=$ac_optarg ;;++  -nfp | --nfp | --nf)+    # Obsolete; use --without-fp.+    with_fp=no ;;++  -no-create | --no-create | --no-creat | --no-crea | --no-cre \+  | --no-cr | --no-c | -n)+    no_create=yes ;;++  -no-recursion | --no-recursion | --no-recursio | --no-recursi \+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)+    no_recursion=yes ;;++  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \+  | --oldin | --oldi | --old | --ol | --o)+    ac_prev=oldincludedir ;;+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)+    oldincludedir=$ac_optarg ;;++  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)+    ac_prev=prefix ;;+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)+    prefix=$ac_optarg ;;++  -program-prefix | --program-prefix | --program-prefi | --program-pref \+  | --program-pre | --program-pr | --program-p)+    ac_prev=program_prefix ;;+  -program-prefix=* | --program-prefix=* | --program-prefi=* \+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)+    program_prefix=$ac_optarg ;;++  -program-suffix | --program-suffix | --program-suffi | --program-suff \+  | --program-suf | --program-su | --program-s)+    ac_prev=program_suffix ;;+  -program-suffix=* | --program-suffix=* | --program-suffi=* \+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)+    program_suffix=$ac_optarg ;;++  -program-transform-name | --program-transform-name \+  | --program-transform-nam | --program-transform-na \+  | --program-transform-n | --program-transform- \+  | --program-transform | --program-transfor \+  | --program-transfo | --program-transf \+  | --program-trans | --program-tran \+  | --progr-tra | --program-tr | --program-t)+    ac_prev=program_transform_name ;;+  -program-transform-name=* | --program-transform-name=* \+  | --program-transform-nam=* | --program-transform-na=* \+  | --program-transform-n=* | --program-transform-=* \+  | --program-transform=* | --program-transfor=* \+  | --program-transfo=* | --program-transf=* \+  | --program-trans=* | --program-tran=* \+  | --progr-tra=* | --program-tr=* | --program-t=*)+    program_transform_name=$ac_optarg ;;++  -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)+    ac_prev=pdfdir ;;+  -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)+    pdfdir=$ac_optarg ;;++  -psdir | --psdir | --psdi | --psd | --ps)+    ac_prev=psdir ;;+  -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)+    psdir=$ac_optarg ;;++  -q | -quiet | --quiet | --quie | --qui | --qu | --q \+  | -silent | --silent | --silen | --sile | --sil)+    silent=yes ;;++  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)+    ac_prev=sbindir ;;+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \+  | --sbi=* | --sb=*)+    sbindir=$ac_optarg ;;++  -sharedstatedir | --sharedstatedir | --sharedstatedi \+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \+  | --sharedst | --shareds | --shared | --share | --shar \+  | --sha | --sh)+    ac_prev=sharedstatedir ;;+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \+  | --sha=* | --sh=*)+    sharedstatedir=$ac_optarg ;;++  -site | --site | --sit)+    ac_prev=site ;;+  -site=* | --site=* | --sit=*)+    site=$ac_optarg ;;++  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)+    ac_prev=srcdir ;;+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)+    srcdir=$ac_optarg ;;++  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \+  | --syscon | --sysco | --sysc | --sys | --sy)+    ac_prev=sysconfdir ;;+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)+    sysconfdir=$ac_optarg ;;++  -target | --target | --targe | --targ | --tar | --ta | --t)+    ac_prev=target_alias ;;+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)+    target_alias=$ac_optarg ;;++  -v | -verbose | --verbose | --verbos | --verbo | --verb)+    verbose=yes ;;++  -version | --version | --versio | --versi | --vers | -V)+    ac_init_version=: ;;++  -with-* | --with-*)+    ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid package name: $ac_useropt"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"with_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval with_$ac_useropt=\$ac_optarg ;;++  -without-* | --without-*)+    ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`+    # Reject names that are not valid shell variable names.+    expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&+      as_fn_error $? "invalid package name: $ac_useropt"+    ac_useropt_orig=$ac_useropt+    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`+    case $ac_user_opts in+      *"+"with_$ac_useropt"+"*) ;;+      *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"+	 ac_unrecognized_sep=', ';;+    esac+    eval with_$ac_useropt=no ;;++  --x)+    # Obsolete; use --with-x.+    with_x=yes ;;++  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \+  | --x-incl | --x-inc | --x-in | --x-i)+    ac_prev=x_includes ;;+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)+    x_includes=$ac_optarg ;;++  -x-libraries | --x-libraries | --x-librarie | --x-librari \+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)+    ac_prev=x_libraries ;;+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)+    x_libraries=$ac_optarg ;;++  -*) as_fn_error $? "unrecognized option: \`$ac_option'+Try \`$0 --help' for more information"+    ;;++  *=*)+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`+    # Reject names that are not valid shell variable names.+    case $ac_envvar in #(+      '' | [0-9]* | *[!_$as_cr_alnum]* )+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;+    esac+    eval $ac_envvar=\$ac_optarg+    export $ac_envvar ;;++  *)+    # FIXME: should be removed in autoconf 3.0.+    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&+      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"+    ;;++  esac+done++if test -n "$ac_prev"; then+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`+  as_fn_error $? "missing argument to $ac_option"+fi++if test -n "$ac_unrecognized_opts"; then+  case $enable_option_checking in+    no) ;;+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;+    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;+  esac+fi++# Check all directory arguments for consistency.+for ac_var in	exec_prefix prefix bindir sbindir libexecdir datarootdir \+		datadir sysconfdir sharedstatedir localstatedir includedir \+		oldincludedir docdir infodir htmldir dvidir pdfdir psdir \+		libdir localedir mandir+do+  eval ac_val=\$$ac_var+  # Remove trailing slashes.+  case $ac_val in+    */ )+      ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`+      eval $ac_var=\$ac_val;;+  esac+  # Be sure to have absolute directory names.+  case $ac_val in+    [\\/$]* | ?:[\\/]* )  continue;;+    NONE | '' ) case $ac_var in *prefix ) continue;; esac;;+  esac+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"+done++# There might be people who depend on the old broken behavior: `$host'+# used to hold the argument of --host etc.+# FIXME: To remove some day.+build=$build_alias+host=$host_alias+target=$target_alias++# FIXME: To remove some day.+if test "x$host_alias" != x; then+  if test "x$build_alias" = x; then+    cross_compiling=maybe+  elif test "x$build_alias" != "x$host_alias"; then+    cross_compiling=yes+  fi+fi++ac_tool_prefix=+test -n "$host_alias" && ac_tool_prefix=$host_alias-++test "$silent" = yes && exec 6>/dev/null+++ac_pwd=`pwd` && test -n "$ac_pwd" &&+ac_ls_di=`ls -di .` &&+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||+  as_fn_error $? "working directory cannot be determined"+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||+  as_fn_error $? "pwd does not report name of working directory"+++# Find the source files, if location was not specified.+if test -z "$srcdir"; then+  ac_srcdir_defaulted=yes+  # Try the directory containing this script, then the parent directory.+  ac_confdir=`$as_dirname -- "$as_myself" ||+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_myself" : 'X\(//\)[^/]' \| \+	 X"$as_myself" : 'X\(//\)$' \| \+	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$as_myself" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+  srcdir=$ac_confdir+  if test ! -r "$srcdir/$ac_unique_file"; then+    srcdir=..+  fi+else+  ac_srcdir_defaulted=no+fi+if test ! -r "$srcdir/$ac_unique_file"; then+  test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"+fi+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"+ac_abs_confdir=`(+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"+	pwd)`+# When building in place, set srcdir=.+if test "$ac_abs_confdir" = "$ac_pwd"; then+  srcdir=.+fi+# Remove unnecessary trailing slashes from srcdir.+# Double slashes in file names in object file debugging info+# mess up M-x gdb in Emacs.+case $srcdir in+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;+esac+for ac_var in $ac_precious_vars; do+  eval ac_env_${ac_var}_set=\${${ac_var}+set}+  eval ac_env_${ac_var}_value=\$${ac_var}+  eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}+  eval ac_cv_env_${ac_var}_value=\$${ac_var}+done++#+# Report the --help message.+#+if test "$ac_init_help" = "long"; then+  # Omit some internal or obsolete options to make the list less imposing.+  # This message is too long to be a string in the A/UX 3.1 sh.+  cat <<_ACEOF+\`configure' configures Haskell Linear Algebra 0.8 to adapt to many kinds of systems.++Usage: $0 [OPTION]... [VAR=VALUE]...++To assign environment variables (e.g., CC, CFLAGS...), specify them as+VAR=VALUE.  See below for descriptions of some of the useful variables.++Defaults for the options are specified in brackets.++Configuration:+  -h, --help              display this help and exit+      --help=short        display options specific to this package+      --help=recursive    display the short help of all the included packages+  -V, --version           display version information and exit+  -q, --quiet, --silent   do not print \`checking ...' messages+      --cache-file=FILE   cache test results in FILE [disabled]+  -C, --config-cache      alias for \`--cache-file=config.cache'+  -n, --no-create         do not create output files+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']++Installation directories:+  --prefix=PREFIX         install architecture-independent files in PREFIX+                          [$ac_default_prefix]+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX+                          [PREFIX]++By default, \`make install' will install all the files in+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify+an installation prefix other than \`$ac_default_prefix' using \`--prefix',+for instance \`--prefix=\$HOME'.++For better control, use the options below.++Fine tuning of the installation directories:+  --bindir=DIR            user executables [EPREFIX/bin]+  --sbindir=DIR           system admin executables [EPREFIX/sbin]+  --libexecdir=DIR        program executables [EPREFIX/libexec]+  --sysconfdir=DIR        read-only single-machine data [PREFIX/etc]+  --sharedstatedir=DIR    modifiable architecture-independent data [PREFIX/com]+  --localstatedir=DIR     modifiable single-machine data [PREFIX/var]+  --libdir=DIR            object code libraries [EPREFIX/lib]+  --includedir=DIR        C header files [PREFIX/include]+  --oldincludedir=DIR     C header files for non-gcc [/usr/include]+  --datarootdir=DIR       read-only arch.-independent data root [PREFIX/share]+  --datadir=DIR           read-only architecture-independent data [DATAROOTDIR]+  --infodir=DIR           info documentation [DATAROOTDIR/info]+  --localedir=DIR         locale-dependent data [DATAROOTDIR/locale]+  --mandir=DIR            man documentation [DATAROOTDIR/man]+  --docdir=DIR            documentation root+                          [DATAROOTDIR/doc/haskell-linear-algebra]+  --htmldir=DIR           html documentation [DOCDIR]+  --dvidir=DIR            dvi documentation [DOCDIR]+  --pdfdir=DIR            pdf documentation [DOCDIR]+  --psdir=DIR             ps documentation [DOCDIR]+_ACEOF++  cat <<\_ACEOF+_ACEOF+fi++if test -n "$ac_init_help"; then+  case $ac_init_help in+     short | recursive ) echo "Configuration of Haskell Linear Algebra 0.8:";;+   esac+  cat <<\_ACEOF++Optional Packages:+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)+  --with-compiler=<cmd>   use Haskell compiler <cmd>+  --with-blas=<lib>       use BLAS library <lib>+  --with-lapack=<lib>     use LAPACK library <lib>++Some influential environment variables:+  CC          C compiler command+  CFLAGS      C compiler flags+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a+              nonstandard directory <lib dir>+  LIBS        libraries to pass to the linker, e.g. -l<library>+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if+              you have headers in a nonstandard directory <include dir>++Use these variables to override the choices made by `configure' or to help+it to find libraries and programs with nonstandard names/locations.++Report bugs to <patperry@gmail.com>.+_ACEOF+ac_status=$?+fi++if test "$ac_init_help" = "recursive"; then+  # If there are subdirs, report their specific --help.+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue+    test -d "$ac_dir" ||+      { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||+      continue+    ac_builddir=.++case "$ac_dir" in+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;+*)+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`+  # A ".." for each directory in $ac_dir_suffix.+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`+  case $ac_top_builddir_sub in+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;+  esac ;;+esac+ac_abs_top_builddir=$ac_pwd+ac_abs_builddir=$ac_pwd$ac_dir_suffix+# for backward compatibility:+ac_top_builddir=$ac_top_build_prefix++case $srcdir in+  .)  # We are building in place.+    ac_srcdir=.+    ac_top_srcdir=$ac_top_builddir_sub+    ac_abs_top_srcdir=$ac_pwd ;;+  [\\/]* | ?:[\\/]* )  # Absolute name.+    ac_srcdir=$srcdir$ac_dir_suffix;+    ac_top_srcdir=$srcdir+    ac_abs_top_srcdir=$srcdir ;;+  *) # Relative name.+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix+    ac_top_srcdir=$ac_top_build_prefix$srcdir+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;+esac+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix++    cd "$ac_dir" || { ac_status=$?; continue; }+    # Check for guested configure.+    if test -f "$ac_srcdir/configure.gnu"; then+      echo &&+      $SHELL "$ac_srcdir/configure.gnu" --help=recursive+    elif test -f "$ac_srcdir/configure"; then+      echo &&+      $SHELL "$ac_srcdir/configure" --help=recursive+    else+      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2+    fi || ac_status=$?+    cd "$ac_pwd" || { ac_status=$?; break; }+  done+fi++test -n "$ac_init_help" && exit $ac_status+if $ac_init_version; then+  cat <<\_ACEOF+Haskell Linear Algebra configure 0.8+generated by GNU Autoconf 2.69++Copyright (C) 2012 Free Software Foundation, Inc.+This configure script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it.+_ACEOF+  exit+fi++## ------------------------ ##+## Autoconf initialization. ##+## ------------------------ ##++# ac_fn_c_try_compile LINENO+# --------------------------+# Try to compile conftest.$ac_ext, and return whether this succeeded.+ac_fn_c_try_compile ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  rm -f conftest.$ac_objext+  if { { ac_try="$ac_compile"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+  (eval "$ac_compile") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    grep -v '^ *+' conftest.err >conftest.er1+    cat conftest.er1 >&5+    mv -f conftest.er1 conftest.err+  fi+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && {+	 test -z "$ac_c_werror_flag" ||+	 test ! -s conftest.err+       } && test -s conftest.$ac_objext; then :+  ac_retval=0+else+  $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++	ac_retval=1+fi+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_c_try_compile++# ac_fn_c_try_link LINENO+# -----------------------+# Try to link conftest.$ac_ext, and return whether this succeeded.+ac_fn_c_try_link ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  rm -f conftest.$ac_objext conftest$ac_exeext+  if { { ac_try="$ac_link"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+  (eval "$ac_link") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    grep -v '^ *+' conftest.err >conftest.er1+    cat conftest.er1 >&5+    mv -f conftest.er1 conftest.err+  fi+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; } && {+	 test -z "$ac_c_werror_flag" ||+	 test ! -s conftest.err+       } && test -s conftest$ac_exeext && {+	 test "$cross_compiling" = yes ||+	 test -x conftest$ac_exeext+       }; then :+  ac_retval=0+else+  $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++	ac_retval=1+fi+  # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information+  # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would+  # interfere with the next link command; also delete a directory that is+  # left behind by Apple's compiler.  We do this before executing the actions.+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno+  as_fn_set_status $ac_retval++} # ac_fn_c_try_link++# ac_fn_c_check_func LINENO FUNC VAR+# ----------------------------------+# Tests whether FUNC exists, setting the cache variable VAR accordingly+ac_fn_c_check_func ()+{+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5+$as_echo_n "checking for $2... " >&6; }+if eval \${$3+:} false; then :+  $as_echo_n "(cached) " >&6+else+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */+#define $2 innocuous_$2++/* System header to define __stub macros and hopefully few prototypes,+    which can conflict with char $2 (); below.+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since+    <limits.h> exists even on freestanding compilers.  */++#ifdef __STDC__+# include <limits.h>+#else+# include <assert.h>+#endif++#undef $2++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char $2 ();+/* The GNU C library defines this for functions which it implements+    to always fail with ENOSYS.  Some functions are actually named+    something starting with __ and the normal name is an alias.  */+#if defined __stub_$2 || defined __stub___$2+choke me+#endif++int+main ()+{+return $2 ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  eval "$3=yes"+else+  eval "$3=no"+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+fi+eval ac_res=\$$3+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+$as_echo "$ac_res" >&6; }+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno++} # ac_fn_c_check_func+cat >config.log <<_ACEOF+This file contains any messages produced by compilers while+running configure, to aid debugging if configure makes a mistake.++It was created by Haskell Linear Algebra $as_me 0.8, which was+generated by GNU Autoconf 2.69.  Invocation command line was++  $ $0 $@++_ACEOF+exec 5>>config.log+{+cat <<_ASUNAME+## --------- ##+## Platform. ##+## --------- ##++hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`+uname -m = `(uname -m) 2>/dev/null || echo unknown`+uname -r = `(uname -r) 2>/dev/null || echo unknown`+uname -s = `(uname -s) 2>/dev/null || echo unknown`+uname -v = `(uname -v) 2>/dev/null || echo unknown`++/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`++/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`+/usr/bin/hostinfo      = `(/usr/bin/hostinfo) 2>/dev/null      || echo unknown`+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`++_ASUNAME++as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    $as_echo "PATH: $as_dir"+  done+IFS=$as_save_IFS++} >&5++cat >&5 <<_ACEOF+++## ----------- ##+## Core tests. ##+## ----------- ##++_ACEOF+++# Keep a trace of the command line.+# Strip out --no-create and --no-recursion so they do not pile up.+# Strip out --silent because we don't want to record it for future runs.+# Also quote any args containing shell meta-characters.+# Make two passes to allow for proper duplicate-argument suppression.+ac_configure_args=+ac_configure_args0=+ac_configure_args1=+ac_must_keep_next=false+for ac_pass in 1 2+do+  for ac_arg+  do+    case $ac_arg in+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \+    | -silent | --silent | --silen | --sile | --sil)+      continue ;;+    *\'*)+      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;+    esac+    case $ac_pass in+    1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;+    2)+      as_fn_append ac_configure_args1 " '$ac_arg'"+      if test $ac_must_keep_next = true; then+	ac_must_keep_next=false # Got value, back to normal.+      else+	case $ac_arg in+	  *=* | --config-cache | -C | -disable-* | --disable-* \+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \+	  | -with-* | --with-* | -without-* | --without-* | --x)+	    case "$ac_configure_args0 " in+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;+	    esac+	    ;;+	  -* ) ac_must_keep_next=true ;;+	esac+      fi+      as_fn_append ac_configure_args " '$ac_arg'"+      ;;+    esac+  done+done+{ ac_configure_args0=; unset ac_configure_args0;}+{ ac_configure_args1=; unset ac_configure_args1;}++# When interrupted or exit'd, cleanup temporary files, and complete+# config.log.  We remove comments because anyway the quotes in there+# would cause problems or look ugly.+# WARNING: Use '\'' to represent an apostrophe within the trap.+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.+trap 'exit_status=$?+  # Save into config.log some information that might help in debugging.+  {+    echo++    $as_echo "## ---------------- ##+## Cache variables. ##+## ---------------- ##"+    echo+    # The following way of writing the cache mishandles newlines in values,+(+  for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do+    eval ac_val=\$$ac_var+    case $ac_val in #(+    *${as_nl}*)+      case $ac_var in #(+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;+      esac+      case $ac_var in #(+      _ | IFS | as_nl) ;; #(+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(+      *) { eval $ac_var=; unset $ac_var;} ;;+      esac ;;+    esac+  done+  (set) 2>&1 |+    case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(+    *${as_nl}ac_space=\ *)+      sed -n \+	"s/'\''/'\''\\\\'\'''\''/g;+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"+      ;; #(+    *)+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"+      ;;+    esac |+    sort+)+    echo++    $as_echo "## ----------------- ##+## Output variables. ##+## ----------------- ##"+    echo+    for ac_var in $ac_subst_vars+    do+      eval ac_val=\$$ac_var+      case $ac_val in+      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;+      esac+      $as_echo "$ac_var='\''$ac_val'\''"+    done | sort+    echo++    if test -n "$ac_subst_files"; then+      $as_echo "## ------------------- ##+## File substitutions. ##+## ------------------- ##"+      echo+      for ac_var in $ac_subst_files+      do+	eval ac_val=\$$ac_var+	case $ac_val in+	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;+	esac+	$as_echo "$ac_var='\''$ac_val'\''"+      done | sort+      echo+    fi++    if test -s confdefs.h; then+      $as_echo "## ----------- ##+## confdefs.h. ##+## ----------- ##"+      echo+      cat confdefs.h+      echo+    fi+    test "$ac_signal" != 0 &&+      $as_echo "$as_me: caught signal $ac_signal"+    $as_echo "$as_me: exit $exit_status"+  } >&5+  rm -f core *.core core.conftest.* &&+    rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&+    exit $exit_status+' 0+for ac_signal in 1 2 13 15; do+  trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal+done+ac_signal=0++# confdefs.h avoids OS command line length limits that DEFS can exceed.+rm -f -r conftest* confdefs.h++$as_echo "/* confdefs.h */" > confdefs.h++# Predefined preprocessor variables.++cat >>confdefs.h <<_ACEOF+#define PACKAGE_NAME "$PACKAGE_NAME"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_VERSION "$PACKAGE_VERSION"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_STRING "$PACKAGE_STRING"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"+_ACEOF++cat >>confdefs.h <<_ACEOF+#define PACKAGE_URL "$PACKAGE_URL"+_ACEOF+++# Let the site file select an alternate cache file if it wants to.+# Prefer an explicitly selected file to automatically selected ones.+ac_site_file1=NONE+ac_site_file2=NONE+if test -n "$CONFIG_SITE"; then+  # We do not want a PATH search for config.site.+  case $CONFIG_SITE in #((+    -*)  ac_site_file1=./$CONFIG_SITE;;+    */*) ac_site_file1=$CONFIG_SITE;;+    *)   ac_site_file1=./$CONFIG_SITE;;+  esac+elif test "x$prefix" != xNONE; then+  ac_site_file1=$prefix/share/config.site+  ac_site_file2=$prefix/etc/config.site+else+  ac_site_file1=$ac_default_prefix/share/config.site+  ac_site_file2=$ac_default_prefix/etc/config.site+fi+for ac_site_file in "$ac_site_file1" "$ac_site_file2"+do+  test "x$ac_site_file" = xNONE && continue+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5+$as_echo "$as_me: loading site script $ac_site_file" >&6;}+    sed 's/^/| /' "$ac_site_file" >&5+    . "$ac_site_file" \+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+as_fn_error $? "failed to load site script $ac_site_file+See \`config.log' for more details" "$LINENO" 5; }+  fi+done++if test -r "$cache_file"; then+  # Some versions of bash will fail to source /dev/null (special files+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then+    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5+$as_echo "$as_me: loading cache $cache_file" >&6;}+    case $cache_file in+      [\\/]* | ?:[\\/]* ) . "$cache_file";;+      *)                      . "./$cache_file";;+    esac+  fi+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5+$as_echo "$as_me: creating cache $cache_file" >&6;}+  >$cache_file+fi++# Check that the precious variables saved in the cache have kept the same+# value.+ac_cache_corrupted=false+for ac_var in $ac_precious_vars; do+  eval ac_old_set=\$ac_cv_env_${ac_var}_set+  eval ac_new_set=\$ac_env_${ac_var}_set+  eval ac_old_val=\$ac_cv_env_${ac_var}_value+  eval ac_new_val=\$ac_env_${ac_var}_value+  case $ac_old_set,$ac_new_set in+    set,)+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}+      ac_cache_corrupted=: ;;+    ,set)+      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}+      ac_cache_corrupted=: ;;+    ,);;+    *)+      if test "x$ac_old_val" != "x$ac_new_val"; then+	# differences in whitespace do not lead to failure.+	ac_old_val_w=`echo x $ac_old_val`+	ac_new_val_w=`echo x $ac_new_val`+	if test "$ac_old_val_w" != "$ac_new_val_w"; then+	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}+	  ac_cache_corrupted=:+	else+	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}+	  eval $ac_var=\$ac_old_val+	fi+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5+$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}+	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5+$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}+      fi;;+  esac+  # Pass precious variables to config.status.+  if test "$ac_new_set" = set; then+    case $ac_new_val in+    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;+    *) ac_arg=$ac_var=$ac_new_val ;;+    esac+    case " $ac_configure_args " in+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.+      *) as_fn_append ac_configure_args " '$ac_arg'" ;;+    esac+  fi+done+if $ac_cache_corrupted; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5+fi+## -------------------- ##+## Main body of script. ##+## -------------------- ##++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu++++++++# Check whether --with-compiler was given.+if test "${with_compiler+set}" = set; then :+  withval=$with_compiler;+fi+++# Checks for programs++# Checks for libraries+ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+if test -n "$ac_tool_prefix"; then+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.+set dummy ${ac_tool_prefix}gcc; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_CC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then+    ac_cv_prog_CC="${ac_tool_prefix}gcc"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+$as_echo "$CC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++fi+if test -z "$ac_cv_prog_CC"; then+  ac_ct_CC=$CC+  # Extract the first word of "gcc", so it can be a program name with args.+set dummy gcc; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_ac_ct_CC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$ac_ct_CC"; then+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_CC="gcc"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi+fi+ac_ct_CC=$ac_cv_prog_ac_ct_CC+if test -n "$ac_ct_CC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5+$as_echo "$ac_ct_CC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi++  if test "x$ac_ct_CC" = x; then+    CC=""+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    CC=$ac_ct_CC+  fi+else+  CC="$ac_cv_prog_CC"+fi++if test -z "$CC"; then+          if test -n "$ac_tool_prefix"; then+    # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.+set dummy ${ac_tool_prefix}cc; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_CC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then+    ac_cv_prog_CC="${ac_tool_prefix}cc"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+$as_echo "$CC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++  fi+fi+if test -z "$CC"; then+  # Extract the first word of "cc", so it can be a program name with args.+set dummy cc; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_CC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+  ac_prog_rejected=no+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then+       ac_prog_rejected=yes+       continue+     fi+    ac_cv_prog_CC="cc"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++if test $ac_prog_rejected = yes; then+  # We found a bogon in the path, so make sure we never use it.+  set dummy $ac_cv_prog_CC+  shift+  if test $# != 0; then+    # We chose a different compiler from the bogus one.+    # However, it has the same basename, so the bogon will be chosen+    # first if we set CC to just the basename; use the full file name.+    shift+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"+  fi+fi+fi+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+$as_echo "$CC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++fi+if test -z "$CC"; then+  if test -n "$ac_tool_prefix"; then+  for ac_prog in cl.exe+  do+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.+set dummy $ac_tool_prefix$ac_prog; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_CC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$CC"; then+  ac_cv_prog_CC="$CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi+fi+CC=$ac_cv_prog_CC+if test -n "$CC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5+$as_echo "$CC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++    test -n "$CC" && break+  done+fi+if test -z "$CC"; then+  ac_ct_CC=$CC+  for ac_prog in cl.exe+do+  # Extract the first word of "$ac_prog", so it can be a program name with args.+set dummy $ac_prog; ac_word=$2+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5+$as_echo_n "checking for $ac_word... " >&6; }+if ${ac_cv_prog_ac_ct_CC+:} false; then :+  $as_echo_n "(cached) " >&6+else+  if test -n "$ac_ct_CC"; then+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.+else+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    for ac_exec_ext in '' $ac_executable_extensions; do+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then+    ac_cv_prog_ac_ct_CC="$ac_prog"+    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5+    break 2+  fi+done+  done+IFS=$as_save_IFS++fi+fi+ac_ct_CC=$ac_cv_prog_ac_ct_CC+if test -n "$ac_ct_CC"; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5+$as_echo "$ac_ct_CC" >&6; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+fi+++  test -n "$ac_ct_CC" && break+done++  if test "x$ac_ct_CC" = x; then+    CC=""+  else+    case $cross_compiling:$ac_tool_warned in+yes:)+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}+ac_tool_warned=yes ;;+esac+    CC=$ac_ct_CC+  fi+fi++fi+++test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+as_fn_error $? "no acceptable C compiler found in \$PATH+See \`config.log' for more details" "$LINENO" 5; }++# Provide some information about the compiler.+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5+set X $ac_compile+ac_compiler=$2+for ac_option in --version -v -V -qversion; do+  { { ac_try="$ac_compiler $ac_option >&5"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+  (eval "$ac_compiler $ac_option >&5") 2>conftest.err+  ac_status=$?+  if test -s conftest.err; then+    sed '10a\+... rest of stderr output deleted ...+         10q' conftest.err >conftest.er1+    cat conftest.er1 >&5+  fi+  rm -f conftest.er1 conftest.err+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+done++cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main ()+{++  ;+  return 0;+}+_ACEOF+ac_clean_files_save=$ac_clean_files+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"+# Try to create an executable without -o first, disregard a.out.+# It will help us diagnose broken compilers, and finding out an intuition+# of exeext.+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5+$as_echo_n "checking whether the C compiler works... " >&6; }+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`++# The possible output files:+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"++ac_rmfiles=+for ac_file in $ac_files+do+  case $ac_file in+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;+    * ) ac_rmfiles="$ac_rmfiles $ac_file";;+  esac+done+rm -f $ac_rmfiles++if { { ac_try="$ac_link_default"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+  (eval "$ac_link_default") 2>&5+  ac_status=$?+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then :+  # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'+# in a Makefile.  We should not override ac_cv_exeext if it was cached,+# so that the user can short-circuit this test for compilers unknown to+# Autoconf.+for ac_file in $ac_files ''+do+  test -f "$ac_file" || continue+  case $ac_file in+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )+	;;+    [ab].out )+	# We found the default executable, but exeext='' is most+	# certainly right.+	break;;+    *.* )+	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;+	then :; else+	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`+	fi+	# We set ac_cv_exeext here because the later test for it is not+	# safe: cross compilers may not add the suffix if given an `-o'+	# argument, so we may need to know it at that point already.+	# Even if this section looks crufty: it has the advantage of+	# actually working.+	break;;+    * )+	break;;+  esac+done+test "$ac_cv_exeext" = no && ac_cv_exeext=++else+  ac_file=''+fi+if test -z "$ac_file"; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5+$as_echo "no" >&6; }+$as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+as_fn_error 77 "C compiler cannot create executables+See \`config.log' for more details" "$LINENO" 5; }+else+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5+$as_echo "yes" >&6; }+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5+$as_echo_n "checking for C compiler default output file name... " >&6; }+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5+$as_echo "$ac_file" >&6; }+ac_exeext=$ac_cv_exeext++rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out+ac_clean_files=$ac_clean_files_save+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5+$as_echo_n "checking for suffix of executables... " >&6; }+if { { ac_try="$ac_link"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+  (eval "$ac_link") 2>&5+  ac_status=$?+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then :+  # If both `conftest.exe' and `conftest' are `present' (well, observable)+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will+# work properly (i.e., refer to `conftest.exe'), while it won't with+# `rm'.+for ac_file in conftest.exe conftest conftest.*; do+  test -f "$ac_file" || continue+  case $ac_file in+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`+	  break;;+    * ) break;;+  esac+done+else+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+as_fn_error $? "cannot compute suffix of executables: cannot compile and link+See \`config.log' for more details" "$LINENO" 5; }+fi+rm -f conftest conftest$ac_cv_exeext+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5+$as_echo "$ac_cv_exeext" >&6; }++rm -f conftest.$ac_ext+EXEEXT=$ac_cv_exeext+ac_exeext=$EXEEXT+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <stdio.h>+int+main ()+{+FILE *f = fopen ("conftest.out", "w");+ return ferror (f) || fclose (f) != 0;++  ;+  return 0;+}+_ACEOF+ac_clean_files="$ac_clean_files conftest.out"+# Check that the compiler produces executables we can run.  If not, either+# the compiler is broken, or we cross compile.+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5+$as_echo_n "checking whether we are cross compiling... " >&6; }+if test "$cross_compiling" != yes; then+  { { ac_try="$ac_link"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+  (eval "$ac_link") 2>&5+  ac_status=$?+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }+  if { ac_try='./conftest$ac_cv_exeext'+  { { case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+  (eval "$ac_try") 2>&5+  ac_status=$?+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; }; then+    cross_compiling=no+  else+    if test "$cross_compiling" = maybe; then+	cross_compiling=yes+    else+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+as_fn_error $? "cannot run C compiled programs.+If you meant to cross compile, use \`--host'.+See \`config.log' for more details" "$LINENO" 5; }+    fi+  fi+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5+$as_echo "$cross_compiling" >&6; }++rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out+ac_clean_files=$ac_clean_files_save+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5+$as_echo_n "checking for suffix of object files... " >&6; }+if ${ac_cv_objext+:} false; then :+  $as_echo_n "(cached) " >&6+else+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main ()+{++  ;+  return 0;+}+_ACEOF+rm -f conftest.o conftest.obj+if { { ac_try="$ac_compile"+case "(($ac_try" in+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;+  *) ac_try_echo=$ac_try;;+esac+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""+$as_echo "$ac_try_echo"; } >&5+  (eval "$ac_compile") 2>&5+  ac_status=$?+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5+  test $ac_status = 0; }; then :+  for ac_file in conftest.o conftest.obj conftest.*; do+  test -f "$ac_file" || continue;+  case $ac_file in+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`+       break;;+  esac+done+else+  $as_echo "$as_me: failed program was:" >&5+sed 's/^/| /' conftest.$ac_ext >&5++{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}+as_fn_error $? "cannot compute suffix of object files: cannot compile+See \`config.log' for more details" "$LINENO" 5; }+fi+rm -f conftest.$ac_cv_objext conftest.$ac_ext+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5+$as_echo "$ac_cv_objext" >&6; }+OBJEXT=$ac_cv_objext+ac_objext=$OBJEXT+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }+if ${ac_cv_c_compiler_gnu+:} false; then :+  $as_echo_n "(cached) " >&6+else+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main ()+{+#ifndef __GNUC__+       choke me+#endif++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"; then :+  ac_compiler_gnu=yes+else+  ac_compiler_gnu=no+fi+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+ac_cv_c_compiler_gnu=$ac_compiler_gnu++fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5+$as_echo "$ac_cv_c_compiler_gnu" >&6; }+if test $ac_compiler_gnu = yes; then+  GCC=yes+else+  GCC=+fi+ac_test_CFLAGS=${CFLAGS+set}+ac_save_CFLAGS=$CFLAGS+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5+$as_echo_n "checking whether $CC accepts -g... " >&6; }+if ${ac_cv_prog_cc_g+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_save_c_werror_flag=$ac_c_werror_flag+   ac_c_werror_flag=yes+   ac_cv_prog_cc_g=no+   CFLAGS="-g"+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main ()+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"; then :+  ac_cv_prog_cc_g=yes+else+  CFLAGS=""+      cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main ()+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"; then :++else+  ac_c_werror_flag=$ac_save_c_werror_flag+	 CFLAGS="-g"+	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++int+main ()+{++  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_compile "$LINENO"; then :+  ac_cv_prog_cc_g=yes+fi+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+fi+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+fi+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext+   ac_c_werror_flag=$ac_save_c_werror_flag+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5+$as_echo "$ac_cv_prog_cc_g" >&6; }+if test "$ac_test_CFLAGS" = set; then+  CFLAGS=$ac_save_CFLAGS+elif test $ac_cv_prog_cc_g = yes; then+  if test "$GCC" = yes; then+    CFLAGS="-g -O2"+  else+    CFLAGS="-g"+  fi+else+  if test "$GCC" = yes; then+    CFLAGS="-O2"+  else+    CFLAGS=+  fi+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }+if ${ac_cv_prog_cc_c89+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_cv_prog_cc_c89=no+ac_save_CC=$CC+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */+#include <stdarg.h>+#include <stdio.h>+struct stat;+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */+struct buf { int x; };+FILE * (*rcsopen) (struct buf *, struct stat *, int);+static char *e (p, i)+     char **p;+     int i;+{+  return p[i];+}+static char *f (char * (*g) (char **, int), char **p, ...)+{+  char *s;+  va_list v;+  va_start (v,p);+  s = g (p, va_arg (v,int));+  va_end (v);+  return s;+}++/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has+   function prototypes and stuff, but not '\xHH' hex character constants.+   These don't provoke an error unfortunately, instead are silently treated+   as 'x'.  The following induces an error, until -std is added to get+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an+   array size at least.  It's necessary to write '\x00'==0 to get something+   that's true only with -std.  */+int osf4_cc_array ['\x00' == 0 ? 1 : -1];++/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters+   inside strings and character constants.  */+#define FOO(x) 'x'+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];++int test (int i, double x);+struct s1 {int (*f) (int a);};+struct s2 {int (*f) (double a);};+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);+int argc;+char **argv;+int+main ()+{+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];+  ;+  return 0;+}+_ACEOF+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \+	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"+do+  CC="$ac_save_CC $ac_arg"+  if ac_fn_c_try_compile "$LINENO"; then :+  ac_cv_prog_cc_c89=$ac_arg+fi+rm -f core conftest.err conftest.$ac_objext+  test "x$ac_cv_prog_cc_c89" != "xno" && break+done+rm -f conftest.$ac_ext+CC=$ac_save_CC++fi+# AC_CACHE_VAL+case "x$ac_cv_prog_cc_c89" in+  x)+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5+$as_echo "none needed" >&6; } ;;+  xno)+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5+$as_echo "unsupported" >&6; } ;;+  *)+    CC="$CC $ac_cv_prog_cc_c89"+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;+esac+if test "x$ac_cv_prog_cc_c89" != xno; then :++fi++ac_ext=c+ac_cpp='$CPP $CPPFLAGS'+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'+ac_compiler_gnu=$ac_cv_c_compiler_gnu+++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cos in -lm" >&5+$as_echo_n "checking for cos in -lm... " >&6; }+if ${ac_cv_lib_m_cos+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lm  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char cos ();+int+main ()+{+return cos ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_m_cos=yes+else+  ac_cv_lib_m_cos=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_cos" >&5+$as_echo "$ac_cv_lib_m_cos" >&6; }+if test "x$ac_cv_lib_m_cos" = xyes; then :+  cat >>confdefs.h <<_ACEOF+#define HAVE_LIBM 1+_ACEOF++  LIBS="-lm $LIBS"++fi++++ax_blas_ok=no+++# Check whether --with-blas was given.+if test "${with_blas+set}" = set; then :+  withval=$with_blas;+fi++case $with_blas in+	yes | "") ;;+	no) ax_blas_ok=disable ;;+	-* | */* | *.a | *.so | *.so.* | *.o) BLAS_LIBS="$with_blas" ;;+	*) BLAS_LIBS="-l$with_blas" ;;+esac++++++++ax_blas_save_LIBS="$LIBS"+LIBS="$LIBS $FLIBS"++# First, check BLAS_LIBS environment variable+if test x$ax_blas_ok = xno; then+  if test x$BLAS_LIBS != x; then+    save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in $BLAS_LIBS" >&5+$as_echo_n "checking for sgemm_ in $BLAS_LIBS... " >&6; }+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ax_blas_ok=yes+else+  BLAS_LIBS=""+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_blas_ok" >&5+$as_echo "$ax_blas_ok" >&6; }+    LIBS="$save_LIBS"+  fi+fi++# BLAS linked to by default?  (happens on some supercomputers)+if test x$ax_blas_ok = xno; then+  save_LIBS="$LIBS"; LIBS="$LIBS"+  ac_fn_c_check_func "$LINENO" "sgemm_" "ac_cv_func_sgemm_"+if test "x$ac_cv_func_sgemm_" = xyes; then :+  ax_blas_ok=yes+fi++  LIBS="$save_LIBS"+fi++# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ATL_xerbla in -latlas" >&5+$as_echo_n "checking for ATL_xerbla in -latlas... " >&6; }+if ${ac_cv_lib_atlas_ATL_xerbla+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-latlas  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char ATL_xerbla ();+int+main ()+{+return ATL_xerbla ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_atlas_ATL_xerbla=yes+else+  ac_cv_lib_atlas_ATL_xerbla=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_atlas_ATL_xerbla" >&5+$as_echo "$ac_cv_lib_atlas_ATL_xerbla" >&6; }+if test "x$ac_cv_lib_atlas_ATL_xerbla" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lf77blas" >&5+$as_echo_n "checking for sgemm_ in -lf77blas... " >&6; }+if ${ac_cv_lib_f77blas_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lf77blas -latlas $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_f77blas_sgemm_=yes+else+  ac_cv_lib_f77blas_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_f77blas_sgemm_" >&5+$as_echo "$ac_cv_lib_f77blas_sgemm_" >&6; }+if test "x$ac_cv_lib_f77blas_sgemm_" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cblas_dgemm in -lcblas" >&5+$as_echo_n "checking for cblas_dgemm in -lcblas... " >&6; }+if ${ac_cv_lib_cblas_cblas_dgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lcblas -lf77blas -latlas $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char cblas_dgemm ();+int+main ()+{+return cblas_dgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_cblas_cblas_dgemm=yes+else+  ac_cv_lib_cblas_cblas_dgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cblas_cblas_dgemm" >&5+$as_echo "$ac_cv_lib_cblas_cblas_dgemm" >&6; }+if test "x$ac_cv_lib_cblas_cblas_dgemm" = xyes; then :+  ax_blas_ok=yes+           BLAS_LIBS="-lcblas -lf77blas -latlas"+fi++fi++fi++fi++# BLAS in Intel MKL library?+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lmkl" >&5+$as_echo_n "checking for sgemm_ in -lmkl... " >&6; }+if ${ac_cv_lib_mkl_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lmkl  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_mkl_sgemm_=yes+else+  ac_cv_lib_mkl_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mkl_sgemm_" >&5+$as_echo "$ac_cv_lib_mkl_sgemm_" >&6; }+if test "x$ac_cv_lib_mkl_sgemm_" = xyes; then :+  ax_blas_ok=yes;BLAS_LIBS="-lmkl"+fi++fi++# BLAS in Apple vecLib library?+if test x$ax_blas_ok = xno; then+  save_LIBS="$LIBS"; LIBS="-framework vecLib $LIBS"+  unset ac_cv_func_sgemm_+  ac_fn_c_check_func "$LINENO" "sgemm_" "ac_cv_func_sgemm_"+if test "x$ac_cv_func_sgemm_" = xyes; then :+  ax_blas_ok=yes;BLAS_LIBS="-lblas"+fi++  LIBS="$save_LIBS"+fi++# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)+if test $ax_blas_ok = no; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lblas" >&5+$as_echo_n "checking for sgemm_ in -lblas... " >&6; }+if ${ac_cv_lib_blas_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lblas  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_blas_sgemm_=yes+else+  ac_cv_lib_blas_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blas_sgemm_" >&5+$as_echo "$ac_cv_lib_blas_sgemm_" >&6; }+if test "x$ac_cv_lib_blas_sgemm_" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgemm_ in -ldgemm" >&5+$as_echo_n "checking for dgemm_ in -ldgemm... " >&6; }+if ${ac_cv_lib_dgemm_dgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-ldgemm -lblas $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char dgemm_ ();+int+main ()+{+return dgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_dgemm_dgemm_=yes+else+  ac_cv_lib_dgemm_dgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dgemm_dgemm_" >&5+$as_echo "$ac_cv_lib_dgemm_dgemm_" >&6; }+if test "x$ac_cv_lib_dgemm_dgemm_" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lsgemm" >&5+$as_echo_n "checking for sgemm_ in -lsgemm... " >&6; }+if ${ac_cv_lib_sgemm_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lsgemm -lblas $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_sgemm_sgemm_=yes+else+  ac_cv_lib_sgemm_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sgemm_sgemm_" >&5+$as_echo "$ac_cv_lib_sgemm_sgemm_" >&6; }+if test "x$ac_cv_lib_sgemm_sgemm_" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lsgemm -ldgemm -lblas"+fi++fi++fi++fi++# BLAS in Alpha CXML library?+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lcxml" >&5+$as_echo_n "checking for sgemm_ in -lcxml... " >&6; }+if ${ac_cv_lib_cxml_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lcxml  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_cxml_sgemm_=yes+else+  ac_cv_lib_cxml_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cxml_sgemm_" >&5+$as_echo "$ac_cv_lib_cxml_sgemm_" >&6; }+if test "x$ac_cv_lib_cxml_sgemm_" = xyes; then :+  ax_blas_ok=yes;BLAS_LIBS="-lcxml"+fi++fi++# BLAS in Alpha DXML library? (now called CXML, see above)+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -ldxml" >&5+$as_echo_n "checking for sgemm_ in -ldxml... " >&6; }+if ${ac_cv_lib_dxml_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-ldxml  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_dxml_sgemm_=yes+else+  ac_cv_lib_dxml_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dxml_sgemm_" >&5+$as_echo "$ac_cv_lib_dxml_sgemm_" >&6; }+if test "x$ac_cv_lib_dxml_sgemm_" = xyes; then :+  ax_blas_ok=yes;BLAS_LIBS="-ldxml"+fi++fi++# BLAS in Sun Performance library?+if test x$ax_blas_ok = xno; then+  if test "x$GCC" != xyes; then # only works with Sun CC+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acosp in -lsunmath" >&5+$as_echo_n "checking for acosp in -lsunmath... " >&6; }+if ${ac_cv_lib_sunmath_acosp+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lsunmath  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char acosp ();+int+main ()+{+return acosp ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_sunmath_acosp=yes+else+  ac_cv_lib_sunmath_acosp=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sunmath_acosp" >&5+$as_echo "$ac_cv_lib_sunmath_acosp" >&6; }+if test "x$ac_cv_lib_sunmath_acosp" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lsunperf" >&5+$as_echo_n "checking for sgemm_ in -lsunperf... " >&6; }+if ${ac_cv_lib_sunperf_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lsunperf -lsunmath $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_sunperf_sgemm_=yes+else+  ac_cv_lib_sunperf_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sunperf_sgemm_" >&5+$as_echo "$ac_cv_lib_sunperf_sgemm_" >&6; }+if test "x$ac_cv_lib_sunperf_sgemm_" = xyes; then :+  BLAS_LIBS="-xlic_lib=sunperf -lsunmath"+       ax_blas_ok=yes+fi++fi++  fi+fi++# BLAS in SCSL library?  (SGI/Cray Scientific Library)+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lscs" >&5+$as_echo_n "checking for sgemm_ in -lscs... " >&6; }+if ${ac_cv_lib_scs_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lscs  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_scs_sgemm_=yes+else+  ac_cv_lib_scs_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_scs_sgemm_" >&5+$as_echo "$ac_cv_lib_scs_sgemm_" >&6; }+if test "x$ac_cv_lib_scs_sgemm_" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lscs"+fi++fi++# BLAS in SGIMATH library?+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lcomplib.sgimath" >&5+$as_echo_n "checking for sgemm_ in -lcomplib.sgimath... " >&6; }+if ${ac_cv_lib_complib_sgimath_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lcomplib.sgimath  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_complib_sgimath_sgemm_=yes+else+  ac_cv_lib_complib_sgimath_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_complib_sgimath_sgemm_" >&5+$as_echo "$ac_cv_lib_complib_sgimath_sgemm_" >&6; }+if test "x$ac_cv_lib_complib_sgimath_sgemm_" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lcomplib.sgimath"+fi++fi++# BLAS in IBM ESSL library? (requires generic BLAS lib, too)+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lblas" >&5+$as_echo_n "checking for sgemm_ in -lblas... " >&6; }+if ${ac_cv_lib_blas_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lblas  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_blas_sgemm_=yes+else+  ac_cv_lib_blas_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blas_sgemm_" >&5+$as_echo "$ac_cv_lib_blas_sgemm_" >&6; }+if test "x$ac_cv_lib_blas_sgemm_" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lessl" >&5+$as_echo_n "checking for sgemm_ in -lessl... " >&6; }+if ${ac_cv_lib_essl_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lessl -lblas $FLIBS $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_essl_sgemm_=yes+else+  ac_cv_lib_essl_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_essl_sgemm_" >&5+$as_echo "$ac_cv_lib_essl_sgemm_" >&6; }+if test "x$ac_cv_lib_essl_sgemm_" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lessl -lblas"+fi++fi++fi++# Generic BLAS library?+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm_ in -lblas" >&5+$as_echo_n "checking for sgemm_ in -lblas... " >&6; }+if ${ac_cv_lib_blas_sgemm_+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lblas  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm_ ();+int+main ()+{+return sgemm_ ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_blas_sgemm_=yes+else+  ac_cv_lib_blas_sgemm_=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blas_sgemm_" >&5+$as_echo "$ac_cv_lib_blas_sgemm_" >&6; }+if test "x$ac_cv_lib_blas_sgemm_" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lblas"+fi++fi++LIBS="$ax_blas_save_LIBS"++++++if test x$ax_blas_ok = xyes; then+  ax_blas_underscore=yes+else+++++++ax_blas_save_LIBS="$LIBS"+LIBS="$LIBS $FLIBS"++# First, check BLAS_LIBS environment variable+if test x$ax_blas_ok = xno; then+  if test x$BLAS_LIBS != x; then+    save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in $BLAS_LIBS" >&5+$as_echo_n "checking for sgemm in $BLAS_LIBS... " >&6; }+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ax_blas_ok=yes+else+  BLAS_LIBS=""+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_blas_ok" >&5+$as_echo "$ax_blas_ok" >&6; }+    LIBS="$save_LIBS"+  fi+fi++# BLAS linked to by default?  (happens on some supercomputers)+if test x$ax_blas_ok = xno; then+  save_LIBS="$LIBS"; LIBS="$LIBS"+  ac_fn_c_check_func "$LINENO" "sgemm" "ac_cv_func_sgemm"+if test "x$ac_cv_func_sgemm" = xyes; then :+  ax_blas_ok=yes+fi++  LIBS="$save_LIBS"+fi++# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ATL_xerbla in -latlas" >&5+$as_echo_n "checking for ATL_xerbla in -latlas... " >&6; }+if ${ac_cv_lib_atlas_ATL_xerbla+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-latlas  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char ATL_xerbla ();+int+main ()+{+return ATL_xerbla ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_atlas_ATL_xerbla=yes+else+  ac_cv_lib_atlas_ATL_xerbla=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_atlas_ATL_xerbla" >&5+$as_echo "$ac_cv_lib_atlas_ATL_xerbla" >&6; }+if test "x$ac_cv_lib_atlas_ATL_xerbla" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lf77blas" >&5+$as_echo_n "checking for sgemm in -lf77blas... " >&6; }+if ${ac_cv_lib_f77blas_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lf77blas -latlas $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_f77blas_sgemm=yes+else+  ac_cv_lib_f77blas_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_f77blas_sgemm" >&5+$as_echo "$ac_cv_lib_f77blas_sgemm" >&6; }+if test "x$ac_cv_lib_f77blas_sgemm" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cblas_dgemm in -lcblas" >&5+$as_echo_n "checking for cblas_dgemm in -lcblas... " >&6; }+if ${ac_cv_lib_cblas_cblas_dgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lcblas -lf77blas -latlas $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char cblas_dgemm ();+int+main ()+{+return cblas_dgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_cblas_cblas_dgemm=yes+else+  ac_cv_lib_cblas_cblas_dgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cblas_cblas_dgemm" >&5+$as_echo "$ac_cv_lib_cblas_cblas_dgemm" >&6; }+if test "x$ac_cv_lib_cblas_cblas_dgemm" = xyes; then :+  ax_blas_ok=yes+           BLAS_LIBS="-lcblas -lf77blas -latlas"+fi++fi++fi++fi++# BLAS in Intel MKL library?+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lmkl" >&5+$as_echo_n "checking for sgemm in -lmkl... " >&6; }+if ${ac_cv_lib_mkl_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lmkl  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_mkl_sgemm=yes+else+  ac_cv_lib_mkl_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mkl_sgemm" >&5+$as_echo "$ac_cv_lib_mkl_sgemm" >&6; }+if test "x$ac_cv_lib_mkl_sgemm" = xyes; then :+  ax_blas_ok=yes;BLAS_LIBS="-lmkl"+fi++fi++# BLAS in Apple vecLib library?+if test x$ax_blas_ok = xno; then+  save_LIBS="$LIBS"; LIBS="-framework vecLib $LIBS"+  unset ac_cv_func_sgemm+  ac_fn_c_check_func "$LINENO" "sgemm" "ac_cv_func_sgemm"+if test "x$ac_cv_func_sgemm" = xyes; then :+  ax_blas_ok=yes;BLAS_LIBS="-lblas"+fi++  LIBS="$save_LIBS"+fi++# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)+if test $ax_blas_ok = no; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lblas" >&5+$as_echo_n "checking for sgemm in -lblas... " >&6; }+if ${ac_cv_lib_blas_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lblas  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_blas_sgemm=yes+else+  ac_cv_lib_blas_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blas_sgemm" >&5+$as_echo "$ac_cv_lib_blas_sgemm" >&6; }+if test "x$ac_cv_lib_blas_sgemm" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dgemm in -ldgemm" >&5+$as_echo_n "checking for dgemm in -ldgemm... " >&6; }+if ${ac_cv_lib_dgemm_dgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-ldgemm -lblas $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char dgemm ();+int+main ()+{+return dgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_dgemm_dgemm=yes+else+  ac_cv_lib_dgemm_dgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dgemm_dgemm" >&5+$as_echo "$ac_cv_lib_dgemm_dgemm" >&6; }+if test "x$ac_cv_lib_dgemm_dgemm" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lsgemm" >&5+$as_echo_n "checking for sgemm in -lsgemm... " >&6; }+if ${ac_cv_lib_sgemm_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lsgemm -lblas $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_sgemm_sgemm=yes+else+  ac_cv_lib_sgemm_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sgemm_sgemm" >&5+$as_echo "$ac_cv_lib_sgemm_sgemm" >&6; }+if test "x$ac_cv_lib_sgemm_sgemm" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lsgemm -ldgemm -lblas"+fi++fi++fi++fi++# BLAS in Alpha CXML library?+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lcxml" >&5+$as_echo_n "checking for sgemm in -lcxml... " >&6; }+if ${ac_cv_lib_cxml_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lcxml  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_cxml_sgemm=yes+else+  ac_cv_lib_cxml_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cxml_sgemm" >&5+$as_echo "$ac_cv_lib_cxml_sgemm" >&6; }+if test "x$ac_cv_lib_cxml_sgemm" = xyes; then :+  ax_blas_ok=yes;BLAS_LIBS="-lcxml"+fi++fi++# BLAS in Alpha DXML library? (now called CXML, see above)+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -ldxml" >&5+$as_echo_n "checking for sgemm in -ldxml... " >&6; }+if ${ac_cv_lib_dxml_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-ldxml  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_dxml_sgemm=yes+else+  ac_cv_lib_dxml_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dxml_sgemm" >&5+$as_echo "$ac_cv_lib_dxml_sgemm" >&6; }+if test "x$ac_cv_lib_dxml_sgemm" = xyes; then :+  ax_blas_ok=yes;BLAS_LIBS="-ldxml"+fi++fi++# BLAS in Sun Performance library?+if test x$ax_blas_ok = xno; then+  if test "x$GCC" != xyes; then # only works with Sun CC+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for acosp in -lsunmath" >&5+$as_echo_n "checking for acosp in -lsunmath... " >&6; }+if ${ac_cv_lib_sunmath_acosp+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lsunmath  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char acosp ();+int+main ()+{+return acosp ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_sunmath_acosp=yes+else+  ac_cv_lib_sunmath_acosp=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sunmath_acosp" >&5+$as_echo "$ac_cv_lib_sunmath_acosp" >&6; }+if test "x$ac_cv_lib_sunmath_acosp" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lsunperf" >&5+$as_echo_n "checking for sgemm in -lsunperf... " >&6; }+if ${ac_cv_lib_sunperf_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lsunperf -lsunmath $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_sunperf_sgemm=yes+else+  ac_cv_lib_sunperf_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_sunperf_sgemm" >&5+$as_echo "$ac_cv_lib_sunperf_sgemm" >&6; }+if test "x$ac_cv_lib_sunperf_sgemm" = xyes; then :+  BLAS_LIBS="-xlic_lib=sunperf -lsunmath"+       ax_blas_ok=yes+fi++fi++  fi+fi++# BLAS in SCSL library?  (SGI/Cray Scientific Library)+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lscs" >&5+$as_echo_n "checking for sgemm in -lscs... " >&6; }+if ${ac_cv_lib_scs_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lscs  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_scs_sgemm=yes+else+  ac_cv_lib_scs_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_scs_sgemm" >&5+$as_echo "$ac_cv_lib_scs_sgemm" >&6; }+if test "x$ac_cv_lib_scs_sgemm" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lscs"+fi++fi++# BLAS in SGIMATH library?+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lcomplib.sgimath" >&5+$as_echo_n "checking for sgemm in -lcomplib.sgimath... " >&6; }+if ${ac_cv_lib_complib_sgimath_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lcomplib.sgimath  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_complib_sgimath_sgemm=yes+else+  ac_cv_lib_complib_sgimath_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_complib_sgimath_sgemm" >&5+$as_echo "$ac_cv_lib_complib_sgimath_sgemm" >&6; }+if test "x$ac_cv_lib_complib_sgimath_sgemm" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lcomplib.sgimath"+fi++fi++# BLAS in IBM ESSL library? (requires generic BLAS lib, too)+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lblas" >&5+$as_echo_n "checking for sgemm in -lblas... " >&6; }+if ${ac_cv_lib_blas_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lblas  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_blas_sgemm=yes+else+  ac_cv_lib_blas_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blas_sgemm" >&5+$as_echo "$ac_cv_lib_blas_sgemm" >&6; }+if test "x$ac_cv_lib_blas_sgemm" = xyes; then :+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lessl" >&5+$as_echo_n "checking for sgemm in -lessl... " >&6; }+if ${ac_cv_lib_essl_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lessl -lblas $FLIBS $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_essl_sgemm=yes+else+  ac_cv_lib_essl_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_essl_sgemm" >&5+$as_echo "$ac_cv_lib_essl_sgemm" >&6; }+if test "x$ac_cv_lib_essl_sgemm" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lessl -lblas"+fi++fi++fi++# Generic BLAS library?+if test x$ax_blas_ok = xno; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for sgemm in -lblas" >&5+$as_echo_n "checking for sgemm in -lblas... " >&6; }+if ${ac_cv_lib_blas_sgemm+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-lblas  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char sgemm ();+int+main ()+{+return sgemm ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ac_cv_lib_blas_sgemm=yes+else+  ac_cv_lib_blas_sgemm=no+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_blas_sgemm" >&5+$as_echo "$ac_cv_lib_blas_sgemm" >&6; }+if test "x$ac_cv_lib_blas_sgemm" = xyes; then :+  ax_blas_ok=yes; BLAS_LIBS="-lblas"+fi++fi++LIBS="$ax_blas_save_LIBS"++++++  if test x$ax_blas_ok = xyes; then+    ax_blas_undersore=no+  fi+fi+++if test x$ax_blas_ok = xyes; then+++$as_echo "#define HAVE_BLAS 1" >>confdefs.h+++    if test x$ax_blas_underscore = xyes; then+      $as_echo "#define F77_FUNC(name) name ## _" >>confdefs.h++    else+      $as_echo "#define F77_FUNC(name) name" >>confdefs.h++    fi+  :+else+  ax_blas_ok=no++fi+++++ax_lapack_ok=no+++# Check whether --with-lapack was given.+if test "${with_lapack+set}" = set; then :+  withval=$with_lapack;+fi++case $with_lapack in+        yes | "") ;;+        no) ax_lapack_ok=disable ;;+        -* | */* | *.a | *.so | *.so.* | *.o) LAPACK_LIBS="$with_lapack" ;;+        *) LAPACK_LIBS="-l$with_lapack" ;;+esac++# Get fortran linker name of LAPACK function to check for.+if test x"$ax_blas_underscore" = xyes; then+    cheev=cheev_+else+    cheev=cheev+fi++# We cannot use LAPACK if BLAS is not found+if test "x$ax_blas_ok" != xyes; then+        ax_lapack_ok=noblas+        LAPACK_LIBS=""+fi++# First, check LAPACK_LIBS environment variable+if test "x$LAPACK_LIBS" != x; then+        save_LIBS="$LIBS"; LIBS="$LAPACK_LIBS $BLAS_LIBS $LIBS"+        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $cheev in $LAPACK_LIBS" >&5+$as_echo_n "checking for $cheev in $LAPACK_LIBS... " >&6; }+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char $cheev ();+int+main ()+{+return $cheev ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  ax_lapack_ok=yes+else+  LAPACK_LIBS=""+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_lapack_ok" >&5+$as_echo "$ax_lapack_ok" >&6; }+        LIBS="$save_LIBS"+        if test $ax_lapack_ok = no; then+                LAPACK_LIBS=""+        fi+fi++# LAPACK linked to by default?  (is sometimes included in BLAS lib)+if test $ax_lapack_ok = no; then+        save_LIBS="$LIBS"; LIBS="$LIBS $BLAS_LIBS"+        as_ac_var=`$as_echo "ac_cv_func_$cheev" | $as_tr_sh`+ac_fn_c_check_func "$LINENO" "$cheev" "$as_ac_var"+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :+  ax_lapack_ok=yes+fi++        LIBS="$save_LIBS"+fi++# Generic LAPACK library?+for lapack in lapack lapack_rs6k; do+        if test $ax_lapack_ok = no; then+                save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"+                as_ac_Lib=`$as_echo "ac_cv_lib_$lapack''_$cheev" | $as_tr_sh`+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $cheev in -l$lapack" >&5+$as_echo_n "checking for $cheev in -l$lapack... " >&6; }+if eval \${$as_ac_Lib+:} false; then :+  $as_echo_n "(cached) " >&6+else+  ac_check_lib_save_LIBS=$LIBS+LIBS="-l$lapack  $LIBS"+cat confdefs.h - <<_ACEOF >conftest.$ac_ext+/* end confdefs.h.  */++/* Override any GCC internal prototype to avoid an error.+   Use char because int might match the return type of a GCC+   builtin and then its argument prototype would still apply.  */+#ifdef __cplusplus+extern "C"+#endif+char $cheev ();+int+main ()+{+return $cheev ();+  ;+  return 0;+}+_ACEOF+if ac_fn_c_try_link "$LINENO"; then :+  eval "$as_ac_Lib=yes"+else+  eval "$as_ac_Lib=no"+fi+rm -f core conftest.err conftest.$ac_objext \+    conftest$ac_exeext conftest.$ac_ext+LIBS=$ac_check_lib_save_LIBS+fi+eval ac_res=\$$as_ac_Lib+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5+$as_echo "$ac_res" >&6; }+if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then :+  ax_lapack_ok=yes; LAPACK_LIBS="-l$lapack"+fi++                LIBS="$save_LIBS"+        fi+done++++# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:+if test x"$ax_lapack_ok" = xyes; then++$as_echo "#define HAVE_LAPACK 1" >>confdefs.h++        :+else+        ax_lapack_ok=no++fi+++if test "$ax_lapack_ok" = yes; then+  BUILD_PACKAGE_BOOL=True+else+  BUILD_PACKAGE_BOOL=False+fi+++ac_config_headers="$ac_config_headers cbits/config.h"++ac_config_files="$ac_config_files linear-algebra.buildinfo"++cat >confcache <<\_ACEOF+# This file is a shell script that caches the results of configure+# tests run on this system so they can be shared between configure+# scripts and configure runs, see configure's option --config-cache.+# It is not useful on other systems.  If it contains results you don't+# want to keep, you may remove or edit it.+#+# config.status only pays attention to the cache file if you give it+# the --recheck option to rerun configure.+#+# `ac_cv_env_foo' variables (set or unset) will be overridden when+# loading this file, other *unset* `ac_cv_foo' will be assigned the+# following values.++_ACEOF++# The following way of writing the cache mishandles newlines in values,+# but we know of no workaround that is simple, portable, and efficient.+# So, we kill variables containing newlines.+# Ultrix sh set writes to stderr and can't be redirected directly,+# and sets the high bit in the cache file unless we assign to the vars.+(+  for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do+    eval ac_val=\$$ac_var+    case $ac_val in #(+    *${as_nl}*)+      case $ac_var in #(+      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;+      esac+      case $ac_var in #(+      _ | IFS | as_nl) ;; #(+      BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(+      *) { eval $ac_var=; unset $ac_var;} ;;+      esac ;;+    esac+  done++  (set) 2>&1 |+    case $as_nl`(ac_space=' '; set) 2>&1` in #(+    *${as_nl}ac_space=\ *)+      # `set' does not quote correctly, so add quotes: double-quote+      # substitution turns \\\\ into \\, and sed turns \\ into \.+      sed -n \+	"s/'/'\\\\''/g;+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"+      ;; #(+    *)+      # `set' quotes correctly as required by POSIX, so do not add quotes.+      sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"+      ;;+    esac |+    sort+) |+  sed '+     /^ac_cv_env_/b end+     t clear+     :clear+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/+     t end+     s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/+     :end' >>confcache+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else+  if test -w "$cache_file"; then+    if test "x$cache_file" != "x/dev/null"; then+      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5+$as_echo "$as_me: updating cache $cache_file" >&6;}+      if test ! -f "$cache_file" || test -h "$cache_file"; then+	cat confcache >"$cache_file"+      else+        case $cache_file in #(+        */* | ?:*)+	  mv -f confcache "$cache_file"$$ &&+	  mv -f "$cache_file"$$ "$cache_file" ;; #(+        *)+	  mv -f confcache "$cache_file" ;;+	esac+      fi+    fi+  else+    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}+  fi+fi+rm -f confcache++test "x$prefix" = xNONE && prefix=$ac_default_prefix+# Let make expand exec_prefix.+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'++DEFS=-DHAVE_CONFIG_H++ac_libobjs=+ac_ltlibobjs=+U=+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue+  # 1. Remove the extension, and $U if already installed.+  ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'+  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`+  # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR+  #    will be set to the directory where LIBOBJS objects are built.+  as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"+  as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'+done+LIBOBJS=$ac_libobjs++LTLIBOBJS=$ac_ltlibobjs++++: "${CONFIG_STATUS=./config.status}"+ac_write_fail=0+ac_clean_files_save=$ac_clean_files+ac_clean_files="$ac_clean_files $CONFIG_STATUS"+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}+as_write_fail=0+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1+#! $SHELL+# Generated by $as_me.+# Run this file to recreate the current configuration.+# Compiler output produced by configure, useful for debugging+# configure, is in config.log if it exists.++debug=false+ac_cs_recheck=false+ac_cs_silent=false++SHELL=\${CONFIG_SHELL-$SHELL}+export SHELL+_ASEOF+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1+## -------------------- ##+## M4sh Initialization. ##+## -------------------- ##++# Be more Bourne compatible+DUALCASE=1; export DUALCASE # for MKS sh+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :+  emulate sh+  NULLCMD=:+  # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which+  # is contrary to our usage.  Disable this feature.+  alias -g '${1+"$@"}'='"$@"'+  setopt NO_GLOB_SUBST+else+  case `(set -o) 2>/dev/null` in #(+  *posix*) :+    set -o posix ;; #(+  *) :+     ;;+esac+fi+++as_nl='+'+export as_nl+# Printing a long string crashes Solaris 7 /usr/bin/printf.+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo+# Prefer a ksh shell builtin over an external printf program on Solaris,+# but without wasting forks for bash or zsh.+if test -z "$BASH_VERSION$ZSH_VERSION" \+    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then+  as_echo='print -r --'+  as_echo_n='print -rn --'+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then+  as_echo='printf %s\n'+  as_echo_n='printf %s'+else+  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then+    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'+    as_echo_n='/usr/ucb/echo -n'+  else+    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'+    as_echo_n_body='eval+      arg=$1;+      case $arg in #(+      *"$as_nl"*)+	expr "X$arg" : "X\\(.*\\)$as_nl";+	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;+      esac;+      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"+    '+    export as_echo_n_body+    as_echo_n='sh -c $as_echo_n_body as_echo'+  fi+  export as_echo_body+  as_echo='sh -c $as_echo_body as_echo'+fi++# The user is always right.+if test "${PATH_SEPARATOR+set}" != set; then+  PATH_SEPARATOR=:+  (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {+    (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||+      PATH_SEPARATOR=';'+  }+fi+++# IFS+# We need space, tab and new line, in precisely that order.  Quoting is+# there to prevent editors from complaining about space-tab.+# (If _AS_PATH_WALK were called with IFS unset, it would disable word+# splitting by setting IFS to empty value.)+IFS=" ""	$as_nl"++# Find who we are.  Look in the path if we contain no directory separator.+as_myself=+case $0 in #((+  *[\\/]* ) as_myself=$0 ;;+  *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR+for as_dir in $PATH+do+  IFS=$as_save_IFS+  test -z "$as_dir" && as_dir=.+    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break+  done+IFS=$as_save_IFS++     ;;+esac+# We did not find ourselves, most probably we were run as `sh COMMAND'+# in which case we are not to be found in the path.+if test "x$as_myself" = x; then+  as_myself=$0+fi+if test ! -f "$as_myself"; then+  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2+  exit 1+fi++# Unset variables that we do not need and which cause bugs (e.g. in+# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"+# suppresses any "Segmentation fault" message there.  '((' could+# trigger a bug in pdksh 5.2.14.+for as_var in BASH_ENV ENV MAIL MAILPATH+do eval test x\${$as_var+set} = xset \+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :+done+PS1='$ '+PS2='> '+PS4='+ '++# NLS nuisances.+LC_ALL=C+export LC_ALL+LANGUAGE=C+export LANGUAGE++# CDPATH.+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH+++# as_fn_error STATUS ERROR [LINENO LOG_FD]+# ----------------------------------------+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the+# script with STATUS, using 1 if that was 0.+as_fn_error ()+{+  as_status=$1; test $as_status -eq 0 && as_status=1+  if test "$4"; then+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4+  fi+  $as_echo "$as_me: error: $2" >&2+  as_fn_exit $as_status+} # as_fn_error+++# as_fn_set_status STATUS+# -----------------------+# Set $? to STATUS, without forking.+as_fn_set_status ()+{+  return $1+} # as_fn_set_status++# as_fn_exit STATUS+# -----------------+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.+as_fn_exit ()+{+  set +e+  as_fn_set_status $1+  exit $1+} # as_fn_exit++# as_fn_unset VAR+# ---------------+# Portably unset VAR.+as_fn_unset ()+{+  { eval $1=; unset $1;}+}+as_unset=as_fn_unset+# as_fn_append VAR VALUE+# ----------------------+# Append the text in VALUE to the end of the definition contained in VAR. Take+# advantage of any shell optimizations that allow amortized linear growth over+# repeated appends, instead of the typical quadratic growth present in naive+# implementations.+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :+  eval 'as_fn_append ()+  {+    eval $1+=\$2+  }'+else+  as_fn_append ()+  {+    eval $1=\$$1\$2+  }+fi # as_fn_append++# as_fn_arith ARG...+# ------------------+# Perform arithmetic evaluation on the ARGs, and store the result in the+# global $as_val. Take advantage of shells that can avoid forks. The arguments+# must be portable across $(()) and expr.+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :+  eval 'as_fn_arith ()+  {+    as_val=$(( $* ))+  }'+else+  as_fn_arith ()+  {+    as_val=`expr "$@" || test $? -eq 1`+  }+fi # as_fn_arith+++if expr a : '\(a\)' >/dev/null 2>&1 &&+   test "X`expr 00001 : '.*\(...\)'`" = X001; then+  as_expr=expr+else+  as_expr=false+fi++if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then+  as_basename=basename+else+  as_basename=false+fi++if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then+  as_dirname=dirname+else+  as_dirname=false+fi++as_me=`$as_basename -- "$0" ||+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \+	 X"$0" : 'X\(//\)$' \| \+	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X/"$0" |+    sed '/^.*\/\([^/][^/]*\)\/*$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\/\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`++# Avoid depending upon Character Ranges.+as_cr_letters='abcdefghijklmnopqrstuvwxyz'+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'+as_cr_Letters=$as_cr_letters$as_cr_LETTERS+as_cr_digits='0123456789'+as_cr_alnum=$as_cr_Letters$as_cr_digits++ECHO_C= ECHO_N= ECHO_T=+case `echo -n x` in #(((((+-n*)+  case `echo 'xy\c'` in+  *c*) ECHO_T='	';;	# ECHO_T is single tab character.+  xy)  ECHO_C='\c';;+  *)   echo `echo ksh88 bug on AIX 6.1` > /dev/null+       ECHO_T='	';;+  esac;;+*)+  ECHO_N='-n';;+esac++rm -f conf$$ conf$$.exe conf$$.file+if test -d conf$$.dir; then+  rm -f conf$$.dir/conf$$.file+else+  rm -f conf$$.dir+  mkdir conf$$.dir 2>/dev/null+fi+if (echo >conf$$.file) 2>/dev/null; then+  if ln -s conf$$.file conf$$ 2>/dev/null; then+    as_ln_s='ln -s'+    # ... but there are two gotchas:+    # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.+    # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.+    # In both cases, we have to default to `cp -pR'.+    ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||+      as_ln_s='cp -pR'+  elif ln conf$$.file conf$$ 2>/dev/null; then+    as_ln_s=ln+  else+    as_ln_s='cp -pR'+  fi+else+  as_ln_s='cp -pR'+fi+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file+rmdir conf$$.dir 2>/dev/null+++# as_fn_mkdir_p+# -------------+# Create "$as_dir" as a directory, including parents if necessary.+as_fn_mkdir_p ()+{++  case $as_dir in #(+  -*) as_dir=./$as_dir;;+  esac+  test -d "$as_dir" || eval $as_mkdir_p || {+    as_dirs=+    while :; do+      case $as_dir in #(+      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(+      *) as_qdir=$as_dir;;+      esac+      as_dirs="'$as_qdir' $as_dirs"+      as_dir=`$as_dirname -- "$as_dir" ||+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$as_dir" : 'X\(//\)[^/]' \| \+	 X"$as_dir" : 'X\(//\)$' \| \+	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$as_dir" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+      test -d "$as_dir" && break+    done+    test -z "$as_dirs" || eval "mkdir $as_dirs"+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"+++} # as_fn_mkdir_p+if mkdir -p . 2>/dev/null; then+  as_mkdir_p='mkdir -p "$as_dir"'+else+  test -d ./-p && rmdir ./-p+  as_mkdir_p=false+fi+++# as_fn_executable_p FILE+# -----------------------+# Test if FILE is an executable regular file.+as_fn_executable_p ()+{+  test -f "$1" && test -x "$1"+} # as_fn_executable_p+as_test_x='test -x'+as_executable_p=as_fn_executable_p++# Sed expression to map a string onto a valid CPP name.+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"++# Sed expression to map a string onto a valid variable name.+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"+++exec 6>&1+## ----------------------------------- ##+## Main body of $CONFIG_STATUS script. ##+## ----------------------------------- ##+_ASEOF+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# Save the log message, to keep $0 and so on meaningful, and to+# report actual input values of CONFIG_FILES etc. instead of their+# values after options handling.+ac_log="+This file was extended by Haskell Linear Algebra $as_me 0.8, which was+generated by GNU Autoconf 2.69.  Invocation command line was++  CONFIG_FILES    = $CONFIG_FILES+  CONFIG_HEADERS  = $CONFIG_HEADERS+  CONFIG_LINKS    = $CONFIG_LINKS+  CONFIG_COMMANDS = $CONFIG_COMMANDS+  $ $0 $@++on `(hostname || uname -n) 2>/dev/null | sed 1q`+"++_ACEOF++case $ac_config_files in *"+"*) set x $ac_config_files; shift; ac_config_files=$*;;+esac++case $ac_config_headers in *"+"*) set x $ac_config_headers; shift; ac_config_headers=$*;;+esac+++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+# Files that config.status was made for.+config_files="$ac_config_files"+config_headers="$ac_config_headers"++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+ac_cs_usage="\+\`$as_me' instantiates files and other configuration actions+from templates according to the current configuration.  Unless the files+and actions are specified as TAGs, all are instantiated by default.++Usage: $0 [OPTION]... [TAG]...++  -h, --help       print this help, then exit+  -V, --version    print version number and configuration settings, then exit+      --config     print configuration, then exit+  -q, --quiet, --silent+                   do not print progress messages+  -d, --debug      don't remove temporary files+      --recheck    update $as_me by reconfiguring in the same conditions+      --file=FILE[:TEMPLATE]+                   instantiate the configuration file FILE+      --header=FILE[:TEMPLATE]+                   instantiate the configuration header FILE++Configuration files:+$config_files++Configuration headers:+$config_headers++Report bugs to <patperry@gmail.com>."++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"+ac_cs_version="\\+Haskell Linear Algebra config.status 0.8+configured by $0, generated by GNU Autoconf 2.69,+  with options \\"\$ac_cs_config\\"++Copyright (C) 2012 Free Software Foundation, Inc.+This config.status script is free software; the Free Software Foundation+gives unlimited permission to copy, distribute and modify it."++ac_pwd='$ac_pwd'+srcdir='$srcdir'+test -n "\$AWK" || AWK=awk+_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# The default lists apply if the user does not specify any file.+ac_need_defaults=:+while test $# != 0+do+  case $1 in+  --*=?*)+    ac_option=`expr "X$1" : 'X\([^=]*\)='`+    ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`+    ac_shift=:+    ;;+  --*=)+    ac_option=`expr "X$1" : 'X\([^=]*\)='`+    ac_optarg=+    ac_shift=:+    ;;+  *)+    ac_option=$1+    ac_optarg=$2+    ac_shift=shift+    ;;+  esac++  case $ac_option in+  # Handling of the options.+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)+    ac_cs_recheck=: ;;+  --version | --versio | --versi | --vers | --ver | --ve | --v | -V )+    $as_echo "$ac_cs_version"; exit ;;+  --config | --confi | --conf | --con | --co | --c )+    $as_echo "$ac_cs_config"; exit ;;+  --debug | --debu | --deb | --de | --d | -d )+    debug=: ;;+  --file | --fil | --fi | --f )+    $ac_shift+    case $ac_optarg in+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;+    '') as_fn_error $? "missing file argument" ;;+    esac+    as_fn_append CONFIG_FILES " '$ac_optarg'"+    ac_need_defaults=false;;+  --header | --heade | --head | --hea )+    $ac_shift+    case $ac_optarg in+    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;+    esac+    as_fn_append CONFIG_HEADERS " '$ac_optarg'"+    ac_need_defaults=false;;+  --he | --h)+    # Conflict between --help and --header+    as_fn_error $? "ambiguous option: \`$1'+Try \`$0 --help' for more information.";;+  --help | --hel | -h )+    $as_echo "$ac_cs_usage"; exit ;;+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \+  | -silent | --silent | --silen | --sile | --sil | --si | --s)+    ac_cs_silent=: ;;++  # This is an error.+  -*) as_fn_error $? "unrecognized option: \`$1'+Try \`$0 --help' for more information." ;;++  *) as_fn_append ac_config_targets " $1"+     ac_need_defaults=false ;;++  esac+  shift+done++ac_configure_extra_args=++if $ac_cs_silent; then+  exec 6>/dev/null+  ac_configure_extra_args="$ac_configure_extra_args --silent"+fi++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+if \$ac_cs_recheck; then+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion+  shift+  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6+  CONFIG_SHELL='$SHELL'+  export CONFIG_SHELL+  exec "\$@"+fi++_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+exec 5>>config.log+{+  echo+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX+## Running $as_me. ##+_ASBOX+  $as_echo "$ac_log"+} >&5++_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1++# Handling of arguments.+for ac_config_target in $ac_config_targets+do+  case $ac_config_target in+    "cbits/config.h") CONFIG_HEADERS="$CONFIG_HEADERS cbits/config.h" ;;+    "linear-algebra.buildinfo") CONFIG_FILES="$CONFIG_FILES linear-algebra.buildinfo" ;;++  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;+  esac+done+++# If the user did not use the arguments to specify the items to instantiate,+# then the envvar interface is used.  Set only those that are not.+# We use the long form for the default assignment because of an extremely+# bizarre bug on SunOS 4.1.3.+if $ac_need_defaults; then+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers+fi++# Have a temporary directory for convenience.  Make it in the build tree+# simply because there is no reason against having it here, and in addition,+# creating and moving files from /tmp can sometimes cause problems.+# Hook for its removal unless debugging.+# Note that there is a small window in which the directory will not be cleaned:+# after its creation but before its name has been assigned to `$tmp'.+$debug ||+{+  tmp= ac_tmp=+  trap 'exit_status=$?+  : "${ac_tmp:=$tmp}"+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status+' 0+  trap 'as_fn_exit 1' 1 2 13 15+}+# Create a (secure) tmp directory for tmp files.++{+  tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&+  test -d "$tmp"+}  ||+{+  tmp=./conf$$-$RANDOM+  (umask 077 && mkdir "$tmp")+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5+ac_tmp=$tmp++# Set up the scripts for CONFIG_FILES section.+# No need to generate them if there are no CONFIG_FILES.+# This happens for instance with `./config.status config.h'.+if test -n "$CONFIG_FILES"; then+++ac_cr=`echo X | tr X '\015'`+# On cygwin, bash can eat \r inside `` if the user requested igncr.+# But we know of no other shell where ac_cr would be empty at this+# point, so we can use a bashism as a fallback.+if test "x$ac_cr" = x; then+  eval ac_cr=\$\'\\r\'+fi+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then+  ac_cs_awk_cr='\\r'+else+  ac_cs_awk_cr=$ac_cr+fi++echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&+_ACEOF+++{+  echo "cat >conf$$subs.awk <<_ACEOF" &&+  echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&+  echo "_ACEOF"+} >conf$$subs.sh ||+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`+ac_delim='%!_!# '+for ac_last_try in false false false false false :; do+  . ./conf$$subs.sh ||+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5++  ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`+  if test $ac_delim_n = $ac_delim_num; then+    break+  elif $ac_last_try; then+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5+  else+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "+  fi+done+rm -f conf$$subs.sh++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&+_ACEOF+sed -n '+h+s/^/S["/; s/!.*/"]=/+p+g+s/^[^!]*!//+:repl+t repl+s/'"$ac_delim"'$//+t delim+:nl+h+s/\(.\{148\}\)..*/\1/+t more1+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/+p+n+b repl+:more1+s/["\\]/\\&/g; s/^/"/; s/$/"\\/+p+g+s/.\{148\}//+t nl+:delim+h+s/\(.\{148\}\)..*/\1/+t more2+s/["\\]/\\&/g; s/^/"/; s/$/"/+p+b+:more2+s/["\\]/\\&/g; s/^/"/; s/$/"\\/+p+g+s/.\{148\}//+t delim+' <conf$$subs.awk | sed '+/^[^""]/{+  N+  s/\n//+}+' >>$CONFIG_STATUS || ac_write_fail=1+rm -f conf$$subs.awk+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+_ACAWK+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&+  for (key in S) S_is_set[key] = 1+  FS = ""++}+{+  line = $ 0+  nfields = split(line, field, "@")+  substed = 0+  len = length(field[1])+  for (i = 2; i < nfields; i++) {+    key = field[i]+    keylen = length(key)+    if (S_is_set[key]) {+      value = S[key]+      line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)+      len += length(value) + length(field[++i])+      substed = 1+    } else+      len += 1 + keylen+  }++  print line+}++_ACAWK+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then+  sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"+else+  cat+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5+_ACEOF++# VPATH may cause trouble with some makes, so we remove sole $(srcdir),+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and+# trailing colons and then remove the whole line if VPATH becomes empty+# (actually we leave an empty line to preserve line numbers).+if test "x$srcdir" = x.; then+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{+h+s///+s/^/:/+s/[	 ]*$/:/+s/:\$(srcdir):/:/g+s/:\${srcdir}:/:/g+s/:@srcdir@:/:/g+s/^:*//+s/:*$//+x+s/\(=[	 ]*\).*/\1/+G+s/\n//+s/^[^=]*=[	 ]*$//+}'+fi++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+fi # test -n "$CONFIG_FILES"++# Set up the scripts for CONFIG_HEADERS section.+# No need to generate them if there are no CONFIG_HEADERS.+# This happens for instance with `./config.status Makefile'.+if test -n "$CONFIG_HEADERS"; then+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||+BEGIN {+_ACEOF++# Transform confdefs.h into an awk script `defines.awk', embedded as+# here-document in config.status, that substitutes the proper values into+# config.h.in to produce config.h.++# Create a delimiter string that does not exist in confdefs.h, to ease+# handling of long lines.+ac_delim='%!_!# '+for ac_last_try in false false :; do+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`+  if test -z "$ac_tt"; then+    break+  elif $ac_last_try; then+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5+  else+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "+  fi+done++# For the awk script, D is an array of macro values keyed by name,+# likewise P contains macro parameters if any.  Preserve backslash+# newline sequences.++ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]*+sed -n '+s/.\{148\}/&'"$ac_delim"'/g+t rset+:rset+s/^[	 ]*#[	 ]*define[	 ][	 ]*/ /+t def+d+:def+s/\\$//+t bsnl+s/["\\]/\\&/g+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\+D["\1"]=" \3"/p+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2"/p+d+:bsnl+s/["\\]/\\&/g+s/^ \('"$ac_word_re"'\)\(([^()]*)\)[	 ]*\(.*\)/P["\1"]="\2"\+D["\1"]=" \3\\\\\\n"\\/p+t cont+s/^ \('"$ac_word_re"'\)[	 ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p+t cont+d+:cont+n+s/.\{148\}/&'"$ac_delim"'/g+t clear+:clear+s/\\$//+t bsnlc+s/["\\]/\\&/g; s/^/"/; s/$/"/p+d+:bsnlc+s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p+b cont+' <confdefs.h | sed '+s/'"$ac_delim"'/"\\\+"/g' >>$CONFIG_STATUS || ac_write_fail=1++cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+  for (key in D) D_is_set[key] = 1+  FS = ""+}+/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ {+  line = \$ 0+  split(line, arg, " ")+  if (arg[1] == "#") {+    defundef = arg[2]+    mac1 = arg[3]+  } else {+    defundef = substr(arg[1], 2)+    mac1 = arg[2]+  }+  split(mac1, mac2, "(") #)+  macro = mac2[1]+  prefix = substr(line, 1, index(line, defundef) - 1)+  if (D_is_set[macro]) {+    # Preserve the white space surrounding the "#".+    print prefix "define", macro P[macro] D[macro]+    next+  } else {+    # Replace #undef with comments.  This is necessary, for example,+    # in the case of _POSIX_SOURCE, which is predefined and required+    # on some systems where configure will not decide to define it.+    if (defundef == "undef") {+      print "/*", prefix defundef, macro, "*/"+      next+    }+  }+}+{ print }+_ACAWK+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5+fi # test -n "$CONFIG_HEADERS"+++eval set X "  :F $CONFIG_FILES  :H $CONFIG_HEADERS    "+shift+for ac_tag+do+  case $ac_tag in+  :[FHLC]) ac_mode=$ac_tag; continue;;+  esac+  case $ac_mode$ac_tag in+  :[FHL]*:*);;+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;+  :[FH]-) ac_tag=-:-;;+  :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;+  esac+  ac_save_IFS=$IFS+  IFS=:+  set x $ac_tag+  IFS=$ac_save_IFS+  shift+  ac_file=$1+  shift++  case $ac_mode in+  :L) ac_source=$1;;+  :[FH])+    ac_file_inputs=+    for ac_f+    do+      case $ac_f in+      -) ac_f="$ac_tmp/stdin";;+      *) # Look for the file first in the build tree, then in the source tree+	 # (if the path is not absolute).  The absolute path cannot be DOS-style,+	 # because $ac_f cannot contain `:'.+	 test -f "$ac_f" ||+	   case $ac_f in+	   [\\/$]*) false;;+	   *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;+	   esac ||+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;+      esac+      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac+      as_fn_append ac_file_inputs " '$ac_f'"+    done++    # Let's still pretend it is `configure' which instantiates (i.e., don't+    # use $as_me), people would be surprised to read:+    #    /* config.h.  Generated by config.status.  */+    configure_input='Generated from '`+	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'+	`' by configure.'+    if test x"$ac_file" != x-; then+      configure_input="$ac_file.  $configure_input"+      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5+$as_echo "$as_me: creating $ac_file" >&6;}+    fi+    # Neutralize special characters interpreted by sed in replacement strings.+    case $configure_input in #(+    *\&* | *\|* | *\\* )+       ac_sed_conf_input=`$as_echo "$configure_input" |+       sed 's/[\\\\&|]/\\\\&/g'`;; #(+    *) ac_sed_conf_input=$configure_input;;+    esac++    case $ac_tag in+    *:-:* | *:-) cat >"$ac_tmp/stdin" \+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;+    esac+    ;;+  esac++  ac_dir=`$as_dirname -- "$ac_file" ||+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \+	 X"$ac_file" : 'X\(//\)[^/]' \| \+	 X"$ac_file" : 'X\(//\)$' \| \+	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||+$as_echo X"$ac_file" |+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)[^/].*/{+	    s//\1/+	    q+	  }+	  /^X\(\/\/\)$/{+	    s//\1/+	    q+	  }+	  /^X\(\/\).*/{+	    s//\1/+	    q+	  }+	  s/.*/./; q'`+  as_dir="$ac_dir"; as_fn_mkdir_p+  ac_builddir=.++case "$ac_dir" in+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;+*)+  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`+  # A ".." for each directory in $ac_dir_suffix.+  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`+  case $ac_top_builddir_sub in+  "") ac_top_builddir_sub=. ac_top_build_prefix= ;;+  *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;+  esac ;;+esac+ac_abs_top_builddir=$ac_pwd+ac_abs_builddir=$ac_pwd$ac_dir_suffix+# for backward compatibility:+ac_top_builddir=$ac_top_build_prefix++case $srcdir in+  .)  # We are building in place.+    ac_srcdir=.+    ac_top_srcdir=$ac_top_builddir_sub+    ac_abs_top_srcdir=$ac_pwd ;;+  [\\/]* | ?:[\\/]* )  # Absolute name.+    ac_srcdir=$srcdir$ac_dir_suffix;+    ac_top_srcdir=$srcdir+    ac_abs_top_srcdir=$srcdir ;;+  *) # Relative name.+    ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix+    ac_top_srcdir=$ac_top_build_prefix$srcdir+    ac_abs_top_srcdir=$ac_pwd/$srcdir ;;+esac+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix+++  case $ac_mode in+  :F)+  #+  # CONFIG_FILE+  #++_ACEOF++cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+# If the template does not know about datarootdir, expand it.+# FIXME: This hack should be removed a few years after 2.60.+ac_datarootdir_hack=; ac_datarootdir_seen=+ac_sed_dataroot='+/datarootdir/ {+  p+  q+}+/@datadir@/p+/@docdir@/p+/@infodir@/p+/@localedir@/p+/@mandir@/p'+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in+*datarootdir*) ac_datarootdir_seen=yes;;+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}+_ACEOF+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+  ac_datarootdir_hack='+  s&@datadir@&$datadir&g+  s&@docdir@&$docdir&g+  s&@infodir@&$infodir&g+  s&@localedir@&$localedir&g+  s&@mandir@&$mandir&g+  s&\\\${datarootdir}&$datarootdir&g' ;;+esac+_ACEOF++# Neutralize VPATH when `$srcdir' = `.'.+# Shell code in configure.ac might set extrasub.+# FIXME: do we really want to maintain this feature?+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1+ac_sed_extra="$ac_vpsub+$extrasub+_ACEOF+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1+:t+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b+s|@configure_input@|$ac_sed_conf_input|;t t+s&@top_builddir@&$ac_top_builddir_sub&;t t+s&@top_build_prefix@&$ac_top_build_prefix&;t t+s&@srcdir@&$ac_srcdir&;t t+s&@abs_srcdir@&$ac_abs_srcdir&;t t+s&@top_srcdir@&$ac_top_srcdir&;t t+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t+s&@builddir@&$ac_builddir&;t t+s&@abs_builddir@&$ac_abs_builddir&;t t+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t+$ac_datarootdir_hack+"+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5++test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \+      "$ac_tmp/out"`; test -z "$ac_out"; } &&+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'+which seems to be undefined.  Please make sure it is defined" >&5+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'+which seems to be undefined.  Please make sure it is defined" >&2;}++  rm -f "$ac_tmp/stdin"+  case $ac_file in+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;+  esac \+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5+ ;;+  :H)+  #+  # CONFIG_HEADER+  #+  if test x"$ac_file" != x-; then+    {+      $as_echo "/* $configure_input  */" \+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"+    } >"$ac_tmp/config.h" \+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then+      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5+$as_echo "$as_me: $ac_file is unchanged" >&6;}+    else+      rm -f "$ac_file"+      mv "$ac_tmp/config.h" "$ac_file" \+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5+    fi+  else+    $as_echo "/* $configure_input  */" \+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \+      || as_fn_error $? "could not create -" "$LINENO" 5+  fi+ ;;+++  esac++done # for ac_tag+++as_fn_exit 0+_ACEOF+ac_clean_files=$ac_clean_files_save++test $ac_write_fail = 0 ||+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5+++# configure is writing to config.log, and then calls config.status.+# config.status does its own redirection, appending to config.log.+# Unfortunately, on DOS this fails, as config.log is still kept open+# by configure, so config.status won't be able to write to it; its+# output is simply discarded.  So we exec the FD to /dev/null,+# effectively closing config.log, so it can be properly (re)opened and+# appended to by config.status.  When coming back to configure, we+# need to make the FD available again.+if test "$no_create" != yes; then+  ac_cs_success=:+  ac_config_status_args=+  test "$silent" = yes &&+    ac_config_status_args="$ac_config_status_args --quiet"+  exec 5>/dev/null+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false+  exec 5>>config.log+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which+  # would make configure fail if this is the last instruction.+  $ac_cs_success || as_fn_exit 1+fi+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}+fi+
+ configure.ac view
@@ -0,0 +1,25 @@+AC_PREREQ([2.61])+AC_INIT([Haskell Linear Algebra], [0.8], [patperry@gmail.com])++AC_CONFIG_SRCDIR([linear-algebra.cabal])+AC_CONFIG_MACRO_DIR([m4])++AC_ARG_WITH(compiler, +    [AC_HELP_STRING([--with-compiler=<cmd>], [use Haskell compiler <cmd>])])++# Checks for programs++# Checks for libraries+AC_CHECK_LIB([m],[cos])+AX_CHECK_LAPACK++if test "$ax_lapack_ok" = yes; then+  BUILD_PACKAGE_BOOL=True+else +  BUILD_PACKAGE_BOOL=False+fi+AC_SUBST([BUILD_PACKAGE_BOOL])++AC_CONFIG_HEADERS([cbits/config.h])+AC_CONFIG_FILES([linear-algebra.buildinfo])+AC_OUTPUT
+ examples/LU.hs view
@@ -0,0 +1,64 @@+module LU ( luFactor, luFactorM ) where++import Control.Monad( zipWithM_ )+import Control.Monad.ST( ST, runST )++import Numeric.LinearAlgebra+import qualified Numeric.LinearAlgebra.Matrix as M+import qualified Numeric.LinearAlgebra.Vector as V+++luFactor :: (BLAS3 e) => Matrix e -> Either Int (Matrix e, [Int])+luFactor a = runST $ do+    ma <- M.newCopy a+    luFactorM ma >>=+        either (return . Left) (\pivots -> do+            a' <- M.unsafeFreeze ma+            return $ Right (a',pivots)+        )++{-+ - Recursive LU factorization with row pivoting.  Takes a matrix+ - A and factors it as P A = L U, where P is a permutation matrix, + - L is a lower triangular matrix with ones along the diagonal, and + - U is an upper triangular matrix.  On successful return, the values of+ - L and U are stored in A, and a list of the row swaps are returned.+ - On failure, the index of the failing column is returned.+ -}      +luFactorM :: (BLAS3 e) => STMatrix s e -> ST s (Either Int [Int])+luFactorM a = do+    (m,n) <- M.getDim a+    let mn = min m n+        nleft = mn `div` 2+    +    case undefined of+        _ | mn > 1 ->     +            M.withSplitColsAtM nleft a $ \a_1 a_2 ->+            M.withSplitRowsAtM nleft a_1 $ \a11 a21 ->+            M.withSplitRowsAtM nleft a_2 $ \a12 a22 ->+            luFactorM a_1 >>=+                either (return . Left) (\pivots -> do+                    zipWithM_ (M.swapRows a_2) [ 0.. ] pivots+                    M.triSolvMatrixM_ LeftSide NoTrans (Tri Lower Unit a11) a12+                    M.addMulMatrixWithScalesM_ (-1) NoTrans a21 NoTrans a12 1 a22+                    luFactorM a22 >>=+                        either (return . Left . (nleft+)) (\pivots' -> do+                            zipWithM_ (M.swapRows a21) [ 0.. ] pivots'+                            return $ Right (pivots ++ map (nleft+) pivots')+                        )+                )+        +        _ | mn == 1 ->+            M.withColM a 0 $ \x ->+                V.getWhichMaxAbs x >>= \(i,e) ->+                    if (e /= 0) +                        then do+                            V.scaleM_ (1/e) x+                            V.read x 0 >>= V.write x i+                            V.write x 0 e+                            return $ Right [i]+                        else+                            return $ Left 0++        _ | otherwise ->+            return $ Right []
+ lib/Foreign/BLAS.hs view
@@ -0,0 +1,24 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.BLAS+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- BLAS operations.+--++module Foreign.BLAS (+    -- * BLAS typeclasses+    module Foreign.BLAS.Level1,+    module Foreign.BLAS.Level2,+    module Foreign.BLAS.Level3,+    -- * Enums+    module Foreign.BLAS.Types,    +    ) where++import Foreign.BLAS.Types+import Foreign.BLAS.Level1+import Foreign.BLAS.Level2+import Foreign.BLAS.Level3
+ lib/Foreign/BLAS/Double.hsc view
@@ -0,0 +1,135 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.BLAS.Double+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Foreign.BLAS.Double +    where+    +import Foreign+import Foreign.C.Types +import Foreign.BLAS.Types++#include "config.h"+#include "f77_func-hsc.h"+++---------------------------- Level 1 Routines -------------------------------++foreign import ccall unsafe #f77_func ddot+    ddot :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO Double++foreign import ccall unsafe #f77_func dnrm2+    dnrm2  :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO Double++foreign import ccall unsafe #f77_func dasum+    dasum  :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO Double++foreign import ccall unsafe #f77_func idamax+    idamax_hidden :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO CInt +-- for some reason ffi stuff wasn't working with return type IO LAInt +idamax :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO LAInt+idamax a b c  =  do res <-  idamax_hidden a b c +                    return $! LAInt res +++foreign import ccall unsafe #f77_func dscal+    dscal  :: Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dswap+    dswap  :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dcopy+    dcopy  :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func daxpy+    daxpy  :: Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func drotg+    drotg  :: Ptr Double -> Ptr Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe #f77_func drot+    drot :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe #f77_func drotmg+    drotmg :: Ptr Double -> Ptr Double -> Ptr Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe #f77_func drotm+    drotm :: Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> IO ()+++---------------------------- Level 2 Routines -------------------------------++foreign import ccall unsafe #f77_func dgemv+    dgemv :: BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dgbmv+    dgbmv ::  BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dtrmv+    dtrmv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dtpmv+    dtpmv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dtpsv+    dtpsv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dtbmv+    dtbmv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()+                 +foreign import ccall unsafe #f77_func dtrsv+    dtrsv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dtbsv+    dtbsv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()+    +foreign import ccall unsafe #f77_func dsymv+    dsymv ::  BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()+    +foreign import ccall unsafe #f77_func dsbmv+    dsbmv ::  BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()+    +foreign import ccall unsafe #f77_func dger+    dger  ::  Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()+        +foreign import ccall unsafe #f77_func dsyr+    dsyr  ::  BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dsyr2+    dsyr2 ::  BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dspmv+    dspmv ::  BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dspr+    dspr  ::  BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> IO ()++foreign import ccall unsafe #f77_func dspr2+    dspr2 ::  BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> IO ()+++---------------------------- Level 3 Routines -------------------------------++foreign import ccall unsafe #f77_func dgemm+    dgemm  ::  BLASTrans -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dsymm+    dsymm  ::  BLASSide -> BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dtrmm+    dtrmm  ::  BLASSide -> BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dtrsm+    dtrsm  ::  BLASSide -> BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dsyrk+    dsyrk  ::  BLASUplo -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()+           +foreign import ccall unsafe #f77_func dsyr2k           +    dsyr2k ::  BLASUplo -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> IO ()
+ lib/Foreign/BLAS/Level1.hs view
@@ -0,0 +1,196 @@+{-# LANGUAGE FlexibleInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.BLAS.Level1+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Vector operations.+--++module Foreign.BLAS.Level1 (+    BLAS1(..),+    ) where+     +import Foreign( Storable, Ptr, peek, with )+import Foreign.Storable.Complex()+import Data.Complex( Complex(..) )++import Foreign.VMath.VFractional( VFractional )+import Foreign.BLAS.Double  +import Foreign.BLAS.Zomplex+        +-- | Types with vector-vector operations.+class (Storable a, VFractional a) => BLAS1 a where+    copy  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()    +    swap  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    dotc  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO a+    dotu  :: Int -> Ptr a -> Int -> Ptr a -> Int -> IO a    +    nrm2  :: Int -> Ptr a -> Int -> IO Double+    asum  :: Int -> Ptr a -> Int -> IO Double+    iamax :: Int -> Ptr a -> Int -> IO Int+    +    scal  :: Int -> a -> Ptr a -> Int -> IO () ++    axpy  :: Int -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()++    rotg  :: Ptr a -> Ptr a -> Ptr a -> Ptr a -> IO ()+    rot   :: Int -> Ptr a -> Int -> Ptr a -> Int -> Double -> Double -> IO ()+++withEnum :: (Enum a, Storable a) => Int -> (Ptr a -> IO b) -> IO b+withEnum = with . toEnum+{-# INLINE withEnum #-}++instance BLAS1 Double where+    copy n px incx py incy =+        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            dcopy pn px pincx py pincy+    {-# INLINE copy #-}++    swap n px incx py incy = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            dswap pn px pincx py pincy+    {-# INLINE swap #-}++    dotc n px incx py incy = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            ddot pn px pincx py pincy+    {-# INLINE dotc #-}++    dotu = dotc+    {-# INLINE dotu #-}+    +    nrm2 n px incx = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+            dnrm2 pn px pincx+    {-# INLINE nrm2 #-}++    asum n px incx = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+            dasum pn px pincx+    {-# INLINE asum #-}++    iamax n px incx = +        withEnum n $ \pn ->+        withEnum incx $ \pincx -> do+            i <- idamax pn px pincx+            return $! fromEnum (i - 1)+    {-# INLINE iamax #-}++    axpy n alpha px incx py incy = +        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            daxpy pn palpha px pincx py pincy+    {-# INLINE axpy #-}+    +    scal n alpha px incx = +        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+            dscal pn palpha px pincx+    {-# INLINE scal #-}++    rotg = drotg+    {-# INLINE rotg #-}+    +    rot n px incx py incy c s = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        with c $ \pc ->+        with s $ \ps ->+            drot pn px pincx py pincy pc ps+    {-# INLINE rot #-}+++instance BLAS1 (Complex Double) where+    copy n px incx py incy =+        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            zcopy pn px pincx py pincy+    {-# INLINE copy #-}++    swap n px incx py incy = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            zswap pn px pincx py pincy+    {-# INLINE swap #-}+    +    dotc n px incx py incy =+        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        with 0 $ \pdotc -> do+            zdotc pdotc pn px pincx py pincy+            peek pdotc+    {-# INLINE dotc #-}++    dotu n px incx py incy =+        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        with 0 $ \pdotu -> do+            zdotu pdotu pn px pincx py pincy+            peek pdotu+    {-# INLINE dotu #-}++    nrm2 n px incx = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+            znrm2 pn px pincx+    {-# INLINE nrm2 #-}++    asum n px incx = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+            zasum pn px pincx+    {-# INLINE asum #-}++    iamax n px incx = +        withEnum n $ \pn ->+        withEnum incx $ \pincx -> do+            i <- izamax pn px pincx+            return $! fromEnum (i - 1)+    {-# INLINE iamax #-}++    axpy n alpha px incx py incy = +        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            zaxpy pn palpha px pincx py pincy+    {-# INLINE axpy #-}+    +    scal n alpha px incx = +        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+            zscal pn palpha px pincx+    {-# INLINE scal #-}++    rotg = zrotg+    {-# INLINE rotg #-}+    +    rot n px incx py incy c s = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        with c $ \pc ->+        with s $ \ps ->+            zdrot pn px pincx py pincy pc ps+    {-# INLINE rot #-}
+ lib/Foreign/BLAS/Level2.hs view
@@ -0,0 +1,396 @@+{-# LANGUAGE FlexibleInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.BLAS.Level2+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Matrix-Vector operations.+--++module Foreign.BLAS.Level2 (+    BLAS2(..),+    ) where+     +import Data.Complex +import Foreign( Ptr, Storable, with )++import Foreign.BLAS.Types+import Foreign.BLAS.Level1+import Foreign.BLAS.Double+import Foreign.BLAS.Zomplex+   +-- | Types with matrix-vector operations.+class (BLAS1 a) => BLAS2 a where+    gbmv :: Trans -> Int -> Int -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    gemv :: Trans -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    gerc :: Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    geru :: Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()++    hbmv :: Uplo -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    hemv :: Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    her  :: Uplo -> Int -> Double -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    her2 :: Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    hpmv :: Uplo -> Int -> a -> Ptr a -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()    +    hpr  :: Uplo -> Int -> Double -> Ptr a -> Int -> Ptr a -> IO ()+    hpr2 :: Uplo -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> Ptr a -> IO ()++    tbmv :: Uplo -> Trans -> Diag -> Int -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    tbsv :: Uplo -> Trans -> Diag -> Int -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    tpmv :: Uplo -> Trans -> Diag -> Int -> Ptr a -> Ptr a -> Int -> IO ()    +    tpsv :: Uplo -> Trans -> Diag -> Int -> Ptr a -> Ptr a -> Int -> IO ()        +    trmv :: Uplo -> Trans -> Diag -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    trsv :: Uplo -> Trans -> Diag -> Int -> Ptr a -> Int -> Ptr a -> Int -> IO ()+++withEnum :: (Enum a, Storable a) => Int -> (Ptr a -> IO b) -> IO b+withEnum = with . toEnum+{-# INLINE withEnum #-}++instance BLAS2 Double where+    gemv transa m n alpha pa lda px incx beta py incy =+        withTrans transa $ \ptransa ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            dgemv ptransa pm pn palpha pa plda px pincx pbeta py pincy+    {-# INLINE gemv #-}+    +    gbmv transa m n kl ku alpha pa lda px incx beta py incy =+        withTrans transa $ \ptransa ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum kl $ \pkl ->+        withEnum ku $ \pku ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            dgbmv ptransa pm pn pkl pku palpha pa plda px pincx pbeta py pincy+    {-# INLINE gbmv #-}++    trmv uplo trans diag n pa lda px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+            dtrmv puplo ptrans pdiag pn pa plda px pincx+    {-# INLINE trmv #-}++    tpmv uplo trans diag n pap px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+            dtpmv puplo ptrans pdiag pn pap px pincx+    {-# INLINE tpmv #-}++    tpsv uplo trans diag n pap px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+            dtpsv puplo ptrans pdiag pn pap px pincx+    {-# INLINE tpsv #-}+     +    tbmv uplo trans diag n k pa lda px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+            dtbmv puplo ptrans pdiag pn pk pa plda px pincx+    {-# INLINE tbmv #-}++    trsv uplo trans diag n pa lda px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+            dtrsv puplo ptrans pdiag pn pa plda px pincx+    {-# INLINE trsv #-}++    tbsv uplo trans diag n k pa lda px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+            dtbsv puplo ptrans pdiag pn pk pa plda px pincx+    {-# INLINE tbsv #-}++    hemv uplo n alpha pa lda px incx beta py incy =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            dsymv puplo pn palpha pa plda px pincx pbeta py pincy+    {-# INLINE hemv #-}++    hbmv uplo n k alpha pa lda px incx beta py incy =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            dsbmv puplo pn pk palpha pa plda px pincx pbeta py pincy+    {-# INLINE hbmv #-}++    gerc m n alpha px incx py incy pa lda =+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        withEnum lda $ \plda ->+            dger pm pn palpha px pincx py pincy pa plda+    {-# INLINE gerc #-}++    geru = gerc+    {-# INLINE geru #-}++    her uplo n alpha px incx pa lda =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum lda $ \plda ->+            dsyr puplo pn palpha px pincx pa plda+    {-# INLINE her #-}++    her2 uplo n alpha px incx py incy pa lda =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        withEnum lda $ \plda ->+            dsyr2 puplo pn palpha px pincx py pincy pa plda+    {-# INLINE her2 #-}++    hpmv uplo n alpha pap px incx beta py incy =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            dspmv puplo pn palpha pap px pincx pbeta py pincy+    {-# INLINE hpmv #-}++    hpr uplo n alpha px incx pap =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+            dspr puplo pn palpha px pincx pap+    {-# INLINE hpr #-}++    hpr2 uplo n alpha px incx py incy pap =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            dspr2 puplo pn palpha px pincx py pincy pap+    {-# INLINE hpr2 #-}+    ++instance BLAS2 (Complex Double) where+    gemv transa m n alpha pa lda px incx beta py incy =+        withTrans transa $ \ptransa ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            zgemv ptransa pm pn palpha pa plda px pincx pbeta py pincy+    {-# INLINE gemv #-}+    +    gbmv transa m n kl ku alpha pa lda px incx beta py incy =+        withTrans transa $ \ptransa ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum kl $ \pkl ->+        withEnum ku $ \pku ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            zgbmv ptransa pm pn pkl pku palpha pa plda px pincx pbeta py pincy+    {-# INLINE gbmv #-}++    trmv uplo trans diag n pa lda px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+            ztrmv puplo ptrans pdiag pn pa plda px pincx+    {-# INLINE trmv #-}++    tpmv uplo trans diag n pap px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+            ztpmv puplo ptrans pdiag pn pap px pincx+    {-# INLINE tpmv #-}++    tpsv uplo trans diag n pap px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+            ztpsv puplo ptrans pdiag pn pap px pincx+    {-# INLINE tpsv #-}+     +    tbmv uplo trans diag n k pa lda px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+            ztbmv puplo ptrans pdiag pn pk pa plda px pincx+    {-# INLINE tbmv #-}++    trsv uplo trans diag n pa lda px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+            ztrsv puplo ptrans pdiag pn pa plda px pincx+    {-# INLINE trsv #-}++    tbsv uplo trans diag n k pa lda px incx =+        withUplo uplo $ \puplo ->+        withTrans trans $ \ptrans ->+        withDiag diag $ \pdiag ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+            ztbsv puplo ptrans pdiag pn pk pa plda px pincx+    {-# INLINE tbsv #-}++    hemv uplo n alpha pa lda px incx beta py incy =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            zhemv puplo pn palpha pa plda px pincx pbeta py pincy+    {-# INLINE hemv #-}++    hbmv uplo n k alpha pa lda px incx beta py incy =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            zhbmv puplo pn pk palpha pa plda px pincx pbeta py pincy+    {-# INLINE hbmv #-}++    gerc m n alpha px incx py incy pa lda =+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        withEnum lda $ \plda ->+            zgerc pm pn palpha px pincx py pincy pa plda+    {-# INLINE gerc #-}++    geru m n alpha px incx py incy pa lda =+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        withEnum lda $ \plda ->+            zgeru pm pn palpha px pincx py pincy pa plda+    {-# INLINE geru #-}++    her uplo n alpha px incx pa lda =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum lda $ \plda ->+            zher puplo pn palpha px pincx pa plda+    {-# INLINE her #-}++    her2 uplo n alpha px incx py incy pa lda =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+        withEnum lda $ \plda ->+            zher2 puplo pn palpha px pincx py pincy pa plda+    {-# INLINE her2 #-}++    hpmv uplo n alpha pap px incx beta py incy =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        with beta $ \pbeta ->+        withEnum incy $ \pincy ->+            zhpmv puplo pn palpha pap px pincx pbeta py pincy+    {-# INLINE hpmv #-}++    hpr uplo n alpha px incx pap =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+            zhpr puplo pn palpha px pincx pap+    {-# INLINE hpr #-}++    hpr2 uplo n alpha px incx py incy pap =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum incx $ \pincx ->+        withEnum incy $ \pincy ->+            zhpr2 puplo pn palpha px pincx py pincy pap+    {-# INLINE hpr2 #-}
+ lib/Foreign/BLAS/Level3.hs view
@@ -0,0 +1,247 @@+{-# LANGUAGE FlexibleInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.BLAS.Level3+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Matrix-Matrix operations.+--++module Foreign.BLAS.Level3 (+    BLAS3(..),+    ) where+     +import Data.Complex +import Foreign( Ptr, Storable, with )++import Foreign.BLAS.Types+import Foreign.BLAS.Level2+import Foreign.BLAS.Double+import Foreign.BLAS.Zomplex++-- | Types with matrix-matrix operations.        +class (BLAS2 a) => BLAS3 a where+    gemm  :: Trans -> Trans -> Int -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    symm  :: Side -> Uplo -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    hemm  :: Side -> Uplo -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    trmm  :: Side -> Uplo -> Trans -> Diag -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    trsm  :: Side -> Uplo -> Trans -> Diag -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> IO ()+    syrk  :: Uplo -> Trans -> Int -> Int -> a -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    syr2k :: Uplo -> Trans -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    herk  :: Uplo -> Trans -> Int -> Int -> a -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+    her2k :: Uplo -> Trans -> Int -> Int -> a -> Ptr a -> Int -> Ptr a -> Int -> a -> Ptr a -> Int -> IO ()+  ++withEnum :: (Enum a, Storable a) => Int -> (Ptr a -> IO b) -> IO b+withEnum = with . toEnum+{-# INLINE withEnum #-}+  +    +instance BLAS3 Double where+    gemm transa transb m n k alpha pa lda pb ldb beta pc ldc =+        withTrans transa $ \ptransa ->+        withTrans transb $ \ptransb ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            dgemm ptransa ptransb pm pn pk palpha pa plda pb pldb pbeta pc pldc+    {-# INLINE gemm #-}++    symm side uplo m n alpha pa lda pb ldb beta pc ldc =+        withSide side $ \pside ->+        withUplo uplo $ \puplo ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            dsymm pside puplo pm pn palpha pa plda pb pldb pbeta pc pldc+    {-# INLINE symm #-}++    hemm = symm+    {-# INLINE hemm #-}++    trmm side uplo transa diag m n alpha pa lda pb ldb =+        withSide side $ \pside ->+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withDiag diag $ \pdiag ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+            dtrmm pside puplo ptransa pdiag pm pn palpha pa plda pb pldb+    {-# INLINE trmm #-}++    trsm side uplo transa diag m n alpha pa lda pb ldb =+        withSide side $ \pside ->+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withDiag diag $ \pdiag ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+            dtrsm pside puplo ptransa pdiag pm pn palpha pa plda pb pldb+    {-# INLINE trsm #-}++    syrk uplo transa n k alpha pa lda beta pc ldc =+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            dsyrk puplo ptransa pn pk palpha pa plda pbeta pc pldc+    {-# INLINE syrk #-}++    syr2k uplo transa n k alpha pa lda pb ldb beta pc ldc =+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            dsyr2k puplo ptransa pn pk palpha pa plda pb pldb pbeta pc pldc+    {-# INLINE syr2k #-}++    herk = syrk+    {-# INLINE herk #-}++    her2k = syr2k+    {-# INLINE her2k #-}++    +instance BLAS3 (Complex Double) where+    gemm transa transb m n k alpha pa lda pb ldb beta pc ldc =+        withTrans transa $ \ptransa ->+        withTrans transb $ \ptransb ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            zgemm ptransa ptransb pm pn pk palpha pa plda pb pldb pbeta pc pldc+    {-# INLINE gemm #-}++    symm side uplo m n alpha pa lda pb ldb beta pc ldc =+        withSide side $ \pside ->+        withUplo uplo $ \puplo ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            zsymm pside puplo pm pn palpha pa plda pb pldb pbeta pc pldc+    {-# INLINE symm #-}++    hemm side uplo m n alpha pa lda pb ldb beta pc ldc =+        withSide side $ \pside ->+        withUplo uplo $ \puplo ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            zhemm pside puplo pm pn palpha pa plda pb pldb pbeta pc pldc+    {-# INLINE hemm #-}++    trmm side uplo transa diag m n alpha pa lda pb ldb =+        withSide side $ \pside ->+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withDiag diag $ \pdiag ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+            ztrmm pside puplo ptransa pdiag pm pn palpha pa plda pb pldb+    {-# INLINE trmm #-}++    trsm side uplo transa diag m n alpha pa lda pb ldb =+        withSide side $ \pside ->+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withDiag diag $ \pdiag ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+            ztrsm pside puplo ptransa pdiag pm pn palpha pa plda pb pldb+    {-# INLINE trsm #-}++    syrk uplo transa n k alpha pa lda beta pc ldc =+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            zsyrk puplo ptransa pn pk palpha pa plda pbeta pc pldc+    {-# INLINE syrk #-}++    syr2k uplo transa n k alpha pa lda pb ldb beta pc ldc =+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            zsyr2k puplo ptransa pn pk palpha pa plda pb pldb pbeta pc pldc+    {-# INLINE syr2k #-}++    herk uplo transa n k alpha pa lda beta pc ldc =+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            zherk puplo ptransa pn pk palpha pa plda pbeta pc pldc+    {-# INLINE herk #-}++    her2k uplo transa n k alpha pa lda pb ldb beta pc ldc =+        withUplo uplo $ \puplo ->+        withTrans transa $ \ptransa ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        with alpha $ \palpha ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        with beta $ \pbeta ->+        withEnum ldc $ \pldc ->+            zher2k puplo ptransa pn pk palpha pa plda pb pldb pbeta pc pldc+    {-# INLINE her2k #-}
+ lib/Foreign/BLAS/Types.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.BLAS.Types+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Foreign.BLAS.Types (+    BLASTrans(..),+    Trans(..),+    withTrans,+    +    BLASUplo(..),+    Uplo(..),+    withUplo,+    +    BLASDiag(..),+    Diag(..),+    withDiag,+    +    BLASSide(..),+    Side(..),+    withSide,+    +    LAInt(..),+    ) where++import Foreign+import Foreign.C.Types+import Foreign.C.String++newtype BLASTrans = BLASTrans CString+data Trans = NoTrans | Trans | ConjTrans deriving (Eq, Show)++withTrans :: Trans -> (BLASTrans -> IO a) -> IO a+withTrans trans f = flip withCString (f . BLASTrans) $ case trans of+    NoTrans   -> "N"+    Trans     -> "T"+    ConjTrans -> "C"++newtype BLASUplo = BLASUplo CString+data Uplo = Upper | Lower deriving (Eq, Show)++withUplo :: Uplo -> (BLASUplo -> IO a) -> IO a+withUplo uplo f = flip withCString (f . BLASUplo) $ case uplo of+    Upper -> "U"+    Lower -> "L"++newtype BLASSide = BLASSide CString+data Side = LeftSide | RightSide deriving (Eq, Show)++withSide :: Side -> (BLASSide -> IO a) -> IO a+withSide side f = flip withCString (f . BLASSide) $ case side of+    LeftSide  -> "L"+    RightSide -> "R"++newtype BLASDiag = BLASDiag CString+data Diag = NonUnit | Unit deriving (Eq, Show)++withDiag :: Diag -> (BLASDiag -> IO a) -> IO a+withDiag diag f = flip withCString (f . BLASDiag) $ case diag of+    NonUnit -> "N"+    Unit    -> "U"++newtype LAInt = LAInt CInt deriving (Eq, Show, Enum, Num, Ord, Storable)
+ lib/Foreign/BLAS/Zomplex.hsc view
@@ -0,0 +1,146 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.BLAS.Zomplex+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Foreign.BLAS.Zomplex +    where++import Data.Complex( Complex )+import Foreign+import Foreign.BLAS.Types+import Foreign.C.Types++#include "config.h"+#include "f77_func-hsc.h"+#define la_int int++---------------------------- Level 1 Routines -------------------------------++foreign import ccall unsafe #f77_func zdotu+    zdotu :: Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zdotc+    zdotc :: Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()+++foreign import ccall unsafe #f77_func dznrm2+    znrm2  :: Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO Double++foreign import ccall unsafe #f77_func dzasum+    zasum  :: Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO Double++foreign import ccall unsafe #f77_func izamax+    izamax_hidden :: Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO CInt +izamax :: Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO LAInt    +izamax a b c = do +                res <- izamax_hidden a b c +                return $! LAInt res +++foreign import ccall unsafe #f77_func zscal+    zscal  :: Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zswap+    zswap  :: Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zcopy+    zcopy  :: Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zaxpy+    zaxpy  :: Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zrotg+    zrotg  :: Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe #f77_func zdrot+    zdrot :: Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr Double -> Ptr Double -> IO ()+++---------------------------- Level 2 Routines -------------------------------++foreign import ccall unsafe #f77_func zgemv+    zgemv :: BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zgbmv+    zgbmv ::  BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func ztrmv+    ztrmv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func ztpmv+    ztpmv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func ztpsv+    ztpsv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func ztbmv+    ztbmv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()+                 +foreign import ccall unsafe #f77_func ztrsv+    ztrsv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func ztbsv+    ztbsv ::  BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()+    +foreign import ccall unsafe #f77_func zhemv+    zhemv ::  BLASUplo -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zhbmv+    zhbmv ::  BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()+    +foreign import ccall unsafe #f77_func zgeru+    zgeru  ::  Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zgerc+    zgerc  ::  Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()+        +foreign import ccall unsafe #f77_func zher+    zher  ::  BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zher2+    zher2 ::  BLASUplo -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zhpmv+    zhpmv ::  BLASUplo -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zhpr+    zhpr  ::  BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe #f77_func zhpr2+    zhpr2 ::  BLASUplo -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> IO ()+++---------------------------- Level 3 Routines -------------------------------++foreign import ccall unsafe #f77_func zgemm+    zgemm  ::  BLASTrans -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zsymm+    zsymm  ::  BLASSide -> BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zhemm+    zhemm  ::  BLASSide -> BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func ztrmm+    ztrmm  ::  BLASSide -> BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func ztrsm+    ztrsm  ::  BLASSide -> BLASUplo -> BLASTrans -> BLASDiag -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zsyrk+    zsyrk  ::  BLASUplo -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()+           +foreign import ccall unsafe #f77_func zsyr2k           +    zsyr2k ::  BLASUplo -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zherk+    zherk  ::  BLASUplo -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()+           +foreign import ccall unsafe #f77_func zher2k           +    zher2k ::  BLASUplo -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt -> IO ()
+ lib/Foreign/LAPACK.hs view
@@ -0,0 +1,305 @@+{-# LANGUAGE FlexibleInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.LAPACK+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Types with a Linear Algebra PACKage.+--+module Foreign.LAPACK (+    -- * LAPACK typeclass+    LAPACK(..),+    -- * Enums+    module Foreign.LAPACK.Types,+    ) where++import Control.Monad( forM_, when )+import Control.Exception( assert )+import Data.Complex( Complex )+import Foreign+import Foreign.BLAS+import Foreign.LAPACK.Types+import Foreign.LAPACK.Double+import Foreign.LAPACK.Zomplex+++-- | Types with LAPACK operations.+class (BLAS3 e) => LAPACK e where+    geqrf :: Int -> Int -> Ptr e -> Int -> Ptr e -> IO ()+    gelqf :: Int -> Int -> Ptr e -> Int -> Ptr e -> IO ()+    +    heevr :: EigJob -> EigRange -> Uplo -> Int -> Ptr e -> Int -> Double+          -> Ptr Double -> Ptr e -> Int -> Ptr Int -> IO Int+    +    larfg :: Int -> Ptr e -> Ptr e -> Int -> IO e+    potrf :: Uplo -> Int -> Ptr e -> Int -> IO Int+    potrs :: Uplo -> Int -> Int -> Ptr e -> Int -> Ptr e -> Int -> IO ()+    pptrf :: Uplo -> Int -> Ptr e -> IO Int+    pptrs :: Uplo -> Int -> Int -> Ptr e -> Ptr e -> Int -> IO ()+    +    unmqr :: Side -> Trans -> Int -> Int -> Int -> Ptr e -> Int -> Ptr e -> Ptr e -> Int -> IO ()+    unmlq :: Side -> Trans -> Int -> Int -> Int -> Ptr e -> Int -> Ptr e -> Ptr e -> Int -> IO ()+++callWithWork :: (Storable e) => (Ptr e -> Ptr LAInt -> Ptr LAInt -> IO ()) -> IO LAInt+callWithWork call =+    alloca $ \pquery ->+    with (-1) $ \pnone ->+    alloca $ \pinfo -> do+        call pquery pnone pinfo+        lwork <- (ceiling . max 1) `fmap` (peek (castPtr pquery) :: IO Double)+        allocaArray lwork $ \pwork ->+            withEnum lwork $ \plwork -> do+                call pwork plwork pinfo+                peek pinfo++callWithWorkIWork :: (Storable e)+    => (Ptr e -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> IO ())+    -> IO LAInt+callWithWorkIWork call =+    alloca $ \pquery ->+    alloca $ \piquery ->+    with (-1) $ \pnone ->+    alloca $ \pinfo -> do+        call pquery pnone piquery pnone pinfo+        lwork <- (ceiling . max 1) `fmap` (peek (castPtr pquery) :: IO Double)+        liwork <- max 1 `fmap` peek piquery+        allocaArray lwork $ \pwork ->+            withEnum lwork $ \plwork ->+                allocaArray (fromEnum liwork) $ \piwork ->+                    with liwork $ \pliwork -> do+                        call pwork plwork piwork pliwork pinfo+                        peek pinfo++callWithWorkRWorkIWork :: (Storable e)+    => (Ptr e -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> IO ())+    -> IO LAInt+callWithWorkRWorkIWork call =+    alloca $ \pquery ->+    alloca $ \prquery ->+    alloca $ \piquery ->+    with (-1) $ \pnone ->+    alloca $ \pinfo -> do+        call pquery pnone prquery pnone piquery pnone pinfo+        lwork <- (ceiling . max 1) `fmap` (peek (castPtr pquery) :: IO Double)+        lrwork <- (ceiling . max 1) `fmap` peek prquery+        liwork <- max 1 `fmap` peek piquery+        allocaArray lwork $ \pwork ->+            withEnum lwork $ \plwork ->+                allocaArray lrwork $ \prwork ->+                    withEnum lrwork $ \plrwork ->+                        allocaArray (fromEnum liwork) $ \piwork ->+                            with liwork $ \pliwork -> do+                                call pwork plwork prwork plrwork piwork pliwork pinfo+                                peek pinfo+++checkInfo :: (Num info,Eq info ) => info -> IO ()+checkInfo info = assert (info == 0) $ return ()++withEnum :: (Enum a, Storable a) => Int -> (Ptr a -> IO b) -> IO b+withEnum = with . toEnum+{-# INLINE withEnum #-}+        ++instance LAPACK Double where+    geqrf m n pa lda ptau =+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+            checkInfo =<< callWithWork (dgeqrf pm pn pa plda ptau)++    gelqf m n pa lda ptau =+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+            checkInfo =<< callWithWork (dgelqf pm pn pa plda ptau)++    heevr jobz range uplo n pa lda abstol pw pz ldz psuppz =+        withEigJob jobz $ \pjobz ->+        withEigRange range $ \prange pvl pvu pil piu ->+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+        with abstol $ \pabstol ->+        alloca $ \pm ->+        withEnum ldz $ \pldz -> +        allocaArray nsuppz $ \psuppz' -> do+            checkInfo =<<+                (callWithWorkIWork $+                    dsyevr pjobz prange puplo pn pa plda pvl pvu pil piu+                           pabstol pm pw pz pldz psuppz')+            m <- fromEnum `fmap` peek pm+            when (psuppz /= nullPtr) $+                forM_ [ 0..2*m - 1 ] $ \i -> do+                    s <- peekElemOff psuppz' i+                    pokeElemOff psuppz i (fromEnum s)+            return m+      where+        nsuppz = if psuppz == nullPtr then 0 else 2 * max 1 n++    unmqr side trans m n k pa lda ptau pc ldc =+        withSide side $ \pside ->+        withTrans trans $ \ptrans ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        withEnum lda $ \plda ->+        withEnum ldc $ \pldc ->+            checkInfo =<< callWithWork (dormqr pside ptrans pm pn pk pa plda ptau pc pldc)++    unmlq side trans m n k pa lda ptau pc ldc =+        withSide side $ \pside ->+        withTrans trans $ \ptrans ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        withEnum lda $ \plda ->+        withEnum ldc $ \pldc ->+            checkInfo =<< callWithWork (dormlq pside ptrans pm pn pk pa plda ptau pc pldc)++    larfg n palpha px incx = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        alloca $ \ptau -> do+            dlarfg pn palpha px pincx ptau+            peek ptau++    potrf uplo n pa lda =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+        alloca $ \pinfo -> do+            dpotrf puplo pn pa plda pinfo+            info <- fromEnum `fmap` peek pinfo+            assert (info >= 0) $ return info            ++    potrs uplo n nrhs pa lda pb ldb =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum nrhs $ \pnrhs ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        alloca $ \pinfo -> do+            dpotrs puplo pn pnrhs pa plda pb pldb pinfo+            checkInfo =<< peek pinfo++    pptrf uplo n pa =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        alloca $ \pinfo -> do+            dpptrf puplo pn pa pinfo+            info <- fromEnum `fmap` peek pinfo+            assert (info >= 0) $ return info            ++    pptrs uplo n nrhs pa pb ldb =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum nrhs $ \pnrhs ->+        withEnum ldb $ \pldb ->+        alloca $ \pinfo -> do+            dpptrs puplo pn pnrhs pa pb pldb pinfo+            checkInfo =<< peek pinfo+++instance LAPACK (Complex Double) where+    geqrf m n pa lda ptau =+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+            checkInfo =<< callWithWork (zgeqrf pm pn pa plda ptau)++    gelqf m n pa lda ptau =+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+            checkInfo =<< callWithWork (zgelqf pm pn pa plda ptau)++    heevr jobz range uplo n pa lda abstol pw pz ldz psuppz =+        withEigJob jobz $ \pjobz ->+        withEigRange range $ \prange pvl pvu pil piu ->+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+        with abstol $ \pabstol ->+        alloca $ \pm ->+        withEnum ldz $ \pldz -> +        allocaArray nsuppz $ \psuppz' -> do+            checkInfo =<<+                (callWithWorkRWorkIWork $+                    zheevr pjobz prange puplo pn pa plda pvl pvu pil piu+                           pabstol pm pw pz pldz psuppz')+            m <- fromEnum `fmap` peek pm+            when (psuppz /= nullPtr) $+                forM_ [ 0..2*m - 1 ] $ \i -> do+                    s <- peekElemOff psuppz' i+                    pokeElemOff psuppz i (fromEnum s)+            return m+      where+        nsuppz = if psuppz == nullPtr then 0 else 2 * max 1 n++    unmqr side trans m n k pa lda ptau pc ldc =+        withSide side $ \pside ->+        withTrans trans $ \ptrans ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        withEnum lda $ \plda ->+        withEnum ldc $ \pldc ->+            checkInfo =<< callWithWork (zunmqr pside ptrans pm pn pk pa plda ptau pc pldc)++    unmlq side trans m n k pa lda ptau pc ldc =+        withSide side $ \pside ->+        withTrans trans $ \ptrans ->+        withEnum m $ \pm ->+        withEnum n $ \pn ->+        withEnum k $ \pk ->+        withEnum lda $ \plda ->+        withEnum ldc $ \pldc ->+            checkInfo =<< callWithWork (zunmlq pside ptrans pm pn pk pa plda ptau pc pldc)++    larfg n palpha px incx = +        withEnum n $ \pn ->+        withEnum incx $ \pincx ->+        alloca $ \ptau -> do+            zlarfg pn palpha px pincx ptau+            peek ptau++    potrf uplo n pa lda =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum lda $ \plda ->+        alloca $ \pinfo -> do+            zpotrf puplo pn pa plda pinfo+            info <- fromEnum `fmap` peek pinfo+            assert (info >= 0) $ return info++    potrs uplo n nrhs pa lda pb ldb =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum nrhs $ \pnrhs ->+        withEnum lda $ \plda ->+        withEnum ldb $ \pldb ->+        alloca $ \pinfo -> do+            zpotrs puplo pn pnrhs pa plda pb pldb pinfo+            checkInfo =<< peek pinfo++    pptrf uplo n pa =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        alloca $ \pinfo -> do+            zpptrf puplo pn pa pinfo+            info <- fromEnum `fmap` peek pinfo+            assert (info >= 0) $ return info++    pptrs uplo n nrhs pa pb ldb =+        withUplo uplo $ \puplo ->+        withEnum n $ \pn ->+        withEnum nrhs $ \pnrhs ->+        withEnum ldb $ \pldb ->+        alloca $ \pinfo -> do+            zpptrs puplo pn pnrhs pa pb pldb pinfo+            checkInfo =<< peek pinfo
+ lib/Foreign/LAPACK/Double.hsc view
@@ -0,0 +1,64 @@+{-# LANGUAGE ForeignFunctionInterface #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.LAPACK.Double+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Foreign.LAPACK.Double+    where++import Foreign( Ptr )+import Foreign.BLAS.Types+import Foreign.LAPACK.Types++#include "f77_func-hsc.h"+++foreign import ccall unsafe #f77_func dgeqrf+    dgeqrf :: Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double+           -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dgelqf+    dgelqf :: Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double+           -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dlarfg+    dlarfg :: Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr Double+           -> IO ()++foreign import ccall unsafe #f77_func dormqr+    dormqr :: BLASSide -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt+           -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt+           -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dormlq+    dormlq :: BLASSide -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt+           -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt+           -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dpotrf+    dpotrf :: BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr LAInt+           -> IO ()+           +foreign import ccall unsafe #f77_func dpotrs+    dpotrs :: BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr LAInt+           -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dpptrf+    dpptrf :: BLASUplo -> Ptr LAInt -> Ptr Double -> Ptr LAInt+           -> IO ()+           +foreign import ccall unsafe #f77_func dpptrs+    dpptrs :: BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr Double+           -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func dsyevr+    dsyevr :: LAEigJob -> LAEigRange -> BLASUplo -> Ptr LAInt -> Ptr Double+           -> Ptr LAInt ->  Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr LAInt+           -> Ptr Double -> Ptr LAInt -> Ptr Double -> Ptr Double -> Ptr LAInt+           -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt+           -> Ptr LAInt -> IO ()
+ lib/Foreign/LAPACK/Types.hs view
@@ -0,0 +1,76 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.LAPACK.Types+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Foreign.LAPACK.Types (+    LAEigJob(..),+    EigJob(..),+    withEigJob,+    +    LAEigRange(..),+    EigRange(..),+    withEigRange,+    +    ) where++import Foreign+import Foreign.C.String++import Foreign.BLAS.Types( LAInt )++newtype LAEigJob = LAEigJob CString++-- | A type of eigenvalue computation.+data EigJob = NoEigVectors -- ^ no eigenvectors (eigenvalues only)+            | EigVectors   -- ^ eigenvalues and eigenvectors+    deriving (Eq, Show)++withEigJob :: EigJob -> (LAEigJob -> IO a) -> IO a+withEigJob evjob f = flip withCString (f . LAEigJob) $ case evjob of+    NoEigVectors -> "N"+    EigVectors   -> "V"++newtype LAEigRange = LAEigRange CString++-- | A range of eigenvalues to compute.+data EigRange = AllEigs                       -- ^ All eigenvalues are computed+              | EigValueRange !Double !Double -- ^ Eigenvalues in the half-open+                                              --   interval @(vl,vu]@ are+                                              --   computed+              | EigIndexRange !Int    !Int    -- ^ Eigenvalues with indices in+                                              --   the closed interval+                                              --   @[il,iu]@ are computed.+                                              --   Index @0@ corresponds to+                                              --   the smallest eigenvalue.+    deriving (Eq, Show)+             +withEigRange :: EigRange+             -> (LAEigRange -> Ptr Double -> Ptr Double -> Ptr LAInt -> Ptr LAInt -> IO a)+             -> IO a+withEigRange eigrange f = case eigrange of+    AllEigs ->+        withCString "A" $ \pA ->+        alloca $ \pvl ->+        alloca $ \pvu ->+        alloca $ \pil ->+        alloca $ \piu ->+            f (LAEigRange pA) pvl pvu pil piu+    EigValueRange vl vu ->+        withCString "V" $ \pV ->+        with vl $ \pvl ->+        with vu $ \pvu ->+        alloca $ \pil ->+        alloca $ \piu ->+            f (LAEigRange pV) pvl pvu pil piu+    EigIndexRange il iu ->+        withCString "I" $ \pI ->+        alloca $ \pvl ->+        alloca $ \pvu ->+        with (toEnum $ il + 1) $ \pil ->+        with (toEnum $ iu + 1) $ \piu ->+            f (LAEigRange pI) pvl pvu pil piu
+ lib/Foreign/LAPACK/Zomplex.hsc view
@@ -0,0 +1,74 @@+{-# LANGUAGE  ForeignFunctionInterface #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.LAPACK.Zomplex+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Foreign.LAPACK.Zomplex+    where++import Data.Complex( Complex )+import Foreign( Ptr )+import Foreign.BLAS.Types+import Foreign.LAPACK.Types++#include "f77_func-hsc.h"+++foreign import ccall unsafe #f77_func zgeqrf+    zgeqrf :: Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double)+           -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double)+           -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zgelqf+    zgelqf :: Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double)+           -> Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double)+           -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zheevr+    zheevr :: LAEigJob -> LAEigRange -> BLASUplo -> Ptr LAInt+           -> Ptr (Complex Double) -> Ptr LAInt -> Ptr Double -> Ptr Double+           -> Ptr LAInt -> Ptr LAInt -> Ptr Double -> Ptr LAInt -> Ptr Double+           -> Ptr (Complex Double) -> Ptr LAInt -> Ptr LAInt+           -> Ptr (Complex Double) -> Ptr LAInt -> Ptr Double -> Ptr LAInt+           -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt -> IO ()++foreign import ccall unsafe #f77_func zlarfg+    zlarfg :: Ptr LAInt -> Ptr (Complex Double) -> Ptr (Complex Double)+           -> Ptr LAInt -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe #f77_func zpotrf+    zpotrf :: BLASUplo -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt+           -> Ptr LAInt -> IO ()+           +foreign import ccall unsafe #f77_func zpotrs+    zpotrs :: BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double)+           -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt -> Ptr LAInt+           -> IO ()++foreign import ccall unsafe #f77_func zpptrf+    zpptrf :: BLASUplo -> Ptr LAInt -> Ptr (Complex Double)+           -> Ptr LAInt -> IO ()+           +foreign import ccall unsafe #f77_func zpptrs+    zpptrs :: BLASUplo -> Ptr LAInt -> Ptr LAInt -> Ptr (Complex Double)+           -> Ptr (Complex Double) -> Ptr LAInt -> Ptr LAInt+           -> IO ()++foreign import ccall unsafe #f77_func zunmqr+    zunmqr :: BLASSide -> BLASTrans -> Ptr LAInt -> Ptr LAInt+           -> Ptr LAInt -> Ptr (Complex Double) -> Ptr LAInt+           -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr LAInt+           -> Ptr (Complex Double) -> Ptr LAInt -> Ptr LAInt+           -> IO ()++foreign import ccall unsafe #f77_func zunmlq+    zunmlq :: BLASSide -> BLASTrans -> Ptr LAInt -> Ptr LAInt -> Ptr LAInt+           -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double)+           -> Ptr (Complex Double) -> Ptr LAInt -> Ptr (Complex Double)+           -> Ptr LAInt -> Ptr LAInt -> IO ()+
+ lib/Foreign/VMath.hs view
@@ -0,0 +1,21 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.VMath+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Vector math operations.+--++module Foreign.VMath (+    -- * Vector Math typeclasses+    module Foreign.VMath.VNum,+    module Foreign.VMath.VFractional,    +    module Foreign.VMath.VFloating    +    ) where++import Foreign.VMath.VNum+import Foreign.VMath.VFractional+import Foreign.VMath.VFloating  
+ lib/Foreign/VMath/Double.hs view
@@ -0,0 +1,100 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# CFILES cbits/vmath-double.c #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.VMath.Double+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Foreign.VMath.Double+    where+        +import Foreign.Ptr( Ptr )++---------------------------- Vector Routines --------------------------------++foreign import ccall unsafe "vdShift"+    vdShift :: Int -> Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdAdd"+    vdAdd :: Int -> Ptr Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdSub"+    vdSub :: Int -> Ptr Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdAxpby"+    vdAxpby :: Int -> Double -> Ptr Double -> Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdScale"+    vdScale :: Int -> Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdMul"+    vdMul :: Int -> Ptr Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdNeg"+    vdNeg :: Int -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdAbs"+    vdAbs :: Int -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdSgn"+    vdSgn :: Int -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdInv"+    vdInv :: Int -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdDiv"+    vdDiv :: Int -> Ptr Double -> Ptr Double -> Ptr Double -> IO ()++foreign import ccall unsafe "vdExp"+    vdExp :: Int -> Ptr Double -> Ptr Double -> IO ()+    +foreign import ccall unsafe "vdSqrt"    +    vdSqrt :: Int -> Ptr Double -> Ptr Double -> IO ()+    +foreign import ccall unsafe "vdLog"+    vdLog :: Int -> Ptr Double -> Ptr Double -> IO ()+    +foreign import ccall unsafe "vdPow"+    vdPow :: Int -> Ptr Double -> Ptr Double -> Ptr Double -> IO ()            +    +foreign import ccall unsafe "vdSin"+    vdSin :: Int -> Ptr Double -> Ptr Double -> IO ()                +    +foreign import ccall unsafe "vdCos"+    vdCos :: Int -> Ptr Double -> Ptr Double -> IO ()+    +foreign import ccall unsafe "vdTan"    +    vdTan :: Int -> Ptr Double -> Ptr Double -> IO ()                        ++foreign import ccall unsafe "vdASin"+    vdASin :: Int -> Ptr Double -> Ptr Double -> IO ()                +    +foreign import ccall unsafe "vdACos"+    vdACos :: Int -> Ptr Double -> Ptr Double -> IO ()+    +foreign import ccall unsafe "vdATan"    +    vdATan :: Int -> Ptr Double -> Ptr Double -> IO ()                        ++foreign import ccall unsafe "vdSinh"+    vdSinh :: Int -> Ptr Double -> Ptr Double -> IO ()                +    +foreign import ccall unsafe "vdCosh"+    vdCosh :: Int -> Ptr Double -> Ptr Double -> IO ()+    +foreign import ccall unsafe "vdTanh"    +    vdTanh :: Int -> Ptr Double -> Ptr Double -> IO ()                        ++foreign import ccall unsafe "vdASinh"+    vdASinh :: Int -> Ptr Double -> Ptr Double -> IO ()                +    +foreign import ccall unsafe "vdACosh"+    vdACosh :: Int -> Ptr Double -> Ptr Double -> IO ()+    +foreign import ccall unsafe "vdATanh"    +    vdATanh :: Int -> Ptr Double -> Ptr Double -> IO ()                        ++                      
+ lib/Foreign/VMath/VFloating.hs view
@@ -0,0 +1,151 @@+{-# LANGUAGE FlexibleInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.VMath.VFloating+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Vector Floating operations.+--++module Foreign.VMath.VFloating (+    VFloating(..)+    ) where+     +import Foreign( Ptr, Storable, peek, poke, advancePtr )+import Data.Complex( Complex(..) )++import Foreign.VMath.VFractional+import Foreign.VMath.Double  +import Foreign.VMath.Zomplex++-- | Types with vectorized 'Floating' operations.+class (VFractional a, Floating a) => VFloating a where+    vExp :: Int -> Ptr a -> Ptr a -> IO ()+    vSqrt :: Int -> Ptr a -> Ptr a -> IO ()+    vLog :: Int -> Ptr a -> Ptr a -> IO ()        +    vPow :: Int -> Ptr a -> Ptr a -> Ptr a -> IO ()            +    vSin :: Int -> Ptr a -> Ptr a -> IO ()                +    vCos :: Int -> Ptr a -> Ptr a -> IO ()                    +    vTan :: Int -> Ptr a -> Ptr a -> IO ()                        +    vASin :: Int -> Ptr a -> Ptr a -> IO ()                +    vACos :: Int -> Ptr a -> Ptr a -> IO ()                    +    vATan :: Int -> Ptr a -> Ptr a -> IO ()                        +    vSinh :: Int -> Ptr a -> Ptr a -> IO ()                +    vCosh :: Int -> Ptr a -> Ptr a -> IO ()                    +    vTanh :: Int -> Ptr a -> Ptr a -> IO ()                        +    vASinh :: Int -> Ptr a -> Ptr a -> IO ()                +    vACosh :: Int -> Ptr a -> Ptr a -> IO ()                    +    vATanh :: Int -> Ptr a -> Ptr a -> IO ()++    vExp = vop exp+    vSqrt = vop sqrt+    vLog = vop log+    vPow = vop2 (**)+    vSin = vop sin+    vCos = vop cos+    vTan = vop tan+    vASin = vop asin+    vACos = vop acos+    vATan = vop atan+    vSinh = vop sinh+    vCosh = vop cosh+    vTanh = vop tanh+    vASinh = vop asinh+    vACosh = vop acosh+    vATanh = vop atanh+    +    +vop :: (Storable a, Storable b)+    => (a -> b) -> Int -> Ptr a -> Ptr b -> IO ()+vop f n src dst | n <= 0    = return ()+                | otherwise = do+    a <- peek src+    poke dst $ f a+    vop f (n-1) (src `advancePtr` 1) (dst `advancePtr` 1)+{-# INLINE vop #-}++vop2 :: (Storable a1, Storable a2, Storable b)+     => (a1 -> a2 -> b) -> Int -> Ptr a1 -> Ptr a2 -> Ptr b -> IO ()+vop2 f n src1 src2 dst | n <= 0    = return ()+                       | otherwise = do+    a1 <- peek src1+    a2 <- peek src2+    poke dst $ f a1 a2+    vop2 f (n-1) (src1 `advancePtr` 1) (src2 `advancePtr` 1)+         (dst `advancePtr` 1)+{-# INLINE vop2 #-}+    +instance VFloating Double where+    vExp = vdExp+    {-# INLINE vExp #-}+    vSqrt = vdSqrt+    {-# INLINE vSqrt #-}+    vLog = vdLog+    {-# INLINE vLog #-}+    vPow = vdPow+    {-# INLINE vPow #-}+    vSin = vdSin+    {-# INLINE vSin #-}+    vCos = vdCos+    {-# INLINE vCos #-}+    vTan = vdTan+    {-# INLINE vTan #-}+    vASin = vdASin+    {-# INLINE vASin #-}+    vACos = vdACos+    {-# INLINE vACos #-}+    vATan = vdATan+    {-# INLINE vATan #-}+    vSinh = vdSinh+    {-# INLINE vSinh #-}+    vCosh = vdCosh+    {-# INLINE vCosh #-}+    vTanh = vdTanh+    {-# INLINE vTanh #-}+    vASinh = vdASinh+    {-# INLINE vASinh #-}+    vACosh = vdACosh+    {-# INLINE vACosh #-}+    vATanh = vdATanh+    {-# INLINE vATanh #-}+++instance VFloating (Complex Double) where+    vSqrt = vzSqrt+    {-# INLINE vSqrt #-}+    vLog = vzLog+    {-# INLINE vLog #-}+    +    {- These functions have branch cuts in the wrong places +    vExp = vzExp+    {-# INLINE vExp #-}+    vPow = vzPow+    {-# INLINE vPow #-}+    vSin = vzSin+    {-# INLINE vSin #-}+    vCos = vzCos+    {-# INLINE vCos #-}+    vTan = vzTan+    {-# INLINE vTan #-}+    vASin = vzASin+    {-# INLINE vASin #-}+    vACos = vzACos+    {-# INLINE vACos #-}+    vATan = vzATan+    {-# INLINE vATan #-}+    vSinh = vzSinh+    {-# INLINE vSinh #-}+    vCosh = vzCosh+    {-# INLINE vCosh #-}+    vTanh = vzTanh+    {-# INLINE vTanh #-}+    vASinh = vzASinh+    {-# INLINE vASinh #-}+    vACosh = vzACosh+    {-# INLINE vACosh #-}+    vATanh = vzATanh+    {-# INLINE vATanh #-}+    -}
+ lib/Foreign/VMath/VFractional.hs view
@@ -0,0 +1,38 @@+{-# LANGUAGE FlexibleInstances #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.VMath.VFractional+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Vector Fractional operations.+--++module Foreign.VMath.VFractional+    where+     +import Foreign( Ptr )+import Data.Complex( Complex(..) )++import Foreign.VMath.VNum+import Foreign.VMath.Double  +import Foreign.VMath.Zomplex+        +-- | Types with vectorized 'Fractional' operations.+class (VNum a, Fractional a) => VFractional a where+    vInv :: Int -> Ptr a -> Ptr a -> IO ()    +    vDiv :: Int -> Ptr a -> Ptr a -> Ptr a -> IO ()++instance VFractional Double where+    vInv = vdInv+    {-# INLINE vInv #-}+    vDiv = vdDiv+    {-# INLINE vDiv #-}++instance VFractional (Complex Double) where+    vInv = vzInv+    {-# INLINE vInv #-}+    vDiv = vzDiv+    {-# INLINE vDiv #-}
+ lib/Foreign/VMath/VNum.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE FlexibleInstances, BangPatterns #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.VMath.VNum+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Vector Num operations.+--++module Foreign.VMath.VNum+    where+     +import Foreign( Storable, Ptr, with, )+import Foreign.Storable.Complex()+import Data.Complex( Complex(..) )++import Foreign.BLAS.Double( dcopy )+import Foreign.VMath.Double+import Foreign.VMath.Zomplex+        +-- | Types with vectorized 'Num' operations.+class (Storable a, Num a) => VNum a where+    vShift :: Int -> a -> Ptr a -> Ptr a -> IO ()        +    vAdd :: Int -> Ptr a -> Ptr a -> Ptr a -> IO ()+    vSub :: Int -> Ptr a -> Ptr a -> Ptr a -> IO ()+    vAxpby :: Int -> a -> Ptr a -> a -> Ptr a -> Ptr a -> IO ()++    vScale :: Int -> a -> Ptr a -> Ptr a -> IO ()    +    vMul :: Int -> Ptr a -> Ptr a -> Ptr a -> IO ()++    vConj :: Int -> Ptr a -> Ptr a -> IO ()    +    vNeg :: Int -> Ptr a -> Ptr a -> IO ()+    vAbs :: Int -> Ptr a -> Ptr a -> IO ()+    vSgn :: Int -> Ptr a -> Ptr a -> IO ()+++instance VNum Double where+    vShift = vdShift    +    {-# INLINE vShift #-}+    vAdd = vdAdd+    {-# INLINE vAdd #-}+    vSub = vdSub+    {-# INLINE vSub #-}+    vAxpby = vdAxpby+    {-# INLINE vAxpby #-}+    vScale = vdScale+    {-# INLINE vScale #-}+    vMul = vdMul+    {-# INLINE vMul #-}+    vConj n src dst = +        with (toEnum n) $ \pn ->+        with 1 $ \pone ->+            dcopy pn src pone dst pone+    {-# INLINE vConj #-}+    vNeg = vdNeg+    {-# INLINE vNeg #-}+    vAbs = vdAbs+    {-# INLINE vAbs #-}+    vSgn = vdSgn+    {-# INLINE vSgn #-}++instance VNum (Complex Double) where+    vShift n alpha pX pZ = with alpha $ \pAlpha ->+        vzShift n pAlpha pX pZ+    {-# INLINE vShift #-}+    vAdd = vzAdd+    {-# INLINE vAdd #-}+    vSub = vzSub+    {-# INLINE vSub #-}+    vAxpby n alpha pX beta pY pZ =+        with alpha $ \pAlpha ->+        with beta $ \pBeta ->+            vzAxpby n pAlpha pX pBeta pY pZ+    {-# INLINE vAxpby #-}+    vScale n alpha pX pZ = with alpha $ \pAlpha ->+        vzScale n pAlpha pX pZ+    {-# INLINE vScale #-}+    vMul = vzMul+    {-# INLINE vMul #-}+    vConj = vzConj+    {-# INLINE vConj #-}+    vNeg = vzNeg+    {-# INLINE vNeg #-}+    vAbs = vzAbs+    {-# INLINE vAbs #-}+    vSgn = vzSgn+    {-# INLINE vSgn #-}
+ lib/Foreign/VMath/Zomplex.hs view
@@ -0,0 +1,101 @@+{-# LANGUAGE ForeignFunctionInterface #-}+{-# CFILES cbits/vmath-zomplex.c #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Foreign.VMath.Zomplex+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Foreign.VMath.Zomplex+    where+        +import Data.Complex ( Complex )+import Foreign.Ptr  ( Ptr )++foreign import ccall unsafe "vzConj"+    vzConj :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzShift"+    vzShift :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzAdd"+    vzAdd :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzSub"+    vzSub :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzAxpby"+    vzAxpby :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzScale"+    vzScale :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzMul"+    vzMul :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzNeg"+    vzNeg :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzAbs"+    vzAbs :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzSgn"+    vzSgn :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzInv"+    vzInv :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzDiv"+    vzDiv :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()++foreign import ccall unsafe "vzExp"+    vzExp :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()+    +foreign import ccall unsafe "vzSqrt"    +    vzSqrt :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()+    +foreign import ccall unsafe "vzLog"+    vzLog :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()+    +foreign import ccall unsafe "vzPow"+    vzPow :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()            +    +foreign import ccall unsafe "vzSin"+    vzSin :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()                +    +foreign import ccall unsafe "vzCos"+    vzCos :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()+    +foreign import ccall unsafe "vzTan"    +    vzTan :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()                        ++foreign import ccall unsafe "vzASin"+    vzASin :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()                +    +foreign import ccall unsafe "vzACos"+    vzACos :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()+    +foreign import ccall unsafe "vzATan"    +    vzATan :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()                        ++foreign import ccall unsafe "vzSinh"+    vzSinh :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()                +    +foreign import ccall unsafe "vzCosh"+    vzCosh :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()+    +foreign import ccall unsafe "vzTanh"    +    vzTanh :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()                        ++foreign import ccall unsafe "vzASinh"+    vzASinh :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()                +    +foreign import ccall unsafe "vzACosh"+    vzACosh :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()+    +foreign import ccall unsafe "vzATanh"    +    vzATanh :: Int -> Ptr (Complex Double) -> Ptr (Complex Double) -> IO ()                        +
+ lib/Numeric/LinearAlgebra.hs view
@@ -0,0 +1,37 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Linear algebra types and operations+--++module Numeric.LinearAlgebra (+    -- * Vector types+    Vector,+    RVector,+    STVector,+    IOVector,+    +    -- * Matrix types+    Matrix,+    RMatrix,+    STMatrix,+    IOMatrix,+    +    -- * Packed matrix types+    Packed,+    RPacked,+    STPacked,+    IOPacked,+    +    module Numeric.LinearAlgebra.Types,+    ) where++import Numeric.LinearAlgebra.Types+import Numeric.LinearAlgebra.Vector( Vector, RVector, STVector, IOVector )+import Numeric.LinearAlgebra.Matrix( Matrix, RMatrix, STMatrix, IOMatrix )+import Numeric.LinearAlgebra.Packed( Packed, RPacked, STPacked, IOPacked )
+ lib/Numeric/LinearAlgebra/Internal.hs view
@@ -0,0 +1,271 @@+{-# LANGUAGE CPP, ForeignFunctionInterface, MagicHash #-}++{-# OPTIONS_HADDOCK hide #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Internal+-- Copyright  : Copyright (c) 2008, Patrick Perry <patperry@stanford.edu>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@stanford.edu>+-- Stability  : experimental+--+++module Numeric.LinearAlgebra.Internal (+    clearArray,+    bzero,+    inlinePerformIO,+    checkedRow,+    checkedCol,+    checkedDiag,+    checkedSubmatrix,+    checkMatMatOp,+    checkMatVecMult,+    checkMatMatMult,+    checkMatVecMultAdd,+    checkMatMatMultAdd,+    checkMatVecSolv,+    checkMatMatSolv,+    checkMatVecSolvTo,+    checkMatMatSolvTo,+    checkSquare,+    checkFat,+    checkTall,+    checkBinaryOp,+    checkTernaryOp,+    diagStart,+    diagLen,    +    ) where+++import Foreign                  ( Ptr, Storable(..), castPtr, sizeOf )+import Foreign.C.Types          ( CSize(..) )+import Text.Printf ( printf )+++#if defined(__GLASGOW_HASKELL__)+import GHC.IO                   ( unsafeDupablePerformIO )+#else+import System.IO.Unsafe         ( unsafePerformIO )+#endif+++clearArray :: Storable e => Ptr e -> Int -> IO ()+clearArray = clearArray' undefined+    where+    clearArray' :: Storable e => e -> Ptr e -> Int -> IO ()+    clearArray' e ptr n =+        let nbytes = fromIntegral (n * sizeOf e)+        in do+            bzero ptr nbytes+{-# INLINE clearArray #-}+++bzero :: Ptr a -> Int -> IO ()+bzero ptr n =+    let ptr' = castPtr ptr+        n'   = fromIntegral n+    in bzero_ ptr' n'+        +foreign import ccall "strings.h bzero"+    bzero_ :: Ptr () -> CSize -> IO ()+    ++inlinePerformIO :: IO a -> a+#if defined(__GLASGOW_HASKELL__)+inlinePerformIO a = unsafeDupablePerformIO a+#else+inlinePerformIO = unsafePerformIO+#endif+{-# INLINE inlinePerformIO #-}++checkedRow ::  (Int,Int) -> (Int -> v) -> Int -> v+checkedRow (m,n) row i +    | i < 0 || i >= m =+        error $ printf+            "Error in row index.  Tried to get row `%d' in a matrix with shape `(%d,%d)'" i m n+    | otherwise =+        row i++checkedCol :: (Int,Int) -> (Int -> v) -> Int -> v+checkedCol (m,n) col j +    | j < 0 || j >= n =+        error $ printf+            "Error in column index.  Tried to get column `%d' in a matrix with shape `(%d,%d)'" j m n+    | otherwise =+        col j++checkedDiag :: (Int,Int) -> (Int -> v) ->  Int -> v+checkedDiag (m,n) diag i+    | i < 0 && negate i >= m =+        error $ printf+            "Tried to get sub-diagonal `%d' of a matrix with shape `(%d,%d)'" (negate i) m n+    | i > 0 && i >= n =+        error $ printf+            "Tried to get super-diagonal `%d' of a matrix with shape `(%d,%d)'" i m n        +    | otherwise = +        diag i++diagStart :: Int -> (Int,Int)+diagStart i+    | i <= 0 =+        (negate i, 0)+    | otherwise =+        (0, i)+        +diagLen :: (Int,Int) -> Int -> Int+diagLen (m,n) i+    | m <= n =+        if i <= 0 +            then max (m + i) 0+            else min (n - i) m+    | otherwise =+        if i > 0+            then max (n - i) 0+            else min (m + i) n++checkedSubmatrix :: (Int,Int) -> ((Int,Int) -> (Int,Int) -> a) -> (Int,Int) -> (Int,Int) -> a+checkedSubmatrix (m,n) sub (i,j) (m',n')+    | or [ i < 0, m' < 0, i + m' > m, +           j < 0, n' < 0, j + n' > n ] =+        error $ printf ("tried to create submatrix of a `(%d,%d)' matrix " +++                        " using offset `(%d,%d)' and shape (%d,%d)") m n i j m' n'+    | otherwise =+        sub (i,j) (m',n')+++checkMatMatOp :: String -> (Int,Int) -> (Int,Int) -> a -> a+checkMatMatOp name mn1 mn2+    | mn1 /= mn2 =+        error $ printf+            ("%s: x and y have different shapes.  x has shape `%s',"+             ++ " and y has shape `%s'") name (show mn1) (show mn2)+    | otherwise = id+        +checkMatVecMult :: (Int,Int) -> Int -> a -> a+checkMatVecMult mn n+    | snd mn /= n =+        error $ printf+            ("Tried to multiply a matrix with shape `%s' by a vector of dimension `%d'")+            (show mn) n+    | otherwise = id+        +checkMatMatMult :: (Int,Int) -> (Int,Int) -> a -> a+checkMatMatMult mk kn+    | snd mk /= fst kn =+        error $ printf+            ("Tried to multiply a matrix with shape `%s' by a matrix with shape `%s'")+            (show mk) (show kn)+    | otherwise = id++checkMatVecMultAdd :: (Int,Int) -> Int -> Int -> a -> a+checkMatVecMultAdd mn n m+    | snd mn /= n =+        error $ printf+            ("Tried to multiply a matrix with shape `%s' by a vector of dimension `%d'")+            (show mn) n+    | fst mn /= m =+        error $ printf+            ("Tried to add a vector of dimension `%d' to a vector of dimension `%d'")+            (fst mn) m+    | otherwise = id++checkMatMatMultAdd :: (Int,Int) -> (Int,Int) -> (Int,Int) -> a -> a+checkMatMatMultAdd mk kn mn+    | snd mk /= fst kn =+        error $ printf+            ("Tried to multiply a matrix with shape `%s' by a matrix with shape `%s'")+            (show mk) (show kn)+    | (fst mk, snd kn) /= mn =+        error $ printf+            ("Tried to add a matrix with shape `%s' to a matrix with shape `%s'")+            (show (fst mk, snd kn)) (show mn)+    | otherwise = id++checkMatVecSolv :: (Int,Int) -> Int -> a -> a+checkMatVecSolv mn m+    | fst mn /= m =+        error $ printf+            ("Tried to solve a matrix with shape `%s' for a vector of dimension `%d'")+            (show mn) m+    | otherwise = id++checkMatVecSolvTo :: (Int,Int) -> Int -> Int -> a -> a+checkMatVecSolvTo mn m n+    | fst mn /= m =+        error $ printf+            ("Tried to solve a matrix with shape `%s' for a vector of dimension `%d'")+            (show mn) m+    | snd mn /= n =+        error $ printf+            ("Tried to store a vector of dimension `%s' in a vector of dimension `%d'")+            (show $ snd mn) n+    | otherwise = id++checkMatMatSolv :: (Int,Int) -> (Int,Int) -> a -> a+checkMatMatSolv mn mk+    | fst mn /= fst mk =+        error $ printf+            ("Tried to solve a matrix with shape `%s' for a matrix with shape `%s'")+            (show mn) (show mk)+    | otherwise = id++checkMatMatSolvTo :: (Int,Int) -> (Int,Int) -> (Int,Int) -> a -> a+checkMatMatSolvTo mk mn kn+    | fst mn /= fst mk =+        error $ printf+            ("Tried to solve a matrix with shape `%s' for a matrix with shape `%s'")+            (show mk) (show mn)+    | kn /= (snd mk, snd mn) =+        error $ printf+            ("Tried to store a matrix with shape `%s' in a matrix with shape `%s'")+            (show (snd mk, snd mn)) (show kn)+    | otherwise = id++checkSquare :: String -> (Int,Int) -> a -> a+checkSquare str (m,n)+    | m /= n =+        error $ printf+            "%s <matrix of shape (%d,%d)>: matrix shape must be square."+            str m n+    | otherwise = id++checkFat :: String -> (Int,Int) -> a -> a+checkFat str (m,n)+    | m > n =+        error $ printf+            "%s <matrix of shape (%d,%d)>: matrix must have at least as many columns as rows."+            str m n+    | otherwise = id++checkTall :: String -> (Int,Int) -> a -> a+checkTall str (m,n)+    | m < n =+        error $ printf+            "%s <matrix of shape (%d,%d)>: matrix must have at least as many rows as columns."+            str m n+    | otherwise = id++checkBinaryOp :: (Eq i, Show i) => i -> i -> a -> a+checkBinaryOp m n+    | m /= n =+        error $ printf+            ("Shapes in binary operation do not match. "+            ++ " First operand has shape `%s' and second has shapw `%s'.")+            (show m)+            (show n)+    | otherwise = id+{-# INLINE checkBinaryOp #-}++checkTernaryOp :: (Eq i, Show i) => i -> i -> i -> a -> a+checkTernaryOp l m n+    | l == m && l == n = id+    | otherwise =+        error $ printf+            ("Shapes in ternary operation do not match. "+            ++ " First operand has shape `%s', second has shapw `%s',"+            ++ " and third has shape `%s'.")+            (show l)+            (show m)+            (show n)+{-# INLINE checkTernaryOp #-}
+ lib/Numeric/LinearAlgebra/Matrix.hs view
@@ -0,0 +1,421 @@+{-# LANGUAGE Rank2Types #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Immutable dense matrices.++module Numeric.LinearAlgebra.Matrix (+    -- * Immutable matrices+    Matrix,+    dim,++    -- * Matrix construction+    fromList,+    fromCols,+    fromRows,+    constant,+    zero,++    -- * Accessing matrices+    at,+    indices,+    elems,+    assocs,++    -- * Incremental matrix updates+    update,+    unsafeUpdate,+    accum,+    unsafeAccum,++    -- * Derived matrices+    map,+    zipWith,++    -- * Matrix views+    slice,+    takeRows,+    dropRows,+    splitRowsAt,+    takeCols,+    dropCols,+    splitColsAt,++    -- * Matrix rows and columns+    col,+    cols,+    row,+    rows,+    +    -- * Matrix diagonals+    diag,+    +    -- * Conversions to vectors+    toVector,+    +    -- * Conversions from vectors+    fromVector,+    fromCol,+    fromRow,++    -- * Matrix math operations+    shiftDiag,+    shiftDiagWithScale,    +    add,+    addWithScale,+    sub,+    scale,+    scaleRows,+    scaleCols,+    negate,+    conjugate,++    -- * Linear algebra+    trans,+    conjTrans,+    rank1Update,+    +    -- ** Matrix-Vector multiplication+    mulVector,+    mulVectorWithScale,+    addMulVectorWithScales,+    +    -- ** Matrix-Matrix multiplication+    mulMatrix,+    mulMatrixWithScale,+    addMulMatrixWithScales,++    -- * Conversions between foreign pointers+    unsafeFromForeignPtr,+    unsafeToForeignPtr,++    -- * Mutable interface+    module Numeric.LinearAlgebra.Matrix.ST,+    +    -- * Hermitian views+    module Numeric.LinearAlgebra.Matrix.Herm,+    +    -- * Triangular views+    module Numeric.LinearAlgebra.Matrix.Tri,+    +    -- * Cholesky factorizations+    module Numeric.LinearAlgebra.Matrix.Cholesky,+    +    -- * Eigenvalues and eigenvectors+    module Numeric.LinearAlgebra.Matrix.Eigen,++    -- * Basic multivariate statistics+    module Numeric.LinearAlgebra.Matrix.Statistics,++    ) where++import Prelude hiding ( map, zipWith, negate, )+import Control.Monad( zipWithM_ )+import Control.Monad.ST( ST )+import Foreign( Storable )+import Text.Printf( printf )++import Foreign.BLAS( BLAS1, BLAS2, BLAS3, Trans(..) )+import Foreign.VMath( VNum )+++import Numeric.LinearAlgebra.Matrix.Base+import Numeric.LinearAlgebra.Matrix.Herm+import Numeric.LinearAlgebra.Matrix.Tri+import Numeric.LinearAlgebra.Matrix.ST+import Numeric.LinearAlgebra.Matrix.Cholesky+import Numeric.LinearAlgebra.Matrix.Eigen+import Numeric.LinearAlgebra.Matrix.Statistics+import Numeric.LinearAlgebra.Vector( Vector )+import qualified Numeric.LinearAlgebra.Vector as V+++infixl 7 `scale`, `scaleRows`, `scaleCols`+infixl 6 `add`, `shiftDiag`, `sub`+++-- | Create a matrix of the given dimension with the given vectors as+-- columns.+fromCols :: (Storable e) => (Int,Int) -> [Vector e] -> Matrix e+fromCols mn cs = create $ do+    a <- new_ mn+    withColsM a $ \cs' -> zipWithM_ V.copyTo cs' cs+    return a++-- | Create a matrix of the given dimension with the given vectors as+-- rows.+fromRows :: (Storable e) => (Int,Int) -> [Vector e] -> Matrix e+fromRows (m,n) rs = create $ do+    a <- new_ (m,n)+    sequence_ [ setRow a i r | (i,r) <- zip [ 0..m-1 ] rs ]+    return a++-- | Get the given row of the matrix.+row :: (BLAS1 e) => Matrix e -> Int -> Vector e+row a i+    | i < 0 || i >= m = error $+        printf ("row <matrix with dim (%d,%d)> %d:"+                ++ " index out of range") m n i+    | otherwise =+        unsafeRow a i+  where+    (m,n) = dim a+{-# INLINE row #-}++-- | Version of 'row' that doesn't range-check indices.+unsafeRow :: (BLAS1 e) => Matrix e -> Int -> Vector e+unsafeRow a@(Matrix v _ n lda) i+    | lda == 1 = v+    | otherwise = V.create $ do+        r <- V.new_ n+        unsafeRowTo r a i+        return r++-- | Get a list of the rows in a matrix+rows :: (BLAS1 e) => Matrix e -> [Vector e]+rows a = [ unsafeRow a i | i <- [ 0..m-1 ] ]+  where+    (m,_) = dim a+++-- | Get the diagonal of the matrix.+diag :: (Storable e) => Matrix e -> Vector e+diag a = V.create $ do+    x <- V.new_ mn+    diagTo x a+    return x+  where+    (m,n) = dim a+    mn = min m n++-- | @shiftDiag d a@ returns @diag(d) + a@.+shiftDiag :: (BLAS1 e) => Vector e -> Matrix e -> Matrix e+shiftDiag s a = create $ do+    a' <- newCopy a+    shiftDiagM_ s a'+    return a'++-- | @shiftDiagWithScale alpha d a@ returns @alpha * diag(d) + a@.+shiftDiagWithScale :: (BLAS1 e) => e -> Vector e -> Matrix e -> Matrix e+shiftDiagWithScale e s a = create $ do+    a' <- newCopy a+    shiftDiagWithScaleM_ e s a'+    return a'++-- | @add a b@ returns @a + b@.+add :: (VNum e) => Matrix e -> Matrix e -> Matrix e+add = result2 addTo++-- | @sub a b@ returns @a - b@.+sub :: (VNum e) => Matrix e -> Matrix e -> Matrix e+sub = result2 subTo++-- | @scale k a@ returns @k * a@.+scale :: (BLAS1 e) => e -> Matrix e -> Matrix e+scale k a = create $ do+    a' <- newCopy a+    scaleM_ k a'+    return a'++-- | @addWithScale alpha x y@ returns @alpha * x + y@.+addWithScale :: (BLAS1 e) => e -> Matrix e -> Matrix e -> Matrix e+addWithScale alpha x y = create $ do+    y' <- newCopy y+    addWithScaleM_ alpha x y'+    return y'++-- | @scaleRows s a@ returns @diag(s) * a@.+scaleRows :: (BLAS1 e) => Vector e -> Matrix e -> Matrix e+scaleRows s a = create $ do+    a' <- newCopy a+    scaleRowsM_ s a'+    return a'++-- | @scaleCols s a@ returns @a * diag(s)@.+scaleCols :: (BLAS1 e) => Vector e -> Matrix e -> Matrix e+scaleCols s a = create $ do+    a' <- newCopy a+    scaleColsM_ s a'+    return a'++-- | @negate a@ returns @-a@.+negate :: (VNum e) => Matrix e -> Matrix e+negate = result negateTo++-- | @conjugate a@ returns @conjugate(a)@.+conjugate :: (VNum e) => Matrix e -> Matrix e+conjugate = result conjugateTo++-- | @trans a@ retunrs @trans(a)@.+trans :: (BLAS1 e)+      => Matrix e+      -> Matrix e+trans a = let+    (m,n) = dim a+    in create $ do+        a' <- new_ (n,m)+        transTo a' a+        return a'++-- | @conjTrans a@ retunrs @conj(trans(a))@.+conjTrans :: (BLAS1 e)+          => Matrix e+          -> Matrix e+conjTrans a = let+    (m,n) = dim a+    in create $ do+        a' <- new_ (n,m)+        conjTransTo a' a+        return a'++-- | @rank1Update alpha x y a@ returns @alpha * x * y^H + a@.+rank1Update :: (BLAS2 e)+            => e+            -> Vector e+            -> Vector e+            -> Matrix e+            -> Matrix e+rank1Update alpha x y a =+    create $ do+        a' <- newCopy a+        rank1UpdateM_ alpha x y a'+        return a'++-- | @mulVector transa a x@+-- returns @op(a) * x@, where @op(a)@ is determined by @transa@.                   +mulVector :: (BLAS2 e)+          => Trans -> Matrix e+          -> Vector e+          -> Vector e+mulVector transa a x = let+    m = case transa of NoTrans -> (fst . dim) a+                       _       -> (snd . dim) a+    in V.create $ do+        y <- V.new_ m+        mulVectorTo y transa a x+        return y++-- | @mulVectorWithScale alpha transa a x@+-- retunrs @alpha * op(a) * x@, where @op(a)@ is determined by @transa@.                   +mulVectorWithScale :: (BLAS2 e)+                   => e+                   -> Trans -> Matrix e+                   -> Vector e+                   -> Vector e+mulVectorWithScale alpha transa a x = let+    m = case transa of NoTrans -> (fst . dim) a+                       _       -> (snd . dim) a+    in V.create $ do+        y <- V.new_ m+        mulVectorWithScaleTo y alpha transa a x+        return y+                       +-- | @addMulVectorWithScales alpha transa a x beta y@+-- returns @alpha * op(a) * x + beta * y@, where @op(a)@ is+-- determined by @transa@.+addMulVectorWithScales :: (BLAS2 e)+                       => e+                       -> Trans -> Matrix e+                       -> Vector e+                       -> e+                       -> Vector e+                       -> Vector e+addMulVectorWithScales alpha transa a x beta y =+    V.create $ do+        y' <- V.newCopy y+        addMulVectorWithScalesM_ alpha transa a x beta y'+        return y'++-- | @mulMatrix transa a transb b@+-- returns @op(a) * op(b)@, where @op(a)@ and @op(b)@ are determined+-- by @transa@ and @transb@.                   +mulMatrix :: (BLAS3 e)+          => Trans -> Matrix e+          -> Trans -> Matrix e+          -> Matrix e+mulMatrix transa a transb b = let+    m = case transa of NoTrans -> (fst . dim) a+                       _       -> (snd . dim) a+    n = case transb of NoTrans -> (snd . dim) b+                       _       -> (fst . dim) b+    in create $ do+        c <- new_ (m,n)+        mulMatrixTo c transa a transb b+        return c++-- | @mulMatrixWithScale alpha transa a transb b@+-- returns @alpha * op(a) * op(b)@, where @op(a)@ and @op(b)@ are determined+-- by @transa@ and @transb@.                   +mulMatrixWithScale :: (BLAS3 e)+                   => e+                   -> Trans -> Matrix e+                   -> Trans -> Matrix e+                   -> Matrix e+mulMatrixWithScale alpha transa a transb b = let+    m = case transa of NoTrans -> (fst . dim) a+                       _       -> (snd . dim) a+    n = case transb of NoTrans -> (snd . dim) b+                       _       -> (fst . dim) b+    in create $ do+        c <- new_ (m,n)+        mulMatrixWithScaleTo c alpha transa a transb b+        return c++-- | @addMulMatrixWithScales alpha transa a transb b beta c@+-- returns @alpha * op(a) * op(b) + beta * c@, where @op(a)@ and+-- @op(b)@ are determined by @transa@ and @transb@.+addMulMatrixWithScales :: (BLAS3 e)+                       => e+                       -> Trans -> Matrix e+                       -> Trans -> Matrix e+                       -> e+                       -> Matrix e+                       -> Matrix e+addMulMatrixWithScales alpha transa a transb b beta c = +    create $ do+        c' <- newCopy c+        addMulMatrixWithScalesM_ alpha transa a transb b beta c'+        return c'++result :: (Storable e, Storable f)+       => (forall s . STMatrix s f -> Matrix e -> ST s a)+       -> Matrix e+       -> Matrix f+result f a = create $ newResult f a+{-# INLINE result #-}++result2 :: (Storable e, Storable f, Storable g)+        => (forall s . STMatrix s g -> Matrix e -> Matrix f -> ST s a)+        -> Matrix e+        -> Matrix f+        -> Matrix g+result2 f a1 a2 = create $ newResult2 f a1 a2+{-# INLINE result2 #-}++newResult :: (RMatrix m, Storable e, Storable f)+          => (STMatrix s f -> m e -> ST s a)+          -> m e+          -> ST s (STMatrix s f)+newResult f a = do+    mn <- getDim a+    c <- new_ mn+    _ <- f c a+    return c+{-# INLINE newResult #-}++newResult2 :: (RMatrix m1, RMatrix m2, Storable e, Storable f, Storable g)+           => (STMatrix s g -> m1 e -> m2 f -> ST s a)+           -> m1 e+           -> m2 f+           -> ST s (STMatrix s g)+newResult2 f a1 a2 = do+    mn <- getDim a1+    c <- new_ mn+    _ <- f c a1 a2+    return c+{-# INLINE newResult2 #-}
+ lib/Numeric/LinearAlgebra/Matrix/Base.hs view
@@ -0,0 +1,480 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, Rank2Types #-}+{-# OPTIONS_HADDOCK hide #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix.Base+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Numeric.LinearAlgebra.Matrix.Base (+    Matrix(..),+    dim,+    +    fromList,+    fromRow,+    fromCol,+    zero,+    constant,+    +    at,+    unsafeAt,++    indices,+    elems,+    assocs,++    col,+    unsafeCol,+    cols,++    update,+    unsafeUpdate,+    accum,+    unsafeAccum,++    map,+    zipWith,+    unsafeZipWith,++    +    slice,+    unsafeSlice,+    +    splitRowsAt,+    dropRows,+    takeRows,++    splitColsAt,+    dropCols,+    takeCols,++    fromVector,+    toVector,++    isContig,+    unsafeFromForeignPtr,+    unsafeToForeignPtr,+    unsafeWith,++    ) where++import Prelude hiding ( read, map, zipWith )+import qualified Prelude as P++import Data.AEq( AEq(..) )+import Data.Typeable( Typeable )+import Foreign( ForeignPtr, Ptr, Storable )+import Text.Printf( printf )++import Numeric.LinearAlgebra.Vector( Vector )+import qualified Numeric.LinearAlgebra.Vector as V++-- | Immutable dense matrices.+data Matrix e =+      Matrix {-# UNPACK #-} !(Vector e) -- matrix data+             {-# UNPACK #-} !Int        -- row dimension+             {-# UNPACK #-} !Int        -- column dimension+             {-# UNPACK #-} !Int        -- leading dimension+  deriving (Typeable)++-- | Get the matrix dimensions (number of rows and number of columns).+dim :: (Storable e) => Matrix e -> (Int,Int)+dim (Matrix _ m n _) = (m,n)+{-# INLINE dim #-}++-- | Indicates if the elements of the matrix are stored contigously+isContig :: (Storable e) => Matrix e -> Bool+isContig (Matrix _ m _ lda) = lda == m || m == 0+{-# INLINE isContig #-}++-- | Create a matrix of the given dimension with elements initialized+-- to the values from the list, in column major order.+fromList :: (Storable e) => (Int,Int) -> [e] -> Matrix e+fromList (m,n) es+    | m < 0 || n < 0 = error $+        printf "fromList (%d,%d): negative dimension" m n+    | otherwise = let+        v = V.fromList (m*n) es+        lda = max 1 m+        in Matrix v m n lda+{-# INLINE fromList #-}++-- | Create a matrix of the given dimension with all elements initialized+-- to the given value+constant :: (Storable e) => (Int,Int) -> e -> Matrix e+constant (m,n) e+    | m < 0 || n < 0 = error $+        printf "constant (%d,%d): negative dimension" m n+    | otherwise = let+        v = V.constant (m*n) e+        lda = max 1 m+        in Matrix v m n lda+{-# INLINE constant #-}++-- | Create a zero of the given dimension with all elements initialized+-- to zero.+zero :: (Storable e, Num e) => (Int,Int) -> Matrix e+zero (m,n)+    | m < 0 || n < 0 = error $+        printf "zero (%d,%d): negative dimension" m n+    | otherwise = let+        v = V.zero (m*n)+        lda = max 1 m+        in Matrix v m n lda+{-# INLINE zero #-}++-- | Returns the element of a matrix at the specified index.+at :: (Storable e) => Matrix e -> (Int,Int) -> e+at a ij@(i,j)+    | i < 0 || i >= m || j < 0 || j >= n = error $+        printf ("at <matrix with dim (%d,%d)> (%d,%d):"+                ++ " invalid index") m n i j+    | otherwise =+        unsafeAt a ij+  where+      (m,n) = dim a+{-# INLINE at #-}++unsafeAt :: (Storable e) => Matrix e -> (Int,Int) -> e+unsafeAt (Matrix v _ _ lda) (i,j) = +    V.unsafeAt v (i + j * lda)+{-# INLINE unsafeAt #-}++-- | Get the indices of the elements in the matrix, in column-major order.+indices :: (Storable e) => Matrix e -> [(Int,Int)]+indices a = [ (i,j) | j <- [ 0..n-1 ], i <- [ 0..m-1 ] ]+  where (m,n) = dim a++-- | Returns a list of the elements of a matrix, in the same order as their+-- indices.+elems :: (Storable e) => Matrix e -> [e]+elems (Matrix v m _ lda)+    | lda == m  = V.elems v+    | otherwise = let+        breakCols [] = []+        breakCols es = let (c,es') = splitAt lda es in c:(breakCols es')++        dropJunk c = take m c++        in concatMap dropJunk $ breakCols (V.elems v)+{-# INLINE elems #-}++-- | Returns the contents of a matrix as a list of associations.+assocs :: (Storable e) => Matrix e -> [((Int,Int),e)]+assocs x = zip (indices x) (elems x)+{-# INLINE assocs #-}++-- | Version of 'update' that doesn't range-check indices.+unsafeUpdate :: (Storable e) => Matrix e -> [((Int,Int),e)] -> Matrix e+unsafeUpdate (Matrix v m n lda) ijes = let+    ies = [ (i + j * lda, e) | ((i,j),e) <- ijes ]+    v' = V.unsafeUpdate v ies+    in Matrix v' m n lda++-- | Create a new matrix by replacing the values at the specified indices.+update :: (Storable e) => Matrix e -> [((Int,Int),e)] -> Matrix e+update (Matrix v m n lda) ijes = let+    ies = [ if i < 0 || i >= m || j < 0 || j >= n+                then error $ printf+                         ("update"+                         ++ " <matrix with dim (%d,%d)>"+                         ++ " [ ..((%d,%d),_).. ]"+                         ++ ": invalid index")+                         m n i j+                else (i + j * lda, e)+          | ((i,j),e) <- ijes+          ]+    v' = V.unsafeUpdate v ies+    in Matrix v' m n lda++-- | Same as 'accum' but does not range-check indices.+unsafeAccum :: (Storable e)+            => (e -> e' -> e)+            -> Matrix e+            -> [((Int,Int), e')]+            -> Matrix e+unsafeAccum f (Matrix v m n lda) ijes = let+    ies = [ (i + j * lda, e) | ((i,j),e) <- ijes ]+    v' = V.unsafeAccum f v ies+    in Matrix v' m n lda++-- | @accum f@ takes a matrix and an association list and accumulates+-- pairs from the list into the matrix with the accumulating function @f@.+accum :: (Storable e)+      => (e -> e' -> e) +      -> Matrix e+      -> [((Int,Int), e')]+      -> Matrix e+accum f (Matrix v m n lda) ijes = let+    ies = [ if i < 0 || i >= m || j < 0 || j >= n+                then error $ printf+                         ("accum"+                         ++ " <matrix with dim (%d,%d)>"+                         ++ " [ ..((%d,%d),_).. ]"+                         ++ ": invalid index")+                         m n i j+                else (i + j * lda, e)+          | ((i,j),e) <- ijes+          ]+    v' = V.unsafeAccum f v ies+    in Matrix v' m n lda++-- | Construct a new matrix by applying a function to every element of+-- a matrix.+map :: (Storable e, Storable e')+    => (e -> e')+    -> Matrix e+    -> Matrix e'+map f a = fromList (dim a) $ P.map f (elems a)+{-# INLINE map #-}++-- | Construct a new matrix by applying a function to every pair of elements+-- of two matrices.  The two matrices must have identical dimensions.+zipWith :: (Storable e, Storable e', Storable f)+        => (e -> e' -> f)+        -> Matrix e+        -> Matrix e'+        -> Matrix f+zipWith f a a'+    | mn /= mn' = error $+        printf ("zipWith"+                ++ " <matrix with dim %s> "+                ++ " <matrix with dim %s>"+                ++ ": dimension mismatch"+                ) (show mn) (show mn')+    | otherwise =+        unsafeZipWith f a a'+  where+    mn  = dim a+    mn' = dim a'    +{-# INLINE zipWith #-}++-- | Version of 'zipWith' that does not check if the input matrices+-- have the same dimensions.+unsafeZipWith :: (Storable e, Storable e', Storable f)+              => (e -> e' -> f)+              -> Matrix e+              -> Matrix e'+              -> Matrix f+unsafeZipWith f a a' =+    fromList (dim a') $ P.zipWith f (elems a) (elems a')+{-# INLINE unsafeZipWith #-}++-- | Get the given column of the matrix.+col :: (Storable e) => Matrix e -> Int -> Vector e+col a j+    | j < 0 || j >= n = error $+        printf ("col <matrix with dim (%d,%d)> %d:"+                ++ " index out of range") m n j+    | otherwise =+        unsafeCol a j+  where+    (m,n) = dim a+{-# INLINE col #-}++-- | Version of 'col' that doesn't range-check indices.+unsafeCol :: (Storable e) => Matrix e -> Int -> Vector e+unsafeCol (Matrix v m _ lda) j = +    V.unsafeSlice (j*lda) m v+{-# INLINE unsafeCol #-}++-- | Get a list of the columns of the matrix.+cols :: (Storable e) => Matrix e -> [Vector e]+cols a = P.map (unsafeCol a) [ 0..n-1 ]+  where+    (_,n) = dim a+{-# INLINE cols #-}++-- | @slice (i,j) (m,n) a@ creates a submatrix view of @a@ starting at+-- element @(i,j)@ and having dimensions @(m,n)@.+slice :: (Storable e)+      => (Int,Int)+      -> (Int,Int)+      -> Matrix e+      -> Matrix e+slice (i,j) (m',n') a+    | (i < 0 || m' < 0 || i + m' > m +       || j < 0 || n' < 0 || j + n' > n) = error $+        printf ( "slice"+               ++ " (%d,%d)"+               ++ " (%d,%d)"+               ++ " <matrix with dim (%d,%d)>"+               ++ ": index out of range"+               ) i j m' n' m n+    | otherwise =+        unsafeSlice (i,j) (m',n') a+  where+    (m,n) = dim a+{-# INLINE slice #-}++-- | Version of 'slice' that doesn't range-check indices.+unsafeSlice :: (Storable e)+            => (Int,Int) -> (Int,Int) -> Matrix e -> Matrix e+unsafeSlice (i,j) (m',n') (Matrix v _ _ lda) = let+    o = i + j*lda+    l = if m' == 0+            then 0+            else lda * n'+    v' = V.unsafeSlice o l v+    in Matrix v' m' n' lda+{-# INLINE unsafeSlice #-}++-- | Create a view of a matrix by taking the initial rows.+takeRows :: (Storable e) => Int -> Matrix e -> Matrix e+takeRows i a = slice (0,0) (i,n) a+  where+    (_,n) = dim a++-- | Create a view of a matrix by dropping the initial rows.+dropRows :: (Storable e) => Int -> Matrix e -> Matrix e+dropRows i a = slice (i,0) (m-i,n) a+  where+    (m,n) = dim a++-- | Split a matrix into two blocks and returns views into the blocks.  If+-- @(a1, a2) = splitRowsAt i a@, then+-- @a1 = slice (0,0) (i,n) a@ and+-- @a2 = slice (i,0) (m-i,n) a@, where @(m,n)@ is the dimension of @a@.+splitRowsAt :: (Storable e) => Int -> Matrix e -> (Matrix e, Matrix e)+splitRowsAt i a+    | i < 0 || i > m = error $+        printf ("splitRowsAt %d <matrix with dim (%d,%d)>:"+                ++ " invalid index") i m n+    | otherwise = let+        a1 = unsafeSlice (0,0) (i,n)   a+        a2 = unsafeSlice (i,0) (m-i,n) a+    in (a1,a2)+  where+    (m,n) = dim a+{-# INLINE splitRowsAt #-}++-- | Create a view of a matrix by taking the initial columns.+takeCols :: (Storable e) => Int -> Matrix e -> Matrix e+takeCols j a = slice (0,0) (m,j) a+  where+    (m,_) = dim a++-- | Create a view of a matrix by dropping the initial columns.+dropCols :: (Storable e) => Int -> Matrix e -> Matrix e+dropCols j a = slice (0,j) (m,n-j) a+  where+    (m,n) = dim a++-- | Split a matrix into two blocks and returns views into the blocks.  If+-- @(a1, a2) = splitColsAt j a@, then+-- @a1 = slice (0,0) (m,j) a@ and+-- @a2 = slice (0,j) (m,n-j) a@, where @(m,n)@ is the dimension of @a@.+splitColsAt :: (Storable e) => Int -> Matrix e -> (Matrix e, Matrix e)+splitColsAt j a+    | j < 0 || j > n = error $+        printf ("splitColsAt %d <matrix with dim (%d,%d)>:"+                ++ " invalid index") j m n+    | otherwise = let+        a1 = unsafeSlice (0,0) (m,j)   a+        a2 = unsafeSlice (0,j) (m,n-j) a+    in (a1,a2)+  where+    (m,n) = dim a+{-# INLINE splitColsAt #-}+++-- | Convert a matrix to a vector by stacking its columns.+toVector :: (Storable e)+         => Matrix e+         -> Vector e+toVector a@(Matrix v m n _lda)+    | isContig a = v+    | otherwise  = V.fromList (m*n) $ elems a++-- | Cast a vector to a matrix of the given shape.+fromVector :: (Storable e)+           => (Int,Int)+           -> Vector e+           -> Matrix e+fromVector (m,n) v+    | nv /= m * n = error $+        printf ("fromVector"+               ++ " (%d,%d)"+               ++ " <vector with dim %d>"+               ++ ": dimension mismatch"+               ) m n nv+    | otherwise =+        Matrix v m n (max 1 m)+  where+    nv = V.dim v+{-# INLINE fromVector #-}++-- | Cast a vector to a matrix with one column.+fromCol :: (Storable e)+        => Vector e+        -> Matrix e+fromCol v = Matrix v m 1 (max 1 m)+  where+    m = V.dim v++-- | Cast a vector to a matrix with one row.+fromRow :: (Storable e)+        => Vector e+        -> Matrix e+fromRow v = Matrix v 1 n 1+  where+    n = V.dim v++instance (Storable e, Show e) => Show (Matrix e) where+    show x = "fromList " ++ show (dim x) ++ " " ++ show (elems x)+    {-# INLINE show #-}++instance (Storable e, Eq e) => Eq (Matrix e) where+    (==) = compareWith (==)+    {-# INLINE (==) #-}++instance (Storable e, AEq e) => AEq (Matrix e) where+    (===) = compareWith (===)+    {-# INLINE (===) #-}+    (~==) = compareWith (~==)+    {-# INLINE (~==) #-}++compareWith :: (Storable e, Storable e')+            => (e -> e' -> Bool)+            -> Matrix e+            -> Matrix e'+            -> Bool+compareWith cmp a a' =+    dim a == dim a'+    && and (P.zipWith cmp (elems a) (elems a'))+{-# INLINE compareWith #-}++-- | Create a matrix from a 'ForeignPtr' with offset, dimensions, and lda. The+-- data may not be modified through the ForeignPtr afterwards.+unsafeFromForeignPtr :: (Storable e)+                     => ForeignPtr e -- ^ pointer+                     -> Int	         -- ^ offset+                     -> (Int,Int)    -- ^ dimensions+                     -> Int          -- ^ leading dimension (lda)+                     -> Matrix e+unsafeFromForeignPtr p o (m,n) lda = let+    nv = if m == 0 then 0 else n * lda+    v = V.unsafeFromForeignPtr p o nv+    in Matrix v m n lda+{-# INLINE unsafeFromForeignPtr #-}++-- | Yield the underlying 'ForeignPtr' together with the offset to the data+-- the matrix dimensions, and the lda. The data may not be modified through+-- the 'ForeignPtr'.+unsafeToForeignPtr :: (Storable e)+                   => Matrix e+                   -> (ForeignPtr e, Int, (Int,Int), Int)+unsafeToForeignPtr (Matrix v m n lda) = let+    (f,o,_) = V.unsafeToForeignPtr v+    in (f, o, (m,n), lda)+{-# INLINE unsafeToForeignPtr #-}++-- | Execute an 'IO' action with a pointer to the first element in the+-- matrix and the leading dimension (lda).+unsafeWith :: (Storable e) => Matrix e -> (Ptr e -> Int -> IO a) -> IO a+unsafeWith (Matrix v _ _ lda) f =+    V.unsafeWith v $ \p -> f p lda+{-# INLINE unsafeWith #-}
+ lib/Numeric/LinearAlgebra/Matrix/Cholesky.hs view
@@ -0,0 +1,133 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix.Cholesky+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Cholesky factorizations of symmetric (Hermitian) positive-definite+-- matrices.+--++module Numeric.LinearAlgebra.Matrix.Cholesky (+    -- * Immutable interface+    cholFactor,+    cholSolveVector,+    cholSolveMatrix,+    +    -- * Mutable interface+    cholFactorM,+    cholSolveVectorM_,+    cholSolveMatrixM_,+    +    ) where++import Control.Monad( when )+import Control.Monad.ST( ST, runST, unsafeIOToST )+import Text.Printf( printf )++import qualified Foreign.LAPACK as LAPACK++import Numeric.LinearAlgebra.Types++import Numeric.LinearAlgebra.Matrix.Base( Matrix )+import Numeric.LinearAlgebra.Matrix.STBase( RMatrix, STMatrix )+import qualified Numeric.LinearAlgebra.Matrix.STBase as M++import Numeric.LinearAlgebra.Vector( Vector, STVector )+import qualified Numeric.LinearAlgebra.Vector as V+++-- | @cholFactor a@ tries to compute the Cholesky+-- factorization of @a@.  If @a@ is positive-definite then the routine+-- returns @Right@ with the factorization.  If the leading minor of order @i@+-- is not positive-definite then the routine returns @Left i@.+cholFactor :: (LAPACK e)+                 => Herm Matrix e+                 -> Either Int (Chol Matrix e)+cholFactor (Herm uplo a) = runST $ do+    ma <- M.newCopy a+    cholFactorM (Herm uplo ma)+        >>= either (return . Left) (\(Chol uplo' ma') -> do+                a' <- M.unsafeFreeze ma'+                return $ Right (Chol uplo' a')+                )++-- | @cholSolveVector a x@ returns @a \\ x@.+cholSolveVector :: (LAPACK e)+                      => Chol Matrix e+                      -> Vector e+                      -> Vector e+cholSolveVector a x = V.create $ do+    x' <- V.newCopy x+    cholSolveVectorM_ a x'+    return x'++-- | @cholSolveMatrix a b@ returns @a \\ b@.+cholSolveMatrix :: (LAPACK e)+                => Chol Matrix e+                -> Matrix e+                -> Matrix e+cholSolveMatrix a c = M.create $ do+    c' <- M.newCopy c+    cholSolveMatrixM_ a c'+    return c'++-- | @cholFactorM a@ tries to compute the Cholesky+-- factorization of @a@ in place.  If @a@ is positive-definite then the+-- routine returns @Right@ with the factorization, stored in the same+-- memory as @a@.  If the leading minor of order @i@ is not+-- positive-definite then the routine returns @Left i@.+-- In either case, the original storage of @a@ is destroyed.+cholFactorM :: (LAPACK e)+            => Herm (STMatrix s) e+            -> ST s (Either Int (Chol (STMatrix s) e))+cholFactorM (Herm uplo a) = do+    (ma,na) <- M.getDim a+    let n = na++    when (not $ (ma,na) == (n,n)) $ error $+        printf ("cholFactorM"+                ++ " (Herm _ <matrix with dim (%d,%d)>): nonsquare matrix"+               ) ma na++    unsafeIOToST $+        M.unsafeWith a $ \pa lda -> do+            info <- LAPACK.potrf uplo n pa lda+            return $ if info > 0 then Left info+                                 else Right (Chol uplo a)+++-- | @cholSolveVectorM_ a x@ sets @x := a \\ x@.+cholSolveVectorM_ :: (LAPACK e, RMatrix m)+                  => Chol m e+                  -> STVector s e+                  -> ST s ()+cholSolveVectorM_ a x =+    M.withFromColM x $ \x' ->+        cholSolveMatrixM_ a x'++-- | @cholSolveMatrixM_ a b@ sets @b := a \\ b@.+cholSolveMatrixM_ :: (LAPACK e, RMatrix m)+                  => Chol m e+                  -> STMatrix s e+                  -> ST s ()+cholSolveMatrixM_ (Chol uplo a) b = do+    (ma,na) <- M.getDim a+    (mb,nb) <- M.getDim b+    let (n,nrhs) = (mb,nb)+    +    when ((not . and) [ (ma,na) == (n,n)+                      , (mb,nb) == (n,nrhs)+                      ]) $ error $+        printf ("cholSolveMatrixM_"+                ++ " (Chol _ <matrix with dim (%d,%d)>)"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch")+               ma na mb nb++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        M.unsafeWith b $ \pb ldb ->+            LAPACK.potrs uplo n nrhs pa lda pb ldb
+ lib/Numeric/LinearAlgebra/Matrix/Eigen.hs view
@@ -0,0 +1,138 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix.Eigen+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Eigenvalue decompositions.+--+module Numeric.LinearAlgebra.Matrix.Eigen (+    hermEigen,+    hermEigenvalues,+    hermEigenM_,+    hermEigenvaluesM_,+    ) where++import Control.Monad( when )+import Control.Monad.ST( ST, runST, unsafeIOToST )+import Foreign( allocaArray, nullPtr )+import Text.Printf( printf )++import Foreign.LAPACK( LAPACK, EigJob(..), EigRange(..) )+import qualified Foreign.LAPACK as LAPACK++import Numeric.LinearAlgebra.Types( Herm(..) )+import Numeric.LinearAlgebra.Matrix.Base( Matrix )+import Numeric.LinearAlgebra.Matrix.STBase( STMatrix )+import qualified Numeric.LinearAlgebra.Matrix.STBase as M+import Numeric.LinearAlgebra.Vector( Vector, STVector )+import qualified Numeric.LinearAlgebra.Vector as V++-- | Compute the eigenvalues and eigenvectors of a Hermitian matrix.+-- Return the eigenvalues are in ascending order in the result vector; +-- store the corresponding eigenvectors are in the columns of the result+-- matrix.+hermEigen :: (LAPACK e) => Herm Matrix e -> (Vector Double, Matrix e)+hermEigen (Herm uplo a) = runST $ do+    (_,n) <- M.getDim a+    ma <- M.newCopy a+    mw <- V.new_ n+    mz <- M.new_ (n,n)+    hermEigenM_ (Herm uplo ma) mw mz+    w <- V.unsafeFreeze mw+    z <- M.unsafeFreeze mz+    return (w,z)+++-- | Return the eigenvalues of a Hermitian matrix in ascending order.+hermEigenvalues :: (LAPACK e) => Herm Matrix e -> Vector Double+hermEigenvalues (Herm uplo a) = V.create $ do+    (_,n) <- M.getDim a+    ma <- M.newCopy a+    w <- V.new_ n+    hermEigenvaluesM_ (Herm uplo ma) w+    return w+++-- | Compute and copy the eigenvalues and eigenvectors of a mutable+-- Hermitian matrix.  This destroys the original Hermitian matrix.+hermEigenM_ :: (LAPACK e)+                  => Herm (STMatrix s) e+                  -> STVector s Double+                  -> STMatrix s e+                  -> ST s ()+hermEigenM_ (Herm uplo a) w z = do+    (ma,na) <- M.getDim a+    (mz,nz) <- M.getDim z+    nw <- V.getDim w+    let n = na+    +    when (ma /= na) $ error $+        printf ("hermEigenM_"+                ++ " (Herm _ <matrix with dim (%d,%d)>): nonsquare matrix"+               ) ma na+    when ((not . and) [ (ma,na) == (n,n)+                      , nw == n+                      , (mz,nz) == (n,n)+                      ]) $ error $+        printf ("hermEigenM_"+                ++ " (Herm _ <matrix with dim (%d,%d)>)"+                ++ " <vector with dim %d>:"+                ++ " <matrix with dim (%d,%d)>"+                ++ " dimension mismatch")+               ma na nw mz nz++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        V.unsafeWith w $ \pw ->+        M.unsafeWith z $ \pz ldz ->+        allocaArray (2*n) $ \psuppz -> do+            _m <- LAPACK.heevr jobz range uplo n pa lda abstol pw pz ldz+                               psuppz+            return ()+  where+    jobz = EigVectors+    range = AllEigs+    abstol = 0+      ++-- | Compute and copy the eigenvalues of a mutable Hermitian matrix.  This+-- destroys the original Hermitian matrix.+hermEigenvaluesM_ :: (LAPACK e)+                        => Herm (STMatrix s) e+                        -> STVector s Double+                        -> ST s ()+hermEigenvaluesM_ (Herm uplo a) w = do+    (ma,na) <- M.getDim a+    nw <- V.getDim w+    let n = na+    +    when (ma /= na) $  error $+        printf ("hermEigenvaluesM_"+                ++ " (Herm _ <matrix with dim (%d,%d)>): nonsquare matrix"+               ) ma na++    when ((not . and) [ (ma,na) == (n,n)+                      , nw == n+                      ]) $ error $+        printf ("hermEigenvaluesM_"+                ++ " (Herm _ <matrix with dim (%d,%d)>)"+                ++ " <vector with dim %d>: dimension mismatch")+               ma na nw+               +    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        V.unsafeWith w $ \pw -> do+            _m <- LAPACK.heevr jobz range uplo n pa lda abstol pw pz ldz+                               psuppz+            return ()+    +  where+    jobz = NoEigVectors+    range = AllEigs+    abstol = 0+    pz = nullPtr+    ldz = 1+    psuppz = nullPtr
+ lib/Numeric/LinearAlgebra/Matrix/Herm.hs view
@@ -0,0 +1,446 @@+{-# LANGUAGE Rank2Types #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix.Herm+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Hermitian views of matrices.+--++module Numeric.LinearAlgebra.Matrix.Herm (+    -- * Immutable interface+    +    -- ** Vector multiplication+    hermMulVector,+    hermMulVectorWithScale,+    addHermMulVectorWithScales,+    +    -- ** Matrix  multiplication+    hermMulMatrix,+    hermMulMatrixWithScale,+    addHermMulMatrixWithScales,++    -- ** Updates+    hermRank1Update,+    hermRank2Update,+    hermRankKUpdate,   +    hermRank2KUpdate,    ++    +    -- * Mutable interface+    hermCreate,+    +    -- ** Vector multiplication+    hermMulVectorTo,+    hermMulVectorWithScaleTo,+    addHermMulVectorWithScalesM_,+    +    -- ** Matrix multiplication+    hermMulMatrixTo,+    hermMulMatrixWithScaleTo,+    addHermMulMatrixWithScalesM_,++    -- ** Updates+    hermRank1UpdateM_,+    hermRank2UpdateM_,+    hermRankKUpdateM_,  +    hermRank2KUpdateM_,+    +    ) where++import Control.Monad( when )+import Control.Monad.ST( ST, runST, unsafeIOToST )+import Text.Printf( printf )++import Numeric.LinearAlgebra.Vector( Vector, RVector, STVector )+import qualified Numeric.LinearAlgebra.Vector as V+import Numeric.LinearAlgebra.Matrix.Base( Matrix )+import Numeric.LinearAlgebra.Matrix.STBase( STMatrix, RMatrix )+import qualified Numeric.LinearAlgebra.Matrix.STBase as M+import Numeric.LinearAlgebra.Types+import qualified Foreign.BLAS as BLAS+++-- | A safe way to create and work with a mutable Herm Matrix before returning +-- an immutable one for later perusal.+hermCreate :: (Storable e)+           => (forall s. ST s (Herm (STMatrix s) e))+           -> Herm Matrix e+hermCreate mh = runST $ do+    (Herm u ma) <- mh+    a <- M.unsafeFreeze ma+    return $ Herm u a++-- | @hermRank1Update alpha x a@ returns+-- @alpha * x * x^H + a@.+hermRank1Update :: (BLAS2 e)+                => Double -> Vector e -> Herm Matrix e -> Herm Matrix e+hermRank1Update alpha x (Herm uplo a) = runST $ do+    ma' <- M.newCopy a+    hermRank1UpdateM_ alpha x (Herm uplo ma')+    a' <- M.unsafeFreeze ma'+    return $ Herm uplo a'++-- | @hermRank2Update alpha x y a@ returns+-- @alpha * x * y^H + conj(alpha) * y * x^H + a@.+hermRank2Update :: (BLAS2 e)+                => e -> Vector e -> Vector e -> Herm Matrix e+                -> Herm Matrix e+hermRank2Update alpha x y (Herm uplo a) = runST $ do+    ma' <- M.newCopy a+    hermRank2UpdateM_ alpha x y (Herm uplo ma')+    a' <- M.unsafeFreeze ma'+    return $ Herm uplo a'++-- | @hermRankKUpdate alpha trans a beta c@ returns+-- @c := alpha * a * a^H + beta * c@ when @trans@ is @NoTrans@ and+-- @c := alpha * a^H * a + beta * c@ when @trans@ is @ConjTrans@.  The+-- function signals an error when @trans@ is @Trans@.+hermRankKUpdate :: (BLAS3 e)+                => e -> Trans -> Matrix e -> e -> Herm Matrix e+                -> Herm Matrix e+hermRankKUpdate alpha trans a beta (Herm uplo c) = runST $ do+    mc' <- M.newCopy c+    hermRankKUpdateM_ alpha trans a beta (Herm uplo mc')+    c' <- M.unsafeFreeze mc'+    return $ Herm uplo c'++-- | @hermRank2KUpdate alpha trans a b beta c@ returns+-- @c := alpha * a * b^H + conj(alpha) * b * a^H + beta * c@ when @trans@ is+-- @NoTrans@ and @c := alpha * b^H * a + conj(alpha) * a^H * b + beta * c@+-- when @trans@ is @ConjTrans@.  The function signals an error when @trans@+-- is @Trans@.+hermRank2KUpdate :: (BLAS3 e)+                 => e -> Trans -> Matrix e -> Matrix e -> e -> Herm Matrix e+                 -> Herm Matrix e+hermRank2KUpdate alpha trans a b beta (Herm uplo c) = runST $ do+    mc' <- M.newCopy c+    hermRank2KUpdateM_ alpha trans a b beta (Herm uplo mc')+    c' <- M.unsafeFreeze mc'+    return $ Herm uplo c'++-- | @hermRank1UpdateM_ alpha x a@ sets+-- @a := alpha * x * x^H + a@.+hermRank1UpdateM_ :: (RVector v, BLAS2 e)+                  => Double -> v e -> Herm (STMatrix s) e -> ST s ()+hermRank1UpdateM_ alpha x (Herm uplo a) = do+    nx <- V.getDim x+    (ma,na) <- M.getDim a+    let n = nx++    when ((not . and) [ nx == n, (ma,na) == (n,n) ]) $ error $+        printf ("hermRank1UpdateM_ _ <vector with dim %d>"+                 ++ " (Herm _ <matrix with dim (%d,%d)>):"+                 ++ " invalid dimensions") nx ma na++    unsafeIOToST $+        V.unsafeWith x $ \px ->+        M.unsafeWith a $ \pa lda ->+            BLAS.her uplo n alpha px 1 pa lda+++-- | @hermRank2UpdateM_ alpha x y a@ sets+-- @a := alpha * x * y^H + conj(alpha) * y * x^H + a@.+hermRank2UpdateM_ :: (RVector v1, RVector v2, BLAS2 e)+                  => e -> v1 e -> v2 e -> Herm (STMatrix s) e -> ST s ()+hermRank2UpdateM_ alpha x y (Herm uplo a) = do+    nx <- V.getDim x+    ny <- V.getDim y+    (ma,na) <- M.getDim a+    let n = nx+    +    when ((not . and) [ nx == n, ny == n, (ma,na) == (n,n) ]) $ error $+        printf ("hermRank2UpdateM_ _ <vector with dim %d>"+                 ++ " <vector with dim %d>"+                 ++ " (Herm _ <matrix with dim (%d,%d)>):"+                 ++ " invalid dimensions") nx ny ma na++    unsafeIOToST $+        V.unsafeWith x $ \px ->+        V.unsafeWith y $ \py ->+        M.unsafeWith a $ \pa lda ->+            BLAS.her2 uplo n alpha px 1 py 1 pa lda+++-- | @hermRankKUpdateM_ alpha trans a beta c@ sets+-- @c := alpha * a * a^H + beta * c@ when @trans@ is @NoTrans@ and+-- @c := alpha * a^H * a + beta * c@ when @trans@ is @ConjTrans@.  The+-- function signals an error when @trans@ is @Trans@.+hermRankKUpdateM_ :: (RMatrix m, BLAS3 e)+                  => e -> Trans -> m e -> e -> Herm (STMatrix s) e+                  -> ST s ()+hermRankKUpdateM_ alpha trans a beta (Herm uplo c) = do+    (ma,na) <- M.getDim a+    (mc,nc) <- M.getDim c+    let (n,k) = if trans == NoTrans then (ma,na) else (na,ma)++    when (trans == Trans) $ error $+        printf ("hermRankKUpdateM_ _ %s:"+                 ++ " trans argument must be NoTrans or ConjTrans")+               (show trans)+               +    when ((not . and) [ (mc,nc) == (n,n)+                      , case trans of NoTrans -> (ma,na) == (n,k)+                                      _       -> (ma,na) == (k,n)+                      ]) $ error $+            printf ("hermRankKUpdateM_ _ %s <matrix with dim (%d,%d)> _"+                    ++ " (Herm _ <matrix with dim (%d,%d)>):"+                    ++ " invalid dimensions") (show trans) ma na mc nc++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        M.unsafeWith c $ \pc ldc ->+            BLAS.herk uplo trans n k alpha pa lda beta pc ldc+++-- | @hermRank2KUpdateM_ alpha trans a b beta c@ sets+-- @c := alpha * a * b^H + conj(alpha) * b * a^H + beta * c@ when @trans@ is+-- @NoTrans@ and @c := alpha * b^H * a + conj(alpha) * a^H * b + beta * c@+-- when @trans@ is @ConjTrans@.  The function signals an error when @trans@+-- is @Trans@.+hermRank2KUpdateM_ :: (RMatrix m1, RMatrix m2, BLAS3 e)+                   => e -> Trans -> m1 e -> m2 e -> e -> Herm (STMatrix s) e+                   -> ST s ()+hermRank2KUpdateM_ alpha trans a b beta (Herm uplo c) = do+    (ma,na) <- M.getDim a+    (mb,nb) <- M.getDim b+    (mc,nc) <- M.getDim c+    let (n,k) = if trans == NoTrans then (ma,na) else (na,ma)++    when (trans == Trans) $ error $+        printf ("hermRank2KUpdateM_ _ %s:"+                 ++ " trans argument must be NoTrans or ConjTrans")+               (show trans)++    when ((not . and) [ (mc,nc) == (n,n)+                      , (mb,nb) == (ma,na)+                      , case trans of NoTrans -> (ma,na) == (n,k)+                                      _       -> (ma,na) == (k,n)+                      ]) $ error $+            printf ("hermRank2KUpdateM_ _ %s <matrix with dim (%d,%d)>"+                    ++ " <matrix with dim (%d,%d)> _"+                    ++ " (Herm _ <matrix with dim (%d,%d)>):"+                    ++ " invalid dimensions") (show trans) ma na mb nb mc nc++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        M.unsafeWith b $ \pb ldb ->+        M.unsafeWith c $ \pc ldc ->+            BLAS.her2k uplo trans n k alpha pa lda pb ldb beta pc ldc+++-- | @hermMulVector a x@ returns @a * x@.+hermMulVector :: (BLAS2 e)+              => Herm Matrix e+              -> Vector e+              -> Vector e+hermMulVector a x =+    V.create $ do+        n <- V.getDim x+        y <- V.new_ n+        hermMulVectorTo y a x+        return y++-- | @hermMulVectorWithScale alpha a x@ retunrs @alpha * a * x@.+hermMulVectorWithScale :: (BLAS2 e)+                       => e+                       -> Herm Matrix e+                       -> Vector e+                       -> Vector e+hermMulVectorWithScale alpha a x =+    V.create $ do+        n <- V.getDim x+        y <- V.new_ n+        hermMulVectorWithScaleTo y alpha a x+        return y+                       +-- | @addHermMulVectorWithScales alpha a x y@+-- returns @alpha * a * x + beta * y@.+addHermMulVectorWithScales :: (BLAS2 e)+                           => e+                           -> Herm Matrix e+                           -> Vector e+                           -> e+                           -> Vector e+                           -> Vector e+addHermMulVectorWithScales alpha a x beta y =+    V.create $ do+        y' <- V.newCopy y+        addHermMulVectorWithScalesM_ alpha a x beta y'+        return y'++-- | @hermMulMatrix side a b@+-- returns @alpha * a * b@ when @side@ is @LeftSide@ and+-- @alpha * b * a@ when @side@ is @RightSide@.+hermMulMatrix :: (BLAS3 e)+              => Side -> Herm Matrix e+              -> Matrix e+              -> Matrix e+hermMulMatrix side a b = +    M.create $ do+        mn <- M.getDim b+        c <- M.new_ mn+        hermMulMatrixTo c side a b+        return c++-- | @hermMulMatrixWithScale alpha side a b@+-- returns @alpha * a * b@ when @side@ is @LeftSide@ and+-- @alpha * b * a@ when @side@ is @RightSide@.+hermMulMatrixWithScale :: (BLAS3 e)+                       => e+                       -> Side -> Herm Matrix e+                       -> Matrix e+                       -> Matrix e+hermMulMatrixWithScale alpha side a b =+    M.create $ do+        mn <- M.getDim b+        c <- M.new_ mn+        hermMulMatrixWithScaleTo c alpha side a b+        return c++-- | @addHermMulMatrixWithScales alpha side a b beta c@+-- returns @alpha * a * b + beta * c@ when @side@ is @LeftSide@ and+-- @alpha * b * a + beta * c@ when @side@ is @RightSide@.+addHermMulMatrixWithScales :: (BLAS3 e)+                           => e+                           -> Side -> Herm Matrix e+                           -> Matrix e+                           -> e+                           -> Matrix e+                           -> Matrix e+addHermMulMatrixWithScales alpha side a b beta c = +    M.create $ do+        c' <- M.newCopy c+        addHermMulMatrixWithScalesM_ alpha side a b beta c'+        return c'++-- | @hermMulVectorTo dst a x@ sets @dst := a * x@.+hermMulVectorTo :: (RMatrix m, RVector v, BLAS2 e)+                => STVector s e+                -> Herm m e+                -> v e+                -> ST s ()+hermMulVectorTo dst = hermMulVectorWithScaleTo dst 1++-- | @hermMulVectorWithScaleTo dst alpha a x@+-- sets @dst := alpha * a * x@.+hermMulVectorWithScaleTo :: (RMatrix m, RVector v, BLAS2 e)+                         => STVector s e+                         -> e+                         -> Herm m e+                         -> v e+                         -> ST s ()+hermMulVectorWithScaleTo dst alpha a x =+    addHermMulVectorWithScalesM_ alpha a x 0 dst++-- | @addHermMulVectorWithScalesM_ alpha a x beta y@+-- sets @y := alpha * a * x + beta * y@.+addHermMulVectorWithScalesM_ :: (RMatrix m, RVector v, BLAS2 e)+                             => e+                             -> Herm m e+                             -> v e+                             -> e+                             -> STVector s e+                             -> ST s ()+addHermMulVectorWithScalesM_ alpha (Herm uplo a) x beta y = do+    (ma,na) <- M.getDim a+    nx <- V.getDim x+    ny <- V.getDim y+    let n = ny+    +    when (ma /= na) $ error $+        printf ("addHermMulVectorWithScalesM_ _"+                ++ " (Herm %s <matrix with dim (%d,%d)>)"+                ++ " %s <vector with dim %d>"+                ++ " _"+                ++ " <vector with dim %d>: Herm matrix is not square")+               (show uplo) ma na+               nx ny+               +    when ((not . and) [ (ma,na) == (n,n)+                      , nx == n+                      , ny == n+                      ]) $ error $+        printf ("addHermMulVectorWithScalesM_ _"+                ++ " (Herm %s <matrix with dim (%d,%d)>)"+                ++ " %s <vector with dim %d>"+                ++ " _"+                ++ " <vector with dim %d>: dimension mismatch")+               (show uplo) ma na+               nx ny++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        V.unsafeWith x $ \px ->+        V.unsafeWith y $ \py ->+            BLAS.hemv uplo n alpha pa lda px 1 beta py 1++-- | @hermMulMatrixTo dst side a b@+-- sets @dst := a * b@ when @side@ is @LeftSide@ and+-- @dst := b * a@ when @side@ is @RightSide@.+hermMulMatrixTo :: (RMatrix m1, RMatrix m2, BLAS3 e)+                => STMatrix s e+                -> Side -> Herm m1 e+                -> m2 e+                -> ST s ()+hermMulMatrixTo dst = hermMulMatrixWithScaleTo dst 1++-- | @hermMulMatrixWithScaleTo dst alpha side a b@+-- sets @dst := alpha * a * b@ when @side@ is @LeftSide@ and+-- @dst := alpha * b * a@ when @side@ is @RightSide@.+hermMulMatrixWithScaleTo :: (RMatrix m1, RMatrix m2, BLAS3 e)+                         => STMatrix s e+                         -> e+                         -> Side -> Herm m1 e+                         -> m2 e+                         -> ST s ()+hermMulMatrixWithScaleTo dst alpha side a b =+    addHermMulMatrixWithScalesM_ alpha side a b 0 dst++-- | @addHermMulMatrixWithScalesM_ alpha side a b beta c@+-- sets @c := alpha * a * b + beta * c@ when @side@ is @LeftSide@ and+-- @c := alpha * b * a + beta * c@ when @side@ is @RightSide@.+addHermMulMatrixWithScalesM_ :: (RMatrix m1, RMatrix m2, BLAS3 e)+                             => e+                             -> Side -> Herm m1 e+                             -> m2 e+                             -> e+                             -> STMatrix s e+                             -> ST s ()+addHermMulMatrixWithScalesM_ alpha side (Herm uplo a) b beta c = do+    (ma,na) <- M.getDim a+    (mb,nb) <- M.getDim b+    (mc,nc) <- M.getDim c+    let (m,n) = (mc,nc)+    +    when (ma /= na) $ error $+        printf ("addHermMulMatrixWithScalesM_ _"+                ++ " %s (Herm %s <matrix with dim (%d,%d)>)" +                ++ " <matrix with dim (%d,%d)>"+                ++ " _"+                ++ " <matrix with dim (%d,%d)>: Herm matrix is not square")+               (show side) (show uplo) ma na+               mb nb+               mc nc+    when ((not . and) [ case side of LeftSide  -> (ma,na) == (m,m)+                                     RightSide -> (ma,na) == (n,n)+                      , (mb, nb ) == (m,n)+                      , (mc, nc ) == (m,n)+                      ]) $ error $+        printf ("addHermMulMatrixWithScalesM_ _"+                ++ " %s (Herm %s <matrix with dim (%d,%d)>)" +                ++ " <matrix with dim (%d,%d)>"+                ++ " _"+                ++ " <matrix with dim (%d,%d)>: dimension mismatch")+               (show side) (show uplo) ma na+               mb nb+               mc nc++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        M.unsafeWith b $ \pb ldb ->+        M.unsafeWith c $ \pc ldc ->+            BLAS.hemm side uplo m n alpha pa lda pb ldb beta pc ldc
+ lib/Numeric/LinearAlgebra/Matrix/ST.hs view
@@ -0,0 +1,128 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix.ST+-- Copyright  : Copyright (c) , Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Mutable matrices in the ST monad.++module Numeric.LinearAlgebra.Matrix.ST (+    -- * Mutable matrices+    STMatrix,+    IOMatrix,+    create,+    +    -- * Read-only matrices+    RMatrix(..),+    +    -- * Creating new matrices+    new_,+    new,+    +    -- * Copying matrices+    newCopy,+    copyTo,++    -- * Matrix views+    withSlice,+    withTakeRows,+    withDropRows,+    withSplitRowsAt,+    withTakeCols,+    withDropCols,+    withSplitColsAt,+    withSliceM,+    withTakeRowsM,+    withDropRowsM,+    withSplitRowsAtM,+    withTakeColsM,+    withDropColsM,+    withSplitColsAtM,+    +    -- * Matrix rows and columns+    rowTo,+    unsafeRowTo,+    setRow,+    unsafeSetRow,+    withCol,++    withColM,+    withColsM,+    +    swapRows,+    unsafeSwapRows,+    swapCols,+    unsafeSwapCols,++    -- * Matrix diagonals+    diagTo,+    setDiag,++    -- * Reading and writing matrix elements+    read,+    write,+    modify,+    getIndices,+    getElems,+    getElems',+    getAssocs,+    getAssocs',+    setElems,+    setAssocs,++    -- * List-like operations+    mapTo,+    zipWithTo,++    -- * Matrix math operations+    shiftDiagM_,+    shiftDiagWithScaleM_,+    addTo,+    subTo,+    scaleM_,+    addWithScaleM_,+    scaleRowsM_,+    scaleColsM_,+    negateTo,+    conjugateTo,++    -- * Linear algebra+    transTo,+    conjTransTo,+    rank1UpdateM_,+    +    -- ** Matrix-Vector multiplication+    mulVectorTo,+    mulVectorWithScaleTo,+    addMulVectorWithScalesM_,+    +    -- ** Matrix-Matrix multiplication+    mulMatrixTo,+    mulMatrixWithScaleTo,+    addMulMatrixWithScalesM_,++    -- * Conversions between mutable and immutable matrices+    freeze,+    +    -- * Vector views of matrices+    maybeWithVectorM,+    +    -- * Matrix views of vectors+    withFromVector,+    withFromCol,+    withFromRow,++    withFromVectorM,+    withFromColM,+    withFromRowM,+    +    -- * Unsafe operations+    unsafeCopyTo,+    unsafeAddWithScaleM_,+    +    ) where++import Prelude()+import Numeric.LinearAlgebra.Matrix.STBase
+ lib/Numeric/LinearAlgebra/Matrix/STBase.hs view
@@ -0,0 +1,1250 @@+{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, Rank2Types #-}+{-# OPTIONS_HADDOCK hide #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix.STBase+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : asinerimental+--++module Numeric.LinearAlgebra.Matrix.STBase+    where+      +import Control.Monad( forM_, when )+import Control.Monad.ST( ST, RealWorld, runST, unsafeInterleaveST,+    unsafeIOToST )+import Data.Maybe( fromMaybe )+import Data.Typeable( Typeable )+import Foreign( Ptr, advancePtr, peek, peekElemOff, pokeElemOff,+    mallocForeignPtrArray )+import Text.Printf( printf )+import Unsafe.Coerce( unsafeCoerce )++import Numeric.LinearAlgebra.Types+import qualified Foreign.BLAS as BLAS+import Numeric.LinearAlgebra.Matrix.Base hiding ( unsafeWith,+    unsafeToForeignPtr, unsafeFromForeignPtr, )+import qualified Numeric.LinearAlgebra.Matrix.Base as M+import Numeric.LinearAlgebra.Vector( STVector, RVector )+import qualified Numeric.LinearAlgebra.Vector as V++-- | Mutable dense matrices in the 'ST' monad.+newtype STMatrix s e = STMatrix { unSTMatrix :: Matrix e }+    deriving (Typeable)++-- | Mutable dense matrices in the 'IO' monad.+type IOMatrix = STMatrix RealWorld++-- | A safe way to create and work with a mutable matrix before returning +-- an immutable matrix for later perusal. This function avoids copying+-- the matrix before returning it - it uses 'unsafeFreeze' internally,+-- but this wrapper is a safe interface to that function. +create :: (Storable e) => (forall s . ST s (STMatrix s e)) -> Matrix e+create mx = runST $ mx >>= unsafeFreeze+{-# INLINE create #-}++-- | Converts a mutable matrix to an immutable one by taking a complete+-- copy of it.+freeze :: (RMatrix m, Storable e) => m e -> ST s (Matrix e)+freeze a = do+    a' <- newCopy a+    unsafeFreeze a'+{-# INLINE freeze #-}+++-- | Read-only matrices+class RMatrix m where+    -- | Get the dimensions of the matrix (number of rows and columns).+    getDim :: (Storable e) => m e -> ST s (Int,Int)+    +    -- | Same as 'withCol' but does not range-check index.+    unsafeWithCol :: (Storable e)+                  => m e+                  -> Int +                  -> (forall v. RVector v => v e -> ST s a)+                  -> ST s a++    -- | Perform an action with a list of views of the matrix columns.+    withCols :: (Storable e)+                 => m e+                 -> (forall v . RVector v => [v e] -> ST s a)+                 -> ST s a++    -- | Same as 'withSlice' but does not range-check index.+    unsafeWithSlice :: (Storable e)+                    => (Int,Int)+                    -> (Int,Int)+                    -> m e+                    -> (forall m'. RMatrix m' => m' e -> ST s a)+                    -> ST s a++    -- | Possibly view a matrix as a vector and perform an action on the+    -- view.  This only succeeds if the matrix is stored contiguously in+    -- memory, i.e. if the matrix contains a single column or the \"lda\"+    -- of the matrix is equal to the number of rows.+    maybeWithVector :: (Storable e)+                    => m e+                    -> (forall v . RVector v => v e -> ST s a)+                    -> Maybe (ST s a)++    -- | Converts a read-only matrix into an immutable matrix. This simply+    -- casts the matrix from one type to the other without copying.+    -- Note that because the matrix is possibly not copied, any subsequent+    -- modifications made to the read-only version of the matrix may be shared+    -- with the immutable version. It is safe to use, therefore, if the+    -- read-only version is never modified after the freeze operation.+    unsafeFreeze :: (Storable e) => m e -> ST s (Matrix e)++    -- | Unsafe cast from a read-only matrix to a mutable matrix.+    unsafeThaw :: (Storable e)+               => m e -> ST s (STMatrix s e)++    -- | Execute an 'IO' action with a pointer to the first element in the+    -- matrix and the leading dimension (lda).+    unsafeWith :: (Storable e) => m e -> (Ptr e -> Int -> IO a) -> IO a++instance RMatrix Matrix where+    getDim = return . dim+    {-# INLINE getDim #-}+    unsafeWithCol a j f = f (unsafeCol a j)+    {-# INLINE unsafeWithCol #-}+    withCols a f = f (cols a)+    {-# INLINE withCols #-}+    unsafeWithSlice ij mn a f = f (unsafeSlice ij mn a)+    {-# INLINE unsafeWithSlice #-}+    maybeWithVector a f | isContig a = Just $ f (toVector a)+                        | otherwise = Nothing+    {-# INLINE maybeWithVector #-}+    unsafeWith = M.unsafeWith+    {-# INLINE unsafeWith #-}+    unsafeFreeze = return+    {-# INLINE unsafeFreeze #-}+    unsafeThaw = return . STMatrix+    {-# INLINE unsafeThaw #-}+++instance RMatrix (STMatrix s) where+    getDim = return . dim . unSTMatrix+    {-# INLINE getDim #-}+    unsafeWithCol = unsafeWithCol . unSTMatrix+    {-# INLINE unsafeWithCol #-}+    withCols = withCols . unSTMatrix+    {-# INLINE withCols #-}+    unsafeWithSlice ij mn = unsafeWithSlice ij mn . unSTMatrix+    {-# INLINE unsafeWithSlice #-}+    maybeWithVector = maybeWithVector . unSTMatrix+    {-# INLINE maybeWithVector #-}+    unsafeWith = unsafeWith . unSTMatrix+    {-# INLINE unsafeWith #-}+    unsafeFreeze = return . unSTMatrix+    {-# INLINE unsafeFreeze #-}+    unsafeThaw v = return $ cast v+      where+        cast :: STMatrix s e -> STMatrix s' e+        cast = unsafeCoerce+    {-# INLINE unsafeThaw #-}++++-- | Perform an action with a view of a mutable matrix column+-- (no index checking).+unsafeWithColM :: (Storable e)+               => STMatrix s e+               -> Int+               -> (STVector s e -> ST s a)+               -> ST s a+unsafeWithColM a j f = +    unsafeWithCol a j $ \c -> do+        mc <- V.unsafeThaw c+        f mc+{-# INLINE unsafeWithColM #-}++-- | Perform an action with a list of views of the mutable matrix columns. See+-- also 'withCols'.+withColsM :: (Storable e)+               => STMatrix s e+               -> ([STVector s e] -> ST s a)+               -> ST s a+withColsM a f =+    withCols a $ \cs -> do+        mcs <- thawVecs cs+        f mcs+  where+    thawVecs [] = return []+    thawVecs (c:cs) = unsafeInterleaveST $ do+        mc <- V.unsafeThaw c+        mcs <- thawVecs cs+        return $ mc:mcs+{-# INLINE withColsM #-}+++-- | Possibly view a matrix as a vector and perform an action on the+-- view.  This succeeds when the matrix is stored contiguously in memory,+-- i.e. if the matrix contains a single column or the \"lda\" of the matrix+-- is equal to the number of rows.  See also 'maybeWithVector'.+maybeWithVectorM :: (Storable e)+                 => STMatrix s e+                 -> (STVector s e -> ST s a)+                 -> Maybe (ST s a)+maybeWithVectorM a f = +    maybeWithVector a $ \v -> do+        mv <- V.unsafeThaw v+        f mv+{-# INLINE maybeWithVectorM #-}+++-- | View a vector as a matrix of the given shape and pass it to+-- the specified function.+withFromVector :: (RVector v, Storable e)+                   => (Int,Int)+                   -> v e+                   -> (forall m . RMatrix m => m e -> ST s a)+                   -> ST s a+withFromVector mn@(m,n) v f = do+    nv <- V.getDim v+    when (nv /= m*n) $ error $+        printf ("withFromVector (%d,%d) <vector with dim %d>:"+                ++ " dimension mismatch") m n nv+    iv <- V.unsafeFreeze v+    f $ fromVector mn iv+{-# INLINE withFromVector #-}+++-- | View a mutable vector as a mutable matrix of the given shape and pass it+-- to the specified function.+withFromVectorM :: (Storable e)+                     => (Int,Int)+                     -> STVector s e+                     -> (STMatrix s e -> ST s a)+                     -> ST s a+withFromVectorM mn@(m,n) v f = do+    nv <- V.getDim v+    when (nv /= m*n) $ error $+        printf ("withFromVectorM (%d,%d) <vector with dim %d>:"+                ++ " dimension mismatch") m n nv+    withFromVector mn v $ \a -> do+        ma <- unsafeThaw a+        f ma+{-# INLINE withFromVectorM #-}+++-- | View a vector as a matrix with one column and pass it to+-- the specified function.+withFromCol :: (RVector v, Storable e)+                => v e+                -> (forall m . RMatrix m => m e -> ST s a)+                -> ST s a+withFromCol v f = do+    m <- V.getDim v+    withFromVector (m,1) v f+{-# INLINE withFromCol #-}+++-- | View a mutable vector as a mutable matrix with one column and pass it to+-- the specified function.+withFromColM :: (Storable e)+                  => STVector s e+                  -> (STMatrix s e -> ST s a)+                  -> ST s a+withFromColM v f = do+    m <- V.getDim v+    withFromVectorM (m, 1) v f+{-# INLINE withFromColM #-}+++-- | View a vector as a matrix with one row and pass it to+-- the specified function.+withFromRow :: (RVector v, Storable e)+                => v e+                -> (forall m . RMatrix m => m e -> ST s a)+                -> ST s a+withFromRow v f = do+    n <- V.getDim v+    withFromVector (1,n) v f+{-# INLINE withFromRow #-}++-- | View a mutable vector as a mutable matrix with one row and pass it to+-- the specified function.+withFromRowM :: (Storable e)+                  => STVector s e+                  -> (STMatrix s e -> ST s a)+                  -> ST s a+withFromRowM v f = do+    n <- V.getDim v+    withFromVectorM (1,n) v f+{-# INLINE withFromRowM #-}++-- | Perform an action with a view of a matrix column.+withCol :: (RMatrix m, Storable e)+            => m e+            -> Int+            -> (forall v . RVector v => v e -> ST s a)+            -> ST s a+withCol a j f = do+    (m,n) <- getDim a+    when (j < 0 || j >= n) $ error $+        printf ("withCol <matrix with dim (%d,%d)> %d:"+                ++ " index out of range") m n j++    unsafeWithCol a j f+{-# INLINE withCol #-}++-- | Like 'withCol', but perform the action with a mutable view.+withColM :: (Storable e)+         => STMatrix s e+         -> Int+         -> (STVector s e -> ST s a)+         -> ST s a+withColM a j f = do+    (m,n) <- getDim a+    when (j < 0 || j >= n) $ error $+        printf ("withColM <matrix with dim (%d,%d)> %d:"+                ++ " index out of range") m n j++    unsafeWithColM a j f+{-# INLINE withColM #-}++-- | Create a new matrix of given shape, but do not initialize the elements.+new_ :: (Storable e) => (Int,Int) -> ST s (STMatrix s e)+new_ (m,n) +    | m < 0 || n < 0 = error $+        printf "new_ (%d,%d): invalid dimensions" m n+    | otherwise = unsafeIOToST $ do+        f <- mallocForeignPtrArray (m*n)+        return $ STMatrix $ M.unsafeFromForeignPtr f 0 (m,n) (max 1 m)++-- | Create a matrix with every element initialized to the same value.+new :: (Storable e) => (Int,Int) -> e -> ST s (STMatrix s e)+new (m,n) e = do+    a <- new_ (m,n)+    setElems a $ replicate (m*n) e+    return a++-- | Creates a new matrix by copying another one.    +newCopy :: (RMatrix m, Storable e) => m e -> ST s (STMatrix s e)+newCopy a = do+    mn <- getDim a+    b <- new_ mn+    unsafeCopyTo b a+    return b++-- | @copyTo dst src@ replaces the values in @dst@ with those in+-- source.  The operands must be the same shape.+copyTo :: (RMatrix m, Storable e) => STMatrix s e -> m e -> ST s ()+copyTo = checkOp2 "copyTo" unsafeCopyTo+{-# INLINE copyTo #-}++-- | Same as 'copyTo' but does not range-check indices.+unsafeCopyTo :: (RMatrix m, Storable e) => STMatrix s e -> m e -> ST s ()+unsafeCopyTo = vectorOp2 V.unsafeCopyTo+{-# INLINE unsafeCopyTo #-}++-- | Get the indices of the elements in the matrix, in column-major order.+getIndices :: (RMatrix m, Storable e) => m e -> ST s [(Int,Int)]+getIndices a = do+    (m,n) <- getDim a+    return $ [ (i,j) | j <- [ 0..n-1 ], i <- [ 0..m-1 ] ]+  +-- | Lazily get the elements of the matrix, in column-major order.  +getElems :: (RMatrix m, Storable e) => m e -> ST s [e]+getElems a = case maybeWithVector a V.getElems of+    Just es -> es+    Nothing -> withCols a $ \xs ->+                   concat `fmap` mapM V.getElems xs++-- | Get the elements of the matrix, in column-major order.+getElems' :: (RMatrix m, Storable e) => m e -> ST s [e]+getElems' a = case maybeWithVector a V.getElems' of+    Just es -> es+    Nothing -> withCols a $ \xs ->+                   concat `fmap` mapM V.getElems' xs++-- | Lazily get the association list of the matrix, in column-major order.+getAssocs :: (RMatrix m, Storable e) => m e -> ST s [((Int,Int),e)]+getAssocs a = do+    is <- getIndices a+    es <- getElems a+    return $ zip is es++-- | Get the association list of the matrix, in column-major order.+getAssocs' :: (RMatrix m, Storable e) => m e -> ST s [((Int,Int),e)]+getAssocs' a = do+    is <- getIndices a+    es <- getElems' a+    return $ zip is es++-- | Set all of the values of the matrix from the elements in the list,+-- in column-major order.+setElems :: (Storable e) => STMatrix s e -> [e] -> ST s ()+setElems a es =+    case maybeWithVectorM a (`V.setElems` es) of+        Just st  -> st+        Nothing -> do+            (m,n) <- getDim a+            go m n 0 es+  where+    go _ n j [] | j == n = return ()+    go m n j [] | j < n = error $ +        printf ("setElems <matrix with dim (%d,%d>"+                ++ "<list with length %d>: not enough elements)") m n (j*m)+    go m n j es' =+        let (es1', es2') = splitAt m es'+        in do+            withColM a j (`V.setElems` es1')+            go m n (j+1) es2'++-- | Set the given values in the matrix.  If an index is repeated twice,+-- the value is implementation-defined.+setAssocs :: (Storable e) => STMatrix s e -> [((Int,Int),e)] -> ST s ()+setAssocs a ies =+    sequence_ [ write a i e | (i,e) <- ies ]++-- | Same as 'setAssocs' but does not range-check indices.+unsafeSetAssocs :: (Storable e) => STMatrix s e -> [((Int,Int),e)] -> ST s ()+unsafeSetAssocs a ies =+    sequence_ [ unsafeWrite a i e | (i,e) <- ies ]++-- | Set the specified row of the matrix to the given vector.+setRow :: (RVector v, Storable e)+       => STMatrix s e -> Int -> v e -> ST s ()+setRow a i x = do+    (m,n) <- getDim a+    nx <- V.getDim x+    +    when (i < 0 || i >= m) $ error $+        printf ("setRow <matrix with dim (%d,%d)> %d:"+                ++ " index out of range") m n i+    when (nx /= n) $ error $+        printf ("setRow <matrix with dim (%d,%d)> _"+                ++ " <vector with dim %d>:"+                ++ " dimension mismatch") m n nx++    unsafeSetRow a i x+{-# INLINE setRow #-}++-- | Same as 'setRow' but does not range-check index or check+-- vector dimension.+unsafeSetRow :: (RVector v, Storable e)+             => STMatrix s e -> Int -> v e -> ST s ()+unsafeSetRow a i x = do+    jes <- V.getAssocs x+    sequence_ [ unsafeWrite a (i,j) e | (j,e) <- jes ]+{-# INLINE unsafeSetRow #-}++-- | Exchange corresponding elements in the given rows.+swapRows :: (BLAS1 e)+         => STMatrix s e -> Int -> Int -> ST s ()+swapRows a i1 i2 = do+    (m,n) <- getDim a+    when (i1 < 0 || i1 >= m || i2 < 0 || i2 >= m) $ error $+        printf ("swapRows <matrix with dim (%d,%d)> %d %d"+                ++ ": index out of range") m n i1 i2+    unsafeSwapRows a i1 i2++-- | Same as 'swapRows' but does not range-check indices.+unsafeSwapRows :: (BLAS1 e)+               => STMatrix s e -> Int -> Int -> ST s ()+unsafeSwapRows a i1 i2 = when (i1 /= i2) $ do+    (_,n) <- getDim a+    unsafeIOToST $+        unsafeWith a $ \pa lda ->+            let px = pa `advancePtr` i1+                py = pa `advancePtr` i2+                incx = lda+                incy = lda+            in+                BLAS.swap n px incx py incy++-- | Exchange corresponding elements in the given columns.+swapCols :: (BLAS1 e)+         => STMatrix s e -> Int -> Int -> ST s ()+swapCols a j1 j2 = do+    (m,n) <- getDim a+    when (j1 < 0 || j1 >= n || j2 < 0 || j2 >= n) $ error $+        printf ("swapCols <matrix with dim (%d,%d)> %d %d"+                ++ ": index out of range") m n j1 j2+    unsafeSwapCols a j1 j2++-- | Same as 'swapCols' but does not range-check indices.+unsafeSwapCols :: (BLAS1 e)+               => STMatrix s e -> Int -> Int -> ST s ()+unsafeSwapCols a j1 j2 = when (j1 /= j2) $ do+    (m,_) <- getDim a+    unsafeIOToST $+        unsafeWith a $ \pa lda ->+            let px = pa `advancePtr` (j1*lda)+                py = pa `advancePtr` (j2*lda)+                incx = 1+                incy = 1+            in+                BLAS.swap m px incx py incy++-- | Copy the specified row of the matrix to the vector.+rowTo :: (RMatrix m, Storable e)+         => STVector s e -> m e -> Int -> ST s ()+rowTo x a i = do+    (m,n) <- getDim a+    nx <- V.getDim x+    when (i < 0 || i >= m) $ error $+        printf ("rowTo"+               ++ " _"+               ++ " <matrix with dim (%d,%d)>"+               ++ " %d:"+               ++ ": index out of range"+               ) m n i+    when (nx /= n) $ error $+        printf ("rowTo"+                ++ " <vector with dim %d>"+                ++ " <matrix with dim (%d,%d)>"+                ++ " _"+                ++ ": dimension mismatch") nx m n++    unsafeRowTo x a i+{-# INLINE rowTo #-}++-- | Same as 'rowTo' but does not range-check index or check dimension.+unsafeRowTo :: (RMatrix m, Storable e)+            =>  STVector s e -> m e -> Int ->ST s ()+unsafeRowTo x a i = do+    (_,n) <- getDim a+    forM_ [ 0..n-1 ] $ \j -> do+        e <- unsafeRead a (i,j)+        V.unsafeWrite x j e+{-# INLINE unsafeRowTo #-}++-- | Set the diagonal of the matrix to the given vector.+setDiag :: (RVector v, Storable e)+        => STMatrix s e -> v e -> ST s ()+setDiag a x = do+    (m,n) <- getDim a+    nx <- V.getDim x+    let mn = min m n+    +    when (nx /= mn) $ error $+        printf ("setRow <matrix with dim (%d,%d)>"+                ++ " <vector with dim %d>:"+                ++ " dimension mismatch") m n nx++    unsafeSetDiag a x+{-# INLINE setDiag #-}++-- | Same as 'setDiag' but does not range-check index or check dimension.+unsafeSetDiag :: (RVector v, Storable e)+              => STMatrix s e -> v e -> ST s ()+unsafeSetDiag a x = do+    ies <- V.getAssocs x+    sequence_ [ unsafeWrite a (i,i) e | (i,e) <- ies ]+{-# INLINE unsafeSetDiag #-}++-- | Copy the diagonal of the matrix to the vector.+diagTo :: (RMatrix m, Storable e)+       => STVector s e -> m e -> ST s ()+diagTo x a = do+    nx <- V.getDim x+    (m,n) <- getDim a+    let mn = min m n+    +    when (nx /= mn) $ error $+        printf ("diagTo"+                ++ " <vector with dim %d>"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch") nx m n++    unsafeDiagTo x a+{-# INLINE diagTo #-}++-- | Same as 'diagTo' but does not range-check index or check dimensions.+unsafeDiagTo :: (RMatrix m, Storable e)+             => STVector s e -> m e -> ST s ()+unsafeDiagTo x a = do+    (m,n) <- getDim a+    let mn = min m n+    forM_ [ 0..mn-1 ] $ \i -> do+        e <- unsafeRead a (i,i)+        V.unsafeWrite x i e+{-# INLINE unsafeDiagTo #-}++-- | Get the element stored at the given index.+read :: (RMatrix m, Storable e) => m e -> (Int,Int) -> ST s e+read a (i,j) = do+    (m,n) <- getDim a+    when (i < 0 || i >= m || j < 0 || j >= n) $ error $+        printf ("read <matrix with dim (%d,%d)> (%d,%d):"+                ++ " index out of range") m n i j+    unsafeRead a (i,j)+{-# INLINE read #-}++-- | Same as 'read' but does not range-check index.+unsafeRead :: (RMatrix m, Storable e) => m e -> (Int,Int) -> ST s e+unsafeRead a (i,j) = unsafeIOToST $+    unsafeWith a $ \p lda ->+        peekElemOff p (i + j * lda)+{-# INLINE unsafeRead #-}++-- | Set the element stored at the given index.+write :: (Storable e)+      => STMatrix s e -> (Int,Int) -> e -> ST s ()+write a (i,j) e = do+    (m,n) <- getDim a+    when (i < 0 || i >= m || j < 0 || j >= n) $ error $+        printf ("write <matrix with dim (%d,%d)> (%d,%d):"+                ++ " index out of range") m n i j+    unsafeWrite a (i,j) e+    +{-# INLINE write #-}++-- | Same as 'write' but does not range-check index.+unsafeWrite :: (Storable e)+            => STMatrix s e -> (Int,Int) -> e -> ST s ()+unsafeWrite a (i,j) e = unsafeIOToST $+    unsafeWith a $ \p lda ->+        pokeElemOff p (i + j * lda) e+{-# INLINE unsafeWrite #-}++-- | Modify the element stored at the given index.+modify :: (Storable e)+       => STMatrix s e -> (Int,Int) -> (e -> e) -> ST s ()+modify a (i,j) f = do+    (m,n) <- getDim a+    when (i < 0 || i >= m || j < 0 || j >= n) $ error $+        printf ("modify <matrix with dim (%d,%d)> (%d,%d):"+                ++ " index out of range") m n i j+    unsafeModify a (i,j) f+{-# INLINE modify #-}++-- | Same as 'modify' but does not range-check index.+unsafeModify :: (Storable e)+             => STMatrix s e -> (Int,Int) -> (e -> e) -> ST s ()+unsafeModify a (i,j) f = unsafeIOToST $+    unsafeWith a $ \p lda -> +        let o = i + j * lda+        in do+            e <- peekElemOff p o+            pokeElemOff p o $ f e+{-# INLINE unsafeModify #-}++-- | @mapTo dst f src@ replaces @dst@ elementwise with @f(src)@.+mapTo :: (RMatrix m, Storable e, Storable f)+      => STMatrix s f+      -> (e -> f)+      -> m e+      -> ST s ()+mapTo dst f src = (checkOp2 "mapTo _" $ \z x -> unsafeMapTo z f x) dst src+{-# INLINE mapTo #-}+             +-- | Same as 'mapTo' but does not check dimensions.+unsafeMapTo :: (RMatrix m, Storable e, Storable f)+            => STMatrix s f+            -> (e -> f)+            -> m e+            -> ST s ()+unsafeMapTo dst f src =+    fromMaybe colwise $ maybeWithVectorM dst $ \vdst ->+    fromMaybe colwise $ maybeWithVector  src $ \vsrc ->+        V.unsafeMapTo vdst f vsrc+  where+    colwise = withColsM dst $ \zs ->+              withCols   src $ \xs ->+                  sequence_ [ V.unsafeMapTo z f x+                            | (z,x) <- zip zs xs+                            ]++-- | @zipWithTo dst f x y@ replaces @dst@ elementwise with @f(x, y)@.+zipWithTo :: (RMatrix m1, RMatrix m2, Storable e1, Storable e2, Storable f)+          => STMatrix s f+          -> (e1 -> e2 -> f)+          -> m1 e1+          -> m2 e2+          -> ST s ()+zipWithTo dst f x y = +    (checkOp3 "zipWithTo _" $ \dst1 x1 y1 -> unsafeZipWithTo dst1 f x1 y1)+        dst x y+{-# INLINE zipWithTo #-}++-- | Same as 'zipWithTo' but does not check dimensions.+unsafeZipWithTo :: (RMatrix m1, RMatrix m2, Storable e1, Storable e2, Storable f)+                => STMatrix s f+                -> (e1 -> e2 -> f)+                -> m1 e1+                -> m2 e2+                -> ST s ()+unsafeZipWithTo dst f x y =+    fromMaybe colwise $ maybeWithVectorM dst $ \vdst ->+    fromMaybe colwise $ maybeWithVector    x $ \vx ->+    fromMaybe colwise $ maybeWithVector    y $ \vy ->+        V.unsafeZipWithTo vdst f vx vy+  where+    colwise = withColsM dst $ \vdsts ->+              withCols   x $ \vxs ->+              withCols   y $ \vys ->+              +                  sequence_ [ V.unsafeZipWithTo vdst f vx vy+                            | (vdst,vx,vy) <- zip3 vdsts vxs vys+                            ]++-- | Set every element in the matrix to a default value.  For+-- standard numeric types (including 'Double', 'Complex Double', and 'Int'),+-- the default value is '0'.+clear :: (Storable e) => STMatrix s e -> ST s ()+clear a = fromMaybe colwise $ maybeWithVectorM a V.clear+  where+    colwise = withColsM a $ mapM_ V.clear++-- | @withSlice (i,j) (m,n) a@ performs an action with a view of the+-- submatrix of @a@ starting at index @(i,j)@ and having dimension @(m,n)@.+withSlice :: (RMatrix m, Storable e)+          => (Int,Int)+          -> (Int,Int)+          -> m e+          -> (forall m'. RMatrix m' => m' e -> ST s a)+          -> ST s a+withSlice ij mn a f = do+    ia <- unsafeFreeze a+    f $ slice ij mn ia++-- | Like 'withSlice', but perform the action with a mutable view.+withSliceM :: (Storable e)+           => (Int,Int)+           -> (Int,Int)+           -> STMatrix s e+           -> (STMatrix s e -> ST s a)+           -> ST s a+withSliceM ij mn a f =+    withSlice ij mn a $ \a' -> do+        ma <- unsafeThaw a'+        f ma++-- | Perform an action with a view gotten from taking the given number of+-- rows from the start of the matrix.+withTakeRows :: (RMatrix m, Storable e)+             => Int+             -> m e+             -> (forall m'. RMatrix m' => m' e -> ST s a)+             -> ST s a+withTakeRows i a f = do+    ia <- unsafeFreeze a+    f $ takeRows i ia++-- | Like 'withTakeRows', but perform the action with a mutable view.+withTakeRowsM :: (Storable e)+              => Int+              -> STMatrix s e+              -> (STMatrix s e -> ST s a)+              -> ST s a+withTakeRowsM i a f =+    withTakeRows i a $ \a' -> do+        ma <- unsafeThaw a'+        f ma++-- | Perform an action with a view gotten from dropping the given number of+-- rows from the start of the matrix.+withDropRows :: (RMatrix m, Storable e)+             => Int+             -> m e+             -> (forall m'. RMatrix m' => m' e -> ST s a)+             -> ST s a+withDropRows n a f = do+    ia <- unsafeFreeze a+    f $ dropRows n ia++-- | Like 'withDropRows', but perform the action with a mutable view.+withDropRowsM :: (Storable e)+              => Int+              -> STMatrix s e+              -> (STMatrix s e -> ST s a)+              -> ST s a+withDropRowsM i a f =+    withDropRows i a $ \a' -> do+        ma <- unsafeThaw a'+        f ma++-- | Perform an action with views from splitting the matrix rows at the given+-- index.+withSplitRowsAt :: (RMatrix m, Storable e)+                => Int+                -> m e+                -> (forall m1 m2. (RMatrix m1, RMatrix m2) => m1 e -> m2 e -> ST s a)+                -> ST s a+withSplitRowsAt i a f = do+    ia <- unsafeFreeze a+    uncurry f $ splitRowsAt i ia++-- | Like 'withSplitRowsAt', but perform the action with a mutable view.+withSplitRowsAtM :: (Storable e)+                 => Int+                 -> STMatrix s e+                 -> (STMatrix s e -> STMatrix s e -> ST s a)+                 -> ST s a+withSplitRowsAtM i a f =+    withSplitRowsAt i a $ \a1' a2' -> do+        ma1 <- unsafeThaw a1'+        ma2 <- unsafeThaw a2'        +        f ma1 ma2+    +-- | Perform an action with a view gotten from taking the given number of+-- columns from the start of the matrix.+withTakeCols :: (RMatrix m, Storable e)+             => Int+             -> m e+             -> (forall m'. RMatrix m' => m' e -> ST s a)+             -> ST s a+withTakeCols i a f = do+    ia <- unsafeFreeze a+    f $ takeCols i ia++-- | Like 'withTakeCols', but perform the action with a mutable view.+withTakeColsM :: (Storable e)+              => Int+              -> STMatrix s e+              -> (STMatrix s e -> ST s a)+              -> ST s a+withTakeColsM i a f =+    withTakeCols i a $ \a' -> do+        ma <- unsafeThaw a'+        f ma++-- | Perform an action with a view gotten from dropping the given number of+-- columns from the start of the matrix.+withDropCols :: (RMatrix m, Storable e)+             => Int+             -> m e+             -> (forall m'. RMatrix m' => m' e -> ST s a)+             -> ST s a+withDropCols n a f = do+    ia <- unsafeFreeze a+    f $ dropCols n ia++-- | Like 'withDropCols', but perform the action with a mutable view.+withDropColsM :: (Storable e)+              => Int+              -> STMatrix s e+              -> (STMatrix s e -> ST s a)+              -> ST s a+withDropColsM i a f =+    withDropCols i a $ \a' -> do+        ma <- unsafeThaw a'+        f ma++-- | Perform an action with views from splitting the matrix columns at the given+-- index.+withSplitColsAt :: (RMatrix m, Storable e)+                => Int+                -> m e+                -> (forall m1 m2. (RMatrix m1, RMatrix m2) => m1 e -> m2 e -> ST s a)+                -> ST s a+withSplitColsAt i a f = do+    ia <- unsafeFreeze a+    uncurry f $ splitColsAt i ia++-- | Like 'withSplitColsAt', but perform the action with mutable views.    +withSplitColsAtM :: (Storable e)+                 => Int+                 -> STMatrix s e+                 -> (STMatrix s e -> STMatrix s e -> ST s a)+                 -> ST s a+withSplitColsAtM i a f =+    withSplitColsAt i a $ \a1' a2' -> do+        ma1 <- unsafeThaw a1'+        ma2 <- unsafeThaw a2'        +        f ma1 ma2+++-- | Add a vector to the diagonal of a matrix.+shiftDiagM_ :: (RVector v, BLAS1 e)+              => v e -> STMatrix s e -> ST s ()+shiftDiagM_ s a = do+    (m,n) <- getDim a+    ns <- V.getDim s+    let mn = min m n+    +    when (ns /= mn) $ error $+        printf ("shiftDiagM_"+                ++ " <vector with dim %d>"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch")+                ns+                m n+    +    shiftDiagWithScaleM_ 1 s a+    ++-- | Add a scaled vector to the diagonal of a matrix.+shiftDiagWithScaleM_ :: (RVector v, BLAS1 e)+                       => e -> v e -> STMatrix s e -> ST s ()+shiftDiagWithScaleM_ e s a = do+    (m,n) <- getDim a+    ns <- V.getDim s+    let mn = min m n++    when (ns /= mn) $ error $+        printf ("shiftDiagWithScaleM_"+                ++ " _"+                ++ " <vector with dim %d>"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch")+                ns+                m n++    unsafeIOToST $+        V.unsafeWith s $ \ps ->+        unsafeWith a $ \pa lda ->+            BLAS.axpy mn e ps 1 pa (lda+1)+++-- | Add two matrices.+addTo :: (RMatrix m1, RMatrix m2, VNum e)+      =>  STMatrix s e -> m1 e -> m2 e -> ST s ()+addTo = checkOp3 "addTo" $ vectorOp3 V.addTo++-- | Subtract two matrices.+subTo :: (RMatrix m1, RMatrix m2, VNum e)+      => STMatrix s e -> m1 e -> m2 e -> ST s ()+subTo = checkOp3 "subTo" $ vectorOp3 V.subTo++-- | Conjugate the entries of a matrix.+conjugateTo :: (RMatrix m, VNum e)+            => STMatrix s e -> m e -> ST s ()+conjugateTo = checkOp2 "conjugateTo" $+    vectorOp2 V.conjugateTo++-- | Negate the entries of a matrix.+negateTo :: (RMatrix m, VNum e)+         => STMatrix s e -> m e -> ST s ()+negateTo = checkOp2 "negateTo" $+    vectorOp2 V.negateTo++-- | Scale the entries of a matrix by the given value.+scaleM_ :: (BLAS1 e)+          => e -> STMatrix s e -> ST s ()+scaleM_ e = vectorOp (V.scaleM_ e)++-- | @addWithScaleM_ alpha x y@ sets @y := alpha * x + y@.+addWithScaleM_ :: (RMatrix m, BLAS1 e)+               => e -> m e -> STMatrix s e -> ST s ()+addWithScaleM_ e = checkOp2 "addWithScaleM_" $+    unsafeAddWithScaleM_ e++unsafeAddWithScaleM_ :: (RMatrix m, BLAS1 e)+                     => e -> m e -> STMatrix s e -> ST s ()+unsafeAddWithScaleM_ alpha x y =+    fromMaybe colwise $ maybeWithVector  x $ \vx ->+    fromMaybe colwise $ maybeWithVectorM y $ \vy ->+        V.unsafeAddWithScaleM_ alpha vx vy+  where+    colwise = withCols   x $ \vxs ->+              withColsM y $ \vys ->+                  sequence_ [ V.unsafeAddWithScaleM_ alpha vx vy+                            | (vx,vy) <- zip vxs vys ]                ++-- | Scale the rows of a matrix; @scaleRowsM_ s a@ sets+-- @a := diag(s) * a@.+scaleRowsM_ :: (RVector v, BLAS1 e)+              => v e -> STMatrix s e -> ST s ()+scaleRowsM_  s a = do+    (m,n) <- getDim a+    ns <- V.getDim s+    when (ns /= m) $ error $+        printf ("scaleRowsM_"+                ++ " <vector with dim %d>"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch")+                ns+                m n++    unsafeIOToST $+        V.unsafeWith s $ \ps ->+        unsafeWith a   $ \pa lda ->+            go m n lda pa ps 0+  where+    go m n lda pa ps i | i == m    = return ()+                       | otherwise = do+                             e <- peek ps+                             BLAS.scal n e pa lda+                             go m n lda (pa `advancePtr` 1)+                                        (ps `advancePtr` 1)+                                        (i+1)++-- | Scale the columns of a matrix; @scaleColBysM_ s a@ sets+-- @a := a * diag(s)@.+scaleColsM_ :: (RVector v, BLAS1 e)+            => v e -> STMatrix s e -> ST s ()+scaleColsM_ s a = do+    (m,n) <- getDim a+    ns <- V.getDim s+    when (ns /= n) $ error $+        printf ("scaleColsM_"+                ++ " <vector with dim %d>"+                ++ " <matrix with dim (%d,%d)>"        +                ++ ": dimension mismatch") +                ns+                m n++    es <- V.getElems s+    withColsM a $ \xs ->+        sequence_ [ V.scaleM_ e x+                  | (e,x) <- zip es xs+                  ]+++-- | @rank1UpdateM_ alpha x y a@ sets @a := alpha * x * y^H + a@.+rank1UpdateM_ :: (RVector v1, RVector v2, BLAS2 e)+              => e -> v1 e -> v2 e -> STMatrix s e -> ST s ()+rank1UpdateM_ alpha x y a = do+    (m,n) <- getDim a    +    nx <- V.getDim x+    ny <- V.getDim y+    +    when (nx /= m || ny /= n) $ error $+        printf ("rank1UpdateTo"+                ++ " _"+                ++ " <vector with dim %d>"+                ++ " <vector with dim %d>"+                ++ ": dimension mismatch"+                ++ "<matrix with dim (%d,%d)>"                )+                nx+                ny+                m n+    +    unsafeIOToST $+        V.unsafeWith x $ \px ->+        V.unsafeWith y $ \py ->+        unsafeWith a $ \pa lda ->+            BLAS.gerc m n alpha px 1 py 1 pa lda+++-- | @transTo dst a@ sets @dst := trans(a)@.+transTo :: (RMatrix m, BLAS1 e)+        => STMatrix s e+        -> m e+        -> ST s ()+transTo a' a = do+    (ma,na) <- getDim a+    (ma',na') <- getDim a'+    let (m,n) = (ma,na)++    when ((ma,na) /= (na',ma')) $ error $+        printf ( "transTo"+               ++ " <matrix with dim (%d,%d)>"+               ++ " <matrix with dim (%d,%d)>"+               ++ ": dimension mismatch"+               )+               ma' na'+               ma na+    +    unsafeIOToST $+        unsafeWith a' $ \pa' lda' ->+        unsafeWith a $ \pa lda -> let+            go j px py | j == n = return ()+                       | otherwise = do+                           BLAS.copy m px 1 py lda'+                           go (j+1) (px `advancePtr` lda) (py `advancePtr` 1)+            in go 0 pa pa'+++-- | @conjTransTo dst a@ sets @dst := conjugate(trans(a))@.+conjTransTo :: (RMatrix m, BLAS1 e)+            => STMatrix s e+            -> m e+            -> ST s ()+conjTransTo a' a = do+    transTo a' a+    conjugateTo a' a'++-- | @mulVectorTo dst transa a x@+-- sets @dst := op(a) * x@, where @op(a)@ is determined by @transa@.                   +mulVectorTo :: (RMatrix m, RVector v, BLAS2 e)+            => STVector s e+            -> Trans -> m e+            -> v e+            -> ST s ()+mulVectorTo dst = mulVectorWithScaleTo dst 1++-- | @mulVectorWithScaleTo dst alpha transa a x@+-- sets @dst := alpha * op(a) * x@, where @op(a)@ is determined by @transa@.                   +mulVectorWithScaleTo :: (RMatrix m, RVector v, BLAS2 e)+                     => STVector s e+                     -> e+                     -> Trans -> m e+                     -> v e+                     -> ST s ()+mulVectorWithScaleTo dst alpha t a x =+    addMulVectorWithScalesM_ alpha t a x 0 dst++-- | @addMulVectorWithScalesM_ alpha transa a x beta y@+-- sets @y := alpha * op(a) * x + beta * y@, where @op(a)@ is+-- determined by @transa@.+addMulVectorWithScalesM_ :: (RMatrix m, RVector v, BLAS2 e)+                         => e+                         -> Trans -> m e+                         -> v e+                         -> e+                         -> STVector s e+                         -> ST s ()+addMulVectorWithScalesM_ alpha transa a x beta y = do+    (ma,na) <- getDim a+    nx <- V.getDim x+    ny <- V.getDim y+    let (m,n) = (ny,nx)++    when ((not . and) [ case transa of NoTrans -> (ma,na) == (m,n)+                                       _       -> (ma,na) == (n,m)+                      , nx == n+                      , ny == m+                      ]) $ error $+        printf ("addMulVectorWithScalesTo"+                ++ " _"+                ++ " %s"+                ++ " <matrix with dim (%d,%d)>" +                ++ " <vector with dim %d>"+                ++ " _"+                ++ " <vector with dim %d>"+                ++ ": dimension mismatch")+               (show transa)+               ma na+               nx+               ny++    unsafeIOToST $+        unsafeWith a $ \pa lda ->+        V.unsafeWith x $ \px ->+        V.unsafeWith y $ \py ->+            if n == 0+                then BLAS.scal m beta py 1+                else BLAS.gemv transa ma na alpha pa lda px 1 beta py 1++-- | @mulMatrixTo dst transa a transb b@+-- sets @dst := op(a) * op(b)@, where @op(a)@ and @op(b)@ are determined+-- by @transa@ and @transb@.                   +mulMatrixTo :: (RMatrix m1, RMatrix m2, BLAS3 e)+            => STMatrix s e+            -> Trans -> m1 e+            -> Trans -> m2 e+            -> ST s ()+mulMatrixTo dst = mulMatrixWithScaleTo dst 1++-- | @mulMatrixWithScaleTo alpha transa a transb b c@+-- sets @c := alpha * op(a) * op(b)@, where @op(a)@ and @op(b)@ are determined+-- by @transa@ and @transb@.                   +mulMatrixWithScaleTo :: (RMatrix m1, RMatrix m2, BLAS3 e)+                     => STMatrix s e+                     -> e+                     -> Trans -> m1 e+                     -> Trans -> m2 e+                     -> ST s ()+mulMatrixWithScaleTo dst alpha ta a tb b =+    addMulMatrixWithScalesM_ alpha ta a tb b 0 dst++-- | @addMulMatrixWithScalesM_ alpha transa a transb b beta c@+-- sets @c := alpha * op(a) * op(b) + beta * c@, where @op(a)@ and+-- @op(b)@ are determined by @transa@ and @transb@.+addMulMatrixWithScalesM_ :: (RMatrix m1, RMatrix m2, BLAS3 e)+                         => e+                         -> Trans -> m1 e+                         -> Trans -> m2 e+                         -> e+                         -> STMatrix s e+                         -> ST s ()+addMulMatrixWithScalesM_ alpha transa a transb b beta c = do+    (ma,na) <- getDim a+    (mb,nb) <- getDim b+    (mc,nc) <- getDim c+    let (m,n) = (mc,nc)+        k = case transa of NoTrans -> na+                           _       -> ma++    when ((not . and) [ case transa of NoTrans -> (ma,na) == (m,k)+                                       _       -> (ma,na) == (k,m)+                      , case transb of NoTrans -> (mb,nb) == (k,n)+                                       _       -> (mb,nb) == (n,k)+                      , (mc, nc) == (m,n)+                      ]) $ error $+        printf ("addMulMatrixWithScalesM_"+                ++ " _"+                ++ " %s <matrix with dim (%d,%d)>" +                ++ " %s <matrix with dim (%d,%d)>"+                ++ " _"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch")+               (show transa) ma na+               (show transb) mb nb+               mc nc++    unsafeIOToST $+        unsafeWith a $ \pa lda ->+        unsafeWith b $ \pb ldb ->+        unsafeWith c $ \pc ldc ->+            BLAS.gemm transa transb m n k alpha pa lda pb ldb beta pc ldc++checkOp2 :: (RMatrix x, RMatrix y, Storable e, Storable f)+         => String+         -> (x e -> y f -> ST s a)+         -> x e+         -> y f+         -> ST s a+checkOp2 str f x y = do+    (m1,n1) <- getDim x+    (m2,n2) <- getDim y+    when ((m1,n1) /= (m2,n2)) $ error $+        printf ("%s <matrix with dim (%d,%d)> <matrix with dim (%d,%d)>:"+                ++ " dimension mismatch") str m1 n1 m2 n2+    f x y+{-# INLINE checkOp2 #-}++checkOp3 :: (RMatrix x, RMatrix y, RMatrix z, Storable e, Storable f, Storable g)+         => String+         -> (x e -> y f -> z g -> ST s a)+         -> x e+         -> y f+         -> z g+         -> ST s a+checkOp3 str f x y z = do+    (m1,n1) <- getDim x+    (m2,n2) <- getDim y+    (m3,n3) <- getDim z+    when((m1,n1) /= (m2,n2) || (m1,n1) /= (m3,n3)) $ error $+        printf ("%s <matrix with dim (%d,%d)> <matrix with dim (%d,%d)>:"+                ++ " <matrix with dim (%d,%d)> dimension mismatch")+               str m1 n1 m2 n2 m3 n3+    f x y z+{-# INLINE checkOp3 #-}++vectorOp :: (Storable e)+         => (STVector s e -> ST s ())+         -> STMatrix s e -> ST s ()+vectorOp f x =+    fromMaybe colwise $ maybeWithVectorM x $ \vx -> f vx+  where+    colwise = withColsM x $ \vxs ->+                  sequence_ [ f vx | vx <- vxs ]++vectorOp2 :: (RMatrix m, Storable e, Storable f)+          => (forall v . RVector v => STVector s f -> v e -> ST s ())+          -> STMatrix s f -> m e -> ST s ()+vectorOp2 f dst x =+    fromMaybe colwise $ maybeWithVectorM dst $ \vdst ->+    fromMaybe colwise $ maybeWithVector    x $ \vx ->+        f vdst vx+  where+    colwise = withColsM dst $ \vdsts ->+              withCols   x   $ \vxs ->+                  sequence_ [ f vdst vx | (vdst,vx) <- zip vdsts vxs ]+{-# INLINE vectorOp2 #-}++vectorOp3 :: (RMatrix m1, RMatrix m2, Storable e1, Storable e2, Storable f)+          => (forall v1 v2 . (RVector v1, RVector v2) => +                  STVector s f -> v1 e1 -> v2 e2 -> ST s ())+          -> STMatrix s f -> m1 e1 -> m2 e2 -> ST s ()+vectorOp3 f dst x y =+    fromMaybe colwise $ maybeWithVectorM dst $ \vdst ->+    fromMaybe colwise $ maybeWithVector    x $ \vx ->+    fromMaybe colwise $ maybeWithVector    y $ \vy ->+        f vdst vx vy+  where+    colwise = withColsM dst $ \vdsts ->+              withCols   x   $ \vxs ->+              withCols   y   $ \vys ->+                  sequence_ [ f vdst vx vy+                            | (vdst,vx,vy) <- zip3 vdsts vxs vys ]+{-# INLINE vectorOp3 #-}
+ lib/Numeric/LinearAlgebra/Matrix/Statistics.hs view
@@ -0,0 +1,180 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix.Statistics+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Basic multivariate statistics.+--++module Numeric.LinearAlgebra.Matrix.Statistics (+    defaultCovUplo,++    -- * Immutable interface+    cov,+    covWithMean,+    weightedCov,+    weightedCovWithMean,++    -- * Mutable interface+    covTo,+    covWithMeanTo,+    weightedCovTo,+    weightedCovWithMeanTo,++    ) where++import Control.Monad( when )+import Control.Monad.ST( ST )+import Data.List( foldl' )+import Text.Printf( printf )++import Numeric.LinearAlgebra.Types++import Numeric.LinearAlgebra.Vector( Vector, RVector )+import qualified Numeric.LinearAlgebra.Vector as V++import Numeric.LinearAlgebra.Matrix.Base( Matrix )+import Numeric.LinearAlgebra.Matrix.STBase( STMatrix )+import qualified Numeric.LinearAlgebra.Matrix.STBase as M+import qualified Numeric.LinearAlgebra.Matrix.Herm as M+++-- | Returns the default storage scheme for covariance matrices.+defaultCovUplo :: Uplo+defaultCovUplo = Lower+++-- | Returns the sample covariance matrix as a hermitian matrix with storage+-- scheme equal to 'defaultCovUplo'.  The first argument gives the dimension+-- of the vectors.+cov :: (BLAS3 e)+          => Int -> CovMethod -> [Vector e] -> Herm Matrix e+cov p t xs = M.hermCreate $ do+    c <- Herm uplo `fmap` M.new_ (p,p)+    covTo c t xs+    return c+  where+    uplo = defaultCovUplo++-- | Given the pre-computed mean, returns the sample covariance matrix+-- with storage scheme equal to 'defaultCovUplo'.+covWithMean :: (BLAS3 e)+                  => Vector e -> CovMethod -> [Vector e] -> Herm Matrix e+covWithMean mu t xs = M.hermCreate $ do+    p <- V.getDim mu    +    c <- Herm uplo `fmap` M.new_ (p,p)+    covWithMeanTo c mu t xs+    return c+  where+    uplo = defaultCovUplo++-- | Returns the weighed sample covariance matrix with storage scheme equal+-- to 'defaultCovUplo'. The first argument gives the dimension of the vectors.+weightedCov :: (BLAS3 e)+                  => Int -> CovMethod -> [(Double, Vector e)] -> Herm Matrix e+weightedCov p t wxs = M.hermCreate $ do+    c <- Herm uplo `fmap` M.new_ (p,p)+    weightedCovTo c t wxs+    return c+  where+    uplo = defaultCovUplo++-- | Given the pre-computed mean, returns the weighed sample covariance matrix+-- with storage scheme equal to 'defaultCovUplo'.+weightedCovWithMean :: (BLAS3 e)+                    => Vector e -> CovMethod -> [(Double, Vector e)]+                    -> Herm Matrix e+weightedCovWithMean mu t wxs = M.hermCreate $ do+    p <- V.getDim mu    +    c <- Herm uplo `fmap` M.new_ (p,p)+    weightedCovWithMeanTo c mu t wxs+    return c+  where+    uplo = defaultCovUplo++-- | Computes and copies the sample covariance matrix to the given+-- destination.+covTo :: (RVector v, BLAS3 e)+      => Herm (STMatrix s) e -> CovMethod -> [v e] -> ST s ()+covTo c@(Herm _ a) t xs = do+    (p,_) <- M.getDim a+    mu <- V.new p 1+    V.meanTo mu xs+    covWithMeanTo c mu t xs+    ++-- | Given the pre-computed mean, computes and copies the sample covariance+-- matrix to the given destination.+covWithMeanTo :: (RVector v1, RVector v2, BLAS3 e)+              => Herm (STMatrix s) e -> v1 e -> CovMethod -> [v2 e] -> ST s ()+covWithMeanTo c@(Herm _ a) mu t xs = do+    (ma,na) <- M.getDim a+    p <- V.getDim mu+    +    when ((ma,na) /= (p,p)) $ error $+        printf ("covWithMeanTo"+                ++ " (Herm _ <matrix with dim (%d,%d)>)"+                ++ " <vector with dim %d>"+                ++ " _ _"+                ++ ": dimension mismatch")+               ma na p++    xt <- M.new_ (p,n)+    M.withColsM xt $ \xs' ->+        sequence_ [ V.subTo x' mu x+                  | (x,x') <- zip xs xs'+                  ]+    M.hermRankKUpdateM_ (1/df) NoTrans xt 0 c+  where++    n = length xs+    df = fromIntegral $ case t of { MLCov -> n ; UnbiasedCov -> n - 1 }++-- | Computes and copies the weighed sample covariance matrix to the+-- given destination.+weightedCovTo :: (RVector v, BLAS3 e)+              => Herm (STMatrix s) e -> CovMethod -> [(Double, v e)] -> ST s ()+weightedCovTo c@(Herm _ a) t wxs = do+    (p,_) <- M.getDim a+    mu <- V.new p 1+    V.weightedMeanTo mu wxs+    weightedCovWithMeanTo c mu t wxs+    ++-- | Given the pre-computed mean, computes and copies the weighed sample+-- covariance matrix to the given destination.+weightedCovWithMeanTo :: (RVector v1, RVector v2, BLAS3 e)+                      => Herm (STMatrix s) e+                      -> v1 e -> CovMethod -> [(Double, v2 e)]+                      -> ST s ()+weightedCovWithMeanTo c@(Herm _ a) mu t wxs = do+    (ma,na) <- M.getDim a+    p <- V.getDim mu++    when ((ma,na) /= (p,p)) $ error $+        printf ("weightedCovWithMeanTo"+                ++ " (Herm _ <matrix with dim (%d,%d)>):"+                ++ " <vector with dim %d>"+                ++ " _ _"+                ++ " dimension mismatch")+               ma na p++    xt <- M.new_ (p,n)+    M.withColsM xt $ \xs' ->+        sequence_ [  V.subTo x' mu x+                  >> V.scaleM_ (realToFrac $ sqrt (w / invscale)) x'+                  |  (w,x,x') <- zip3 ws xs xs'+                  ]+    M.hermRankKUpdateM_ 1 NoTrans xt 0 c+  where+    (ws0,xs) = unzip wxs+    w_sum = foldl' (+) 0 ws0+    ws = if w_sum == 0 then ws0 else map (/w_sum) ws0+    w2s_sum = foldl' (+) 0 $ map (^^(2::Int)) ws+    invscale = case t of +                   MLCov -> 1+                   UnbiasedCov -> (1 - w2s_sum)+    n = length ws0
+ lib/Numeric/LinearAlgebra/Matrix/Tri.hs view
@@ -0,0 +1,343 @@+{-# LANGUAGE Rank2Types #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Matrix.Tri+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Triangular views of matrices.+--++module Numeric.LinearAlgebra.Matrix.Tri (+    -- * Immutable interface+    +    -- ** Vector multiplication+    triMulVector,+    +    -- ** Matrix multiplication+    triMulMatrix,+    triMulMatrixWithScale,++    -- ** Vector solving+    triSolvVector,+    +    -- ** Matrix solving+    triSolvMatrix,+    triSolvMatrixWithScale,++    -- * Mutable interface+    triCreate,+    +    -- ** Vector multiplication+    triMulVectorM_,+    +    -- ** Matrix multiplication+    triMulMatrixM_,+    triMulMatrixWithScaleM_,++    -- ** Vector solving+    triSolvVectorM_,++    -- ** Matrix solving+    triSolvMatrixM_,+    triSolvMatrixWithScaleM_,++    ) where++import Control.Monad( when )+import Control.Monad.ST( ST, runST, unsafeIOToST )+import Text.Printf( printf )++import Numeric.LinearAlgebra.Vector( Vector, STVector )+import qualified Numeric.LinearAlgebra.Vector as V+import Numeric.LinearAlgebra.Matrix.Base( Matrix )+import Numeric.LinearAlgebra.Matrix.STBase( STMatrix, RMatrix )+import qualified Numeric.LinearAlgebra.Matrix.STBase as M+import Numeric.LinearAlgebra.Types+import qualified Foreign.BLAS as BLAS+++-- | A safe way to create and work with a mutable Tri Matrix before returning +-- an immutable one for later perusal.+triCreate :: (Storable e)+           => (forall s. ST s (Tri (STMatrix s) e))+           -> Tri Matrix e+triCreate mt = runST $ do+    (Tri u d ma) <- mt+    a <- M.unsafeFreeze ma+    return $ Tri u d a++-- | @triMulVector trans a x@ returns @op(a) * x@, where @op(a)@ is+-- determined by @trans@.+triMulVector :: (BLAS2 e)+             => Trans+             -> Tri Matrix e+             -> Vector e+             -> Vector e+triMulVector trans a x =+    V.create $ do+        x' <- V.newCopy x+        triMulVectorM_ trans a x'+        return x'++-- | @triMulMatrix side a b@+-- returns @alpha * op(a) * b@ when @side@ is @LeftSide@ and+-- @alpha * b * op(a)@ when @side@ is @RightSide@.  Operation+-- @op(a)@ is determined by @trans@.+triMulMatrix :: (BLAS3 e)+              => Side+              -> Trans -> Tri Matrix e+              -> Matrix e+              -> Matrix e+triMulMatrix side trans a b = +    M.create $ do+        b' <- M.newCopy b+        triMulMatrixM_ side trans a b'+        return b'++-- | @triMulMatrixWithScale alpha side trans a b@+-- returns @alpha * op(a) * b@ when @side@ is @LeftSide@ and+-- @alpha * b * op(a)@ when @side@ is @RightSide@.  Operation+-- @op(a)@ is determined by @trans@.+triMulMatrixWithScale :: (BLAS3 e)+                       => e+                       -> Side+                       -> Trans -> Tri Matrix e+                       -> Matrix e+                       -> Matrix e+triMulMatrixWithScale alpha side trans a b =+    M.create $ do+        b' <- M.newCopy b+        triMulMatrixWithScaleM_ alpha side trans a b'+        return b'++-- | @triMulVectorM_ a x@ sets @x := op(a) * x@, where @op(a)@ is determined+-- by @trans@.+triMulVectorM_ :: (RMatrix m, BLAS2 e)+               => Trans -> Tri m e+               -> STVector s e+               -> ST s ()+triMulVectorM_ trans (Tri uplo diag a) x = do+    (ma,na) <- M.getDim a+    nx <- V.getDim x+    let n = nx+    +    when (ma /= na) $ error $+        printf ("triMulVectorM_"+                ++ " _"+                ++ " (Tri _ _ <matrix with dim (%d,%d)>)"+                ++ " _"+                ++ ": matrix is not square")+               ma na+               +    when ((not . and) [ (ma,na) == (n,n)+                      , nx == n+                      ]) $ error $+        printf ("triMulVectorM_"+                ++ " _"+                ++ " (Tri _ _ <matrix with dim (%d,%d)>)"+                ++ " <vector with dim %d>"+                ++ ": dimension mismatch")+               ma na+               nx++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        V.unsafeWith x $ \px ->+            BLAS.trmv uplo trans diag n pa lda px 1+++-- | @triMulMatrixM_ side trans a b@+-- sets @b := op(a) * b@ when @side@ is @LeftSide@ and+-- @b := b * op(a)@ when @side@ is @RightSide@.  Operation+-- @op(a)@ is determined by @trans@.+triMulMatrixM_ :: (RMatrix m, BLAS3 e)+               => Side +               -> Trans -> Tri m e+               -> STMatrix s e+               -> ST s ()+triMulMatrixM_ = triMulMatrixWithScaleM_ 1++-- | @triMulMatrixWithScaleM_ alpha side trans a b@+-- sets @b := alpha * op(a) * b@ when @side@ is @LeftSide@ and+-- @b := alpha * b * op(a)@ when @side@ is @RightSide@.  Operation+-- @op(a)@ is determined by @trans@.+triMulMatrixWithScaleM_ :: (RMatrix m, BLAS3 e)+                         => e+                         -> Side+                         -> Trans -> Tri m e+                         -> STMatrix s e+                         -> ST s ()+triMulMatrixWithScaleM_ alpha side trans (Tri uplo diag a) b = do+    (ma,na) <- M.getDim a+    (mb,nb) <- M.getDim b+    let (m,n) = (mb,nb)+    +    when (ma /= na) $ error $+        printf ("triMulMatrixWithScaleM_"+                ++ " _"+                ++ " _"+                ++ " _"+                ++ " (Tri _ _ <matrix with dim (%d,%d)>)"+                ++ " _"+                ++ ": matrix is not square")+               ma na++    when ((not . and) [ case side of LeftSide  -> (ma,na) == (m,m)+                                     RightSide -> (ma,na) == (n,n)+                      , (mb, nb ) == (m,n)+                      ]) $ error $+        printf ("triMulMatrixWithScaleM_"+                ++ " _"+                ++ " %s"+                ++ " _"+                ++ " (Tri _ _ <matrix with dim (%d,%d)>)"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch")+               (show side)+               ma na+               mb nb++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        M.unsafeWith b $ \pb ldb ->+            BLAS.trmm side uplo trans diag m n alpha pa lda pb ldb+++-- | @triSolvVector trans a x@ returns @op(a) \\ x@, where @op(a)@ is+-- determined by @trans@.+triSolvVector :: (BLAS2 e)+             => Trans+             -> Tri Matrix e+             -> Vector e+             -> Vector e+triSolvVector trans a x =+    V.create $ do+        x' <- V.newCopy x+        triSolvVectorM_ trans a x'+        return x'++-- | @triSolvMatrix side a b@+-- returns @alpha * op(a) \\ b@ when @side@ is @LeftSide@ and+-- @alpha * b * op(a)@ when @side@ is @RightSide@.  Operation+-- @op(a)@ is determined by @trans@.+triSolvMatrix :: (BLAS3 e)+              => Side+              -> Trans -> Tri Matrix e+              -> Matrix e+              -> Matrix e+triSolvMatrix side trans a b = +    M.create $ do+        b' <- M.newCopy b+        triSolvMatrixM_ side trans a b'+        return b'++-- | @triSolvMatrixWithScale alpha side trans a b@+-- returns @alpha * op(a) \\ b@ when @side@ is @LeftSide@ and+-- @alpha * b * op(a)@ when @side@ is @RightSide@.  Operation+-- @op(a)@ is determined by @trans@.+triSolvMatrixWithScale :: (BLAS3 e)+                       => e+                       -> Side+                       -> Trans -> Tri Matrix e+                       -> Matrix e+                       -> Matrix e+triSolvMatrixWithScale alpha side trans a b =+    M.create $ do+        b' <- M.newCopy b+        triSolvMatrixWithScaleM_ alpha side trans a b'+        return b'++-- | @triSolvVectorM_ a x@ sets @x := op(a) \\ x@, where @op(a)@ is determined+-- by @trans@.+triSolvVectorM_ :: (RMatrix m, BLAS2 e)+               => Trans -> Tri m e+               -> STVector s e+               -> ST s ()+triSolvVectorM_ trans (Tri uplo diag a) x = do+    (ma,na) <- M.getDim a+    nx <- V.getDim x+    let n = nx+    +    when (ma /= na) $ error $+        printf ("triSolvVectorM_"+                ++ " _"+                ++ " (Tri _ _ <matrix with dim (%d,%d)>)"+                ++ " _"+                ++ ": matrix is not square")+               ma na+               +    when ((not . and) [ (ma,na) == (n,n)+                      , nx == n+                      ]) $ error $+        printf ("triSolvVectorM_"+                ++ " _"+                ++ " (Tri _ _ <matrix with dim (%d,%d)>)"+                ++ " <vector with dim %d>"+                ++ ": dimension mismatch")+               ma na+               nx++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        V.unsafeWith x $ \px ->+            BLAS.trsv uplo trans diag n pa lda px 1+++-- | @triSolvMatrixM_ side trans a b@+-- sets @b := op(a) \\ b@ when @side@ is @LeftSide@ and+-- @b := b * op(a)@ when @side@ is @RightSide@.  Operation+-- @op(a)@ is determined by @trans@.+triSolvMatrixM_ :: (RMatrix m, BLAS3 e)+               => Side +               -> Trans -> Tri m e+               -> STMatrix s e+               -> ST s ()+triSolvMatrixM_ = triSolvMatrixWithScaleM_ 1++-- | @triSolvMatrixWithScaleM_ alpha side trans a b@+-- sets @b := alpha * op(a) \\ b@ when @side@ is @LeftSide@ and+-- @b := alpha * b * op(a)@ when @side@ is @RightSide@.  Operation+-- @op(a)@ is determined by @trans@.+triSolvMatrixWithScaleM_ :: (RMatrix m, BLAS3 e)+                         => e+                         -> Side+                         -> Trans -> Tri m e+                         -> STMatrix s e+                         -> ST s ()+triSolvMatrixWithScaleM_ alpha side trans (Tri uplo diag a) b = do+    (ma,na) <- M.getDim a+    (mb,nb) <- M.getDim b+    let (m,n) = (mb,nb)+    +    when (ma /= na) $ error $+        printf ("triSolvMatrixWithScaleM_"+                ++ " _"+                ++ " _"+                ++ " _"+                ++ " (Tri _ _ <matrix with dim (%d,%d)>)"+                ++ " _"+                ++ ": matrix is not square")+               ma na++    when ((not . and) [ case side of LeftSide  -> (ma,na) == (m,m)+                                     RightSide -> (ma,na) == (n,n)+                      , (mb, nb ) == (m,n)+                      ]) $ error $+        printf ("triSolvMatrixWithScaleM_"+                ++ " _"+                ++ " %s"+                ++ " _"+                ++ " (Tri _ _ <matrix with dim (%d,%d)>)"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch")+               (show side)+               ma na+               mb nb++    unsafeIOToST $+        M.unsafeWith a $ \pa lda ->+        M.unsafeWith b $ \pb ldb ->+            BLAS.trsm side uplo trans diag m n alpha pa lda pb ldb
+ lib/Numeric/LinearAlgebra/Packed.hs view
@@ -0,0 +1,45 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Packed+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Packed matrices.+--+module Numeric.LinearAlgebra.Packed (+    -- * Immutable packed matrices+    Packed,+    dim,+    +    -- * Read-only packed matrices+    RPacked(..),+    +    -- * Conversions between vectors and packed matrices+    fromVector,+    toVector,++    -- * Mutable interface+    module Numeric.LinearAlgebra.Packed.ST,++    -- * Hermitian views+    module Numeric.LinearAlgebra.Packed.Herm,++    -- * Triangular views+    module Numeric.LinearAlgebra.Packed.Tri,++    -- * Cholesky factorizations+    module Numeric.LinearAlgebra.Packed.Cholesky,++    -- * Basic multivariate statistics+    module Numeric.LinearAlgebra.Packed.Statistics,++    ) where++import Numeric.LinearAlgebra.Packed.Base+import Numeric.LinearAlgebra.Packed.ST hiding ( RPacked(..) )+import Numeric.LinearAlgebra.Packed.Herm+import Numeric.LinearAlgebra.Packed.Tri+import Numeric.LinearAlgebra.Packed.Cholesky+import Numeric.LinearAlgebra.Packed.Statistics
+ lib/Numeric/LinearAlgebra/Packed/Base.hs view
@@ -0,0 +1,388 @@+{-# LANGUAGE DeriveDataTypeable, FlexibleContexts, Rank2Types #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Packed.Base+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Packed matrices.+--+module Numeric.LinearAlgebra.Packed.Base+    where++import Control.Monad( when )+import Control.Monad.ST( ST, RealWorld, runST, unsafeIOToST )+import Data.Typeable( Typeable )+import Foreign( Storable, Ptr )+import Text.Printf( printf )+import Unsafe.Coerce( unsafeCoerce )++import Numeric.LinearAlgebra.Types( Herm(..) )+import Numeric.LinearAlgebra.Vector( Vector, RVector, STVector )+import qualified Numeric.LinearAlgebra.Vector as V+import Foreign.BLAS( BLAS2 )+import qualified Foreign.BLAS as BLAS+++-- | Immutable packed matrices, stored in column-major order.+data Packed e = Packed !Int !(Vector e)+    deriving (Typeable)+    +-- | Mutable packed matrices in the 'ST' monad.+newtype STPacked s e = STPacked { unSTPacked :: Packed e }+    deriving (Typeable)+    +-- | Mutable packed matrices in the 'IO' monad.+type IOPacked = STPacked RealWorld++-- | The dimension of the packed matrix.+dim :: (Storable e) => Packed e -> Int+dim (Packed n _) = n+{-# INLINE dim #-}++-- | Allocate a mutable packed matrix of the given dimension.+new_ :: (Storable e) => Int -> ST s (STPacked s e)+new_ n+    | n < 0 = error $+        printf "new_ %d: negative dimension" n+    | otherwise = do+        mx <- V.new_ (n*(n+1) `div` 2)+        x <- V.unsafeFreeze mx+        return $ STPacked $ Packed n x+{-# INLINE new_ #-}++-- | Create a packed matrix view of a vector, ensurint that the+-- vector has dimension @n * (n+1)/2@, where @n@ is the desired dimension.+fromVector :: (Storable e) => Int -> Vector e -> Packed e+fromVector n x+    | not $ 2 * nx == n * (n+1) = error $+        printf ("fromVector %d <vector with dim %d>: dimension mismatch")+               n nx+    | otherwise =+        unsafeFromVector n x+  where+    nx = V.dim x+{-# INLINE fromVector #-}++-- | Create a packed matrix view of a vector, wihtout checking+-- the dimension of the vector.+unsafeFromVector :: (Storable e) => Int -> Vector e -> Packed e+unsafeFromVector = Packed+{-# INLINE unsafeFromVector #-}++-- | Returns the dimension and underlying vector storage of a+-- packed matrix.+toVector :: (Storable e) => Packed e -> (Int, Vector e)+toVector (Packed n v) = (n,v)+{-# INLINE toVector #-}++{-+-- | Create a packed matrix view of a vector, ensurint that the+-- vector has dimension @n * (n+1)/2@, where @n@ is the desired dimension.+fromSTVector :: (Storable e) => Int -> STVector s e -> STPacked s e+fromSTVector n x+    | not $ 2 * nx == n * (n+1) = error $+        printf ("fromVectorST %d <vector with dim %d>: dimension mismatch")+               n nx+    | otherwise =+        STPacked $ unsafeFromVector n x+  where+    nx = V.dim x+{-# INLINE fromSTVector #-}++-- | Create a packed matrix view of a vector, wihtout checking+-- the dimension of the vector.+unsafeFromSTVector :: (Storable e) => Int -> STVector s e -> STPacked s e+unsafeFromSTVector = STPacked+{-# INLINE unsafeFromSTVector #-}++-- | Returns the dimension and underlying vector storage of a+-- packed matrix.+toSTVector :: (Storable e) => STPacked s e -> (Int, STVector s e)+toSTVector (STPacked n v) = (n,v)+{-# INLINE toSTVector #-}+-}++-- | Read-only packed matrices.+class RPacked p where+    -- | Returns the dimension of the packed matrix.+    getDim :: (Storable e) => p e -> ST s Int++    -- | Perform an action with the underlying vector storage of+    -- the packed matrix.+    withVector :: (Storable e)+               => p e+               -> (forall v . RVector v => v e -> ST s a)+               -> ST s a+    +    -- | Perform an IO action with a pointer to the first element of+    -- the packed matrix.+    unsafeWith :: (Storable e) => p e -> (Ptr e -> IO a) -> IO a++    -- | Converts a read-only packed matrix into an immutable one. This simply+    -- casts the matrix from one type to the other without copying the matrix.+    -- Note that because the matrix is possibly not copied, any subsequent+    -- modifications made to the mutable version of the matrix may be shared+    -- with the immutable version. It is safe to use, therefore, if the mutable+    -- version is never modified after the freeze operation.+    unsafeFreeze :: (Storable e) => p e -> ST s (Packed e)++    unsafeThaw :: (Storable e) => p e -> ST s (STPacked s e)+    ++-- | View a vector as a packed matrix and pass it to a function.+withFromVector :: (RVector v, Storable e)+               => Int+               -> v e+               -> (forall p . RPacked p => p e -> ST s a)+               -> ST s a+withFromVector n v f = do+    iv <- V.unsafeFreeze v+    f $ fromVector n iv+{-# INLINE withFromVector #-}++-- | View a mutable vector as a mutable packed matrix and pass it+-- to a function.+withFromVectorM :: (Storable e)+                => Int+                -> STVector s e+                -> (STPacked s e -> ST s a)+                -> ST s a+withFromVectorM n v f =+    withFromVector n v $ \p -> do+        mp <- unsafeThaw p+        f mp+{-# INLINE withFromVectorM #-}++-- | Perform an action with the underlying vector storage of+-- the mutable packed matrix.  See also 'withVectorView'.+withVectorM :: (Storable e)+            => STPacked s e+            -> (STVector s e -> ST s a)+            -> ST s a+withVectorM mp f =+    withVector mp $ \v -> do+        mv <- V.unsafeThaw v+        f mv+{-# INLINE withVectorM #-}++instance RPacked Packed where+    getDim = return . dim+    {-# INLINE getDim #-}+    withVector (Packed _ v) f = f v+    {-# INLINE withVector #-}+    unsafeWith (Packed _ v) = V.unsafeWith v+    {-# INLINE unsafeWith #-}+    unsafeFreeze = return+    {-# INLINE unsafeFreeze #-}+    unsafeThaw = return . STPacked+    {-# INLINE unsafeThaw #-}++instance RPacked (STPacked s) where+    getDim = getDim . unSTPacked+    {-# INLINE getDim #-}+    withVector = withVector . unSTPacked+    {-# INLINE withVector #-}+    unsafeWith = unsafeWith . unSTPacked+    {-# INLINE unsafeWith #-}+    unsafeFreeze = return . unSTPacked+    {-# INLINE unsafeFreeze #-}+    unsafeThaw p = return $ cast p+      where+        cast :: STPacked s e -> STPacked s' e+        cast = unsafeCoerce+    {-# INLINE unsafeThaw #-}+++-- | Create a new copy of a packed matrix.+newCopy :: (RPacked p, Storable e)+        => p e -> ST s (STPacked s e)+newCopy p = do+    n <- getDim p+    p' <- new_ n+    withVector p $ \v ->+        withVectorM p' $ \v' ->+            V.unsafeCopyTo v' v+    return p'+{-# INLINE newCopy #-}++-- | Converts a mutable packed matrix to an immutable one by taking a complete+-- copy of it.+freeze :: (RPacked p, Storable e) => p e -> ST s (Packed e)+freeze p = do+    p' <- newCopy p+    unsafeFreeze p'++-- | A safe way to create and work with a mutable Packed before returning +-- an immutable one for later perusal.+create :: (Storable e)+       => (forall s. ST s ((STPacked s) e))+       -> Packed e+create stmp = runST $ do+    mp <- stmp+    unsafeFreeze mp+++-- | A safe way to create and work with a mutable Herm Packed before returning +-- an immutable one for later perusal.+hermCreate :: (Storable e)+           => (forall s. ST s (Herm (STPacked s) e))+           -> Herm Packed e+hermCreate stmh = runST $ do+    (Herm u mp) <- stmh+    p <- unsafeFreeze mp+    return $ Herm u p++-- | @hermRank1Update alpha x a@ returns+-- @alpha * x * x^H + a@.+hermRank1Update :: (BLAS2 e)+                => Double -> Vector e -> Herm Packed e -> Herm Packed e+hermRank1Update alpha x (Herm uplo ap) = hermCreate $ do+    hp' <- Herm uplo `fmap` newCopy ap+    hermRank1UpdateM_ alpha x hp'+    return hp'++-- | @hermRank2Update alpha x y a@ returns+-- @alpha * x * y^H + conj(alpha) * y * x^H + a@.+hermRank2Update :: (BLAS2 e)+                => e -> Vector e -> Vector e -> Herm Packed e+                -> Herm Packed e+hermRank2Update alpha x y (Herm uplo ap) = hermCreate $ do+    hp' <- Herm uplo `fmap` newCopy ap+    hermRank2UpdateM_ alpha x y hp'+    return hp'++-- | @hermRank1UpdateM_ alpha x a@ sets+-- @a := alpha * x * x^H + a@.+hermRank1UpdateM_ :: (RVector v, BLAS2 e)+                  => Double -> v e -> Herm (STPacked s) e -> ST s ()+hermRank1UpdateM_ alpha x (Herm uplo a) = do+    nx <- V.getDim x+    na <- getDim a+    let n = nx++    when ((not . and) [ nx == n, na == n ]) $ error $+        printf ("hermRank1UpdateM_ _ <vector with dim %d>"+                 ++ " (Herm _ <packed matrix with dim %d>):"+                 ++ " invalid dimensions") nx na++    unsafeIOToST $+        V.unsafeWith x $ \px ->+        unsafeWith a $ \pa ->+            BLAS.hpr uplo n alpha px 1 pa+++-- | @hermRank2UpdateM_ alpha x y a@ sets+-- @a := alpha * x * y^H + conj(alpha) * y * x^H + a@.+hermRank2UpdateM_ :: (RVector v1, RVector v2, BLAS2 e)+                  => e -> v1 e -> v2 e -> Herm (STPacked s) e -> ST s ()+hermRank2UpdateM_ alpha x y (Herm uplo a) = do+    nx <- V.getDim x+    ny <- V.getDim y+    na <- getDim a+    let n = nx+    +    when ((not . and) [ nx == n, ny == n, na == n ]) $ error $+        printf ("hermRank2UpdateM_ _ <vector with dim %d>"+                 ++ " <vector with dim %d>"+                 ++ " (Herm _ <packed matrix with dim %d>):"+                 ++ " invalid dimensions") nx ny na++    unsafeIOToST $+        V.unsafeWith x $ \px ->+        V.unsafeWith y $ \py ->        +        unsafeWith a $ \pa ->+            BLAS.hpr2 uplo n alpha px 1 py 1 pa+++-- | @hermMulVector a x@ returns @a * x@.+hermMulVector :: (BLAS2 e)+                    => Herm Packed e+                    -> Vector e+                    -> Vector e+hermMulVector a x =+    V.create $ do+        y <- V.new_ (V.dim x)+        hermMulVectorTo y a x+        return y++-- | @hermMulVectorWithScale alpha a x@ retunrs @alpha * a * x@.+hermMulVectorWithScale :: (BLAS2 e)+                       => e+                       -> Herm Packed e+                       -> Vector e+                       -> Vector e+hermMulVectorWithScale alpha a x =+    V.create $ do+        y <- V.new_ (V.dim x)+        hermMulVectorWithScaleTo y alpha a x+        return y+                       +-- | @addHermMulVectorWithScales alpha a x y@+-- returns @alpha * a * x + beta * y@.+addHermMulVectorWithScales :: (BLAS2 e)+                           => e+                           -> Herm Packed e+                           -> Vector e+                           -> e+                           -> Vector e+                           -> Vector e+addHermMulVectorWithScales alpha a x beta y =+    V.create $ do+        y' <- V.newCopy y+        addHermMulVectorWithScalesM_ alpha a x beta y'+        return y'++-- | @hermMulVectorTo dst a x@ sets @dst := a * x@.+hermMulVectorTo :: (RPacked p, RVector v, BLAS2 e)+                => STVector s e+                -> Herm p e+                -> v e+                -> ST s ()+hermMulVectorTo dst = hermMulVectorWithScaleTo dst 1++-- | @hermMulVectorWithScaleTo dst alpha a x@+-- sets @dst := alpha * a * x@.+hermMulVectorWithScaleTo :: (RPacked p, RVector v, BLAS2 e)+                         => STVector s e+                         -> e+                         -> Herm p e+                         -> v e+                         -> ST s ()+hermMulVectorWithScaleTo dst alpha a x =+    addHermMulVectorWithScalesM_ alpha a x 0 dst++-- | @addHermMulVectorWithScalesM_ alpha a x beta y@+-- sets @y := alpha * a * x + beta * y@.+addHermMulVectorWithScalesM_ :: (RPacked p, RVector v, BLAS2 e)+                             => e+                             -> Herm p e+                             -> v e+                             -> e+                             -> STVector s e+                             -> ST s ()+addHermMulVectorWithScalesM_ alpha (Herm uplo a) x beta y = do+    na <- getDim a+    nx <- V.getDim x+    ny <- V.getDim y+    let n = ny++    when ((not . and) [ na == n+                      , nx == n+                      , ny == n+                      ]) $ error $+        printf ("addHermMulVectorWithScalesM_ _"+                ++ " (Herm %s <packed matrix with dim %d>)"+                ++ " %s <vector with dim %d>"+                ++ " _"+                ++ " <vector with dim %d>: dimension mismatch")+               (show uplo) na+               nx ny++    unsafeIOToST $+        unsafeWith a $ \pa ->+        V.unsafeWith x $ \px ->+        V.unsafeWith y $ \py ->+            BLAS.hpmv uplo n alpha pa px 1 beta py 1
+ lib/Numeric/LinearAlgebra/Packed/Cholesky.hs view
@@ -0,0 +1,125 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Packed.Cholesky+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Cholesky factorizations of symmetric (Hermitian) positive-definite+-- matrices.+--++module Numeric.LinearAlgebra.Packed.Cholesky (+    -- * Immutable interface+    cholFactor,+    cholSolveVector,+    cholSolveMatrix,++    -- * Mutable interface+    cholFactorM,+    cholSolveVectorM_,+    cholSolveMatrixM_,+    ) where++import Control.Monad( when )+import Control.Monad.ST( ST, runST, unsafeIOToST )+import Text.Printf( printf )++import qualified Foreign.LAPACK as LAPACK++import Numeric.LinearAlgebra.Types++import Numeric.LinearAlgebra.Packed.Base( Packed, RPacked, STPacked )+import qualified Numeric.LinearAlgebra.Packed.Base as P++import Numeric.LinearAlgebra.Matrix( Matrix, STMatrix )+import qualified Numeric.LinearAlgebra.Matrix as M++import Numeric.LinearAlgebra.Vector( Vector, STVector )+import qualified Numeric.LinearAlgebra.Vector as V++-- | @cholFactor a@ tries to compute the Cholesky+-- factorization of @a@.  If @a@ is positive-definite then the routine+-- returns @Right@ with the factorization.  If the leading minor of order @i@+-- is not positive-definite then the routine returns @Left i@.+cholFactor :: (LAPACK e)+                 => Herm Packed e+                 -> Either Int (Chol Packed e)+cholFactor (Herm uplo a) = runST $ do+    ma <- P.newCopy a+    cholFactorM (Herm uplo ma)+        >>= either (return . Left) (\(Chol uplo' ma') -> do+                a' <- P.unsafeFreeze ma'+                return $ Right (Chol uplo' a')+                )++-- | @cholSolveVector a x@ returns @a \\ x@.+cholSolveVector :: (LAPACK e)+                      => Chol Packed e+                      -> Vector e+                      -> Vector e+cholSolveVector a x = V.create $ do+    x' <- V.newCopy x+    cholSolveVectorM_ a x'+    return x'++-- | @cholSolveMatrix a b@ returns @a \\ b@.+cholSolveMatrix :: (LAPACK e)+                      => Chol Packed e+                      -> Matrix e+                      -> Matrix e+cholSolveMatrix a c = M.create $ do+    c' <- M.newCopy c+    cholSolveMatrixM_ a c'+    return c'++-- | @cholFactorM a@ tries to compute the Cholesky+-- factorization of @a@ in place.  If @a@ is positive-definite then the+-- routine returns @Right@ with the factorization, stored in the same+-- memory as @a@.  If the leading minor of order @i@ is not+-- positive-definite then the routine returns @Left i@.+-- In either case, the original storage of @a@ is destroyed.+cholFactorM :: (LAPACK e)+             => Herm (STPacked s) e+             -> ST s (Either Int (Chol (STPacked s) e))+cholFactorM (Herm uplo a) = do+    n <- P.getDim a+    unsafeIOToST $+        P.unsafeWith a $ \pa -> do+            info <- LAPACK.pptrf uplo n pa+            return $ if info > 0 then Left info+                                 else Right (Chol uplo a)++-- | @cholSolveVectorM_ a x@ sets @x := a \\ x@.+cholSolveVectorM_ :: (LAPACK e, RPacked p)+                  => Chol p e+                  -> STVector s e+                  -> ST s ()+cholSolveVectorM_ a x =+    M.withFromColM x $ \x' ->+        cholSolveMatrixM_ a x'++-- | @cholSolveMatrixM_ a b@ sets @b := a \\ b@.+cholSolveMatrixM_ :: (LAPACK e, RPacked p)+                  => Chol p e+                  -> STMatrix s e+                  -> ST s ()+cholSolveMatrixM_ (Chol uplo a) b = do+    na <- P.getDim a+    (mb,nb) <- M.getDim b+    let (n,nrhs) = (mb,nb)++    when ((not . and) [ na == n+                      , (mb,nb) == (n,nrhs)+                      ]) $ error $+        printf ("cholSolveMatrixM_"+                ++ " (Chol _ <packed matrix with dim %d>)"+                ++ " <matrix with dim (%d,%d)>"+                ++ ": dimension mismatch")+               na mb nb++    unsafeIOToST $+        P.unsafeWith a $ \pa ->+        M.unsafeWith b $ \pb ldb ->+            LAPACK.pptrs uplo n nrhs pa pb ldb
+ lib/Numeric/LinearAlgebra/Packed/Herm.hs view
@@ -0,0 +1,37 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Packed.Herm+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Hermitian views of packed matrices.+--+module Numeric.LinearAlgebra.Packed.Herm (+    -- * Immutable interface++    -- ** Vector multiplication+    hermMulVector,+    hermMulVectorWithScale,+    addHermMulVectorWithScales,+    +    -- ** Updates+    hermRank1Update,+    hermRank2Update,++    -- * Mutable interface+    hermCreate,    ++    -- ** Vector multiplication+    hermMulVectorTo,+    hermMulVectorWithScaleTo,+    addHermMulVectorWithScalesM_,+    +    -- ** Updates+    hermRank1UpdateM_,+    hermRank2UpdateM_,++    ) where++import Numeric.LinearAlgebra.Packed.Base
+ lib/Numeric/LinearAlgebra/Packed/ST.hs view
@@ -0,0 +1,39 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Packed.ST+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Mutable packed matrices.+--+module Numeric.LinearAlgebra.Packed.ST (+    -- * Mutable packed matrices+    STPacked,+    IOPacked,+    create,++    -- * Read-only packed matrices+    RPacked(..),++    -- * Conversions between mutable and immutable packed matrices+    freeze,++    -- * Creating new packed matrices+    new_,+    +    -- * Copying matrices+    newCopy,++    -- * Vector views of packed matrices+    withVectorM,+    +    -- * Packed matrix views of vectors+    withFromVector,+    withFromVectorM,+    +    ) where++import Numeric.LinearAlgebra.Packed.Base+
+ lib/Numeric/LinearAlgebra/Packed/Statistics.hs view
@@ -0,0 +1,188 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Packed.Statistics+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Basic multivariate statistics.+--++module Numeric.LinearAlgebra.Packed.Statistics (+    defaultCovUplo,++    -- * Immutable interface+    cov,+    covWithMean,+    weightedCov,+    weightedCovWithMean,++    -- * Mutable interface+    covTo,+    covWithMeanTo,+    weightedCovTo,+    weightedCovWithMeanTo,++    ) where++import Control.Monad( when )+import Control.Monad.ST( ST )+import Data.List( foldl' )+import Text.Printf( printf )++import Numeric.LinearAlgebra.Types+import Numeric.LinearAlgebra.Packed.Base( Packed, STPacked )+import qualified Numeric.LinearAlgebra.Packed.Base as P++import Numeric.LinearAlgebra.Vector( Vector, RVector )+import qualified Numeric.LinearAlgebra.Vector as V++import qualified Numeric.LinearAlgebra.Matrix as M+++-- | Returns the default storage scheme for covariance matrices.+defaultCovUplo :: Uplo+defaultCovUplo = Lower++-- | Returns the sample covariance matrix hermitian matrix (in packed form)+-- with storage scheme equal to 'defaultCovUplo'.  The first argument gives+-- the dimension of the vectors.+cov :: (BLAS2 e)+    => Int -> CovMethod -> [Vector e] -> Herm Packed e+cov p t xs = P.hermCreate $ do+    c <- Herm uplo `fmap` P.new_ p+    covTo c t xs+    return c+  where+    uplo = defaultCovUplo++-- | Given the pre-computed mean, returns the sample covariance matrix+-- (in packed form) with storage scheme equal to 'defaultCovUplo'.+covWithMean :: (BLAS2 e)+            => Vector e -> CovMethod -> [Vector e] -> Herm Packed e+covWithMean mu t xs = P.hermCreate $ do+    c <- Herm uplo `fmap` P.new_ p+    covWithMeanTo c mu t xs+    return c+  where+    p = V.dim mu+    uplo = defaultCovUplo++-- | Returns the weighed sample covariance matrix (in packed form) with+-- storage scheme equal to 'defaultCovUplo'. The first argument gives the+-- dimension of the vectors.+weightedCov :: (BLAS2 e)+            => Int -> CovMethod -> [(Double, Vector e)] -> Herm Packed e+weightedCov p t wxs = P.hermCreate $ do+    c <- Herm uplo `fmap` P.new_ p+    weightedCovTo c t wxs+    return c+  where+    uplo = defaultCovUplo++-- | Given the pre-computed mean, returns the weighed sample covariance matrix+-- (in packed form) with storage scheme equal to 'defaultCovUplo'.+weightedCovWithMean :: (BLAS2 e)+                    => Vector e -> CovMethod -> [(Double, Vector e)]+                    -> Herm Packed e+weightedCovWithMean mu t wxs = P.hermCreate $ do+    c <- Herm uplo `fmap` P.new_ p+    weightedCovWithMeanTo c mu t wxs+    return c+  where+    p = V.dim mu+    uplo = defaultCovUplo++-- | Computes and copies the sample covariance matrix (in packed form)+-- to the given destination.+covTo :: (RVector v, BLAS2 e)+      => Herm (STPacked s) e -> CovMethod -> [v e] -> ST s ()+covTo c@(Herm _ a) t xs = do+    p <- P.getDim a+    mu <- V.new p 1+    V.meanTo mu xs+    covWithMeanTo c mu t xs+++-- | Given the pre-computed mean, computes and copies the sample covariance+-- matrix (in packed form) to the given destination.+covWithMeanTo :: (RVector v1, RVector v2, BLAS2 e)+              => Herm (STPacked s) e+              -> v1 e -> CovMethod -> [v2 e]+              -> ST s ()+covWithMeanTo c@(Herm _ a) mu t xs = do+    pa <- P.getDim a+    p <- V.getDim mu   +     +    when (pa /= p) $ error $+        printf ("covWithMeanTo"+                ++ " (Herm _ <packed matrix with dim %d>)"+                ++ " <vector with dim %d>"+                ++ " _ _"+                ++ ": dimension mismatch")+               pa p++    xt <- M.new_ (p,n)+    M.withColsM xt $ \xs' ->+        sequence_ [ V.subTo x' mu x+                  | (x,x') <- zip xs xs'+                  ]+    P.withVectorM a V.clear+    M.withColsM xt $ \xs' ->+        sequence_ [ P.hermRank1UpdateM_ scale x' c | x' <- xs' ]+  where+    n = length xs+    df = fromIntegral $ case t of { MLCov -> n ; UnbiasedCov -> n - 1 }+    scale = 1/df+++-- | Computes and copies the weighed sample covariance matrix (in packed+-- form) to the given destination.+weightedCovTo :: (RVector v, BLAS2 e)+              => Herm (STPacked s) e+              -> CovMethod -> [(Double, v e)] +              -> ST s ()+weightedCovTo c@(Herm _ a) t wxs = do+    p <- P.getDim a+    mu <- V.new p 1+    V.weightedMeanTo mu wxs+    weightedCovWithMeanTo c mu t wxs+++-- | Given the pre-computed mean, computes and copies the weighed sample+-- covariance matrix (in packed form) to the given destination.+weightedCovWithMeanTo :: (RVector v1, RVector v2, BLAS2 e)+                      => Herm (STPacked s) e+                      -> v1 e -> CovMethod -> [(Double, v2 e)]+                      -> ST s ()+weightedCovWithMeanTo c@(Herm _ a) mu t wxs = do+    pa <- P.getDim a+    p <- V.getDim mu+    +    when (pa /= p) $ error $+        printf ("weightedCovWithMeanTo"+                ++ " (Herm _ <packed matrix with dim %d>)"+                ++ " <vector with dim %d>"+                ++ " _ _"+                ++ ": dimension mismatch")+               pa p++    xt <- M.new_ (p,n)+    M.withColsM xt $ \xs' ->+        sequence_ [  V.subTo x' mu x+                  >> V.scaleM_ (realToFrac $ sqrt (w / invscale)) x'+                  |  (w,x,x') <- zip3 ws xs xs'+                  ]+    P.withVectorM a V.clear                      +    M.withCols xt $ \xs' ->+        sequence_ [ P.hermRank1UpdateM_ 1 x' c | x' <- xs' ]+  where+    (ws0,xs) = unzip wxs+    w_sum = foldl' (+) 0 ws0+    ws = if w_sum == 0 then ws0 else map (/w_sum) ws0+    w2s_sum = foldl' (+) 0 $ map (^^(2::Int)) ws+    invscale = case t of +                   MLCov -> 1+                   UnbiasedCov -> (1 - w2s_sum)+    n = length ws0
+ lib/Numeric/LinearAlgebra/Packed/Tri.hs view
@@ -0,0 +1,130 @@+{-# LANGUAGE Rank2Types #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Packed.Tri+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Triangular views of packed matrices.+--++module Numeric.LinearAlgebra.Packed.Tri (+    -- * Immutable interface+    +    -- ** Vector multiplication+    triMulVector,+    +    -- ** Vector solving+    triSolvVector,+    +    -- * Mutable interface+    triCreate,+    +    -- ** Vector multiplication+    triMulVectorM_,+    +    -- ** Vector solving+    triSolvVectorM_,++    ) where++import Control.Monad( when )+import Control.Monad.ST( ST, runST, unsafeIOToST )+import Text.Printf( printf )++import Numeric.LinearAlgebra.Vector( Vector, STVector )+import qualified Numeric.LinearAlgebra.Vector as V+import Numeric.LinearAlgebra.Packed.Base( Packed, RPacked, STPacked )+import qualified Numeric.LinearAlgebra.Packed.Base as P+import Numeric.LinearAlgebra.Types+import qualified Foreign.BLAS as BLAS+++-- | A safe way to create and work with a mutable Tri Packed before returning +-- an immutable one for later perusal.+triCreate :: (Storable e)+          => (forall s. ST s (Tri (STPacked s) e))+          -> Tri Packed e+triCreate mt = runST $ do+    (Tri u d ma) <- mt+    a <- P.unsafeFreeze ma+    return $ Tri u d a++-- | @triMulVector trans a x@ returns @op(a) * x@, where @op(a)@ is+-- determined by @trans@.+triMulVector :: (BLAS2 e)+             => Trans+             -> Tri Packed e+             -> Vector e+             -> Vector e+triMulVector trans a x =+    V.create $ do+        x' <- V.newCopy x+        triMulVectorM_ trans a x'+        return x'++-- | @triMulVectorM_ a x@ sets @x := op(a) * x@, where @op(a)@ is determined+-- by @trans@.+triMulVectorM_ :: (RPacked p, BLAS2 e)+               => Trans -> Tri p e+               -> STVector s e+               -> ST s ()+triMulVectorM_ trans (Tri uplo diag a) x = do+    na <- P.getDim a+    nx <- V.getDim x+    let n = nx+    +    when (nx /= n) $ error $+        printf ("triMulVectorM_"+                ++ " _"+                ++ " (Tri _ _ <packed matrix with dim %d>)"+                ++ " <vector with dim %d>"+                ++ ": dimension mismatch")+               na+               nx++    unsafeIOToST $+        P.unsafeWith a $ \pa ->+        V.unsafeWith x $ \px ->+            BLAS.tpmv uplo trans diag n pa px 1+++-- | @triSolvVector trans a x@ returns @op(a) \\ x@, where @op(a)@ is+-- determined by @trans@.+triSolvVector :: (BLAS2 e)+             => Trans+             -> Tri Packed e+             -> Vector e+             -> Vector e+triSolvVector trans a x =+    V.create $ do+        x' <- V.newCopy x+        triSolvVectorM_ trans a x'+        return x'++-- | @triSolvVectorM_ a x@ sets @x := op(a) \\ x@, where @op(a)@ is determined+-- by @trans@.+triSolvVectorM_ :: (RPacked p, BLAS2 e)+               => Trans -> Tri p e+               -> STVector s e+               -> ST s ()+triSolvVectorM_ trans (Tri uplo diag a) x = do+    na <- P.getDim a+    nx <- V.getDim x+    let n = nx+    +    when (nx /= n) $ error $+        printf ("triMulVectorM_"+                ++ " _"+                ++ " (Tri _ _ <packed matrix with dim %d>)"+                ++ " <vector with dim %d>"+                ++ ": dimension mismatch")+               na+               nx++    unsafeIOToST $+        P.unsafeWith a $ \pa ->+        V.unsafeWith x $ \px ->+            BLAS.tpsv uplo trans diag n pa px 1
+ lib/Numeric/LinearAlgebra/Types.hs view
@@ -0,0 +1,92 @@+{-# OPTIONS_HADDOCK hide #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Types+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Basic type classes and enums.+--++module Numeric.LinearAlgebra.Types (++    -- * Matrix views+    Herm(..),+    Tri(..),++    -- * Matrix factorization views+    Chol(..),++    -- * Vector math types+    VNum,+    VFractional,+    VFloating,++    -- * BLAS element types+    BLAS1,+    BLAS2,+    BLAS3,+    +    -- * LAPACK element types+    LAPACK,+    +    -- * Enums+    Trans(..),+    Uplo(..),+    Side(..),+    Diag(..),++    -- * Algorithm-specific parameters+    CovMethod(..),++    -- * Re-export of Complex from Data.Complex+    module Data.Complex,++    -- * Re-export of Storable from Foreign.Storable+    module Foreign.Storable,+        +    ) where++import Foreign.VMath( VNum, VFractional, VFloating )+import Foreign.BLAS( Trans(..), Uplo(..), Side(..), Diag(..), BLAS1, BLAS2, BLAS3 )+import Foreign.LAPACK( LAPACK )+import Data.Complex( Complex(..) )+import Foreign.Storable( Storable() )++-- | A hermitian view of an underlying matrix.  The view can either be+-- of the upper or lower triangular part of the matrix.  The type arguments+-- are as follows:+--+--     * @m@: the underlyting matrix type.+--+--     * @e@: the element type of the matrix.+--+data Herm m e = Herm Uplo (m e) deriving (Show)++-- | A triangular view of an underlying matrix.  The view can either be+-- upper or lower triangular, with a unit or non-unit diagonal.  The type+-- arguments are as follows:+--+--     * @m@: the underlyting matrix type.+--+--     * @e@: the element type of the matrix.+--+data Tri m e = Tri Uplo Diag (m e) deriving (Show)++-- | A Cholesky decomposition view of a matrix.+data Chol m e = Chol Uplo (m e) deriving (Show)++-- | The method of scaling the sample covariance matrix.+data CovMethod =+      UnbiasedCov -- ^ This is the default behavior. Corresponds to a+                  -- scaling of @n/(n-1)@ in the unweighed case, and+                  -- @1/(1 - \\sum w_i^2)@ in the weighted case, where @w_i@+                  -- is the normalized weight. Note the unweighted and+                  -- weighted cases agree when @w_i = 1/n@.+                  +    | MLCov       -- ^ Returns the centered second moment matrix without+                  -- scaling the result.+    deriving (Eq, Show)+
+ lib/Numeric/LinearAlgebra/Vector.hs view
@@ -0,0 +1,302 @@+{-# LANGUAGE Rank2Types #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Vector+-- Copyright  : Copyright (c) , Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Immutable dense vectors.++module Numeric.LinearAlgebra.Vector (+    -- * Immutable vectors+    Vector,+    dim,+    +    -- * Vector construction+    fromList,+    zero,+    constant,++    -- * Accessing vectors+    at,+    unsafeAt,+    indices,+    elems,+    assocs,++    -- * Incremental vector updates+    update,+    unsafeUpdate,+    accum,+    unsafeAccum,++    -- * Derived vectors+    map,+    zipWith,+    unsafeZipWith,+    concat,++    -- * Vector views+    slice,+    unsafeSlice,+    splitAt,+    drop,+    take,++    -- * Vector properties+    sumAbs,    +    norm2,+    whichMaxAbs,+    dot,+    unsafeDot,+    kronecker,++    -- * Vector math operations+    -- ** Num+    add,+    addWithScale,+    sub,+    scale,+    mul,+    negate,+    conjugate,+    abs,+    signum,++    -- ** Fractional+    div,+    recip,        ++    -- ** Floating+    sqrt,+    exp,+    log,+    pow,+    sin,+    cos,+    tan,+    asin,+    acos,+    atan,+    sinh,+    cosh,+    tanh,+    asinh,+    acosh,+    atanh,+    +    -- * Conversions between foreign pointers+    unsafeFromForeignPtr,+    unsafeToForeignPtr,+    +    -- * Mutable interface+    module Numeric.LinearAlgebra.Vector.ST,+    +    -- * Basic multivariate statistics+    module Numeric.LinearAlgebra.Vector.Statistics,++    ) where++import Prelude( Int, Double, ($), (*), return )+import Control.Monad.ST( runST, ST )+import Foreign( Storable )+import Foreign.BLAS( BLAS1, BLAS2 )+import Foreign.VMath( VNum, VFractional, VFloating )++import Numeric.LinearAlgebra.Vector.Base+import Numeric.LinearAlgebra.Vector.ST+import Numeric.LinearAlgebra.Vector.Statistics++infixr 8 `pow`+infixl 7 `div`+infixl 7 `mul`, `scale`, `kronecker`+infixl 6 `add`, `sub`+++-- | Compute the sum of absolute values of entries in the vector.+sumAbs :: (BLAS1 e) => Vector e -> Double+sumAbs v = runST $ getSumAbs v+{-# INLINE sumAbs #-}++-- | Compute the 2-norm (Euclidean norm) of a vector.+norm2 :: (BLAS1 e) => Vector e -> Double+norm2 v = runST $ getNorm2 v+{-# INLINE norm2 #-}++-- | Get the index and norm of the element with absulte value.  Not valid +-- if any of the vector entries are @NaN@.  Raises an exception if the +-- vector has length @0@.+whichMaxAbs :: (BLAS1 e) => Vector e -> (Int, e)+whichMaxAbs v = runST $ getWhichMaxAbs v+{-# INLINE whichMaxAbs #-}++-- | Compute the dot product of two vectors.+dot :: (BLAS1 e) => Vector e -> Vector e -> e+dot v v' = runST $ getDot v v'+{-# INLINE dot #-}++unsafeDot :: (BLAS1 e) => Vector e -> Vector e -> e+unsafeDot v v' = runST $ unsafeGetDot v v'+{-# INLINE unsafeDot #-}++-- | Compute the kronecker product of two vectors.+kronecker :: (BLAS2 e) => Vector e -> Vector e -> Vector e+kronecker x y = create $ do+    z <- new_ (dim x * dim y)+    kroneckerTo z x y+    return z++-- | @add x y@ returns @x + y@.+add :: (VNum e) => Vector e -> Vector e -> Vector e+add = result2 addTo++-- | @sub x y@ returns @x - y@.+sub :: (VNum e) => Vector e -> Vector e -> Vector e+sub = result2 subTo++-- | @scale k x@ returns @k * x@.+scale :: (BLAS1 e) => e -> Vector e -> Vector e+scale k x = create $ do+    x' <- newCopy x+    scaleM_ k x'+    return x'++-- | @addWithScale alpha x y@ return @alpha * x + y@.+addWithScale :: (BLAS1 e) => e -> Vector e -> Vector e -> Vector e+addWithScale alpha x y = create $ do+    y' <- newCopy y+    addWithScaleM_ alpha x y'+    return y'++-- | @mul x y@ returns @x * y@.+mul :: (VNum e) => Vector e -> Vector e -> Vector e+mul = result2 mulTo++-- | @negate x@ returns @-x@.+negate :: (VNum e) => Vector e -> Vector e+negate = result negateTo++-- | @conjugate x@ returns @conjugate(x)@.+conjugate :: (VNum e) => Vector e -> Vector e+conjugate = result conjugateTo++-- | @abs x@ returns @abs(x)@.+abs :: (VNum e) => Vector e -> Vector e+abs = result absTo++-- | @signum x@ returns @signum(x)@.+signum :: (VNum e) => Vector e -> Vector e+signum = result signumTo++-- | @div x y@ returns @x / y@.+div :: (VFractional e) => Vector e -> Vector e -> Vector e+div = result2 divTo++-- | @recip x y@ returns @1 / x@.+recip :: (VFractional e) => Vector e -> Vector e+recip = result recipTo++-- | @sqrt x@ returns @sqrt(x)@.+sqrt :: (VFloating e) => Vector e -> Vector e+sqrt = result sqrtTo++-- | @exp x@ returns @exp(x)@.+exp :: (VFloating e) => Vector e -> Vector e+exp = result expTo++-- | @log x@ returns @log(x)@.+log :: (VFloating e) => Vector e -> Vector e+log = result logTo++-- | @pow x y@ returns @x ** y@.+pow :: (VFloating e) => Vector e -> Vector e -> Vector e+pow = result2 powTo++-- | @sin x@ returns @sin(x)@.+sin :: (VFloating e) => Vector e -> Vector e+sin = result sinTo++-- | @cos x@ returns @cos(x)@.+cos :: (VFloating e) => Vector e -> Vector e+cos = result cosTo++-- | @tan x@ returns @tan(x)@.+tan :: (VFloating e) => Vector e -> Vector e+tan = result tanTo++-- | @asin x@ returns @asin(x)@.+asin :: (VFloating e) => Vector e -> Vector e+asin = result asinTo++-- | @acos x@ returns @acos(x)@.+acos :: (VFloating e) => Vector e -> Vector e+acos = result acosTo++-- | @atan x@ returns @atan(x)@.+atan :: (VFloating e) => Vector e -> Vector e+atan = result atanTo++-- | @sinh x@ returns @sinh(x)@.+sinh :: (VFloating e) => Vector e -> Vector e+sinh = result sinhTo++-- | @cosh x@ returns @cosh(x)@.+cosh :: (VFloating e) => Vector e -> Vector e+cosh = result coshTo++-- | @tanh x@ returns @tanh(x)@.+tanh :: (VFloating e) => Vector e -> Vector e+tanh = result tanhTo++-- | @asinh x@ returns @asinh(x)@.+asinh :: (VFloating e) => Vector e -> Vector e+asinh = result asinhTo++-- | @acosh x@ returns @acosh(x)@.+acosh :: (VFloating e) => Vector e -> Vector e+acosh = result acoshTo++-- | @atanh x@ returns @atanh(x)@.+atanh :: (VFloating e) => Vector e -> Vector e+atanh = result atanhTo+++result :: (Storable e, Storable f)+       => (forall s . STVector s f -> Vector e -> ST s a)+       -> Vector e+       -> Vector f+result f v = create $ newResult f v+{-# INLINE result #-}++result2 :: (Storable e, Storable f, Storable g)+        => (forall s . STVector s g -> Vector e -> Vector f -> ST s a)+        -> Vector e+        -> Vector f+        -> Vector g+result2 f v1 v2 = create $ newResult2 f v1 v2+{-# INLINE result2 #-}++newResult :: (RVector v, Storable e, Storable f)+          => (STVector s f -> v e -> ST s a)+          -> v e+          -> ST s (STVector s f)+newResult f v = do+    n <- getDim v+    z <- new_ n+    _ <- f z v+    return z+{-# INLINE newResult #-}++newResult2 :: (RVector v1, RVector v2, Storable e, Storable f, Storable g)+           => (STVector s g -> v1 e -> v2 f -> ST s a)+           -> v1 e+           -> v2 f+           -> ST s (STVector s g)+newResult2 f v1 v2 = do+    n <- getDim v1+    z <- new_ n+    _ <- f z v1 v2+    return z+{-# INLINE newResult2 #-}
+ lib/Numeric/LinearAlgebra/Vector/Base.hs view
@@ -0,0 +1,288 @@+{-# LANGUAGE Rank2Types #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# OPTIONS_HADDOCK hide #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Vector.Base+-- Copyright  : Copyright (c) , Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--++module Numeric.LinearAlgebra.Vector.Base (+    Vector,+    dim,+    +    fromList,+    zero,+    constant,+    +    at,+    unsafeAt,+    +    indices,+    elems,+    assocs,+    +    update,+    unsafeUpdate,+    accum,+    unsafeAccum,+    +    map,+    zipWith,+    unsafeZipWith,+    concat,+    +    slice,+    splitAt,+    drop,+    take,+    +    unsafeSlice,+    unsafeFromForeignPtr,+    unsafeToForeignPtr,+    unsafeWith,+    ) where++import Prelude hiding ( concat, drop, map, read, splitAt, take, zipWith, +    negate, signum, abs, div, recip, sqrt, exp, log, sin, cos, tan, asin,+    acos, atan, sinh, cosh, tanh, asinh, acosh, atanh )+import qualified Prelude as P++import Data.AEq( AEq(..) )+import Data.Vector.Storable( Vector )+import qualified Data.Vector.Storable as Vector+import Foreign( ForeignPtr, Ptr, Storable )+import Text.Printf( printf )+++-- | The dimension of a vector.  This is equal to the number of+-- elements in the vector.                          +dim :: (Storable e) => Vector e -> Int+dim = Vector.length+{-# INLINE dim #-}++-- | Create a vector of the given dimension with elements initialized+-- to the values from the list.  The list must have at least as many+-- elements as the dimension of the vector; elements in the list past+-- the dimension of the vector are discarded.+fromList :: (Storable e) => Int -> [e] -> Vector e+fromList n es = Vector.fromListN n $ es ++ repeat (error msg)+  where+    msg = printf ( "fromList"+                 ++ " %d"+                 ++ " <list with length less than %d>"+                 ++ ": not enough elements"+                 ) n n+{-# INLINE fromList #-}++-- | Create a zero vector of the given dimension with all elements initialized+-- to the given zero.+zero :: (Storable e, Num e) => Int -> Vector e+zero n = constant n 0+{-# INLINE zero #-}++-- | Create a vector of the given dimension with all elements initialized+-- to the given value.+constant :: (Storable e) => Int -> e -> Vector e+constant n e+    | n < 0 = error $+        printf ("constant %d: negative dimension") n+    | otherwise =+        Vector.fromListN n $ repeat e+{-# INLINE constant #-}++-- | Returns the element of a vector at the specified index.+at :: (Storable e) => Vector e -> Int -> e+at v i+    | i < 0 || i >= n = error $+        printf "at <vector with dim %d> %d: invalid index" n i+    | otherwise =+        unsafeAt v i+  where+    n = dim v+{-# INLINE at #-}++-- | Same as 'at' but does not range-check index.+unsafeAt :: (Storable e) => Vector e -> Int -> e+unsafeAt v i = Vector.unsafeIndex v i+{-# INLINE unsafeAt #-}++-- | Get the indices of the elements in the vector, @[ 0..n-1 ]@, where+-- @n@ is the dimension of the vector.+indices :: (Storable e) => Vector e -> [Int]+indices x = [ 0..n-1 ] where n = dim x+{-# INLINE indices #-}++-- | Returns a list of the elements of a vector, in the same order as their+-- indices.+elems :: (Storable e) => Vector e -> [e]+elems = Vector.toList+{-# INLINE elems #-}++-- | Returns the contents of a vector as a list of associations.+assocs :: (Storable e) => Vector e -> [(Int,e)]+assocs x = zip (indices x) (elems x)+{-# INLINE assocs #-}++-- | Same as 'update' but does not range-check indices.+unsafeUpdate :: (Storable e) => Vector e -> [(Int,e)] -> Vector e+unsafeUpdate = Vector.unsafeUpd++-- | Create a new vector by replacing the values at the specified indices.+update :: (Storable e) => Vector e -> [(Int,e)] -> Vector e+update = (Vector.//)++-- | @accum f@ takes a vector and an association list and accumulates+-- pairs from the list into the vector with the accumulating function @f@.+accum :: (Storable e)+      => (e -> e' -> e) +            -> Vector e+            -> [(Int, e')]+            -> Vector e+accum = Vector.accum+{-# INLINE accum #-}++-- | Same as 'accum' but does not range-check indices.+unsafeAccum :: (Storable e)+            => (e -> e' -> e)+            -> Vector e+            -> [(Int, e')]+            -> Vector e+unsafeAccum = Vector.unsafeAccum+{-# INLINE unsafeAccum #-}++-- | Construct a new vector by applying a function to every element of+-- a vector.+map :: (Storable e, Storable e')+    => (e -> e')+    -> Vector e+    -> Vector e'+map = Vector.map+{-# INLINE map #-}++-- | Construct a new vector by applying a function to every pair of elements+-- of two vectors.  The two vectors must have identical dimensions.+zipWith :: (Storable e, Storable e', Storable f)+        => (e -> e' -> f)+        -> Vector e+        -> Vector e'+        -> Vector f+zipWith f v v'+    | n /= n' = error $+        printf ("zipWith <function> <vector with dim %d>"+                ++ " <vector with dim %d>: lengths differ") n n'+    | otherwise =+        unsafeZipWith f v v'+  where+    n  = dim v+    n' = dim v'+{-# INLINE zipWith #-}++-- | Same as 'zipWith' but does not check if the input vectors+-- have the same dimensions.+unsafeZipWith :: (Storable e, Storable e', Storable f)+              => (e -> e' -> f)+              -> Vector e+              -> Vector e'+              -> Vector f+unsafeZipWith = Vector.zipWith+{-# INLINE unsafeZipWith #-}++-- | Create a new vector by concatenating a list of vectors.+concat :: (Storable e) => [Vector e] -> Vector e+concat = Vector.concat+{-# INLINE concat #-}++-- | Same as 'slice' but does not range-change indices.+unsafeSlice :: (Storable e)+            => Int+            -> Int+            -> Vector e+            -> Vector e            +unsafeSlice = Vector.unsafeSlice+{-# INLINE unsafeSlice #-}++-- | @slice i n v@ creates a subvector view of @v@ starting at+-- index @i@ and having dimension @n@.+slice :: (Storable e)+      => Int+      -> Int+      -> Vector e+      -> Vector e            +slice i n' v+    | i < 0 || n' < 0 || i + n' > n = error $+        printf "slice %d %d <vector with dim %d>: index out of range"+               i n' n+    | otherwise =+        unsafeSlice i n' v+  where+    n = dim v+{-# INLINE slice #-}++-- | @drop i v@ is equal to @slice i (n-i) v@, where @n@ is+-- the dimension of the vector.+drop :: (Storable e) => Int -> Vector e -> Vector e+drop i v = slice i (dim v - i) v+{-# INLINE drop #-}++-- | @take n v@ is equal to @slice 0 n v@.+take :: (Storable e) => Int -> Vector e -> Vector e+take n v = slice 0 n v+{-# INLINE take #-}++-- | Split a vector into two blocks and returns views into the blocks.  If+-- @(v1, v2) = splitAt i v@, then+-- @v1 = slice 0 i v@ and+-- @v2 = slice i (dim v - i) v@.+splitAt :: (Storable e) => Int -> Vector e -> (Vector e, Vector e)+splitAt i v +    | i < 0 || i > n = error $+        printf "splitAt %d <vector with dim %d>: invalid index" i n+    | otherwise = let+        v1 = unsafeSlice 0 i     v+        v2 = unsafeSlice i (n-i) v+        in (v1, v2)+  where+    n = dim v++-- | Create a vector from a 'ForeignPtr' with an offset and a dimension. The+-- data may not be modified through the ForeignPtr afterwards.+unsafeFromForeignPtr :: (Storable e)+                     => ForeignPtr e -- ^ pointer+                     -> Int	         -- ^ offset+                     -> Int	         -- ^ dimension+                     -> Vector e+unsafeFromForeignPtr = Vector.unsafeFromForeignPtr+{-# INLINE unsafeFromForeignPtr #-}++-- | Yield the underlying 'ForeignPtr' together with the offset to the data+-- and its length. The data may not be modified through the 'ForeignPtr'.+unsafeToForeignPtr :: (Storable e) => Vector e -> (ForeignPtr e, Int, Int)+unsafeToForeignPtr = Vector.unsafeToForeignPtr+{-# INLINE unsafeToForeignPtr #-}++-- | Pass a pointer to the vector's data to the 'IO' action. The data may+-- not be modified through the 'Ptr'.+unsafeWith :: (Storable e) => Vector e -> (Ptr e -> IO a) -> IO a+unsafeWith = Vector.unsafeWith+++instance (Storable e, AEq e) => AEq (Vector e) where+    (===) = compareWith (===)+    {-# INLINE (===) #-}+    (~==) = compareWith (~==)+    {-# INLINE (~==) #-}++compareWith :: (Storable e, Storable e')+            => (e -> e' -> Bool)+            -> Vector e+            -> Vector e'+            -> Bool+compareWith cmp v v' =+    dim v == dim v'+    && and (P.zipWith cmp (elems v) (elems v'))+{-# INLINE compareWith #-}+
+ lib/Numeric/LinearAlgebra/Vector/ST.hs view
@@ -0,0 +1,115 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Vector.ST+-- Copyright  : Copyright (c) , Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Mutable vectors in the ST monad.++module Numeric.LinearAlgebra.Vector.ST (+    -- * Mutable vectors+    STVector,+    IOVector,+    create,+    +    -- * Read-only vectors+    RVector(..),+    +    -- * Creating new vectors+    new_,+    new,+    +    -- * Copying vectors+    newCopy,+    copyTo,+    swap,++    -- * Reading and writing vector elements+    read,+    write,+    modify,+    getIndices,+    getElems,+    getElems',+    getAssocs,+    getAssocs',+    setElems,+    setAssocs,    +    clear,++    -- * List-like operations+    mapTo,+    zipWithTo,++    -- * Vector linear algebra+    getSumAbs,+    getNorm2,+    getWhichMaxAbs,+    getDot,+    scaleM_,+    addWithScaleM_,+    kroneckerTo,+    +    -- * Vector views    +    withSlice,+    withDrop,+    withTake,+    withSplitAt,+    +    withSliceM,+    withDropM,+    withTakeM,+    withSplitAtM,+    +    -- * Vector math operations+    -- ** Num+    addTo,+    subTo,+    mulTo,+    negateTo,+    conjugateTo,+    absTo,+    signumTo,++    -- ** Fractional+    divTo,+    recipTo,        ++    -- ** Floating+    sqrtTo,+    expTo,+    logTo,+    powTo,+    sinTo,+    cosTo,+    tanTo,+    asinTo,+    acosTo,+    atanTo,+    sinhTo,+    coshTo,+    tanhTo,+    asinhTo,+    acoshTo,+    atanhTo,++    -- * Conversions between mutable and immutable vectors+    freeze,+    +    -- * Unsafe operations+    unsafeCopyTo,+    unsafeSwap,+    unsafeRead,+    unsafeWrite,+    unsafeModify,+    unsafeMapTo,+    unsafeZipWithTo,+    unsafeAddWithScaleM_,+    unsafeGetDot,+    +    ) where++import Prelude()+import Numeric.LinearAlgebra.Vector.STBase
+ lib/Numeric/LinearAlgebra/Vector/STBase.hs view
@@ -0,0 +1,925 @@+{-# LANGUAGE Rank2Types, DeriveDataTypeable #-}+{-# OPTIONS_HADDOCK hide #-}+{-# OPTIONS_GHC -fno-warn-unused-imports #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Vector.STBase+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : asinerimental+--++module Numeric.LinearAlgebra.Vector.STBase (+    STVector,+    IOVector,+    RVector(..),+    +    create,+    freeze,+    +    new_,+    new,+    newCopy,+    +    clear,+    copyTo,+    unsafeCopyTo,+    swap,+    unsafeSwap,+    +    getIndices,+    getElems,+    getElems',+    getAssocs,+    getAssocs',+    setElems,+    setAssocs,+    unsafeSetAssocs,+    +    read,+    unsafeRead,+    write,+    unsafeWrite,+    modify,+    unsafeModify,+    unsafeSwapElems,++    mapTo,+    unsafeMapTo,+    zipWithTo,+    unsafeZipWithTo,+    +    withSlice,+    withDrop,+    withTake,+    withSplitAt,+    +    withSliceM,+    withDropM,+    withTakeM,+    withSplitAtM,+    +    getSumAbs,+    getNorm2,+    getWhichMaxAbs,+    getDot,+    unsafeGetDot,+    scaleM_,+    addWithScaleM_,+    unsafeAddWithScaleM_,+    kroneckerTo,+    +    addTo,+    subTo,+    mulTo,+    negateTo,+    conjugateTo,+    absTo,+    signumTo,+    divTo,+    recipTo,        +    sqrtTo,+    expTo,+    logTo,+    powTo,+    sinTo,+    cosTo,+    tanTo,+    asinTo,+    acosTo,+    atanTo,+    sinhTo,+    coshTo,+    tanhTo,+    asinhTo,+    acoshTo,+    atanhTo,+    ) where++import Prelude hiding ( drop, read, splitAt, take )++import Control.Monad( when, liftM2 )+import Control.Monad.ST( RealWorld, ST, runST, stToIO, unsafeIOToST )+import Data.Complex( Complex )+import Data.Typeable( Typeable )+import Foreign( Ptr, Storable, advancePtr, peek, poke, peekElemOff,+    pokeElemOff, copyArray, mallocForeignPtrArray )+import System.IO.Unsafe( unsafeInterleaveIO )+import Text.Printf( printf )+import Unsafe.Coerce( unsafeCoerce )++import Foreign.BLAS( BLAS1, BLAS2 )+import qualified Foreign.BLAS as BLAS+import Foreign.VMath( VNum, VFractional, VFloating )+import qualified Foreign.VMath as VMath++import Numeric.LinearAlgebra.Internal( clearArray )+import Numeric.LinearAlgebra.Vector.Base hiding ( unsafeWith )+import qualified Numeric.LinearAlgebra.Vector.Base as V+++-- | Mutable vectors in the 'ST' monad.+newtype STVector s e = STVector { unSTVector :: Vector e }+    deriving (Typeable)++-- | Mutable vectors in the 'IO' monad.  Note that 'IO' operations+-- aren't directly supported; to perform an operation in the 'IO'+-- monad, perform the action in 'ST' 'RealWorld' and then convert+-- it via 'stToIO'.+type IOVector s = STVector RealWorld++-- | A safe way to create and work with a mutable vector before returning +-- an immutable vector for later perusal. This function avoids copying+-- the vector before returning it - it uses 'unsafeFreeze' internally,+-- but this wrapper is a safe interface to that function.+create :: (Storable e) => (forall s . ST s (STVector s e)) -> Vector e+create stmv = runST $ do+    mv <- stmv+    unsafeFreeze mv+{-# INLINE create #-}++-- | Converts a mutable vector to an immutable one by taking a complete+-- copy of it.+freeze :: (RVector v, Storable e) => v e -> ST s (Vector e)+freeze mv = do+    mv' <- newCopy mv+    unsafeFreeze mv'+{-# INLINE freeze #-}++++-- | Read-only vectors+class RVector v where+    -- | Get the dimension of the vector.  This is equal to the number of+    -- elements in the vector.                          +    getDim :: (Storable e) => v e -> ST s Int++    -- | Same as 'withSlice' but does not range-check indices.+    unsafeWithSlice :: (Storable e)+                    => Int -> Int -> v e+                    -> (forall v'. RVector v' => v' e -> ST s a)+                    -> ST s a++    -- | Execute an 'IO' action with a pointer to the first element in the+    -- vector.+    unsafeWith :: (Storable e) => v e -> (Ptr e -> IO a) -> IO a++    -- | Converts a read-only vector into an immutable vector. This simply+    -- casts the vector from one type to the other without copying the vector.+    -- Note that because the vector is possibly not copied, any subsequent+    -- modifications made to the mutable version of the vector may be shared+    -- with the immutable version. It is safe to use, therefore, if the+    -- mutable version is never modified after the freeze operation.+    unsafeFreeze :: (Storable e) => v e -> ST s (Vector e)++    -- | Unsafe cast from a read-only vector to a mutable vector.+    unsafeThaw :: (Storable e)+               => v e -> ST s (STVector s e)+++instance RVector Vector where+    getDim = return . dim+    {-# INLINE getDim #-}++    unsafeWith = V.unsafeWith+    {-# INLINE unsafeWith #-}++    unsafeWithSlice i n' v f =+        f (V.unsafeSlice i n' v)+    {-# INLINE unsafeWithSlice #-}++    unsafeFreeze = return . id+    {-# INLINE unsafeFreeze #-}++    unsafeThaw = return . STVector+    {-# INLINE unsafeThaw #-}+++instance RVector (STVector s) where+    getDim = return . dim . unSTVector+    {-# INLINE getDim #-}++    unsafeWith v f = V.unsafeWith (unSTVector v) f+    {-# INLINE unsafeWith #-}++    unsafeWithSlice i n' v f =+        f $ unsafeSlice i n' (unSTVector v)+    {-# INLINE unsafeWithSlice #-}++    unsafeFreeze = return . unSTVector+    {-# INLINE unsafeFreeze #-}++    unsafeThaw v = return $ cast v+      where+        cast :: STVector s e -> STVector s' e+        cast = unsafeCoerce+    {-# INLINE unsafeThaw #-}+++-- | @withSlice i n v@ performs an action with a view of the+-- @n@-dimensional subvector of @v@ starting at index @i@.+withSlice :: (RVector v, Storable e)+          => Int+          -> Int+          -> v e+          -> (forall v'. RVector v' => v' e -> ST s a)+          -> ST s a+withSlice i n' v f = do+    n <- getDim v+    when (i < 0 || n' < 0 || i + n' > n) $ error $+        printf "withSlice %d %d <vector with dim %d>: index out of range"+               i n' n+    unsafeWithSlice i n' v f++-- | Same as 'withSliceM' but does not range-check indices.+unsafeWithSliceM :: (Storable e)+                 => Int+                 -> Int+                 -> STVector s e+                 -> (STVector s e -> ST s a)+                 -> ST s a+unsafeWithSliceM i n' v f =+    f $ STVector $ unsafeSlice i n' (unSTVector v)++-- | Like 'withSlice', but perform the action with a mutable view +-- of the vector.+withSliceM :: (Storable e)+           => Int+           -> Int+           -> STVector s e+           -> (STVector s e -> ST s a)+           -> ST s a+withSliceM i n' v f = do+    n <- getDim v+    when (i < 0 || n' < 0 || i + n' > n) $ error $+        printf "withSlice %d %d <vector with dim %d>: index out of range"+               i n' n+    unsafeWithSliceM i n' v f++-- | Like 'withDrop', but perform the action with a mutable view +-- of the vector.+withDropM :: (Storable e)+          => Int+          -> STVector s e+          -> (STVector s e -> ST s a)+          -> ST s a+withDropM i v f = do+    n <- getDim v+    withSliceM i (n-i) v f++-- | Like 'withTake', but perform the action with a mutable view +-- of the vector.+withTakeM :: (Storable e)+          => Int+          -> STVector s e+          -> (STVector s e -> ST s a)+          -> ST s a+withTakeM = withSliceM 0++-- | Like 'withSplitAt' but perform the action with mutable views+-- of the vector.+withSplitAtM :: (Storable e)+             => Int+             -> STVector s e+             -> (STVector s e -> STVector s e -> ST s a)+             -> ST s a+withSplitAtM i v f = do+    n <- getDim v+    withSliceM 0 i v $ \v1 ->+        withSliceM i (n-i) v $ \v2 ->+            f v1 v2++-- | Perform an action the a view gotten from dropping the given+-- number of elements from the start of the vector.+withDrop :: (RVector v, Storable e)+         => Int+         -> v e+         -> (forall v'. RVector v' => v' e -> ST s a)+         -> ST s a+withDrop i v f = do+    mv <- unsafeThaw v+    withDropM i mv f++-- | Perform an action with a view gotten from taking the given+-- number of elements from the start of the vector.+withTake :: (RVector v, Storable e)+         => Int+         -> v e+         -> (forall v'. RVector v' => v' e -> ST s a)+         -> ST s a+withTake n v f = do+    mv <- unsafeThaw v+    withTakeM n mv f++-- | Perform an action with views from splitting the vector at the+-- given index.+withSplitAt :: (RVector v, Storable e)+            => Int+            -> v e+            -> (forall v1' v2'. (RVector v1', RVector v2') => v1' e -> v2' e -> ST s a)+            -> ST s a+withSplitAt i v f = do+    mv <- unsafeThaw v+    withSplitAtM i mv f++-- | Creates a new vector of the given length.  The elements will be+-- uninitialized.+new_ :: (Storable e) => Int -> ST s (STVector s e)+new_ n+    | n < 0 =  error $+        printf "new_ %d: invalid dimension" n+    | otherwise = unsafeIOToST $ do+        f <- mallocForeignPtrArray n+        return $ STVector $ V.unsafeFromForeignPtr f 0 n++-- | Create a vector with every element initialized to the same value.+new :: (Storable e) => Int -> e -> ST s (STVector s e)+new n e = do+    x <- new_ n+    setElems x $ replicate n e+    return x++-- | Creates a new vector by copying another one.    +newCopy :: (RVector v, Storable e) => v e -> ST s (STVector s e)+newCopy x = do+    n <- getDim x+    y <- new_ n+    unsafeCopyTo y x+    return y++-- | @copyTo dst src@ replaces the values in @dst@ with those in+-- source.  The operands must be the same shape.+copyTo :: (RVector v, Storable e) => STVector s e -> v e -> ST s ()+copyTo = checkOp2 "copyTo" unsafeCopyTo+{-# INLINE copyTo #-}++-- | Same as 'copyTo' but does not check the dimensions.+unsafeCopyTo :: (RVector v, Storable e) => STVector s e -> v e -> ST s ()+unsafeCopyTo dst src = do+    n <- getDim dst+    unsafeIOToST $+        unsafeWith dst $ \pdst ->+        unsafeWith src $ \psrc ->+            copyArray pdst psrc n+{-# INLINE unsafeCopyTo #-}++-- | Swap the values stored in two vectors.+swap :: (BLAS1 e) => STVector s e -> STVector s e -> ST s ()+swap = checkOp2 "swap" unsafeSwap+{-# INLINE swap #-}++-- | Same as 'swap' but does not check the dimensions.+unsafeSwap :: (BLAS1 e) => STVector s e -> STVector s e -> ST s ()+unsafeSwap = strideCall2 BLAS.swap+{-# INLINE unsafeSwap #-}++-- | Get the indices of the elements in the vector, @[ 0..n-1 ]@, where+-- @n@ is the dimension of the vector.+getIndices :: (RVector v, Storable e) => v e -> ST s [Int]+getIndices v = do+    n <- getDim v+    return $ [ 0..n-1 ]+{-# INLINE getIndices #-}++-- | Lazily get the elements of the vector.+getElems :: (RVector v, Storable e) => v e -> ST s [e]+getElems v = let+    go end p' | p' == end = do+                  touch v+                  return []+              | otherwise = unsafeInterleaveIO $ do+                  e   <- peek p'+                  es  <- go end (p' `advancePtr` 1)+                  return $ e `seq` (e:es)+    in do+        n <- getDim v+        unsafeIOToST $+            unsafeWith v $ \p -> +                go (p `advancePtr` n) p+  where+    touch v' = unsafeWith v' $ const (return ())+{-# SPECIALIZE INLINE getElems :: STVector s Double -> ST s [Double] #-}+{-# SPECIALIZE INLINE getElems :: STVector s (Complex Double) -> ST s [Complex Double] #-}++-- | Get the elements of the vector.+getElems' :: (RVector v, Storable e) => v e -> ST s [e]+getElems' v = let+    go end p' es | p' == end =+                     return es+                 | otherwise = do+                     e <- peek p'+                     go end (p' `advancePtr` (-1)) (e:es)+    in do+        n <- getDim v+        unsafeIOToST $+            unsafeWith v $ \p ->+                go (p `advancePtr` (-1)) (p `advancePtr` (n-1)) []+{-# SPECIALIZE INLINE getElems' :: STVector s Double -> ST s [Double] #-}+{-# SPECIALIZE INLINE getElems' :: STVector s (Complex Double) -> ST s [Complex Double] #-}++-- | Lazily get the association list of the vector.+getAssocs :: (RVector v, Storable e) => v e -> ST s [(Int,e)]+getAssocs x = liftM2 zip (getIndices x) (getElems x)+{-# INLINE getAssocs #-}++-- | Get the association list of the vector.+getAssocs' :: (RVector v, Storable e) => v e -> ST s [(Int,e)]+getAssocs' x = liftM2 zip (getIndices x) (getElems' x)+{-# INLINE getAssocs' #-}++-- | Set all of the values of the vector from the elements in the list.+setElems  :: (Storable e) => STVector s e -> [e] -> ST s ()+setElems x es = let+    go n [] i _ | i < n = error $ +                    printf ("setElems <vector with dim %d>"+                            ++ " <list with length %d>:"+                            ++ " not enough elements") n i+    go n (_:_) i _ | i == n = error $ +                    printf ("setElems <vector with dim %d>"+                            ++ " <list with length at least %d>:"+                            ++ " too many elements") n (i+1)+    go _ []     _ _ = return ()+    go n (f:fs) i p = do+        poke p f+        go n fs (i+1) (p `advancePtr` 1)+    +    in do+        n <- getDim x+        unsafeIOToST $ unsafeWith x $ go n es 0++-- | Set the given values in the vector.  If an index is repeated twice,+-- the value is implementation-defined.+setAssocs :: (Storable e) => STVector s e -> [(Int,e)] -> ST s ()+setAssocs x ies =+    let go n p ((i,e):ies') = do+            when (i < 0 || i >= n) $ error $+                printf ("setAssocs <vector with dim %d>"+                        ++ " [ ..., (%d,_), ... ]: invalid index") n i+            pokeElemOff p i e+            go n p ies'+        go _ _ [] = return ()+    in do+        n <- getDim x+        unsafeIOToST $ unsafeWith x $ \p -> go n p ies++unsafeSetAssocs :: (Storable e) => STVector s e -> [(Int,e)] -> ST s ()+unsafeSetAssocs x ies =+    let go p ((i,e):ies') = do+            pokeElemOff p i e+            go p ies'+        go _ [] = return ()+    in unsafeIOToST $ unsafeWith x $ \p -> go p ies++-- | Get the element stored at the given index.+read :: (RVector v, Storable e) => v e -> Int -> ST s e+read x i = do+    n <- getDim x+    when (i < 0 || i >= n) $ error $+        printf ("read <vector with dim %d> %d:"+                ++ " invalid index") n i+    unsafeRead x i+{-# SPECIALIZE INLINE read :: STVector s Double -> Int -> ST s (Double) #-}+{-# SPECIALIZE INLINE read :: STVector s (Complex Double) -> Int -> ST s (Complex Double) #-}++-- | Same as 'read' but does not range check the index.+unsafeRead :: (RVector v, Storable e) => v e -> Int -> ST s e+unsafeRead x i =+    unsafeIOToST $ unsafeWith x $ \p -> peekElemOff p i+{-# SPECIALIZE INLINE unsafeRead :: STVector s Double -> Int -> ST s (Double) #-}+{-# SPECIALIZE INLINE unsafeRead :: STVector s (Complex Double) -> Int -> ST s (Complex Double) #-}++-- | Set the element stored at the given index.+write :: (Storable e) => STVector s e -> Int -> e -> ST s ()+write x i e = do+    n <- getDim x+    when (i < 0 || i >= n) $ error $+        printf ("write <vector with dim %d> %d:"+                ++ " invalid index") n i+    unsafeWrite x i e+{-# SPECIALIZE INLINE write :: STVector s Double -> Int -> Double -> ST s () #-}+{-# SPECIALIZE INLINE write :: STVector s (Complex Double) -> Int -> Complex Double -> ST s () #-}++-- | Same as 'write' but does not range check the index.+unsafeWrite :: (Storable e) => STVector s e -> Int -> e -> ST s ()+unsafeWrite x i e =+    unsafeIOToST $ unsafeWith x $ \p -> pokeElemOff p i e+{-# SPECIALIZE INLINE unsafeWrite :: STVector s Double -> Int -> Double -> ST s () #-}+{-# SPECIALIZE INLINE unsafeWrite :: STVector s (Complex Double) -> Int -> Complex Double -> ST s () #-}++-- | Modify the element stored at the given index.+modify :: (Storable e) => STVector s e -> Int -> (e -> e) -> ST s ()+modify x i f = do+    n <- getDim x+    when (i < 0 || i >= n) $ error $+        printf ("modify <vector with dim %d> %d:"+                ++ " invalid index") n i+    unsafeModify x i f+{-# SPECIALIZE INLINE modify :: STVector s Double -> Int -> (Double -> Double) -> ST s () #-}+{-# SPECIALIZE INLINE modify :: STVector s (Complex Double) -> Int -> (Complex Double -> Complex Double) -> ST s () #-}++-- | Same as 'modify' but does not range check the index.+unsafeModify :: (Storable e) => STVector s e -> Int -> (e -> e) -> ST s ()+unsafeModify x i f =+    unsafeIOToST $ unsafeWith x $ \p -> do+        e <- peekElemOff p i+        pokeElemOff p i $ f e+{-# SPECIALIZE INLINE unsafeModify :: STVector s Double -> Int -> (Double -> Double) -> ST s () #-}+{-# SPECIALIZE INLINE unsafeModify :: STVector s (Complex Double) -> Int -> (Complex Double -> Complex Double) -> ST s () #-}++unsafeSwapElems :: (Storable e) => STVector s e -> Int -> Int -> ST s ()+unsafeSwapElems x i1 i2 = unsafeIOToST $ unsafeWith x $ \p ->+    let p1 = p `advancePtr` i1+        p2 = p `advancePtr` i2+    in do+        e1  <- peek p1+        e2  <- peek p2+        poke p2 e1+        poke p1 e2+{-# SPECIALIZE INLINE unsafeSwapElems :: STVector s Double -> Int -> Int -> ST s () #-}+{-# SPECIALIZE INLINE unsafeSwapElems :: STVector s (Complex Double) -> Int -> Int -> ST s () #-}++-- | @mapTo dst f src@ replaces @dst@ elementwise with @f(src)@.+mapTo :: (RVector v, Storable e, Storable f)+      => STVector s f+      -> (e -> f)+      -> v e+      -> ST s ()+mapTo dst f src = (checkOp2 "mapTo _" $ \z x -> unsafeMapTo z f x) dst src+{-# INLINE mapTo #-}++-- | Same as 'mapTo' but does not check dimensions.+unsafeMapTo :: (RVector v, Storable e, Storable f)+            => STVector s f+            -> (e -> f)+            -> v e+            -> ST s ()+unsafeMapTo dst f src =+    let go end pdst psrc+            | pdst == end =+                return ()+            | otherwise = do+                e <- peek psrc+                poke pdst (f e)+                go end (pdst `advancePtr` 1) (psrc `advancePtr` 1)+    in do+        ndst <- getDim dst+        unsafeIOToST $+           unsafeWith dst $ \pdst ->+           unsafeWith src $ \psrc -> +               go (pdst `advancePtr` ndst) pdst psrc+  where++{-# INLINE unsafeMapTo #-}++-- | @zipWithTo dst f x y@ replaces @dst@ elementwise with @f(x,y)@.+zipWithTo :: (RVector v1, RVector v2, Storable e1, Storable e2, Storable f)+          => STVector s f+          -> (e1 -> e2 -> f)+          -> v1 e1+          -> v2 e2+          -> ST s ()+zipWithTo dst f x y = +    (checkOp3 "zipWithTo _" $ \dst1 x1 y1 -> unsafeZipWithTo dst1 f x1 y1)+        dst x y+{-# INLINE zipWithTo #-}++-- | Same as 'zipWithTo' but does not range-check dimensions.+unsafeZipWithTo :: (RVector v1, RVector v2, Storable e1, Storable e2, Storable f)+                => STVector s f+                -> (e1 -> e2 -> f)+                -> v1 e1+                -> v2 e2+                -> ST s ()+unsafeZipWithTo dst f src1 src2 =+    let go end pdst psrc1 psrc2 +            | pdst == end = +                return ()+            | otherwise = do+                e1 <- peek psrc1+                e2 <- peek psrc2+                poke pdst (f e1 e2)+                go end (pdst `advancePtr` 1) (psrc1 `advancePtr` 1)+                   (psrc2 `advancePtr` 1)+    in do+        ndst <- getDim dst+        unsafeIOToST $+           unsafeWith dst $ \pdst ->+           unsafeWith src1 $ \psrc1 ->+           unsafeWith src2 $ \psrc2 -> +               go (pdst `advancePtr` ndst) pdst psrc1 psrc2+{-# INLINE unsafeZipWithTo #-}+++-- | Set every element in the vector to a default value.  For+-- standard numeric types (including 'Double', 'Complex Double', and 'Int'),+-- the default value is '0'.+clear :: (Storable e) => STVector s e -> ST s ()+clear x = do+    n <- getDim x+    unsafeIOToST $ unsafeWith x $ \p -> clearArray p n++-- | @negateTo dst x@ replaces @dst@ with @negate(x)@.+negateTo :: (RVector v, VNum e) => STVector s e -> v e -> ST s ()+negateTo = checkOp2 "negateTo" $ \dst x -> +    call2 VMath.vNeg x dst+{-# INLINE negateTo #-}++-- | @absTo dst x@ replaces @dst@ with @abs(x)@.+absTo :: (RVector v, VNum e) => STVector s e -> v e -> ST s ()+absTo = checkOp2 "absTo" $ \dst x -> +    call2 VMath.vAbs x dst+{-# INLINE absTo #-}++-- | @signumTo dst x@ replaces @dst@ with @signum(x)@.+signumTo :: (RVector v, VNum e) => STVector s e -> v e -> ST s ()+signumTo = checkOp2 "signumTo" $ \dst x ->+    call2 VMath.vSgn x dst+{-# INLINE signumTo #-}+++-- | @conjugateTo dst x@ replaces @dst@ with @conjugate(x)@.+conjugateTo :: (RVector v, VNum e) => STVector s e -> v e -> ST s ()+conjugateTo = checkOp2 "conjugateTo" $ \dst x ->+    call2 VMath.vConj x dst+{-# INLINE conjugateTo #-}++-- | @addTo dst x y@ replaces @dst@ with @x+y@.+addTo :: (RVector v1, RVector v2, VNum e)+      =>  STVector s e -> v1 e -> v2 e -> ST s ()+addTo = checkOp3 "addTo" $ \dst x y -> call3 VMath.vAdd x y dst+{-# INLINE addTo #-}++-- | @subTo dst x y@ replaces @dst@ with @x-y@.+subTo :: (RVector v1, RVector v2, VNum e)+      => STVector s e -> v1 e -> v2 e -> ST s ()+subTo = checkOp3 "subTo" $ \dst x y -> call3 VMath.vSub x y dst+{-# INLINE subTo #-}++-- | @mulTo dst x y@ replaces @dst@ with @x*y@.+mulTo :: (RVector v1, RVector v2, VNum e)+      => STVector s e -> v1 e -> v2 e -> ST s ()+mulTo = checkOp3 "mulTo" $ \dst x y -> call3 VMath.vMul x y dst+{-# INLINE mulTo #-}+ +-- | @divTo dst x y@ replaces @dst@ with @x/y@.+divTo :: (RVector v1, RVector v2, VFractional e)+      => STVector s e -> v1 e -> v2 e -> ST s ()+divTo = checkOp3 "divTo" $ \dst x y -> call3 VMath.vDiv x y dst+{-# INLINE divTo #-}++-- | @recipTo dst x@ replaces @dst@ with @1/x@.+recipTo :: (RVector v, VFractional e)+        => STVector s e -> v e -> ST s ()+recipTo = checkOp2 "recipTo" $ \dst x -> call2 VMath.vInv x dst+{-# INLINE recipTo #-}++-- | @sqrtTo dst x@ replaces @dst@ with @sqrt(x)@.+sqrtTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+sqrtTo = checkOp2 "sqrtTo" $ \dst x -> call2 VMath.vSqrt x dst+{-# INLINE sqrtTo #-}++-- | @expTo dst x@ replaces @dst@ with @exp(x)@.+expTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+expTo = checkOp2 "expTo" $ \dst x -> call2 VMath.vExp x dst+{-# INLINE expTo #-}++-- | @logTo dst x@ replaces @dst@ with @log(x)@.+logTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+logTo = checkOp2 "logTo" $ \dst x -> call2 VMath.vLog x dst+{-# INLINE logTo #-}++-- | @powTo dst x y@ replaces @dst@ with @x ** y@.+powTo :: (RVector v1, RVector v2, VFloating e)+      => STVector s e -> v1 e -> v2 e -> ST s ()+powTo = checkOp3 "powTo" $ \dst x y -> call3 VMath.vPow x y dst+{-# INLINE powTo #-}++-- | @sinTo dst x@ replaces @dst@ with @sin(x)@.+sinTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+sinTo = checkOp2 "sinTo" $ \dst x -> call2 VMath.vSin x dst+{-# INLINE sinTo #-}++-- | @cosTo dst x@ replaces @dst@ with @cos(x)@.+cosTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+cosTo = checkOp2 "cosTo" $ \dst x -> call2 VMath.vCos x dst+{-# INLINE cosTo #-}++-- | @tanTo dst x@ replaces @dst@ with @tan(x)@.+tanTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+tanTo = checkOp2 "tanTo" $ \dst x -> call2 VMath.vTan x dst+{-# INLINE tanTo #-}++-- | @asinTo dst x@ replaces @dst@ with @asin(x)@.+asinTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+asinTo = checkOp2 "asinTo" $ \dst x -> call2 VMath.vASin x dst+{-# INLINE asinTo #-}++-- | @acosTo dst x@ replaces @dst@ with @acos(x)@.+acosTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+acosTo = checkOp2 "acosTo" $ \dst x -> call2 VMath.vACos x dst+{-# INLINE acosTo #-}++-- | @atanTo dst x@ replaces @dst@ with @atan(x)@.+atanTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+atanTo = checkOp2 "atanTo" $ \dst x -> call2 VMath.vATan x dst+{-# INLINE atanTo #-}++-- | @sinhTo dst x@ replaces @dst@ with @sinh(x)@.+sinhTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+sinhTo = checkOp2 "sinhTo" $ \dst x -> call2 VMath.vSinh x dst+{-# INLINE sinhTo #-}++-- | @coshTo dst x@ replaces @dst@ with @cosh(x)@.+coshTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+coshTo = checkOp2 "coshTo" $ \dst x -> call2 VMath.vCosh x dst+{-# INLINE coshTo #-}++-- | @tanhTo dst x@ replaces @dst@ with @tanh(x)@.+tanhTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+tanhTo = checkOp2 "tanhTo" $ \dst x -> call2 VMath.vTanh x dst+{-# INLINE tanhTo #-}++-- | @asinhTo dst x@ replaces @dst@ with @asinh(x)@.+asinhTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+asinhTo = checkOp2 "asinhTo" $ \dst x -> call2 VMath.vASinh x dst+{-# INLINE asinhTo #-}++-- | @acoshTo dst x@ replaces @dst@ with @acosh(x)@.+acoshTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+acoshTo = checkOp2 "acoshTo" $ \dst x -> call2 VMath.vACosh x dst+{-# INLINE acoshTo #-}++-- | @atanhTo dst x@ replaces @dst@ with @atanh(x)@.+atanhTo :: (RVector v, VFloating e) => STVector s e -> v e -> ST s ()+atanhTo = checkOp2 "atanhTo" $ \dst x -> call2 VMath.vATanh x dst+{-# INLINE atanhTo #-}+++-- | Gets the sum of the absolute values of the vector entries.+getSumAbs :: (RVector v, BLAS1 e) => v e -> ST s Double+getSumAbs = strideCall BLAS.asum+{-# INLINE getSumAbs #-}++-- | Gets the 2-norm of a vector.+getNorm2 :: (RVector v, BLAS1 e) => v e -> ST s Double+getNorm2 = strideCall BLAS.nrm2+{-# INLINE getNorm2 #-}++-- | Gets the index and norm of the element with maximum magnitude.  This is +-- undefined if any of the elements are @NaN@.  It will throw an exception if +-- the dimension of the vector is 0.+getWhichMaxAbs :: (RVector v, BLAS1 e) => v e -> ST s (Int, e)+getWhichMaxAbs x = do+    n <- getDim x+    when (n == 0) $ error $+        "getWhichMaxAbs <vector with dim 0>: empty vector"++    i <- strideCall BLAS.iamax x+    e <- unsafeRead x i+    return (i,e)+{-# INLINE getWhichMaxAbs #-}++-- | Computes the dot product of two vectors.+getDot :: (RVector v, RVector v', BLAS1 e)+       => v e -> v' e -> ST s e+getDot = checkOp2 "getDot" unsafeGetDot+{-# INLINE getDot #-}++-- | Same as 'getDot' but does not check dimensions.+unsafeGetDot :: (RVector x, RVector y, BLAS1 e)+             => x e -> y e -> ST s e+unsafeGetDot x y = (strideCall2 BLAS.dotc) y x+{-# INLINE unsafeGetDot #-}++-- | @scaleM k x@ sets @x := k * x@.+scaleM_ :: (Storable e, BLAS1 e) => e -> STVector s e -> ST s ()+scaleM_ k x = do+    n <- getDim x+    unsafeIOToST $+        unsafeWith x $ \px ->+            BLAS.scal n k px 1+{-# INLINE scaleM_ #-}++-- | @addWithScaleM_ alpha x y@ sets @y := alpha * x + y@.+addWithScaleM_ :: (RVector v, BLAS1 e) => e -> v e -> STVector s e -> ST s ()+addWithScaleM_ alpha x y =+    (checkOp2 "addWithScaleM_" $ \x1 y1 -> unsafeAddWithScaleM_ alpha x1 y1)+        x y+{-# INLINE addWithScaleM_ #-}++-- | Same as 'addWithScaleM_' but does not check dimensions.+unsafeAddWithScaleM_ :: (RVector v, BLAS1 e)+                     => e -> v e -> STVector s e -> ST s ()+unsafeAddWithScaleM_ alpha x y =+    (strideCall2 $ flip BLAS.axpy alpha) x y+{-# INLINE unsafeAddWithScaleM_ #-}++-- | @kroneckerTo dst x y@ sets @dst := x \otimes y@.+kroneckerTo :: (RVector v1, RVector v2, BLAS2 e)+            => STVector s e -> v1 e -> v2 e -> ST s ()+kroneckerTo dst x y = do+    m <- getDim x+    n <- getDim y+    dimdst <- getDim dst+    +    when (dimdst /= m * n) $ error $+        printf ("kroneckerTo"+                ++ " <vector with dim %d>"+                ++ " <vector with dim %d>"+                ++ " <vector with dim %d>:"+                ++ " dimension mismatch") dimdst m n ++    clear dst+    unsafeIOToST $+        unsafeWith dst $ \pdst ->+        unsafeWith x $ \px ->+        unsafeWith y $ \py ->+            BLAS.geru n m 1 py 1 px 1 pdst (max n 1)++call2 :: (RVector x, RVector y, Storable e, Storable f)+      => (Int -> Ptr e -> Ptr f -> IO a) +      -> x e -> y f -> ST s a+call2 f x y = do+    n <- getDim x+    unsafeIOToST $+        unsafeWith x $ \pX ->+        unsafeWith y $ \pY ->+            f n pX pY+{-# INLINE call2 #-}    ++call3 :: (RVector x, RVector y, RVector z, Storable e, Storable f, Storable g)+      => (Int -> Ptr e -> Ptr f -> Ptr g -> IO a) +      -> x e -> y f -> z g -> ST s a+call3 f x y z = do+    n <- getDim x+    unsafeIOToST $+        unsafeWith x $ \pX ->+        unsafeWith y $ \pY ->+        unsafeWith z $ \pZ ->           +            f n pX pY pZ+{-# INLINE call3 #-}   ++strideCall :: (RVector x, Storable e)+           => (Int -> Ptr e -> Int -> IO a) +           ->  x e -> ST s a+strideCall f x = do+    n <- getDim x+    unsafeIOToST $+        unsafeWith x $ \pX ->+            f n pX incX+  where+    incX = 1+{-# INLINE strideCall #-}++strideCall2 :: (RVector x, RVector y, Storable e, Storable f)+            => (Int -> Ptr e -> Int -> Ptr f -> Int -> IO a) +            -> x e -> y f -> ST s a+strideCall2 f x y = do+    n <- getDim x+    unsafeIOToST $+       unsafeWith x $ \pX ->+       unsafeWith y $ \pY ->+           f n pX incX pY incY+  where+    incX = 1+    incY = 1+{-# INLINE strideCall2 #-}    ++checkOp2 :: (RVector x, RVector y, Storable e, Storable f)+         => String+         -> (x e -> y f -> ST s a)+         -> x e+         -> y f+         -> ST s a+checkOp2 str f x y = do+    n1 <- getDim x+    n2 <- getDim y+    +    when (n1 /= n2) $ error $+        printf ("%s <vector with dim %d> <vector with dim %d>:"+                ++ " dimension mismatch") str n1 n2++    f x y+{-# INLINE checkOp2 #-}++checkOp3 :: (RVector x, RVector y, RVector z, Storable e, Storable f, Storable g)+         => String+         -> (x e -> y f -> z g -> ST s a)+         -> x e+         -> y f+         -> z g+         -> ST s a+checkOp3 str f x y z = do+    n1 <- getDim x+    n2 <- getDim y        +    n3 <- getDim z+    +    when (n1 /= n2 || n1 /= n3) $ error $+        printf ("%s <vector with dim %d> <vector with dim %d>"+                ++ " <vector with dim %d>:"+                ++ " dimension mismatch") str n1 n2 n3++    f x y z+{-# INLINE checkOp3 #-}+
+ lib/Numeric/LinearAlgebra/Vector/Statistics.hs view
@@ -0,0 +1,121 @@+-----------------------------------------------------------------------------+-- |+-- Module     : Numeric.LinearAlgebra.Vector.Statistics+-- Copyright  : Copyright (c) 2010, Patrick Perry <patperry@gmail.com>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@gmail.com>+-- Stability  : experimental+--+-- Basic multivariate statistics.+--++module Numeric.LinearAlgebra.Vector.Statistics (+    -- * Immutable interface+    sum,+    mean,+    weightedSum,+    weightedMean,++    -- * Mutable interface+    addSumTo,+    meanTo,+    addWeightedSumTo,+    weightedMeanTo,++    ) where++import Prelude hiding ( sum )++import Control.Monad( forM_ )+import Control.Monad.ST( ST )++import Numeric.LinearAlgebra.Types++import Numeric.LinearAlgebra.Vector.Base( Vector )+import Numeric.LinearAlgebra.Vector.STBase( RVector, STVector )+import qualified Numeric.LinearAlgebra.Vector.STBase as V+++-- | Returns the sum of the vectors.  The first argument gives the dimension+-- of the vectors.+sum :: (BLAS1 e) => Int -> [Vector e] -> Vector e+sum p xs = V.create $ do+    s <- V.new_ p+    V.clear s+    addSumTo s xs+    return s++-- | Returns the mean of the vectors.  The first argument gives the dimension+-- of the vectors.+mean :: (BLAS1 e) => Int -> [Vector e] -> Vector e+mean p xs = V.create $ do+      m <- V.new_ p+      meanTo m xs+      return m++-- | Returns the weighted sum of the vectors.  The first argument gives the+-- dimension of the vectors.+weightedSum :: (BLAS1 e) => Int -> [(e, Vector e)] -> Vector e+weightedSum p wxs = V.create $ do+    s <- V.new_ p+    V.clear s+    addWeightedSumTo s wxs+    return s++-- | Returns the weighted mean of the vectors.  The first argument gives the+-- dimension of the vectors.+weightedMean :: (BLAS1 e)+             => Int -> [(Double, Vector e)] -> Vector e+weightedMean p wxs = V.create $ do+    m <- V.new_ p+    weightedMeanTo m wxs+    return m++-- | Adds the sum of the vectors to the target vector.+addSumTo :: (RVector v, BLAS1 e) => STVector s e -> [v e] -> ST s ()+addSumTo dst = addWeightedSumTo dst . zip (repeat 1)++-- | Sets the target vector to the mean of the vectors.+meanTo :: (RVector v, BLAS1 e)+       => STVector s e -> [v e] -> ST s()+meanTo dst = weightedMeanTo dst . zip (repeat 1)++-- | Adds the weigthed sum of the vectors to the target vector.+addWeightedSumTo :: (RVector v, BLAS1 e)+                 => STVector s e ->  [(e, v e)] -> ST s ()+addWeightedSumTo s wxs = do+    n <- V.getDim s+    err <- V.new n 0+    old_s <- V.new_ n+    diff <- V.new_ n+    val <- V.new_ n+    +    forM_ wxs $ \(w,x) -> do+        V.unsafeCopyTo old_s s -- old_s := s+        +        V.unsafeCopyTo val x   -- val := w * x+        V.scaleM_ w val++        V.addTo err err val    -- err := err + val+        V.addTo s s err        -- s := s + err+        +        V.subTo diff old_s s   -- diff := old_s - s+        V.addTo err diff val   -- err := diff + val++-- | Sets the target vector to the weighted mean of the vectors.+weightedMeanTo :: (RVector v, BLAS1 e)+               =>  STVector s e -> [(Double, v e)] -> ST s ()+weightedMeanTo m wxs = let+    go _ _ [] = return ()+    go diff w_sum ((w,x):wxs') | w == 0    = go diff w_sum wxs'+                               | otherwise = let w_sum' = w_sum + w+                                             in do+                                    V.subTo diff x m+                                    V.addWithScaleM_ +                                        (realToFrac $ w/w_sum') diff m+                                    go diff w_sum' wxs'+    in do+        n <- V.getDim m+        diff <- V.new_ n+        V.clear m+        go diff 0 wxs
+ lib/Test/QuickCheck/LinearAlgebra.hs view
@@ -0,0 +1,511 @@+{-# LANGUAGE FlexibleInstances, GeneralizedNewtypeDeriving #-}+{-# OPTIONS_GHC -fno-warn-orphans #-}+-----------------------------------------------------------------------------+-- |+-- Module     : Test.QuickCheck.LinearAlgebra+-- Copyright  : Copyright (c) , Patrick Perry <patperry@stanford.edu>+-- License    : BSD3+-- Maintainer : Patrick Perry <patperry@stanford.edu>+-- Stability  : experimental+--+--+-- Test generators for linear algebra types.+--++module Test.QuickCheck.LinearAlgebra (+    -- Testable element types+    TestElem(..),+    +    -- * Generating random objects+    -- ** Dimensions+    dim,+    dim2,+    Dim(..),+    Dim2(..),+    +    -- ** Indices+    index,+    index2,    +    Index(..),+    Index2(..),     +    +    -- ** Elements+    elem,+    elems,+    -- realElem,+    -- realElems,+    +    -- ** Association lists+    assocs,+    assocs2,+    Assocs(..),    +    Assocs2(..),+    -- bandedAssocs,+    +    -- ** Vectors+    vector,+    VectorPair(..),+    VectorTriple(..),+    VectorList(..),+    WeightedVectorList(..),+    NonEmptyVectorList(..),+    NonEmptyWeightedVectorList(..),+    +    --  ** Matrices+    matrix,+    MatrixPair(..),+    MatrixTriple(..),+    -- hermMatrix,+    -- triMatrix,++    --  Banded matrices+    -- bandwidths,+    -- banded,+    -- bandedWith,+    -- hermBanded,+    -- triBanded,+    +    -- BandedAssocs(..),++    ) where++import Prelude hiding ( elem )++-- import BLAS.Types( UpLoEnum(..), DiagEnum(..) )+import Control.Monad+import Data.Complex( magnitude )+import Data.Maybe( fromJust )++import Test.QuickCheck hiding ( vector )+import qualified Test.QuickCheck as QC++import Numeric.LinearAlgebra.Types+import Numeric.LinearAlgebra.Vector( Vector )+import qualified Numeric.LinearAlgebra.Vector as V+import Numeric.LinearAlgebra.Matrix( Matrix )+import qualified Numeric.LinearAlgebra.Matrix as M+-- import Data.Matrix.Banded( Banded, maybeBandedFromMatrixStorage )+-- import Data.Matrix.Banded.ST( runSTBanded, unsafeThawBanded, +--     diagViewBanded )+++class TestElem e where+    maybeToReal :: e -> Maybe Double+    toReal :: e -> Double+    norm1 :: e -> Double+    norm :: e -> Double+    conjugate :: e -> e+    +    toReal = fromJust . maybeToReal+    +instance (TestElem Double) where+    maybeToReal = Just+    toReal = id+    norm1 = abs+    norm = abs+    conjugate = id+    +instance (TestElem (Complex Double)) where+    maybeToReal (x :+ y) | y == 0    = Just x+                         | otherwise = Nothing+    norm1 (x :+ y) = abs x + abs y+    norm z = magnitude z+    conjugate (x :+ y) = x :+ (-y)++{-+-- | Element types that can be tested with QuickCheck properties.+class (Storable e, Arbitrary e, CoArbitrary e) => TestElem e where+    -- | Inicates whether or not the value should be used in tests.  For+    -- 'Double's, @isTestElem e@ is defined as +    -- @not (isNaN e || isInfinite e || isDenormalized e)@.+    isTestElem :: e -> Bool++instance TestElem Double where+    isTestElem e = not (isNaN e || isInfinite e || isDenormalized e)+    {-# INLINE isTestElem #-}++instance TestElem (Complex Double) where+    isTestElem (x :+ y) = isTestElem x && isTestElem y+    {-# INLINE isTestElem #-}+-}++minit:: Int ->Int+minit  n=  n `mod` 20++-- | Generate a random element.+elem :: (Arbitrary e) => Gen e+elem = arbitrary++-- | Generate a list of elements suitable for testing with.+elems :: (Arbitrary e) => Int -> Gen [e]+elems n = replicateM n elem++-- Generate a random element that has no imaginary part.+-- realElem :: (TestElem e) => Gen e+-- realElem = liftM fromReal elem++-- Generate a list of elements for testing that have no imaginary part.+-- realElems :: (TestElem e) => Int -> Gen [e]+-- realElems n = replicateM n realElem++-- | Get an appropriate dimension for a random vector+dim :: Gen Int+dim = sized $ \s -> do+    (NonNegative n) <- resize (s `div` 4) $ arbitrary+    return (minit n)+ +-- | Get an appropriate dimension for a random matrix+dim2 :: Gen (Int,Int)+dim2 = sized $ \s -> do+    m <- resize (s `div` 2) $ dim+    n <- resize (s `div` 2) $ dim+    return (m,n)+ +-- | A vector dimension.   +newtype Dim = Dim Int+  deriving (Eq, Ord, Num, Integral, Real, Enum, Show, Read)++instance Arbitrary Dim where+    arbitrary = sized $ \s -> do+        (NonNegative n) <- resize (s `div` 4) $ arbitrary+        return $ Dim n+    +    shrink (Dim a) = +        [ Dim a' | (NonNegative a') <- shrink (NonNegative a) ]++-- | A matrix dimension.   +newtype Dim2 = Dim2 (Int,Int)+  deriving (Eq, Show, Read)++instance Arbitrary Dim2 where+    arbitrary = do+        mn <- dim2+        return $ Dim2 mn+++-- | Given a dimension generate a valid index.  The dimension must be positive.+index :: Int -> Gen Int+index n | n <= 0 = +            error $ "index " ++ (show n) ++ ":"+                  ++ " dimension must be positive (QuickCheck error)"+        | otherwise =+            choose (0,n-1)++-- | Given a matrix dimension generate a valid index.+index2 :: (Int,Int) -> Gen (Int,Int)+index2 (m,n) = do+    i <- index m+    j <- index n+    return (i,j)++-- | A dimension and a valid index for it.+data Index = Index Int Int deriving (Eq,Show)+instance Arbitrary Index where+    arbitrary = do+        n <- (1+) `fmap` dim+        i <- index n+        return $ Index n i++-- | A matrix dimension and a valid index for it.+data Index2 = Index2 (Int,Int) (Int,Int) deriving (Eq,Show)+instance Arbitrary Index2 where+    arbitrary = do+        (m',n') <- dim2+        let mn = (m' + 1, n' + 1)+        ij <- index2 mn+        return $ Index2 mn ij+    +    +-- | Generate an associations list for a vector of the given dimension.+assocs :: (Arbitrary e) => Int -> Gen [(Int,e)]+assocs n | n == 0    = return []+         | otherwise = do+    l <- choose(0, 2*n)+    is <- replicateM l $ index n+    es <- elems l+    return $ zip is es++-- | Generate an associations list for a matrix of the given shape.+assocs2 :: (Arbitrary e) => (Int,Int) -> Gen [((Int,Int),e)]+assocs2 (m,n) | m*n == 0  = return []+              | otherwise = do+    l <- choose(0, 2*m*n)+    is <- replicateM l $ index2 (m,n)+    es <- elems l+    return $ zip is es+++-- | A dimension and an associations list.+data Assocs e = Assocs Int [(Int,e)] deriving (Eq,Show)++instance (Arbitrary e) => Arbitrary (Assocs e) where+    arbitrary = do+        n   <- dim+        ies <- assocs n+        return $ Assocs n ies+    +    shrink (Assocs n ies) =+        [ Assocs n' $ filter ((< n') . fst) ies+        | n' <- shrink n+        ] +++        [ Assocs n ies'+        | ies' <- shrink ies+        ]++-- | A shape and an associations list.+data Assocs2 e = Assocs2 (Int,Int) [((Int,Int),e)] deriving (Eq,Show)+instance (Arbitrary e) => Arbitrary (Assocs2 e) where+    arbitrary = do+        mn   <- dim2+        ies  <- assocs2 mn+        return $ Assocs2 mn ies+++-- | Generate a random vector of the given size.+vector :: (Arbitrary e, Storable e) => Int -> Gen (Vector e)+vector n = do+    es <- elems n+    return $ V.fromList n es++instance (Arbitrary e, Storable e) => Arbitrary (Vector e) where+    arbitrary = dim >>= vector+    +    shrink x =+        [ V.slice 0 n x+        | (NonNegative n) <- shrink (NonNegative $ V.dim x)+        ]++-- | Two vectors with the same dimension.+data VectorPair e f = +    VectorPair (Vector e) (Vector f) deriving (Eq, Show)+instance (Arbitrary e, Storable e, Arbitrary f, Storable f) =>+    Arbitrary (VectorPair e f) where+        arbitrary = do+            x <- arbitrary+            y <- vector (V.dim x)+            return $ VectorPair x y+            +        shrink (VectorPair x y) =+            [ VectorPair (V.slice 0 n' x) (V.slice 0 n' y)+            | n' <- shrink (V.dim x)+            ]++-- | Three vectors with the same dimension.+data VectorTriple e f g =+    VectorTriple (Vector e) (Vector f) (Vector g) deriving (Eq, Show)+instance (Arbitrary e, Storable e, Arbitrary f, Storable f,+          Arbitrary g, Storable g) =>+    Arbitrary (VectorTriple e f g) where+        arbitrary = do+            x <- arbitrary+            y <- vector (V.dim x)+            z <- vector (V.dim x)+            return $ VectorTriple x y z++-- | A nonempty list of vectors with the same dimension.+data NonEmptyVectorList e = NonEmptyVectorList Int [Vector e] deriving (Eq, Show)+instance (Arbitrary e, Storable e) => Arbitrary (NonEmptyVectorList e) where+    arbitrary = do+        x <- arbitrary+        n <- choose (0,20)+        let p = V.dim x+        xs <- replicateM n $ vector p+        return $ NonEmptyVectorList p $ x:xs++-- | A nonempty list of (weight, vector) pairs, with the weights all non-negative+-- and the vectors all having the same dimension.+data NonEmptyWeightedVectorList e = NonEmptyWeightedVectorList Int [(e, Vector e)]+    deriving (Eq, Show)+instance (Arbitrary e, Storable e, Num e) => Arbitrary (NonEmptyWeightedVectorList e) where+    arbitrary = do+        (NonEmptyVectorList p xs) <- arbitrary+        ws <- replicateM (length xs) $ fmap abs arbitrary+        return $ NonEmptyWeightedVectorList p $ zip ws xs+        +-- | A list of vectors with the same dimension.+data VectorList e = VectorList Int [Vector e] deriving (Eq, Show)+instance (Arbitrary e, Storable e) => Arbitrary (VectorList e) where+    arbitrary = do+        (NonEmptyVectorList p (_:xs)) <- arbitrary+        return $ VectorList p xs++-- | A list of (weight, vector) pairs, with the weights all non-negative+-- and the vectors all having the same dimension.+data WeightedVectorList e = WeightedVectorList Int [(e, Vector e)]+    deriving (Eq, Show)+instance (Arbitrary e, Storable e, Num e) => Arbitrary (WeightedVectorList e) where+    arbitrary = do+        (NonEmptyWeightedVectorList p (_:wxs)) <- arbitrary+        return $ WeightedVectorList p wxs++-- | Generate a random matrix of the given size.+matrix :: (Arbitrary e, Storable e) => (Int,Int) -> Gen (Matrix e)+matrix (m,n) = +    oneof [ raw, sub ]+  where+    raw = do+        es <- elems $ m * n+        return $ M.fromList (m,n) es+    sub = do+        m' <- choose (m, 2*m)+        es <- elems $ m' * n+        return $ M.slice (0,0) (m,n) (M.fromList (m',n) es)++instance (Arbitrary e, Storable e) => Arbitrary (Matrix e) where+    arbitrary = dim2 >>= matrix+    +-- | Two matrices with the same dimension.+data MatrixPair e f = +    MatrixPair (Matrix e) (Matrix f) deriving (Eq, Show)+instance (Arbitrary e, Storable e, Arbitrary f, Storable f) =>+    Arbitrary (MatrixPair e f) where+        arbitrary = do+            x <- arbitrary+            y <- matrix (M.dim x)+            return $ MatrixPair x y++-- | Three matrices with the same dimension.+data MatrixTriple e f g =+    MatrixTriple (Matrix e) (Matrix f) (Matrix g) deriving (Eq, Show)+instance (Arbitrary e, Storable e, Arbitrary f, Storable f,+          Arbitrary g, Storable g) =>+    Arbitrary (MatrixTriple e f g) where+        arbitrary = do+            x <- arbitrary+            y <- matrix (M.dim x)+            z <- matrix (M.dim x)+            return $ MatrixTriple x y z++instance Arbitrary Trans where+    arbitrary = elements [ NoTrans, Trans, ConjTrans ]+{-++-- | Generate a triangular dense matrix.+triMatrix :: (TestElem e) => (Int,Int) -> Gen (Tri Matrix e)+triMatrix (m,n) = do+    a <- matrix (m,n)+    u <- QC.elements [ Lower, Upper  ]+    d <- QC.elements [ Unit, NonUnit ]+    return $ Tri u d a+    +-- | Generate a Hermitian dense matrix.+hermMatrix :: (TestElem e) => Int -> Gen (Herm Matrix e)+hermMatrix n = do+    a <- matrix (n,n)+    d <- realElems n+    let a' = runSTMatrix $ do+                 ma <- unsafeThawMatrix a+                 setElems (diagView ma 0) d+                 return ma+    u <- QC.elements [ Lower, Upper ]+    return $ Herm u a'++rawMatrix :: (TestElem e) => (Int,Int) -> Gen (Matrix e)+rawMatrix (m,n) = do+    es <- elems (m*n)+    return $ M.fromList (m,n) es+++subMatrix :: (TestElem e) => (Int,Int) -> Gen (SubMatrix e)+subMatrix (m,n) = +    oneof [ rawSubMatrix (m,n)+          , rawSubMatrix (n,m) >>= \(SubMatrix a (i,j) (m',n')) ->+                return $ SubMatrix (herm a) (j,i) (n',m')+          ]++rawSubMatrix :: (TestElem e) => (Int,Int) -> Gen (SubMatrix e)+rawSubMatrix (m,n) = do+    i <- choose (0,5)+    j <- choose (0,5)+    e <- choose (0,5)+    f <- choose (0,5)+    x <- rawMatrix (i+m+e, j+n+f)+    return $ SubMatrix x (i,j) (m,n)++instance (TestElem e) => Arbitrary (SubMatrix e) where+    arbitrary = do+        (m,n) <- shape+        (SubMatrix a ij mn) <- subMatrix (m,n)+        return $ SubMatrix a ij mn++-- | Generate valid bandwidth for a given matrix dimension size+bandwidth :: Int -> Gen Int+bandwidth n = if n == 0 then return 0 else choose (0,n-1)+    +-- | Generate valid bandwidths for the given matrix shape.+bandwidths :: (Int,Int) -> Gen (Int,Int)+bandwidths (m,n) = liftM2 (,) (bandwidth m) (bandwidth n)++-- | Generate a random banded matrix of the given shape.+banded :: (TestElem e) => (Int,Int) -> Gen (Banded e)+banded mn = do+    lu <- bandwidths mn+    bandedWith lu mn++-- | Generate a random banded matrix with the given bandwidths.+bandedWith :: (TestElem e) +           => (Int,Int) -> (Int,Int) -> Gen (Banded e)+bandedWith lu mn = frequency [ (3, rawBanded mn lu)  +                             , (2, hermedBanded mn lu)+                             ]++-- | Generate a triangular banded matrix.+triBanded :: (TestElem e) => Int -> Gen (Tri Banded e)+triBanded n = do+    a <- banded (n,n)+    u <- QC.elements [ Lower, Upper  ]+    d <- QC.elements [ Unit, NonUnit ]+    return $ Tri u d a+    +-- | Generate a Hermitian banded matrix.+hermBanded :: (TestElem e) => Int -> Gen (Herm Banded e)+hermBanded n = do+    a <- banded (n,n)+    d <- realElems n+    let a' = runSTBanded $ do+                 ma <- unsafeThawBanded a+                 setElems (diagViewBanded ma 0) d+                 return ma+    u <- QC.elements [ Lower, Upper ]+    return $ Herm u a'    ++rawBanded :: (TestElem e) => +    (Int,Int) -> (Int,Int) -> Gen (Banded e)+rawBanded (m,n) (kl,ku) = +    let bw = kl+ku+1+    in do+        a <- frequency [ (2, rawMatrix (bw,n))+                       , (1, rawSubMatrix (bw,n) >>= \(SubMatrix b ij _) ->+                                 return $ submatrix b ij (bw,n))     +                       ]+        return $ fromJust (maybeBandedFromMatrixStorage (m,n) (kl,ku) a)++hermedBanded :: (TestElem e) => +    (Int,Int) -> (Int,Int) -> Gen (Banded e)+hermedBanded (m,n) (kl,ku) = do+    x <- rawBanded (n,m) (ku,kl)+    return $ herm x++-- | Generate an associations list for a banded matrix of the given shape+-- and bandwidths.+bandedAssocs :: (TestElem e) => (Int,Int) -> (Int,Int) -> Gen [((Int,Int),e)]+bandedAssocs (m,n) (kl,ku) | m*n == 0  = return []+                           | otherwise = do+    (Nat l) <- arbitrary+    ijs     <- replicateM l $ index2 (kl+1+ku,n)+    let ijs' = mapMaybe (\(i,j) -> let i' = i - j - ku in+                                   if 0 <= i' && i' < m then Just (i',j)+                                                        else Nothing    ) ijs+    es      <- replicateM l elem+    return $ zip ijs' es+++-- | A shape, bandwidths, and an associations list.+data BandedAssocs e = BandedAssocs (Int,Int) (Int,Int) [((Int,Int),e)] deriving (Eq,Show)+instance (TestElem e) => Arbitrary (BandedAssocs e) where+    arbitrary = do+        mn  <- shape+        bw  <- bandwidths mn+        ies <- bandedAssocs mn bw+        return $ BandedAssocs mn bw ies+-}
+ linear-algebra-cblas.cabal view
@@ -0,0 +1,146 @@+name:            linear-algebra-cblas+version:         0.1+homepage:        http://github.com/cartazio/hs-cblas+synopsis:        A linear algebra library with bindings to BLAS and LAPACK+description:+    Note There are some known bugs in this code, do not use it in production!+    this package is meant mostly for easy cblas vs haskell benchmarks, not real use.+    .+    .+    The BLAS (Basic Linear Algebra Subprograms) are routines that provide+    standard building blocks for performing basic vector and matrix operations. +    The Level 1 BLAS perform scalar, vector and vector-vector operations, the +    Level 2 BLAS perform matrix-vector operations, and the Level 3 BLAS perform+    matrix-matrix operations. Because the BLAS are efficient, portable, and+    widely available, they are commonly used in the development of high quality+    linear algebra software, LAPACK for example.+    .+    For more information, see the Netlib BLAS webpage:+    <http://www.netlib.org/blas/> +    .+category:        Math+license:         BSD3+license-file:    COPYING+copyright:       (c) 2010. Patrick Perry <patperry@gmail.com>, Carter Schonwald <carter atsign wellposed dot com> 2012+author:          Patrick Perry, Carter Schonwald+maintainer:      Carter Schonwald <carter atsign wellposed dot com> +cabal-version:   >= 1.2.3+build-type:      Configure+tested-with:     GHC == 7.6.2++extra-source-files:     NEWS README TODO configure.ac configure+                        aclocal.m4 m4/ax_check_blas.m4+                        m4/ax_check_lapack.m4+                        linear-algebra.buildinfo.in cbits/config.h.in+                        tests/Makefile.in+                        +                        examples/LU.hs+                        +                                            +extra-tmp-files:        config.log config.status autom4te.cache+                        linear-algebra.buildinfo cbits/config.h+                        tests/Makefile++Library+    hs-source-dirs:     lib+    exposed-modules:    +                        Foreign.BLAS+                        Foreign.LAPACK+                        Foreign.VMath+                        +                        Numeric.LinearAlgebra++                        Numeric.LinearAlgebra.Matrix+                        Numeric.LinearAlgebra.Matrix.Cholesky+                        Numeric.LinearAlgebra.Matrix.Eigen+                        Numeric.LinearAlgebra.Matrix.Herm+                        Numeric.LinearAlgebra.Matrix.ST+                        Numeric.LinearAlgebra.Matrix.Statistics+                        Numeric.LinearAlgebra.Matrix.Tri++                        Numeric.LinearAlgebra.Packed                     +                        Numeric.LinearAlgebra.Packed.Cholesky                        +                        Numeric.LinearAlgebra.Packed.Herm+                        Numeric.LinearAlgebra.Packed.ST                   +                        Numeric.LinearAlgebra.Packed.Statistics+                        Numeric.LinearAlgebra.Packed.Tri++                        Numeric.LinearAlgebra.Vector+                        Numeric.LinearAlgebra.Vector.ST+                        Numeric.LinearAlgebra.Vector.Statistics+                        +                        Test.QuickCheck.LinearAlgebra+                        +    other-modules:      +                        Foreign.BLAS.Types+                        Foreign.BLAS.Level1+                        Foreign.BLAS.Level2+                        Foreign.BLAS.Level3+                        Foreign.BLAS.Double+                        Foreign.BLAS.Zomplex++                        Foreign.LAPACK.Types+                        Foreign.LAPACK.Double+                        Foreign.LAPACK.Zomplex+                        +                        Foreign.VMath.VNum+                        Foreign.VMath.VFractional+                        Foreign.VMath.VFloating+                        Foreign.VMath.Double+                        Foreign.VMath.Zomplex+                        +                        Numeric.LinearAlgebra.Types+                        Numeric.LinearAlgebra.Internal+                        Numeric.LinearAlgebra.Vector.Base+                        Numeric.LinearAlgebra.Vector.STBase                        +                        Numeric.LinearAlgebra.Matrix.Base+                        Numeric.LinearAlgebra.Matrix.STBase+                        Numeric.LinearAlgebra.Packed.Base+    +    includes:           cbits/config.h+                        cbits/f77_func-hsc.h+                        cbits/vmath.h+    include-dirs:       cbits++    c-sources:          cbits/vmath-double.c+                        cbits/vmath-zomplex.c+                        +    ghc-options:        -Wall -funbox-strict-fields +    +    extensions:         BangPatterns,+                        CPP,+                        DeriveDataTypeable,+                        FlexibleContexts,+                        FlexibleInstances,+                        GeneralizedNewtypeDeriving,+                        ForeignFunctionInterface, +                        Rank2Types+                         +    build-depends:      base >= 4 && < 5, ieee754, storable-complex,+                        vector >= 0.7, QuickCheck >= 2.1.1 && < 3++Executable test-hs-linear-algebra+    hs-source-dirs:     lib, tests+    main-is:            Main.hs+    other-modules:      Vector+                        STVector,+                        Matrix,+                        STMatrix,+                        Statistics,+                        Typed+                        Foreign.BLAS.Double+                        Foreign.BLAS.Zomplex+                        Foreign.LAPACK.Double+                        Foreign.LAPACK.Zomplex++    includes:           cbits/config.h+                        cbits/f77_func-hsc.h+                        cbits/vmath.h+    include-dirs:       cbits++    c-sources:          cbits/vmath-double.c+                        cbits/vmath-zomplex.c++    build-depends:      QuickCheck >= 2.1 && < 3,+                        test-framework >= 0.3.1,+                        test-framework-quickcheck2 >= 0.2.7 
+ linear-algebra.buildinfo.in view
@@ -0,0 +1,7 @@++buildable: @BUILD_PACKAGE_BOOL@+ld-options: @LDFLAGS@ @LAPACK_LIBS@ @BLAS_LIBS@ @LIBS@++executable: test-hs-linear-algebra+buildable: @BUILD_PACKAGE_BOOL@+ld-options: @LDFLAGS@ @LAPACK_LIBS@ @BLAS_LIBS@ @LIBS@
+ m4/ax_check_blas.m4 view
@@ -0,0 +1,238 @@+# SYNOPSIS+#+#   AX_CHECK_BLAS([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])+#+# DESCRIPTION+#+#   This macro looks for a library that implements the BLAS linear-algebra+#   interface (see http://www.netlib.org/blas/). On success, it sets the+#   BLAS_LIBS output variable to hold the requisite library linkages.+#+#   To link with BLAS, you should link with:+#+#       $BLAS_LIBS $LIBS $FLIBS+#+#   in that order.+#+#   To call a BLAS function, use the F77_FUNC macro, defined in config.h+#+#   Many libraries are searched for, from ATLAS to CXML to ESSL. The user+#   may also use --with-blas=<lib> in order to use some specific BLAS+#   library <lib>.+#+#   ACTION-IF-FOUND is a list of shell commands to run if a BLAS library is+#   found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it is+#   not found. If ACTION-IF-FOUND is not specified, the default action will+#   define HAVE_BLAS.+#+#   This macro requires autoconf 2.50 or later.+#+#   The macro is a modified version of ACX_BLAS, from the autoconf macro+#   archive.  The original macro depends on a Fortran compiler, and this+#   version does not.  This version has not been tested extensively, but+#   it is known to work with ATLAS and vecLib.+#+# LAST MODIFICATION+#+#   2009-10-8+#+# COPYLEFT+#+#   Copyright (c) 2009 Patrick O. Perry  <patperry@stanfordalumni.org>+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>+#+#   This program is free software: you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation, either version 3 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <http://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Macro Archive. When you make and+#   distribute a modified version of the Autoconf Macro, you may extend this+#   special exception to the GPL to apply to your modified version as well.++AC_DEFUN([AX_CHECK_BLAS], [+AC_PREREQ(2.50)+ax_blas_ok=no+ +AC_ARG_WITH([blas],+	[AC_HELP_STRING([--with-blas=<lib>], [use BLAS library <lib>])])+case $with_blas in+	yes | "") ;;+	no) ax_blas_ok=disable ;;+	-* | */* | *.a | *.so | *.so.* | *.o) BLAS_LIBS="$with_blas" ;;+	*) BLAS_LIBS="-l$with_blas" ;;+esac++_AX_CHECK_BLAS([gemm_])+if test x$ax_blas_ok = xyes; then+  ax_blas_underscore=yes+else+  _AX_CHECK_BLAS([gemm])+  if test x$ax_blas_ok = xyes; then+    ax_blas_undersore=no+  fi+fi+AC_SUBST([BLAS_LIBS])++if test x$ax_blas_ok = xyes; then+  ifelse([$1],, [+    AC_DEFINE(HAVE_BLAS,1, [Define if you have a BLAS library.])+    AH_TEMPLATE([F77_FUNC], +                [Define to a macro mangling the given Fortan function name])+    if test x$ax_blas_underscore = xyes; then+      AC_DEFINE([F77_FUNC(name)], [name ## _])+    else+      AC_DEFINE([F77_FUNC(name)], [name])+    fi],+    [$1])+  :+else+  ax_blas_ok=no+  [$2]+fi++])dnl AX_CHECK_BLAS+++# _AX_CHECK_BLAS(GEMM)+# --------------------------------------------------------+# Look for a BLAS library in all of the standard places by checking for the +# functions s$GEMM and d$GEMM.  On success, define BLAS_LIBS, set+# ax_blas_ok to yes, and execute ACTION-IF-FOUND.  On failure, set ax_blas_ok+# to no and execute ACTION-IF-NOT-FOUND.+AC_DEFUN([_AX_CHECK_BLAS], [+AC_PREREQ([2.50])++m4_pushdef([sgemm],[[s$1]])+m4_pushdef([dgemm],[[d$1]])++ax_blas_save_LIBS="$LIBS"+LIBS="$LIBS $FLIBS"++# First, check BLAS_LIBS environment variable+if test x$ax_blas_ok = xno; then+  if test x$BLAS_LIBS != x; then+    save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"+    AC_MSG_CHECKING([for ]sgemm[ in $BLAS_LIBS])+    AC_TRY_LINK_FUNC(sgemm, [ax_blas_ok=yes], [BLAS_LIBS=""])+    AC_MSG_RESULT([$ax_blas_ok])+    LIBS="$save_LIBS"+  fi+fi++# BLAS linked to by default?  (happens on some supercomputers)+if test x$ax_blas_ok = xno; then+  save_LIBS="$LIBS"; LIBS="$LIBS"+  AC_CHECK_FUNC(sgemm, [ax_blas_ok=yes])+  LIBS="$save_LIBS"+fi++# BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)+if test x$ax_blas_ok = xno; then+  AC_CHECK_LIB([atlas], [ATL_xerbla],+    [AC_CHECK_LIB([f77blas], sgemm,+       [AC_CHECK_LIB([cblas], [cblas_dgemm],+          [ax_blas_ok=yes+           BLAS_LIBS="-lcblas -lf77blas -latlas"],+          [],+          [-lf77blas -latlas])],+       [],+       [-latlas])])+fi++# BLAS in Intel MKL library?+if test x$ax_blas_ok = xno; then+  AC_CHECK_LIB([mkl], sgemm, [ax_blas_ok=yes;BLAS_LIBS="-lmkl"])+fi++# BLAS in Apple vecLib library?+if test x$ax_blas_ok = xno; then+  save_LIBS="$LIBS"; LIBS="-framework vecLib $LIBS"+  unset ac_cv_func_[]sgemm+  AC_CHECK_FUNC(sgemm, [ax_blas_ok=yes;BLAS_LIBS="-lblas"])+  LIBS="$save_LIBS"+fi++# BLAS in PhiPACK libraries? (requires generic BLAS lib, too)+if test $ax_blas_ok = no; then+  AC_CHECK_LIB([blas], sgemm,+    [AC_CHECK_LIB([dgemm], dgemm,+      [AC_CHECK_LIB([sgemm], sgemm,+        [ax_blas_ok=yes; BLAS_LIBS="-lsgemm -ldgemm -lblas"],+        [],+        [-lblas])],+      [],+      [-lblas])])+fi++# BLAS in Alpha CXML library?+if test x$ax_blas_ok = xno; then+  AC_CHECK_LIB([cxml], sgemm, [ax_blas_ok=yes;BLAS_LIBS="-lcxml"])+fi+ +# BLAS in Alpha DXML library? (now called CXML, see above)+if test x$ax_blas_ok = xno; then+  AC_CHECK_LIB([dxml], sgemm, [ax_blas_ok=yes;BLAS_LIBS="-ldxml"])+fi+ +# BLAS in Sun Performance library?+if test x$ax_blas_ok = xno; then+  if test "x$GCC" != xyes; then # only works with Sun CC+    AC_CHECK_LIB([sunmath], [acosp],+      [AC_CHECK_LIB([sunperf], sgemm,+      [BLAS_LIBS="-xlic_lib=sunperf -lsunmath"+       ax_blas_ok=yes],+      [],+      [-lsunmath])])+  fi+fi+ +# BLAS in SCSL library?  (SGI/Cray Scientific Library)+if test x$ax_blas_ok = xno; then+  AC_CHECK_LIB([scs], sgemm, [ax_blas_ok=yes; BLAS_LIBS="-lscs"])+fi+ +# BLAS in SGIMATH library?+if test x$ax_blas_ok = xno; then+  AC_CHECK_LIB([complib.sgimath], sgemm,+    [ax_blas_ok=yes; BLAS_LIBS="-lcomplib.sgimath"])+fi+ +# BLAS in IBM ESSL library? (requires generic BLAS lib, too)+if test x$ax_blas_ok = xno; then+  AC_CHECK_LIB([blas], sgemm,+    [AC_CHECK_LIB([essl], sgemm,+      [ax_blas_ok=yes; BLAS_LIBS="-lessl -lblas"],+      [],+      [-lblas $FLIBS])])+fi+ +# Generic BLAS library?+if test x$ax_blas_ok = xno; then+  AC_CHECK_LIB([blas], sgemm, [ax_blas_ok=yes; BLAS_LIBS="-lblas"])+fi+ +LIBS="$ax_blas_save_LIBS"++m4_popdef([sgemm])+m4_popdef([dgemm])++])dnl _AX_CHECK_BLAS+
+ m4/ax_check_lapack.m4 view
@@ -0,0 +1,131 @@+# SYNOPSIS+#+#   AX_CHECK_LAPACK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])+#+# DESCRIPTION+#+#   This macro looks for a library that implements the LAPACK linear-algebra+#   interface (see http://www.netlib.org/lapack/). On success, it sets the+#   LAPACK_LIBS output variable to hold the requisite library linkages.+#+#   To link with LAPACK, you should link with:+#+#       $LAPACK_LIBS $BLAS_LIBS $LIBS+#+#   in that order. BLAS_LIBS is the output variable of the AX_BLAS macro,+#   called automatically. +#+#   The user may also use --with-lapack=<lib> in order to use some specific+#   LAPACK library <lib>.+#+#   ACTION-IF-FOUND is a list of shell commands to run if a LAPACK library+#   is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it+#   is not found. If ACTION-IF-FOUND is not specified, the default action+#   will define HAVE_LAPACK.+#+#   The macro is a modified version of ACX_LAPACK, from the autoconf macro+#   archive.  The original macro depends on a Fortran compiler, and this+#   version does not.  This version has not been tested extensively, but+#   it is known to work with ATLAS and vecLib.+#+# LAST MODIFICATION+#+#   2008-12-29+#+# COPYLEFT+#+#   Copyright (c) 2008 Patrick O. Perry  <patperry@stanfordalumni.org>+#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>+#+#   This program is free software: you can redistribute it and/or modify it+#   under the terms of the GNU General Public License as published by the+#   Free Software Foundation, either version 3 of the License, or (at your+#   option) any later version.+#+#   This program is distributed in the hope that it will be useful, but+#   WITHOUT ANY WARRANTY; without even the implied warranty of+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General+#   Public License for more details.+#+#   You should have received a copy of the GNU General Public License along+#   with this program. If not, see <http://www.gnu.org/licenses/>.+#+#   As a special exception, the respective Autoconf Macro's copyright owner+#   gives unlimited permission to copy, distribute and modify the configure+#   scripts that are the output of Autoconf when processing the Macro. You+#   need not follow the terms of the GNU General Public License when using+#   or distributing such scripts, even though portions of the text of the+#   Macro appear in them. The GNU General Public License (GPL) does govern+#   all other use of the material that constitutes the Autoconf Macro.+#+#   This special exception to the GPL applies to versions of the Autoconf+#   Macro released by the Autoconf Macro Archive. When you make and+#   distribute a modified version of the Autoconf Macro, you may extend this+#   special exception to the GPL to apply to your modified version as well.++AC_DEFUN([AX_CHECK_LAPACK], [+AC_REQUIRE([AX_CHECK_BLAS])+ax_lapack_ok=no++AC_ARG_WITH(lapack,+        [AC_HELP_STRING([--with-lapack=<lib>], [use LAPACK library <lib>])])+case $with_lapack in+        yes | "") ;;+        no) ax_lapack_ok=disable ;;+        -* | */* | *.a | *.so | *.so.* | *.o) LAPACK_LIBS="$with_lapack" ;;+        *) LAPACK_LIBS="-l$with_lapack" ;;+esac++# Get fortran linker name of LAPACK function to check for.+if test x"$ax_blas_underscore" = xyes; then+    cheev=cheev_+else+    cheev=cheev+fi++# We cannot use LAPACK if BLAS is not found+if test "x$ax_blas_ok" != xyes; then+        ax_lapack_ok=noblas+        LAPACK_LIBS=""+fi++# First, check LAPACK_LIBS environment variable+if test "x$LAPACK_LIBS" != x; then+        save_LIBS="$LIBS"; LIBS="$LAPACK_LIBS $BLAS_LIBS $LIBS"+        AC_MSG_CHECKING([for $cheev in $LAPACK_LIBS])+        AC_TRY_LINK_FUNC($cheev, [ax_lapack_ok=yes], [LAPACK_LIBS=""])+        AC_MSG_RESULT($ax_lapack_ok)+        LIBS="$save_LIBS"+        if test $ax_lapack_ok = no; then+                LAPACK_LIBS=""+        fi+fi++# LAPACK linked to by default?  (is sometimes included in BLAS lib)+if test $ax_lapack_ok = no; then+        save_LIBS="$LIBS"; LIBS="$LIBS $BLAS_LIBS"+        AC_CHECK_FUNC($cheev, [ax_lapack_ok=yes])+        LIBS="$save_LIBS"+fi++# Generic LAPACK library?+for lapack in lapack lapack_rs6k; do+        if test $ax_lapack_ok = no; then+                save_LIBS="$LIBS"; LIBS="$BLAS_LIBS $LIBS"+                AC_CHECK_LIB($lapack, $cheev,+                    [ax_lapack_ok=yes; LAPACK_LIBS="-l$lapack"], [], [])+                LIBS="$save_LIBS"+        fi+done++AC_SUBST(LAPACK_LIBS)++# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:+if test x"$ax_lapack_ok" = xyes; then+        ifelse([$1],,AC_DEFINE(HAVE_LAPACK,1,[Define if you have LAPACK library.]),[$1])+        :+else+        ax_lapack_ok=no+        $2+fi+])dnl AX_LAPACK
+ tests/Main.hs view
@@ -0,0 +1,19 @@++import Test.Framework+import Test.Framework.Providers.QuickCheck2++import Vector+import STVector+import Matrix+import STMatrix+import Statistics++main :: IO ()+main = defaultMain tests+  where+    tests = [ tests_Vector+            , tests_STVector+            , tests_Matrix+            , tests_STMatrix+            , tests_Statistics+            ]
+ tests/Makefile.in view
+ tests/Matrix.hs view
@@ -0,0 +1,433 @@+module Matrix (+    tests_Matrix+    ) where++import Control.Monad( replicateM, zipWithM_ )+import Data.AEq+import Data.List( transpose )+import Debug.Trace+import Test.Framework+import Test.Framework.Providers.QuickCheck2+import Test.QuickCheck hiding ( vector )+import qualified Test.QuickCheck as QC++import Numeric.LinearAlgebra+import qualified Numeric.LinearAlgebra.Matrix as M+import qualified Numeric.LinearAlgebra.Vector as V++import Test.QuickCheck.LinearAlgebra( TestElem(..), Dim2(..), Index2(..),+    Assocs2(..), MatrixPair(..) )+import qualified Test.QuickCheck.LinearAlgebra as Test++import Typed+++tests_Matrix = testGroup "Matrix"+    [ testPropertyI "dim . fromList" prop_dim_fromList+    , testPropertyI "at . fromList" prop_at_fromList+    , testPropertyI "fromCols" prop_fromCols    +    , testPropertyI "fromRows" prop_fromRows        +    , testPropertyI "constant" prop_constant+    , testPropertyI "indices" prop_indices+    , testPropertyI "elems" prop_elems+    , testPropertyI "assocs" prop_assocs+    , testPropertyI "update" prop_update+    , testPropertyI "accum" prop_accum+    , testPropertyI "map" prop_map+    , testPropertyI "zipWith" prop_zipWith+    , testPropertyI "col" prop_col+    , testPropertyI "cols" prop_cols+    , testPropertyD "row" prop_row+    , testPropertyD "rows" prop_rows+    , testPropertyI "diag" prop_diag+    , testPropertyI "slice" prop_slice+    , testPropertyI "splitRowsAt" prop_splitRowsAt+    , testPropertyI "splitColsAt" prop_splitColsAt+    , testPropertyI "viewVector" prop_viewVector+    , testPropertyDZ "shiftDiag" prop_shiftDiag prop_shiftDiag+    , testPropertyDZ "shiftDiagWithScale"+        prop_shiftDiagWithScale prop_shiftDiagWithScale+    , testPropertyDZ "add" prop_add prop_add+    , testPropertyDZ "sub" prop_sub prop_sub+    , testPropertyDZ "scale" prop_scale prop_scale+    , testPropertyDZ "scaleRows" prop_scaleRows prop_scaleRows+    , testPropertyDZ "scaleCols" prop_scaleCols prop_scaleCols+    , testPropertyDZ "negate" prop_negate prop_negate+    , testPropertyDZ "conjugate" prop_conjugate prop_conjugate+    , testPropertyDZ "trans" prop_trans prop_trans+    , testPropertyDZ "conjTrans" prop_conjTrans prop_conjTrans+    , testPropertyDZ "rank1Update" prop_rank1Update prop_rank1Update+    , testPropertyDZ "mulVector" prop_mulVector prop_mulVector+    , testPropertyDZ "mulVectorWithScale" prop_mulVectorWithScale prop_mulVectorWithScale+    , testPropertyDZ "addMulVectorWithScales" prop_addMulVectorWithScales prop_addMulVectorWithScales    +    , testPropertyDZ "mulMatrix" prop_mulMatrix prop_mulMatrix+    , testPropertyDZ "mulMatrixWithScale" prop_mulMatrixWithScale prop_mulMatrixWithScale+    , testPropertyDZ "addMulMatrixWithScales" prop_addMulMatrixWithScales prop_addMulMatrixWithScales    ++    ]++++------------------------- Matrix Construction ------------------------------++prop_dim_fromList t (Dim2 (m,n)) =+    forAll (QC.vector $ m*n) $ \es -> let+        a = typed t $ M.fromList (m,n) es+        in M.dim a == (m,n)+        +prop_at_fromList t (Dim2 (m,n)) =+    forAll (QC.vector $ m*n) $ \es -> let+        a = typed t $ M.fromList (m,n) es+        in and [ M.at a (i,j) === e+               | ((i,j),e) <- zip [ (i,j) | j <- [ 0..n-1 ], i <- [ 0..m-1 ] ]+                                  es+               ]++prop_fromCols t (Dim2 (m,n)) =+    forAll (replicateM n $ Test.vector m) $ \cs ->+        M.fromCols (m,n) cs === (typed t $ M.fromList (m,n) $+            concatMap V.elems cs)++prop_fromRows t (Dim2 (m,n)) =+    forAll (replicateM m $ Test.vector n) $ \rs ->+        M.fromRows (m,n) rs === (typed t $ M.fromList (m,n) $+            concat $ transpose $ map V.elems rs)++prop_constant t (Dim2 (m,n)) e =+    M.constant (m,n) e === M.fromList (m,n) (replicate (m*n) e)+  where+    _ = typed t [e]+++-------------------------- Accessing Matrices ------------------------------++prop_indices t x =+    M.indices x === [ (i,j) | j <- [ 0..n-1 ], i <- [ 0..m-1 ] ]+  where+    (m,n) = M.dim x+    _ = immutableMatrix x+    _ = typed t x++prop_elems t x =+    M.elems x === [ M.at x i | i <- M.indices x ]+  where+    _ = typed t x+    +prop_assocs t x =+    M.assocs x === zip (M.indices x) (M.elems x)+  where+    _ = typed t x+++------------------------- Incremental Updates ------------------------------+    +prop_update t (Assocs2 mn ies) =+    forAll (typed t `fmap` Test.matrix mn) $ \x -> let+        x' = M.update x ies+        is = M.indices x+        is1 = (fst . unzip) ies+        is0 = [ i | i <- is, i `notElem` is1 ]+        in and $+            [ M.at x' i `elem` [ e | (i',e) <- ies, i' == i ]+            | i <- is1+            ] +++            [ M.at x' i === M.at x i+            | i <- is0+            ]++prop_accum t (Blind f) (Assocs2 mn ies) =+    forAll (typed t `fmap` Test.matrix mn) $ \x -> let+        x' = M.accum f x ies+        in x' === M.fromList mn [ foldl f e [ e' | (i',e') <- ies, i' == i]+                                | (i,e) <- M.assocs x ]+  where+      _ = typed t $ (snd . unzip) ies++-------------------------- Derived Matrices ------------------------------+     +prop_map t (Blind f) x =+    M.map f x === M.fromList (M.dim x) (map f $ M.elems x)+  where+    _ = typed t x+    _ = typed t $ M.map f x++prop_zipWith t (Blind f) (MatrixPair x y) =+    M.zipWith f x y === (M.fromList (M.dim x) $+                                zipWith f (M.elems x) (M.elems y))+  where+    _ = typed t x+    _ = typed t y    +    _ = typed t $ M.zipWith f x y+     ++------------------------------ Matrix Views --------------------------------++prop_col t (Index2 (m,n) (_,j)) =+    forAll (typed t `fmap` Test.matrix (m,n)) $ \a ->+        M.col a j === V.fromList m [ M.at a (i,j) | i <- [ 0..m-1 ] ]++prop_cols t a =+    M.cols a === [ M.col a j | j <- [ 0..n-1 ] ]+  where+    (_,n) = M.dim a+    _ = typed t $ immutableMatrix a++prop_row t (Index2 (m,n) (i,_)) =+    forAll (typed t `fmap` Test.matrix (m,n)) $ \a ->+        M.row a i === V.fromList n [ M.at a (i,j) | j <- [ 0..n-1 ] ]++prop_rows t a =+    M.rows a === [ M.row a i | i <- [ 0..m-1 ] ]+  where+    (m,_) = M.dim a+    _ = typed t $ immutableMatrix a++prop_diag t a =+    M.diag a === V.fromList mn [ M.at a (i,i) | i <- [ 0..mn-1 ] ]+  where+    (m,n) = M.dim a+    mn = min m n+    _ = typed t $ immutableMatrix a++prop_slice t a =+    forAll (choose (0,m)) $ \m' ->+    forAll (choose (0,n)) $ \n' ->+    forAll (choose (0,m-m')) $ \i ->+    forAll (choose (0,n-n')) $ \j ->+        M.slice (i,j) (m',n') a+            === M.fromCols (m',n') [ V.slice i m' (M.col a j')+                                      | j' <- [ j..j+n'-1 ] ]+  where+    (m,n) = M.dim a+    _ = typed t a++prop_splitRowsAt t a =+    forAll (choose (0,m)) $ \i ->+        M.splitRowsAt i a+            === ( M.slice (0,0) (i,n) a+                , M.slice (i,0) (m-i,n) a+                )+  where+    (m,n) = M.dim a+    _  = typed t $ immutableMatrix a++prop_splitColsAt t a =+    forAll (choose (0,n)) $ \j ->+        M.splitColsAt j a+            === ( M.slice (0,0) (m,j) a+                , M.slice (0,j) (m,n-j) a+                )+  where+    (m,n) = M.dim a+    _  = typed t $ immutableMatrix a++prop_viewVector t (Dim2 (m,n)) =+    forAll (Test.vector $ m*n) $ \x -> let _ = typed t x in+        M.elems (M.fromVector (m,n) x) === V.elems x+++-------------------------- Num Matrix Operations --------------------------++prop_shiftDiag t a =+    forAll (Test.vector (min m n)) $ \d ->+        M.shiftDiag d a+            === M.accum (+) a [ ((i,i),e) | (i,e) <- V.assocs d ]+  where+    (m,n) = M.dim a+    _ = typed t a++prop_shiftDiagWithScale t k a =+    forAll (Test.vector (min m n)) $ \d ->+        M.shiftDiagWithScale k d a+            ~== M.accum (+) a [ ((i,i),k * e) | (i,e) <- V.assocs d ]+  where+    (m,n) = M.dim a+    _ = typed t a++prop_add t (MatrixPair x y) =+    x `M.add` y === M.zipWith (+) x y+  where+    _ = typed t x++prop_sub t (MatrixPair x y) =+    x `M.sub` y === M.zipWith (-) x y+  where+    _ = typed t x++prop_scale t k x =+    M.scale k x ~== M.map (k*) x+  where+    _ = typed t x++prop_scaleRows t a =+    forAll (Test.vector m) $ \s ->+        M.scaleRows s a+            ~== M.fromCols (m,n) [ V.mul s x | x <- M.cols a ]+  where+    (m,n) = M.dim a+    _ = typed t a++prop_scaleCols t a =+    forAll (Test.vector n) $ \s ->+        M.scaleCols s a+            ~== M.fromCols (m,n)+                    [ V.scale e x+                    | (e,x) <- zip (V.elems s) (M.cols a) ]+  where+    (m,n) = M.dim a+    _ = typed t a+    +prop_negate t x =+    M.negate x === M.map negate x+  where+    _ = typed t x++prop_conjugate t x =+    M.conjugate x === M.map conjugate x+  where+    _ = typed t x+++-------------------------- Linear Algebra --------------------------++prop_trans t a =+    M.trans a+        ===+        M.update (M.zero (swap $ M.dim a)) [ (swap ij, e) | (ij,e) <- M.assocs a ]+  where+    swap (i,j) = (j,i)+    _ = typed t a+    +prop_conjTrans t a =+    M.conjTrans a === M.conjugate (M.trans a)+  where+    _ = typed t a++prop_rank1Update t alpha a =+    forAll (Test.vector m) $ \x ->+    forAll (Test.vector n) $ \y -> let y' = V.conjugate y in+        M.rank1Update alpha x y a+            ~==+            M.update (M.zero (m,n))+                     [ ((i,j), alpha * V.at x i * V.at y' j + e)+                     | ((i,j),e) <- M.assocs a+                     ]+  where+    (m,n)= M.dim a+    _ = typed t a++data MulMatrixAddVector e =+    MulMatrixAddVector Trans (Matrix e) (Vector e) (Vector e) deriving (Show)+    +instance (Storable e, Arbitrary e) => Arbitrary (MulMatrixAddVector e) where+    arbitrary = do+        transa <- arbitrary+        a <- arbitrary+        let (ma,na) = M.dim a+            (m,n) = case transa of NoTrans -> (ma,na)+                                   _       -> (na,ma)+        x <- Test.vector n+        y <- Test.vector m+        return $ MulMatrixAddVector transa a x y+        +data MulMatrixVector e =+    MulMatrixVector Trans (Matrix e) (Vector e) deriving (Show)+instance (Storable e, Arbitrary e) => Arbitrary (MulMatrixVector e) where+    arbitrary = do+        (MulMatrixAddVector transa a x _) <- arbitrary+        return $ MulMatrixVector transa a x+        +prop_mulVector t (MulMatrixVector transa a x) =+    M.mulVector transa a x+        ~==+        case transa of+            NoTrans   -> V.fromList (fst $ M.dim a)+                                    [ V.dot x (V.conjugate r)+                                    | r <- M.rows a ]++            Trans     -> V.fromList (snd $ M.dim a)+                                    [ V.dot x (V.conjugate c)+                                    | c <- M.cols a ]+                                    +            ConjTrans -> V.fromList (snd $ M.dim a)+                                    [ V.dot x c+                                    | c <- M.cols a ]+  where+    _ = typed t a++prop_mulVectorWithScale t alpha (MulMatrixVector transa a x) =+    M.mulVectorWithScale alpha transa a x+        ~==+        M.mulVector transa a (V.scale alpha x)+  where+    _ = typed t a++prop_addMulVectorWithScales t alpha beta (MulMatrixAddVector transa a x y) =+    M.addMulVectorWithScales alpha transa a x beta y+        ~==+        V.add (M.mulVectorWithScale alpha transa a x)+              (V.scale beta y)+  where+    _ = typed t a++data MulMatrixAddMatrix e =+    MulMatrixAddMatrix Trans (Matrix e) Trans (Matrix e) (Matrix e) deriving (Show)+    +instance (Storable e, Arbitrary e) => Arbitrary (MulMatrixAddMatrix e) where+    arbitrary = do+        transa <- arbitrary+        transb <- arbitrary+        c <- arbitrary+        k <- fst `fmap` Test.dim2+        +        let (m,n) = M.dim c+            (ma,na) = case transa of NoTrans -> (m,k)+                                     _       -> (k,m)+            (mb,nb) = case transb of NoTrans -> (k,n)+                                     _       -> (n,k)+        a <- Test.matrix (ma,na)+        b <- Test.matrix (mb,nb)+        +        return $ MulMatrixAddMatrix transa a transb b c++data MulMatrixMatrix e =+    MulMatrixMatrix Trans (Matrix e) Trans (Matrix e) deriving (Show)+instance (Storable e, Arbitrary e) => Arbitrary (MulMatrixMatrix e) where+    arbitrary = do+        (MulMatrixAddMatrix transa a transb b _) <- arbitrary+        return $ MulMatrixMatrix transa a transb b++prop_mulMatrix t (MulMatrixMatrix transa a transb b) =+    M.mulMatrix transa a transb b+        ~==+        M.fromCols (m,n) [ M.mulVector transa a x | x <- M.cols b' ]+  where+    m = case transa of NoTrans -> (fst $ M.dim a)+                       _       -> (snd $ M.dim a)+    n = case transb of NoTrans -> (snd $ M.dim b)+                       _       -> (fst $ M.dim b)+    b' = case transb of NoTrans   -> b+                        Trans     -> M.trans b+                        ConjTrans -> M.conjTrans b+    _ = typed t a++prop_mulMatrixWithScale t alpha (MulMatrixMatrix transa a transb b) =+    M.mulMatrixWithScale alpha transa a transb b+        ~==+        M.scale alpha (M.mulMatrix transa a transb b)+  where+    _ = typed t a++prop_addMulMatrixWithScales t alpha beta (MulMatrixAddMatrix transa a transb b c) =+    M.addMulMatrixWithScales alpha transa a transb b beta c+        ~==+        M.add (M.scale alpha (M.mulMatrix transa a transb b))+              (M.scale beta c)+  where+    _ = typed t a++++testAEq a b =+    if a ~== b then True+               else trace ("expected: " ++ show b ++ "\nactual: " ++ show a) False
+ tests/STMatrix.hs view
@@ -0,0 +1,300 @@+{-# LANGUAGE NoMonomorphismRestriction, Rank2Types #-}+module STMatrix (+    tests_STMatrix,+    mutatesToMatrix,+    readOnlyMatrix,+    +    ) where++import Control.Monad+import Control.Monad.ST+import Data.AEq+import Data.Complex( magnitude )+import Debug.Trace+import Test.Framework+import Test.Framework.Providers.QuickCheck2+import Test.QuickCheck hiding ( vector )+import qualified Test.QuickCheck as QC++import Numeric.LinearAlgebra+import qualified Numeric.LinearAlgebra.Vector as V+import qualified Numeric.LinearAlgebra.Matrix as M++import Test.QuickCheck.LinearAlgebra( TestElem(..), Dim2(..), Index2(..),+    Assocs2(..), MatrixPair(..), MatrixTriple(..) )+import qualified Test.QuickCheck.LinearAlgebra as Test++import STVector( readOnlyVector )+import Typed+++tests_STMatrix = testGroup "STMatrix"+    [ testPropertyI "new_" prop_new_+    , testPropertyI "new" prop_new+    , testPropertyI "newCopy" prop_newCopy+    , testPropertyI "copyTo" prop_copyTo+    , testPropertyI "read" prop_read+    , testPropertyI "write" prop_write+    , testPropertyI "modify" prop_modify+    , testPropertyI "getElems" prop_getElems+    , testPropertyI "getElems'" prop_getElems'+    , testPropertyI "getAssocs" prop_getAssocs+    , testPropertyI "getAssocs'" prop_getAssocs'+    , testPropertyI "setElems" prop_setElems+    , testPropertyI "setAssocs" prop_setAssocs+    , testPropertyI "mapTo" prop_mapTo+    , testPropertyI "zipWithTo" prop_zipWithTo+    , testPropertyDZ "shiftDiagM_" prop_shiftDiagM_ prop_shiftDiagM_+    , testPropertyDZ "shiftDiagWithScaleToM_"+        prop_shiftDiagWithScaleM_ prop_shiftDiagWithScaleM_+    , testPropertyDZ "addTo" prop_addTo prop_addTo+    , testPropertyDZ "subTo" prop_subTo prop_subTo+    , testPropertyDZ "scaleM_" prop_scaleM_ prop_scaleM_+    , testPropertyDZ "addWithScaleM_" prop_addWithScaleM_ prop_addWithScaleM_+    , testPropertyDZ "scaleRowsM" prop_scaleRowsM_ prop_scaleRowsM_+    , testPropertyDZ "scaleColsM_" prop_scaleColsM_ prop_scaleColsM_+    , testPropertyDZ "negateTo" prop_negateTo prop_negateTo+    , testPropertyDZ "conjugateTo" prop_conjugateTo prop_conjugateTo+    , testPropertyDZ "swapRows" prop_swapRows prop_swapRows+    , testPropertyDZ "swapCols" prop_swapCols prop_swapCols+    ]+    +    +prop_new_ t (Dim2 n) = +    (M.dim $ typed t $ M.create $ M.new_ n) === n++prop_new t (Dim2 n) e = +    (M.create $ M.new n e) === (typed t $ M.constant n e)+    +prop_newCopy t x = +    (M.create $ M.newCopy x) === x+  where+    _ = typed t x+        +prop_copyTo t (MatrixPair x y) = runST $+    x `readOnlyMatrix` \mx ->+    y `mutatesToMatrix` x $ \my ->+        M.copyTo my mx+  where+    _ = typed t x++prop_read t (Index2 n i) =+    forAll (typed t `fmap` Test.matrix n) $ \x -> runST $+        x `readOnlyMatrix` \mx -> do+            e <- M.read mx i+            return $ e === M.at x i++prop_write t (Index2 n i) e =+    forAll (Test.matrix n) $ \x -> runST $+        x `mutatesToMatrix` (x `M.update` [(i,e)]) $ \mx -> do+            M.write mx i e+  where+    _ = e == t++prop_modify t (Index2 n i) (Blind f) =+    forAll (Test.matrix n) $ \x -> runST $+        x `mutatesToMatrix`+            (typed t $ x `M.update` [(i, f $ M.at x i)]) $ \mx ->+                M.modify mx i f++prop_getElems t x =+    forAll arbitrary $ \(Blind f) -> runST $+        x `mutatesToMatrix` (M.map f x) $ \mx -> do+            es <- M.getElems mx+            M.mapTo mx f mx+            return $ es === M.elems (M.map f x)+  where+    _ = typed t x++prop_getElems' t x =+    forAll arbitrary $ \(Blind f) -> runST $+        x `mutatesToMatrix` (M.map f x) $ \mx -> do+            es <- M.getElems' mx+            M.mapTo mx f mx+            return $ es === M.elems x+  where+    _ = typed t x++prop_getAssocs t x =+    forAll arbitrary $ \(Blind f) -> runST $+        x `mutatesToMatrix` (M.map f x) $ \mx -> do+            ies <- M.getAssocs mx+            M.mapTo mx f mx+            return $ ies === M.assocs (M.map f x)+  where+    _ = typed t x++prop_getAssocs' t x =+    forAll arbitrary $ \(Blind f) -> runST $+        x `mutatesToMatrix` (M.map f x) $ \mx -> do+            ies <- M.getAssocs' mx+            M.mapTo mx f mx+            return $ ies === M.assocs x+  where+    _ = typed t x++prop_setElems t x =+    forAll (QC.vector $ m*n) $ \es -> runST $+        x `mutatesToMatrix` (M.fromList (m,n) es) $ \mx ->+            M.setElems mx es+  where+    (m,n) = M.dim x+    _ = typed t x++prop_setAssocs t (Assocs2 mn ies) =+    forAll (Test.matrix mn) $ \x -> runST $+        x `mutatesToMatrix` (typed t $ M.update x ies) $ \mx ->+            M.setAssocs mx ies++prop_mapTo t (Blind f) = binaryProp t+    (\x -> M.map f x)+    (\dst mx -> M.mapTo dst f mx)++prop_zipWithTo t (Blind f) = ternaryProp t+    (\x y -> M.zipWith f x y)+    (\dst mx my -> M.zipWithTo dst f mx my)++prop_shiftDiagM_ t a =+    forAll (Test.vector (min m n)) $ \s -> runST $+        s `readOnlyVector` \ms ->+        a `mutatesToMatrix` (M.shiftDiag s a) $ \ma ->+            M.shiftDiagM_ ms ma+  where+    (m,n) = M.dim a+    _ = typed t a++prop_shiftDiagWithScaleM_ t e a =+    forAll (Test.vector (min m n)) $ \s -> runST $+        s `readOnlyVector` \ms ->+        a `mutatesToMatrix` (M.shiftDiagWithScale e s a) $ \ma ->+            M.shiftDiagWithScaleM_ e ms ma+  where+    (m,n) = M.dim a+    _ = typed t a++prop_addTo t = ternaryProp t M.add M.addTo++prop_subTo t = ternaryProp t M.sub M.subTo++prop_scaleM_ t e a = runST $+    a `mutatesToMatrix` (M.scale e a) $ \ma ->+        M.scaleM_ e ma+  where+    _ = typed t a++prop_addWithScaleM_ t alpha (MatrixPair x y) = runST $+    x `readOnlyMatrix` \mx ->+    y `mutatesToMatrix` (M.addWithScale alpha x y) $ \my ->+        M.addWithScaleM_ alpha mx my+  where+    _ = typed t x++prop_scaleRowsM_ t a =+    forAll (Test.vector m) $ \s -> runST $+        s `readOnlyVector` \ms ->+        a `mutatesToMatrix` (M.scaleRows s a) $ \ma ->+            M.scaleRowsM_ ms ma+  where+    (m,n) = M.dim a+    _ = typed t a++prop_scaleColsM_ t a =+    forAll (Test.vector n) $ \s -> runST $+        s `readOnlyVector` \ms ->+        a `mutatesToMatrix` (M.scaleCols s a) $ \ma ->+            M.scaleColsM_ ms ma+  where+    (m,n) = M.dim a+    _ = typed t a++prop_negateTo t = binaryProp t M.negate M.negateTo++prop_conjugateTo t = binaryProp t M.conjugate M.conjugateTo++prop_swapRows t =+    forAll arbitrary $ \(Index2 (m,n) (i1,_)) ->+    forAll (choose (0,m-1)) $ \i2 ->+    forAll (typed t `fmap` Test.matrix (m,n)) $ \a ->+        let a' = M.update a $ [ ((i2,j),e) | (j,e) <- V.assocs (M.row a i1)+                              ] +++                              [ ((i1,j),e) | (j,e) <- V.assocs (M.row a i2)+                              ]+        in runST $+            a `mutatesToMatrix` a' $ \ma ->+            M.swapRows ma i1 i2++prop_swapCols t =+    forAll arbitrary $ \(Index2 (m,n) (_,j1)) ->+    forAll (choose (0,n-1)) $ \j2 ->+    forAll (typed t `fmap` Test.matrix (m,n)) $ \a ->+        let a' = M.update a $ [ ((i,j2),e) | (i,e) <- V.assocs (M.col a j1)+                              ] +++                              [ ((i,j1),e) | (i,e) <- V.assocs (M.col a j2)+                              ]+        in runST $+            a `mutatesToMatrix` a' $ \ma ->+            M.swapCols ma j1 j2+++binaryProp :: (AEq e, Arbitrary e, Show e, Storable e, Testable a)+            => e+            -> (Matrix e -> Matrix e)+            -> (forall s . STMatrix s e -> STMatrix s e -> ST s a)+            -> Property+binaryProp t imm_f f = let+    prop1 t x = runST $+        x `mutatesToMatrix` (imm_f x) $ \mx -> f mx mx+      where _ = typed t x+    prop2 t (MatrixPair x y) = runST $ let _ = typed t x in+        x `readOnlyMatrix` \mx ->+        y `mutatesToMatrix` (imm_f x) $ \my -> f my mx+      where _ = typed t x+    in (    label "1" prop1+        .&. label "2" prop2+       )+    +ternaryProp :: (AEq e, Arbitrary e, Show e, Storable e, Testable a)+            => e+            -> (Matrix e -> Matrix e -> Matrix e)+            -> (forall s . STMatrix s e -> STMatrix s e -> STMatrix s e -> ST s a)+            -> Property+ternaryProp t imm_f f = let+    prop1 t x = runST $+        x `mutatesToMatrix` (imm_f x x) $ \mx -> f mx mx mx+      where _ = typed t x+    prop2a t (MatrixPair x y) = runST $+        x `readOnlyMatrix` \mx ->+        y `mutatesToMatrix` (imm_f x y) $ \my -> f my mx my+      where _ = typed t x+    prop2b t (MatrixPair x y) = runST $+        x `mutatesToMatrix` (imm_f x y) $ \mx ->+        y `readOnlyMatrix` \my -> f mx mx my+      where _ = typed t x        +    prop3 t (MatrixTriple x y z) = runST $+        x `readOnlyMatrix` \mx ->+        y `readOnlyMatrix` \my ->+        z `mutatesToMatrix` (imm_f x y) $ \mz -> f mz mx my+      where _ = typed t x+    in (    label "1" prop1+        .&. label "2a" prop2a+        .&. label "2b" prop2b+        .&. label "3" prop3+       )+++readOnlyMatrix :: (Storable e, AEq e, Testable prop, Show e)+               => Matrix e+               -> (STMatrix s e ->  ST s prop)+               -> ST s Property+readOnlyMatrix x = mutatesToMatrix x x++mutatesToMatrix :: (Storable e, AEq e, Testable prop, Show e)+                => Matrix e+                -> Matrix e+                -> (STMatrix s e -> ST s prop)+                -> ST s Property+mutatesToMatrix x x_new f = do+    mx <- M.newCopy x+    prop <- f mx+    x' <- M.freeze mx+    return $ prop .&. (x' === x_new)
+ tests/STVector.hs view
@@ -0,0 +1,312 @@+{-# LANGUAGE NoMonomorphismRestriction, Rank2Types #-}+module STVector (+    tests_STVector,+    mutatesToVector,+    readOnlyVector,+    ) where++import Control.Monad+import Control.Monad.ST+import Data.AEq+import Data.Complex( magnitude )+import Debug.Trace+import Foreign( Storable )+import Test.Framework+import Test.Framework.Providers.QuickCheck2+import Test.QuickCheck hiding ( vector )+import qualified Test.QuickCheck as QC++import Numeric.LinearAlgebra.Vector( Vector, STVector )+import qualified Numeric.LinearAlgebra.Vector as V++import Test.QuickCheck.LinearAlgebra( TestElem(..), Dim(..), Index(..),+    Assocs(..), VectorPair(..), VectorTriple(..) )+import qualified Test.QuickCheck.LinearAlgebra as Test+import Test.QuickCheck.Property(rejected)++import Typed+++--- this could be a bad idea ..+instance Testable () where+  property _ = property rejected+++tests_STVector = testGroup "STVector"+    [ testPropertyI "new_" prop_new_+    , testPropertyI "new" prop_new+    , testPropertyI "newCopy" prop_newCopy+    , testPropertyI "copyTo" prop_copyTo+    , testPropertyDZ "swap" prop_swap prop_swap+    , testPropertyI "read" prop_read+    , testPropertyI "write" prop_write+    , testPropertyI "modify" prop_modify+    , testPropertyI "getElems" prop_getElems+    , testPropertyI "getElems'" prop_getElems'+    , testPropertyI "getAssocs" prop_getAssocs+    , testPropertyI "getAssocs'" prop_getAssocs'+    , testPropertyI "setElems" prop_setElems+    , testPropertyI "setAssocs" prop_setAssocs+    , testPropertyI "mapTo" prop_mapTo+    , testPropertyI "zipWithTo" prop_zipWithTo+    , testPropertyDZ "getSumAbs" prop_getSumAbs prop_getSumAbs+    , testPropertyDZ "getNorm2" prop_getNorm2 prop_getNorm2+    , testPropertyDZ "getDot" prop_getDot prop_getDot+    , testPropertyDZ "kroneckerTo" prop_kroneckerTo prop_kroneckerTo+    , testPropertyDZ "addTo" prop_addTo prop_addTo+    , testPropertyDZ "subTo" prop_subTo prop_subTo+    , testPropertyDZ "mulTo" prop_mulTo prop_mulTo+    , testPropertyDZ "negateTo" prop_negateTo prop_negateTo+    , testPropertyDZ "conjugateTo" prop_conjugateTo prop_conjugateTo+    , testPropertyDZ "absTo" prop_absTo prop_absTo+    , testPropertyDZ "signumTo" prop_signumTo prop_signumTo+    , testPropertyDZ "divTo" prop_divTo prop_divTo+    , testPropertyDZ "recipTo" prop_recipTo prop_recipTo+    , testPropertyDZ "sqrtTo" prop_sqrtTo prop_sqrtTo+    , testPropertyDZ "expTo" prop_expTo prop_expTo+    , testPropertyDZ "logTo" prop_logTo prop_logTo+    , testPropertyDZ "powTo" prop_powTo prop_powTo+    , testPropertyDZ "sinTo" prop_sinTo prop_sinTo+    , testPropertyDZ "cosTo" prop_cosTo prop_cosTo+    , testPropertyDZ "tanTo" prop_tanTo prop_tanTo+    , testPropertyDZ "asinTo" prop_asinTo prop_asinTo+    , testPropertyDZ "acosTo" prop_acosTo prop_acosTo+    , testPropertyDZ "atanTo" prop_atanTo prop_atanTo+    , testPropertyDZ "sinhTo" prop_sinhTo prop_sinhTo+    , testPropertyDZ "coshTo" prop_coshTo prop_coshTo+    , testPropertyDZ "tanhTo" prop_tanhTo prop_tanhTo+    , testPropertyDZ "asinhTo" prop_asinhTo prop_asinhTo+    , testPropertyDZ "acoshTo" prop_acoshTo prop_acoshTo+    , testPropertyDZ "atanhTo" prop_atanhTo prop_atanhTo+    ]+    ++{-+  getSumAbs:++    Double: [Failed]+*** Failed! Falsifiable (after 34 tests and 1 shrink): +fromList [48.00809219086489,-28.969358622663314,63.04503159639685,5.714612973491514,-5.312024428882535,60.56484370204321,20.339282130713237,-25.609691263383986,11.776052643355653,-72.22738635520177]+LHS+(used seed -5655945031033394469)++    Complex Double: [Failed]+*** Failed! Falsifiable (after 46 tests): +fromList [(-126.63684010249744) :+ (-25.732604105949363),48.30271669448071 :+ (-39.257907001851365),(-742.581416038894) :+ (-40.94772884905545),(-21.033310146590043) :+ 11.040319311574454,(-32.47272728995846) :+ (-75.38889146104881),34.61215019691849 :+ 63.02796474654257,25.495435934718248 :+ 14.86496960897311,285.1569736733574 :+ 20.592531068434027,(-75.03887610996705) :+ 62.568157533798285,13.719037128011735 :+ 49.186886152517744,(-23.33031638959207) :+ (-41.802953657765805),46.325514491999364 :+ (-40.3054052139413),(-97.8445174356864) :+ 62.27686352261467,(-210.08994152230045) :+ 23.4837419831381,(-47.12015960420664) :+ 9.502863461401958]+LHS++    Double: [Failed]+*** Failed! Falsifiable (after 61 tests): +VectorPair (fromList [24.074823693680273,166.2322847046224,-2.8103216076602617,6.544349669641704,157.92295537758915,-52.792112116283036,-56.334929255514766,12.079209274206134,-51.61912866052746,163.39401573569245,-49.34434955256682,-17.020978906318945,116.41247221011058]) (fromList [91.62365332716433,-46.23902424675873,151.71325376854423,34.663441501788725,-2.5921683575991397,-48.720845208466315,51.34009695413845,41.16706632522662,-52.1781413047511,18.0562293933656,-198.82058422020668,-4.213635327473868,40.59717128981193])+LHS+LHS+(used seed -6941761855370166739)++    Complex Double: [OK, passed 100 tests]++-}    +    +prop_new_ t (Dim n) = +    (V.dim $ typed t $ V.create $ V.new_ n) === n++prop_new t (Dim n) e = +    (V.create $ V.new n e) === (typed t $ V.constant n e)+    +prop_newCopy t x = +    (V.create $ V.newCopy x) === x+  where+    _ = typed t x+        +prop_copyTo t (VectorPair x y) = runST $+    x `readOnlyVector` \mx ->+    y `mutatesToVector` x $ \my ->+        V.copyTo my mx+  where+    _ = typed t x++prop_swap t (VectorPair x y) = runST $+    x `mutatesToVector` y $ \mx ->+    y `mutatesToVector` x $ \my ->+        V.swap mx my+  where+    _ = typed t x+    +prop_read t (Index n i) =+    forAll (typed t `fmap` Test.vector n) $ \x -> runST $+        x `readOnlyVector` \mx -> do+            e <- V.read mx i+            return $ e === V.at x i++prop_write t (Index n i) e =+    forAll (Test.vector n) $ \x -> runST $+        x `mutatesToVector` (x `V.update` [(i,e)]) $ \mx -> do+            V.write mx i e+  where+    _ = e == t++prop_modify t (Index n i) (Blind f) =+    forAll (Test.vector n) $ \x -> runST $+        x `mutatesToVector`+            (typed t $ x `V.update` [(i, f $ V.at x i)]) $ \mx ->+                V.modify mx i f++prop_getElems t x =+    forAll arbitrary $ \(Blind f) -> runST $+        x `mutatesToVector` (V.map f x) $ \mx -> do+            es <- V.getElems mx+            V.mapTo mx f mx+            return $ es === V.elems (V.map f x)+  where+    _ = typed t x++prop_getElems' t x =+    forAll arbitrary $ \(Blind f) -> runST $+        x `mutatesToVector` (V.map f x) $ \mx -> do+            es <- V.getElems' mx+            V.mapTo mx f mx+            return $ es === V.elems x+  where+    _ = typed t x++prop_getAssocs t x =+    forAll arbitrary $ \(Blind f) -> runST $+        x `mutatesToVector` (V.map f x) $ \mx -> do+            ies <- V.getAssocs mx+            V.mapTo mx f mx+            return $ ies === V.assocs (V.map f x)+  where+    _ = typed t x++prop_getAssocs' t x =+    forAll arbitrary $ \(Blind f) -> runST $+        x `mutatesToVector` (V.map f x) $ \mx -> do+            ies <- V.getAssocs' mx+            V.mapTo mx f mx+            return $ ies === V.assocs x+  where+    _ = typed t x++prop_setElems t x =+    forAll (QC.vector n) $ \es -> runST $+        x `mutatesToVector` (V.fromList n es) $ \mx ->+            V.setElems mx es+  where+    n = V.dim x+    _ = typed t x++prop_setAssocs t (Assocs n ies) =+    forAll (Test.vector n) $ \x -> runST $+        x `mutatesToVector` (typed t $ V.update x ies) $ \mx ->+            V.setAssocs mx ies++prop_mapTo t (Blind f) = binaryProp t+    (\x -> V.map f x)+    (\dst mx -> V.mapTo dst f mx)++prop_zipWithTo t (Blind f) = ternaryProp t+    (\x y -> V.zipWith f x y)+    (\dst mx my -> V.zipWithTo dst f mx my)++prop_getSumAbs t x = runST $+    x `readOnlyVector` \mx -> do+        s <- V.getSumAbs mx+        return $ s === V.sumAbs x+  where+    _ = typed t x++prop_getNorm2 t x = runST $+    x `readOnlyVector` \mx -> do+        n <- V.getNorm2 mx+        return $ n === V.norm2 x+  where+    _ = typed t x++prop_getDot t (VectorPair x y) = runST $+    x `readOnlyVector` \mx ->+    y `readOnlyVector` \my -> do+        d <- V.getDot mx my+        return $ d === V.dot x y+  where+    _ = typed t x++prop_kroneckerTo t = sized $ \s -> resize (s `div` 2) $+    forAll arbitrary $ \x ->+    forAll arbitrary $ \y ->+    forAll (Test.vector $ V.dim x * V.dim y) $ \z -> runST $+        x `readOnlyVector` \mx ->+        y `readOnlyVector` \my ->+        z `mutatesToVector` (typed t $ V.kronecker x y) $ \mz ->+            V.kroneckerTo mz mx my++prop_addTo t = ternaryProp t V.add V.addTo+prop_subTo t = ternaryProp t V.sub V.subTo+prop_mulTo t = ternaryProp t V.mul V.mulTo+prop_negateTo t = binaryProp t V.negate V.negateTo+prop_conjugateTo t = binaryProp t V.conjugate V.conjugateTo+prop_absTo t = binaryProp t V.abs V.absTo+prop_signumTo t = binaryProp t V.signum V.signumTo++prop_divTo t = ternaryProp t V.div V.divTo+prop_recipTo t = binaryProp t V.recip V.recipTo++prop_sqrtTo t = binaryProp t V.sqrt V.sqrtTo+prop_expTo t = binaryProp t V.exp V.expTo+prop_logTo t = binaryProp t V.log V.logTo+prop_powTo t = ternaryProp t V.pow V.powTo+prop_sinTo t = binaryProp t V.sin V.sinTo+prop_cosTo t = binaryProp t V.cos V.cosTo+prop_tanTo t = binaryProp t V.tan V.tanTo+prop_asinTo t = binaryProp t V.asin V.asinTo+prop_acosTo t = binaryProp t V.acos V.acosTo+prop_atanTo t = binaryProp t V.atan V.atanTo+prop_sinhTo t = binaryProp t V.sinh V.sinhTo+prop_coshTo t = binaryProp t V.cosh V.coshTo+prop_tanhTo t = binaryProp t V.tanh V.tanhTo+prop_asinhTo t = binaryProp t V.asinh V.asinhTo+prop_acoshTo t = binaryProp t V.acosh V.acoshTo+prop_atanhTo t = binaryProp t V.atanh V.atanhTo+++binaryProp :: (AEq e, Arbitrary e, Show e, Storable e, Testable a)+            => e+            -> (Vector e -> Vector e)+            -> (forall s . STVector s e -> STVector s e -> ST s a)+            -> Property+binaryProp t imm_f f = let+    prop2 t (VectorPair x y) = runST $ let _ = typed t x in+        x `readOnlyVector` \mx ->+        y `mutatesToVector` (imm_f x) $ \my -> f my mx+      where _ = typed t x+    in label "" prop2+    +ternaryProp :: (AEq e, Arbitrary e, Show e, Storable e, Testable a)+            => e+            -> (Vector e -> Vector e -> Vector e)+            -> (forall s . STVector s e -> STVector s e -> STVector s e -> ST s a)+            -> Property+ternaryProp t imm_f f = let+    prop3 t (VectorTriple x y z) = runST $+        x `readOnlyVector` \mx ->+        y `readOnlyVector` \my ->+        z `mutatesToVector` (imm_f x y) $ \mz -> f mz mx my+      where _ = typed t x+    in label "" prop3+       +++readOnlyVector :: (Storable e, AEq e, Testable prop, Show e)+               => Vector e+               -> (STVector s e -> ST s prop)+               -> ST s Property+readOnlyVector x = mutatesToVector x x++mutatesToVector :: (Storable e, AEq e, Testable prop, Show e)+          => Vector e+          -> Vector e+          -> (STVector s e -> ST s prop)+          -> ST s Property+mutatesToVector x x_new f = do+    mx <- V.newCopy x+    prop <- f mx+    x' <- V.freeze mx+    return $ prop .&. (x' === x_new)
+ tests/Statistics.hs view
@@ -0,0 +1,209 @@+module Statistics (+    tests_Statistics+    ) where++import Control.Monad( replicateM )+import Data.AEq+import Data.List( foldl' )+import Debug.Trace+import Test.Framework+import Test.Framework.Providers.QuickCheck2+import Test.QuickCheck hiding ( vector )+import qualified Test.QuickCheck as QC++import Numeric.LinearAlgebra+import qualified Numeric.LinearAlgebra.Packed as P+import qualified Numeric.LinearAlgebra.Matrix as M+import qualified Numeric.LinearAlgebra.Vector as V++import Test.QuickCheck.LinearAlgebra( VectorList(..), WeightedVectorList(..) )+import qualified Test.QuickCheck.LinearAlgebra as Test++import Typed++testAEq actual expected =+    if actual ~== expected+        then True+        else trace ("expected: " ++ show expected ++ "\nactual: " ++ show actual)+                   False++++tests_Statistics = testGroup "Statistics"+    [ testPropertyD "sum" prop_sum+    , testPropertyD "weightedSum" prop_weightedSum+    , testPropertyD "mean" prop_mean+    , testPropertyD "weightedMean" prop_weightedMean+    , testPropertyD "weightedMean (equal weights)" prop_weightedMean_eqw+    , testPropertyD "Matrix cov" prop_Matrix_cov+    , testPropertyD "Matrix covWithMean" prop_Matrix_covWithMean+    , testPropertyD "Matrix weightedCov (equal weights)" prop_Matrix_weightedCov_eqw+    , testPropertyD "Matrix weightedCov" prop_Matrix_weightedCov+    , testPropertyD "Matrix weightedCovWithMean" prop_Matrix_weightedCovWithMean+    , testPropertyD "Packed cov" prop_Packed_cov+    , testPropertyD "Packed covWithMean" prop_Packed_covWithMean+    , testPropertyD "Packed weightedCov (equal weights)" prop_Packed_weightedCov_eqw+    , testPropertyD "Packed weightedCov" prop_Packed_weightedCov+    , testPropertyD "Packed weightedCovWithMean" prop_Packed_weightedCovWithMean+    ]+++prop_sum t (VectorList p xs) =+    V.sum p xs ~== foldl' V.add (V.constant p 0) xs+  where+    _ = typed t (head xs)++prop_weightedSum t (WeightedVectorList p wxs) =+    V.weightedSum p wxs+            ~== V.sum p (map (uncurry V.scale) wxs)+  where+    n = length wxs+    _ = typed t (snd $ head wxs)++prop_mean t (VectorList p xs) =+    V.mean p xs ~== V.scale (1/n) (V.sum p xs)+  where+    n = fromIntegral $ max (length xs) 1+    _ = typed t (head xs)++prop_weightedMean_eqw t (VectorList p xs) = let+    wxs = zip (repeat 1) xs+    in V.weightedMean p wxs ~== V.mean p xs+  where+    _ = typed t (head xs)+    +prop_weightedMean t (WeightedVectorList p wxs) = let+        w_sum = (sum . fst . unzip) wxs+        in V.weightedMean p wxs+            ~== if w_sum == 0 then V.constant p 0+                              else V.scale (1/w_sum) (V.weightedSum p wxs)+  where+    n = length wxs+    _ = typed t (snd $ head wxs)++prop_Matrix_cov t (VectorList p xs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        xbar = V.mean p xs+        ys = [ V.sub x xbar | x <- xs ]+        scale = case method of { UnbiasedCov -> 1/(n-1) ; MLCov -> 1/n }+        cov' = foldl' (flip $ \y -> M.rank1Update scale y y)+                      (M.constant (p,p) 0)+                      ys+        cov = M.cov p method xs++        in M.hermMulVector cov z ~== M.mulVector NoTrans cov' z+  where+    n = fromIntegral $ length xs+    _ = typed t $ head xs++prop_Matrix_covWithMean t (VectorList p xs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        xbar = V.mean p xs+        cov' = M.covWithMean xbar method xs+        cov = M.cov p method xs+        in M.hermMulVector cov z ~== M.hermMulVector cov' z+  where+    n = fromIntegral $ length xs+    _ = typed t $ head xs++prop_Matrix_weightedCov_eqw t (VectorList p xs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        wxs = zip (repeat 1) xs+        cov = M.weightedCov p method wxs+        cov' = M.cov p method xs+        in M.hermMulVector cov z ~== M.hermMulVector cov' z+  where+    n = fromIntegral $ length xs+    _ = typed t $ head xs++prop_Matrix_weightedCov t (WeightedVectorList p wxs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        (ws,xs) = unzip wxs+        +        w_sum = sum ws+        ws' = [ w / w_sum | w <- ws ]+        w2_sum = sum [ w*w | w <- ws' ]+        scale = case method of { UnbiasedCov -> 1/(1-w2_sum) ; MLCov -> 1 }++        xbar = V.weightedMean p wxs+        wys = [ (w, V.sub x xbar) | (w,x) <- zip ws' xs ]+        cov' = if w_sum == 0+                    then M.constant (p,p) 0+                    else foldl' (flip $ \(w,y) -> M.rank1Update (scale*w) y y)+                                (M.constant (p,p) 0)+                                wys++        cov = M.weightedCov p method wxs++        in M.hermMulVector cov z ~== M.mulVector NoTrans cov' z+  where+    n = fromIntegral $ length wxs+    _ = typed t $ snd $ head wxs++prop_Matrix_weightedCovWithMean t (WeightedVectorList p wxs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        xbar = V.weightedMean p wxs+        cov' = M.weightedCov p method wxs+        cov = M.weightedCovWithMean xbar method wxs+        in M.hermMulVector cov z ~== M.hermMulVector cov' z+  where+    n = fromIntegral $ length wxs+    _ = typed t $ snd $ head wxs++prop_Packed_cov t (VectorList p xs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        cov' = M.cov p method xs+        cov = P.cov p method xs+        in P.hermMulVector cov z ~== M.hermMulVector cov' z+  where+    n = fromIntegral $ length xs+    _ = typed t $ head xs++prop_Packed_covWithMean t (VectorList p xs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        xbar = V.mean p xs+        cov = P.covWithMean xbar method xs+        cov' = P.cov p method xs+        in P.hermMulVector cov z ~== P.hermMulVector cov' z+  where+    n = fromIntegral $ length xs+    _ = typed t $ head xs++prop_Packed_weightedCov_eqw t (VectorList p xs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        wxs = zip (repeat 1) xs+        cov = P.weightedCov p method wxs+        cov' = P.cov p method xs+        in P.hermMulVector cov z ~== P.hermMulVector cov' z+  where+    n = fromIntegral $ length xs+    _ = typed t $ head xs++prop_Packed_weightedCov t (WeightedVectorList p wxs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        cov' = M.weightedCov p method wxs+        cov = P.weightedCov p method wxs+        in P.hermMulVector cov z ~== M.hermMulVector cov' z+  where+    n = fromIntegral $ length wxs+    _ = typed t $ snd $ head wxs++prop_Packed_weightedCovWithMean t (WeightedVectorList p wxs) =+    forAll (Test.vector p) $ \z ->+    forAll (elements [ UnbiasedCov, MLCov ]) $ \method -> let+        xbar = V.weightedMean p wxs+        cov' = P.weightedCov p method wxs+        cov = P.weightedCovWithMean xbar method wxs+        in P.hermMulVector cov z ~== P.hermMulVector cov' z+  where+    n = fromIntegral $ length wxs+    _ = typed t $ snd $ head wxs
+ tests/Typed.hs view
@@ -0,0 +1,63 @@+module Typed(+    typed,+    +    testPropertyI,+    testPropertyD,+    testPropertyZ,+    testPropertyDZ,+    +    immutableVector,+    immutableMatrix,+    ) where+++import Data.Complex( Complex )+import Test.Framework+import Test.Framework.Providers.QuickCheck2+import Test.QuickCheck++import Numeric.LinearAlgebra.Vector( Vector )+import Numeric.LinearAlgebra.Matrix( Matrix )+        ++typed :: e -> a e -> a e+typed _ = id++immutableVector :: Vector e -> Vector e+immutableVector = id++immutableMatrix :: Matrix e -> Matrix e+immutableMatrix = id++testPropertyI :: (Testable a)+              => TestName+              -> (Int -> a)+              -> Test+testPropertyI str prop =+    testProperty str $ prop undefined++testPropertyDZ :: (Testable a, Testable b)+               => TestName+               -> (Double -> a)+               -> (Complex Double -> b)+               -> Test+testPropertyDZ str propd propz =+    testGroup str+        [ testProperty "Double" $ propd undefined+        , testProperty "Complex Double" $ propz undefined+        ]++testPropertyD :: (Testable a)+              => TestName+              -> (Double -> a)+              -> Test+testPropertyD str prop =+    testProperty str $ prop undefined++testPropertyZ :: (Testable a)+              => TestName+              -> (Complex Double -> a)+              -> Test+testPropertyZ str prop =+    testProperty str $ prop undefined+        
+ tests/Vector.hs view
@@ -0,0 +1,389 @@+module Vector (+    tests_Vector+    ) where++import Data.AEq+import Debug.Trace+import Test.Framework+import Test.Framework.Providers.QuickCheck2+import Test.QuickCheck hiding ( vector )+import qualified Test.QuickCheck as QC++import Numeric.LinearAlgebra.Vector( Vector )+import qualified Numeric.LinearAlgebra.Vector as V++import Test.QuickCheck.LinearAlgebra( TestElem(..), Dim(..), Assocs(..),+    VectorPair(..) )+import qualified Test.QuickCheck.LinearAlgebra as Test++import Typed+++tests_Vector = testGroup "Vector"+    [ testPropertyI "dim/fromList" prop_dim_fromList+    , testPropertyI "at/fromList" prop_at_fromList+    , testPropertyI "zero" prop_zero+    , testPropertyI "constant" prop_constant+    , testPropertyI "indices" prop_indices+    , testPropertyI "elems" prop_elems+    , testPropertyI "assocs" prop_assocs+    , testPropertyI "update" prop_update+    , testPropertyI "accum" prop_accum+    , testPropertyI "map" prop_map+    , testPropertyI "zipWith" prop_zipWith+    , testPropertyI "concat" prop_concat+    , testPropertyI "slice" prop_slice+    , testPropertyI "splitAt" prop_splitAt+    , testPropertyDZ "sumAbs" prop_sumAbs prop_sumAbs    +    , testPropertyDZ "norm2" prop_norm2 prop_norm2+    , testPropertyDZ "whichMaxAbs1" prop_whichMaxAbs1 prop_whichMaxAbs1+    , testPropertyDZ "whichMaxAbs2" prop_whichMaxAbs1 prop_whichMaxAbs2+    , testPropertyDZ "dot" prop_dot prop_dot+    , testPropertyDZ "kronecker" prop_kronecker prop_kronecker+    , testPropertyDZ "add" prop_add prop_add+    , testPropertyDZ "addWithScale" prop_addWithScale prop_addWithScale+    , testPropertyDZ "sub" prop_sub prop_sub+    , testPropertyDZ "scale" prop_scale prop_scale+    , testPropertyDZ "mul" prop_mul prop_mul+    , testPropertyDZ "negate" prop_negate prop_negate+    , testPropertyDZ "conjugate" prop_conjugate prop_conjugate+    , testPropertyDZ "abs" prop_abs prop_abs+    , testPropertyDZ "signum" prop_signum prop_signum+    , testPropertyDZ "div" prop_div prop_div+    , testPropertyDZ "recip" prop_recip prop_recip+    , testPropertyDZ "sqrt" prop_sqrt prop_sqrt+    , testPropertyDZ "exp" prop_exp prop_exp+    , testPropertyDZ "log" prop_log prop_log+    , testPropertyDZ "pow" prop_pow prop_pow+    , testPropertyDZ "sin" prop_sin prop_sin+    , testPropertyDZ "cos" prop_cos prop_cos+    , testPropertyDZ "tan" prop_tan prop_tan+    , testPropertyDZ "asin" prop_asin prop_asin    +    , testPropertyDZ "acos" prop_acos prop_acos    +    , testPropertyDZ "atan" prop_atan prop_atan    +    , testPropertyDZ "sinh" prop_sinh prop_sinh+    , testPropertyDZ "cosh" prop_cosh prop_cosh+    , testPropertyDZ "tanh" prop_tanh prop_tanh+    , testPropertyDZ "asinh" prop_asinh prop_asinh+    , testPropertyDZ "acosh" prop_acosh prop_acosh+    , testPropertyDZ "atanh" prop_atanh prop_atanh+    ]+++{-+abs and signum fail for complex doubles (NB, their ST Vector analogues dont!)++  abs:++    Double: [OK, passed 100 tests]++    Complex Double: [Failed]+*** Failed! Falsifiable (after 18 tests and 1 shrink): +fromList [(-6.7066276741258) :+ 6.89825617623592,(-11.603500174324518) :+ 62.02307490865834]+(used seed -7536870184029858963)++  signum:++    Double: [OK, passed 100 tests]++    Complex Double: [Failed]+*** Failed! Falsifiable (after 2 tests): +fromList [6.727193397617394 :+ 2.38960475296862]+(used seed -6373326149733724790)++-}++------------------------- Vector Construction ------------------------------++prop_dim_fromList t (Dim n) =+    forAll (QC.vector n) $ \es -> let+        x = typed t $ V.fromList n es+        in V.dim x == n+        +prop_at_fromList t (Dim n) =+    forAll (QC.vector n) $ \es -> let+        x = typed t $ V.fromList n es+        in and [ V.at x i === e | (i,e) <- zip [ 0..n-1 ] es ]++prop_zero t (Dim n) = let+    x = typed t $ V.zero n+    in x === V.fromList n (replicate n 0)++prop_constant t (Dim n) e =+    V.constant n e === V.fromList n (replicate n e)+  where+    _ = typed t [e]+++-------------------------- Accessing Vectors ------------------------------++prop_indices t x =+    V.indices x === [ 0..((V.dim x) - 1) ]+  where+    _ = immutableVector x+    _ = typed t x++prop_elems t x =+    V.elems x === [ V.at x i | i <- V.indices x ]+  where+    _ = typed t x+    +prop_assocs t x =+    V.assocs x === zip (V.indices x) (V.elems x)+  where+    _ = typed t x+++------------------------- Incremental Updates ------------------------------+    +prop_update t (Assocs n ies) =+    forAll (typed t `fmap` Test.vector n) $ \x -> let+        x' = V.update x ies+        is = V.indices x+        is1 = (fst . unzip) ies+        is0 = [ i | i <- is, i `notElem` is1 ]+        in and $+            [ V.at x' i `elem` [ e | (i',e) <- ies, i' == i ]+            | i <- is1+            ] +++            [ V.at x' i === V.at x i+            | i <- is0+            ]++prop_accum t (Blind f) (Assocs n ies) =+    forAll (typed t `fmap` Test.vector n) $ \x -> let+        x' = V.accum f x ies+        in x' === V.fromList n [ foldl f e [ e' | (i',e') <- ies, i' == i]+                               | (i,e) <- V.assocs x ]+  where+      _ = typed t $ (snd . unzip) ies+     +     +-------------------------- Derived Vectors ------------------------------+     +prop_map t (Blind f) x =+    V.map f x === V.fromList (V.dim x) (map f $ V.elems x)+  where+    _ = typed t x+    _ = typed t $ V.map f x++prop_zipWith t (Blind f) (VectorPair x y) =+    V.zipWith f x y === (V.fromList (V.dim x) $+                                zipWith f (V.elems x) (V.elems y))+  where+    _ = typed t x+    _ = typed t y    +    _ = typed t $ V.zipWith f x y++prop_concat t xs =+    V.elems (V.concat xs) === concatMap V.elems xs+  where+    _ = typed t $ head xs++------------------------------ Vector Views-- --------------------------------++prop_slice t x = +    forAll (choose (0,n)) $ \n' ->+    forAll (choose (0,n-n')) $ \o ->+        V.slice o n' x === V.fromList n' (take n' $ drop o $ es)+  where+    n  = V.dim x+    es = V.elems x+    _  = typed t x++prop_splitAt t x =+    forAll (choose (0,n)) $ \k ->+        V.splitAt k x === (V.fromList k $ take k es,+                           V.fromList (n-k) $ drop k es)+  where+    n  = V.dim x+    es = V.elems x+    _  = typed t x+    +++-------------------------- Num Vector Operations --------------------------++prop_add t (VectorPair x y) =+    x `V.add` y === V.zipWith (+) x y+  where+    _ = typed t x++prop_addWithScale t alpha (VectorPair x y) =+    V.addWithScale alpha x y ~== V.add (V.scale alpha x) y+  where+    _ = typed t x++prop_sub t (VectorPair x y) =+    x `V.sub` y === V.zipWith (-) x y+  where+    _ = typed t x++prop_scale t k x =+    V.scale k x ~== V.map (k*) x+  where+    _ = typed t x++prop_mul t (VectorPair x y) =+    x `V.mul` y === V.zipWith (*) x y+  where+    _ = typed t x++prop_negate t x =+    V.negate x === V.map negate x+  where+    _ = typed t x++prop_conjugate t x =+    V.conjugate x === V.map conjugate x+  where+    _ = typed t x++prop_abs t x =+    V.abs x === V.map abs x+  where+    _ = typed t x++prop_signum t x =+    V.signum x === V.map signum x+  where+    _ = typed t x+++---------------------- Fractional Vector Operations ------------------------++prop_div t (VectorPair x y) =+    x `V.div` y ~== V.zipWith (/) x y+  where+    _ = typed t x+    +prop_recip t x =+    V.recip x ~== V.map (1/) x+  where+    _ = typed t x+    ++---------------------- Floating Vector Operations ------------------------++prop_exp t x =+    V.exp x ~== V.map exp x+  where+    _ = typed t x++prop_sqrt t x =+    V.sqrt x ~== V.map sqrt x+  where+    _ = typed t x++prop_log t x =+    V.log x ~== V.map log x+  where+    _ = typed t x++prop_pow t (VectorPair x y) =+    x `V.pow` y ~== V.zipWith (**) x y+  where+    _ = typed t x++prop_sin t x =+    V.sin x ~== V.map sin x+  where+    _ = typed t x++prop_cos t x =+    V.cos x ~== V.map cos x+  where+    _ = typed t x++prop_tan t x =+    V.tan x ~== V.map tan x+  where+    _ = typed t x++prop_asin t x =+    -- trace (show (V.asin x) ++ "\n" ++ (show $ V.map asin x)) $    +    V.asin x ~== V.map asin x+  where+    _ = typed t x++prop_acos t x =+    V.acos x ~== V.map acos x+  where+    _ = typed t x++prop_atan t x =+    V.atan x ~== V.map atan x+  where+    _ = typed t x++prop_sinh t x =+    V.sinh x ~== V.map sinh x+  where+    _ = typed t x++prop_cosh t x =+    V.cosh x ~== V.map cosh x+  where+    _ = typed t x++prop_tanh t x =+    V.tanh x ~== V.map tanh x+  where+    _ = typed t x++prop_asinh t x =+    -- trace (show (V.asinh x) ++ "\n" ++ (show $ V.map asinh x)) $+    V.asinh x ~== V.map asinh x+  where+    _ = typed t x++prop_acosh t x =+    V.acosh x ~== V.map acosh x+  where+    _ = typed t x++prop_atanh t x =+    V.atanh x ~== V.map atanh x+  where+    _ = typed t x+++-------------------------- Vector Properties ---------------------------------++prop_sumAbs t x =+    V.sumAbs x ~== (sum $ map norm1 $ V.elems x)+  where+    _ = typed t x++prop_norm2 t x =+    V.norm2 x ~== (sqrt $ sum $ map (^^2) $ map norm $ V.elems x)+  where+    _ = typed t x++prop_whichMaxAbs1 t x =+    (V.dim x > 0) && all (not . isNaN) (map norm1 $ V.elems x) ==>+        V.at x i === e+  where+    (i,e) = V.whichMaxAbs x      +    _     = typed t x++prop_whichMaxAbs2 t x =+    (V.dim x > 0) && all (not . isNaN) (map norm1 $ V.elems x) ==>+        all (<= norm1 e) $ map norm1 (V.elems x)+  where+    (_,e) = V.whichMaxAbs x+    _     = typed t x++prop_dot t (VectorPair x y) =+    V.dot x y ~== sum (V.elems (x * conj y))+  where+    conj = V.conjugate+    (*)  = V.mul+    _    = typed t x++prop_kronecker t x y =+    x `V.kronecker` y ~==+        V.fromList (V.dim x * V.dim y)+                   [ e*f | e <- V.elems x, f <- V.elems y ]+  where+    _ = typed t x