Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
TMatrixT.h
Go to the documentation of this file.
1 // @(#)root/matrix:$Id$
2 // Authors: Fons Rademakers, Eddy Offermann Nov 2003
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #ifndef ROOT_TMatrixT
13 #define ROOT_TMatrixT
14 
15 //////////////////////////////////////////////////////////////////////////
16 // //
17 // TMatrixT //
18 // //
19 // Template class of a general matrix in the linear algebra package //
20 // //
21 //////////////////////////////////////////////////////////////////////////
22 
23 #include "TMatrixTBase.h"
24 #include "TMatrixTUtils.h"
25 
26 #ifdef CBLAS
27 #include <vecLib/vBLAS.h>
28 //#include <cblas.h>
29 #endif
30 
31 #include "Rtypes.h"
32 #include "TError.h"
33 
34 
35 template<class Element> class TMatrixTSym;
36 template<class Element> class TMatrixTSparse;
37 template<class Element> class TMatrixTLazy;
38 
39 template<class Element> class TMatrixT : public TMatrixTBase<Element> {
40 
41 protected:
42 
43  Element fDataStack[TMatrixTBase<Element>::kSizeMax]; //! data container
44  Element *fElements; //[fNelems] elements themselves
45 
46  Element *New_m (Int_t size);
47  void Delete_m(Int_t size,Element*&);
48  Int_t Memcpy_m(Element *newp,const Element *oldp,Int_t copySize,
49  Int_t newSize,Int_t oldSize);
50  void Allocate(Int_t nrows,Int_t ncols,Int_t row_lwb = 0,Int_t col_lwb = 0,Int_t init = 0,
51  Int_t /*nr_nonzeros*/ = -1);
52 
53 
54 public:
55 
56 
57  enum {kWorkMax = 100};
58  enum EMatrixCreatorsOp1 { kZero,kUnit,kTransposed,kInverted,kAtA };
59  enum EMatrixCreatorsOp2 { kMult,kTransposeMult,kInvMult,kMultTranspose,kPlus,kMinus };
60 
61  TMatrixT(): fDataStack(), fElements(0) { }
62  TMatrixT(Int_t nrows,Int_t ncols);
63  TMatrixT(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb);
64  TMatrixT(Int_t nrows,Int_t ncols,const Element *data,Option_t *option="");
65  TMatrixT(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,const Element *data,Option_t *option="");
66  TMatrixT(const TMatrixT <Element> &another);
67  TMatrixT(const TMatrixTSym <Element> &another);
68  TMatrixT(const TMatrixTSparse<Element> &another);
69  template <class Element2> TMatrixT(const TMatrixT<Element2> &another): fElements(0)
70  {
71  R__ASSERT(another.IsValid());
72  Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb());
73  *this = another;
74  }
75 
76  TMatrixT(EMatrixCreatorsOp1 op,const TMatrixT<Element> &prototype);
77  TMatrixT(const TMatrixT <Element> &a,EMatrixCreatorsOp2 op,const TMatrixT <Element> &b);
78  TMatrixT(const TMatrixT <Element> &a,EMatrixCreatorsOp2 op,const TMatrixTSym<Element> &b);
79  TMatrixT(const TMatrixTSym <Element> &a,EMatrixCreatorsOp2 op,const TMatrixT <Element> &b);
80  TMatrixT(const TMatrixTSym <Element> &a,EMatrixCreatorsOp2 op,const TMatrixTSym<Element> &b);
81  TMatrixT(const TMatrixTLazy<Element> &lazy_constructor);
82 
83  virtual ~TMatrixT() { TMatrixT::Clear(); }
84 
85  // Elementary constructors
86 
87  void Plus (const TMatrixT <Element> &a,const TMatrixT <Element> &b);
88  void Plus (const TMatrixT <Element> &a,const TMatrixTSym<Element> &b);
89  void Plus (const TMatrixTSym<Element> &a,const TMatrixT <Element> &b) { Plus(b,a); }
90 
91  void Minus(const TMatrixT <Element> &a,const TMatrixT <Element> &b);
92  void Minus(const TMatrixT <Element> &a,const TMatrixTSym<Element> &b);
93  void Minus(const TMatrixTSym<Element> &a,const TMatrixT <Element> &b) { Minus(b,a); }
94 
95  void Mult (const TMatrixT <Element> &a,const TMatrixT <Element> &b);
96  void Mult (const TMatrixT <Element> &a,const TMatrixTSym<Element> &b);
97  void Mult (const TMatrixTSym<Element> &a,const TMatrixT <Element> &b);
98  void Mult (const TMatrixTSym<Element> &a,const TMatrixTSym<Element> &b);
99 
100  void TMult(const TMatrixT <Element> &a,const TMatrixT <Element> &b);
101  void TMult(const TMatrixT <Element> &a,const TMatrixTSym<Element> &b);
102  void TMult(const TMatrixTSym<Element> &a,const TMatrixT <Element> &b) { Mult(a,b); }
103  void TMult(const TMatrixTSym<Element> &a,const TMatrixTSym<Element> &b) { Mult(a,b); }
104 
105  void MultT(const TMatrixT <Element> &a,const TMatrixT <Element> &b);
106  void MultT(const TMatrixT <Element> &a,const TMatrixTSym<Element> &b) { Mult(a,b); }
107  void MultT(const TMatrixTSym<Element> &a,const TMatrixT <Element> &b);
108  void MultT(const TMatrixTSym<Element> &a,const TMatrixTSym<Element> &b) { Mult(a,b); }
109 
110  virtual const Element *GetMatrixArray () const;
111  virtual Element *GetMatrixArray ();
112  virtual const Int_t *GetRowIndexArray() const { return 0; }
113  virtual Int_t *GetRowIndexArray() { return 0; }
114  virtual const Int_t *GetColIndexArray() const { return 0; }
115  virtual Int_t *GetColIndexArray() { return 0; }
116 
117  virtual TMatrixTBase<Element> &SetRowIndexArray(Int_t * /*data*/) { MayNotUse("SetRowIndexArray(Int_t *)"); return *this; }
118  virtual TMatrixTBase<Element> &SetColIndexArray(Int_t * /*data*/) { MayNotUse("SetColIndexArray(Int_t *)"); return *this; }
119 
120  virtual void Clear(Option_t * /*option*/ ="") { if (this->fIsOwner) Delete_m(this->fNelems,fElements);
121  else fElements = 0;
122  this->fNelems = 0; }
123 
124  TMatrixT <Element> &Use (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Element *data);
125  const TMatrixT <Element> &Use (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,const Element *data) const
126  { return (const TMatrixT<Element>&)
127  ((const_cast<TMatrixT<Element> *>(this))->Use(row_lwb,row_upb,col_lwb,col_upb, const_cast<Element *>(data))); }
128  TMatrixT <Element> &Use (Int_t nrows,Int_t ncols,Element *data);
129  const TMatrixT <Element> &Use (Int_t nrows,Int_t ncols,const Element *data) const;
130  TMatrixT <Element> &Use (TMatrixT<Element> &a);
131  const TMatrixT <Element> &Use (const TMatrixT<Element> &a) const;
132 
133  virtual TMatrixTBase<Element> &GetSub (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
134  TMatrixTBase<Element> &target,Option_t *option="S") const;
135  TMatrixT <Element> GetSub (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Option_t *option="S") const;
136  virtual TMatrixTBase<Element> &SetSub (Int_t row_lwb,Int_t col_lwb,const TMatrixTBase<Element> &source);
137 
138  virtual TMatrixTBase<Element> &ResizeTo(Int_t nrows,Int_t ncols,Int_t /*nr_nonzeros*/ =-1);
139  virtual TMatrixTBase<Element> &ResizeTo(Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Int_t /*nr_nonzeros*/ =-1);
140  inline TMatrixTBase<Element> &ResizeTo(const TMatrixT<Element> &m) {
141  return ResizeTo(m.GetRowLwb(),m.GetRowUpb(),m.GetColLwb(),m.GetColUpb());
142  }
143 
144  virtual Double_t Determinant () const;
145  virtual void Determinant (Double_t &d1,Double_t &d2) const;
146 
147  TMatrixT<Element> &Invert (Double_t *det=0);
148  TMatrixT<Element> &InvertFast (Double_t *det=0);
149  TMatrixT<Element> &Transpose (const TMatrixT<Element> &source);
150  inline TMatrixT<Element> &T () { return this->Transpose(*this); }
151  TMatrixT<Element> &Rank1Update (const TVectorT<Element> &v,Element alpha=1.0);
152  TMatrixT<Element> &Rank1Update (const TVectorT<Element> &v1,const TVectorT<Element> &v2,Element alpha=1.0);
153  Element Similarity (const TVectorT<Element> &v) const;
154 
155  TMatrixT<Element> &NormByColumn(const TVectorT<Element> &v,Option_t *option="D");
156  TMatrixT<Element> &NormByRow (const TVectorT<Element> &v,Option_t *option="D");
157 
158  // Either access a_ij as a(i,j)
159  inline Element operator()(Int_t rown,Int_t coln) const;
160  inline Element &operator()(Int_t rown,Int_t coln);
161 
162  // or as a[i][j]
163  inline const TMatrixTRow_const<Element> operator[](Int_t rown) const { return TMatrixTRow_const<Element>(*this,rown); }
164  inline TMatrixTRow <Element> operator[](Int_t rown) { return TMatrixTRow <Element>(*this,rown); }
165 
166  TMatrixT<Element> &operator= (const TMatrixT <Element> &source);
167  TMatrixT<Element> &operator= (const TMatrixTSym <Element> &source);
168  TMatrixT<Element> &operator= (const TMatrixTSparse<Element> &source);
169  TMatrixT<Element> &operator= (const TMatrixTLazy <Element> &source);
170  template <class Element2> TMatrixT<Element> &operator= (const TMatrixT<Element2> &source)
171  {
172  if (!AreCompatible(*this,source)) {
173  Error("operator=(const TMatrixT2 &)","matrices not compatible");
174  return *this;
175  }
176 
177  TObject::operator=(source);
178  const Element2 * const ps = source.GetMatrixArray();
179  Element * const pt = this->GetMatrixArray();
180  for (Int_t i = 0; i < this->fNelems; i++)
181  pt[i] = ps[i];
182  this->fTol = source.GetTol();
183  return *this;
184  }
185 
186  TMatrixT<Element> &operator= (Element val);
187  TMatrixT<Element> &operator-=(Element val);
188  TMatrixT<Element> &operator+=(Element val);
189  TMatrixT<Element> &operator*=(Element val);
190 
191  TMatrixT<Element> &operator+=(const TMatrixT <Element> &source);
192  TMatrixT<Element> &operator+=(const TMatrixTSym<Element> &source);
193  TMatrixT<Element> &operator-=(const TMatrixT <Element> &source);
194  TMatrixT<Element> &operator-=(const TMatrixTSym<Element> &source);
195 
196  TMatrixT<Element> &operator*=(const TMatrixT <Element> &source);
197  TMatrixT<Element> &operator*=(const TMatrixTSym <Element> &source);
198  TMatrixT<Element> &operator*=(const TMatrixTDiag_const <Element> &diag);
199  TMatrixT<Element> &operator/=(const TMatrixTDiag_const <Element> &diag);
200  TMatrixT<Element> &operator*=(const TMatrixTRow_const <Element> &row);
201  TMatrixT<Element> &operator/=(const TMatrixTRow_const <Element> &row);
202  TMatrixT<Element> &operator*=(const TMatrixTColumn_const<Element> &col);
203  TMatrixT<Element> &operator/=(const TMatrixTColumn_const<Element> &col);
204 
205  const TMatrixT<Element> EigenVectors(TVectorT<Element> &eigenValues) const;
206 
207  ClassDef(TMatrixT,4) // Template of General Matrix class
208 };
209 
210 #ifndef __CINT__
211 // When building with -fmodules, it instantiates all pending instantiations,
212 // instead of delaying them until the end of the translation unit.
213 // We 'got away with' probably because the use and the definition of the
214 // explicit specialization do not occur in the same TU.
215 //
216 // In case we are building with -fmodules, we need to forward declare the
217 // specialization in order to compile the dictionary G__Matrix.cxx.
218 template <> TClass *TMatrixT<double>::Class();
219 #endif // __CINT__
220 
221 
222 template <class Element> inline const Element *TMatrixT<Element>::GetMatrixArray() const { return fElements; }
223 template <class Element> inline Element *TMatrixT<Element>::GetMatrixArray() { return fElements; }
224 
225 template <class Element> inline TMatrixT<Element> &TMatrixT<Element>::Use (Int_t nrows,Int_t ncols,Element *data)
226  { return Use(0,nrows-1,0,ncols-1,data); }
227 template <class Element> inline const TMatrixT<Element> &TMatrixT<Element>::Use (Int_t nrows,Int_t ncols,const Element *data) const
228  { return Use(0,nrows-1,0,ncols-1,data); }
229 template <class Element> inline TMatrixT<Element> &TMatrixT<Element>::Use (TMatrixT &a)
230  {
231  R__ASSERT(a.IsValid());
232  return Use(a.GetRowLwb(),a.GetRowUpb(),
233  a.GetColLwb(),a.GetColUpb(),a.GetMatrixArray());
234  }
235 template <class Element> inline const TMatrixT<Element> &TMatrixT<Element>::Use (const TMatrixT &a) const
236  {
237  R__ASSERT(a.IsValid());
238  return Use(a.GetRowLwb(),a.GetRowUpb(),
239  a.GetColLwb(),a.GetColUpb(),a.GetMatrixArray());
240  }
241 
242 template <class Element> inline TMatrixT<Element> TMatrixT<Element>::GetSub (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
243  Option_t *option) const
244  {
245  TMatrixT tmp;
246  this->GetSub(row_lwb,row_upb,col_lwb,col_upb,tmp,option);
247  return tmp;
248  }
249 
250 template <class Element> inline Element TMatrixT<Element>::operator()(Int_t rown,Int_t coln) const
251 {
252  R__ASSERT(this->IsValid());
253  const Int_t arown = rown-this->fRowLwb;
254  const Int_t acoln = coln-this->fColLwb;
255  if (arown >= this->fNrows || arown < 0) {
256  Error("operator()","Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows);
257  return TMatrixTBase<Element>::NaNValue();
258  }
259  if (acoln >= this->fNcols || acoln < 0) {
260  Error("operator()","Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols);
261  return TMatrixTBase<Element>::NaNValue();
262 
263  }
264  return (fElements[arown*this->fNcols+acoln]);
265 }
266 
267 template <class Element> inline Element &TMatrixT<Element>::operator()(Int_t rown,Int_t coln)
268 {
269  R__ASSERT(this->IsValid());
270  const Int_t arown = rown-this->fRowLwb;
271  const Int_t acoln = coln-this->fColLwb;
272  if (arown >= this->fNrows || arown < 0) {
273  Error("operator()","Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows);
274  return TMatrixTBase<Element>::NaNValue();
275  }
276  if (acoln >= this->fNcols || acoln < 0) {
277  Error("operator()","Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols);
278  return TMatrixTBase<Element>::NaNValue();
279  }
280  return (fElements[arown*this->fNcols+acoln]);
281 }
282 
283 template <class Element> TMatrixT<Element> operator+ (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
284 template <class Element> TMatrixT<Element> operator+ (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
285 template <class Element> TMatrixT<Element> operator+ (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
286 template <class Element> TMatrixT<Element> operator+ (const TMatrixT <Element> &source , Element val );
287 template <class Element> TMatrixT<Element> operator+ ( Element val ,const TMatrixT <Element> &source );
288 template <class Element> TMatrixT<Element> operator- (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
289 template <class Element> TMatrixT<Element> operator- (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
290 template <class Element> TMatrixT<Element> operator- (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
291 template <class Element> TMatrixT<Element> operator- (const TMatrixT <Element> &source , Element val );
292 template <class Element> TMatrixT<Element> operator- ( Element val ,const TMatrixT <Element> &source );
293 template <class Element> TMatrixT<Element> operator* ( Element val ,const TMatrixT <Element> &source );
294 template <class Element> TMatrixT<Element> operator* (const TMatrixT <Element> &source , Element val );
295 template <class Element> TMatrixT<Element> operator* (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
296 template <class Element> TMatrixT<Element> operator* (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
297 template <class Element> TMatrixT<Element> operator* (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
298 template <class Element> TMatrixT<Element> operator* (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element> &source2);
299 // Preventing warnings with -Weffc++ in GCC since overloading the || and && operators was a design choice.
300 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
301 #pragma GCC diagnostic push
302 #pragma GCC diagnostic ignored "-Weffc++"
303 #endif
304 template <class Element> TMatrixT<Element> operator&& (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
305 template <class Element> TMatrixT<Element> operator&& (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
306 template <class Element> TMatrixT<Element> operator&& (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
307 template <class Element> TMatrixT<Element> operator|| (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
308 template <class Element> TMatrixT<Element> operator|| (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
309 template <class Element> TMatrixT<Element> operator|| (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
310 #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40600
311 #pragma GCC diagnostic pop
312 #endif
313 template <class Element> TMatrixT<Element> operator> (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
314 template <class Element> TMatrixT<Element> operator> (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
315 template <class Element> TMatrixT<Element> operator> (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
316 template <class Element> TMatrixT<Element> operator>= (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
317 template <class Element> TMatrixT<Element> operator>= (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
318 template <class Element> TMatrixT<Element> operator>= (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
319 template <class Element> TMatrixT<Element> operator<= (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
320 template <class Element> TMatrixT<Element> operator<= (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
321 template <class Element> TMatrixT<Element> operator<= (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
322 template <class Element> TMatrixT<Element> operator< (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
323 template <class Element> TMatrixT<Element> operator< (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
324 template <class Element> TMatrixT<Element> operator< (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
325 template <class Element> TMatrixT<Element> operator!= (const TMatrixT <Element> &source1,const TMatrixT <Element> &source2);
326 template <class Element> TMatrixT<Element> operator!= (const TMatrixT <Element> &source1,const TMatrixTSym<Element> &source2);
327 template <class Element> TMatrixT<Element> operator!= (const TMatrixTSym<Element> &source1,const TMatrixT <Element> &source2);
328 
329 template <class Element> TMatrixT<Element> &Add (TMatrixT<Element> &target, Element scalar,const TMatrixT <Element> &source);
330 template <class Element> TMatrixT<Element> &Add (TMatrixT<Element> &target, Element scalar,const TMatrixTSym<Element> &source);
331 template <class Element> TMatrixT<Element> &ElementMult(TMatrixT<Element> &target,const TMatrixT <Element> &source);
332 template <class Element> TMatrixT<Element> &ElementMult(TMatrixT<Element> &target,const TMatrixTSym<Element> &source);
333 template <class Element> TMatrixT<Element> &ElementDiv (TMatrixT<Element> &target,const TMatrixT <Element> &source);
334 template <class Element> TMatrixT<Element> &ElementDiv (TMatrixT<Element> &target,const TMatrixTSym<Element> &source);
335 
336 template <class Element> void AMultB (const Element * const ap,Int_t na,Int_t ncolsa,
337  const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp);
338 template <class Element> void AtMultB(const Element * const ap,Int_t ncolsa,
339  const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp);
340 template <class Element> void AMultBt(const Element * const ap,Int_t na,Int_t ncolsa,
341  const Element * const bp,Int_t nb,Int_t ncolsb,Element *cp);
342 
343 #endif