1#ifndef TATOOINE_TENSOR_OPERATIONS_INV_H
2#define TATOOINE_TENSOR_OPERATIONS_INV_H
14template <fixed_size_quadratic_mat<2> Mat>
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) {
24 auto const div = 1 /
det;
25 auto const e = -b * div;
34template <fixed_size_quadratic_mat<2> Mat>
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) {
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) {
48 auto const div = 1 /
det;
58template <fixed_
size_tensor<3, 3> Mat>
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);
68 (a * d - b * b) * f - a * e * e + 2 * b * c * e - c * c * d;
69 if (std::abs(
det) < 1e-10) {
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}} /
83template <fixed_size_quadratic_mat<3> Mat>
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) {
96 decltype(
auto) a = A(0, 0);
97 decltype(
auto) e = A(1, 1);
98 decltype(
auto) i = A(2, 2);
100 (a * e - b * d) * i + (c * d - a * f) * h + (b * f - c * e) * g;
101 if (std::abs(
det) < 1e-10) {
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}} /
117template <fixed_size_quadratic_mat<4> Mat>
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);
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);
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) *
140 ((b * f - c * e) * j + (d * e - b * g) * i + c * g * g - d * f * g) *
142 -((b * f - c * e) * i + (d * e - b * g) * h + c * f * g - d * f * f) *
144 {-((b * h - c * f) * j - b * i * i + (c * g + d * f) * i - d * g * h) *
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) *
149 ((a * f - b * c) * i + (b * d - a * g) * h + c * c * g - c * d * f) *
151 {((b * f - c * e) * j + (d * e - b * g) * i + c * g * g - d * f * g) *
153 -((a * f - b * c) * j + (b * d - a * g) * i + c * d * g - d * d * f) *
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) *
158 {-((b * f - c * e) * i + (d * e - b * g) * h + c * f * g - d * f * f) *
160 ((a * f - b * c) * i + (b * d - a * g) * h + c * c * g - c * d * f) *
162 -((a * e - b * b) * i + (b * c - a * f) * g + b * d * f - c * d * e) *
164 ((a * e - b * b) * h - a * f * f + 2 * b * c * f - c * c * e) * div}};
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);
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) {
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);
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) {
206 const auto div = 1 /
det;
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) *
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) *
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) *
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