vmmlib  1.7.0
 All Classes Namespaces Functions Pages
lapack_gaussian_elimination.hpp
1 /*
2  * Copyright (c) 2006-2014, Visualization and Multimedia Lab,
3  * University of Zurich <http://vmml.ifi.uzh.ch>,
4  * Eyescale Software GmbH,
5  * Blue Brain Project, EPFL
6  *
7  * This file is part of VMMLib <https://github.com/VMML/vmmlib/>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions are met:
11  *
12  * Redistributions of source code must retain the above copyright notice, this
13  * list of conditions and the following disclaimer. Redistributions in binary
14  * form must reproduce the above copyright notice, this list of conditions and
15  * the following disclaimer in the documentation and/or other materials provided
16  * with the distribution. Neither the name of the Visualization and Multimedia
17  * Lab, University of Zurich nor the names of its contributors may be used to
18  * endorse or promote products derived from this software without specific prior
19  * written permission.
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 #ifndef __VMML__VMMLIB_LAPACK_GAUSSIAN_ELIMINATION__HPP__
33 #define __VMML__VMMLIB_LAPACK_GAUSSIAN_ELIMINATION__HPP__
34 
35 #include <vmmlib/matrix.hpp>
36 #include <vmmlib/vector.hpp>
37 #include <vmmlib/exception.hpp>
38 
39 #include <vmmlib/lapack_types.hpp>
40 #include <vmmlib/lapack_includes.hpp>
41 
42 #include <string>
43 
54 namespace vmml
55 {
56 
57 // XYYZZZ
58 // X = data type: S - float, D - double
59 // YY = matrix type, GE - general, TR - triangular
60 // ZZZ = function name
61 
62 namespace lapack
63 {
64 
65 //
66 //
67 //
68 // SGESV/DGESV
69 //
70 //
71 
72 template< typename float_t >
74 {
75  lapack_int n; // order of matrix A = M * N
76  lapack_int nrhs; // number of columns of B
77  float_t* a; // input A, output P*L*U
78  lapack_int lda; // leading dimension of A (for us: number of rows)
79  lapack_int* ipiv; // pivot indices, integer array of size N
80  float_t* b; // input b, output X
81  lapack_int ldb; // leading dimension of b
82  lapack_int info;
83 
84  friend std::ostream& operator << ( std::ostream& os,
85  const xgesv_params< float_t >& p )
86  {
87  os
88  << "n " << p.n
89  << " nrhs " << p.nrhs
90  << " lda " << p.lda
91  << " ldb " << p.ldb
92  << " info " << p.info
93  << std::endl;
94  return os;
95  }
96 
97 };
98 
99 
100 #if 0
101 /* Subroutine */ int dgesv_(integer *n, integer *nrhs, doublereal *a, integer
102  *lda, integer *ipiv, doublereal *b, integer *ldb, integer *info);
103 #endif
104 
105 
106 template< typename float_t >
107 inline void
108 xgesv_call( xgesv_params< float_t >& )
109 {
110  VMMLIB_ERROR( "not implemented for this type.", VMMLIB_HERE );
111 }
112 
113 
114 template<>
115 inline void
116 xgesv_call( xgesv_params< float >& p )
117 {
118  sgesv_(
119  &p.n,
120  &p.nrhs,
121  p.a,
122  &p.lda,
123  p.ipiv,
124  p.b,
125  &p.ldb,
126  &p.info
127  );
128 
129 }
130 
131 
132 template<>
133 inline void
134 xgesv_call( xgesv_params< double >& p )
135 {
136  dgesv_(
137  &p.n,
138  &p.nrhs,
139  p.a,
140  &p.lda,
141  p.ipiv,
142  p.b,
143  &p.ldb,
144  &p.info
145  );
146 }
147 
148 
149 template< size_t M, size_t N, typename float_t >
151 {
152  // computes x ( Ax = b ). x replaces b on output.
153  void compute(
156  );
157 
158  void compute(
161  );
162 
165 
166  const lapack::xgesv_params< float_t >& get_params() { return p; }
167 
169 
170 }; // struct lapack_linear_least_squares
171 
172 
173 
174 template< size_t M, size_t N, typename float_t >
175 void
177 compute(
180  )
181 {
182  p.a = A.array;
183  p.b = b.array;
184 
185  lapack::xgesv_call( p );
186 
187  if ( p.info != 0 )
188  {
189  if ( p.info < 0 )
190  VMMLIB_ERROR( "invalid value in input matrix", VMMLIB_HERE );
191  else
192  VMMLIB_ERROR( "factor U is exactly singular, solution could not be computed.", VMMLIB_HERE );
193  }
194 }
195 
196 
197 
198 template< size_t M, size_t N, typename float_t >
199 void
200 gaussian_elimination< M, N, float_t >::
201 compute(
202  matrix< N, N, float_t >& A,
203  vector< N, float_t >& b
204  )
205 {
206  p.a = A.array;
207  p.b = b.array;
208 
209  lapack::xgesv_call( p );
210 
211  if ( p.info != 0 )
212  {
213  if ( p.info < 0 )
214  VMMLIB_ERROR( "invalid value in input matrix", VMMLIB_HERE );
215  else
216  VMMLIB_ERROR( "factor U is exactly singular, solution could not be computed.", VMMLIB_HERE );
217  }
218 }
219 
220 
221 
222 template< size_t M, size_t N, typename float_t >
223 gaussian_elimination< M, N, float_t >::
224 gaussian_elimination()
225 {
226  p.n = N;
227  p.nrhs = M;
228  p.lda = N;
229  p.ldb = N;
230  p.ipiv = new lapack_int[ N ];
231 
232 }
233 
234 
235 
236 template< size_t M, size_t N, typename float_t >
237 gaussian_elimination< M, N, float_t >::
238 ~gaussian_elimination()
239 {
240  delete[] p.ipiv;
241 }
242 
243 
244 } // namespace lapack
245 
246 } // namespace vmml
247 
248 #endif