Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
LASymMatrix.h
Go to the documentation of this file.
1// @(#)root/minuit2:$Id$
2// Authors: M. Winkler, F. James, L. Moneta, A. Zsenei 2003-2005
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2005 LCG ROOT Math team, CERN/PH-SFT *
7 * *
8 **********************************************************************/
9
10#ifndef ROOT_Minuit2_LASymMatrix
11#define ROOT_Minuit2_LASymMatrix
12
13#include "Minuit2/MnConfig.h"
14#include "Minuit2/ABSum.h"
18
19#include <cassert>
20#include <memory>
21#include <cstring> // for memcopy
22
23// extern StackAllocator StackAllocatorHolder::Get();
24
25namespace ROOT {
26
27namespace Minuit2 {
28
29int Mndaxpy(unsigned int, double, const double *, int, double *, int);
30int Mndscal(unsigned int, double, double *, int);
31
32class LAVector;
33
34int Invert(LASymMatrix &);
35
36/**
37 Class describing a symmetric matrix of size n.
38 The size is specified as a run-time argument passed in the
39 constructor.
40 The class uses expression templates for the operations and functions.
41 Only the independent data are kept in the fdata array of size n*(n+1)/2
42 containing the lower triangular data
43 */
44
46
47private:
48 LASymMatrix() : fSize(0), fNRow(0), fData(nullptr) {}
49
50public:
51 typedef sym Type;
52
53 LASymMatrix(unsigned int n)
54 : fSize(n * (n + 1) / 2),
55 fNRow(n),
56 fData( (n> 0) ? (double *)StackAllocatorHolder::Get().Allocate(sizeof(double) * n * (n + 1) / 2)
57 : nullptr )
58 {
59 // assert(fSize>0);
60 if (fData)
61 std::memset(fData, 0, fSize * sizeof(double));
62 }
63
65 {
66 if (fData)
68 }
69
71 : fSize(v.size()), fNRow(v.Nrow()),
72 fData((double *)StackAllocatorHolder::Get().Allocate(sizeof(double) * v.size()))
73 {
74 std::memcpy(fData, v.Data(), fSize * sizeof(double));
75 }
76
78 {
79 if (fSize < v.size()) {
80 if (fData)
82 fSize = v.size();
83 fData = (double *)StackAllocatorHolder::Get().Allocate(sizeof(double) * fSize);
84 }
85 std::memcpy(fData, v.Data(), fSize * sizeof(double));
86 return *this;
87 }
88
89 template <class T>
91 : fSize(v.Obj().size()), fNRow(v.Obj().Nrow()),
92 fData((double *)StackAllocatorHolder::Get().Allocate(sizeof(double) * v.Obj().size()))
93 {
94 // std::cout<<"LASymMatrix(const ABObj<sym, LASymMatrix, T>& v)"<<std::endl;
95 // std::cout<<"allocate "<<fSize<<std::endl;
96 std::memcpy(fData, v.Obj().Data(), fSize * sizeof(double));
97 Mndscal(fSize, double(v.f()), fData, 1);
98 // std::cout<<"fData= "<<fData[0]<<" "<<fData[1]<<std::endl;
99 }
100
101 template <class A, class B, class T>
103 {
104 // std::cout<<"template<class A, class B, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, A, T>,
105 // ABObj<sym, B, T> > >& sum)"<<std::endl; recursive construction
106 (*this) = sum.Obj().A();
107 (*this) += sum.Obj().B();
108 // std::cout<<"leaving template<class A, class B, class T> LASymMatrix(const ABObj..."<<std::endl;
109 }
110
111 template <class A, class T>
113 : fSize(0), fNRow(0), fData(nullptr)
114 {
115 // std::cout<<"template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix, T>,
116 // ABObj<sym, A, T> >,T>& sum)"<<std::endl;
117
118 // recursive construction
119 // std::cout<<"(*this)=sum.Obj().B();"<<std::endl;
120 (*this) = sum.Obj().B();
121 // std::cout<<"(*this)+=sum.Obj().A();"<<std::endl;
122 (*this) += sum.Obj().A();
123 // std::cout<<"leaving template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym,
124 // LASymMatrix,.."<<std::endl;
125 }
126
127 template <class A, class T>
128 LASymMatrix(const ABObj<sym, ABObj<sym, A, T>, T> &something) : fSize(0), fNRow(0), fData(nullptr)
129 {
130 // std::cout<<"template<class A, class T> LASymMatrix(const ABObj<sym, ABObj<sym, A, T>, T>&
131 // something)"<<std::endl;
132 (*this) = something.Obj();
133 (*this) *= something.f();
134 // std::cout<<"leaving template<class A, class T> LASymMatrix(const ABObj<sym, ABObj<sym, A, T>, T>&
135 // something)"<<std::endl;
136 }
137
138 template <class T>
140 : fSize(inv.Obj().Obj().Obj().size()), fNRow(inv.Obj().Obj().Obj().Nrow()),
141 fData((double *)StackAllocatorHolder::Get().Allocate(sizeof(double) * inv.Obj().Obj().Obj().size()))
142 {
143 std::memcpy(fData, inv.Obj().Obj().Obj().Data(), fSize * sizeof(double));
144 Mndscal(fSize, double(inv.Obj().Obj().f()), fData, 1);
145 Invert(*this);
146 Mndscal(fSize, double(inv.f()), fData, 1);
147 }
148
149 template <class A, class T>
152 &sum)
153 : fSize(0), fNRow(0), fData(0)
154 {
155 // std::cout<<"template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym, MatrixInverse<sym,
156 // ABObj<sym, LASymMatrix, T>, T>, T>, ABObj<sym, A, T> >, T>& sum)"<<std::endl;
157
158 // recursive construction
159 (*this) = sum.Obj().B();
160 (*this) += sum.Obj().A();
161 // std::cout<<"leaving template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym,
162 // LASymMatrix,.."<<std::endl;
163 }
164
166
167 template <class A, class T>
170 : fSize(0), fNRow(0), fData(nullptr)
171 {
172 // std::cout<<"template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym,
173 // VectorOuterProduct<ABObj<vec, LAVector, T>, T>, T> ABObj<sym, A, T> >,T>& sum)"<<std::endl;
174
175 // recursive construction
176 (*this) = sum.Obj().B();
177 (*this) += sum.Obj().A();
178 // std::cout<<"leaving template<class A, class T> LASymMatrix(const ABObj<sym, ABSum<ABObj<sym,
179 // LASymMatrix,.."<<std::endl;
180 }
181
183 {
184 // std::cout<<"LASymMatrix& operator+=(const LASymMatrix& m)"<<std::endl;
185 assert(fSize == m.size());
186 Mndaxpy(fSize, 1., m.Data(), 1, fData, 1);
187 return *this;
188 }
189
191 {
192 // std::cout<<"LASymMatrix& operator-=(const LASymMatrix& m)"<<std::endl;
193 assert(fSize == m.size());
194 Mndaxpy(fSize, -1., m.Data(), 1, fData, 1);
195 return *this;
196 }
197
198 template <class T>
200 {
201 // std::cout<<"template<class T> LASymMatrix& operator+=(const ABObj<sym, LASymMatrix, T>& m)"<<std::endl;
202 assert(fSize == m.Obj().size());
203 if (m.Obj().Data() == fData) {
204 Mndscal(fSize, 1. + double(m.f()), fData, 1);
205 } else {
206 Mndaxpy(fSize, double(m.f()), m.Obj().Data(), 1, fData, 1);
207 }
208 // std::cout<<"fData= "<<fData[0]<<" "<<fData[1]<<std::endl;
209 return *this;
210 }
211
212 template <class A, class T>
214 {
215 // std::cout<<"template<class A, class T> LASymMatrix& operator+=(const ABObj<sym, A,T>& m)"<<std::endl;
216 (*this) += LASymMatrix(m);
217 return *this;
218 }
219
220 template <class T>
222 {
223 // std::cout<<"template<class T> LASymMatrix& operator+=(const ABObj<sym, MatrixInverse<sym, ABObj<sym,
224 // LASymMatrix, T>, T>, T>& m)"<<std::endl;
225 assert(fNRow > 0);
226 LASymMatrix tmp(m.Obj().Obj());
227 Invert(tmp);
228 tmp *= double(m.f());
229 (*this) += tmp;
230 return *this;
231 }
232
233 template <class T>
235 {
236 // std::cout<<"template<class T> LASymMatrix& operator+=(const ABObj<sym, VectorOuterProduct<ABObj<vec,
237 // LAVector, T>, T>, T>&"<<std::endl;
238 assert(fNRow > 0);
239 Outer_prod(*this, m.Obj().Obj().Obj(), m.f() * m.Obj().Obj().f() * m.Obj().Obj().f());
240 return *this;
241 }
242
244 {
245 Mndscal(fSize, scal, fData, 1);
246 return *this;
247 }
248
249 double operator()(unsigned int row, unsigned int col) const
250 {
251 assert(row < fNRow && col < fNRow);
252 if (row > col)
253 return fData[col + row * (row + 1) / 2];
254 else
255 return fData[row + col * (col + 1) / 2];
256 }
257
258 double &operator()(unsigned int row, unsigned int col)
259 {
260 assert(row < fNRow && col < fNRow);
261 if (row > col)
262 return fData[col + row * (row + 1) / 2];
263 else
264 return fData[row + col * (col + 1) / 2];
265 }
266
267 const double *Data() const { return fData; }
268
269 double *Data() { return fData; }
270
271 unsigned int size() const { return fSize; }
272
273 unsigned int Nrow() const { return fNRow; }
274
275 unsigned int Ncol() const { return Nrow(); }
276
277private:
278 unsigned int fSize;
279 unsigned int fNRow;
280 double *fData;
281
282public:
283 template <class T>
285 {
286 // std::cout<<"template<class T> LASymMatrix& operator=(ABObj<sym, LASymMatrix, T>& v)"<<std::endl;
287 if (fSize == 0 && !fData) {
288 fSize = v.Obj().size();
289 fNRow = v.Obj().Nrow();
290 fData = (double *)StackAllocatorHolder::Get().Allocate(sizeof(double) * fSize);
291 } else {
292 assert(fSize == v.Obj().size());
293 }
294 // std::cout<<"fData= "<<fData[0]<<" "<<fData[1]<<std::endl;
295 std::memcpy(fData, v.Obj().Data(), fSize * sizeof(double));
296 (*this) *= v.f();
297 return *this;
298 }
299
300 template <class A, class T>
302 {
303 // std::cout<<"template<class A, class T> LASymMatrix& operator=(const ABObj<sym, ABObj<sym, A, T>, T>&
304 // something)"<<std::endl;
305 if (fSize == 0 && fData == 0) {
306 (*this) = something.Obj();
307 (*this) *= something.f();
308 } else {
309 LASymMatrix tmp(something.Obj());
310 tmp *= something.f();
311 assert(fSize == tmp.size());
312 std::memcpy(fData, tmp.Data(), fSize * sizeof(double));
313 }
314 // std::cout<<"template<class A, class T> LASymMatrix& operator=(const ABObj<sym, ABObj<sym, A, T>, T>&
315 // something)"<<std::endl;
316 return *this;
317 }
318
319 template <class A, class B, class T>
321 {
322 // std::cout<<"template<class A, class B, class T> LASymMatrix& operator=(const ABObj<sym, ABSum<ABObj<sym, A, T>,
323 // ABObj<sym, B, T> >,T>& sum)"<<std::endl;
324 // recursive construction
325 if (fSize == 0 && fData == 0) {
326 (*this) = sum.Obj().A();
327 (*this) += sum.Obj().B();
328 (*this) *= sum.f();
329 } else {
330 LASymMatrix tmp(sum.Obj().A());
331 tmp += sum.Obj().B();
332 tmp *= sum.f();
333 assert(fSize == tmp.size());
334 std::memcpy(fData, tmp.Data(), fSize * sizeof(double));
335 }
336 return *this;
337 }
338
339 template <class A, class T>
341 {
342 // std::cout<<"template<class A, class T> LASymMatrix& operator=(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix,
343 // T>, ABObj<sym, A, T> >,T>& sum)"<<std::endl;
344
345 if (fSize == 0 && fData == 0) {
346 // std::cout<<"fSize == 0 && fData == 0"<<std::endl;
347 (*this) = sum.Obj().B();
348 (*this) += sum.Obj().A();
349 (*this) *= sum.f();
350 } else {
351 // std::cout<<"creating tmp variable"<<std::endl;
352 LASymMatrix tmp(sum.Obj().B());
353 tmp += sum.Obj().A();
354 tmp *= sum.f();
355 assert(fSize == tmp.size());
356 std::memcpy(fData, tmp.Data(), fSize * sizeof(double));
357 }
358 // std::cout<<"leaving LASymMatrix& operator=(const ABObj<sym, ABSum<ABObj<sym, LASymMatrix..."<<std::endl;
359 return *this;
360 }
361
362 template <class T>
364 {
365 if (fSize == 0 && fData == 0) {
366 fSize = inv.Obj().Obj().Obj().size();
367 fNRow = inv.Obj().Obj().Obj().Nrow();
368 fData = (double *)StackAllocatorHolder::Get().Allocate(sizeof(double) * fSize);
369 std::memcpy(fData, inv.Obj().Obj().Obj().Data(), fSize * sizeof(double));
370 (*this) *= inv.Obj().Obj().f();
371 Invert(*this);
372 (*this) *= inv.f();
373 } else {
374 LASymMatrix tmp(inv.Obj().Obj());
375 Invert(tmp);
376 tmp *= double(inv.f());
377 assert(fSize == tmp.size());
378 std::memcpy(fData, tmp.Data(), fSize * sizeof(double));
379 }
380 return *this;
381 }
382
384};
385
386} // namespace Minuit2
387
388} // namespace ROOT
389
390#endif // ROOT_Minuit2_LASymMatrix
Class describing a symmetric matrix of size n.
Definition LASymMatrix.h:45
LASymMatrix(const ABObj< sym, MatrixInverse< sym, ABObj< sym, LASymMatrix, T >, T >, T > &inv)
LASymMatrix & operator=(const ABObj< sym, LASymMatrix, T > &v)
LASymMatrix & operator-=(const LASymMatrix &m)
LASymMatrix(const ABObj< sym, ABSum< ABObj< sym, LASymMatrix, T >, ABObj< sym, A, T > >, T > &sum)
double & operator()(unsigned int row, unsigned int col)
const double * Data() const
unsigned int Ncol() const
double operator()(unsigned int row, unsigned int col) const
LASymMatrix & operator=(const LASymMatrix &v)
Definition LASymMatrix.h:77
LASymMatrix & operator+=(const ABObj< sym, LASymMatrix, T > &m)
LASymMatrix(const ABObj< sym, ABSum< ABObj< sym, MatrixInverse< sym, ABObj< sym, LASymMatrix, T >, T >, T >, ABObj< sym, A, T > >, T > &sum)
LASymMatrix(const ABObj< sym, ABSum< ABObj< sym, A, T >, ABObj< sym, B, T > >, T > &sum)
LASymMatrix & operator*=(double scal)
LASymMatrix & operator+=(const ABObj< sym, A, T > &m)
LASymMatrix & operator=(const ABObj< sym, MatrixInverse< sym, ABObj< sym, LASymMatrix, T >, T >, T > &inv)
LASymMatrix(unsigned int n)
Definition LASymMatrix.h:53
LASymMatrix(const ABObj< sym, LASymMatrix, T > &v)
Definition LASymMatrix.h:90
LASymMatrix & operator=(const ABObj< sym, ABSum< ABObj< sym, A, T >, ABObj< sym, B, T > >, T > &sum)
LASymMatrix(const LASymMatrix &v)
Definition LASymMatrix.h:70
unsigned int Nrow() const
LASymMatrix(const ABObj< sym, ABObj< sym, A, T >, T > &something)
LASymMatrix & operator+=(const ABObj< sym, MatrixInverse< sym, ABObj< sym, LASymMatrix, T >, T >, T > &m)
LASymMatrix & operator=(const ABObj< sym, ABSum< ABObj< sym, LASymMatrix, T >, ABObj< sym, A, T > >, T > &sum)
LASymMatrix(const ABObj< sym, ABSum< ABObj< sym, VectorOuterProduct< ABObj< vec, LAVector, T >, T >, T >, ABObj< sym, A, T > >, T > &sum)
LASymMatrix & operator+=(const LASymMatrix &m)
LASymMatrix & operator+=(const ABObj< sym, VectorOuterProduct< ABObj< vec, LAVector, T >, T >, T > &m)
unsigned int size() const
LASymMatrix & operator=(const ABObj< sym, ABObj< sym, A, T >, T > &something)
static StackAllocator & Get()
void * Allocate(size_t nBytes)
const Int_t n
Definition legend1.C:16
int Invert(LASymMatrix &)
Definition LaInverse.cxx:21
int Mndaxpy(unsigned int, double, const double *, int, double *, int)
Definition mndaxpy.cxx:19
int Mndscal(unsigned int, double, double *, int)
Definition mndscal.cxx:19
void Outer_prod(LASymMatrix &, const LAVector &, double f=1.)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
void inv(rsa_NUMBER *, rsa_NUMBER *, rsa_NUMBER *)
Definition rsaaux.cxx:949
TMarker m
Definition textangle.C:8
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345