Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/error_propagation/src/G4ErrorSymMatrix.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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