TooN
gaussian_elimination.h
1 // -*- c++ -*-
2 
3 // Copyright (C) 2008,2009 Ethan Eade, Tom Drummond (twd20@cam.ac.uk)
4 // and Ed Rosten (er258@cam.ac.uk)
5 
6 //All rights reserved.
7 //
8 //Redistribution and use in source and binary forms, with or without
9 //modification, are permitted provided that the following conditions
10 //are met:
11 //1. Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 //2. Redistributions in binary form must reproduce the above copyright
14 // notice, this list of conditions and the following disclaimer in the
15 // documentation and/or other materials provided with the distribution.
16 //
17 //THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 //AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 //IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 //ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 //LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 //CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 //SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 //INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 //CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 //ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 //POSSIBILITY OF SUCH DAMAGE.
28 
29 
30 #ifndef GAUSSIAN_ELIMINATION_H
31 #define GAUSSIAN_ELIMINATION_H
32 
33 #include <utility>
34 #include <cmath>
35 #include <TooN/TooN.h>
36 
37 namespace TooN {
42  template<int N, typename Precision>
44  using std::swap;
45  using std::abs;
46 
47  int size=b.size();
48 
49  for (int i=0; i<size; ++i) {
50  int argmax = i;
51  Precision maxval = abs(A[i][i]);
52 
53  for (int ii=i+1; ii<size; ++ii) {
54  double v = abs(A[ii][i]);
55  if (v > maxval) {
56  maxval = v;
57  argmax = ii;
58  }
59  }
60  Precision pivot = A[argmax][i];
61  //assert(abs(pivot) > 1e-16);
62  Precision inv_pivot = static_cast<Precision>(1)/pivot;
63  if (argmax != i) {
64  for (int j=i; j<size; ++j)
65  swap(A[i][j], A[argmax][j]);
66  swap(b[i], b[argmax]);
67  }
68  //A[i][i] = 1;
69  for (int j=i+1; j<size; ++j)
70  A[i][j] *= inv_pivot;
71  b[i] *= inv_pivot;
72 
73  for (int u=i+1; u<size; ++u) {
74  double factor = A[u][i];
75  //A[u][i] = 0;
76  for (int j=i+1; j<size; ++j)
77  A[u][j] -= factor * A[i][j];
78  b[u] -= factor * b[i];
79  }
80  }
81 
82  Vector<N,Precision> x(size);
83  for (int i=size-1; i>=0; --i) {
84  x[i] = b[i];
85  for (int j=i+1; j<size; ++j)
86  x[i] -= A[i][j] * x[j];
87  }
88  return x;
89  }
90 
91  namespace Internal
92  {
93  template<int i, int j, int k> struct Size3
94  {
95  static const int s = !IsStatic<i>::is?i: (!IsStatic<j>::is?j:k);
96  };
97 
98  };
99 
104  template<int R1, int C1, int R2, int C2, typename Precision>
106  using std::swap;
107  using std::abs;
108  SizeMismatch<R1, C1>::test(A.num_rows(), A.num_cols());
109  SizeMismatch<R1, R2>::test(A.num_rows(), b.num_rows());
110 
111  int size=A.num_rows();
112 
113  for (int i=0; i<size; ++i) {
114  int argmax = i;
115  Precision maxval = abs(A[i][i]);
116 
117  for (int ii=i+1; ii<size; ++ii) {
118  Precision v = abs(A[ii][i]);
119  if (v > maxval) {
120  maxval = v;
121  argmax = ii;
122  }
123  }
124  Precision pivot = A[argmax][i];
125  //assert(abs(pivot) > 1e-16);
126  Precision inv_pivot = static_cast<Precision>(1)/pivot;
127  if (argmax != i) {
128  for (int j=i; j<size; ++j)
129  swap(A[i][j], A[argmax][j]);
130 
131  for(int j=0; j < b.num_cols(); j++)
132  swap(b[i][j], b[argmax][j]);
133  }
134  //A[i][i] = 1;
135  for (int j=i+1; j<size; ++j)
136  A[i][j] *= inv_pivot;
137  b[i] *= inv_pivot;
138 
139  for (int u=i+1; u<size; ++u) {
140  Precision factor = A[u][i];
141  //A[u][i] = 0;
142  for (int j=i+1; j<size; ++j)
143  A[u][j] -= factor * A[i][j];
144  b[u] -= factor * b[i];
145  }
146  }
147 
148  Matrix<Internal::Size3<R1, C1, R2>::s,C2,Precision> x(b.num_rows(), b.num_cols());
149  for (int i=size-1; i>=0; --i) {
150  for(int k=0; k <b.num_cols(); k++)
151  {
152  x[i][k] = b[i][k];
153  for (int j=i+1; j<size; ++j)
154  x[i][k] -= A[i][j] * x[j][k];
155  }
156  }
157  return x;
158  }
159 }
160 #endif
Pretty generic SFINAE introspection generator.
Definition: vec_test.cc:21
Definition: TooN.h:294
Definition: size_mismatch.hh:103
Vector< N, Precision > gaussian_elimination(Matrix< N, N, Precision > A, Vector< N, Precision > b)
Return the solution for , given and .
Definition: gaussian_elimination.h:43
Definition: gaussian_elimination.h:93