Project
Loading...
Searching...
No Matches
MatrixSparse.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
13
14#include <iomanip>
15#include <TStopwatch.h>
16
17#include "Framework/Logger.h"
19
20using namespace o2::fwdalign;
21
23
24//___________________________________________________________
26 : MatrixSq(),
27 fVecs(nullptr)
28{
29 fNcols = fNrows = sz;
30
31 fVecs = new VectorSparse*[sz];
32 for (int i = GetSize(); i--;) {
33 fVecs[i] = new VectorSparse();
34 }
35}
36
37//___________________________________________________________
39 : MatrixSq(src),
40 fVecs(nullptr)
41{
42 fVecs = new VectorSparse*[src.GetSize()];
43 for (int i = GetSize(); i--;) {
44 fVecs[i] = new VectorSparse(*src.GetRow(i));
45 }
46}
47
48//___________________________________________________________
50{
51 // get row, add if needed
52 if (ir >= fNrows) {
53 VectorSparse** arrv = new VectorSparse*[ir + 1];
54 for (int i = GetSize(); i--;) {
55 arrv[i] = fVecs[i];
56 }
57 delete[] fVecs;
58 fVecs = arrv;
59 for (int i = GetSize(); i <= ir; i++) {
60 fVecs[i] = new VectorSparse();
61 }
62 fNrows = ir + 1;
63 if (IsSymmetric() && fNcols < fNrows) {
64 fNcols = fNrows;
65 }
66 }
67 return fVecs[ir];
68}
69
70//___________________________________________________________
72{
73 if (this == &src) {
74 return *this;
75 }
77
78 Clear();
79 fNcols = src.GetNCols();
80 fNrows = src.GetNRows();
81 SetSymmetric(src.IsSymmetric());
82 fVecs = new VectorSparse*[fNrows];
83 for (int i = fNrows; i--;) {
84 fVecs[i] = new VectorSparse(*src.GetRow(i));
85 }
86 return *this;
87}
88
89//___________________________________________________________
90void MatrixSparse::Clear(Option_t*)
91{
92 for (int i = fNrows; i--;) {
93 delete GetRow(i);
94 }
95 delete[] fVecs;
96 fNcols = fNrows = 0;
97}
98
99//___________________________________________________________
100void MatrixSparse::Print(Option_t* opt) const
101{
102 LOG(info) << "Sparse Matrix of size " << fNrows << " x " << fNcols;
103 if (IsSymmetric()) {
104 LOG(info) << " (Symmetric)\n";
105 }
106 for (int i = 0; i < fNrows; i++) {
108 if (!row->GetNElems()) {
109 continue;
110 }
111 printf("%3d: ", i);
112 row->Print(opt);
113 }
114}
115
116//___________________________________________________________
117void MatrixSparse::MultiplyByVec(const Double_t* vecIn, Double_t* vecOut) const
118{
119 memset(vecOut, 0, GetSize() * sizeof(Double_t));
120
121 for (int rw = GetSize(); rw--;) { // loop over rows >>>
122 const VectorSparse* rowV = GetRow(rw);
123 Int_t nel = rowV->GetNElems();
124 if (!nel) {
125 continue;
126 }
127
128 UShort_t* indV = rowV->GetIndices();
129 Double_t* elmV = rowV->GetElems();
130
131 if (IsSymmetric()) {
132 // treat diagonal term separately. If filled, it should be the last one
133 if (indV[--nel] == rw) {
134 vecOut[rw] += vecIn[rw] * elmV[nel];
135 } else {
136 nel = rowV->GetNElems(); // diag elem was not filled
137 }
138 for (int iel = nel; iel--;) { // less element retrieval for symmetric case
139 if (elmV[iel]) {
140 vecOut[rw] += vecIn[indV[iel]] * elmV[iel];
141 vecOut[indV[iel]] += vecIn[rw] * elmV[iel];
142 }
143 }
144 } else {
145 for (int iel = nel; iel--;) {
146 if (elmV[iel]) {
147 vecOut[rw] += vecIn[indV[iel]] * elmV[iel];
148 }
149 }
150 }
151 } // loop over rows <<<
152}
153
154//___________________________________________________________
155void MatrixSparse::SortIndices(Bool_t valuesToo)
156{
157 TStopwatch sw;
158 sw.Start();
159 LOG(info) << "MatrixSparse:SortIndices >>";
160 for (int i = GetSize(); i--;) {
161 GetRow(i)->SortIndices(valuesToo);
162 }
163 sw.Stop();
164 sw.Print();
165 LOG(info) << "MatrixSparse:SortIndices <<";
166}
167
168//___________________________________________________________
169void MatrixSparse::AddToRow(Int_t r, Double_t* valc, Int_t* indc, Int_t n)
170{
171 // for sym. matrix count how many elems to add have row >= col and assign excplicitly
172 // those which have row < col
173
174 // range in increasing order of indices
175 for (int i = n; i--;) {
176 for (int j = i; j >= 0; j--) {
177 if (indc[j] > indc[i]) { // swap
178 int ti = indc[i];
179 indc[i] = indc[j];
180 indc[j] = ti;
181 double tv = valc[i];
182 valc[i] = valc[j];
183 valc[j] = tv;
184 }
185 }
186 }
187
188 int ni = n;
189 if (IsSymmetric()) {
190 while (ni--) {
191 if (indc[ni] > r) {
192 (*this)(indc[ni], r) += valc[ni];
193 } else {
194 break; // use the fact that the indices are ranged in increasing order
195 }
196 }
197 }
198
199 if (ni < 0) {
200 return;
201 }
203 row->Add(valc, indc, ni + 1);
204}
205
206//___________________________________________________________
208{
209
210 Int_t nel = 0;
211 for (int i = GetSize(); i--;) {
212 nel += GetRow(i)->GetNElems();
213 }
214 int den = IsSymmetric() ? (GetSize() + 1) * GetSize() / 2 : GetSize() * GetSize();
215 return float(nel) / den;
216}
int32_t i
ClassImp(MatrixSparse)
Sparse matrix class (from AliROOT), used as a global matrix for MillePede2.
uint32_t j
Definition RawData.h:0
void Clear(Option_t *option="") override
MatrixSparse & operator=(const MatrixSparse &src)
Int_t GetSize() const override
void AddToRow(Int_t r, Double_t *valc, Int_t *indc, Int_t n) override
void MultiplyByVec(const TVectorD &vecIn, TVectorD &vecOut) const override
fill vecOut by matrix * vecIn (vector should be of the same size as the matrix)
void SortIndices(Bool_t valuesToo=kFALSE)
sort columns in increasing order. Used to fix the matrix after ILUk decompostion
void Print(Option_t *option="") const override
Float_t GetDensity() const override
get fraction of non-zero elements
VectorSparse * GetRow(Int_t ir) const
VectorSparse * GetRowAdd(Int_t ir)
Bool_t IsSymmetric() const override
Definition MatrixSq.h:64
MatrixSq & operator=(const MatrixSq &src)
= operator
Definition MatrixSq.cxx:35
void SetSymmetric(Bool_t v=kTRUE)
Definition MatrixSq.h:65
Double_t * GetElems() const
UShort_t * GetIndices() const
void SortIndices(Bool_t valuesToo=kFALSE)
sort indices in increasing order. Used to fix the row after ILUk decomposition
GLdouble n
Definition glcorearb.h:1982
GLenum src
Definition glcorearb.h:1767
GLboolean r
Definition glcorearb.h:1233
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)
TStopwatch sw
std::vector< int > row