//Author: Eddy Offermann // This macro shows several ways to invert a matrix . Each method // is a trade-off between accuracy of the inversion and speed. // Which method to chose depends on "how well-behaved" the matrix is. // This is best checked through a call to Condition(), available in each // decomposition class. A second possibilty (less preferred) would be to // check the determinant // // USAGE // ----- // This macro can be execued via CINT or via ACLIC // - via CINT, do // root > .x invertMatrix.C // - via ACLIC // root > gSystem->Load("libMatrix"); // root > .x invertMatrix.C+ #ifndef __CINT__ #include "Riostream.h" #include "TMath.h" #include "TMatrixD.h" #include "TMatrixDLazy.h" #include "TVectorD.h" #include "TDecompLU.h" #include "TDecompSVD.h" #endif void invertMatrix(Int_t msize=6) { #ifdef __CINT__ gSystem->Load("libMatrix"); #endif if (msize < 2 || msize > 10) { cout << "2 <= msize <= 10" < 6 x 6 but for smaller sizes, the // inversion is performed according to Cramer's rule by explicitly calculating // all Jacobi's sub-determinants . For instance for a 6 x 6 matrix this means: // # of 5 x 5 determinant : 36 // # of 4 x 4 determinant : 75 // # of 3 x 3 determinant : 80 // # of 2 x 2 determinant : 45 (see TMatrixD/FCramerInv.cxx) // // The only "quality" control in this process is to check whether the 6 x 6 // determinant is unequal 0 . But speed gains are significant compared to Invert() , // upto an order of magnitude for sizes <= 4 x 4 // // The inversion is done "in place", so the original matrix will be overwritten // If a pointer to a Double_t is supplied the determinant is calculated // cout << "1. Use .InvertFast(&det)" < 6) cout << " for ("< 1 // - The last step is a standard forward/backward substitution . // // It is important to realize that both InvertFast() and Invert() are "one-shot" deals , speed // comes at a price . If something goes wrong because the matrix is (near) singular, you have // overwritten your original matrix and no factorization is available anymore to get more // information like condition number or change the tolerance number . // // All other calls in the matrix classes involving inversion like the ones with the "smart" // constructors (kInverted,kInvMult...) use this inversion method . // cout << "2. Use .Invert(&det)" < slower) and several operations can be performed without having to repeat // the decomposition step . // Inverting a matrix is nothing else than solving a set of equations where the rhs is given // by the unit matrix, so the steps to take are identical to those solving a linear equation : // cout << "3. Use TDecompLU" <