ROOT logo
// @(#)root/matrix:$Id: TMatrixTSym.h 27658 2009-02-28 05:34:57Z pcanal $
// Authors: Fons Rademakers, Eddy Offermann   Nov 2003

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TMatrixTSym
#define ROOT_TMatrixTSym

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMatrixTSym                                                          //
//                                                                      //
// Implementation of a symmetric matrix in the linear algebra package   //
//                                                                      //
// Note that in this implementation both matrix element m[i][j] and     //
// m[j][i] are updated and stored in memory . However, when making the  //
// object persistent only the upper right triangle is stored .          //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TMatrixTBase
#include "TMatrixTBase.h"
#endif
#ifndef ROOT_TMatrixTUtils
#include "TMatrixTUtils.h"
#endif

template<class Element>class TMatrixT;
template<class Element>class TMatrixTSymLazy;
template<class Element>class TVectorT;

template<class Element> class TMatrixTSym : public TMatrixTBase<Element> {

protected:

   Element  fDataStack[TMatrixTBase<Element>::kSizeMax]; //! data container
   Element *fElements;                                   //[fNelems] elements themselves

   Element *New_m   (Int_t size);
   void     Delete_m(Int_t size,Element*&);
   Int_t    Memcpy_m(Element *newp,const Element *oldp,Int_t copySize,
                     Int_t newSize,Int_t oldSize);
   void     Allocate(Int_t nrows,Int_t ncols,Int_t row_lwb = 0,Int_t col_lwb = 0,Int_t init = 0,
                     Int_t nr_nonzeros = -1);

public:

   enum {kWorkMax = 100}; // size of work array
   enum EMatrixCreatorsOp1 { kZero,kUnit,kTransposed,kInverted,kAtA };
   enum EMatrixCreatorsOp2 { kPlus,kMinus };

   TMatrixTSym() { fElements = 0; }
   explicit TMatrixTSym(Int_t nrows);
   TMatrixTSym(Int_t row_lwb,Int_t row_upb);
   TMatrixTSym(Int_t nrows,const Element *data,Option_t *option="");
   TMatrixTSym(Int_t row_lwb,Int_t row_upb,const Element *data,Option_t *option="");
   TMatrixTSym(const TMatrixTSym<Element> &another);
   template <class Element2> TMatrixTSym(const TMatrixTSym<Element2> &another)
   {
      R__ASSERT(another.IsValid());
      Allocate(another.GetNrows(),another.GetNcols(),another.GetRowLwb(),another.GetColLwb());
      *this = another;
   }

   TMatrixTSym(EMatrixCreatorsOp1 op,const TMatrixTSym<Element> &prototype);
   TMatrixTSym(EMatrixCreatorsOp1 op,const TMatrixT   <Element> &prototype);
   TMatrixTSym(const TMatrixTSym<Element> &a,EMatrixCreatorsOp2 op,const TMatrixTSym<Element> &b);
   TMatrixTSym(const TMatrixTSymLazy<Element> &lazy_constructor);

   virtual ~TMatrixTSym() { Clear(); }

   // Elementary constructors
   void TMult(const TMatrixT   <Element> &a);
   void TMult(const TMatrixTSym<Element> &a);
   void Mult (const TMatrixTSym<Element> &a) { TMult(a); }

   void Plus (const TMatrixTSym<Element> &a,const TMatrixTSym<Element> &b);
   void Minus(const TMatrixTSym<Element> &a,const TMatrixTSym<Element> &b);

   virtual const Element *GetMatrixArray  () const;
   virtual       Element *GetMatrixArray  ();
   virtual const Int_t   *GetRowIndexArray() const { return 0; }
   virtual       Int_t   *GetRowIndexArray()       { return 0; }
   virtual const Int_t   *GetColIndexArray() const { return 0; }
   virtual       Int_t   *GetColIndexArray()       { return 0; }

   virtual       TMatrixTBase<Element> &SetRowIndexArray(Int_t * /*data*/) { MayNotUse("SetRowIndexArray(Int_t *)"); return *this; }
   virtual       TMatrixTBase<Element> &SetColIndexArray(Int_t * /*data*/) { MayNotUse("SetColIndexArray(Int_t *)"); return *this; }

   virtual void   Clear      (Option_t * /*option*/ ="") { if (this->fIsOwner) Delete_m(this->fNelems,fElements);
                                                           else fElements = 0; this->fNelems = 0; }
   virtual Bool_t IsSymmetric() const { return kTRUE; }

           TMatrixTSym <Element> &Use           (Int_t row_lwb,Int_t row_upb,Element *data);
   const   TMatrixTSym <Element> &Use           (Int_t row_lwb,Int_t row_upb,const Element *data) const
                                                  { return (const TMatrixTSym<Element>&)
                                                           ((const_cast<TMatrixTSym<Element> *>(this))->Use(row_lwb,row_upb,const_cast<Element *>(data))); }
           TMatrixTSym <Element> &Use           (Int_t nrows,Element *data);
   const   TMatrixTSym <Element> &Use           (Int_t nrows,const Element *data) const;
           TMatrixTSym <Element> &Use           (TMatrixTSym<Element> &a);
   const   TMatrixTSym <Element> &Use           (const TMatrixTSym<Element> &a) const;

           TMatrixTSym <Element> &GetSub        (Int_t row_lwb,Int_t row_upb,TMatrixTSym<Element> &target,Option_t *option="S") const;
   virtual TMatrixTBase<Element> &GetSub        (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
                                                TMatrixTBase<Element> &target,Option_t *option="S") const;
           TMatrixTSym <Element>  GetSub        (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,Option_t *option="S") const;
           TMatrixTSym <Element> &SetSub        (Int_t row_lwb,const TMatrixTBase<Element> &source);
   virtual TMatrixTBase<Element> &SetSub        (Int_t row_lwb,Int_t col_lwb,const TMatrixTBase<Element> &source);

   virtual TMatrixTBase<Element> &SetMatrixArray(const Element *data, Option_t *option="");

   virtual TMatrixTBase<Element> &Shift         (Int_t row_shift,Int_t col_shift);
   virtual TMatrixTBase<Element> &ResizeTo      (Int_t nrows,Int_t ncols,Int_t nr_nonzeros=-1);
   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);
   inline  TMatrixTBase<Element> &ResizeTo      (const TMatrixTSym<Element> &m) {
                                                return ResizeTo(m.GetRowLwb(),m.GetRowUpb(),m.GetColLwb(),m.GetColUpb()); }

   virtual Double_t      Determinant   () const;
   virtual void          Determinant   (Double_t &d1,Double_t &d2) const;

           TMatrixTSym<Element>  &Invert        (Double_t *det=0);
           TMatrixTSym<Element>  &InvertFast    (Double_t *det=0);
           TMatrixTSym<Element>  &Transpose     (const TMatrixTSym<Element> &source);
   inline  TMatrixTSym<Element>  &T             () { return this->Transpose(*this); }
           TMatrixTSym<Element>  &Rank1Update   (const TVectorT   <Element> &v,Element alpha=1.0);
           TMatrixTSym<Element>  &Similarity    (const TMatrixT   <Element> &n);
           TMatrixTSym<Element>  &Similarity    (const TMatrixTSym<Element> &n);
           Element                Similarity    (const TVectorT   <Element> &v) const;
           TMatrixTSym<Element>  &SimilarityT   (const TMatrixT   <Element> &n);

   // Either access a_ij as a(i,j)
   inline       Element                    operator()(Int_t rown,Int_t coln) const;
   inline       Element                   &operator()(Int_t rown,Int_t coln);

   // or as a[i][j]
   inline const TMatrixTRow_const<Element> operator[](Int_t rown) const { return TMatrixTRow_const<Element>(*this,rown); }
   inline       TMatrixTRow      <Element> operator[](Int_t rown)       { return TMatrixTRow      <Element>(*this,rown); }

   TMatrixTSym<Element> &operator= (const TMatrixTSym    <Element> &source);
   TMatrixTSym<Element> &operator= (const TMatrixTSymLazy<Element> &source);
   template <class Element2> TMatrixTSym<Element> &operator= (const TMatrixTSym<Element2> &source)
   {
      if (!AreCompatible(*this,source)) {
         Error("operator=(const TMatrixTSym2 &)","matrices not compatible");
         return *this;
      }

      TObject::operator=(source);
      const Element2 * const ps = source.GetMatrixArray();
            Element  * const pt = this->GetMatrixArray();
      for (Int_t i = 0; i < this->fNelems; i++)
         pt[i] = ps[i];
      this->fTol = source.GetTol();
      return *this;
   }

   TMatrixTSym<Element> &operator= (Element val);
   TMatrixTSym<Element> &operator-=(Element val);
   TMatrixTSym<Element> &operator+=(Element val);
   TMatrixTSym<Element> &operator*=(Element val);

   TMatrixTSym &operator+=(const TMatrixTSym &source);
   TMatrixTSym &operator-=(const TMatrixTSym &source);

   TMatrixTBase<Element> &Apply(const TElementActionT   <Element> &action);
   TMatrixTBase<Element> &Apply(const TElementPosActionT<Element> &action);

   virtual TMatrixTBase<Element> &Randomize  (Element alpha,Element beta,Double_t &seed);
   virtual TMatrixTSym <Element> &RandomizePD(Element alpha,Element beta,Double_t &seed);

   const TMatrixT<Element> EigenVectors(TVectorT<Element> &eigenValues) const;

   ClassDef(TMatrixTSym,2) // Template of Symmetric Matrix class
};

template <class Element> inline const Element               *TMatrixTSym<Element>::GetMatrixArray() const { return fElements; }
template <class Element> inline       Element               *TMatrixTSym<Element>::GetMatrixArray()       { return fElements; }

template <class Element> inline       TMatrixTSym<Element>  &TMatrixTSym<Element>::Use           (Int_t nrows,Element *data) { return Use(0,nrows-1,data); }
template <class Element> inline const TMatrixTSym<Element>  &TMatrixTSym<Element>::Use           (Int_t nrows,const Element *data) const
                                                                                                   { return Use(0,nrows-1,data); }
template <class Element> inline       TMatrixTSym<Element>  &TMatrixTSym<Element>::Use           (TMatrixTSym<Element> &a)
                                                                                                 { return Use(a.GetRowLwb(),a.GetRowUpb(),a.GetMatrixArray()); }
template <class Element> inline const TMatrixTSym<Element>  &TMatrixTSym<Element>::Use           (const TMatrixTSym<Element> &a) const
                                                                                                 { return Use(a.GetRowLwb(),a.GetRowUpb(),a.GetMatrixArray()); }

template <class Element> inline       TMatrixTSym<Element>   TMatrixTSym<Element>::GetSub        (Int_t row_lwb,Int_t row_upb,Int_t col_lwb,Int_t col_upb,
                                                                                                  Option_t *option) const
                                                                                                 {
                                                                                                   TMatrixTSym<Element> tmp;
                                                                                                   this->GetSub(row_lwb,row_upb,col_lwb,col_upb,tmp,option);
                                                                                                   return tmp;
                                                                                                 }

template <class Element> inline Element TMatrixTSym<Element>::operator()(Int_t rown,Int_t coln) const
{
   R__ASSERT(this->IsValid());
   const Int_t arown = rown-this->fRowLwb;
   const Int_t acoln = coln-this->fColLwb;
   if (arown >= this->fNrows || arown < 0) {
      Error("operator()","Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows);
      return 0.0;
   }
   if (acoln >= this->fNcols || acoln < 0) {
      Error("operator()","Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols);
      return 0.0;
   }
   return (fElements[arown*this->fNcols+acoln]);
}

template <class Element> inline Element &TMatrixTSym<Element>::operator()(Int_t rown,Int_t coln)
{
   R__ASSERT(this->IsValid());
   const Int_t arown = rown-this->fRowLwb;
   const Int_t acoln = coln-this->fColLwb;
   if (arown >= this->fNrows || arown < 0) {
      Error("operator()","Request row(%d) outside matrix range of %d - %d",rown,this->fRowLwb,this->fRowLwb+this->fNrows);
      return fElements[0];
   }
   if (acoln >= this->fNcols || acoln < 0) {
      Error("operator()","Request column(%d) outside matrix range of %d - %d",coln,this->fColLwb,this->fColLwb+this->fNcols);
      return fElements[0];
   }
   return (fElements[arown*this->fNcols+acoln]);
}

template <class Element> Bool_t                operator== (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator+  (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator+  (const TMatrixTSym<Element> &source1,      Element                val);
template <class Element> TMatrixTSym<Element>  operator+  (      Element               val    ,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator-  (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator-  (const TMatrixTSym<Element> &source1,      Element                val);
template <class Element> TMatrixTSym<Element>  operator-  (      Element               val    ,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator*  (const TMatrixTSym<Element> &source,       Element                val    );
template <class Element> TMatrixTSym<Element>  operator*  (      Element               val,    const TMatrixTSym<Element>  &source );
template <class Element> TMatrixTSym<Element>  operator&& (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator|| (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator>  (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator>= (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator<= (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);
template <class Element> TMatrixTSym<Element>  operator<  (const TMatrixTSym<Element> &source1,const TMatrixTSym<Element>  &source2);

template <class Element> TMatrixTSym<Element> &Add        (TMatrixTSym<Element> &target,      Element               scalar,const TMatrixTSym<Element> &source);
template <class Element> TMatrixTSym<Element> &ElementMult(TMatrixTSym<Element> &target,const TMatrixTSym<Element> &source);
template <class Element> TMatrixTSym<Element> &ElementDiv (TMatrixTSym<Element> &target,const TMatrixTSym<Element> &source);

#endif
 TMatrixTSym.h:1
 TMatrixTSym.h:2
 TMatrixTSym.h:3
 TMatrixTSym.h:4
 TMatrixTSym.h:5
 TMatrixTSym.h:6
 TMatrixTSym.h:7
 TMatrixTSym.h:8
 TMatrixTSym.h:9
 TMatrixTSym.h:10
 TMatrixTSym.h:11
 TMatrixTSym.h:12
 TMatrixTSym.h:13
 TMatrixTSym.h:14
 TMatrixTSym.h:15
 TMatrixTSym.h:16
 TMatrixTSym.h:17
 TMatrixTSym.h:18
 TMatrixTSym.h:19
 TMatrixTSym.h:20
 TMatrixTSym.h:21
 TMatrixTSym.h:22
 TMatrixTSym.h:23
 TMatrixTSym.h:24
 TMatrixTSym.h:25
 TMatrixTSym.h:26
 TMatrixTSym.h:27
 TMatrixTSym.h:28
 TMatrixTSym.h:29
 TMatrixTSym.h:30
 TMatrixTSym.h:31
 TMatrixTSym.h:32
 TMatrixTSym.h:33
 TMatrixTSym.h:34
 TMatrixTSym.h:35
 TMatrixTSym.h:36
 TMatrixTSym.h:37
 TMatrixTSym.h:38
 TMatrixTSym.h:39
 TMatrixTSym.h:40
 TMatrixTSym.h:41
 TMatrixTSym.h:42
 TMatrixTSym.h:43
 TMatrixTSym.h:44
 TMatrixTSym.h:45
 TMatrixTSym.h:46
 TMatrixTSym.h:47
 TMatrixTSym.h:48
 TMatrixTSym.h:49
 TMatrixTSym.h:50
 TMatrixTSym.h:51
 TMatrixTSym.h:52
 TMatrixTSym.h:53
 TMatrixTSym.h:54
 TMatrixTSym.h:55
 TMatrixTSym.h:56
 TMatrixTSym.h:57
 TMatrixTSym.h:58
 TMatrixTSym.h:59
 TMatrixTSym.h:60
 TMatrixTSym.h:61
 TMatrixTSym.h:62
 TMatrixTSym.h:63
 TMatrixTSym.h:64
 TMatrixTSym.h:65
 TMatrixTSym.h:66
 TMatrixTSym.h:67
 TMatrixTSym.h:68
 TMatrixTSym.h:69
 TMatrixTSym.h:70
 TMatrixTSym.h:71
 TMatrixTSym.h:72
 TMatrixTSym.h:73
 TMatrixTSym.h:74
 TMatrixTSym.h:75
 TMatrixTSym.h:76
 TMatrixTSym.h:77
 TMatrixTSym.h:78
 TMatrixTSym.h:79
 TMatrixTSym.h:80
 TMatrixTSym.h:81
 TMatrixTSym.h:82
 TMatrixTSym.h:83
 TMatrixTSym.h:84
 TMatrixTSym.h:85
 TMatrixTSym.h:86
 TMatrixTSym.h:87
 TMatrixTSym.h:88
 TMatrixTSym.h:89
 TMatrixTSym.h:90
 TMatrixTSym.h:91
 TMatrixTSym.h:92
 TMatrixTSym.h:93
 TMatrixTSym.h:94
 TMatrixTSym.h:95
 TMatrixTSym.h:96
 TMatrixTSym.h:97
 TMatrixTSym.h:98
 TMatrixTSym.h:99
 TMatrixTSym.h:100
 TMatrixTSym.h:101
 TMatrixTSym.h:102
 TMatrixTSym.h:103
 TMatrixTSym.h:104
 TMatrixTSym.h:105
 TMatrixTSym.h:106
 TMatrixTSym.h:107
 TMatrixTSym.h:108
 TMatrixTSym.h:109
 TMatrixTSym.h:110
 TMatrixTSym.h:111
 TMatrixTSym.h:112
 TMatrixTSym.h:113
 TMatrixTSym.h:114
 TMatrixTSym.h:115
 TMatrixTSym.h:116
 TMatrixTSym.h:117
 TMatrixTSym.h:118
 TMatrixTSym.h:119
 TMatrixTSym.h:120
 TMatrixTSym.h:121
 TMatrixTSym.h:122
 TMatrixTSym.h:123
 TMatrixTSym.h:124
 TMatrixTSym.h:125
 TMatrixTSym.h:126
 TMatrixTSym.h:127
 TMatrixTSym.h:128
 TMatrixTSym.h:129
 TMatrixTSym.h:130
 TMatrixTSym.h:131
 TMatrixTSym.h:132
 TMatrixTSym.h:133
 TMatrixTSym.h:134
 TMatrixTSym.h:135
 TMatrixTSym.h:136
 TMatrixTSym.h:137
 TMatrixTSym.h:138
 TMatrixTSym.h:139
 TMatrixTSym.h:140
 TMatrixTSym.h:141
 TMatrixTSym.h:142
 TMatrixTSym.h:143
 TMatrixTSym.h:144
 TMatrixTSym.h:145
 TMatrixTSym.h:146
 TMatrixTSym.h:147
 TMatrixTSym.h:148
 TMatrixTSym.h:149
 TMatrixTSym.h:150
 TMatrixTSym.h:151
 TMatrixTSym.h:152
 TMatrixTSym.h:153
 TMatrixTSym.h:154
 TMatrixTSym.h:155
 TMatrixTSym.h:156
 TMatrixTSym.h:157
 TMatrixTSym.h:158
 TMatrixTSym.h:159
 TMatrixTSym.h:160
 TMatrixTSym.h:161
 TMatrixTSym.h:162
 TMatrixTSym.h:163
 TMatrixTSym.h:164
 TMatrixTSym.h:165
 TMatrixTSym.h:166
 TMatrixTSym.h:167
 TMatrixTSym.h:168
 TMatrixTSym.h:169
 TMatrixTSym.h:170
 TMatrixTSym.h:171
 TMatrixTSym.h:172
 TMatrixTSym.h:173
 TMatrixTSym.h:174
 TMatrixTSym.h:175
 TMatrixTSym.h:176
 TMatrixTSym.h:177
 TMatrixTSym.h:178
 TMatrixTSym.h:179
 TMatrixTSym.h:180
 TMatrixTSym.h:181
 TMatrixTSym.h:182
 TMatrixTSym.h:183
 TMatrixTSym.h:184
 TMatrixTSym.h:185
 TMatrixTSym.h:186
 TMatrixTSym.h:187
 TMatrixTSym.h:188
 TMatrixTSym.h:189
 TMatrixTSym.h:190
 TMatrixTSym.h:191
 TMatrixTSym.h:192
 TMatrixTSym.h:193
 TMatrixTSym.h:194
 TMatrixTSym.h:195
 TMatrixTSym.h:196
 TMatrixTSym.h:197
 TMatrixTSym.h:198
 TMatrixTSym.h:199
 TMatrixTSym.h:200
 TMatrixTSym.h:201
 TMatrixTSym.h:202
 TMatrixTSym.h:203
 TMatrixTSym.h:204
 TMatrixTSym.h:205
 TMatrixTSym.h:206
 TMatrixTSym.h:207
 TMatrixTSym.h:208
 TMatrixTSym.h:209
 TMatrixTSym.h:210
 TMatrixTSym.h:211
 TMatrixTSym.h:212
 TMatrixTSym.h:213
 TMatrixTSym.h:214
 TMatrixTSym.h:215
 TMatrixTSym.h:216
 TMatrixTSym.h:217
 TMatrixTSym.h:218
 TMatrixTSym.h:219
 TMatrixTSym.h:220
 TMatrixTSym.h:221
 TMatrixTSym.h:222
 TMatrixTSym.h:223
 TMatrixTSym.h:224
 TMatrixTSym.h:225
 TMatrixTSym.h:226
 TMatrixTSym.h:227
 TMatrixTSym.h:228
 TMatrixTSym.h:229
 TMatrixTSym.h:230
 TMatrixTSym.h:231
 TMatrixTSym.h:232
 TMatrixTSym.h:233
 TMatrixTSym.h:234
 TMatrixTSym.h:235
 TMatrixTSym.h:236
 TMatrixTSym.h:237
 TMatrixTSym.h:238
 TMatrixTSym.h:239
 TMatrixTSym.h:240
 TMatrixTSym.h:241
 TMatrixTSym.h:242
 TMatrixTSym.h:243
 TMatrixTSym.h:244
 TMatrixTSym.h:245
 TMatrixTSym.h:246
 TMatrixTSym.h:247
 TMatrixTSym.h:248
 TMatrixTSym.h:249
 TMatrixTSym.h:250
 TMatrixTSym.h:251
 TMatrixTSym.h:252
 TMatrixTSym.h:253