EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KfMatrix.h
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file KfMatrix.h
1 //
2 // AYK (ayk@bnl.gov), cleaned up 2014/10/14;
3 //
4 // Yet another matrix package; using ROOT matrices does not help
5 // to easily improve performance (FIXME: should try to replace
6 // per-element access by hopefully optimized ROOT matrix operations);
7 //
8 
9 //#define _USE_ROOT_TMATRIX_
10 
11 #ifdef _USE_ROOT_TMATRIX_
12 #include <TMatrixD.h>
13 #endif
14 
15 #ifndef _KF_MATRIX_H
16 #define _KF_MATRIX_H
17 
18 #define _PRINTOUT_FORMAT_DEFAULT_ ("%12.8f ")
19 
20 // General matrix structure;
21 class KfMatrix {
22  public:
23  // Will work for both "matrix" and "vector" types;
24  KfMatrix(unsigned dim1, unsigned dim2 = 1);
25  ~KfMatrix();
26 
27  static void SetDimensionCheckFlag(bool what) { mDimensionCheckFlag = what; };
28  static bool GetDimensionCheckFlag() { return mDimensionCheckFlag; };
29 
30  // Trivial routines to access matrix dimension values;
31  int GetDim1() const { return mDim1; };
32  int GetDim2() const { return mDim2; };
33 
34  // Matrix element access; try to minimize changes to the original C code
35  // where KFV() and KFM() were preprocessor macros which allowed to be
36  // used both as lvalue and rvalue -> use references here; this indeed
37  // compromises encapsulation, however allows to keep access under certain
38  // control, and also sould with minimal changes work for other matrix
39  // implementation types;
40 #ifdef _USE_ROOT_TMATRIX_
41  double & KFV(int ip) { return (*mMtx)[ip][ 0]; };
42  double & KFM(int ip, int iq) { return (*mMtx)[ip][iq]; };
43  double * ARR() { return &(*mMtx)[ 0][ 0]; };
44  TMatrixD &Vec() { return *mMtx; }
45  TMatrixD &Mtx() { return *mMtx; }
46 #else
47  double & KFV(int ip) { return mArr[ip]; };
48  double & KFM(int ip, int iq) { return mArr[ip*mDim2+iq]; };
49  // Leave this separate instead of using &KFV(0), just as a sign, that
50  // sequential access to data array is in fact needed in a few places;
51  // can be cured if eg GSL matrix library is used;
52  double * ARR() { return mArr; };
53 #endif
54 
55  // Reset to a unity (square) matrix;
56  int Unity();
57  // Reset all matrix elements to 0.0;
58  void Reset();
59 
61  // Square matrix invertion ('type' is either _SYMMETRIC_ or _ARBITRARY_);
62  int Invert(MtxType type = Arbitrary);
63 
64  // Forces square matrix symmetrization (just fills out both lower an upper
65  // triangles with half-sum);
66  int ForceSymmetric();
67 
68  // Returns '-1' if a square matrix does not pass positivity check;
69  int CheckPositivity();
70  int FixPositivity(double maxFixablePositivityScrewup, double positivityCorrelationFix);
71 
72  // Print out matrix contents in a human-readable format; NB: if format pointer
73  // is NULL, _PRINTOUT_FORMAT_DEFAULT_ is used;
74  void Print(const char *fmt = _PRINTOUT_FORMAT_DEFAULT_);
75  // Prints out matrix correlation coefficients;
76  int CorrelationPrint(const char *fmt = _PRINTOUT_FORMAT_DEFAULT_);
77 
78  int CopyFrom (KfMatrix *in);
79  int Add (KfMatrix *in);
80  int Subtract (KfMatrix *in);
81 
82  int SetToSum (KfMatrix *in1, KfMatrix *in2);
83  int SetToDifference(KfMatrix *in1, KfMatrix *in2);
84  int SetToProduct (double cff, KfMatrix *in);
85  int SetToProduct (KfMatrix *in1, KfMatrix *in2, unsigned mode = 0x0000);
86  int SetToProduct (KfMatrix *in1, KfMatrix *in2, KfMatrix *in3, unsigned mode = 0x0000);
87 
88  // This routine works only for KfVector objects of course;
89  int VectorLengthSquare(KfMatrix *metric, double *lsqr);
90 
91  private:
92  // 1-st & 2-d dimensions; mDim = mDim1 * mDim2;
93  int mDim1, mDim2, mDim;
94 
95 #ifdef _USE_ROOT_TMATRIX_
96  TMatrixD *mMtx;
97 #else
98  // Data array;
99  double *mArr;
100 #endif
101 
102  static bool mDimensionCheckFlag;
103 
104  static int KfmReturn(int ret);
105 
106  // NB: dim[] array is filled by dim1 & dim2 values depending on whether
107  // transposition is needed or not;
108  void AssignTrueDimensions(int trans, int dim[2]);
109 
110  int AddCore (KfMatrix *in1, KfMatrix *in2, int what);
111  int SetToProductCore(KfMatrix *in1, KfMatrix *in2, KfMatrix *in3, unsigned mode = 0x0000);
112 
113  int DimensionMatchCheck(KfMatrix *kfm2);
114  int DimensionChainCheck(KfMatrix *in1, KfMatrix *in2, unsigned mode);
115 
116  KfMatrix *Bufferize();
117 };
118 
119 // 'mode' bitwise pattern; NB: never change these values (bitwise shifts
120 // _TRANSPOSE_IN3_ -> _TRANSPOSE_IN2_ used, etc);
121 #define _TRANSPOSE_IN1_ 0x001
122 #define _TRANSPOSE_IN2_ 0x002
123 #define _TRANSPOSE_IN3_ 0x004
124 
125 // Yes, it is easier to work always with 2-dim stuff; if dim2=1 it is
126 // however more legible to emphasise on this fact;
128 
129 #endif