Tatooine
inv.h
Go to the documentation of this file.
1#ifndef TATOOINE_TENSOR_OPERATIONS_INV_H
2#define TATOOINE_TENSOR_OPERATIONS_INV_H
3//==============================================================================
6#include <tatooine/mat.h>
7#include <optional>
8//==============================================================================
9namespace tatooine {
10//==============================================================================
14template <fixed_size_quadratic_mat<2> Mat>
15constexpr auto inv_sym(Mat&& A)
16 -> std::optional<mat<tatooine::value_type<Mat>, 2, 2>> {
17 decltype(auto) a = A(0, 0);
18 decltype(auto) b = A(1, 0);
19 decltype(auto) c = A(1, 1);
20 auto const det = a * c - b * b;
21 if (std::abs(det) < 1e-10) {
22 return {};
23 }
24 auto const div = 1 / det;
25 auto const e = -b * div;
27 {c * div, e},
28 {e, a * div}};
29}
30//------------------------------------------------------------------------------
34template <fixed_size_quadratic_mat<2> Mat>
35constexpr auto inv(Mat&& A)
36 -> std::optional<mat<tatooine::value_type<Mat>, 2, 2>> {
37 decltype(auto) b = A(0, 1);
38 decltype(auto) c = A(1, 0);
39 if (std::abs(b - c) < 1e-10) {
40 return inv_sym(A);
41 }
42 decltype(auto) a = A(0, 0);
43 decltype(auto) d = A(1, 1);
44 auto const det = a * d - b * c;
45 if (std::abs(det) < 1e-10) {
46 return std::nullopt;
47 }
48 auto const div = 1 / det;
50 { d* div, -b* div},
51 {-c* div, a* div}} ;
52}
53//------------------------------------------------------------------------------
58template <fixed_size_tensor<3, 3> Mat>
59constexpr auto inv_sym(Mat&& A)
60 -> std::optional<mat<tatooine::value_type<Mat>, 3, 3>> {
61 decltype(auto) a = A(0, 0);
62 decltype(auto) b = A(1, 0);
63 decltype(auto) c = A(2, 0);
64 decltype(auto) d = A(1, 1);
65 decltype(auto) e = A(2, 1);
66 decltype(auto) f = A(2, 2);
67 auto const det =
68 (a * d - b * b) * f - a * e * e + 2 * b * c * e - c * c * d;
69 if (std::abs(det) < 1e-10) {
70 return {};
71 }
72 return mat<tatooine::value_type<Mat>, 3, 3>{
73 {d * f - e * e, c * e - b * f, b * e - c * d},
74 {c * e - b * f, a * f - c * c, b * c - a * e},
75 {b * e - c * d, b * c - a * e, a * d - b * b}} /
76 det;
77}
78//------------------------------------------------------------------------------
83template <fixed_size_quadratic_mat<3> Mat>
84constexpr auto inv(Mat&& A)
85 -> std::optional<mat<tatooine::value_type<Mat>, 3, 3>> {
86 decltype(auto) b = A(0, 1);
87 decltype(auto) c = A(0, 2);
88 decltype(auto) d = A(1, 0);
89 decltype(auto) g = A(2, 0);
90 decltype(auto) f = A(1, 2);
91 decltype(auto) h = A(2, 1);
92 if (std::abs(b - d) < 1e-10 && std::abs(c - g) < 1e-10 &&
93 std::abs(f - h) < 1e-10) {
94 return inv_sym(A);
95 }
96 decltype(auto) a = A(0, 0);
97 decltype(auto) e = A(1, 1);
98 decltype(auto) i = A(2, 2);
99 auto const det =
100 (a * e - b * d) * i + (c * d - a * f) * h + (b * f - c * e) * g;
101 if (std::abs(det) < 1e-10) {
102 return std::nullopt;
103 }
104
105 return mat<tatooine::value_type<Mat>, 3, 3>{
106 {e * i - f * h, c * h - b * i, b * f - c * e},
107 {f * g - d * i, a * i - c * g, c * d - a * f},
108 {d * h - e * g, b * g - a * h, a * e - b * d}} /
109 det;
110}
111//------------------------------------------------------------------------------
117template <fixed_size_quadratic_mat<4> Mat>
118constexpr auto inv_sym(Mat&& A)
119 -> std::optional<mat<tatooine::value_type<Mat>, 4, 4>> {
120 decltype(auto) a = A(0, 0);
121 decltype(auto) b = A(1, 0);
122 decltype(auto) c = A(2, 0);
123 decltype(auto) d = A(3, 0);
124 decltype(auto) e = A(1, 1);
125 decltype(auto) f = A(2, 1);
126 decltype(auto) g = A(3, 1);
127 decltype(auto) h = A(2, 2);
128 decltype(auto) i = A(3, 2);
129 decltype(auto) j = A(3, 3);
130 auto const div =
131 1 / (((a * e - b * b) * h - a * f * f + 2 * b * c * f - c * c * e) * j +
132 (b * b - a * e) * i * i +
133 ((2 * a * f - 2 * b * c) * g - 2 * b * d * f + 2 * c * d * e) * i +
134 (-a * g * g + 2 * b * d * g - d * d * e) * h + c * c * g * g -
135 2 * c * d * f * g + d * d * f * f);
136 return mat{
137 {((e * h - f * f) * j - e * i * i + 2 * f * g * i - g * g * h) * div,
138 -((b * h - c * f) * j - b * i * i + (c * g + d * f) * i - d * g * h) *
139 div,
140 ((b * f - c * e) * j + (d * e - b * g) * i + c * g * g - d * f * g) *
141 div,
142 -((b * f - c * e) * i + (d * e - b * g) * h + c * f * g - d * f * f) *
143 div},
144 {-((b * h - c * f) * j - b * i * i + (c * g + d * f) * i - d * g * h) *
145 div,
146 ((a * h - c * c) * j - a * i * i + 2 * c * d * i - d * d * h) * div,
147 -((a * f - b * c) * j + (b * d - a * g) * i + c * d * g - d * d * f) *
148 div,
149 ((a * f - b * c) * i + (b * d - a * g) * h + c * c * g - c * d * f) *
150 div},
151 {((b * f - c * e) * j + (d * e - b * g) * i + c * g * g - d * f * g) *
152 div,
153 -((a * f - b * c) * j + (b * d - a * g) * i + c * d * g - d * d * f) *
154 div,
155 ((a * e - b * b) * j - a * g * g + 2 * b * d * g - d * d * e) * div,
156 -((a * e - b * b) * i + (b * c - a * f) * g + b * d * f - c * d * e) *
157 div},
158 {-((b * f - c * e) * i + (d * e - b * g) * h + c * f * g - d * f * f) *
159 div,
160 ((a * f - b * c) * i + (b * d - a * g) * h + c * c * g - c * d * f) *
161 div,
162 -((a * e - b * b) * i + (b * c - a * f) * g + b * d * f - c * d * e) *
163 div,
164 ((a * e - b * b) * h - a * f * f + 2 * b * c * f - c * c * e) * div}};
165}
166//------------------------------------------------------------------------------
172template <fixed_size_quadratic_mat<4> Mat>
173constexpr auto inv(Mat && A)
174 -> std::optional<mat<tatooine::value_type<Mat>, 4, 4>> {
175 decltype(auto) b = A(0, 1);
176 decltype(auto) c = A(0, 2);
177 decltype(auto) d = A(0, 3);
178 decltype(auto) e = A(1, 0);
179 decltype(auto) g = A(1, 2);
180 decltype(auto) h = A(1, 3);
181 decltype(auto) i = A(2, 0);
182 decltype(auto) j = A(2, 1);
183 decltype(auto) l = A(2, 3);
184 decltype(auto) m = A(3, 0);
185 decltype(auto) n = A(3, 1);
186 decltype(auto) o = A(3, 2);
187
188 if (std::abs(b - e) < 1e-10 && std::abs(c - i) < 1e-10 &&
189 std::abs(d - m) < 1e-10 && std::abs(g - j) < 1e-10 &&
190 std::abs(h - n) < 1e-10 && std::abs(l - o) < 1e-10) {
191 return inv_sym(A);
192 }
193
194 decltype(auto) a = A(0, 0);
195 decltype(auto) f = A(1, 1);
196 decltype(auto) k = A(2, 2);
197 decltype(auto) p = A(3, 3);
198 const auto det =
199 ((((a * f - b * e) * k + (c * e - a * g) * j + (b * g - c * f) * i) * p +
200 ((b * e - a * f) * l + (a * h - d * e) * j + (d * f - b * h) * i) * o +
201 ((a * g - c * e) * l + (d * e - a * h) * k + (c * h - d * g) * i) * n +
202 ((c * f - b * g) * l + (b * h - d * f) * k + (d * g - c * h) * j) * m));
203 if (std::abs(det) < 1e-10) {
204 return {};
205 }
206 const auto div = 1 / det;
207 return mat{
208 {((f * k - g * j) * p + (h * j - f * l) * o + (g * l - h * k) * n) * div,
209 -((b * k - c * j) * p + (d * j - b * l) * o + (c * l - d * k) * n) * div,
210 ((b * g - c * f) * p + (d * f - b * h) * o + (c * h - d * g) * n) * div,
211 -((b * g - c * f) * l + (d * f - b * h) * k + (c * h - d * g) * j) *
212 div},
213 {-((e * k - g * i) * p + (h * i - e * l) * o + (g * l - h * k) * m) * div,
214 ((a * k - c * i) * p + (d * i - a * l) * o + (c * l - d * k) * m) * div,
215 -((a * g - c * e) * p + (d * e - a * h) * o + (c * h - d * g) * m) * div,
216 ((a * g - c * e) * l + (d * e - a * h) * k + (c * h - d * g) * i) * div},
217 {((e * j - f * i) * p + (h * i - e * l) * n + (f * l - h * j) * m) * div,
218 -((a * j - b * i) * p + (d * i - a * l) * n + (b * l - d * j) * m) * div,
219 ((a * f - b * e) * p + (d * e - a * h) * n + (b * h - d * f) * m) * div,
220 -((a * f - b * e) * l + (d * e - a * h) * j + (b * h - d * f) * i) *
221 div},
222 {-((e * j - f * i) * o + (g * i - e * k) * n + (f * k - g * j) * m) * div,
223 ((a * j - b * i) * o + (c * i - a * k) * n + (b * k - c * j) * m) * div,
224 -((a * f - b * e) * o + (c * e - a * g) * n + (b * g - c * f) * m) * div,
225 ((a * f - b * e) * k + (c * e - a * g) * j + (b * g - c * f) * i) *
226 div}};
227}
228//==============================================================================
229} // namespace tatooine
230//==============================================================================
231#endif
Definition: algorithm.h:6
constexpr auto inv(diag_static_tensor< Tensor, N, N > const &A) -> std::optional< diag_static_tensor< vec< tatooine::value_type< Tensor >, N >, N, N > >
Definition: diag_tensor.h:109
mat(Rows const(&&... rows)[C]) -> mat< common_type< Rows... >, sizeof...(Rows), C >
mat< real_number, M, N > Mat
Definition: mat_typedefs.h:10
constexpr auto inv_sym(Mat &&A) -> std::optional< mat< tatooine::value_type< Mat >, 2, 2 > >
Definition: inv.h:15
constexpr auto det(base_tensor< Tensor, T, 2, 2 > const &A) -> T
Definition: determinant.h:7
Definition: mat.h:14