67 static_assert(is_floating_point_v<T>,
68 "inverse requires a floating-point scalar type");
78 result(0, 0) = T(1) / A(0, 0);
81 else if constexpr (N == 2)
83 T det = A(0, 0) * A(1, 1) - A(0, 1) * A(1, 0);
90 T inv_det = T(1) / det;
93 result(0, 0) = A(1, 1) * inv_det;
94 result(0, 1) = -A(0, 1) * inv_det;
95 result(1, 0) = -A(1, 0) * inv_det;
96 result(1, 1) = A(0, 0) * inv_det;
99 else if constexpr (N == 3)
102 T c00 = A(1, 1) * A(2, 2) - A(1, 2) * A(2, 1);
103 T c01 = A(1, 2) * A(2, 0) - A(1, 0) * A(2, 2);
104 T c02 = A(1, 0) * A(2, 1) - A(1, 1) * A(2, 0);
106 T det = A(0, 0) * c00 + A(0, 1) * c01 + A(0, 2) * c02;
113 T inv_det = T(1) / det;
117 result(0, 0) = c00 * inv_det;
118 result(0, 1) = (A(0, 2) * A(2, 1) - A(0, 1) * A(2, 2)) * inv_det;
119 result(0, 2) = (A(0, 1) * A(1, 2) - A(0, 2) * A(1, 1)) * inv_det;
121 result(1, 0) = c01 * inv_det;
122 result(1, 1) = (A(0, 0) * A(2, 2) - A(0, 2) * A(2, 0)) * inv_det;
123 result(1, 2) = (A(0, 2) * A(1, 0) - A(0, 0) * A(1, 2)) * inv_det;
125 result(2, 0) = c02 * inv_det;
126 result(2, 1) = (A(0, 1) * A(2, 0) - A(0, 0) * A(2, 1)) * inv_det;
127 result(2, 2) = (A(0, 0) * A(1, 1) - A(0, 1) * A(1, 0)) * inv_det;
131 else if constexpr (N == 4)
134 T c0 = A(0, 0) * A(1, 1) - A(0, 1) * A(1, 0);
135 T c1 = A(0, 0) * A(1, 2) - A(0, 2) * A(1, 0);
136 T c2 = A(0, 0) * A(1, 3) - A(0, 3) * A(1, 0);
137 T c3 = A(0, 1) * A(1, 2) - A(0, 2) * A(1, 1);
138 T c4 = A(0, 1) * A(1, 3) - A(0, 3) * A(1, 1);
139 T c5 = A(0, 2) * A(1, 3) - A(0, 3) * A(1, 2);
142 T s0 = A(2, 0) * A(3, 1) - A(2, 1) * A(3, 0);
143 T s1 = A(2, 0) * A(3, 2) - A(2, 2) * A(3, 0);
144 T s2 = A(2, 0) * A(3, 3) - A(2, 3) * A(3, 0);
145 T s3 = A(2, 1) * A(3, 2) - A(2, 2) * A(3, 1);
146 T s4 = A(2, 1) * A(3, 3) - A(2, 3) * A(3, 1);
147 T s5 = A(2, 2) * A(3, 3) - A(2, 3) * A(3, 2);
149 T det = c0 * s5 - c1 * s4 + c2 * s3 + c3 * s2 - c4 * s1 + c5 * s0;
156 T inv_det = T(1) / det;
161 result(0, 0) = (A(1, 1) * s5 - A(1, 2) * s4 + A(1, 3) * s3) * inv_det;
162 result(0, 1) = (-A(0, 1) * s5 + A(0, 2) * s4 - A(0, 3) * s3) * inv_det;
163 result(0, 2) = (A(3, 1) * c5 - A(3, 2) * c4 + A(3, 3) * c3) * inv_det;
164 result(0, 3) = (-A(2, 1) * c5 + A(2, 2) * c4 - A(2, 3) * c3) * inv_det;
166 result(1, 0) = (-A(1, 0) * s5 + A(1, 2) * s2 - A(1, 3) * s1) * inv_det;
167 result(1, 1) = (A(0, 0) * s5 - A(0, 2) * s2 + A(0, 3) * s1) * inv_det;
168 result(1, 2) = (-A(3, 0) * c5 + A(3, 2) * c2 - A(3, 3) * c1) * inv_det;
169 result(1, 3) = (A(2, 0) * c5 - A(2, 2) * c2 + A(2, 3) * c1) * inv_det;
171 result(2, 0) = (A(1, 0) * s4 - A(1, 1) * s2 + A(1, 3) * s0) * inv_det;
172 result(2, 1) = (-A(0, 0) * s4 + A(0, 1) * s2 - A(0, 3) * s0) * inv_det;
173 result(2, 2) = (A(3, 0) * c4 - A(3, 1) * c2 + A(3, 3) * c0) * inv_det;
174 result(2, 3) = (-A(2, 0) * c4 + A(2, 1) * c2 - A(2, 3) * c0) * inv_det;
176 result(3, 0) = (-A(1, 0) * s3 + A(1, 1) * s1 - A(1, 2) * s0) * inv_det;
177 result(3, 1) = (A(0, 0) * s3 - A(0, 1) * s1 + A(0, 2) * s0) * inv_det;
178 result(3, 2) = (-A(3, 0) * c3 + A(3, 1) * c1 - A(3, 2) * c0) * inv_det;
179 result(3, 3) = (A(2, 0) * c3 - A(2, 1) * c1 + A(2, 2) * c0) * inv_det;
188 auto lu_result =
lu(A);
190 if (!lu_result.has_value())
195 auto &decomp = lu_result.value();
202 PI(i, decomp.perm(i)) = T(1);
210 auto fwd_result = forward_substitute<true>(L, PI);
212 if (!fwd_result.has_value())
217 auto &Y = fwd_result.value();
222 if (!back_result.has_value())
227 return move(back_result.value());