// @(#)root/matrix:$Id$
// 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_TVectorT
#define ROOT_TVectorT

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TVectorT                                                             //
//                                                                      //
// Template class of Vectors in the linear algebra package              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TMatrixT
#include "TMatrixT.h"
#endif
#ifndef ROOT_TMatrixTSym
#include "TMatrixTSym.h"
#endif
#ifndef ROOT_TMatrixTSparse
#include "TMatrixTSparse.h"
#endif

template<class Element> class TVectorT : public TObject {

protected:
   Int_t    fNrows;                // number of rows
   Int_t    fRowLwb;               // lower bound of the row index
   Element *fElements;             //[fNrows] elements themselves

   enum {kSizeMax = 5};             // size data container on stack, see New_m(),Delete_m()
   enum {kWorkMax = 100};           // size of work array's in several routines

   Element  fDataStack[kSizeMax];  //! data container
   Bool_t   fIsOwner;              //!default kTRUE, when Use array kFALSE

   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 row_lwb = 0,Int_t init = 0);

   enum EVectorStatusBits {
     kStatus = BIT(14) // set if vector object is valid
   };

public:

   TVectorT() : fNrows(0), fRowLwb(0), fElements(0), fDataStack (), fIsOwner(kTRUE) { }
   explicit TVectorT(Int_t n);
   TVectorT(Int_t lwb,Int_t upb);
   TVectorT(Int_t n,const Element *elements);
   TVectorT(Int_t lwb,Int_t upb,const Element *elements);
   TVectorT(const TVectorT            <Element> &another);
   TVectorT(const TMatrixTRow_const   <Element> &mr);
   TVectorT(const TMatrixTColumn_const<Element> &mc);
   TVectorT(const TMatrixTDiag_const  <Element> &md);
   template <class Element2> TVectorT(const TVectorT<Element2> &another)
   {
      R__ASSERT(another.IsValid());
      Allocate(another.GetUpb()-another.GetLwb()+1,another.GetLwb());
      *this = another;
   }
#ifndef __CINT__
   TVectorT(Int_t lwb,Int_t upb,Element iv1, ...);
#endif
   virtual ~TVectorT() { Clear(); }

   inline          Int_t     GetLwb       () const { return fRowLwb; }
   inline          Int_t     GetUpb       () const { return fNrows+fRowLwb-1; }
   inline          Int_t     GetNrows     () const { return fNrows; }
   inline          Int_t     GetNoElements() const { return fNrows; }

   inline          Element  *GetMatrixArray  ()       { return fElements; }
   inline const    Element  *GetMatrixArray  () const { return fElements; }

   inline void     Invalidate ()       { SetBit(kStatus); }
   inline void     MakeValid  ()       { ResetBit(kStatus); }
   inline Bool_t   IsValid    () const { return !TestBit(kStatus); }
   inline Bool_t   IsOwner    () const { return fIsOwner; }
   inline void     SetElements(const Element *elements) { R__ASSERT(IsValid());
                                                          memcpy(fElements,elements,fNrows*sizeof(Element)); }
   inline TVectorT<Element> &Shift     (Int_t row_shift)            { fRowLwb += row_shift; return *this; }
          TVectorT<Element> &ResizeTo  (Int_t lwb,Int_t upb);
   inline TVectorT<Element> &ResizeTo  (Int_t n)                    { return ResizeTo(0,n-1); }
   inline TVectorT<Element> &ResizeTo  (const TVectorT<Element> &v) { return ResizeTo(v.GetLwb(),v.GetUpb()); }

          TVectorT<Element> &Use       (Int_t lwb,Int_t upb,Element *data);
   const  TVectorT<Element> &Use       (Int_t lwb,Int_t upb,const Element *data) const
					 { return (const TVectorT<Element>&)(const_cast<TVectorT<Element> *>(this))->Use(lwb,upb,const_cast<Element *>(data)); }
          TVectorT<Element> &Use       (Int_t n,Element *data);
   const  TVectorT<Element> &Use       (Int_t n,const Element *data) const ;
          TVectorT<Element> &Use       (TVectorT<Element> &v);
   const  TVectorT<Element> &Use       (const TVectorT<Element> &v) const ;

          TVectorT<Element> &GetSub    (Int_t row_lwb,Int_t row_upb,TVectorT<Element> &target,Option_t *option="S") const;
          TVectorT<Element>  GetSub    (Int_t row_lwb,Int_t row_upb,Option_t *option="S") const;
          TVectorT<Element> &SetSub    (Int_t row_lwb,const TVectorT<Element> &source);

   TVectorT<Element> &Zero();
   TVectorT<Element> &Abs ();
   TVectorT<Element> &Sqr ();
   TVectorT<Element> &Sqrt();
   TVectorT<Element> &Invert();
   TVectorT<Element> &SelectNonZeros(const TVectorT<Element> &select);

   Element Norm1   () const;
   Element Norm2Sqr() const;
   Element NormInf () const;
   Int_t   NonZeros() const;
   Element Sum     () const;
   Element Min     () const;
   Element Max     () const;

   inline const Element &operator()(Int_t index) const;
   inline       Element &operator()(Int_t index);
   inline const Element &operator[](Int_t index) const { return (*this)(index); }
   inline       Element &operator[](Int_t index)       { return (*this)(index); }

   TVectorT<Element> &operator= (const TVectorT                <Element> &source);
   TVectorT<Element> &operator= (const TMatrixTRow_const       <Element> &mr);
   TVectorT<Element> &operator= (const TMatrixTColumn_const    <Element> &mc);
   TVectorT<Element> &operator= (const TMatrixTDiag_const      <Element> &md);
   TVectorT<Element> &operator= (const TMatrixTSparseRow_const <Element> &md);
   TVectorT<Element> &operator= (const TMatrixTSparseDiag_const<Element> &md);
   template <class Element2> TVectorT<Element> &operator= (const TVectorT<Element2> &source)
   {
      if (!AreCompatible(*this,source)) {
         Error("operator=(const TVectorT2 &)","vectors not compatible");
         return *this;
      }

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

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

   TVectorT<Element> &operator+=(const TVectorT      <Element> &source);
   TVectorT<Element> &operator-=(const TVectorT      <Element> &source);
   TVectorT<Element> &operator*=(const TMatrixT      <Element> &a);
   TVectorT<Element> &operator*=(const TMatrixTSym   <Element> &a);
   TVectorT<Element> &operator*=(const TMatrixTSparse<Element> &a);

   Bool_t operator==(Element val) const;
   Bool_t operator!=(Element val) const;
   Bool_t operator< (Element val) const;
   Bool_t operator<=(Element val) const;
   Bool_t operator> (Element val) const;
   Bool_t operator>=(Element val) const;

   Bool_t MatchesNonZeroPattern(const TVectorT<Element> &select);
   Bool_t SomePositive         (const TVectorT<Element> &select);
   void   AddSomeConstant      (Element val,const TVectorT<Element> &select);

   void   Randomize            (Element alpha,Element beta,Double_t &seed);

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

   void Add(const TVectorT<Element> &v);
   void Add(const TVectorT<Element> &v1, const TVectorT<Element> &v2);
   void Clear(Option_t * /*option*/ ="") { if (fIsOwner) Delete_m(fNrows,fElements);
                                           else fElements = 0; fNrows = 0; }
   void Draw (Option_t *option=""); // *MENU*
   void Print(Option_t *option="") const;  // *MENU*

   ClassDef(TVectorT,4)  // Template of Vector class
};

template<class Element> inline       TVectorT<Element> &TVectorT<Element>::Use     (Int_t n,Element *data) { return Use(0,n-1,data); }
template<class Element> inline const TVectorT<Element> &TVectorT<Element>::Use     (Int_t n,const Element *data) const { return Use(0,n-1,data); }
template<class Element> inline       TVectorT<Element> &TVectorT<Element>::Use     (TVectorT &v)
                                                                                   {
                                                                                     R__ASSERT(v.IsValid());
                                                                                     return Use(v.GetLwb(),v.GetUpb(),v.GetMatrixArray());
                                                                                   }
template<class Element> inline const TVectorT<Element> &TVectorT<Element>::Use     (const TVectorT &v) const
                                                                                   {
                                                                                     R__ASSERT(v.IsValid());
                                                                                     return Use(v.GetLwb(),v.GetUpb(),v.GetMatrixArray());
                                                                                   }
template<class Element> inline       TVectorT<Element>  TVectorT<Element>::GetSub  (Int_t row_lwb,Int_t row_upb,Option_t *option) const
                                                                                   {
                                                                                     TVectorT tmp;
                                                                                     this->GetSub(row_lwb,row_upb,tmp,option);
                                                                                     return tmp;
                                                                                   }

template<class Element> inline const Element &TVectorT<Element>::operator()(Int_t ind) const
{
   // Access a vector element.

   R__ASSERT(IsValid());
   const Int_t aind = ind-fRowLwb;
   if (aind >= fNrows || aind < 0) {
      Error("operator()","Request index(%d) outside vector range of %d - %d",ind,fRowLwb,fRowLwb+fNrows);
      return fElements[0];
   }

   return fElements[aind];
}
template<class Element> inline Element &TVectorT<Element>::operator()(Int_t ind)
{
   // Access a vector element.
   
   R__ASSERT(IsValid());
   const Int_t aind = ind-fRowLwb;
   if (aind >= fNrows || aind < 0) {
      Error("operator()","Request index(%d) outside vector range of %d - %d",ind,fRowLwb,fRowLwb+fNrows);
      return fElements[0];
   }
   
   return fElements[aind];
}

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

template<class Element> Element             Dot         (const TVectorT      <Element>  &source1,const TVectorT <Element>  &source2);
template <class Element1,class Element2>
                        TMatrixT<Element1>  OuterProduct(const TVectorT      <Element1> &v1,     const TVectorT <Element2> &v2);
template <class Element1,class Element2,class Element3>
                        TMatrixT<Element1> &OuterProduct(      TMatrixT      <Element1> &target, const TVectorT <Element2> &v1,     const TVectorT      <Element3> &v2);
template <class Element1,class Element2,class Element3>
                        Element1            Mult        (const TVectorT      <Element1> &v1,     const TMatrixT <Element2> &m,      const TVectorT      <Element3> &v2);

template<class Element> TVectorT<Element>  &Add         (      TVectorT      <Element>  &target,       Element              scalar, const TVectorT      <Element>  &source);
template<class Element> TVectorT<Element>  &Add         (      TVectorT      <Element>  &target,       Element              scalar, const TMatrixT      <Element>  &a,
                                                         const TVectorT<Element> &source);
template<class Element> TVectorT<Element>  &Add         (      TVectorT      <Element>  &target,       Element              scalar, const TMatrixTSym   <Element>  &a,
                                                         const TVectorT<Element> &source);
template<class Element> TVectorT<Element>  &Add         (      TVectorT      <Element>  &target,       Element              scalar, const TMatrixTSparse<Element>  &a,
                                                         const TVectorT<Element> &source);
template<class Element> TVectorT<Element>  &AddElemMult (      TVectorT      <Element>  &target,       Element              scalar, const TVectorT      <Element>  &source1,
                                                         const TVectorT      <Element>  &source2);
template<class Element> TVectorT<Element>  &AddElemMult (      TVectorT      <Element>  &target,       Element              scalar, const TVectorT      <Element>  &source1,
                                                         const TVectorT      <Element>  &source2,const TVectorT <Element>  &select);
template<class Element> TVectorT<Element>  &AddElemDiv  (      TVectorT      <Element>  &target,       Element              scalar, const TVectorT      <Element>  &source1,
                                                         const TVectorT      <Element>  &source2);
template<class Element> TVectorT<Element>  &AddElemDiv  (      TVectorT      <Element>  &target,       Element              scalar, const TVectorT      <Element>  &source1,
                                                         const TVectorT      <Element>  &source2,const TVectorT <Element>  &select);
template<class Element> TVectorT<Element>  &ElementMult (      TVectorT      <Element>  &target, const TVectorT <Element>  &source);
template<class Element> TVectorT<Element>  &ElementMult (      TVectorT      <Element>  &target, const TVectorT <Element>  &source, const TVectorT      <Element>  &select);
template<class Element> TVectorT<Element>  &ElementDiv  (      TVectorT      <Element>  &target, const TVectorT <Element>  &source);
template<class Element> TVectorT<Element>  &ElementDiv  (      TVectorT      <Element>  &target, const TVectorT <Element>  &source, const TVectorT      <Element>  &select);

template<class Element1,class Element2> Bool_t AreCompatible(const TVectorT<Element1> &v1,const TVectorT<Element2> &v2,Int_t verbose=0);
// Check matrix and vector for compatibility in multiply:  M * v and v * M
template<class Element1,class Element2> Bool_t AreCompatible(const TMatrixT<Element1> &m, const TVectorT<Element2> &v, Int_t verbose=0);
template<class Element1,class Element2> Bool_t AreCompatible(const TVectorT<Element1> &v, const TMatrixT<Element2> &m, Int_t verbose=0);

template<class Element> void   Compare              (const TVectorT <Element>  &source1,const TVectorT <Element>  &source2);
template<class Element> Bool_t VerifyVectorValue    (const TVectorT <Element>  &m,            Element val,Int_t verbose, Element maxDevAllow);
template<class Element> Bool_t VerifyVectorValue    (const TVectorT <Element>  &m,            Element val,Int_t verbose)
                                                     { return VerifyVectorValue(m,val,verbose,Element(0.0)); }
template<class Element> Bool_t VerifyVectorValue    (const TVectorT <Element>  &m,            Element val)
                                                     { return VerifyVectorValue(m,val,1,Element(0.0)); }
template<class Element> Bool_t VerifyVectorIdentity (const TVectorT <Element>  &m1,const TVectorT <Element> &m2, Int_t verbose, Element maxDevAllow);
template<class Element> Bool_t VerifyVectorIdentity (const TVectorT <Element>  &m1,const TVectorT <Element> &m2, Int_t verbose)
                                                     { return VerifyVectorIdentity(m1,m2,verbose,Element(0.0)); }
template<class Element> Bool_t VerifyVectorIdentity (const TVectorT <Element>  &m1,const TVectorT <Element> &m2)
                                                     { return VerifyVectorIdentity(m1,m2,1,Element(0.0)); }

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