ROOT logo
#include "AliMatrixSparse.h"
#include "TStopwatch.h"

/**********************************************************************************************/
/* Sparse matrix class, used as a global matrix for AliMillePede2                             */
/*                                                                                            */ 
/* Author: ruben.shahoyan@cern.ch                                                             */
/*                                                                                            */ 
/*                                                                                            */ 
/*                                                                                            */ 
/**********************************************************************************************/

//___________________________________________________________
ClassImp(AliMatrixSparse)

//___________________________________________________________
AliMatrixSparse::AliMatrixSparse(Int_t sz)
: AliMatrixSq(),fVecs(0)
{
  // constructor
  fNcols=fNrows=sz;
  //
  fVecs = new AliVectorSparse*[sz];
  for (int i=GetSize();i--;) fVecs[i] = new AliVectorSparse();
}

//___________________________________________________________
AliMatrixSparse::AliMatrixSparse(const AliMatrixSparse& src)
  : AliMatrixSq(src),fVecs(0)
{
  // copy c-tor
  fVecs = new AliVectorSparse*[src.GetSize()];
  for (int i=GetSize();i--;) fVecs[i] = new AliVectorSparse( *src.GetRow(i));
}

//___________________________________________________________
AliVectorSparse* AliMatrixSparse::GetRowAdd(Int_t ir)
{
  // get row, add if needed
  if (ir>=fNrows) {
    AliVectorSparse** arrv = new AliVectorSparse*[ir+1];
    for (int i=GetSize();i--;) arrv[i] = fVecs[i];
    delete [] fVecs;
    fVecs = arrv;    
    for (int i=GetSize();i<=ir;i++) fVecs[i] = new AliVectorSparse();
    fNrows = ir+1;
    if (IsSymmetric() && fNcols<fNrows) fNcols = fNrows;
  }
  return fVecs[ir];
}

//___________________________________________________________
AliMatrixSparse& AliMatrixSparse::operator=(const AliMatrixSparse& src)
{
  // assignment op-r
  if (this == &src) return *this;
  AliMatrixSq::operator=(src);

  Clear();
  fNcols = src.GetNCols();
  fNrows = src.GetNRows();
  SetSymmetric(src.IsSymmetric());
  fVecs = new AliVectorSparse*[fNrows];
  for (int i=fNrows;i--;) fVecs[i] = new AliVectorSparse( *src.GetRow(i));
  return *this;
}

//___________________________________________________________
void AliMatrixSparse::Clear(Option_t*) 
{
  // clear
  for (int i=fNrows;i--;) delete GetRow(i);
  delete [] fVecs;
  fNcols = fNrows = 0;
}

//___________________________________________________________
void AliMatrixSparse::Print(Option_t* opt)  const
{
  // print itself
  printf("Sparse Matrix of size %d x %d %s\n",fNrows,fNcols,IsSymmetric() ? " (Symmetric)":"");
  for (int i=0;i<fNrows;i++) {
    AliVectorSparse* row = GetRow(i);
    if (!row->GetNElems()) continue;
    printf("%3d: ",i); 
    row->Print(opt);
  }
}

//___________________________________________________________
void AliMatrixSparse::MultiplyByVec(const Double_t* vecIn, Double_t* vecOut) const
{
  // fill vecOut by matrix*vecIn
  // vector should be of the same size as the matrix
  //
  memset(vecOut,0,GetSize()*sizeof(Double_t));
  //
  for (int rw=GetSize();rw--;) {  // loop over rows >>>
    const AliVectorSparse* rowV = GetRow(rw);
    Int_t nel  = rowV->GetNElems();
    if (!nel) continue;
    //
    UShort_t* indV = rowV->GetIndices();
    Double_t* elmV = rowV->GetElems();
    //
    if (IsSymmetric()) {
      // treat diagonal term separately. If filled, it should be the last one
      if (indV[--nel]==rw) vecOut[rw] += vecIn[rw]*elmV[nel];
      else nel = rowV->GetNElems(); // diag elem was not filled
      //
      for (int iel=nel;iel--;) {          // less element retrieval for symmetric case
	if (elmV[iel]) {        
	  vecOut[rw]        += vecIn[indV[iel]]*elmV[iel];
	  vecOut[indV[iel]] += vecIn[rw]*elmV[iel];
	}
      }
    }
    else for (int iel=nel;iel--;) if (elmV[iel]) vecOut[rw] += vecIn[indV[iel]]*elmV[iel];
    //
  } // loop over rows <<<
  //
}

//___________________________________________________________
void AliMatrixSparse::SortIndices(Bool_t valuesToo)
{
  // sort columns in increasing order. Used to fix the matrix after ILUk decompostion
  TStopwatch sw; 
  sw.Start();
  printf("AliMatrixSparse:sort>>\n");
  for (int i=GetSize();i--;) GetRow(i)->SortIndices(valuesToo);
  sw.Stop();
  sw.Print();
  printf("AliMatrixSparse:sort<<\n");
}

//___________________________________________________________
void AliMatrixSparse::AddToRow(Int_t r, Double_t *valc,Int_t *indc,Int_t n)
{
  // for sym. matrix count how many elems to add have row>=col and assign excplicitly 
  // those which have row<col
  //   
  // range in increasing order of indices
  for (int i=n;i--;) {
    for (int j=i;j>=0;j--) {
      if (indc[j]>indc[i]) { // swap
	int    ti = indc[i]; indc[i] = indc[j]; indc[j] = ti;
	double tv = valc[i]; valc[i] = valc[j]; valc[j] = tv;
      }
    }
  }
  //
  int ni=n;
  if (IsSymmetric()) {
    while(ni--) {
      if (indc[ni]>r) (*this)(indc[ni],r) += valc[ni]; 
      else break;  // use the fact that the indices are ranged in increasing order
    }
  }
  //
  if (ni<0) return;
  AliVectorSparse* row = GetRowAdd(r);
  row->Add(valc,indc,ni+1);
}

//___________________________________________________________
Float_t AliMatrixSparse::GetDensity() const
{
  // get fraction of non-zero elements
  Int_t nel = 0;
  for (int i=GetSize();i--;) nel += GetRow(i)->GetNElems();
  int den = IsSymmetric() ? (GetSize()+1)*GetSize()/2 : GetSize()*GetSize();
  return float(nel)/den;
}

 AliMatrixSparse.cxx:1
 AliMatrixSparse.cxx:2
 AliMatrixSparse.cxx:3
 AliMatrixSparse.cxx:4
 AliMatrixSparse.cxx:5
 AliMatrixSparse.cxx:6
 AliMatrixSparse.cxx:7
 AliMatrixSparse.cxx:8
 AliMatrixSparse.cxx:9
 AliMatrixSparse.cxx:10
 AliMatrixSparse.cxx:11
 AliMatrixSparse.cxx:12
 AliMatrixSparse.cxx:13
 AliMatrixSparse.cxx:14
 AliMatrixSparse.cxx:15
 AliMatrixSparse.cxx:16
 AliMatrixSparse.cxx:17
 AliMatrixSparse.cxx:18
 AliMatrixSparse.cxx:19
 AliMatrixSparse.cxx:20
 AliMatrixSparse.cxx:21
 AliMatrixSparse.cxx:22
 AliMatrixSparse.cxx:23
 AliMatrixSparse.cxx:24
 AliMatrixSparse.cxx:25
 AliMatrixSparse.cxx:26
 AliMatrixSparse.cxx:27
 AliMatrixSparse.cxx:28
 AliMatrixSparse.cxx:29
 AliMatrixSparse.cxx:30
 AliMatrixSparse.cxx:31
 AliMatrixSparse.cxx:32
 AliMatrixSparse.cxx:33
 AliMatrixSparse.cxx:34
 AliMatrixSparse.cxx:35
 AliMatrixSparse.cxx:36
 AliMatrixSparse.cxx:37
 AliMatrixSparse.cxx:38
 AliMatrixSparse.cxx:39
 AliMatrixSparse.cxx:40
 AliMatrixSparse.cxx:41
 AliMatrixSparse.cxx:42
 AliMatrixSparse.cxx:43
 AliMatrixSparse.cxx:44
 AliMatrixSparse.cxx:45
 AliMatrixSparse.cxx:46
 AliMatrixSparse.cxx:47
 AliMatrixSparse.cxx:48
 AliMatrixSparse.cxx:49
 AliMatrixSparse.cxx:50
 AliMatrixSparse.cxx:51
 AliMatrixSparse.cxx:52
 AliMatrixSparse.cxx:53
 AliMatrixSparse.cxx:54
 AliMatrixSparse.cxx:55
 AliMatrixSparse.cxx:56
 AliMatrixSparse.cxx:57
 AliMatrixSparse.cxx:58
 AliMatrixSparse.cxx:59
 AliMatrixSparse.cxx:60
 AliMatrixSparse.cxx:61
 AliMatrixSparse.cxx:62
 AliMatrixSparse.cxx:63
 AliMatrixSparse.cxx:64
 AliMatrixSparse.cxx:65
 AliMatrixSparse.cxx:66
 AliMatrixSparse.cxx:67
 AliMatrixSparse.cxx:68
 AliMatrixSparse.cxx:69
 AliMatrixSparse.cxx:70
 AliMatrixSparse.cxx:71
 AliMatrixSparse.cxx:72
 AliMatrixSparse.cxx:73
 AliMatrixSparse.cxx:74
 AliMatrixSparse.cxx:75
 AliMatrixSparse.cxx:76
 AliMatrixSparse.cxx:77
 AliMatrixSparse.cxx:78
 AliMatrixSparse.cxx:79
 AliMatrixSparse.cxx:80
 AliMatrixSparse.cxx:81
 AliMatrixSparse.cxx:82
 AliMatrixSparse.cxx:83
 AliMatrixSparse.cxx:84
 AliMatrixSparse.cxx:85
 AliMatrixSparse.cxx:86
 AliMatrixSparse.cxx:87
 AliMatrixSparse.cxx:88
 AliMatrixSparse.cxx:89
 AliMatrixSparse.cxx:90
 AliMatrixSparse.cxx:91
 AliMatrixSparse.cxx:92
 AliMatrixSparse.cxx:93
 AliMatrixSparse.cxx:94
 AliMatrixSparse.cxx:95
 AliMatrixSparse.cxx:96
 AliMatrixSparse.cxx:97
 AliMatrixSparse.cxx:98
 AliMatrixSparse.cxx:99
 AliMatrixSparse.cxx:100
 AliMatrixSparse.cxx:101
 AliMatrixSparse.cxx:102
 AliMatrixSparse.cxx:103
 AliMatrixSparse.cxx:104
 AliMatrixSparse.cxx:105
 AliMatrixSparse.cxx:106
 AliMatrixSparse.cxx:107
 AliMatrixSparse.cxx:108
 AliMatrixSparse.cxx:109
 AliMatrixSparse.cxx:110
 AliMatrixSparse.cxx:111
 AliMatrixSparse.cxx:112
 AliMatrixSparse.cxx:113
 AliMatrixSparse.cxx:114
 AliMatrixSparse.cxx:115
 AliMatrixSparse.cxx:116
 AliMatrixSparse.cxx:117
 AliMatrixSparse.cxx:118
 AliMatrixSparse.cxx:119
 AliMatrixSparse.cxx:120
 AliMatrixSparse.cxx:121
 AliMatrixSparse.cxx:122
 AliMatrixSparse.cxx:123
 AliMatrixSparse.cxx:124
 AliMatrixSparse.cxx:125
 AliMatrixSparse.cxx:126
 AliMatrixSparse.cxx:127
 AliMatrixSparse.cxx:128
 AliMatrixSparse.cxx:129
 AliMatrixSparse.cxx:130
 AliMatrixSparse.cxx:131
 AliMatrixSparse.cxx:132
 AliMatrixSparse.cxx:133
 AliMatrixSparse.cxx:134
 AliMatrixSparse.cxx:135
 AliMatrixSparse.cxx:136
 AliMatrixSparse.cxx:137
 AliMatrixSparse.cxx:138
 AliMatrixSparse.cxx:139
 AliMatrixSparse.cxx:140
 AliMatrixSparse.cxx:141
 AliMatrixSparse.cxx:142
 AliMatrixSparse.cxx:143
 AliMatrixSparse.cxx:144
 AliMatrixSparse.cxx:145
 AliMatrixSparse.cxx:146
 AliMatrixSparse.cxx:147
 AliMatrixSparse.cxx:148
 AliMatrixSparse.cxx:149
 AliMatrixSparse.cxx:150
 AliMatrixSparse.cxx:151
 AliMatrixSparse.cxx:152
 AliMatrixSparse.cxx:153
 AliMatrixSparse.cxx:154
 AliMatrixSparse.cxx:155
 AliMatrixSparse.cxx:156
 AliMatrixSparse.cxx:157
 AliMatrixSparse.cxx:158
 AliMatrixSparse.cxx:159
 AliMatrixSparse.cxx:160
 AliMatrixSparse.cxx:161
 AliMatrixSparse.cxx:162
 AliMatrixSparse.cxx:163
 AliMatrixSparse.cxx:164
 AliMatrixSparse.cxx:165
 AliMatrixSparse.cxx:166
 AliMatrixSparse.cxx:167
 AliMatrixSparse.cxx:168
 AliMatrixSparse.cxx:169
 AliMatrixSparse.cxx:170
 AliMatrixSparse.cxx:171
 AliMatrixSparse.cxx:172
 AliMatrixSparse.cxx:173
 AliMatrixSparse.cxx:174
 AliMatrixSparse.cxx:175