| 1238 | |
| 1239 | |
| 1240 | shared_ptr<CoefficientFunction> DeterminantCF (shared_ptr<CoefficientFunction> coef) |
| 1241 | { |
| 1242 | auto dims = coef->Dimensions(); |
| 1243 | if (dims.Size() != 2) throw Exception("Inverse of non-matrix"); |
| 1244 | if (dims[0] != dims[1]) throw Exception("Inverse of non-quadratic matrix"); |
| 1245 | |
| 1246 | if (coef->IsZeroCF()) |
| 1247 | return ZeroCF(Array<int>()); |
| 1248 | |
| 1249 | if (dynamic_pointer_cast<IdentityCoefficientFunction> (coef) && !coef->IsVariable()) |
| 1250 | return make_shared<ConstantCoefficientFunction>(1); |
| 1251 | |
| 1252 | |
| 1253 | // common pattern : Det (F^T F) = Det(F)**2, for F square |
| 1254 | if (!coef->IsVariable()) |
| 1255 | if (auto mmm = dynamic_pointer_cast<MultMatMatCoefficientFunction> (coef)) |
| 1256 | { |
| 1257 | auto AB = mmm->InputCoefficientFunctions(); |
| 1258 | if (!AB[0]->IsVariable()) |
| 1259 | if (auto trans = dynamic_pointer_cast<TransposeCoefficientFunction> (AB[0])) |
| 1260 | { |
| 1261 | auto At = trans->InputCoefficientFunctions()[0]; |
| 1262 | if (At->Dimensions()[0] == At->Dimensions()[1]) |
| 1263 | { |
| 1264 | auto detF = DeterminantCF (At); |
| 1265 | return detF*detF; |
| 1266 | } |
| 1267 | } |
| 1268 | } |
| 1269 | |
| 1270 | switch (dims[0]) |
| 1271 | { |
| 1272 | case 1: return make_shared<DeterminantCoefficientFunction<1>> (coef); |
| 1273 | case 2: return make_shared<DeterminantCoefficientFunction<2>> (coef); |
| 1274 | case 3: return make_shared<DeterminantCoefficientFunction<3>> (coef); |
| 1275 | default: |
| 1276 | throw Exception("Determinant of matrix of size "+ToString(dims[0]) + " not available"); |
| 1277 | } |
| 1278 | } |
| 1279 | |
| 1280 | shared_ptr<CoefficientFunction> CofactorCF (shared_ptr<CoefficientFunction> coef) |
| 1281 | { |
no test coverage detected