$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: thomas.klimpel_at_[hidden]
Date: 2008-08-09 18:15:35
Author: klimpel
Date: 2008-08-09 18:15:34 EDT (Sat, 09 Aug 2008)
New Revision: 48048
URL: http://svn.boost.org/trac/boost/changeset/48048
Log:
Add Nicola Mori's bindings for getri, sytri, sptri.
Text files modified: 
   sandbox/boost/numeric/bindings/lapack/gesv.hpp       |   162 ++++++++++++++++++++++++++++++++++++-   
   sandbox/boost/numeric/bindings/lapack/lapack.h       |    30 +++++++                                 
   sandbox/boost/numeric/bindings/lapack/lapack_names.h |    18 ++++                                    
   sandbox/boost/numeric/bindings/lapack/spsv.hpp       |    71 +++++++++++++++                         
   sandbox/boost/numeric/bindings/lapack/sysv.hpp       |   171 +++++++++++++++++++++++++++++++++------ 
   5 files changed, 416 insertions(+), 36 deletions(-)
Modified: sandbox/boost/numeric/bindings/lapack/gesv.hpp
==============================================================================
--- sandbox/boost/numeric/bindings/lapack/gesv.hpp	(original)
+++ sandbox/boost/numeric/bindings/lapack/gesv.hpp	2008-08-09 18:15:34 EDT (Sat, 09 Aug 2008)
@@ -18,6 +18,9 @@
 #include <boost/numeric/bindings/traits/traits.hpp>
 #include <boost/numeric/bindings/lapack/lapack.h>
 #include <boost/numeric/bindings/traits/detail/array.hpp>
+#include <boost/numeric/bindings/lapack/workspace.hpp>
+#include <boost/numeric/bindings/lapack/ilaenv.hpp>
+
 
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
 #  include <boost/static_assert.hpp>
@@ -87,7 +90,7 @@
                       traits::complex_ptr (b), &ldb, info);
       }
 
-    } 
+    } //namespace detail
 
     template <typename MatrA, typename MatrB, typename IVec>
     inline
@@ -179,7 +182,7 @@
         LAPACK_ZGETRF (&n, &m, traits::complex_ptr (a), &lda, ipiv, info);
       }
 
-    }
+    } //namespace detail
 
     template <typename MatrA, typename IVec>
     inline
@@ -252,7 +255,7 @@
                        traits::complex_ptr (b), &ldb, info);
       }
 
-    }
+    } // namespace detail
 
     template <typename MatrA, typename MatrB, typename IVec>
     inline
@@ -302,10 +305,157 @@
       return getrs (no_transpose, a, ipiv, b); 
     }
 
-    // TO DO: getri() 
+    /*
+     * getri() computes the inverse of a matrix using  
+     * the LU factorization computed by getrf().
+     */
+
+    namespace detail {
+
+      inline 
+      void getri (int const n, float* a, int const lda, int const* ipiv, 
+                  float* work, int const lwork, int* info) 
+      {
+        LAPACK_SGETRI (&n, a, &lda, ipiv, work, &lwork, info);
+      }
+
+      inline 
+      void getri (int const n, double* a, int const lda, int const* ipiv, 
+                  double* work, int const lwork, int* info) 
+      {
+        LAPACK_DGETRI (&n, a, &lda, ipiv, work, &lwork, info);
+      }
+
+      inline 
+      void getri (int const n, traits::complex_f* a, int const lda, 
+          int const* ipiv, traits::complex_f* work, int const lwork, 
+          int* info) 
+      {
+        LAPACK_CGETRI (&n, traits::complex_ptr (a), &lda, ipiv, 
+            traits::complex_ptr (work), &lwork, info);
+      }
+
+      inline 
+      void getri (int const n, traits::complex_d* a, int const lda, 
+          int const* ipiv, traits::complex_d* work, int const lwork, 
+          int* info) 
+      {
+        LAPACK_ZGETRI (&n, traits::complex_ptr (a), &lda, ipiv, 
+            traits::complex_ptr (work), &lwork, info);
+      }
+
+			
+			
+      template <typename MatrA, typename IVec, typename Work>
+      inline
+      int getri (MatrA& a, IVec const& ipiv, Work& work) 
+      {
+	#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
+        BOOST_STATIC_ASSERT((boost::is_same<
+              typename traits::matrix_traits<MatrA>::matrix_structure, 
+              traits::general_t
+              >::value)); 
+	#endif 
+
+        int const n = traits::matrix_size1 (a);
+        assert (n > 0);
+        assert (n <= traits::leading_dimension (a)); 
+        assert (n == traits::matrix_size2 (a));
+        assert (n == traits::vector_size (ipiv)); 
+        assert (n <= traits::vector_size (work)); //Minimal workspace size
+
+        int info;
+        //double* dummy = traits::matrix_storage (a);
+        detail::getri (n, traits::matrix_storage (a), 
+            traits::leading_dimension (a),
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+            traits::vector_storage (ipiv),  
+#else
+            traits::vector_storage_const (ipiv), 
+#endif
+            traits::vector_storage (work),
+            traits::vector_size (work),
+            &info);
+        return info;
+      }
+		
+			
+      inline
+      int getri_block(float)
+      {
+        return lapack::ilaenv(1, "sgetri", "");
+      }
+
+      inline
+      int getri_block(double)
+      {
+        return lapack::ilaenv(1, "dgetri", "");
+      }
+
+      inline
+      int getri_block(traits::complex_f)
+      {
+        return lapack::ilaenv(1, "cgetri", "");
+      }
+
+      inline
+      int getri_block(traits::complex_d)
+      {
+        return lapack::ilaenv(1, "zgetri", "");
+      }
+
+    } // namespace detail
+
+		
+    template <typename MatrA, typename IVec>
+    inline
+    int getri(MatrA& a, IVec& ipiv, minimal_workspace)
+    {
+      typedef typename MatrA::value_type value_type;
+
+      int n = traits::matrix_size1(a);
+      traits::detail::array<value_type> work(std::max<int>(1,n));
+
+      return detail::getri(a, ipiv, work);
+
+    } 
+
+
+    // optimal workspace allocation
+    template <typename MatrA, typename IVec>
+    inline
+    int getri(MatrA& a, IVec& ipiv, optimal_workspace)
+    {
+      typedef typename MatrA::value_type value_type;
+
+      int n = traits::matrix_size1(a);
+      int nb = detail::getri_block(value_type());
+      traits::detail::array<value_type> work(std::max<int>(1,n*nb));
+
+      return detail::getri(a, ipiv, work);
+    }
+
+
+    template <typename MatrA, typename IVec>
+    inline
+    int getri(MatrA& a, IVec& ipiv)
+    {
+      return getri(a, ipiv, optimal_workspace());
+    }
+
+
+    template <typename MatrA, typename IVec, typename Work>
+    inline
+    int getri(MatrA& a, IVec& ipiv, Work& work)
+    {
+      return detail::getri(a, ipiv, work);
+    } 
+
+  } // namespace lapack
+
+}}} // namespace boost::numeric::bindings
+
 
-  }
 
-}}}
 
 #endif 
Modified: sandbox/boost/numeric/bindings/lapack/lapack.h
==============================================================================
--- sandbox/boost/numeric/bindings/lapack/lapack.h	(original)
+++ sandbox/boost/numeric/bindings/lapack/lapack.h	2008-08-09 18:15:34 EDT (Sat, 09 Aug 2008)
@@ -66,6 +66,14 @@
                       dcomplex_t const* a, int const* lda, int const* ipiv, 
                       dcomplex_t* b, int const* ldb, int* info);
 
+  void LAPACK_SGETRI (int const* n, float* a, int const* lda,	int const* ipiv, 
+		      float* work, int const* lwork, int* info);
+  void LAPACK_DGETRI (int const* n, double* a, int const* lda,	int const* ipiv, 
+		      double* work, int const* lwork, int* info);
+  void LAPACK_CGETRI (int const* n, fcomplex_t* a, int const* lda,	int const* ipiv, 
+		      fcomplex_t* work, int const* lwork, int* info);
+  void LAPACK_ZGETRI (int const* n, dcomplex_t* a, int const* lda,	int const* ipiv, 
+		      dcomplex_t* work, int const* lwork, int* info);
 
   /* symmetric/Hermitian positive definite */
 
@@ -203,6 +211,19 @@
                       dcomplex_t const* a, int const* lda, int const* ipiv, 
                       dcomplex_t* b, int const* ldb, int* info);
 
+  void LAPACK_SSYTRI (char const* uplo, int const* n, float* a, 
+		      int const* lda, int const* ipiv, float* work, 
+		      int* info);
+  void LAPACK_DSYTRI (char const* uplo, int const* n, double* a, 
+		      int const* lda, int const* ipiv, double* work, 
+		      int* info);
+  void LAPACK_CSYTRI (char const* uplo, int const* n, fcomplex_t* a, 
+		      int const* lda, int const* ipiv, fcomplex_t* work, 
+		      int* info);
+  void LAPACK_ZSYTRI (char const* uplo, int const* n, dcomplex_t* a, 
+		      int const* lda, int const* ipiv, dcomplex_t* work, 
+		      int* info);
+ 
   void LAPACK_CHETRS (char const* uplo, int const* n, int const* nrhs,
                       fcomplex_t const* a, int const* lda, int const* ipiv, 
                       fcomplex_t* b, int const* ldb, int* info);
@@ -260,6 +281,15 @@
                       dcomplex_t const* ap, int const* ipiv, 
                       dcomplex_t* b, int const* ldb, int* info);
 
+  void LAPACK_SSPTRI (char const* uplo, int const* n, float const* ap, 
+		      int const* ipiv, float* work, int* info);
+  void LAPACK_DSPTRI (char const* uplo, int const* n, double const* ap, 
+		      int const* ipiv, double* work, int* info);
+  void LAPACK_CSPTRI (char const* uplo, int const* n, fcomplex_t const* ap, 
+		      int const* ipiv, fcomplex_t* work, int* info);
+  void LAPACK_ZSPTRI (char const* uplo, int const* n, dcomplex_t const* ap, 
+		      int const* ipiv, dcomplex_t* work, int* info);
+
   void LAPACK_CHPTRS (char const* uplo, int const* n, int const* nrhs,
                       fcomplex_t const* ap, int const* ipiv, 
                       fcomplex_t* b, int const* ldb, int* info);
Modified: sandbox/boost/numeric/bindings/lapack/lapack_names.h
==============================================================================
--- sandbox/boost/numeric/bindings/lapack/lapack_names.h	(original)
+++ sandbox/boost/numeric/bindings/lapack/lapack_names.h	2008-08-09 18:15:34 EDT (Sat, 09 Aug 2008)
@@ -114,6 +114,12 @@
 #define LAPACK_CHETRS FORTRAN_ID( chetrs )
 #define LAPACK_ZHETRS FORTRAN_ID( zhetrs )
 
+#define LAPACK_SSYTRI FORTRAN_ID( ssytri )
+#define LAPACK_DSYTRI FORTRAN_ID( dsytri )
+#define LAPACK_CSYTRI FORTRAN_ID( csytri )
+#define LAPACK_ZSYTRI FORTRAN_ID( zsytri )
+
+
 
 /* symmetric/Hermitian indefinite and complex symmetric in packed storage */
 
@@ -138,6 +144,18 @@
 #define LAPACK_CHPTRS FORTRAN_ID( chptrs )
 #define LAPACK_ZHPTRS FORTRAN_ID( zhptrs )
 
+#define LAPACK_SSPTRI FORTRAN_ID( ssptri )
+#define LAPACK_DSPTRI FORTRAN_ID( dsptri )
+#define LAPACK_CSPTRI FORTRAN_ID( csptri )
+#define LAPACK_ZSPTRI FORTRAN_ID( zsptri )
+#define LAPACK_CHPTRI FORTRAN_ID( chptri )
+#define LAPACK_ZHPTRI FORTRAN_ID( zhptri )
+
+/* banded solve */
+
+#define LAPACK_DGBTRF FORTRAN_ID( dgbtrf )
+#define LAPACK_DGBTRS FORTRAN_ID( dgbtrs )
+
 
 /********************************************/
 /* eigenproblems */ 
Modified: sandbox/boost/numeric/bindings/lapack/spsv.hpp
==============================================================================
--- sandbox/boost/numeric/bindings/lapack/spsv.hpp	(original)
+++ sandbox/boost/numeric/bindings/lapack/spsv.hpp	2008-08-09 18:15:34 EDT (Sat, 09 Aug 2008)
@@ -293,10 +293,75 @@
     }
 
 
-    // TO DO: sptri 
+    namespace detail {
+      inline 
+      void sptri (char const uplo, int const n, 
+          float* ap, int* ipiv, float* work, int* info) 
+      {
+        LAPACK_SSPTRI (&uplo, &n, ap, ipiv, work, info);
+      }
+
+      inline 
+      void sptri (char const uplo, int const n, 
+          double* ap, int* ipiv, double* work, int* info) 
+      {
+        LAPACK_DSPTRI (&uplo, &n, ap, ipiv, work, info);
+      }
+
+      inline 
+      void sptri (char const uplo, int const n, 
+          traits::complex_f* ap, int* ipiv, traits::complex_f* work, int* info) 
+      {
+        LAPACK_CSPTRI (&uplo, &n, traits::complex_ptr (ap), 
+            ipiv, traits::complex_ptr (work), info);
+      }
+
+      inline 
+      void sptri (char const uplo, int const n, 
+          traits::complex_d* ap, int* ipiv, traits::complex_d* work, int* info) 
+      {
+        LAPACK_ZSPTRI (&uplo, &n, traits::complex_ptr (ap), 
+            ipiv, traits::complex_ptr (work), info);
+      }
+    } // namespace detail
+
+    template <typename SymmA, typename IVec>
+    inline
+    int sptri (SymmA& a, IVec& ipiv) 
+    {
+#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
+      BOOST_STATIC_ASSERT((boost::is_same<
+        typename traits::matrix_traits<SymmA>::matrix_structure, 
+        traits::symmetric_packed_t
+      >::value));
+#endif
+
+      int const n = traits::matrix_size1 (a);
+      assert (n == traits::matrix_size2 (a)); 
+      assert (n == traits::vector_size (ipiv)); 
+
+      char uplo = traits::matrix_uplo_tag (a);
+      int info; 
+
+      typedef typename SymmA::value_type value_type;
+      traits::detail::array<value_type> work(traits::matrix_size1(a));
+
+      detail::sptri (uplo, n, traits::matrix_storage (a), 
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+          traits::vector_storage (ipiv),  
+#else
+          traits::vector_storage_const (ipiv), 
+#endif
+          traits::vector_storage (work),
+          &info);
+      return info; 
+    }
+
+  } // namespace lapack
+
+}}} // namespace boost::numeric::bindings
+
 
-  }
 
-}}}
 
 #endif 
Modified: sandbox/boost/numeric/bindings/lapack/sysv.hpp
==============================================================================
--- sandbox/boost/numeric/bindings/lapack/sysv.hpp	(original)
+++ sandbox/boost/numeric/bindings/lapack/sysv.hpp	2008-08-09 18:15:34 EDT (Sat, 09 Aug 2008)
@@ -17,8 +17,11 @@
 #include <boost/numeric/bindings/traits/type_traits.hpp>
 #include <boost/numeric/bindings/traits/traits.hpp>
 #include <boost/numeric/bindings/lapack/lapack.h>
-#include <boost/numeric/bindings/lapack/ilaenv.hpp>
 #include <boost/numeric/bindings/traits/detail/array.hpp>
+#include "boost/numeric/bindings/traits/ublas_symmetric.hpp"
+#include <boost/numeric/bindings/lapack/ilaenv.hpp>
+#include <boost/numeric/bindings/lapack/workspace.hpp>
+
 
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
 #  include <boost/static_assert.hpp>
@@ -40,7 +43,8 @@
     namespace detail {
 
       inline 
-      int sytrf_block (float, int const ispec, char const ul, int const n) {
+      int sytrf_block (float, int const ispec, char const ul, int const n) 
+      {
         char ul2[2] = "x"; ul2[0] = ul; 
         return ilaenv (ispec, "SSYTRF", ul2, n); 
       }
@@ -63,14 +67,13 @@
         char ul2[2] = "x"; ul2[0] = ul; 
         return ilaenv (ispec, "ZSYTRF", ul2, n); 
       }
-
     }
 
 
     template <typename SymmA>
     inline
-    int sytrf_block (char const q, char const ul, SymmA const& a) {
-
+    int sytrf_block (char const q, char const ul, SymmA const& a) 
+    {
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
       BOOST_STATIC_ASSERT((boost::is_same<
         typename traits::matrix_traits<SymmA>::matrix_structure, 
@@ -94,8 +97,8 @@
 
     template <typename SymmA>
     inline
-    int sytrf_block (char const q, SymmA const& a) {
-
+    int sytrf_block (char const q, SymmA const& a) 
+    {
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
       BOOST_STATIC_ASSERT((boost::is_same<
         typename traits::matrix_traits<SymmA>::matrix_structure, 
@@ -119,8 +122,8 @@
 
     template <typename SymmA>
     inline
-    int sytrf_work (char const q, char const ul, SymmA const& a) {
-
+    int sytrf_work (char const q, char const ul, SymmA const& a) 
+    {
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
       BOOST_STATIC_ASSERT((boost::is_same<
         typename traits::matrix_traits<SymmA>::matrix_structure, 
@@ -202,7 +205,8 @@
      * of equations A * X = B.
      */
 
-    namespace detail {
+    namespace detail 
+    {
 
       inline 
       void sysv (char const uplo, int const n, int const nrhs,
@@ -248,8 +252,8 @@
 
       template <typename SymmA, typename MatrB, typename IVec, typename Work>
       inline
-      int sysv (char const ul, SymmA& a, IVec& i, MatrB& b, Work& w) {
-
+      int sysv (char const ul, SymmA& a, IVec& i, MatrB& b, Work& w) 
+      {
         int const n = traits::matrix_size1 (a);
         assert (n == traits::matrix_size2 (a)); 
         assert (n == traits::matrix_size1 (b)); 
@@ -272,8 +276,8 @@
 
     template <typename SymmA, typename MatrB, typename IVec, typename Work>
     inline
-    int sysv (char const ul, SymmA& a, IVec& i, MatrB& b, Work& w) {
-
+    int sysv (char const ul, SymmA& a, IVec& i, MatrB& b, Work& w) 
+    {
       assert (ul == 'U' || ul == 'L'); 
 
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
@@ -313,7 +317,8 @@
 
     template <typename SymmA, typename MatrB>
     inline
-    int sysv (char const ul, SymmA& a, MatrB& b) {
+    int sysv (char const ul, SymmA& a, MatrB& b) 
+    {
       // with 'internal' pivot and work vectors 
 
       assert (ul == 'U' || ul == 'L'); 
@@ -351,7 +356,8 @@
 
     template <typename SymmA, typename MatrB>
     inline
-    int sysv (SymmA& a, MatrB& b) {
+    int sysv (SymmA& a, MatrB& b) 
+    {
       // with 'internal' pivot and work vectors 
 
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
@@ -397,8 +403,8 @@
      * 1-by-1 and 2-by-2 diagonal blocks.
      */
 
-    namespace detail {
-
+    namespace detail 
+    {
       inline 
       void sytrf (char const uplo, int const n, 
                   float* a, int const lda, int* ipiv, 
@@ -457,8 +463,8 @@
 
     template <typename SymmA, typename IVec, typename Work>
     inline
-    int sytrf (char const ul, SymmA& a, IVec& i, Work& w) {
-
+    int sytrf (char const ul, SymmA& a, IVec& i, Work& w) 
+    {
       assert (ul == 'U' || ul == 'L'); 
 
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
@@ -474,8 +480,8 @@
 
     template <typename SymmA, typename IVec, typename Work>
     inline
-    int sytrf (SymmA& a, IVec& i, Work& w) {
-
+    int sytrf (SymmA& a, IVec& i, Work& w) 
+    {
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
       BOOST_STATIC_ASSERT((boost::is_same<
         typename traits::matrix_traits<SymmA>::matrix_structure, 
@@ -490,7 +496,8 @@
 
     template <typename SymmA, typename Ivec>
     inline
-    int sytrf (char const ul, SymmA& a, Ivec& i) {
+    int sytrf (char const ul, SymmA& a, Ivec& i) 
+    {
       // with 'internal' work vector
 
       assert (ul == 'U' || ul == 'L'); 
@@ -518,7 +525,8 @@
 
     template <typename SymmA, typename Ivec>
     inline
-    int sytrf (SymmA& a, Ivec& i) {
+    int sytrf (SymmA& a, Ivec& i) 
+    {
       // with 'internal' work vector 
 
 #ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
@@ -660,10 +668,119 @@
     }
 
 
-    // TO DO: sytri 
 
-  }
+    namespace detail 
+    {
+      inline 
+      void sytri (char const uplo, int const n, float* a, int const lda, 
+          int const* ipiv, float* work, int* info) 
+      {
+        LAPACK_SSYTRI (&uplo, &n, a, &lda, ipiv, work, info);
+      }
+
+      inline 
+      void sytri (char const uplo, int const n, double* a, int const lda, 
+          int const* ipiv, double* work, int* info) 
+      {
+        LAPACK_DSYTRI (&uplo, &n, a, &lda, ipiv, work, info);
+      }
+
+      inline 
+      void sytri (char const uplo, int const n, traits::complex_f* a, 
+          int const lda, int const* ipiv, traits::complex_f* work, int* info) 
+      {
+        LAPACK_CSYTRI (&uplo, &n, traits::complex_ptr (a), &lda, ipiv, 
+            traits::complex_ptr (work), info);
+      }
+
+      inline 
+      void sytri (char const uplo, int const n, traits::complex_d* a, 
+          int const lda, int const* ipiv, traits::complex_d* work, int* info) 
+      {
+        LAPACK_ZSYTRI (&uplo, &n, traits::complex_ptr (a), &lda, ipiv,
+            traits::complex_ptr (work), info);
+      }
+
+      template <typename SymmA, typename IVec, typename Work>
+      inline
+      int sytri (char const ul, SymmA& a, IVec const& ipiv, Work& work) 
+      {
+        assert (ul == 'U' || ul == 'L'); 
+
+        int const n = traits::matrix_size1 (a);
+        assert (n == traits::matrix_size2 (a)); 
+        assert (n == traits::vector_size (ipiv));
+        assert (n == traits::vector_size (work));
+
+        int info;
+        //const double* dummy = traits::matrix_storage (a);
+        detail::sytri (ul, n, traits::matrix_storage (a), 
+            traits::leading_dimension (a),
+#ifndef BOOST_NO_FUNCTION_TEMPLATE_ORDERING
+            traits::vector_storage (ipiv),  
+#else
+            traits::vector_storage_const (ipiv), 
+#endif
+            traits::vector_storage (work),
+            &info);
+        return info;
+      }
+
+    } // namespace detail
+
+
+    //Internal allocation of workspace, general matrix with up/low tag
+    template <typename SymmA, typename IVec>
+    inline
+    int sytri (char const ul, SymmA& a, IVec const& ipiv) 
+    {
+      assert (ul == 'U' || ul == 'L'); 
+
+#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
+      BOOST_STATIC_ASSERT((boost::is_same<
+            typename traits::matrix_traits<SymmA>::matrix_structure, 
+            traits::general_t
+            >::value));
+#endif
+
+      typedef typename SymmA::value_type value_type;
+      int n = traits::matrix_size1(a);
+      traits::detail::array<value_type> work(std::max<int>(1,n));
+
+      return detail::sytri (ul, a, ipiv, work); 
+    }
+
+    //Internal allocation of workspace, symmetric matrix
+
+    /*Warning: the function will work only if SymmA is a 
+      symmetric_adaptor. With SymmA = symmetric_matrix a
+      boost::STATIC_ASSERTION_FAILURE will be thrown at compile
+      time, because symmetric_matrix has a symmetric_packed_t 
+      structure instead of symmetric_t. Use sptri() for
+      symmetric packed matrices.
+      */  
+    template <typename SymmA, typename IVec>
+    inline
+    int sytri (SymmA& a, IVec const& ipiv) 
+    {
+
+#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK
+      BOOST_STATIC_ASSERT((boost::is_same<
+        typename traits::matrix_traits<SymmA>::matrix_structure, 
+        traits::symmetric_t
+      >::value));
+#endif
+
+      typedef typename SymmA::value_type value_type;
+      int n = traits::matrix_size1(a);
+      traits::detail::array<value_type> work(std::max<int>(1,n));
+
+      char uplo = traits::matrix_uplo_tag (a);
+      return detail::sytri (uplo, a, ipiv, work); 
+    } 
+
+  } // namespace lapack
 
-}}}
+}}} // namespace boost::numeric::bindings
 
 #endif