~ubuntu-branches/ubuntu/maverick/freecad/maverick

« back to all changes in this revision

Viewing changes to src/3rdParty/boost/numeric/bindings/lapack/hbev.hpp

  • Committer: Bazaar Package Importer
  • Author(s): Teemu Ikonen
  • Date: 2009-07-16 18:37:41 UTC
  • Revision ID: james.westby@ubuntu.com-20090716183741-oww9kcxqrk991i1n
Tags: upstream-0.8.2237
ImportĀ upstreamĀ versionĀ 0.8.2237

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * 
 
3
 * Copyright (c) Toon Knapen, Karl Meerbergen & Kresimir Fresl 2003
 
4
 *
 
5
 * Distributed under the Boost Software License, Version 1.0.
 
6
 * (See accompanying file LICENSE_1_0.txt or copy at
 
7
 * http://www.boost.org/LICENSE_1_0.txt)
 
8
 *
 
9
 * KF acknowledges the support of the Faculty of Civil Engineering, 
 
10
 * University of Zagreb, Croatia.
 
11
 *
 
12
 */
 
13
 
 
14
#ifndef BOOST_NUMERIC_BINDINGS_LAPACK_HBEV_HPP
 
15
#define BOOST_NUMERIC_BINDINGS_LAPACK_HBEV_HPP
 
16
 
 
17
#include <boost/numeric/bindings/traits/type.hpp>
 
18
#include <boost/numeric/bindings/traits/traits.hpp>
 
19
#include <boost/numeric/bindings/traits/type_traits.hpp>
 
20
#include <boost/numeric/bindings/lapack/lapack.h>
 
21
#include <boost/numeric/bindings/lapack/workspace.hpp>
 
22
#include <boost/numeric/bindings/traits/detail/array.hpp>
 
23
#include <boost/numeric/bindings/traits/detail/utils.hpp>
 
24
 
 
25
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
 
26
#  include <boost/static_assert.hpp>
 
27
#  include <boost/type_traits.hpp>
 
28
#endif 
 
29
 
 
30
 
 
31
namespace boost { namespace numeric { namespace bindings { 
 
32
 
 
33
  namespace lapack {
 
34
 
 
35
    ///////////////////////////////////////////////////////////////////
 
36
    //
 
37
    // Eigendecomposition of a banded Hermitian matrix.
 
38
    // 
 
39
    ///////////////////////////////////////////////////////////////////
 
40
 
 
41
    /* 
 
42
     * hbev() computes the eigenvalues and optionally the associated
 
43
     * eigenvectors of a banded Hermitian matrix A. A matrix is Hermitian
 
44
     * when herm( A ) == A. When A is real, a Hermitian matrix is also
 
45
     * called symmetric.
 
46
     *
 
47
     * The eigen decomposition is A = U S * herm(U)  where  U  is a
 
48
     * unitary matrix and S is a diagonal matrix. The eigenvalues of A
 
49
     * are on the main diagonal of S. The eigenvalues are real.
 
50
     *
 
51
     * Workspace is organized following the arguments in the calling sequence.
 
52
     *  optimal_workspace() : for optimizing use of blas 3 kernels
 
53
     *  minimal_workspace() : minimum size of workarrays, but does not allow for optimization
 
54
     *                        of blas 3 kernels
 
55
     *  workspace( work ) for real matrices where work is a real array with
 
56
     *                    vector_size( work ) >= 3*matrix_size1( a ) - 2
 
57
     *  workspace( work, rwork ) for complex matrices where work is a complex
 
58
     *                           array with vector_size( work ) >= matrix_size1( a )
 
59
     *                           and rwork is a real array with
 
60
     *                           vector_size( rwork ) >= 3 * matrix_size1( a ) - 2.
 
61
     */
 
62
 
 
63
    /*
 
64
     * If uplo=='L' only the lower triangular part is stored.
 
65
     * If uplo=='U' only the upper triangular part is stored.
 
66
     *
 
67
     * The matrix is assumed to be stored in LAPACK band format, i.e.
 
68
     * matrices are stored columnwise, in a compressed format so that when e.g. uplo=='U'
 
69
     * the (i,j) element with j>=i is in position  (i-j) + j * (KD+1) + KD  where KD is the
 
70
     * half bandwidth of the matrix. For a triadiagonal matrix, KD=1, for a diagonal matrix
 
71
     * KD=0.
 
72
     * When uplo=='L', the (i,j) element with j>=i is in position  (i-j) + j * (KD+1).
 
73
     *
 
74
     * The matrix A is thus a rectangular matrix with KD+1 rows and N columns.
 
75
     */ 
 
76
 
 
77
    namespace detail {
 
78
      inline 
 
79
      void hbev (char const jobz, char const uplo, int const n, int const kd,
 
80
                 float* ab, int const ldab, float* w, float* z, int const ldz,
 
81
                 float* work, int& info) 
 
82
      {
 
83
              //for (int i=0; i<n*kd; ++i) std::cout << *(ab+i) << " " ;
 
84
              //std::cout << "\n" ;
 
85
        LAPACK_SSBEV (&jobz, &uplo, &n, &kd, ab, &ldab, w, z, &ldz,
 
86
                      work, &info);
 
87
      }
 
88
 
 
89
      inline 
 
90
      void hbev (char const jobz, char const uplo, int const n, int const kd,
 
91
                 double* ab, int const ldab, double* w, double* z, int const ldz,
 
92
                 double* work, int& info) 
 
93
      {
 
94
        LAPACK_DSBEV (&jobz, &uplo, &n, &kd, ab, &ldab, w, z, &ldz,
 
95
                      work, &info);
 
96
      }
 
97
 
 
98
      inline 
 
99
      void hbev (char const jobz, char const uplo, int const n, int const kd,
 
100
                 traits::complex_f* ab, int const ldab, float* w,
 
101
                 traits::complex_f* z, int const ldz,
 
102
                 traits::complex_f* work, float* rwork, int& info) 
 
103
      {
 
104
        LAPACK_CHBEV (&jobz, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
 
105
                      w, traits::complex_ptr(z), &ldz,
 
106
                      traits::complex_ptr(work), rwork, &info);
 
107
      }
 
108
 
 
109
      inline 
 
110
      void hbev (char const jobz, char const uplo, int const n, int const kd,
 
111
                 traits::complex_d* ab, int const ldab, double* w,
 
112
                 traits::complex_d* z, int const ldz,
 
113
                 traits::complex_d* work, double* rwork, int& info) 
 
114
      {
 
115
        LAPACK_ZHBEV (&jobz, &uplo, &n, &kd, traits::complex_ptr(ab), &ldab,
 
116
                      w, traits::complex_ptr(z), &ldz,
 
117
                      traits::complex_ptr(work), rwork, &info);
 
118
      }
 
119
    } 
 
120
 
 
121
 
 
122
    namespace detail {
 
123
       template <int N>
 
124
       struct Hbev{};
 
125
 
 
126
 
 
127
       /// Handling of workspace in the case of one workarray.
 
128
       template <>
 
129
       struct Hbev< 1 > {
 
130
          template <typename T, typename R>
 
131
          void operator() (char const jobz, char const uplo, int const n,
 
132
                           int const kd, T* ab, int const ldab, R* w, T* z,
 
133
                           int const ldz, minimal_workspace , int& info ) const {
 
134
             traits::detail::array<T> work( 3*n-2 );
 
135
             hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
 
136
                   traits::vector_storage( work ),
 
137
                   info );
 
138
          }
 
139
 
 
140
          template <typename T, typename R>
 
141
          void operator() (char const jobz, char const uplo, int const n,
 
142
                           int const kd, T* ab, int const ldab, R* w, T* z,
 
143
                           int const ldz, optimal_workspace , int& info ) const {
 
144
             traits::detail::array<T> work( 3*n-2 );
 
145
 
 
146
             hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
 
147
                   traits::vector_storage( work ),
 
148
                   info );
 
149
          }
 
150
 
 
151
          template <typename T, typename R, typename W>
 
152
          void operator() (char const jobz, char const uplo, int const n,
 
153
                           int const kd, T* ab, int const ldab, R* w, T* z,
 
154
                           int const ldz, detail::workspace1<W> work,
 
155
                           int& info ) const {
 
156
             assert( traits::vector_size( work.w_ ) >= 3*n-2 );
 
157
 
 
158
             hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
 
159
                   traits::vector_storage( work.w_ ),
 
160
                   info );
 
161
          }
 
162
       }; // Hbev< 1 >
 
163
 
 
164
 
 
165
       /// Handling of workspace in the case of two workarrays.
 
166
       template <>
 
167
       struct Hbev< 2 > {
 
168
          template <typename T, typename R>
 
169
          void operator() (char const jobz, char const uplo, int const n,
 
170
                           int const kd, T* ab, int const ldab, R* w, T* z,
 
171
                           int const ldz, minimal_workspace , int& info ) const {
 
172
             traits::detail::array<T> work( n );
 
173
             traits::detail::array<R> rwork( 3*n-2 );
 
174
 
 
175
             hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
 
176
                   traits::vector_storage( work ),
 
177
                   traits::vector_storage( rwork ),
 
178
                   info );
 
179
          }
 
180
 
 
181
          template <typename T, typename R>
 
182
          void operator() (char const jobz, char const uplo, int const n,
 
183
                           int const kd, T* ab, int const ldab, R* w, T* z,
 
184
                           int const ldz, optimal_workspace , int& info ) const {
 
185
             traits::detail::array<T> work( n );
 
186
             traits::detail::array<R> rwork( 3*n-2 );
 
187
 
 
188
             hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
 
189
                   traits::vector_storage( work ),
 
190
                   traits::vector_storage( rwork ),
 
191
                   info );
 
192
          }
 
193
 
 
194
          template <typename T, typename R, typename W, typename RW>
 
195
          void operator() (char const jobz, char const uplo, int const n,
 
196
                           int const kd, T* ab, int const ldab, R* w, T* z,
 
197
                           int const ldz, detail::workspace2<W,RW> work,
 
198
                           int& info ) const {
 
199
             assert( traits::vector_size( work.wr_ ) >= 3*n-2 );
 
200
             assert( traits::vector_size( work.w_ ) >= n );
 
201
 
 
202
             hbev( jobz, uplo, n, kd, ab, ldab, w, z, ldz,
 
203
                   traits::vector_storage( work.w_ ),
 
204
                   traits::vector_storage( work.wr_ ),
 
205
                   info );
 
206
          }
 
207
       }; // Hbev< 2 >
 
208
    
 
209
 
 
210
 
 
211
       /// Compute eigendecomposition of the banded Hermitian matrix ab.
 
212
       /// if jobz=='N' only the eigenvalues are computed.
 
213
       /// if jobz=='V' compute the eigenvalues a and the eigenvectors.
 
214
       ///
 
215
       /// Workspace is organized following the arguments in the calling sequence.
 
216
       ///  optimal_workspace() : for optimizing use of blas 3 kernels
 
217
       ///  minimal_workspace() : minimum size of workarrays, but does not allow for optimization
 
218
       ///                       of blas 3 kernels
 
219
       ///  workspace( work ) for real matrices where work is a real array with
 
220
       ///                    vector_size( work ) >= 3*matrix_size1( a )-2
 
221
       ///  workspace( work, rwork ) for complex matrices where work is a complex
 
222
       ///                           array with vector_size( work ) >= matrix_size1( a )
 
223
       ///                           and rwork is a real array with
 
224
       ///                           vector_size( rwork ) >= 3*matrix_size1( a )-2.
 
225
       template <typename AB, typename Z, typename W, typename Work>
 
226
       int hbev( char const jobz, AB& ab, W& w, Z& z, Work work ) {
 
227
#ifndef BOOST_NUMERIC_BINDINGS_NO_STRUCTURE_CHECK 
 
228
         BOOST_STATIC_ASSERT((boost::is_same<
 
229
           typename traits::matrix_traits<AB>::matrix_structure, 
 
230
           traits::hermitian_t
 
231
         >::value)); 
 
232
#endif 
 
233
 
 
234
         typedef typename AB::value_type                            value_type ;
 
235
 
 
236
         int const n = traits::matrix_size2 (ab);
 
237
         assert (n == traits::matrix_size1 (z)); 
 
238
         assert (n == traits::vector_size (w));
 
239
         assert ( jobz=='N' || jobz=='V' );
 
240
 
 
241
         int info ; 
 
242
         detail::Hbev< n_workspace_args<value_type>::value >() (jobz,
 
243
                       traits::matrix_uplo_tag( ab ), n,
 
244
                       traits::matrix_upper_bandwidth(ab),
 
245
                       traits::matrix_storage (ab), 
 
246
                       traits::leading_dimension (ab),
 
247
                       traits::vector_storage (w),
 
248
                       traits::matrix_storage (z),
 
249
                       traits::leading_dimension (z),
 
250
                       work, info);
 
251
         return info ;
 
252
       } // hbev()
 
253
       
 
254
       } // namespace detail
 
255
 
 
256
 
 
257
       /// Compute eigendecomposition without eigenvectors
 
258
       template <typename AB, typename W, typename Work>
 
259
       inline
 
260
       int hbev (AB& ab, W& w, Work work) {
 
261
          return detail::hbev( 'N', ab, w, ab, work );
 
262
       } // hbev()
 
263
 
 
264
 
 
265
       /// Compute eigendecomposition with eigenvectors
 
266
       template <typename AB, typename W, typename Z, typename Work>
 
267
       inline
 
268
       int hbev (AB& ab, W& w, Z& z, Work work) {
 
269
         BOOST_STATIC_ASSERT((boost::is_same<
 
270
           typename traits::matrix_traits<Z>::matrix_structure, 
 
271
           traits::general_t
 
272
         >::value)); 
 
273
         int const n = traits::matrix_size2 (ab);
 
274
          assert (n == traits::matrix_size1 (z)); 
 
275
          assert (n == traits::matrix_size2 (z)); 
 
276
          return detail::hbev( 'V', ab, w, z, work );
 
277
       } // hbev()
 
278
 
 
279
  }
 
280
 
 
281
}}}
 
282
 
 
283
#endif