Mercurial > hg > orthanc-stone
annotate Framework/Toolbox/LinearAlgebra.cpp @ 790:9f68155c75b0
speeding up LinearAlgebra::ParseVector()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Tue, 28 May 2019 08:29:01 +0200 |
parents | 5aa728500586 |
children | 61ba4b504e9a |
rev | line source |
---|---|
158 | 1 /** |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
439 | 5 * Copyright (C) 2017-2019 Osimis S.A., Belgium |
158 | 6 * |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "LinearAlgebra.h" | |
23 | |
212
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
24 #include <Core/Logging.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
25 #include <Core/OrthancException.h> |
5412adf19980
resort to OrthancFramework
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
201
diff
changeset
|
26 #include <Core/Toolbox.h> |
158 | 27 |
28 #include <stdio.h> | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
29 #include <boost/numeric/ublas/lu.hpp> |
158 | 30 |
31 namespace OrthancStone | |
32 { | |
33 namespace LinearAlgebra | |
34 { | |
35 void Print(const Vector& v) | |
36 { | |
37 for (size_t i = 0; i < v.size(); i++) | |
38 { | |
39 printf("%g\n", v[i]); | |
40 //printf("%8.2f\n", v[i]); | |
41 } | |
42 printf("\n"); | |
43 } | |
44 | |
45 | |
46 void Print(const Matrix& m) | |
47 { | |
48 for (size_t i = 0; i < m.size1(); i++) | |
49 { | |
50 for (size_t j = 0; j < m.size2(); j++) | |
51 { | |
52 printf("%g ", m(i,j)); | |
53 //printf("%8.2f ", m(i,j)); | |
54 } | |
55 printf("\n"); | |
56 } | |
57 printf("\n"); | |
58 } | |
59 | |
60 | |
61 bool ParseVector(Vector& target, | |
62 const std::string& value) | |
63 { | |
64 std::vector<std::string> items; | |
786
5aa728500586
optimizing constructor of DicomStructureSet
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
439
diff
changeset
|
65 Orthanc::Toolbox::TokenizeString(items, Orthanc::Toolbox::StripSpaces(value), '\\'); |
158 | 66 |
67 target.resize(items.size()); | |
68 | |
69 for (size_t i = 0; i < items.size(); i++) | |
70 { | |
71 try | |
72 { | |
790
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
73 /** |
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
74 * We don't use "boost::lexical_cast<>" here, as it is very |
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
75 * slow. As we are parsing many doubles, we prefer to use |
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
76 * the standard "std::stod" function: |
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
77 * http://www.cplusplus.com/reference/string/stod/ |
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
78 **/ |
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
79 |
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
80 target[i] = std::stod(items[i]); |
158 | 81 } |
790
9f68155c75b0
speeding up LinearAlgebra::ParseVector()
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
786
diff
changeset
|
82 catch (std::exception&) |
158 | 83 { |
84 target.clear(); | |
85 return false; | |
86 } | |
87 } | |
88 | |
89 return true; | |
90 } | |
91 | |
92 | |
93 bool ParseVector(Vector& target, | |
94 const Orthanc::DicomMap& dataset, | |
95 const Orthanc::DicomTag& tag) | |
96 { | |
97 std::string value; | |
98 return (dataset.CopyToString(value, tag, false) && | |
99 ParseVector(target, value)); | |
100 } | |
101 | |
102 | |
103 void NormalizeVector(Vector& u) | |
104 { | |
105 double norm = boost::numeric::ublas::norm_2(u); | |
106 if (!IsCloseToZero(norm)) | |
107 { | |
108 u = u / norm; | |
109 } | |
110 } | |
111 | |
112 | |
113 void CrossProduct(Vector& result, | |
114 const Vector& u, | |
115 const Vector& v) | |
116 { | |
117 if (u.size() != 3 || | |
118 v.size() != 3) | |
119 { | |
120 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
121 } | |
122 | |
123 result.resize(3); | |
124 | |
125 result[0] = u[1] * v[2] - u[2] * v[1]; | |
126 result[1] = u[2] * v[0] - u[0] * v[2]; | |
127 result[2] = u[0] * v[1] - u[1] * v[0]; | |
128 } | |
129 | |
130 | |
131 void FillMatrix(Matrix& target, | |
132 size_t rows, | |
133 size_t columns, | |
134 const double values[]) | |
135 { | |
136 target.resize(rows, columns); | |
137 | |
138 size_t index = 0; | |
139 | |
140 for (size_t y = 0; y < rows; y++) | |
141 { | |
142 for (size_t x = 0; x < columns; x++, index++) | |
143 { | |
144 target(y, x) = values[index]; | |
145 } | |
146 } | |
147 } | |
148 | |
149 | |
150 void FillVector(Vector& target, | |
151 size_t size, | |
152 const double values[]) | |
153 { | |
154 target.resize(size); | |
155 | |
156 for (size_t i = 0; i < size; i++) | |
157 { | |
158 target[i] = values[i]; | |
159 } | |
160 } | |
161 | |
162 | |
163 void Convert(Matrix& target, | |
164 const Vector& source) | |
165 { | |
166 const size_t n = source.size(); | |
167 | |
168 target.resize(n, 1); | |
169 | |
170 for (size_t i = 0; i < n; i++) | |
171 { | |
172 target(i, 0) = source[i]; | |
173 } | |
174 } | |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
175 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
176 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
177 double ComputeDeterminant(const Matrix& a) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
178 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
179 if (a.size1() != a.size2()) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
180 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
181 LOG(ERROR) << "Determinant only exists for square matrices"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
182 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
183 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
184 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
185 // https://en.wikipedia.org/wiki/Rule_of_Sarrus |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
186 if (a.size1() == 1) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
187 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
188 return a(0,0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
189 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
190 else if (a.size1() == 2) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
191 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
192 return a(0,0) * a(1,1) - a(0,1) * a(1,0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
193 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
194 else if (a.size1() == 3) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
195 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
196 return (a(0,0) * a(1,1) * a(2,2) + |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
197 a(0,1) * a(1,2) * a(2,0) + |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
198 a(0,2) * a(1,0) * a(2,1) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
199 a(2,0) * a(1,1) * a(0,2) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
200 a(2,1) * a(1,2) * a(0,0) - |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
201 a(2,2) * a(1,0) * a(0,1)); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
202 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
203 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
204 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
205 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
206 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
207 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
208 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
209 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
210 bool IsOrthogonalMatrix(const Matrix& q, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
211 double threshold) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
212 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
213 // https://en.wikipedia.org/wiki/Orthogonal_matrix |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
214 |
392 | 215 if (q.size1() != q.size2()) |
216 { | |
217 LOG(ERROR) << "An orthogonal matrix must be squared"; | |
218 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
219 } | |
220 | |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
221 using namespace boost::numeric::ublas; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
222 |
392 | 223 const Matrix check = prod(trans(q), q) - identity_matrix<double>(q.size1()); |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
224 |
160 | 225 type_traits<double>::real_type norm = norm_inf(check); |
159
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
226 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
227 return (norm <= threshold); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
228 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
229 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
230 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
231 bool IsOrthogonalMatrix(const Matrix& q) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
232 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
233 return IsOrthogonalMatrix(q, 10.0 * std::numeric_limits<float>::epsilon()); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
234 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
235 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
236 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
237 bool IsRotationMatrix(const Matrix& r, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
238 double threshold) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
239 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
240 return (IsOrthogonalMatrix(r, threshold) && |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
241 IsNear(ComputeDeterminant(r), 1.0, threshold)); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
242 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
243 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
244 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
245 bool IsRotationMatrix(const Matrix& r) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
246 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
247 return IsRotationMatrix(r, 10.0 * std::numeric_limits<float>::epsilon()); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
248 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
249 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
250 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
251 void InvertUpperTriangularMatrix(Matrix& output, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
252 const Matrix& k) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
253 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
254 if (k.size1() != k.size2()) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
255 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
256 LOG(ERROR) << "Determinant only exists for square matrices"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
257 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
258 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
259 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
260 output.resize(k.size1(), k.size2()); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
261 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
262 for (size_t i = 1; i < k.size1(); i++) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
263 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
264 for (size_t j = 0; j < i; j++) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
265 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
266 if (!IsCloseToZero(k(i, j))) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
267 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
268 LOG(ERROR) << "Not an upper triangular matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
269 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
270 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
271 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
272 output(i, j) = 0; // The output is also upper triangular |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
273 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
274 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
275 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
276 if (k.size1() == 3) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
277 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
278 // https://math.stackexchange.com/a/1004181 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
279 double a = k(0, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
280 double b = k(0, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
281 double c = k(0, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
282 double d = k(1, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
283 double e = k(1, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
284 double f = k(2, 2); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
285 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
286 if (IsCloseToZero(a) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
287 IsCloseToZero(d) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
288 IsCloseToZero(f)) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
289 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
290 LOG(ERROR) << "Singular upper triangular matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
291 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
292 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
293 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
294 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
295 output(0, 0) = 1.0 / a; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
296 output(0, 1) = -b / (a * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
297 output(0, 2) = (b * e - c * d) / (a * f * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
298 output(1, 1) = 1.0 / d; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
299 output(1, 2) = -e / (f * d); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
300 output(2, 2) = 1.0 / f; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
301 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
302 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
303 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
304 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
305 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
306 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
307 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
308 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
309 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
310 static void GetGivensComponent(double& c, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
311 double& s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
312 const Matrix& a, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
313 size_t i, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
314 size_t j) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
315 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
316 assert(i < 3 && j < 3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
317 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
318 double x = a(i, i); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
319 double y = a(i, j); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
320 double n = sqrt(x * x + y * y); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
321 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
322 if (IsCloseToZero(n)) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
323 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
324 c = 1; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
325 s = 0; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
326 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
327 else |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
328 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
329 c = x / n; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
330 s = -y / n; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
331 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
332 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
333 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
334 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
335 /** |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
336 * This function computes the RQ decomposition of a 3x3 matrix, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
337 * using Givens rotations. Reference: Algorithm A4.1 (page 579) of |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
338 * "Multiple View Geometry in Computer Vision" (2nd edition). The |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
339 * output matrix "Q" is a rotation matrix, and "R" is upper |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
340 * triangular. |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
341 **/ |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
342 void RQDecomposition3x3(Matrix& r, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
343 Matrix& q, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
344 const Matrix& a) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
345 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
346 using namespace boost::numeric::ublas; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
347 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
348 if (a.size1() != 3 || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
349 a.size2() != 3) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
350 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
351 LOG(ERROR) << "Only applicable to a 3x3 matrix"; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
352 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
353 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
354 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
355 r.resize(3, 3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
356 q.resize(3, 3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
357 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
358 r = a; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
359 q = identity_matrix<double>(3); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
360 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
361 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
362 // Set A(2,1) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
363 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
364 GetGivensComponent(c, s, r, 2, 1); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
365 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
366 double v[9] = { 1, 0, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
367 0, c, -s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
368 0, s, c }; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
369 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
370 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
371 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
372 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
373 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
374 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
375 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
376 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
377 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
378 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
379 // Set A(2,0) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
380 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
381 GetGivensComponent(c, s, r, 2, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
382 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
383 double v[9] = { c, 0, -s, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
384 0, 1, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
385 s, 0, c }; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
386 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
387 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
388 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
389 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
390 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
391 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
392 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
393 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
394 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
395 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
396 // Set A(1,0) to zero |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
397 double c, s; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
398 GetGivensComponent(c, s, r, 1, 0); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
399 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
400 double v[9] = { c, -s, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
401 s, c, 0, |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
402 0, 0, 1 }; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
403 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
404 Matrix g; |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
405 FillMatrix(g, 3, 3, v); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
406 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
407 r = prod(r, g); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
408 q = prod(trans(g), q); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
409 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
410 |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
411 if (!IsCloseToZero(norm_inf(prod(r, q) - a)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
412 !IsRotationMatrix(q) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
413 !IsCloseToZero(r(1, 0)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
414 !IsCloseToZero(r(2, 0)) || |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
415 !IsCloseToZero(r(2, 1))) |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
416 { |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
417 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
418 } |
0a73d76333db
populating LinearAlgebra
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
158
diff
changeset
|
419 } |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
420 |
169 | 421 |
422 bool InvertMatrixUnsafe(Matrix& target, | |
423 const Matrix& source) | |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
424 { |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
425 if (source.size1() != source.size2()) |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
426 { |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
427 LOG(ERROR) << "Inverse only exists for square matrices"; |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
428 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
429 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
430 |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
431 if (source.size1() < 4) |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
432 { |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
433 // For matrices with size below 4, use direct computations |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
434 // instead of LU decomposition |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
435 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
436 if (source.size1() == 0) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
437 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
438 // By convention, the inverse of the empty matrix, is itself the empty matrix |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
439 target.resize(0, 0); |
169 | 440 return true; |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
441 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
442 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
443 double determinant = ComputeDeterminant(source); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
444 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
445 if (IsCloseToZero(determinant)) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
446 { |
169 | 447 return false; |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
448 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
449 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
450 double denominator = 1.0 / determinant; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
451 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
452 target.resize(source.size1(), source.size2()); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
453 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
454 if (source.size1() == 1) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
455 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
456 target(0, 0) = denominator; |
169 | 457 |
458 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
459 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
460 else if (source.size1() == 2) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
461 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
462 // https://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_2_%C3%97_2_matrices |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
463 target(0, 0) = source(1, 1) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
464 target(0, 1) = -source(0, 1) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
465 target(1, 0) = -source(1, 0) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
466 target(1, 1) = source(0, 0) * denominator; |
169 | 467 |
468 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
469 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
470 else if (source.size1() == 3) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
471 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
472 // https://en.wikipedia.org/wiki/Invertible_matrix#Inversion_of_3_%C3%97_3_matrices |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
473 const double a = source(0, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
474 const double b = source(0, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
475 const double c = source(0, 2); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
476 const double d = source(1, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
477 const double e = source(1, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
478 const double f = source(1, 2); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
479 const double g = source(2, 0); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
480 const double h = source(2, 1); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
481 const double i = source(2, 2); |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
482 |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
483 target(0, 0) = (e * i - f * h) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
484 target(0, 1) = -(b * i - c * h) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
485 target(0, 2) = (b * f - c * e) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
486 target(1, 0) = -(d * i - f * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
487 target(1, 1) = (a * i - c * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
488 target(1, 2) = -(a * f - c * d) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
489 target(2, 0) = (d * h - e * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
490 target(2, 1) = -(a * h - b * g) * denominator; |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
491 target(2, 2) = (a * e - b * d) * denominator; |
169 | 492 |
493 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
494 } |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
495 else |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
496 { |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
497 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
498 } |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
499 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
500 else |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
501 { |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
502 // General case, using LU decomposition |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
503 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
504 Matrix a = source; // Copy the source matrix, as "lu_factorize()" modifies it |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
505 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
506 boost::numeric::ublas::permutation_matrix<size_t> permutation(source.size1()); |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
507 |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
508 if (boost::numeric::ublas::lu_factorize(a, permutation) != 0) |
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
509 { |
169 | 510 return false; |
511 } | |
512 else | |
513 { | |
514 target = boost::numeric::ublas::identity_matrix<double>(source.size1()); | |
515 lu_substitute(a, permutation, target); | |
516 return true; | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
517 } |
169 | 518 } |
519 } | |
520 | |
164
432b1f812d14
inversion of general matrices
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
163
diff
changeset
|
521 |
169 | 522 |
523 void InvertMatrix(Matrix& target, | |
524 const Matrix& source) | |
525 { | |
526 if (!InvertMatrixUnsafe(target, source)) | |
527 { | |
528 LOG(ERROR) << "Cannot invert singular matrix"; | |
529 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
163
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
530 } |
8c5b24892ed2
LinearAlgebra::InvertMatrix
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
161
diff
changeset
|
531 } |
165
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
532 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
533 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
534 void CreateSkewSymmetric(Matrix& s, |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
535 const Vector& v) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
536 { |
392 | 537 if (v.size() != 3) |
538 { | |
539 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); | |
540 } | |
165
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
541 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
542 s.resize(3, 3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
543 s(0,0) = 0; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
544 s(0,1) = -v[2]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
545 s(0,2) = v[1]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
546 s(1,0) = v[2]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
547 s(1,1) = 0; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
548 s(1,2) = -v[0]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
549 s(2,0) = -v[1]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
550 s(2,1) = v[0]; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
551 s(2,2) = 0; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
552 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
553 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
554 |
166 | 555 Matrix InvertScalingTranslationMatrix(const Matrix& t) |
165
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
556 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
557 if (t.size1() != 4 || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
558 t.size2() != 4 || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
559 !LinearAlgebra::IsCloseToZero(t(0,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
560 !LinearAlgebra::IsCloseToZero(t(0,2)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
561 !LinearAlgebra::IsCloseToZero(t(1,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
562 !LinearAlgebra::IsCloseToZero(t(1,2)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
563 !LinearAlgebra::IsCloseToZero(t(2,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
564 !LinearAlgebra::IsCloseToZero(t(2,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
565 !LinearAlgebra::IsCloseToZero(t(3,0)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
566 !LinearAlgebra::IsCloseToZero(t(3,1)) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
567 !LinearAlgebra::IsCloseToZero(t(3,2))) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
568 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
569 LOG(ERROR) << "This matrix is more than a zoom/translate transform"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
570 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
571 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
572 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
573 const double sx = t(0,0); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
574 const double sy = t(1,1); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
575 const double sz = t(2,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
576 const double w = t(3,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
577 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
578 if (LinearAlgebra::IsCloseToZero(sx) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
579 LinearAlgebra::IsCloseToZero(sy) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
580 LinearAlgebra::IsCloseToZero(sz) || |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
581 LinearAlgebra::IsCloseToZero(w)) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
582 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
583 LOG(ERROR) << "Singular transform"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
584 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
585 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
586 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
587 const double tx = t(0,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
588 const double ty = t(1,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
589 const double tz = t(2,3); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
590 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
591 Matrix m = IdentityMatrix(4); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
592 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
593 m(0,0) = 1.0 / sx; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
594 m(1,1) = 1.0 / sy; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
595 m(2,2) = 1.0 / sz; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
596 m(3,3) = 1.0 / w; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
597 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
598 m(0,3) = -tx / (sx * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
599 m(1,3) = -ty / (sy * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
600 m(2,3) = -tz / (sz * w); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
601 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
602 return m; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
603 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
604 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
605 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
606 bool IsShearMatrix(const Matrix& shear) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
607 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
608 return (shear.size1() == 4 && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
609 shear.size2() == 4 && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
610 LinearAlgebra::IsNear(1.0, shear(0,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
611 LinearAlgebra::IsNear(0.0, shear(0,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
612 LinearAlgebra::IsNear(0.0, shear(0,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
613 LinearAlgebra::IsNear(0.0, shear(1,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
614 LinearAlgebra::IsNear(1.0, shear(1,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
615 LinearAlgebra::IsNear(0.0, shear(1,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
616 LinearAlgebra::IsNear(0.0, shear(2,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
617 LinearAlgebra::IsNear(0.0, shear(2,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
618 LinearAlgebra::IsNear(1.0, shear(2,2)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
619 LinearAlgebra::IsNear(0.0, shear(2,3)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
620 LinearAlgebra::IsNear(0.0, shear(3,0)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
621 LinearAlgebra::IsNear(0.0, shear(3,1)) && |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
622 LinearAlgebra::IsNear(1.0, shear(3,3))); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
623 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
624 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
625 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
626 Matrix InvertShearMatrix(const Matrix& shear) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
627 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
628 if (!IsShearMatrix(shear)) |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
629 { |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
630 LOG(ERROR) << "Not a valid shear matrix"; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
631 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
632 } |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
633 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
634 Matrix m = IdentityMatrix(4); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
635 m(0,2) = -shear(0,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
636 m(1,2) = -shear(1,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
637 m(3,2) = -shear(3,2); |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
638 |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
639 return m; |
8d50e6be565d
LinearAlgebra toolbox
Sebastien Jodogne <s.jodogne@gmail.com>
parents:
164
diff
changeset
|
640 } |
158 | 641 } |
642 } |