source: trunk/source/error_propagation/src/G4ErrorSymMatrix.cc@ 1301

Last change on this file since 1301 was 1228, checked in by garnier, 16 years ago

update geant4.9.3 tag

File size: 80.6 KB
Line 
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// $Id: G4ErrorSymMatrix.cc,v 1.3 2007/06/21 15:04:10 gunter Exp $
27// GEANT4 tag $Name: geant4-09-03 $
28//
29// ------------------------------------------------------------
30// GEANT 4 class implementation file
31// ------------------------------------------------------------
32
33#include "globals.hh"
34#include <iostream>
35#include <cmath>
36
37#include "G4ErrorSymMatrix.hh"
38#include "G4ErrorMatrix.hh"
39
40// Simple operation for all elements
41
42#define SIMPLE_UOP(OPER) \
43 G4ErrorMatrixIter a=m.begin(); \
44 G4ErrorMatrixIter e=m.begin()+num_size(); \
45 for(;a<e; a++) (*a) OPER t;
46
47#define SIMPLE_BOP(OPER) \
48 G4ErrorMatrixIter a=m.begin(); \
49 G4ErrorMatrixConstIter b=m2.m.begin(); \
50 G4ErrorMatrixConstIter e=m.begin()+num_size(); \
51 for(;a<e; a++, b++) (*a) OPER (*b);
52
53#define SIMPLE_TOP(OPER) \
54 G4ErrorMatrixConstIter a=m1.m.begin(); \
55 G4ErrorMatrixConstIter b=m2.m.begin(); \
56 G4ErrorMatrixIter t=mret.m.begin(); \
57 G4ErrorMatrixConstIter e=m1.m.begin()+m1.num_size(); \
58 for( ;a<e; a++, b++, t++) (*t) = (*a) OPER (*b);
59
60#define CHK_DIM_2(r1,r2,c1,c2,fun) \
61 if (r1!=r2 || c1!=c2) { \
62 G4ErrorMatrix::error("Range error in Matrix function " #fun "(1)."); \
63 }
64
65#define CHK_DIM_1(c1,r2,fun) \
66 if (c1!=r2) { \
67 G4ErrorMatrix::error("Range error in Matrix function " #fun "(2)."); \
68 }
69
70// Constructors. (Default constructors are inlined and in .icc file)
71
72G4ErrorSymMatrix::G4ErrorSymMatrix(G4int p)
73 : m(p*(p+1)/2), nrow(p)
74{
75 size = nrow * (nrow+1) / 2;
76 m.assign(size,0);
77}
78
79G4ErrorSymMatrix::G4ErrorSymMatrix(G4int p, G4int init)
80 : m(p*(p+1)/2), nrow(p)
81{
82 size = nrow * (nrow+1) / 2;
83
84 m.assign(size,0);
85 switch(init)
86 {
87 case 0:
88 break;
89
90 case 1:
91 {
92 G4ErrorMatrixIter a = m.begin();
93 for(G4int i=1;i<=nrow;i++)
94 {
95 *a = 1.0;
96 a += (i+1);
97 }
98 break;
99 }
100 default:
101 G4ErrorMatrix::error("G4ErrorSymMatrix: initialization must be 0 or 1.");
102 }
103}
104
105//
106// Destructor
107//
108
109G4ErrorSymMatrix::~G4ErrorSymMatrix()
110{
111}
112
113G4ErrorSymMatrix::G4ErrorSymMatrix(const G4ErrorSymMatrix &m1)
114 : m(m1.size), nrow(m1.nrow), size(m1.size)
115{
116 m = m1.m;
117}
118
119//
120//
121// Sub matrix
122//
123//
124
125G4ErrorSymMatrix G4ErrorSymMatrix::sub(G4int min_row, G4int max_row) const
126{
127 G4ErrorSymMatrix mret(max_row-min_row+1);
128 if(max_row > num_row())
129 { G4ErrorMatrix::error("G4ErrorSymMatrix::sub: Index out of range"); }
130 G4ErrorMatrixIter a = mret.m.begin();
131 G4ErrorMatrixConstIter b1 = m.begin() + (min_row+2)*(min_row-1)/2;
132 for(G4int irow=1; irow<=mret.num_row(); irow++)
133 {
134 G4ErrorMatrixConstIter b = b1;
135 for(G4int icol=1; icol<=irow; icol++)
136 {
137 *(a++) = *(b++);
138 }
139 b1 += irow+min_row-1;
140 }
141 return mret;
142}
143
144G4ErrorSymMatrix G4ErrorSymMatrix::sub(G4int min_row, G4int max_row)
145{
146 G4ErrorSymMatrix mret(max_row-min_row+1);
147 if(max_row > num_row())
148 { G4ErrorMatrix::error("G4ErrorSymMatrix::sub: Index out of range"); }
149 G4ErrorMatrixIter a = mret.m.begin();
150 G4ErrorMatrixIter b1 = m.begin() + (min_row+2)*(min_row-1)/2;
151 for(G4int irow=1; irow<=mret.num_row(); irow++)
152 {
153 G4ErrorMatrixIter b = b1;
154 for(G4int icol=1; icol<=irow; icol++)
155 {
156 *(a++) = *(b++);
157 }
158 b1 += irow+min_row-1;
159 }
160 return mret;
161}
162
163void G4ErrorSymMatrix::sub(G4int row,const G4ErrorSymMatrix &m1)
164{
165 if(row <1 || row+m1.num_row()-1 > num_row() )
166 { G4ErrorMatrix::error("G4ErrorSymMatrix::sub: Index out of range"); }
167 G4ErrorMatrixConstIter a = m1.m.begin();
168 G4ErrorMatrixIter b1 = m.begin() + (row+2)*(row-1)/2;
169 for(G4int irow=1; irow<=m1.num_row(); irow++)
170 {
171 G4ErrorMatrixIter b = b1;
172 for(G4int icol=1; icol<=irow; icol++)
173 {
174 *(b++) = *(a++);
175 }
176 b1 += irow+row-1;
177 }
178}
179
180//
181// Direct sum of two matricies
182//
183
184G4ErrorSymMatrix dsum(const G4ErrorSymMatrix &m1,
185 const G4ErrorSymMatrix &m2)
186{
187 G4ErrorSymMatrix mret(m1.num_row() + m2.num_row(), 0);
188 mret.sub(1,m1);
189 mret.sub(m1.num_row()+1,m2);
190 return mret;
191}
192
193/* -----------------------------------------------------------------------
194 This section contains support routines for matrix.h. This section contains
195 The two argument functions +,-. They call the copy constructor and +=,-=.
196 ----------------------------------------------------------------------- */
197
198G4ErrorSymMatrix G4ErrorSymMatrix::operator- () const
199{
200 G4ErrorSymMatrix m2(nrow);
201 G4ErrorMatrixConstIter a=m.begin();
202 G4ErrorMatrixIter b=m2.m.begin();
203 G4ErrorMatrixConstIter e=m.begin()+num_size();
204 for(;a<e; a++, b++) { (*b) = -(*a); }
205 return m2;
206}
207
208G4ErrorMatrix operator+(const G4ErrorMatrix &m1, const G4ErrorSymMatrix &m2)
209{
210 G4ErrorMatrix mret(m1);
211 CHK_DIM_2(m1.num_row(),m2.num_row(), m1.num_col(),m2.num_col(),+);
212 mret += m2;
213 return mret;
214}
215
216G4ErrorMatrix operator+(const G4ErrorSymMatrix &m1, const G4ErrorMatrix &m2)
217{
218 G4ErrorMatrix mret(m2);
219 CHK_DIM_2(m1.num_row(),m2.num_row(),m1.num_col(),m2.num_col(),+);
220 mret += m1;
221 return mret;
222}
223
224G4ErrorSymMatrix operator+(const G4ErrorSymMatrix &m1,
225 const G4ErrorSymMatrix &m2)
226{
227 G4ErrorSymMatrix mret(m1.nrow);
228 CHK_DIM_1(m1.nrow, m2.nrow,+);
229 SIMPLE_TOP(+)
230 return mret;
231}
232
233//
234// operator -
235//
236
237G4ErrorMatrix operator-(const G4ErrorMatrix &m1, const G4ErrorSymMatrix &m2)
238{
239 G4ErrorMatrix mret(m1);
240 CHK_DIM_2(m1.num_row(),m2.num_row(),m1.num_col(),m2.num_col(),-);
241 mret -= m2;
242 return mret;
243}
244
245G4ErrorMatrix operator-(const G4ErrorSymMatrix &m1, const G4ErrorMatrix &m2)
246{
247 G4ErrorMatrix mret(m1);
248 CHK_DIM_2(m1.num_row(),m2.num_row(),m1.num_col(),m2.num_col(),-);
249 mret -= m2;
250 return mret;
251}
252
253G4ErrorSymMatrix operator-(const G4ErrorSymMatrix &m1,
254 const G4ErrorSymMatrix &m2)
255{
256 G4ErrorSymMatrix mret(m1.num_row());
257 CHK_DIM_1(m1.num_row(),m2.num_row(),-);
258 SIMPLE_TOP(-)
259 return mret;
260}
261
262/* -----------------------------------------------------------------------
263 This section contains support routines for matrix.h. This file contains
264 The two argument functions *,/. They call copy constructor and then /=,*=.
265 ----------------------------------------------------------------------- */
266
267G4ErrorSymMatrix operator/(const G4ErrorSymMatrix &m1,G4double t)
268{
269 G4ErrorSymMatrix mret(m1);
270 mret /= t;
271 return mret;
272}
273
274G4ErrorSymMatrix operator*(const G4ErrorSymMatrix &m1,G4double t)
275{
276 G4ErrorSymMatrix mret(m1);
277 mret *= t;
278 return mret;
279}
280
281G4ErrorSymMatrix operator*(G4double t,const G4ErrorSymMatrix &m1)
282{
283 G4ErrorSymMatrix mret(m1);
284 mret *= t;
285 return mret;
286}
287
288G4ErrorMatrix operator*(const G4ErrorMatrix &m1, const G4ErrorSymMatrix &m2)
289{
290 G4ErrorMatrix mret(m1.num_row(),m2.num_col());
291 CHK_DIM_1(m1.num_col(),m2.num_row(),*);
292 G4ErrorMatrixConstIter mit1, mit2, sp,snp; //mit2=0
293 G4double temp;
294 G4ErrorMatrixIter mir=mret.m.begin();
295 G4int step,stept;
296 for(mit1=m1.m.begin();
297 mit1<m1.m.begin()+m1.num_row()*m1.num_col(); mit1 = mit2)
298 {
299 for(step=1,snp=m2.m.begin();step<=m2.num_row();)
300 {
301 mit2=mit1;
302 sp=snp;
303 snp+=step;
304 temp=0;
305 while(sp<snp)
306 {
307 temp+=*(sp++)*(*(mit2++));
308 }
309 sp+=step-1;
310 for(stept=++step;stept<=m2.num_row();stept++)
311 {
312 temp+=*sp*(*(mit2++));
313 sp+=stept;
314 }
315 *(mir++)=temp;
316 }
317 }
318 return mret;
319}
320
321G4ErrorMatrix operator*(const G4ErrorSymMatrix &m1, const G4ErrorMatrix &m2)
322{
323 G4ErrorMatrix mret(m1.num_row(),m2.num_col());
324 CHK_DIM_1(m1.num_col(),m2.num_row(),*);
325 G4int step,stept;
326 G4ErrorMatrixConstIter mit1,mit2,sp,snp;
327 G4double temp;
328 G4ErrorMatrixIter mir=mret.m.begin();
329 for(step=1,snp=m1.m.begin();step<=m1.num_row();snp+=step++)
330 {
331 for(mit1=m2.m.begin();mit1<m2.m.begin()+m2.num_col();mit1++)
332 {
333 mit2=mit1;
334 sp=snp;
335 temp=0;
336 while(sp<snp+step)
337 {
338 temp+=*mit2*(*(sp++));
339 mit2+=m2.num_col();
340 }
341 sp+=step-1;
342 for(stept=step+1;stept<=m1.num_row();stept++)
343 {
344 temp+=*mit2*(*sp);
345 mit2+=m2.num_col();
346 sp+=stept;
347 }
348 *(mir++)=temp;
349 }
350 }
351 return mret;
352}
353
354G4ErrorMatrix operator*(const G4ErrorSymMatrix &m1, const G4ErrorSymMatrix &m2)
355{
356 G4ErrorMatrix mret(m1.num_row(),m1.num_row());
357 CHK_DIM_1(m1.num_col(),m2.num_row(),*);
358 G4int step1,stept1,step2,stept2;
359 G4ErrorMatrixConstIter snp1,sp1,snp2,sp2;
360 G4double temp;
361 G4ErrorMatrixIter mr = mret.m.begin();
362 for(step1=1,snp1=m1.m.begin();step1<=m1.num_row();snp1+=step1++)
363 {
364 for(step2=1,snp2=m2.m.begin();step2<=m2.num_row();)
365 {
366 sp1=snp1;
367 sp2=snp2;
368 snp2+=step2;
369 temp=0;
370 if(step1<step2)
371 {
372 while(sp1<snp1+step1)
373 { temp+=(*(sp1++))*(*(sp2++)); }
374 sp1+=step1-1;
375 for(stept1=step1+1;stept1!=step2+1;sp1+=stept1++)
376 { temp+=(*sp1)*(*(sp2++)); }
377 sp2+=step2-1;
378 for(stept2=++step2;stept2<=m2.num_row();sp1+=stept1++,sp2+=stept2++)
379 { temp+=(*sp1)*(*sp2); }
380 }
381 else
382 {
383 while(sp2<snp2)
384 { temp+=(*(sp1++))*(*(sp2++)); }
385 sp2+=step2-1;
386 for(stept2=++step2;stept2!=step1+1;sp2+=stept2++)
387 { temp+=(*(sp1++))*(*sp2); }
388 sp1+=step1-1;
389 for(stept1=step1+1;stept1<=m1.num_row();sp1+=stept1++,sp2+=stept2++)
390 { temp+=(*sp1)*(*sp2); }
391 }
392 *(mr++)=temp;
393 }
394 }
395 return mret;
396}
397
398/* -----------------------------------------------------------------------
399 This section contains the assignment and inplace operators =,+=,-=,*=,/=.
400 ----------------------------------------------------------------------- */
401
402G4ErrorMatrix & G4ErrorMatrix::operator+=(const G4ErrorSymMatrix &m2)
403{
404 CHK_DIM_2(num_row(),m2.num_row(),num_col(),m2.num_col(),+=);
405 G4int n = num_col();
406 G4ErrorMatrixConstIter sjk = m2.m.begin();
407 G4ErrorMatrixIter m1j = m.begin();
408 G4ErrorMatrixIter mj = m.begin();
409 // j >= k
410 for(G4int j=1;j<=num_row();j++)
411 {
412 G4ErrorMatrixIter mjk = mj;
413 G4ErrorMatrixIter mkj = m1j;
414 for(G4int k=1;k<=j;k++)
415 {
416 *(mjk++) += *sjk;
417 if(j!=k) *mkj += *sjk;
418 sjk++;
419 mkj += n;
420 }
421 mj += n;
422 m1j++;
423 }
424 return (*this);
425}
426
427G4ErrorSymMatrix & G4ErrorSymMatrix::operator+=(const G4ErrorSymMatrix &m2)
428{
429 CHK_DIM_2(num_row(),m2.num_row(),num_col(),m2.num_col(),+=);
430 SIMPLE_BOP(+=)
431 return (*this);
432}
433
434G4ErrorMatrix & G4ErrorMatrix::operator-=(const G4ErrorSymMatrix &m2)
435{
436 CHK_DIM_2(num_row(),m2.num_row(),num_col(),m2.num_col(),-=);
437 G4int n = num_col();
438 G4ErrorMatrixConstIter sjk = m2.m.begin();
439 G4ErrorMatrixIter m1j = m.begin();
440 G4ErrorMatrixIter mj = m.begin();
441 // j >= k
442 for(G4int j=1;j<=num_row();j++)
443 {
444 G4ErrorMatrixIter mjk = mj;
445 G4ErrorMatrixIter mkj = m1j;
446 for(G4int k=1;k<=j;k++)
447 {
448 *(mjk++) -= *sjk;
449 if(j!=k) *mkj -= *sjk;
450 sjk++;
451 mkj += n;
452 }
453 mj += n;
454 m1j++;
455 }
456 return (*this);
457}
458
459G4ErrorSymMatrix & G4ErrorSymMatrix::operator-=(const G4ErrorSymMatrix &m2)
460{
461 CHK_DIM_2(num_row(),m2.num_row(),num_col(),m2.num_col(),-=);
462 SIMPLE_BOP(-=)
463 return (*this);
464}
465
466G4ErrorSymMatrix & G4ErrorSymMatrix::operator/=(G4double t)
467{
468 SIMPLE_UOP(/=)
469 return (*this);
470}
471
472G4ErrorSymMatrix & G4ErrorSymMatrix::operator*=(G4double t)
473{
474 SIMPLE_UOP(*=)
475 return (*this);
476}
477
478G4ErrorMatrix & G4ErrorMatrix::operator=(const G4ErrorSymMatrix &m1)
479{
480 if(m1.nrow*m1.nrow != size)
481 {
482 size = m1.nrow * m1.nrow;
483 m.resize(size);
484 }
485 nrow = m1.nrow;
486 ncol = m1.nrow;
487 G4int n = ncol;
488 G4ErrorMatrixConstIter sjk = m1.m.begin();
489 G4ErrorMatrixIter m1j = m.begin();
490 G4ErrorMatrixIter mj = m.begin();
491 // j >= k
492 for(G4int j=1;j<=num_row();j++)
493 {
494 G4ErrorMatrixIter mjk = mj;
495 G4ErrorMatrixIter mkj = m1j;
496 for(G4int k=1;k<=j;k++)
497 {
498 *(mjk++) = *sjk;
499 if(j!=k) *mkj = *sjk;
500 sjk++;
501 mkj += n;
502 }
503 mj += n;
504 m1j++;
505 }
506 return (*this);
507}
508
509G4ErrorSymMatrix & G4ErrorSymMatrix::operator=(const G4ErrorSymMatrix &m1)
510{
511 if(m1.nrow != nrow)
512 {
513 nrow = m1.nrow;
514 size = m1.size;
515 m.resize(size);
516 }
517 m = m1.m;
518 return (*this);
519}
520
521// Print the Matrix.
522
523std::ostream& operator<<(std::ostream &s, const G4ErrorSymMatrix &q)
524{
525 s << G4endl;
526
527 // Fixed format needs 3 extra characters for field,
528 // while scientific needs 7
529
530 G4int width;
531 if(s.flags() & std::ios::fixed)
532 {
533 width = s.precision()+3;
534 }
535 else
536 {
537 width = s.precision()+7;
538 }
539 for(G4int irow = 1; irow<= q.num_row(); irow++)
540 {
541 for(G4int icol = 1; icol <= q.num_col(); icol++)
542 {
543 s.width(width);
544 s << q(irow,icol) << " ";
545 }
546 s << G4endl;
547 }
548 return s;
549}
550
551G4ErrorSymMatrix G4ErrorSymMatrix::
552apply(G4double (*f)(G4double, G4int, G4int)) const
553{
554 G4ErrorSymMatrix mret(num_row());
555 G4ErrorMatrixConstIter a = m.begin();
556 G4ErrorMatrixIter b = mret.m.begin();
557 for(G4int ir=1;ir<=num_row();ir++)
558 {
559 for(G4int ic=1;ic<=ir;ic++)
560 {
561 *(b++) = (*f)(*(a++), ir, ic);
562 }
563 }
564 return mret;
565}
566
567void G4ErrorSymMatrix::assign (const G4ErrorMatrix &m1)
568{
569 if(m1.nrow != nrow)
570 {
571 nrow = m1.nrow;
572 size = nrow * (nrow+1) / 2;
573 m.resize(size);
574 }
575 G4ErrorMatrixConstIter a = m1.m.begin();
576 G4ErrorMatrixIter b = m.begin();
577 for(G4int r=1;r<=nrow;r++)
578 {
579 G4ErrorMatrixConstIter d = a;
580 for(G4int c=1;c<=r;c++)
581 {
582 *(b++) = *(d++);
583 }
584 a += nrow;
585 }
586}
587
588G4ErrorSymMatrix G4ErrorSymMatrix::similarity(const G4ErrorMatrix &m1) const
589{
590 G4ErrorSymMatrix mret(m1.num_row());
591 G4ErrorMatrix temp = m1*(*this);
592
593// If m1*(*this) has correct dimensions, then so will the m1.T multiplication.
594// So there is no need to check dimensions again.
595
596 G4int n = m1.num_col();
597 G4ErrorMatrixIter mr = mret.m.begin();
598 G4ErrorMatrixIter tempr1 = temp.m.begin();
599 for(G4int r=1;r<=mret.num_row();r++)
600 {
601 G4ErrorMatrixConstIter m1c1 = m1.m.begin();
602 for(G4int c=1;c<=r;c++)
603 {
604 G4double tmp = 0.0;
605 G4ErrorMatrixIter tempri = tempr1;
606 G4ErrorMatrixConstIter m1ci = m1c1;
607 for(G4int i=1;i<=m1.num_col();i++)
608 {
609 tmp+=(*(tempri++))*(*(m1ci++));
610 }
611 *(mr++) = tmp;
612 m1c1 += n;
613 }
614 tempr1 += n;
615 }
616 return mret;
617}
618
619G4ErrorSymMatrix G4ErrorSymMatrix::similarity(const G4ErrorSymMatrix &m1) const
620{
621 G4ErrorSymMatrix mret(m1.num_row());
622 G4ErrorMatrix temp = m1*(*this);
623 G4int n = m1.num_col();
624 G4ErrorMatrixIter mr = mret.m.begin();
625 G4ErrorMatrixIter tempr1 = temp.m.begin();
626 for(G4int r=1;r<=mret.num_row();r++)
627 {
628 G4ErrorMatrixConstIter m1c1 = m1.m.begin();
629 G4int c;
630 for(c=1;c<=r;c++)
631 {
632 G4double tmp = 0.0;
633 G4ErrorMatrixIter tempri = tempr1;
634 G4ErrorMatrixConstIter m1ci = m1c1;
635 G4int i;
636 for(i=1;i<c;i++)
637 {
638 tmp+=(*(tempri++))*(*(m1ci++));
639 }
640 for(i=c;i<=m1.num_col();i++)
641 {
642 tmp+=(*(tempri++))*(*(m1ci));
643 m1ci += i;
644 }
645 *(mr++) = tmp;
646 m1c1 += c;
647 }
648 tempr1 += n;
649 }
650 return mret;
651}
652
653G4ErrorSymMatrix G4ErrorSymMatrix::similarityT(const G4ErrorMatrix &m1) const
654{
655 G4ErrorSymMatrix mret(m1.num_col());
656 G4ErrorMatrix temp = (*this)*m1;
657 G4int n = m1.num_col();
658 G4ErrorMatrixIter mrc = mret.m.begin();
659 G4ErrorMatrixIter temp1r = temp.m.begin();
660 for(G4int r=1;r<=mret.num_row();r++)
661 {
662 G4ErrorMatrixConstIter m11c = m1.m.begin();
663 for(G4int c=1;c<=r;c++)
664 {
665 G4double tmp = 0.0;
666 G4ErrorMatrixIter tempir = temp1r;
667 G4ErrorMatrixConstIter m1ic = m11c;
668 for(G4int i=1;i<=m1.num_row();i++)
669 {
670 tmp+=(*(tempir))*(*(m1ic));
671 tempir += n;
672 m1ic += n;
673 }
674 *(mrc++) = tmp;
675 m11c++;
676 }
677 temp1r++;
678 }
679 return mret;
680}
681
682void G4ErrorSymMatrix::invert(G4int &ifail)
683{
684 ifail = 0;
685
686 switch(nrow)
687 {
688 case 3:
689 {
690 G4double det, temp;
691 G4double t1, t2, t3;
692 G4double c11,c12,c13,c22,c23,c33;
693 c11 = (*(m.begin()+2)) * (*(m.begin()+5))
694 - (*(m.begin()+4)) * (*(m.begin()+4));
695 c12 = (*(m.begin()+4)) * (*(m.begin()+3))
696 - (*(m.begin()+1)) * (*(m.begin()+5));
697 c13 = (*(m.begin()+1)) * (*(m.begin()+4))
698 - (*(m.begin()+2)) * (*(m.begin()+3));
699 c22 = (*(m.begin()+5)) * (*m.begin())
700 - (*(m.begin()+3)) * (*(m.begin()+3));
701 c23 = (*(m.begin()+3)) * (*(m.begin()+1))
702 - (*(m.begin()+4)) * (*m.begin());
703 c33 = (*m.begin()) * (*(m.begin()+2))
704 - (*(m.begin()+1)) * (*(m.begin()+1));
705 t1 = std::fabs(*m.begin());
706 t2 = std::fabs(*(m.begin()+1));
707 t3 = std::fabs(*(m.begin()+3));
708 if (t1 >= t2)
709 {
710 if (t3 >= t1)
711 {
712 temp = *(m.begin()+3);
713 det = c23*c12-c22*c13;
714 }
715 else
716 {
717 temp = *m.begin();
718 det = c22*c33-c23*c23;
719 }
720 }
721 else if (t3 >= t2)
722 {
723 temp = *(m.begin()+3);
724 det = c23*c12-c22*c13;
725 }
726 else
727 {
728 temp = *(m.begin()+1);
729 det = c13*c23-c12*c33;
730 }
731 if (det==0)
732 {
733 ifail = 1;
734 return;
735 }
736 {
737 G4double s = temp/det;
738 G4ErrorMatrixIter mm = m.begin();
739 *(mm++) = s*c11;
740 *(mm++) = s*c12;
741 *(mm++) = s*c22;
742 *(mm++) = s*c13;
743 *(mm++) = s*c23;
744 *(mm) = s*c33;
745 }
746 }
747 break;
748 case 2:
749 {
750 G4double det, temp, s;
751 det = (*m.begin())*(*(m.begin()+2)) - (*(m.begin()+1))*(*(m.begin()+1));
752 if (det==0)
753 {
754 ifail = 1;
755 return;
756 }
757 s = 1.0/det;
758 *(m.begin()+1) *= -s;
759 temp = s*(*(m.begin()+2));
760 *(m.begin()+2) = s*(*m.begin());
761 *m.begin() = temp;
762 break;
763 }
764 case 1:
765 {
766 if ((*m.begin())==0)
767 {
768 ifail = 1;
769 return;
770 }
771 *m.begin() = 1.0/(*m.begin());
772 break;
773 }
774 case 5:
775 {
776 invert5(ifail);
777 return;
778 }
779 case 6:
780 {
781 invert6(ifail);
782 return;
783 }
784 case 4:
785 {
786 invert4(ifail);
787 return;
788 }
789 default:
790 {
791 invertBunchKaufman(ifail);
792 return;
793 }
794 }
795 return; // inversion successful
796}
797
798G4double G4ErrorSymMatrix::determinant() const
799{
800 static const G4int max_array = 20;
801
802 // ir must point to an array which is ***1 longer than*** nrow
803
804 static std::vector<G4int> ir_vec (max_array+1);
805 if (ir_vec.size() <= static_cast<unsigned int>(nrow))
806 {
807 ir_vec.resize(nrow+1);
808 }
809 G4int * ir = &ir_vec[0];
810
811 G4double det;
812 G4ErrorMatrix mt(*this);
813 G4int i = mt.dfact_matrix(det, ir);
814 if(i==0) { return det; }
815 return 0.0;
816}
817
818G4double G4ErrorSymMatrix::trace() const
819{
820 G4double t = 0.0;
821 for (G4int i=0; i<nrow; i++)
822 { t += *(m.begin() + (i+3)*i/2); }
823 return t;
824}
825
826void G4ErrorSymMatrix::invertBunchKaufman(G4int &ifail)
827{
828 // Bunch-Kaufman diagonal pivoting method
829 // It is decribed in J.R. Bunch, L. Kaufman (1977).
830 // "Some Stable Methods for Calculating Inertia and Solving Symmetric
831 // Linear Systems", Math. Comp. 31, p. 162-179. or in Gene H. Golub,
832 // Charles F. van Loan, "Matrix Computations" (the second edition
833 // has a bug.) and implemented in "lapack"
834 // Mario Stanke, 09/97
835
836 G4int i, j, k, s;
837 G4int pivrow;
838
839 // Establish the two working-space arrays needed: x and piv are
840 // used as pointers to arrays of doubles and ints respectively, each
841 // of length nrow. We do not want to reallocate each time through
842 // unless the size needs to grow. We do not want to leak memory, even
843 // by having a new without a delete that is only done once.
844
845 static const G4int max_array = 25;
846 static std::vector<G4double> xvec (max_array);
847 static std::vector<G4int> pivv (max_array);
848 typedef std::vector<G4int>::iterator pivIter;
849 if (xvec.size() < static_cast<unsigned int>(nrow)) xvec.resize(nrow);
850 if (pivv.size() < static_cast<unsigned int>(nrow)) pivv.resize(nrow);
851 // Note - resize should do nothing if the size is already larger than nrow,
852 // but on VC++ there are indications that it does so we check.
853 // Note - the data elements in a vector are guaranteed to be contiguous,
854 // so x[i] and piv[i] are optimally fast.
855 G4ErrorMatrixIter x = xvec.begin();
856 // x[i] is used as helper storage, needs to have at least size nrow.
857 pivIter piv = pivv.begin();
858 // piv[i] is used to store details of exchanges
859
860 G4double temp1, temp2;
861 G4ErrorMatrixIter ip, mjj, iq;
862 G4double lambda, sigma;
863 const G4double alpha = .6404; // = (1+sqrt(17))/8
864 const G4double epsilon = 32*DBL_EPSILON;
865 // whenever a sum of two doubles is below or equal to epsilon
866 // it is set to zero.
867 // this constant could be set to zero but then the algorithm
868 // doesn't neccessarily detect that a matrix is singular
869
870 for (i = 0; i < nrow; i++)
871 {
872 piv[i] = i+1;
873 }
874
875 ifail = 0;
876
877 // compute the factorization P*A*P^T = L * D * L^T
878 // L is unit lower triangular, D is direct sum of 1x1 and 2x2 matrices
879 // L and D^-1 are stored in A = *this, P is stored in piv[]
880
881 for (j=1; j < nrow; j+=s) // main loop over columns
882 {
883 mjj = m.begin() + j*(j-1)/2 + j-1;
884 lambda = 0; // compute lambda = max of A(j+1:n,j)
885 pivrow = j+1;
886 ip = m.begin() + (j+1)*j/2 + j-1;
887 for (i=j+1; i <= nrow ; ip += i++)
888 {
889 if (std::fabs(*ip) > lambda)
890 {
891 lambda = std::fabs(*ip);
892 pivrow = i;
893 }
894 }
895 if (lambda == 0 )
896 {
897 if (*mjj == 0)
898 {
899 ifail = 1;
900 return;
901 }
902 s=1;
903 *mjj = 1./ *mjj;
904 }
905 else
906 {
907 if (std::fabs(*mjj) >= lambda*alpha)
908 {
909 s=1;
910 pivrow=j;
911 }
912 else
913 {
914 sigma = 0; // compute sigma = max A(pivrow, j:pivrow-1)
915 ip = m.begin() + pivrow*(pivrow-1)/2+j-1;
916 for (k=j; k < pivrow; k++)
917 {
918 if (std::fabs(*ip) > sigma)
919 sigma = std::fabs(*ip);
920 ip++;
921 }
922 if (sigma * std::fabs(*mjj) >= alpha * lambda * lambda)
923 {
924 s=1;
925 pivrow = j;
926 }
927 else if (std::fabs(*(m.begin()+pivrow*(pivrow-1)/2+pivrow-1))
928 >= alpha * sigma)
929 { s=1; }
930 else
931 { s=2; }
932 }
933 if (pivrow == j) // no permutation neccessary
934 {
935 piv[j-1] = pivrow;
936 if (*mjj == 0)
937 {
938 ifail=1;
939 return;
940 }
941 temp2 = *mjj = 1./ *mjj; // invert D(j,j)
942
943 // update A(j+1:n, j+1,n)
944 for (i=j+1; i <= nrow; i++)
945 {
946 temp1 = *(m.begin() + i*(i-1)/2 + j-1) * temp2;
947 ip = m.begin()+i*(i-1)/2+j;
948 for (k=j+1; k<=i; k++)
949 {
950 *ip -= temp1 * *(m.begin() + k*(k-1)/2 + j-1);
951 if (std::fabs(*ip) <= epsilon)
952 { *ip=0; }
953 ip++;
954 }
955 }
956 // update L
957 ip = m.begin() + (j+1)*j/2 + j-1;
958 for (i=j+1; i <= nrow; ip += i++)
959 {
960 *ip *= temp2;
961 }
962 }
963 else if (s==1) // 1x1 pivot
964 {
965 piv[j-1] = pivrow;
966
967 // interchange rows and columns j and pivrow in
968 // submatrix (j:n,j:n)
969 ip = m.begin() + pivrow*(pivrow-1)/2 + j;
970 for (i=j+1; i < pivrow; i++, ip++)
971 {
972 temp1 = *(m.begin() + i*(i-1)/2 + j-1);
973 *(m.begin() + i*(i-1)/2 + j-1)= *ip;
974 *ip = temp1;
975 }
976 temp1 = *mjj;
977 *mjj = *(m.begin()+pivrow*(pivrow-1)/2+pivrow-1);
978 *(m.begin()+pivrow*(pivrow-1)/2+pivrow-1) = temp1;
979 ip = m.begin() + (pivrow+1)*pivrow/2 + j-1;
980 iq = ip + pivrow-j;
981 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
982 {
983 temp1 = *iq;
984 *iq = *ip;
985 *ip = temp1;
986 }
987
988 if (*mjj == 0)
989 {
990 ifail = 1;
991 return;
992 }
993 temp2 = *mjj = 1./ *mjj; // invert D(j,j)
994
995 // update A(j+1:n, j+1:n)
996 for (i = j+1; i <= nrow; i++)
997 {
998 temp1 = *(m.begin() + i*(i-1)/2 + j-1) * temp2;
999 ip = m.begin()+i*(i-1)/2+j;
1000 for (k=j+1; k<=i; k++)
1001 {
1002 *ip -= temp1 * *(m.begin() + k*(k-1)/2 + j-1);
1003 if (std::fabs(*ip) <= epsilon)
1004 { *ip=0; }
1005 ip++;
1006 }
1007 }
1008 // update L
1009 ip = m.begin() + (j+1)*j/2 + j-1;
1010 for (i=j+1; i<=nrow; ip += i++)
1011 {
1012 *ip *= temp2;
1013 }
1014 }
1015 else // s=2, ie use a 2x2 pivot
1016 {
1017 piv[j-1] = -pivrow;
1018 piv[j] = 0; // that means this is the second row of a 2x2 pivot
1019
1020 if (j+1 != pivrow)
1021 {
1022 // interchange rows and columns j+1 and pivrow in
1023 // submatrix (j:n,j:n)
1024 ip = m.begin() + pivrow*(pivrow-1)/2 + j+1;
1025 for (i=j+2; i < pivrow; i++, ip++)
1026 {
1027 temp1 = *(m.begin() + i*(i-1)/2 + j);
1028 *(m.begin() + i*(i-1)/2 + j) = *ip;
1029 *ip = temp1;
1030 }
1031 temp1 = *(mjj + j + 1);
1032 *(mjj + j + 1) =
1033 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1);
1034 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1) = temp1;
1035 temp1 = *(mjj + j);
1036 *(mjj + j) = *(m.begin() + pivrow*(pivrow-1)/2 + j-1);
1037 *(m.begin() + pivrow*(pivrow-1)/2 + j-1) = temp1;
1038 ip = m.begin() + (pivrow+1)*pivrow/2 + j;
1039 iq = ip + pivrow-(j+1);
1040 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
1041 {
1042 temp1 = *iq;
1043 *iq = *ip;
1044 *ip = temp1;
1045 }
1046 }
1047 // invert D(j:j+1,j:j+1)
1048 temp2 = *mjj * *(mjj + j + 1) - *(mjj + j) * *(mjj + j);
1049 if (temp2 == 0)
1050 {
1051 G4cerr
1052 << "G4ErrorSymMatrix::bunch_invert: error in pivot choice"
1053 << G4endl;
1054 }
1055 temp2 = 1. / temp2;
1056
1057 // this quotient is guaranteed to exist by the choice
1058 // of the pivot
1059
1060 temp1 = *mjj;
1061 *mjj = *(mjj + j + 1) * temp2;
1062 *(mjj + j + 1) = temp1 * temp2;
1063 *(mjj + j) = - *(mjj + j) * temp2;
1064
1065 if (j < nrow-1) // otherwise do nothing
1066 {
1067 // update A(j+2:n, j+2:n)
1068 for (i=j+2; i <= nrow ; i++)
1069 {
1070 ip = m.begin() + i*(i-1)/2 + j-1;
1071 temp1 = *ip * *mjj + *(ip + 1) * *(mjj + j);
1072 if (std::fabs(temp1 ) <= epsilon)
1073 { temp1 = 0; }
1074 temp2 = *ip * *(mjj + j) + *(ip + 1) * *(mjj + j + 1);
1075 if (std::fabs(temp2 ) <= epsilon)
1076 { temp2 = 0; }
1077 for (k = j+2; k <= i ; k++)
1078 {
1079 ip = m.begin() + i*(i-1)/2 + k-1;
1080 iq = m.begin() + k*(k-1)/2 + j-1;
1081 *ip -= temp1 * *iq + temp2 * *(iq+1);
1082 if (std::fabs(*ip) <= epsilon)
1083 { *ip = 0; }
1084 }
1085 }
1086 // update L
1087 for (i=j+2; i <= nrow ; i++)
1088 {
1089 ip = m.begin() + i*(i-1)/2 + j-1;
1090 temp1 = *ip * *mjj + *(ip+1) * *(mjj + j);
1091 if (std::fabs(temp1) <= epsilon)
1092 { temp1 = 0; }
1093 *(ip+1) = *ip * *(mjj + j) + *(ip+1) * *(mjj + j + 1);
1094 if (std::fabs(*(ip+1)) <= epsilon)
1095 { *(ip+1) = 0; }
1096 *ip = temp1;
1097 }
1098 }
1099 }
1100 }
1101 } // end of main loop over columns
1102
1103 if (j == nrow) // the the last pivot is 1x1
1104 {
1105 mjj = m.begin() + j*(j-1)/2 + j-1;
1106 if (*mjj == 0)
1107 {
1108 ifail = 1;
1109 return;
1110 }
1111 else
1112 {
1113 *mjj = 1. / *mjj;
1114 }
1115 } // end of last pivot code
1116
1117 // computing the inverse from the factorization
1118
1119 for (j = nrow ; j >= 1 ; j -= s) // loop over columns
1120 {
1121 mjj = m.begin() + j*(j-1)/2 + j-1;
1122 if (piv[j-1] > 0) // 1x1 pivot, compute column j of inverse
1123 {
1124 s = 1;
1125 if (j < nrow)
1126 {
1127 ip = m.begin() + (j+1)*j/2 + j-1;
1128 for (i=0; i < nrow-j; ip += 1+j+i++)
1129 {
1130 x[i] = *ip;
1131 }
1132 for (i=j+1; i<=nrow ; i++)
1133 {
1134 temp2=0;
1135 ip = m.begin() + i*(i-1)/2 + j;
1136 for (k=0; k <= i-j-1; k++)
1137 { temp2 += *ip++ * x[k]; }
1138 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
1139 { temp2 += *ip * x[k]; }
1140 *(m.begin()+ i*(i-1)/2 + j-1) = -temp2;
1141 }
1142 temp2 = 0;
1143 ip = m.begin() + (j+1)*j/2 + j-1;
1144 for (k=0; k < nrow-j; ip += 1+j+k++)
1145 { temp2 += x[k] * *ip; }
1146 *mjj -= temp2;
1147 }
1148 }
1149 else //2x2 pivot, compute columns j and j-1 of the inverse
1150 {
1151 if (piv[j-1] != 0)
1152 { G4cerr << "error in piv" << piv[j-1] << G4endl; }
1153 s=2;
1154 if (j < nrow)
1155 {
1156 ip = m.begin() + (j+1)*j/2 + j-1;
1157 for (i=0; i < nrow-j; ip += 1+j+i++)
1158 {
1159 x[i] = *ip;
1160 }
1161 for (i=j+1; i<=nrow ; i++)
1162 {
1163 temp2 = 0;
1164 ip = m.begin() + i*(i-1)/2 + j;
1165 for (k=0; k <= i-j-1; k++)
1166 { temp2 += *ip++ * x[k]; }
1167 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
1168 { temp2 += *ip * x[k]; }
1169 *(m.begin()+ i*(i-1)/2 + j-1) = -temp2;
1170 }
1171 temp2 = 0;
1172 ip = m.begin() + (j+1)*j/2 + j-1;
1173 for (k=0; k < nrow-j; ip += 1+j+k++)
1174 { temp2 += x[k] * *ip; }
1175 *mjj -= temp2;
1176 temp2 = 0;
1177 ip = m.begin() + (j+1)*j/2 + j-2;
1178 for (i=j+1; i <= nrow; ip += i++)
1179 { temp2 += *ip * *(ip+1); }
1180 *(mjj-1) -= temp2;
1181 ip = m.begin() + (j+1)*j/2 + j-2;
1182 for (i=0; i < nrow-j; ip += 1+j+i++)
1183 {
1184 x[i] = *ip;
1185 }
1186 for (i=j+1; i <= nrow ; i++)
1187 {
1188 temp2 = 0;
1189 ip = m.begin() + i*(i-1)/2 + j;
1190 for (k=0; k <= i-j-1; k++)
1191 { temp2 += *ip++ * x[k]; }
1192 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
1193 { temp2 += *ip * x[k]; }
1194 *(m.begin()+ i*(i-1)/2 + j-2)= -temp2;
1195 }
1196 temp2 = 0;
1197 ip = m.begin() + (j+1)*j/2 + j-2;
1198 for (k=0; k < nrow-j; ip += 1+j+k++)
1199 { temp2 += x[k] * *ip; }
1200 *(mjj-j) -= temp2;
1201 }
1202 }
1203
1204 // interchange rows and columns j and piv[j-1]
1205 // or rows and columns j and -piv[j-2]
1206
1207 pivrow = (piv[j-1]==0)? -piv[j-2] : piv[j-1];
1208 ip = m.begin() + pivrow*(pivrow-1)/2 + j;
1209 for (i=j+1;i < pivrow; i++, ip++)
1210 {
1211 temp1 = *(m.begin() + i*(i-1)/2 + j-1);
1212 *(m.begin() + i*(i-1)/2 + j-1) = *ip;
1213 *ip = temp1;
1214 }
1215 temp1 = *mjj;
1216 *mjj = *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1);
1217 *(m.begin() + pivrow*(pivrow-1)/2 + pivrow-1) = temp1;
1218 if (s==2)
1219 {
1220 temp1 = *(mjj-1);
1221 *(mjj-1) = *( m.begin() + pivrow*(pivrow-1)/2 + j-2);
1222 *( m.begin() + pivrow*(pivrow-1)/2 + j-2) = temp1;
1223 }
1224
1225 ip = m.begin() + (pivrow+1)*pivrow/2 + j-1; // &A(i,j)
1226 iq = ip + pivrow-j;
1227 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
1228 {
1229 temp1 = *iq;
1230 *iq = *ip;
1231 *ip = temp1;
1232 }
1233 } // end of loop over columns (in computing inverse from factorization)
1234
1235 return; // inversion successful
1236}
1237
1238G4double G4ErrorSymMatrix::posDefFraction5x5 = 1.0;
1239G4double G4ErrorSymMatrix::posDefFraction6x6 = 1.0;
1240G4double G4ErrorSymMatrix::adjustment5x5 = 0.0;
1241G4double G4ErrorSymMatrix::adjustment6x6 = 0.0;
1242const G4double G4ErrorSymMatrix::CHOLESKY_THRESHOLD_5x5 = .5;
1243const G4double G4ErrorSymMatrix::CHOLESKY_THRESHOLD_6x6 = .2;
1244const G4double G4ErrorSymMatrix::CHOLESKY_CREEP_5x5 = .005;
1245const G4double G4ErrorSymMatrix::CHOLESKY_CREEP_6x6 = .002;
1246
1247// Aij are indices for a 6x6 symmetric matrix.
1248// The indices for 5x5 or 4x4 symmetric matrices are the same,
1249// ignoring all combinations with an index which is inapplicable.
1250
1251#define A00 0
1252#define A01 1
1253#define A02 3
1254#define A03 6
1255#define A04 10
1256#define A05 15
1257
1258#define A10 1
1259#define A11 2
1260#define A12 4
1261#define A13 7
1262#define A14 11
1263#define A15 16
1264
1265#define A20 3
1266#define A21 4
1267#define A22 5
1268#define A23 8
1269#define A24 12
1270#define A25 17
1271
1272#define A30 6
1273#define A31 7
1274#define A32 8
1275#define A33 9
1276#define A34 13
1277#define A35 18
1278
1279#define A40 10
1280#define A41 11
1281#define A42 12
1282#define A43 13
1283#define A44 14
1284#define A45 19
1285
1286#define A50 15
1287#define A51 16
1288#define A52 17
1289#define A53 18
1290#define A54 19
1291#define A55 20
1292
1293void G4ErrorSymMatrix::invert5(G4int & ifail)
1294{
1295 if (posDefFraction5x5 >= CHOLESKY_THRESHOLD_5x5)
1296 {
1297 invertCholesky5(ifail);
1298 posDefFraction5x5 = .9*posDefFraction5x5 + .1*(1-ifail);
1299 if (ifail!=0) // Cholesky failed -- invert using Haywood
1300 {
1301 invertHaywood5(ifail);
1302 }
1303 }
1304 else
1305 {
1306 if (posDefFraction5x5 + adjustment5x5 >= CHOLESKY_THRESHOLD_5x5)
1307 {
1308 invertCholesky5(ifail);
1309 posDefFraction5x5 = .9*posDefFraction5x5 + .1*(1-ifail);
1310 if (ifail!=0) // Cholesky failed -- invert using Haywood
1311 {
1312 invertHaywood5(ifail);
1313 adjustment5x5 = 0;
1314 }
1315 }
1316 else
1317 {
1318 invertHaywood5(ifail);
1319 adjustment5x5 += CHOLESKY_CREEP_5x5;
1320 }
1321 }
1322 return;
1323}
1324
1325void G4ErrorSymMatrix::invert6(G4int & ifail)
1326{
1327 if (posDefFraction6x6 >= CHOLESKY_THRESHOLD_6x6)
1328 {
1329 invertCholesky6(ifail);
1330 posDefFraction6x6 = .9*posDefFraction6x6 + .1*(1-ifail);
1331 if (ifail!=0) // Cholesky failed -- invert using Haywood
1332 {
1333 invertHaywood6(ifail);
1334 }
1335 }
1336 else
1337 {
1338 if (posDefFraction6x6 + adjustment6x6 >= CHOLESKY_THRESHOLD_6x6)
1339 {
1340 invertCholesky6(ifail);
1341 posDefFraction6x6 = .9*posDefFraction6x6 + .1*(1-ifail);
1342 if (ifail!=0) // Cholesky failed -- invert using Haywood
1343 {
1344 invertHaywood6(ifail);
1345 adjustment6x6 = 0;
1346 }
1347 }
1348 else
1349 {
1350 invertHaywood6(ifail);
1351 adjustment6x6 += CHOLESKY_CREEP_6x6;
1352 }
1353 }
1354 return;
1355}
1356
1357void G4ErrorSymMatrix::invertHaywood5 (G4int & ifail)
1358{
1359 ifail = 0;
1360
1361 // Find all NECESSARY 2x2 dets: (25 of them)
1362
1363 G4double Det2_23_01 = m[A20]*m[A31] - m[A21]*m[A30];
1364 G4double Det2_23_02 = m[A20]*m[A32] - m[A22]*m[A30];
1365 G4double Det2_23_03 = m[A20]*m[A33] - m[A23]*m[A30];
1366 G4double Det2_23_12 = m[A21]*m[A32] - m[A22]*m[A31];
1367 G4double Det2_23_13 = m[A21]*m[A33] - m[A23]*m[A31];
1368 G4double Det2_23_23 = m[A22]*m[A33] - m[A23]*m[A32];
1369 G4double Det2_24_01 = m[A20]*m[A41] - m[A21]*m[A40];
1370 G4double Det2_24_02 = m[A20]*m[A42] - m[A22]*m[A40];
1371 G4double Det2_24_03 = m[A20]*m[A43] - m[A23]*m[A40];
1372 G4double Det2_24_04 = m[A20]*m[A44] - m[A24]*m[A40];
1373 G4double Det2_24_12 = m[A21]*m[A42] - m[A22]*m[A41];
1374 G4double Det2_24_13 = m[A21]*m[A43] - m[A23]*m[A41];
1375 G4double Det2_24_14 = m[A21]*m[A44] - m[A24]*m[A41];
1376 G4double Det2_24_23 = m[A22]*m[A43] - m[A23]*m[A42];
1377 G4double Det2_24_24 = m[A22]*m[A44] - m[A24]*m[A42];
1378 G4double Det2_34_01 = m[A30]*m[A41] - m[A31]*m[A40];
1379 G4double Det2_34_02 = m[A30]*m[A42] - m[A32]*m[A40];
1380 G4double Det2_34_03 = m[A30]*m[A43] - m[A33]*m[A40];
1381 G4double Det2_34_04 = m[A30]*m[A44] - m[A34]*m[A40];
1382 G4double Det2_34_12 = m[A31]*m[A42] - m[A32]*m[A41];
1383 G4double Det2_34_13 = m[A31]*m[A43] - m[A33]*m[A41];
1384 G4double Det2_34_14 = m[A31]*m[A44] - m[A34]*m[A41];
1385 G4double Det2_34_23 = m[A32]*m[A43] - m[A33]*m[A42];
1386 G4double Det2_34_24 = m[A32]*m[A44] - m[A34]*m[A42];
1387 G4double Det2_34_34 = m[A33]*m[A44] - m[A34]*m[A43];
1388
1389 // Find all NECESSARY 3x3 dets: (30 of them)
1390
1391 G4double Det3_123_012 = m[A10]*Det2_23_12 - m[A11]*Det2_23_02
1392 + m[A12]*Det2_23_01;
1393 G4double Det3_123_013 = m[A10]*Det2_23_13 - m[A11]*Det2_23_03
1394 + m[A13]*Det2_23_01;
1395 G4double Det3_123_023 = m[A10]*Det2_23_23 - m[A12]*Det2_23_03
1396 + m[A13]*Det2_23_02;
1397 G4double Det3_123_123 = m[A11]*Det2_23_23 - m[A12]*Det2_23_13
1398 + m[A13]*Det2_23_12;
1399 G4double Det3_124_012 = m[A10]*Det2_24_12 - m[A11]*Det2_24_02
1400 + m[A12]*Det2_24_01;
1401 G4double Det3_124_013 = m[A10]*Det2_24_13 - m[A11]*Det2_24_03
1402 + m[A13]*Det2_24_01;
1403 G4double Det3_124_014 = m[A10]*Det2_24_14 - m[A11]*Det2_24_04
1404 + m[A14]*Det2_24_01;
1405 G4double Det3_124_023 = m[A10]*Det2_24_23 - m[A12]*Det2_24_03
1406 + m[A13]*Det2_24_02;
1407 G4double Det3_124_024 = m[A10]*Det2_24_24 - m[A12]*Det2_24_04
1408 + m[A14]*Det2_24_02;
1409 G4double Det3_124_123 = m[A11]*Det2_24_23 - m[A12]*Det2_24_13
1410 + m[A13]*Det2_24_12;
1411 G4double Det3_124_124 = m[A11]*Det2_24_24 - m[A12]*Det2_24_14
1412 + m[A14]*Det2_24_12;
1413 G4double Det3_134_012 = m[A10]*Det2_34_12 - m[A11]*Det2_34_02
1414 + m[A12]*Det2_34_01;
1415 G4double Det3_134_013 = m[A10]*Det2_34_13 - m[A11]*Det2_34_03
1416 + m[A13]*Det2_34_01;
1417 G4double Det3_134_014 = m[A10]*Det2_34_14 - m[A11]*Det2_34_04
1418 + m[A14]*Det2_34_01;
1419 G4double Det3_134_023 = m[A10]*Det2_34_23 - m[A12]*Det2_34_03
1420 + m[A13]*Det2_34_02;
1421 G4double Det3_134_024 = m[A10]*Det2_34_24 - m[A12]*Det2_34_04
1422 + m[A14]*Det2_34_02;
1423 G4double Det3_134_034 = m[A10]*Det2_34_34 - m[A13]*Det2_34_04
1424 + m[A14]*Det2_34_03;
1425 G4double Det3_134_123 = m[A11]*Det2_34_23 - m[A12]*Det2_34_13
1426 + m[A13]*Det2_34_12;
1427 G4double Det3_134_124 = m[A11]*Det2_34_24 - m[A12]*Det2_34_14
1428 + m[A14]*Det2_34_12;
1429 G4double Det3_134_134 = m[A11]*Det2_34_34 - m[A13]*Det2_34_14
1430 + m[A14]*Det2_34_13;
1431 G4double Det3_234_012 = m[A20]*Det2_34_12 - m[A21]*Det2_34_02
1432 + m[A22]*Det2_34_01;
1433 G4double Det3_234_013 = m[A20]*Det2_34_13 - m[A21]*Det2_34_03
1434 + m[A23]*Det2_34_01;
1435 G4double Det3_234_014 = m[A20]*Det2_34_14 - m[A21]*Det2_34_04
1436 + m[A24]*Det2_34_01;
1437 G4double Det3_234_023 = m[A20]*Det2_34_23 - m[A22]*Det2_34_03
1438 + m[A23]*Det2_34_02;
1439 G4double Det3_234_024 = m[A20]*Det2_34_24 - m[A22]*Det2_34_04
1440 + m[A24]*Det2_34_02;
1441 G4double Det3_234_034 = m[A20]*Det2_34_34 - m[A23]*Det2_34_04
1442 + m[A24]*Det2_34_03;
1443 G4double Det3_234_123 = m[A21]*Det2_34_23 - m[A22]*Det2_34_13
1444 + m[A23]*Det2_34_12;
1445 G4double Det3_234_124 = m[A21]*Det2_34_24 - m[A22]*Det2_34_14
1446 + m[A24]*Det2_34_12;
1447 G4double Det3_234_134 = m[A21]*Det2_34_34 - m[A23]*Det2_34_14
1448 + m[A24]*Det2_34_13;
1449 G4double Det3_234_234 = m[A22]*Det2_34_34 - m[A23]*Det2_34_24
1450 + m[A24]*Det2_34_23;
1451
1452 // Find all NECESSARY 4x4 dets: (15 of them)
1453
1454 G4double Det4_0123_0123 = m[A00]*Det3_123_123 - m[A01]*Det3_123_023
1455 + m[A02]*Det3_123_013 - m[A03]*Det3_123_012;
1456 G4double Det4_0124_0123 = m[A00]*Det3_124_123 - m[A01]*Det3_124_023
1457 + m[A02]*Det3_124_013 - m[A03]*Det3_124_012;
1458 G4double Det4_0124_0124 = m[A00]*Det3_124_124 - m[A01]*Det3_124_024
1459 + m[A02]*Det3_124_014 - m[A04]*Det3_124_012;
1460 G4double Det4_0134_0123 = m[A00]*Det3_134_123 - m[A01]*Det3_134_023
1461 + m[A02]*Det3_134_013 - m[A03]*Det3_134_012;
1462 G4double Det4_0134_0124 = m[A00]*Det3_134_124 - m[A01]*Det3_134_024
1463 + m[A02]*Det3_134_014 - m[A04]*Det3_134_012;
1464 G4double Det4_0134_0134 = m[A00]*Det3_134_134 - m[A01]*Det3_134_034
1465 + m[A03]*Det3_134_014 - m[A04]*Det3_134_013;
1466 G4double Det4_0234_0123 = m[A00]*Det3_234_123 - m[A01]*Det3_234_023
1467 + m[A02]*Det3_234_013 - m[A03]*Det3_234_012;
1468 G4double Det4_0234_0124 = m[A00]*Det3_234_124 - m[A01]*Det3_234_024
1469 + m[A02]*Det3_234_014 - m[A04]*Det3_234_012;
1470 G4double Det4_0234_0134 = m[A00]*Det3_234_134 - m[A01]*Det3_234_034
1471 + m[A03]*Det3_234_014 - m[A04]*Det3_234_013;
1472 G4double Det4_0234_0234 = m[A00]*Det3_234_234 - m[A02]*Det3_234_034
1473 + m[A03]*Det3_234_024 - m[A04]*Det3_234_023;
1474 G4double Det4_1234_0123 = m[A10]*Det3_234_123 - m[A11]*Det3_234_023
1475 + m[A12]*Det3_234_013 - m[A13]*Det3_234_012;
1476 G4double Det4_1234_0124 = m[A10]*Det3_234_124 - m[A11]*Det3_234_024
1477 + m[A12]*Det3_234_014 - m[A14]*Det3_234_012;
1478 G4double Det4_1234_0134 = m[A10]*Det3_234_134 - m[A11]*Det3_234_034
1479 + m[A13]*Det3_234_014 - m[A14]*Det3_234_013;
1480 G4double Det4_1234_0234 = m[A10]*Det3_234_234 - m[A12]*Det3_234_034
1481 + m[A13]*Det3_234_024 - m[A14]*Det3_234_023;
1482 G4double Det4_1234_1234 = m[A11]*Det3_234_234 - m[A12]*Det3_234_134
1483 + m[A13]*Det3_234_124 - m[A14]*Det3_234_123;
1484
1485 // Find the 5x5 det:
1486
1487 G4double det = m[A00]*Det4_1234_1234
1488 - m[A01]*Det4_1234_0234
1489 + m[A02]*Det4_1234_0134
1490 - m[A03]*Det4_1234_0124
1491 + m[A04]*Det4_1234_0123;
1492
1493 if ( det == 0 )
1494 {
1495 ifail = 1;
1496 return;
1497 }
1498
1499 G4double oneOverDet = 1.0/det;
1500 G4double mn1OverDet = - oneOverDet;
1501
1502 m[A00] = Det4_1234_1234 * oneOverDet;
1503 m[A01] = Det4_1234_0234 * mn1OverDet;
1504 m[A02] = Det4_1234_0134 * oneOverDet;
1505 m[A03] = Det4_1234_0124 * mn1OverDet;
1506 m[A04] = Det4_1234_0123 * oneOverDet;
1507
1508 m[A11] = Det4_0234_0234 * oneOverDet;
1509 m[A12] = Det4_0234_0134 * mn1OverDet;
1510 m[A13] = Det4_0234_0124 * oneOverDet;
1511 m[A14] = Det4_0234_0123 * mn1OverDet;
1512
1513 m[A22] = Det4_0134_0134 * oneOverDet;
1514 m[A23] = Det4_0134_0124 * mn1OverDet;
1515 m[A24] = Det4_0134_0123 * oneOverDet;
1516
1517 m[A33] = Det4_0124_0124 * oneOverDet;
1518 m[A34] = Det4_0124_0123 * mn1OverDet;
1519
1520 m[A44] = Det4_0123_0123 * oneOverDet;
1521
1522 return;
1523}
1524
1525void G4ErrorSymMatrix::invertHaywood6 (G4int & ifail)
1526{
1527 ifail = 0;
1528
1529 // Find all NECESSARY 2x2 dets: (39 of them)
1530
1531 G4double Det2_34_01 = m[A30]*m[A41] - m[A31]*m[A40];
1532 G4double Det2_34_02 = m[A30]*m[A42] - m[A32]*m[A40];
1533 G4double Det2_34_03 = m[A30]*m[A43] - m[A33]*m[A40];
1534 G4double Det2_34_04 = m[A30]*m[A44] - m[A34]*m[A40];
1535 G4double Det2_34_12 = m[A31]*m[A42] - m[A32]*m[A41];
1536 G4double Det2_34_13 = m[A31]*m[A43] - m[A33]*m[A41];
1537 G4double Det2_34_14 = m[A31]*m[A44] - m[A34]*m[A41];
1538 G4double Det2_34_23 = m[A32]*m[A43] - m[A33]*m[A42];
1539 G4double Det2_34_24 = m[A32]*m[A44] - m[A34]*m[A42];
1540 G4double Det2_34_34 = m[A33]*m[A44] - m[A34]*m[A43];
1541 G4double Det2_35_01 = m[A30]*m[A51] - m[A31]*m[A50];
1542 G4double Det2_35_02 = m[A30]*m[A52] - m[A32]*m[A50];
1543 G4double Det2_35_03 = m[A30]*m[A53] - m[A33]*m[A50];
1544 G4double Det2_35_04 = m[A30]*m[A54] - m[A34]*m[A50];
1545 G4double Det2_35_05 = m[A30]*m[A55] - m[A35]*m[A50];
1546 G4double Det2_35_12 = m[A31]*m[A52] - m[A32]*m[A51];
1547 G4double Det2_35_13 = m[A31]*m[A53] - m[A33]*m[A51];
1548 G4double Det2_35_14 = m[A31]*m[A54] - m[A34]*m[A51];
1549 G4double Det2_35_15 = m[A31]*m[A55] - m[A35]*m[A51];
1550 G4double Det2_35_23 = m[A32]*m[A53] - m[A33]*m[A52];
1551 G4double Det2_35_24 = m[A32]*m[A54] - m[A34]*m[A52];
1552 G4double Det2_35_25 = m[A32]*m[A55] - m[A35]*m[A52];
1553 G4double Det2_35_34 = m[A33]*m[A54] - m[A34]*m[A53];
1554 G4double Det2_35_35 = m[A33]*m[A55] - m[A35]*m[A53];
1555 G4double Det2_45_01 = m[A40]*m[A51] - m[A41]*m[A50];
1556 G4double Det2_45_02 = m[A40]*m[A52] - m[A42]*m[A50];
1557 G4double Det2_45_03 = m[A40]*m[A53] - m[A43]*m[A50];
1558 G4double Det2_45_04 = m[A40]*m[A54] - m[A44]*m[A50];
1559 G4double Det2_45_05 = m[A40]*m[A55] - m[A45]*m[A50];
1560 G4double Det2_45_12 = m[A41]*m[A52] - m[A42]*m[A51];
1561 G4double Det2_45_13 = m[A41]*m[A53] - m[A43]*m[A51];
1562 G4double Det2_45_14 = m[A41]*m[A54] - m[A44]*m[A51];
1563 G4double Det2_45_15 = m[A41]*m[A55] - m[A45]*m[A51];
1564 G4double Det2_45_23 = m[A42]*m[A53] - m[A43]*m[A52];
1565 G4double Det2_45_24 = m[A42]*m[A54] - m[A44]*m[A52];
1566 G4double Det2_45_25 = m[A42]*m[A55] - m[A45]*m[A52];
1567 G4double Det2_45_34 = m[A43]*m[A54] - m[A44]*m[A53];
1568 G4double Det2_45_35 = m[A43]*m[A55] - m[A45]*m[A53];
1569 G4double Det2_45_45 = m[A44]*m[A55] - m[A45]*m[A54];
1570
1571 // Find all NECESSARY 3x3 dets: (65 of them)
1572
1573 G4double Det3_234_012 = m[A20]*Det2_34_12 - m[A21]*Det2_34_02
1574 + m[A22]*Det2_34_01;
1575 G4double Det3_234_013 = m[A20]*Det2_34_13 - m[A21]*Det2_34_03
1576 + m[A23]*Det2_34_01;
1577 G4double Det3_234_014 = m[A20]*Det2_34_14 - m[A21]*Det2_34_04
1578 + m[A24]*Det2_34_01;
1579 G4double Det3_234_023 = m[A20]*Det2_34_23 - m[A22]*Det2_34_03
1580 + m[A23]*Det2_34_02;
1581 G4double Det3_234_024 = m[A20]*Det2_34_24 - m[A22]*Det2_34_04
1582 + m[A24]*Det2_34_02;
1583 G4double Det3_234_034 = m[A20]*Det2_34_34 - m[A23]*Det2_34_04
1584 + m[A24]*Det2_34_03;
1585 G4double Det3_234_123 = m[A21]*Det2_34_23 - m[A22]*Det2_34_13
1586 + m[A23]*Det2_34_12;
1587 G4double Det3_234_124 = m[A21]*Det2_34_24 - m[A22]*Det2_34_14
1588 + m[A24]*Det2_34_12;
1589 G4double Det3_234_134 = m[A21]*Det2_34_34 - m[A23]*Det2_34_14
1590 + m[A24]*Det2_34_13;
1591 G4double Det3_234_234 = m[A22]*Det2_34_34 - m[A23]*Det2_34_24
1592 + m[A24]*Det2_34_23;
1593 G4double Det3_235_012 = m[A20]*Det2_35_12 - m[A21]*Det2_35_02
1594 + m[A22]*Det2_35_01;
1595 G4double Det3_235_013 = m[A20]*Det2_35_13 - m[A21]*Det2_35_03
1596 + m[A23]*Det2_35_01;
1597 G4double Det3_235_014 = m[A20]*Det2_35_14 - m[A21]*Det2_35_04
1598 + m[A24]*Det2_35_01;
1599 G4double Det3_235_015 = m[A20]*Det2_35_15 - m[A21]*Det2_35_05
1600 + m[A25]*Det2_35_01;
1601 G4double Det3_235_023 = m[A20]*Det2_35_23 - m[A22]*Det2_35_03
1602 + m[A23]*Det2_35_02;
1603 G4double Det3_235_024 = m[A20]*Det2_35_24 - m[A22]*Det2_35_04
1604 + m[A24]*Det2_35_02;
1605 G4double Det3_235_025 = m[A20]*Det2_35_25 - m[A22]*Det2_35_05
1606 + m[A25]*Det2_35_02;
1607 G4double Det3_235_034 = m[A20]*Det2_35_34 - m[A23]*Det2_35_04
1608 + m[A24]*Det2_35_03;
1609 G4double Det3_235_035 = m[A20]*Det2_35_35 - m[A23]*Det2_35_05
1610 + m[A25]*Det2_35_03;
1611 G4double Det3_235_123 = m[A21]*Det2_35_23 - m[A22]*Det2_35_13
1612 + m[A23]*Det2_35_12;
1613 G4double Det3_235_124 = m[A21]*Det2_35_24 - m[A22]*Det2_35_14
1614 + m[A24]*Det2_35_12;
1615 G4double Det3_235_125 = m[A21]*Det2_35_25 - m[A22]*Det2_35_15
1616 + m[A25]*Det2_35_12;
1617 G4double Det3_235_134 = m[A21]*Det2_35_34 - m[A23]*Det2_35_14
1618 + m[A24]*Det2_35_13;
1619 G4double Det3_235_135 = m[A21]*Det2_35_35 - m[A23]*Det2_35_15
1620 + m[A25]*Det2_35_13;
1621 G4double Det3_235_234 = m[A22]*Det2_35_34 - m[A23]*Det2_35_24
1622 + m[A24]*Det2_35_23;
1623 G4double Det3_235_235 = m[A22]*Det2_35_35 - m[A23]*Det2_35_25
1624 + m[A25]*Det2_35_23;
1625 G4double Det3_245_012 = m[A20]*Det2_45_12 - m[A21]*Det2_45_02
1626 + m[A22]*Det2_45_01;
1627 G4double Det3_245_013 = m[A20]*Det2_45_13 - m[A21]*Det2_45_03
1628 + m[A23]*Det2_45_01;
1629 G4double Det3_245_014 = m[A20]*Det2_45_14 - m[A21]*Det2_45_04
1630 + m[A24]*Det2_45_01;
1631 G4double Det3_245_015 = m[A20]*Det2_45_15 - m[A21]*Det2_45_05
1632 + m[A25]*Det2_45_01;
1633 G4double Det3_245_023 = m[A20]*Det2_45_23 - m[A22]*Det2_45_03
1634 + m[A23]*Det2_45_02;
1635 G4double Det3_245_024 = m[A20]*Det2_45_24 - m[A22]*Det2_45_04
1636 + m[A24]*Det2_45_02;
1637 G4double Det3_245_025 = m[A20]*Det2_45_25 - m[A22]*Det2_45_05
1638 + m[A25]*Det2_45_02;
1639 G4double Det3_245_034 = m[A20]*Det2_45_34 - m[A23]*Det2_45_04
1640 + m[A24]*Det2_45_03;
1641 G4double Det3_245_035 = m[A20]*Det2_45_35 - m[A23]*Det2_45_05
1642 + m[A25]*Det2_45_03;
1643 G4double Det3_245_045 = m[A20]*Det2_45_45 - m[A24]*Det2_45_05
1644 + m[A25]*Det2_45_04;
1645 G4double Det3_245_123 = m[A21]*Det2_45_23 - m[A22]*Det2_45_13
1646 + m[A23]*Det2_45_12;
1647 G4double Det3_245_124 = m[A21]*Det2_45_24 - m[A22]*Det2_45_14
1648 + m[A24]*Det2_45_12;
1649 G4double Det3_245_125 = m[A21]*Det2_45_25 - m[A22]*Det2_45_15
1650 + m[A25]*Det2_45_12;
1651 G4double Det3_245_134 = m[A21]*Det2_45_34 - m[A23]*Det2_45_14
1652 + m[A24]*Det2_45_13;
1653 G4double Det3_245_135 = m[A21]*Det2_45_35 - m[A23]*Det2_45_15
1654 + m[A25]*Det2_45_13;
1655 G4double Det3_245_145 = m[A21]*Det2_45_45 - m[A24]*Det2_45_15
1656 + m[A25]*Det2_45_14;
1657 G4double Det3_245_234 = m[A22]*Det2_45_34 - m[A23]*Det2_45_24
1658 + m[A24]*Det2_45_23;
1659 G4double Det3_245_235 = m[A22]*Det2_45_35 - m[A23]*Det2_45_25
1660 + m[A25]*Det2_45_23;
1661 G4double Det3_245_245 = m[A22]*Det2_45_45 - m[A24]*Det2_45_25
1662 + m[A25]*Det2_45_24;
1663 G4double Det3_345_012 = m[A30]*Det2_45_12 - m[A31]*Det2_45_02
1664 + m[A32]*Det2_45_01;
1665 G4double Det3_345_013 = m[A30]*Det2_45_13 - m[A31]*Det2_45_03
1666 + m[A33]*Det2_45_01;
1667 G4double Det3_345_014 = m[A30]*Det2_45_14 - m[A31]*Det2_45_04
1668 + m[A34]*Det2_45_01;
1669 G4double Det3_345_015 = m[A30]*Det2_45_15 - m[A31]*Det2_45_05
1670 + m[A35]*Det2_45_01;
1671 G4double Det3_345_023 = m[A30]*Det2_45_23 - m[A32]*Det2_45_03
1672 + m[A33]*Det2_45_02;
1673 G4double Det3_345_024 = m[A30]*Det2_45_24 - m[A32]*Det2_45_04
1674 + m[A34]*Det2_45_02;
1675 G4double Det3_345_025 = m[A30]*Det2_45_25 - m[A32]*Det2_45_05
1676 + m[A35]*Det2_45_02;
1677 G4double Det3_345_034 = m[A30]*Det2_45_34 - m[A33]*Det2_45_04
1678 + m[A34]*Det2_45_03;
1679 G4double Det3_345_035 = m[A30]*Det2_45_35 - m[A33]*Det2_45_05
1680 + m[A35]*Det2_45_03;
1681 G4double Det3_345_045 = m[A30]*Det2_45_45 - m[A34]*Det2_45_05
1682 + m[A35]*Det2_45_04;
1683 G4double Det3_345_123 = m[A31]*Det2_45_23 - m[A32]*Det2_45_13
1684 + m[A33]*Det2_45_12;
1685 G4double Det3_345_124 = m[A31]*Det2_45_24 - m[A32]*Det2_45_14
1686 + m[A34]*Det2_45_12;
1687 G4double Det3_345_125 = m[A31]*Det2_45_25 - m[A32]*Det2_45_15
1688 + m[A35]*Det2_45_12;
1689 G4double Det3_345_134 = m[A31]*Det2_45_34 - m[A33]*Det2_45_14
1690 + m[A34]*Det2_45_13;
1691 G4double Det3_345_135 = m[A31]*Det2_45_35 - m[A33]*Det2_45_15
1692 + m[A35]*Det2_45_13;
1693 G4double Det3_345_145 = m[A31]*Det2_45_45 - m[A34]*Det2_45_15
1694 + m[A35]*Det2_45_14;
1695 G4double Det3_345_234 = m[A32]*Det2_45_34 - m[A33]*Det2_45_24
1696 + m[A34]*Det2_45_23;
1697 G4double Det3_345_235 = m[A32]*Det2_45_35 - m[A33]*Det2_45_25
1698 + m[A35]*Det2_45_23;
1699 G4double Det3_345_245 = m[A32]*Det2_45_45 - m[A34]*Det2_45_25
1700 + m[A35]*Det2_45_24;
1701 G4double Det3_345_345 = m[A33]*Det2_45_45 - m[A34]*Det2_45_35
1702 + m[A35]*Det2_45_34;
1703
1704 // Find all NECESSARY 4x4 dets: (55 of them)
1705
1706 G4double Det4_1234_0123 = m[A10]*Det3_234_123 - m[A11]*Det3_234_023
1707 + m[A12]*Det3_234_013 - m[A13]*Det3_234_012;
1708 G4double Det4_1234_0124 = m[A10]*Det3_234_124 - m[A11]*Det3_234_024
1709 + m[A12]*Det3_234_014 - m[A14]*Det3_234_012;
1710 G4double Det4_1234_0134 = m[A10]*Det3_234_134 - m[A11]*Det3_234_034
1711 + m[A13]*Det3_234_014 - m[A14]*Det3_234_013;
1712 G4double Det4_1234_0234 = m[A10]*Det3_234_234 - m[A12]*Det3_234_034
1713 + m[A13]*Det3_234_024 - m[A14]*Det3_234_023;
1714 G4double Det4_1234_1234 = m[A11]*Det3_234_234 - m[A12]*Det3_234_134
1715 + m[A13]*Det3_234_124 - m[A14]*Det3_234_123;
1716 G4double Det4_1235_0123 = m[A10]*Det3_235_123 - m[A11]*Det3_235_023
1717 + m[A12]*Det3_235_013 - m[A13]*Det3_235_012;
1718 G4double Det4_1235_0124 = m[A10]*Det3_235_124 - m[A11]*Det3_235_024
1719 + m[A12]*Det3_235_014 - m[A14]*Det3_235_012;
1720 G4double Det4_1235_0125 = m[A10]*Det3_235_125 - m[A11]*Det3_235_025
1721 + m[A12]*Det3_235_015 - m[A15]*Det3_235_012;
1722 G4double Det4_1235_0134 = m[A10]*Det3_235_134 - m[A11]*Det3_235_034
1723 + m[A13]*Det3_235_014 - m[A14]*Det3_235_013;
1724 G4double Det4_1235_0135 = m[A10]*Det3_235_135 - m[A11]*Det3_235_035
1725 + m[A13]*Det3_235_015 - m[A15]*Det3_235_013;
1726 G4double Det4_1235_0234 = m[A10]*Det3_235_234 - m[A12]*Det3_235_034
1727 + m[A13]*Det3_235_024 - m[A14]*Det3_235_023;
1728 G4double Det4_1235_0235 = m[A10]*Det3_235_235 - m[A12]*Det3_235_035
1729 + m[A13]*Det3_235_025 - m[A15]*Det3_235_023;
1730 G4double Det4_1235_1234 = m[A11]*Det3_235_234 - m[A12]*Det3_235_134
1731 + m[A13]*Det3_235_124 - m[A14]*Det3_235_123;
1732 G4double Det4_1235_1235 = m[A11]*Det3_235_235 - m[A12]*Det3_235_135
1733 + m[A13]*Det3_235_125 - m[A15]*Det3_235_123;
1734 G4double Det4_1245_0123 = m[A10]*Det3_245_123 - m[A11]*Det3_245_023
1735 + m[A12]*Det3_245_013 - m[A13]*Det3_245_012;
1736 G4double Det4_1245_0124 = m[A10]*Det3_245_124 - m[A11]*Det3_245_024
1737 + m[A12]*Det3_245_014 - m[A14]*Det3_245_012;
1738 G4double Det4_1245_0125 = m[A10]*Det3_245_125 - m[A11]*Det3_245_025
1739 + m[A12]*Det3_245_015 - m[A15]*Det3_245_012;
1740 G4double Det4_1245_0134 = m[A10]*Det3_245_134 - m[A11]*Det3_245_034
1741 + m[A13]*Det3_245_014 - m[A14]*Det3_245_013;
1742 G4double Det4_1245_0135 = m[A10]*Det3_245_135 - m[A11]*Det3_245_035
1743 + m[A13]*Det3_245_015 - m[A15]*Det3_245_013;
1744 G4double Det4_1245_0145 = m[A10]*Det3_245_145 - m[A11]*Det3_245_045
1745 + m[A14]*Det3_245_015 - m[A15]*Det3_245_014;
1746 G4double Det4_1245_0234 = m[A10]*Det3_245_234 - m[A12]*Det3_245_034
1747 + m[A13]*Det3_245_024 - m[A14]*Det3_245_023;
1748 G4double Det4_1245_0235 = m[A10]*Det3_245_235 - m[A12]*Det3_245_035
1749 + m[A13]*Det3_245_025 - m[A15]*Det3_245_023;
1750 G4double Det4_1245_0245 = m[A10]*Det3_245_245 - m[A12]*Det3_245_045
1751 + m[A14]*Det3_245_025 - m[A15]*Det3_245_024;
1752 G4double Det4_1245_1234 = m[A11]*Det3_245_234 - m[A12]*Det3_245_134
1753 + m[A13]*Det3_245_124 - m[A14]*Det3_245_123;
1754 G4double Det4_1245_1235 = m[A11]*Det3_245_235 - m[A12]*Det3_245_135
1755 + m[A13]*Det3_245_125 - m[A15]*Det3_245_123;
1756 G4double Det4_1245_1245 = m[A11]*Det3_245_245 - m[A12]*Det3_245_145
1757 + m[A14]*Det3_245_125 - m[A15]*Det3_245_124;
1758 G4double Det4_1345_0123 = m[A10]*Det3_345_123 - m[A11]*Det3_345_023
1759 + m[A12]*Det3_345_013 - m[A13]*Det3_345_012;
1760 G4double Det4_1345_0124 = m[A10]*Det3_345_124 - m[A11]*Det3_345_024
1761 + m[A12]*Det3_345_014 - m[A14]*Det3_345_012;
1762 G4double Det4_1345_0125 = m[A10]*Det3_345_125 - m[A11]*Det3_345_025
1763 + m[A12]*Det3_345_015 - m[A15]*Det3_345_012;
1764 G4double Det4_1345_0134 = m[A10]*Det3_345_134 - m[A11]*Det3_345_034
1765 + m[A13]*Det3_345_014 - m[A14]*Det3_345_013;
1766 G4double Det4_1345_0135 = m[A10]*Det3_345_135 - m[A11]*Det3_345_035
1767 + m[A13]*Det3_345_015 - m[A15]*Det3_345_013;
1768 G4double Det4_1345_0145 = m[A10]*Det3_345_145 - m[A11]*Det3_345_045
1769 + m[A14]*Det3_345_015 - m[A15]*Det3_345_014;
1770 G4double Det4_1345_0234 = m[A10]*Det3_345_234 - m[A12]*Det3_345_034
1771 + m[A13]*Det3_345_024 - m[A14]*Det3_345_023;
1772 G4double Det4_1345_0235 = m[A10]*Det3_345_235 - m[A12]*Det3_345_035
1773 + m[A13]*Det3_345_025 - m[A15]*Det3_345_023;
1774 G4double Det4_1345_0245 = m[A10]*Det3_345_245 - m[A12]*Det3_345_045
1775 + m[A14]*Det3_345_025 - m[A15]*Det3_345_024;
1776 G4double Det4_1345_0345 = m[A10]*Det3_345_345 - m[A13]*Det3_345_045
1777 + m[A14]*Det3_345_035 - m[A15]*Det3_345_034;
1778 G4double Det4_1345_1234 = m[A11]*Det3_345_234 - m[A12]*Det3_345_134
1779 + m[A13]*Det3_345_124 - m[A14]*Det3_345_123;
1780 G4double Det4_1345_1235 = m[A11]*Det3_345_235 - m[A12]*Det3_345_135
1781 + m[A13]*Det3_345_125 - m[A15]*Det3_345_123;
1782 G4double Det4_1345_1245 = m[A11]*Det3_345_245 - m[A12]*Det3_345_145
1783 + m[A14]*Det3_345_125 - m[A15]*Det3_345_124;
1784 G4double Det4_1345_1345 = m[A11]*Det3_345_345 - m[A13]*Det3_345_145
1785 + m[A14]*Det3_345_135 - m[A15]*Det3_345_134;
1786 G4double Det4_2345_0123 = m[A20]*Det3_345_123 - m[A21]*Det3_345_023
1787 + m[A22]*Det3_345_013 - m[A23]*Det3_345_012;
1788 G4double Det4_2345_0124 = m[A20]*Det3_345_124 - m[A21]*Det3_345_024
1789 + m[A22]*Det3_345_014 - m[A24]*Det3_345_012;
1790 G4double Det4_2345_0125 = m[A20]*Det3_345_125 - m[A21]*Det3_345_025
1791 + m[A22]*Det3_345_015 - m[A25]*Det3_345_012;
1792 G4double Det4_2345_0134 = m[A20]*Det3_345_134 - m[A21]*Det3_345_034
1793 + m[A23]*Det3_345_014 - m[A24]*Det3_345_013;
1794 G4double Det4_2345_0135 = m[A20]*Det3_345_135 - m[A21]*Det3_345_035
1795 + m[A23]*Det3_345_015 - m[A25]*Det3_345_013;
1796 G4double Det4_2345_0145 = m[A20]*Det3_345_145 - m[A21]*Det3_345_045
1797 + m[A24]*Det3_345_015 - m[A25]*Det3_345_014;
1798 G4double Det4_2345_0234 = m[A20]*Det3_345_234 - m[A22]*Det3_345_034
1799 + m[A23]*Det3_345_024 - m[A24]*Det3_345_023;
1800 G4double Det4_2345_0235 = m[A20]*Det3_345_235 - m[A22]*Det3_345_035
1801 + m[A23]*Det3_345_025 - m[A25]*Det3_345_023;
1802 G4double Det4_2345_0245 = m[A20]*Det3_345_245 - m[A22]*Det3_345_045
1803 + m[A24]*Det3_345_025 - m[A25]*Det3_345_024;
1804 G4double Det4_2345_0345 = m[A20]*Det3_345_345 - m[A23]*Det3_345_045
1805 + m[A24]*Det3_345_035 - m[A25]*Det3_345_034;
1806 G4double Det4_2345_1234 = m[A21]*Det3_345_234 - m[A22]*Det3_345_134
1807 + m[A23]*Det3_345_124 - m[A24]*Det3_345_123;
1808 G4double Det4_2345_1235 = m[A21]*Det3_345_235 - m[A22]*Det3_345_135
1809 + m[A23]*Det3_345_125 - m[A25]*Det3_345_123;
1810 G4double Det4_2345_1245 = m[A21]*Det3_345_245 - m[A22]*Det3_345_145
1811 + m[A24]*Det3_345_125 - m[A25]*Det3_345_124;
1812 G4double Det4_2345_1345 = m[A21]*Det3_345_345 - m[A23]*Det3_345_145
1813 + m[A24]*Det3_345_135 - m[A25]*Det3_345_134;
1814 G4double Det4_2345_2345 = m[A22]*Det3_345_345 - m[A23]*Det3_345_245
1815 + m[A24]*Det3_345_235 - m[A25]*Det3_345_234;
1816
1817 // Find all NECESSARY 5x5 dets: (19 of them)
1818
1819 G4double Det5_01234_01234 = m[A00]*Det4_1234_1234 - m[A01]*Det4_1234_0234
1820 + m[A02]*Det4_1234_0134 - m[A03]*Det4_1234_0124 + m[A04]*Det4_1234_0123;
1821 G4double Det5_01235_01234 = m[A00]*Det4_1235_1234 - m[A01]*Det4_1235_0234
1822 + m[A02]*Det4_1235_0134 - m[A03]*Det4_1235_0124 + m[A04]*Det4_1235_0123;
1823 G4double Det5_01235_01235 = m[A00]*Det4_1235_1235 - m[A01]*Det4_1235_0235
1824 + m[A02]*Det4_1235_0135 - m[A03]*Det4_1235_0125 + m[A05]*Det4_1235_0123;
1825 G4double Det5_01245_01234 = m[A00]*Det4_1245_1234 - m[A01]*Det4_1245_0234
1826 + m[A02]*Det4_1245_0134 - m[A03]*Det4_1245_0124 + m[A04]*Det4_1245_0123;
1827 G4double Det5_01245_01235 = m[A00]*Det4_1245_1235 - m[A01]*Det4_1245_0235
1828 + m[A02]*Det4_1245_0135 - m[A03]*Det4_1245_0125 + m[A05]*Det4_1245_0123;
1829 G4double Det5_01245_01245 = m[A00]*Det4_1245_1245 - m[A01]*Det4_1245_0245
1830 + m[A02]*Det4_1245_0145 - m[A04]*Det4_1245_0125 + m[A05]*Det4_1245_0124;
1831 G4double Det5_01345_01234 = m[A00]*Det4_1345_1234 - m[A01]*Det4_1345_0234
1832 + m[A02]*Det4_1345_0134 - m[A03]*Det4_1345_0124 + m[A04]*Det4_1345_0123;
1833 G4double Det5_01345_01235 = m[A00]*Det4_1345_1235 - m[A01]*Det4_1345_0235
1834 + m[A02]*Det4_1345_0135 - m[A03]*Det4_1345_0125 + m[A05]*Det4_1345_0123;
1835 G4double Det5_01345_01245 = m[A00]*Det4_1345_1245 - m[A01]*Det4_1345_0245
1836 + m[A02]*Det4_1345_0145 - m[A04]*Det4_1345_0125 + m[A05]*Det4_1345_0124;
1837 G4double Det5_01345_01345 = m[A00]*Det4_1345_1345 - m[A01]*Det4_1345_0345
1838 + m[A03]*Det4_1345_0145 - m[A04]*Det4_1345_0135 + m[A05]*Det4_1345_0134;
1839 G4double Det5_02345_01234 = m[A00]*Det4_2345_1234 - m[A01]*Det4_2345_0234
1840 + m[A02]*Det4_2345_0134 - m[A03]*Det4_2345_0124 + m[A04]*Det4_2345_0123;
1841 G4double Det5_02345_01235 = m[A00]*Det4_2345_1235 - m[A01]*Det4_2345_0235
1842 + m[A02]*Det4_2345_0135 - m[A03]*Det4_2345_0125 + m[A05]*Det4_2345_0123;
1843 G4double Det5_02345_01245 = m[A00]*Det4_2345_1245 - m[A01]*Det4_2345_0245
1844 + m[A02]*Det4_2345_0145 - m[A04]*Det4_2345_0125 + m[A05]*Det4_2345_0124;
1845 G4double Det5_02345_01345 = m[A00]*Det4_2345_1345 - m[A01]*Det4_2345_0345
1846 + m[A03]*Det4_2345_0145 - m[A04]*Det4_2345_0135 + m[A05]*Det4_2345_0134;
1847 G4double Det5_02345_02345 = m[A00]*Det4_2345_2345 - m[A02]*Det4_2345_0345
1848 + m[A03]*Det4_2345_0245 - m[A04]*Det4_2345_0235 + m[A05]*Det4_2345_0234;
1849 G4double Det5_12345_01234 = m[A10]*Det4_2345_1234 - m[A11]*Det4_2345_0234
1850 + m[A12]*Det4_2345_0134 - m[A13]*Det4_2345_0124 + m[A14]*Det4_2345_0123;
1851 G4double Det5_12345_01235 = m[A10]*Det4_2345_1235 - m[A11]*Det4_2345_0235
1852 + m[A12]*Det4_2345_0135 - m[A13]*Det4_2345_0125 + m[A15]*Det4_2345_0123;
1853 G4double Det5_12345_01245 = m[A10]*Det4_2345_1245 - m[A11]*Det4_2345_0245
1854 + m[A12]*Det4_2345_0145 - m[A14]*Det4_2345_0125 + m[A15]*Det4_2345_0124;
1855 G4double Det5_12345_01345 = m[A10]*Det4_2345_1345 - m[A11]*Det4_2345_0345
1856 + m[A13]*Det4_2345_0145 - m[A14]*Det4_2345_0135 + m[A15]*Det4_2345_0134;
1857 G4double Det5_12345_02345 = m[A10]*Det4_2345_2345 - m[A12]*Det4_2345_0345
1858 + m[A13]*Det4_2345_0245 - m[A14]*Det4_2345_0235 + m[A15]*Det4_2345_0234;
1859 G4double Det5_12345_12345 = m[A11]*Det4_2345_2345 - m[A12]*Det4_2345_1345
1860 + m[A13]*Det4_2345_1245 - m[A14]*Det4_2345_1235 + m[A15]*Det4_2345_1234;
1861
1862 // Find the determinant
1863
1864 G4double det = m[A00]*Det5_12345_12345
1865 - m[A01]*Det5_12345_02345
1866 + m[A02]*Det5_12345_01345
1867 - m[A03]*Det5_12345_01245
1868 + m[A04]*Det5_12345_01235
1869 - m[A05]*Det5_12345_01234;
1870
1871 if ( det == 0 )
1872 {
1873 ifail = 1;
1874 return;
1875 }
1876
1877 G4double oneOverDet = 1.0/det;
1878 G4double mn1OverDet = - oneOverDet;
1879
1880 m[A00] = Det5_12345_12345*oneOverDet;
1881 m[A01] = Det5_12345_02345*mn1OverDet;
1882 m[A02] = Det5_12345_01345*oneOverDet;
1883 m[A03] = Det5_12345_01245*mn1OverDet;
1884 m[A04] = Det5_12345_01235*oneOverDet;
1885 m[A05] = Det5_12345_01234*mn1OverDet;
1886
1887 m[A11] = Det5_02345_02345*oneOverDet;
1888 m[A12] = Det5_02345_01345*mn1OverDet;
1889 m[A13] = Det5_02345_01245*oneOverDet;
1890 m[A14] = Det5_02345_01235*mn1OverDet;
1891 m[A15] = Det5_02345_01234*oneOverDet;
1892
1893 m[A22] = Det5_01345_01345*oneOverDet;
1894 m[A23] = Det5_01345_01245*mn1OverDet;
1895 m[A24] = Det5_01345_01235*oneOverDet;
1896 m[A25] = Det5_01345_01234*mn1OverDet;
1897
1898 m[A33] = Det5_01245_01245*oneOverDet;
1899 m[A34] = Det5_01245_01235*mn1OverDet;
1900 m[A35] = Det5_01245_01234*oneOverDet;
1901
1902 m[A44] = Det5_01235_01235*oneOverDet;
1903 m[A45] = Det5_01235_01234*mn1OverDet;
1904
1905 m[A55] = Det5_01234_01234*oneOverDet;
1906
1907 return;
1908}
1909
1910void G4ErrorSymMatrix::invertCholesky5 (G4int & ifail)
1911{
1912
1913 // Invert by
1914 //
1915 // a) decomposing M = G*G^T with G lower triangular
1916 // (if M is not positive definite this will fail, leaving this unchanged)
1917 // b) inverting G to form H
1918 // c) multiplying H^T * H to get M^-1.
1919 //
1920 // If the matrix is pos. def. it is inverted and 1 is returned.
1921 // If the matrix is not pos. def. it remains unaltered and 0 is returned.
1922
1923 G4double h10; // below-diagonal elements of H
1924 G4double h20, h21;
1925 G4double h30, h31, h32;
1926 G4double h40, h41, h42, h43;
1927
1928 G4double h00, h11, h22, h33, h44; // 1/diagonal elements of G =
1929 // diagonal elements of H
1930
1931 G4double g10; // below-diagonal elements of G
1932 G4double g20, g21;
1933 G4double g30, g31, g32;
1934 G4double g40, g41, g42, g43;
1935
1936 ifail = 1; // We start by assuing we won't succeed...
1937
1938 // Form G -- compute diagonal members of H directly rather than of G
1939 //-------
1940
1941 // Scale first column by 1/sqrt(A00)
1942
1943 h00 = m[A00];
1944 if (h00 <= 0) { return; }
1945 h00 = 1.0 / std::sqrt(h00);
1946
1947 g10 = m[A10] * h00;
1948 g20 = m[A20] * h00;
1949 g30 = m[A30] * h00;
1950 g40 = m[A40] * h00;
1951
1952 // Form G11 (actually, just h11)
1953
1954 h11 = m[A11] - (g10 * g10);
1955 if (h11 <= 0) { return; }
1956 h11 = 1.0 / std::sqrt(h11);
1957
1958 // Subtract inter-column column dot products from rest of column 1 and
1959 // scale to get column 1 of G
1960
1961 g21 = (m[A21] - (g10 * g20)) * h11;
1962 g31 = (m[A31] - (g10 * g30)) * h11;
1963 g41 = (m[A41] - (g10 * g40)) * h11;
1964
1965 // Form G22 (actually, just h22)
1966
1967 h22 = m[A22] - (g20 * g20) - (g21 * g21);
1968 if (h22 <= 0) { return; }
1969 h22 = 1.0 / std::sqrt(h22);
1970
1971 // Subtract inter-column column dot products from rest of column 2 and
1972 // scale to get column 2 of G
1973
1974 g32 = (m[A32] - (g20 * g30) - (g21 * g31)) * h22;
1975 g42 = (m[A42] - (g20 * g40) - (g21 * g41)) * h22;
1976
1977 // Form G33 (actually, just h33)
1978
1979 h33 = m[A33] - (g30 * g30) - (g31 * g31) - (g32 * g32);
1980 if (h33 <= 0) { return; }
1981 h33 = 1.0 / std::sqrt(h33);
1982
1983 // Subtract inter-column column dot product from A43 and scale to get G43
1984
1985 g43 = (m[A43] - (g30 * g40) - (g31 * g41) - (g32 * g42)) * h33;
1986
1987 // Finally form h44 - if this is possible inversion succeeds
1988
1989 h44 = m[A44] - (g40 * g40) - (g41 * g41) - (g42 * g42) - (g43 * g43);
1990 if (h44 <= 0) { return; }
1991 h44 = 1.0 / std::sqrt(h44);
1992
1993 // Form H = 1/G -- diagonal members of H are already correct
1994 //-------------
1995
1996 // The order here is dictated by speed considerations
1997
1998 h43 = -h33 * g43 * h44;
1999 h32 = -h22 * g32 * h33;
2000 h42 = -h22 * (g32 * h43 + g42 * h44);
2001 h21 = -h11 * g21 * h22;
2002 h31 = -h11 * (g21 * h32 + g31 * h33);
2003 h41 = -h11 * (g21 * h42 + g31 * h43 + g41 * h44);
2004 h10 = -h00 * g10 * h11;
2005 h20 = -h00 * (g10 * h21 + g20 * h22);
2006 h30 = -h00 * (g10 * h31 + g20 * h32 + g30 * h33);
2007 h40 = -h00 * (g10 * h41 + g20 * h42 + g30 * h43 + g40 * h44);
2008
2009 // Change this to its inverse = H^T*H
2010 //------------------------------------
2011
2012 m[A00] = h00 * h00 + h10 * h10 + h20 * h20 + h30 * h30 + h40 * h40;
2013 m[A01] = h10 * h11 + h20 * h21 + h30 * h31 + h40 * h41;
2014 m[A11] = h11 * h11 + h21 * h21 + h31 * h31 + h41 * h41;
2015 m[A02] = h20 * h22 + h30 * h32 + h40 * h42;
2016 m[A12] = h21 * h22 + h31 * h32 + h41 * h42;
2017 m[A22] = h22 * h22 + h32 * h32 + h42 * h42;
2018 m[A03] = h30 * h33 + h40 * h43;
2019 m[A13] = h31 * h33 + h41 * h43;
2020 m[A23] = h32 * h33 + h42 * h43;
2021 m[A33] = h33 * h33 + h43 * h43;
2022 m[A04] = h40 * h44;
2023 m[A14] = h41 * h44;
2024 m[A24] = h42 * h44;
2025 m[A34] = h43 * h44;
2026 m[A44] = h44 * h44;
2027
2028 ifail = 0;
2029 return;
2030}
2031
2032void G4ErrorSymMatrix::invertCholesky6 (G4int & ifail)
2033{
2034 // Invert by
2035 //
2036 // a) decomposing M = G*G^T with G lower triangular
2037 // (if M is not positive definite this will fail, leaving this unchanged)
2038 // b) inverting G to form H
2039 // c) multiplying H^T * H to get M^-1.
2040 //
2041 // If the matrix is pos. def. it is inverted and 1 is returned.
2042 // If the matrix is not pos. def. it remains unaltered and 0 is returned.
2043
2044 G4double h10; // below-diagonal elements of H
2045 G4double h20, h21;
2046 G4double h30, h31, h32;
2047 G4double h40, h41, h42, h43;
2048 G4double h50, h51, h52, h53, h54;
2049
2050 G4double h00, h11, h22, h33, h44, h55; // 1/diagonal elements of G =
2051 // diagonal elements of H
2052
2053 G4double g10; // below-diagonal elements of G
2054 G4double g20, g21;
2055 G4double g30, g31, g32;
2056 G4double g40, g41, g42, g43;
2057 G4double g50, g51, g52, g53, g54;
2058
2059 ifail = 1; // We start by assuing we won't succeed...
2060
2061 // Form G -- compute diagonal members of H directly rather than of G
2062 //-------
2063
2064 // Scale first column by 1/sqrt(A00)
2065
2066 h00 = m[A00];
2067 if (h00 <= 0) { return; }
2068 h00 = 1.0 / std::sqrt(h00);
2069
2070 g10 = m[A10] * h00;
2071 g20 = m[A20] * h00;
2072 g30 = m[A30] * h00;
2073 g40 = m[A40] * h00;
2074 g50 = m[A50] * h00;
2075
2076 // Form G11 (actually, just h11)
2077
2078 h11 = m[A11] - (g10 * g10);
2079 if (h11 <= 0) { return; }
2080 h11 = 1.0 / std::sqrt(h11);
2081
2082 // Subtract inter-column column dot products from rest of column 1 and
2083 // scale to get column 1 of G
2084
2085 g21 = (m[A21] - (g10 * g20)) * h11;
2086 g31 = (m[A31] - (g10 * g30)) * h11;
2087 g41 = (m[A41] - (g10 * g40)) * h11;
2088 g51 = (m[A51] - (g10 * g50)) * h11;
2089
2090 // Form G22 (actually, just h22)
2091
2092 h22 = m[A22] - (g20 * g20) - (g21 * g21);
2093 if (h22 <= 0) { return; }
2094 h22 = 1.0 / std::sqrt(h22);
2095
2096 // Subtract inter-column column dot products from rest of column 2 and
2097 // scale to get column 2 of G
2098
2099 g32 = (m[A32] - (g20 * g30) - (g21 * g31)) * h22;
2100 g42 = (m[A42] - (g20 * g40) - (g21 * g41)) * h22;
2101 g52 = (m[A52] - (g20 * g50) - (g21 * g51)) * h22;
2102
2103 // Form G33 (actually, just h33)
2104
2105 h33 = m[A33] - (g30 * g30) - (g31 * g31) - (g32 * g32);
2106 if (h33 <= 0) { return; }
2107 h33 = 1.0 / std::sqrt(h33);
2108
2109 // Subtract inter-column column dot products from rest of column 3 and
2110 // scale to get column 3 of G
2111
2112 g43 = (m[A43] - (g30 * g40) - (g31 * g41) - (g32 * g42)) * h33;
2113 g53 = (m[A53] - (g30 * g50) - (g31 * g51) - (g32 * g52)) * h33;
2114
2115 // Form G44 (actually, just h44)
2116
2117 h44 = m[A44] - (g40 * g40) - (g41 * g41) - (g42 * g42) - (g43 * g43);
2118 if (h44 <= 0) { return; }
2119 h44 = 1.0 / std::sqrt(h44);
2120
2121 // Subtract inter-column column dot product from M54 and scale to get G54
2122
2123 g54 = (m[A54] - (g40 * g50) - (g41 * g51) - (g42 * g52) - (g43 * g53)) * h44;
2124
2125 // Finally form h55 - if this is possible inversion succeeds
2126
2127 h55 = m[A55] - (g50*g50) - (g51*g51) - (g52*g52) - (g53*g53) - (g54*g54);
2128 if (h55 <= 0) { return; }
2129 h55 = 1.0 / std::sqrt(h55);
2130
2131 // Form H = 1/G -- diagonal members of H are already correct
2132 //-------------
2133
2134 // The order here is dictated by speed considerations
2135
2136 h54 = -h44 * g54 * h55;
2137 h43 = -h33 * g43 * h44;
2138 h53 = -h33 * (g43 * h54 + g53 * h55);
2139 h32 = -h22 * g32 * h33;
2140 h42 = -h22 * (g32 * h43 + g42 * h44);
2141 h52 = -h22 * (g32 * h53 + g42 * h54 + g52 * h55);
2142 h21 = -h11 * g21 * h22;
2143 h31 = -h11 * (g21 * h32 + g31 * h33);
2144 h41 = -h11 * (g21 * h42 + g31 * h43 + g41 * h44);
2145 h51 = -h11 * (g21 * h52 + g31 * h53 + g41 * h54 + g51 * h55);
2146 h10 = -h00 * g10 * h11;
2147 h20 = -h00 * (g10 * h21 + g20 * h22);
2148 h30 = -h00 * (g10 * h31 + g20 * h32 + g30 * h33);
2149 h40 = -h00 * (g10 * h41 + g20 * h42 + g30 * h43 + g40 * h44);
2150 h50 = -h00 * (g10 * h51 + g20 * h52 + g30 * h53 + g40 * h54 + g50 * h55);
2151
2152 // Change this to its inverse = H^T*H
2153 //------------------------------------
2154
2155 m[A00] = h00 * h00 + h10 * h10 + h20 * h20 + h30 * h30 + h40 * h40 + h50*h50;
2156 m[A01] = h10 * h11 + h20 * h21 + h30 * h31 + h40 * h41 + h50 * h51;
2157 m[A11] = h11 * h11 + h21 * h21 + h31 * h31 + h41 * h41 + h51 * h51;
2158 m[A02] = h20 * h22 + h30 * h32 + h40 * h42 + h50 * h52;
2159 m[A12] = h21 * h22 + h31 * h32 + h41 * h42 + h51 * h52;
2160 m[A22] = h22 * h22 + h32 * h32 + h42 * h42 + h52 * h52;
2161 m[A03] = h30 * h33 + h40 * h43 + h50 * h53;
2162 m[A13] = h31 * h33 + h41 * h43 + h51 * h53;
2163 m[A23] = h32 * h33 + h42 * h43 + h52 * h53;
2164 m[A33] = h33 * h33 + h43 * h43 + h53 * h53;
2165 m[A04] = h40 * h44 + h50 * h54;
2166 m[A14] = h41 * h44 + h51 * h54;
2167 m[A24] = h42 * h44 + h52 * h54;
2168 m[A34] = h43 * h44 + h53 * h54;
2169 m[A44] = h44 * h44 + h54 * h54;
2170 m[A05] = h50 * h55;
2171 m[A15] = h51 * h55;
2172 m[A25] = h52 * h55;
2173 m[A35] = h53 * h55;
2174 m[A45] = h54 * h55;
2175 m[A55] = h55 * h55;
2176
2177 ifail = 0;
2178 return;
2179}
2180
2181void G4ErrorSymMatrix::invert4 (G4int & ifail)
2182{
2183 ifail = 0;
2184
2185 // Find all NECESSARY 2x2 dets: (14 of them)
2186
2187 G4double Det2_12_01 = m[A10]*m[A21] - m[A11]*m[A20];
2188 G4double Det2_12_02 = m[A10]*m[A22] - m[A12]*m[A20];
2189 G4double Det2_12_12 = m[A11]*m[A22] - m[A12]*m[A21];
2190 G4double Det2_13_01 = m[A10]*m[A31] - m[A11]*m[A30];
2191 G4double Det2_13_02 = m[A10]*m[A32] - m[A12]*m[A30];
2192 G4double Det2_13_03 = m[A10]*m[A33] - m[A13]*m[A30];
2193 G4double Det2_13_12 = m[A11]*m[A32] - m[A12]*m[A31];
2194 G4double Det2_13_13 = m[A11]*m[A33] - m[A13]*m[A31];
2195 G4double Det2_23_01 = m[A20]*m[A31] - m[A21]*m[A30];
2196 G4double Det2_23_02 = m[A20]*m[A32] - m[A22]*m[A30];
2197 G4double Det2_23_03 = m[A20]*m[A33] - m[A23]*m[A30];
2198 G4double Det2_23_12 = m[A21]*m[A32] - m[A22]*m[A31];
2199 G4double Det2_23_13 = m[A21]*m[A33] - m[A23]*m[A31];
2200 G4double Det2_23_23 = m[A22]*m[A33] - m[A23]*m[A32];
2201
2202 // Find all NECESSARY 3x3 dets: (10 of them)
2203
2204 G4double Det3_012_012 = m[A00]*Det2_12_12 - m[A01]*Det2_12_02
2205 + m[A02]*Det2_12_01;
2206 G4double Det3_013_012 = m[A00]*Det2_13_12 - m[A01]*Det2_13_02
2207 + m[A02]*Det2_13_01;
2208 G4double Det3_013_013 = m[A00]*Det2_13_13 - m[A01]*Det2_13_03
2209 + m[A03]*Det2_13_01;
2210 G4double Det3_023_012 = m[A00]*Det2_23_12 - m[A01]*Det2_23_02
2211 + m[A02]*Det2_23_01;
2212 G4double Det3_023_013 = m[A00]*Det2_23_13 - m[A01]*Det2_23_03
2213 + m[A03]*Det2_23_01;
2214 G4double Det3_023_023 = m[A00]*Det2_23_23 - m[A02]*Det2_23_03
2215 + m[A03]*Det2_23_02;
2216 G4double Det3_123_012 = m[A10]*Det2_23_12 - m[A11]*Det2_23_02
2217 + m[A12]*Det2_23_01;
2218 G4double Det3_123_013 = m[A10]*Det2_23_13 - m[A11]*Det2_23_03
2219 + m[A13]*Det2_23_01;
2220 G4double Det3_123_023 = m[A10]*Det2_23_23 - m[A12]*Det2_23_03
2221 + m[A13]*Det2_23_02;
2222 G4double Det3_123_123 = m[A11]*Det2_23_23 - m[A12]*Det2_23_13
2223 + m[A13]*Det2_23_12;
2224
2225 // Find the 4x4 det:
2226
2227 G4double det = m[A00]*Det3_123_123
2228 - m[A01]*Det3_123_023
2229 + m[A02]*Det3_123_013
2230 - m[A03]*Det3_123_012;
2231
2232 if ( det == 0 )
2233 {
2234 ifail = 1;
2235 return;
2236 }
2237
2238 G4double oneOverDet = 1.0/det;
2239 G4double mn1OverDet = - oneOverDet;
2240
2241 m[A00] = Det3_123_123 * oneOverDet;
2242 m[A01] = Det3_123_023 * mn1OverDet;
2243 m[A02] = Det3_123_013 * oneOverDet;
2244 m[A03] = Det3_123_012 * mn1OverDet;
2245
2246
2247 m[A11] = Det3_023_023 * oneOverDet;
2248 m[A12] = Det3_023_013 * mn1OverDet;
2249 m[A13] = Det3_023_012 * oneOverDet;
2250
2251 m[A22] = Det3_013_013 * oneOverDet;
2252 m[A23] = Det3_013_012 * mn1OverDet;
2253
2254 m[A33] = Det3_012_012 * oneOverDet;
2255
2256 return;
2257}
2258
2259void G4ErrorSymMatrix::invertHaywood4 (G4int & ifail)
2260{
2261 invert4(ifail); // For the 4x4 case, the method we use for invert is already
2262 // the Haywood method.
2263}
2264
Note: See TracBrowser for help on using the repository browser.