CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
Matrix.cc
Go to the documentation of this file.
1// -*- C++ -*-
2// ---------------------------------------------------------------------------
3//
4// This file is a part of the CLHEP - a Class Library for High Energy Physics.
5//
6
7#include <iostream>
8#include <string.h>
9#include <float.h> // for DBL_EPSILON
10#include <cmath>
11#include <stdlib.h>
12
13#include "CLHEP/Matrix/defs.h"
14#include "CLHEP/Random/Random.h"
15#include "CLHEP/Matrix/Matrix.h"
16#include "CLHEP/Matrix/SymMatrix.h"
17#include "CLHEP/Matrix/DiagMatrix.h"
18#include "CLHEP/Matrix/Vector.h"
19#include "CLHEP/Utility/thread_local.h"
20
21#ifdef HEP_DEBUG_INLINE
22#include "CLHEP/Matrix/Matrix.icc"
23#endif
24
25namespace CLHEP {
26
27// Simple operation for all elements
28
29#define SIMPLE_UOP(OPER) \
30 mIter a=m.begin(); \
31 mIter e=m.end(); \
32 for(;a!=e; a++) (*a) OPER t;
33
34#define SIMPLE_BOP(OPER) \
35 HepMatrix::mIter a=m.begin(); \
36 HepMatrix::mcIter b=hm2.m.begin(); \
37 HepMatrix::mIter e=m.end(); \
38 for(;a!=e; a++, b++) (*a) OPER (*b);
39
40#define SIMPLE_TOP(OPER) \
41 HepMatrix::mcIter a=hm1.m.begin(); \
42 HepMatrix::mcIter b=hm2.m.begin(); \
43 HepMatrix::mIter t=mret.m.begin(); \
44 HepMatrix::mcIter e=hm1.m.end(); \
45 for(;a!=e; a++, b++, t++) (*t) = (*a) OPER (*b);
46
47// Static functions.
48
49#define CHK_DIM_2(r1,r2,c1,c2,fun) \
50 if (r1!=r2 || c1!=c2) { \
51 HepGenMatrix::error("Range error in Matrix function " #fun "(1)."); \
52 }
53
54#define CHK_DIM_1(c1,r2,fun) \
55 if (c1!=r2) { \
56 HepGenMatrix::error("Range error in Matrix function " #fun "(2)."); \
57 }
58
59// Constructors. (Default constructors are inlined and in .icc file)
60
62 : m(p*q), nrow(p), ncol(q)
63{
64 size_ = nrow * ncol;
65}
66
67HepMatrix::HepMatrix(int p,int q,int init)
68 : m(p*q), nrow(p), ncol(q)
69{
70 size_ = nrow * ncol;
71
72 if (size_ > 0) {
73 switch(init)
74 {
75 case 0:
76 break;
77
78 case 1:
79 {
80 if ( ncol == nrow ) {
81 mIter a = m.begin();
82 for( int step=0; step < size_; step+=(ncol+1) ) *(a+step) = 1.0;
83 } else {
84 error("Invalid dimension in HepMatrix(int,int,1).");
85 }
86 break;
87 }
88 default:
89 error("Matrix: initialization must be either 0 or 1.");
90 }
91 }
92}
93
95 : m(p*q), nrow(p), ncol(q)
96{
97 size_ = nrow * ncol;
98
99 mIter a = m.begin();
100 mIter b = m.end();
101 for(; a<b; a++) *a = r();
102}
103//
104// Destructor
105//
107}
108
110 : HepGenMatrix(hm1), m(hm1.size_), nrow(hm1.nrow), ncol(hm1.ncol), size_(hm1.size_)
111{
112 m = hm1.m;
113
114}
115
116// trivial
117
118int HepMatrix::num_row() const { return nrow;}
119
120int HepMatrix::num_col() const { return ncol;}
121
122int HepMatrix::num_size() const { return size_;}
123
124// operator()
125
126double & HepMatrix::operator()(int row, int col)
127{
128#ifdef MATRIX_BOUND_CHECK
129 if(row<1 || row>num_row() || col<1 || col>num_col())
130 error("Range error in HepMatrix::operator()");
131#endif
132 return *(m.begin()+(row-1)*ncol+col-1);
133}
134
135const double & HepMatrix::operator()(int row, int col) const
136{
137#ifdef MATRIX_BOUND_CHECK
138 if(row<1 || row>num_row() || col<1 || col>num_col())
139 error("Range error in HepMatrix::operator()");
140#endif
141 return *(m.begin()+(row-1)*ncol+col-1);
142}
143
144
146 : m(hm1.nrow*hm1.nrow), nrow(hm1.nrow), ncol(hm1.nrow)
147{
148 size_ = nrow * ncol;
149
150 mcIter sjk = hm1.m.begin();
151 // j >= k
152 for(int j=0; j!=nrow; ++j) {
153 for(int k=0; k<=j; ++k) {
154 m[j*ncol+k] = *sjk;
155 // we could copy the diagonal element twice or check
156 // doing the check may be a tiny bit faster,
157 // so we choose that option for now
158 if(k!=j) m[k*nrow+j] = *sjk;
159 ++sjk;
160 }
161 }
162}
163
165 : m(hm1.nrow*hm1.nrow), nrow(hm1.nrow), ncol(hm1.nrow)
166{
167 size_ = nrow * ncol;
168
169 int n = num_row();
170 mIter mrr;
171 mcIter mr = hm1.m.begin();
172 for(int r=0;r<n;r++) {
173 mrr = m.begin()+(n+1)*r;
174 *mrr = *(mr++);
175 }
176}
177
179 : m(hm1.nrow), nrow(hm1.nrow), ncol(1)
180{
181
182 size_ = nrow;
183 m = hm1.m;
184}
185
186
187//
188//
189// Sub matrix
190//
191//
192
193HepMatrix HepMatrix::sub(int min_row, int max_row,
194 int min_col,int max_col) const
195#ifdef HEP_GNU_OPTIMIZED_RETURN
196return mret(max_row-min_row+1,max_col-min_col+1);
197{
198#else
199{
200 HepMatrix mret(max_row-min_row+1,max_col-min_col+1);
201#endif
202 if(max_row > num_row() || max_col >num_col())
203 error("HepMatrix::sub: Index out of range");
204 mIter a = mret.m.begin();
205 int nc = num_col();
206 mcIter b1 = m.begin() + (min_row - 1) * nc + min_col - 1;
207 int rowsize = mret.num_row();
208 for(int irow=1; irow<=rowsize; ++irow) {
209 mcIter brc = b1;
210 for(int icol=0; icol<mret.num_col(); ++icol) {
211 *(a++) = *(brc++);
212 }
213 if(irow<rowsize) b1 += nc;
214 }
215 return mret;
216}
217
218void HepMatrix::sub(int row,int col,const HepMatrix &hm1)
219{
220 if(row <1 || row+hm1.num_row()-1 > num_row() ||
221 col <1 || col+hm1.num_col()-1 > num_col() )
222 error("HepMatrix::sub: Index out of range");
223 mcIter a = hm1.m.begin();
224 int nc = num_col();
225 mIter b1 = m.begin() + (row - 1) * nc + col - 1;
226 int rowsize = hm1.num_row();
227 for(int irow=1; irow<=rowsize; ++irow) {
228 mIter brc = b1;
229 for(int icol=0; icol<hm1.num_col(); ++icol) {
230 *(brc++) = *(a++);
231 }
232 if(irow<rowsize) b1 += nc;
233 }
234}
235
236//
237// Direct sum of two matricies
238//
239
240HepMatrix dsum(const HepMatrix &hm1, const HepMatrix &hm2)
241#ifdef HEP_GNU_OPTIMIZED_RETURN
242 return mret(hm1.num_row() + hm2.num_row(), hm1.num_col() + hm2.num_col(),
243 0);
244{
245#else
246{
247 HepMatrix mret(hm1.num_row() + hm2.num_row(), hm1.num_col() + hm2.num_col(),
248 0);
249#endif
250 mret.sub(1,1,hm1);
251 mret.sub(hm1.num_row()+1,hm1.num_col()+1,hm2);
252 return mret;
253}
254
255/* -----------------------------------------------------------------------
256 This section contains support routines for matrix.h. This section contains
257 The two argument functions +,-. They call the copy constructor and +=,-=.
258 ----------------------------------------------------------------------- */
260#ifdef HEP_GNU_OPTIMIZED_RETURN
261 return hm2(nrow, ncol);
262{
263#else
264{
265 HepMatrix hm2(nrow, ncol);
266#endif
267 mcIter a=m.begin();
268 mIter b=hm2.m.begin();
269 mcIter e=m.end();
270 for(;a<e; a++, b++) (*b) = -(*a);
271 return hm2;
272}
273
274
275
277#ifdef HEP_GNU_OPTIMIZED_RETURN
278 return mret(hm1.nrow, hm1.ncol);
279{
280#else
281{
282 HepMatrix mret(hm1.nrow, hm1.ncol);
283#endif
284 CHK_DIM_2(hm1.num_row(),hm2.num_row(), hm1.num_col(),hm2.num_col(),+);
285 SIMPLE_TOP(+)
286 return mret;
287}
288
289//
290// operator -
291//
292
293HepMatrix operator-(const HepMatrix &hm1,const HepMatrix &hm2)
294#ifdef HEP_GNU_OPTIMIZED_RETURN
295 return mret(hm1.num_row(), hm1.num_col());
296{
297#else
298{
299 HepMatrix mret(hm1.num_row(), hm1.num_col());
300#endif
301 CHK_DIM_2(hm1.num_row(),hm2.num_row(),
302 hm1.num_col(),hm2.num_col(),-);
303 SIMPLE_TOP(-)
304 return mret;
305}
306
307/* -----------------------------------------------------------------------
308 This section contains support routines for matrix.h. This file contains
309 The two argument functions *,/. They call copy constructor and then /=,*=.
310 ----------------------------------------------------------------------- */
311
312HepMatrix operator/(
313const HepMatrix &hm1,double t)
314#ifdef HEP_GNU_OPTIMIZED_RETURN
315 return mret(hm1);
316{
317#else
318{
319 HepMatrix mret(hm1);
320#endif
321 mret /= t;
322 return mret;
323}
324
325HepMatrix operator*(const HepMatrix &hm1,double t)
326#ifdef HEP_GNU_OPTIMIZED_RETURN
327 return mret(hm1);
328{
329#else
330{
331 HepMatrix mret(hm1);
332#endif
333 mret *= t;
334 return mret;
335}
336
337HepMatrix operator*(double t,const HepMatrix &hm1)
338#ifdef HEP_GNU_OPTIMIZED_RETURN
339 return mret(hm1);
340{
341#else
342{
343 HepMatrix mret(hm1);
344#endif
345 mret *= t;
346 return mret;
347}
348
350#ifdef HEP_GNU_OPTIMIZED_RETURN
351 return mret(hm1.nrow,hm2.ncol,0);
352{
353#else
354{
355 // initialize matrix to 0.0
356 HepMatrix mret(hm1.nrow,hm2.ncol,0);
357#endif
358 CHK_DIM_1(hm1.ncol,hm2.nrow,*);
359
360 int m1cols = hm1.ncol;
361 int m2cols = hm2.ncol;
362
363 for (int i=0; i<hm1.nrow; i++)
364 {
365 for (int j=0; j<m1cols; j++)
366 {
367 double temp = hm1.m[i*m1cols+j];
368 HepMatrix::mIter pt = mret.m.begin() + i*m2cols;
369
370 // Loop over k (the column index in matrix hm2)
371 HepMatrix::mcIter pb = hm2.m.begin() + m2cols*j;
372 const HepMatrix::mcIter pblast = pb + m2cols;
373 while (pb < pblast)
374 {
375 (*pt) += temp * (*pb);
376 pb++;
377 pt++;
378 }
379 }
380 }
381
382 return mret;
383}
384
385/* -----------------------------------------------------------------------
386 This section contains the assignment and inplace operators =,+=,-=,*=,/=.
387 ----------------------------------------------------------------------- */
388
390{
391 CHK_DIM_2(num_row(),hm2.num_row(),num_col(),hm2.num_col(),+=);
392 SIMPLE_BOP(+=)
393 return (*this);
394}
395
397{
398 CHK_DIM_2(num_row(),hm2.num_row(),num_col(),hm2.num_col(),-=);
399 SIMPLE_BOP(-=)
400 return (*this);
401}
402
404{
405 SIMPLE_UOP(/=)
406 return (*this);
407}
408
410{
411 SIMPLE_UOP(*=)
412 return (*this);
413}
414
416{
417 if(hm1.nrow*hm1.ncol != size_) //??fixme?? hm1.size != size
418 {
419 size_ = hm1.nrow * hm1.ncol;
420 m.resize(size_); //??fixme?? if (size < hm1.size) m.resize(hm1.size);
421 }
422 nrow = hm1.nrow;
423 ncol = hm1.ncol;
424 m = hm1.m;
425 return (*this);
426}
427
428// HepMatrix & HepMatrix::operator=(const HepRotation &hm2)
429// is now in Matrix=Rotation.cc
430
431// Print the Matrix.
432
433std::ostream& operator<<(std::ostream &os, const HepMatrix &q)
434{
435 os << "\n";
436/* Fixed format needs 3 extra characters for field, while scientific needs 7 */
437 long width;
438 if(os.flags() & std::ios::fixed)
439 width = os.precision()+3;
440 else
441 width = os.precision()+7;
442 for(int irow = 1; irow<= q.num_row(); irow++)
443 {
444 for(int icol = 1; icol <= q.num_col(); icol++)
445 {
446 os.width(width);
447 os << q(irow,icol) << " ";
448 }
449 os << std::endl;
450 }
451 return os;
452}
453
455#ifdef HEP_GNU_OPTIMIZED_RETURN
456return mret(ncol,nrow);
457{
458#else
459{
460 HepMatrix mret(ncol,nrow);
461#endif
462 mcIter pme = m.begin();
463 mIter pt = mret.m.begin();
464 for( int nr=0; nr<nrow; ++nr) {
465 for( int nc=0; nc<ncol; ++nc) {
466 pt = mret.m.begin() + nr + nrow*nc;
467 (*pt) = (*pme);
468 ++pme;
469 }
470 }
471 return mret;
472}
473
474HepMatrix HepMatrix::apply(double (*f)(double, int, int)) const
475#ifdef HEP_GNU_OPTIMIZED_RETURN
476return mret(num_row(),num_col());
477{
478#else
479{
480 HepMatrix mret(num_row(),num_col());
481#endif
482 mcIter a = m.begin();
483 mIter b = mret.m.begin();
484 for(int ir=1;ir<=num_row();ir++) {
485 for(int ic=1;ic<=num_col();ic++) {
486 *(b++) = (*f)(*(a++), ir, ic);
487 }
488 }
489 return mret;
490}
491
492int HepMatrix::dfinv_matrix(int *ir) {
493 if (num_col()!=num_row())
494 error("dfinv_matrix: Matrix is not NxN");
495 int n = num_col();
496 if (n==1) return 0;
497
498 double s31, s32;
499 double s33, s34;
500
501 mIter hm11 = m.begin();
502 mIter hm12 = hm11 + 1;
503 mIter hm21 = hm11 + n;
504 mIter hm22 = hm12 + n;
505 *hm21 = -(*hm22) * (*hm11) * (*hm21);
506 *hm12 = -(*hm12);
507 if (n>2) {
508 mIter mimim = hm11 + n + 1;
509 for (int i=3;i<=n;i++) {
510 // calculate these to avoid pointing off the end of the storage array
511 mIter mi = hm11 + (i-1) * n;
512 mIter mii= hm11 + (i-1) * n + i - 1;
513 int ihm2 = i - 2;
514 mIter mj = hm11;
515 mIter mji = mj + i - 1;
516 mIter mij = mi;
517 for (int j=1;j<=ihm2;j++) {
518 s31 = 0.0;
519 s32 = *mji;
520 mIter mkj = mj + j - 1;
521 mIter mik = mi + j - 1;
522 mIter mjkp = mj + j;
523 mIter mkpi = mj + n + i - 1;
524 for (int k=j;k<=ihm2;k++) {
525 s31 += (*mkj) * (*(mik++));
526 s32 += (*(mjkp++)) * (*mkpi);
527 mkj += n;
528 mkpi += n;
529 } // for k
530 *mij = -(*mii) * (((*(mij-n)))*( (*(mii-1)))+(s31));
531 *mji = -s32;
532 mj += n;
533 mji += n;
534 mij++;
535 } // for j
536 *(mii-1) = -(*mii) * (*mimim) * (*(mii-1));
537 *(mimim+1) = -(*(mimim+1));
538 mimim += (n+1);
539 } // for i
540 } // n>2
541 mIter mi = hm11;
542 mIter mii = hm11;
543 for (int i=1;i<n;i++) {
544 int ni = n - i;
545 mIter mij = mi;
546 int j;
547 for (j=1; j<=i;j++) {
548 s33 = *mij;
549 // change initial definition of mikj to avoid pointing off the end of the storage array
550 mIter mikj = mi + j - 1;
551 mIter miik = mii + 1;
552 mIter min_end = mi + n;
553 for (;miik<min_end;) {
554 // iterate by n as we enter the loop to avoid pointing off the end of the storage array
555 mikj += n;
556 s33 += (*mikj) * (*(miik++));
557 }
558 *(mij++) = s33;
559 }
560 for (j=1;j<=ni;j++) {
561 s34 = 0.0;
562 mIter miik = mii + j;
563 for (int k=j;k<=ni;k++) {
564 // calculate mikij here to avoid pointing off the end of the storage array
565 mIter mikij = mii + k * n + j;
566 s34 += *mikij * (*(miik++));
567 }
568 *(mii+j) = s34;
569 }
570 mi += n;
571 mii += (n+1);
572 } // for i
573 int nxch = ir[n];
574 if (nxch==0) return 0;
575 for (int hmm=1;hmm<=nxch;hmm++) {
576 int k = nxch - hmm + 1;
577 int ij = ir[k];
578 int i = ij >> 12;
579 int j = ij%4096;
580 for (k=1; k<=n;k++) {
581 // avoid setting the iterator beyond the end of the storage vector
582 mIter mki = hm11 + (k-1)*n + i - 1;
583 mIter mkj = hm11 + (k-1)*n + j - 1;
584 // 2/24/05 David Sachs fix of improper swap bug that was present
585 // for many years:
586 double ti = *mki; // 2/24/05
587 *mki = *mkj;
588 *mkj = ti; // 2/24/05
589 }
590 } // for hmm
591 return 0;
592}
593
594int HepMatrix::dfact_matrix(double &det, int *ir) {
595 if (ncol!=nrow)
596 error("dfact_matrix: Matrix is not NxN");
597
598 int ifail, jfail;
599 int n = ncol;
600
601 double tf;
602 double g1 = 1.0e-19, g2 = 1.0e19;
603
604 double p, q, t;
605 double s11, s12;
606
607 double epsilon = 8*DBL_EPSILON;
608 // could be set to zero (like it was before)
609 // but then the algorithm often doesn't detect
610 // that a matrix is singular
611
612 int normal = 0, imposs = -1;
613 int jrange = 0, jover = 1, junder = -1;
614 ifail = normal;
615 jfail = jrange;
616 int nxch = 0;
617 det = 1.0;
618 mIter mj = m.begin();
619 mIter mjj = mj;
620 for (int j=1;j<=n;j++) {
621 int k = j;
622 p = (fabs(*mjj));
623 if (j!=n) {
624 // replace mij with calculation of position
625 for (int i=j+1;i<n;i++) {
626 q = (fabs(*(mj + n*(i-j) + j - 1)));
627 if (q > p) {
628 k = i;
629 p = q;
630 }
631 } // for i
632 if (k==j) {
633 if (p <= epsilon) {
634 det = 0;
635 ifail = imposs;
636 jfail = jrange;
637 return ifail;
638 }
639 det = -det; // in this case the sign of the determinant
640 // must not change. So I change it twice.
641 } // k==j
642 mIter mjl = mj;
643 mIter mkl = m.begin() + (k-1)*n;
644 for (int l=1;l<=n;l++) {
645 tf = *mjl;
646 *(mjl++) = *mkl;
647 *(mkl++) = tf;
648 }
649 nxch = nxch + 1; // this makes the determinant change its sign
650 ir[nxch] = (((j)<<12)+(k));
651 } else { // j!=n
652 if (p <= epsilon) {
653 det = 0.0;
654 ifail = imposs;
655 jfail = jrange;
656 return ifail;
657 }
658 } // j!=n
659 det *= *mjj;
660 *mjj = 1.0 / *mjj;
661 t = (fabs(det));
662 if (t < g1) {
663 det = 0.0;
664 if (jfail == jrange) jfail = junder;
665 } else if (t > g2) {
666 det = 1.0;
667 if (jfail==jrange) jfail = jover;
668 }
669 // calculate mk and mkjp so we don't point off the end of the vector
670 if (j!=n) {
671 mIter mjk = mj + j;
672 for (k=j+1;k<=n;k++) {
673 mIter mk = mj + n*(k-j);
674 mIter mkjp = mk + j;
675 s11 = - (*mjk);
676 s12 = - (*mkjp);
677 if (j!=1) {
678 mIter mik = m.begin() + k - 1;
679 mIter mijp = m.begin() + j;
680 mIter mki = mk;
681 mIter mji = mj;
682 for (int i=1;i<j;i++) {
683 s11 += (*mik) * (*(mji++));
684 s12 += (*mijp) * (*(mki++));
685 mik += n;
686 mijp += n;
687 } // for i
688 } // j!=1
689 *(mjk++) = -s11 * (*mjj);
690 *(mkjp) = -(((*(mjj+1)))*((*(mkjp-1)))+(s12));
691 } // for k
692 } // j!=n
693 // avoid setting the iterator beyond the end of the vector
694 if(j!=n) {
695 mj += n;
696 mjj += (n+1);
697 }
698 } // for j
699 if (nxch%2==1) det = -det;
700 if (jfail !=jrange) det = 0.0;
701 ir[n] = nxch;
702 return 0;
703}
704
705void HepMatrix::invert(int &ierr) {
706 if(ncol != nrow)
707 error("HepMatrix::invert: Matrix is not NxN");
708
709 static CLHEP_THREAD_LOCAL int max_array = 20;
710 static CLHEP_THREAD_LOCAL int *ir = new int [max_array+1];
711
712 if (ncol > max_array) {
713 delete [] ir;
714 max_array = nrow;
715 ir = new int [max_array+1];
716 }
717 double t1, t2, t3;
718 double det, temp, sd;
719 int ifail;
720 switch(nrow) {
721 case 3:
722 double c11,c12,c13,c21,c22,c23,c31,c32,c33;
723 ifail = 0;
724 c11 = (*(m.begin()+4)) * (*(m.begin()+8)) - (*(m.begin()+5)) * (*(m.begin()+7));
725 c12 = (*(m.begin()+5)) * (*(m.begin()+6)) - (*(m.begin()+3)) * (*(m.begin()+8));
726 c13 = (*(m.begin()+3)) * (*(m.begin()+7)) - (*(m.begin()+4)) * (*(m.begin()+6));
727 c21 = (*(m.begin()+7)) * (*(m.begin()+2)) - (*(m.begin()+8)) * (*(m.begin()+1));
728 c22 = (*(m.begin()+8)) * (*m.begin()) - (*(m.begin()+6)) * (*(m.begin()+2));
729 c23 = (*(m.begin()+6)) * (*(m.begin()+1)) - (*(m.begin()+7)) * (*m.begin());
730 c31 = (*(m.begin()+1)) * (*(m.begin()+5)) - (*(m.begin()+2)) * (*(m.begin()+4));
731 c32 = (*(m.begin()+2)) * (*(m.begin()+3)) - (*m.begin()) * (*(m.begin()+5));
732 c33 = (*m.begin()) * (*(m.begin()+4)) - (*(m.begin()+1)) * (*(m.begin()+3));
733 t1 = fabs(*m.begin());
734 t2 = fabs(*(m.begin()+3));
735 t3 = fabs(*(m.begin()+6));
736 if (t1 >= t2) {
737 if (t3 >= t1) {
738 temp = *(m.begin()+6);
739 det = c23*c12-c22*c13;
740 } else {
741 temp = *(m.begin());
742 det = c22*c33-c23*c32;
743 }
744 } else if (t3 >= t2) {
745 temp = *(m.begin()+6);
746 det = c23*c12-c22*c13;
747 } else {
748 temp = *(m.begin()+3);
749 det = c13*c32-c12*c33;
750 }
751 if (det==0) {
752 ierr = 1;
753 return;
754 }
755 {
756 double s1 = temp/det;
757 mIter hmm = m.begin();
758 *(hmm++) = s1*c11;
759 *(hmm++) = s1*c21;
760 *(hmm++) = s1*c31;
761 *(hmm++) = s1*c12;
762 *(hmm++) = s1*c22;
763 *(hmm++) = s1*c32;
764 *(hmm++) = s1*c13;
765 *(hmm++) = s1*c23;
766 *(hmm) = s1*c33;
767 }
768 break;
769 case 2:
770 ifail = 0;
771 det = (*m.begin())*(*(m.begin()+3)) - (*(m.begin()+1))*(*(m.begin()+2));
772 if (det==0) {
773 ierr = 1;
774 return;
775 }
776 sd = 1.0/det;
777 temp = sd*(*(m.begin()+3));
778 *(m.begin()+1) *= -sd;
779 *(m.begin()+2) *= -sd;
780 *(m.begin()+3) = sd*(*m.begin());
781 *(m.begin()) = temp;
782 break;
783 case 1:
784 ifail = 0;
785 if ((*(m.begin()))==0) {
786 ierr = 1;
787 return;
788 }
789 *(m.begin()) = 1.0/(*(m.begin()));
790 break;
791 case 4:
792 invertHaywood4(ierr);
793 return;
794 case 5:
795 invertHaywood5(ierr);
796 return;
797 case 6:
798 invertHaywood6(ierr);
799 return;
800 default:
801 ifail = dfact_matrix(det, ir);
802 if(ifail) {
803 ierr = 1;
804 return;
805 }
806 dfinv_matrix(ir);
807 break;
808 }
809 ierr = 0;
810 return;
811}
812
814 static CLHEP_THREAD_LOCAL int max_array = 20;
815 static CLHEP_THREAD_LOCAL int *ir = new int [max_array+1];
816 if(ncol != nrow)
817 error("HepMatrix::determinant: Matrix is not NxN");
818 if (ncol > max_array) {
819 delete [] ir;
820 max_array = nrow;
821 ir = new int [max_array+1];
822 }
823 double det;
824 HepMatrix mt(*this);
825 int i = mt.dfact_matrix(det, ir);
826 if(i==0) return det;
827 return 0;
828}
829
830double HepMatrix::trace() const {
831 double t = 0.0;
832 for (mcIter d = m.begin(); d < m.end(); d += (ncol+1) )
833 t += *d;
834 return t;
835}
836
837} // namespace CLHEP
#define CHK_DIM_2(r1, r2, c1, c2, fun)
Definition: DiagMatrix.cc:44
#define SIMPLE_BOP(OPER)
Definition: DiagMatrix.cc:31
#define SIMPLE_UOP(OPER)
Definition: DiagMatrix.cc:26
#define SIMPLE_TOP(OPER)
Definition: DiagMatrix.cc:37
#define CHK_DIM_1(c1, r2, fun)
Definition: DiagMatrix.cc:49
std::vector< double, Alloc< double, 25 > >::const_iterator mcIter
Definition: GenMatrix.h:74
std::vector< double, Alloc< double, 25 > >::iterator mIter
Definition: GenMatrix.h:73
static void error(const char *s)
Definition: GenMatrix.cc:70
virtual ~HepMatrix()
Definition: Matrix.cc:106
virtual void invertHaywood4(int &ierr)
HepMatrix sub(int min_row, int max_row, int min_col, int max_col) const
Definition: Matrix.cc:193
HepMatrix & operator=(const HepMatrix &)
Definition: Matrix.cc:415
HepMatrix apply(double(*f)(double, int, int)) const
Definition: Matrix.cc:474
virtual int num_col() const
Definition: Matrix.cc:120
virtual const double & operator()(int row, int col) const
Definition: Matrix.cc:135
HepMatrix & operator/=(double t)
Definition: Matrix.cc:403
virtual int num_row() const
Definition: Matrix.cc:118
HepMatrix & operator+=(const HepMatrix &)
Definition: Matrix.cc:389
HepMatrix operator-() const
Definition: Matrix.cc:259
HepMatrix & operator*=(double t)
Definition: Matrix.cc:409
HepMatrix & operator-=(const HepMatrix &)
Definition: Matrix.cc:396
HepMatrix T() const
Definition: Matrix.cc:454
double determinant() const
Definition: Matrix.cc:813
virtual void invertHaywood6(int &ierr)
virtual int num_size() const
Definition: Matrix.cc:122
virtual void invertHaywood5(int &ierr)
double trace() const
Definition: Matrix.cc:830
void f(void g())
Definition: excDblThrow.cc:38
std::ostream & operator<<(std::ostream &s, const HepDiagMatrix &q)
Definition: DiagMatrix.cc:560
HepMatrix operator+(const HepMatrix &hm1, const HepDiagMatrix &d2)
Definition: DiagMatrix.cc:193
HepMatrix operator*(const HepMatrix &hm1, const HepDiagMatrix &hm2)
Definition: DiagMatrix.cc:372
HepDiagMatrix dsum(const HepDiagMatrix &s1, const HepDiagMatrix &s2)
Definition: DiagMatrix.cc:161
void init()
Definition: testRandom.cc:29