4#ifndef ROOT_Math_MatrixInversion_icc
5#define ROOT_Math_MatrixInversion_icc
8#error "Do not use MatrixInversion.icc directly. #include \"Math/Dinv.h\" instead."
38template <
unsigned int idim,
unsigned int N>
71 pivIter piv = pivv.
begin();
74 value_type temp1, temp2;
76 value_type lambda,
sigma;
77 const value_type alpha = .6404;
87 for (i = 0; i < nrow; i++)
96 for (j=1; j < nrow; j+=
s)
98 mjj = rhs.
Array() + j*(j-1)/2 + j-1;
101 ip = rhs.
Array() + (j+1)*j/2 + j-1;
102 for (i=j+1; i <= nrow ; ip += i++)
103 if (std::abs(*ip) > lambda)
105 lambda = std::abs(*ip);
121 if (std::abs(*mjj) >= lambda*alpha)
129 ip = rhs.
Array() + pivrow*(pivrow-1)/2+j-1;
130 for (k=j; k < pivrow; k++)
132 if (std::abs(*ip) >
sigma)
133 sigma = std::abs(*ip);
137 if ( std::abs(*mjj) >= alpha * lambda * (lambda/
sigma) )
142 else if (std::abs(*(rhs.
Array()+pivrow*(pivrow-1)/2+pivrow-1))
156 temp2 = *mjj = 1.0f/ *mjj;
159 for (i=j+1; i <= nrow; i++)
161 temp1 = *(rhs.
Array() + i*(i-1)/2 + j-1) * temp2;
162 ip = rhs.
Array()+i*(i-1)/2+j;
163 for (k=j+1; k<=i; k++)
165 *ip -=
static_cast<T> ( temp1 * *(rhs.
Array() + k*(k-1)/2 + j-1) );
172 ip = rhs.
Array() + (j+1)*j/2 + j-1;
173 for (i=j+1; i <= nrow; ip += i++)
174 *ip *=
static_cast<T> ( temp2 );
182 ip = rhs.
Array() + pivrow*(pivrow-1)/2 + j;
183 for (i=j+1; i < pivrow; i++, ip++)
185 temp1 = *(rhs.
Array() + i*(i-1)/2 + j-1);
186 *(rhs.
Array() + i*(i-1)/2 + j-1)= *ip;
187 *ip =
static_cast<T> ( temp1 );
190 *mjj = *(rhs.
Array()+pivrow*(pivrow-1)/2+pivrow-1);
191 *(rhs.
Array()+pivrow*(pivrow-1)/2+pivrow-1) =
static_cast<T> (temp1 );
192 ip = rhs.
Array() + (pivrow+1)*pivrow/2 + j-1;
194 for (i = pivrow+1; i <= nrow; ip += i,
iq += i++)
198 *ip =
static_cast<T>( temp1 );
206 temp2 = *mjj = 1.0f / *mjj;
209 for (i = j+1; i <= nrow; i++)
211 temp1 = *(rhs.
Array() + i*(i-1)/2 + j-1) * temp2;
212 ip = rhs.
Array()+i*(i-1)/2+j;
213 for (k=j+1; k<=i; k++)
215 *ip -=
static_cast<T> (temp1 * *(rhs.
Array() + k*(k-1)/2 + j-1) );
222 ip = rhs.
Array() + (j+1)*j/2 + j-1;
223 for (i=j+1; i<=nrow; ip += i++)
224 *ip *=
static_cast<T>( temp2 );
235 ip = rhs.
Array() + pivrow*(pivrow-1)/2 + j+1;
236 for (i=j+2; i < pivrow; i++, ip++)
238 temp1 = *(rhs.
Array() + i*(i-1)/2 + j);
239 *(rhs.
Array() + i*(i-1)/2 + j) = *ip;
240 *ip =
static_cast<T>( temp1 );
242 temp1 = *(mjj + j + 1);
244 *(rhs.
Array() + pivrow*(pivrow-1)/2 + pivrow-1);
245 *(rhs.
Array() + pivrow*(pivrow-1)/2 + pivrow-1) =
static_cast<T>( temp1 );
247 *(mjj + j) = *(rhs.
Array() + pivrow*(pivrow-1)/2 + j-1);
248 *(rhs.
Array() + pivrow*(pivrow-1)/2 + j-1) =
static_cast<T>( temp1 );
249 ip = rhs.
Array() + (pivrow+1)*pivrow/2 + j;
250 iq = ip + pivrow-(j+1);
251 for (i = pivrow+1; i <= nrow; ip += i,
iq += i++)
255 *ip =
static_cast<T>( temp1 );
259 temp2 = *mjj * *(mjj + j + 1) - *(mjj + j) * *(mjj + j);
262 <<
"SymMatrix::bunch_invert: error in pivot choice"
268 *mjj =
static_cast<T>( *(mjj + j + 1) * temp2 );
269 *(mjj + j + 1) =
static_cast<T>( temp1 * temp2 );
270 *(mjj + j) =
static_cast<T>( - *(mjj + j) * temp2 );
275 for (i=j+2; i <= nrow ; i++)
277 ip = rhs.
Array() + i*(i-1)/2 + j-1;
278 temp1 = *ip * *mjj + *(ip + 1) * *(mjj + j);
281 temp2 = *ip * *(mjj + j) + *(ip + 1) * *(mjj + j + 1);
284 for (k = j+2; k <= i ; k++)
286 ip = rhs.
Array() + i*(i-1)/2 + k-1;
287 iq = rhs.
Array() + k*(k-1)/2 + j-1;
288 *ip -=
static_cast<T>( temp1 * *
iq + temp2 * *(
iq+1) );
294 for (i=j+2; i <= nrow ; i++)
296 ip = rhs.
Array() + i*(i-1)/2 + j-1;
297 temp1 = *ip * *mjj + *(ip+1) * *(mjj + j);
300 *(ip+1) = *ip * *(mjj + j)
301 + *(ip+1) * *(mjj + j + 1);
304 *ip =
static_cast<T>( temp1 );
313 mjj = rhs.
Array() + j*(j-1)/2 + j-1;
325 for (j = nrow ; j >= 1 ; j -=
s)
327 mjj = rhs.
Array() + j*(j-1)/2 + j-1;
333 ip = rhs.
Array() + (j+1)*j/2 + j-1;
334 for (i=0; i < nrow-j; ip += 1+j+i++)
336 for (i=j+1; i<=nrow ; i++)
339 ip = rhs.
Array() + i*(i-1)/2 + j;
340 for (k=0; k <= i-j-1; k++)
341 temp2 += *ip++ *
x[k];
342 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
344 *(rhs.
Array()+ i*(i-1)/2 + j-1) =
static_cast<T>( -temp2 );
347 ip = rhs.
Array() + (j+1)*j/2 + j-1;
348 for (k=0; k < nrow-j; ip += 1+j+k++)
350 *mjj -=
static_cast<T>( temp2 );
356 std::cerr <<
"error in piv" << piv[j-1] << std::endl;
360 ip = rhs.
Array() + (j+1)*j/2 + j-1;
361 for (i=0; i < nrow-j; ip += 1+j+i++)
363 for (i=j+1; i<=nrow ; i++)
366 ip = rhs.
Array() + i*(i-1)/2 + j;
367 for (k=0; k <= i-j-1; k++)
368 temp2 += *ip++ *
x[k];
369 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
371 *(rhs.
Array()+ i*(i-1)/2 + j-1) =
static_cast<T>( -temp2 );
374 ip = rhs.
Array() + (j+1)*j/2 + j-1;
375 for (k=0; k < nrow-j; ip += 1+j+k++)
377 *mjj -=
static_cast<T>( temp2 );
379 ip = rhs.
Array() + (j+1)*j/2 + j-2;
380 for (i=j+1; i <= nrow; ip += i++)
381 temp2 += *ip * *(ip+1);
382 *(mjj-1) -=
static_cast<T>( temp2 );
383 ip = rhs.
Array() + (j+1)*j/2 + j-2;
384 for (i=0; i < nrow-j; ip += 1+j+i++)
386 for (i=j+1; i <= nrow ; i++)
389 ip = rhs.
Array() + i*(i-1)/2 + j;
390 for (k=0; k <= i-j-1; k++)
391 temp2 += *ip++ *
x[k];
392 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
394 *(rhs.
Array()+ i*(i-1)/2 + j-2)=
static_cast<T>( -temp2 );
397 ip = rhs.
Array() + (j+1)*j/2 + j-2;
398 for (k=0; k < nrow-j; ip += 1+j+k++)
400 *(mjj-j) -=
static_cast<T>( temp2 );
407 pivrow = (piv[j-1]==0)? -piv[j-2] : piv[j-1];
408 ip = rhs.
Array() + pivrow*(pivrow-1)/2 + j;
409 for (i=j+1;i < pivrow; i++, ip++)
411 temp1 = *(rhs.
Array() + i*(i-1)/2 + j-1);
412 *(rhs.
Array() + i*(i-1)/2 + j-1) = *ip;
413 *ip =
static_cast<T>( temp1 );
416 *mjj = *(rhs.
Array() + pivrow*(pivrow-1)/2 + pivrow-1);
417 *(rhs.
Array() + pivrow*(pivrow-1)/2 + pivrow-1) =
static_cast<T>( temp1 );
421 *(mjj-1) = *( rhs.
Array() + pivrow*(pivrow-1)/2 + j-2);
422 *( rhs.
Array() + pivrow*(pivrow-1)/2 + j-2) =
static_cast<T>( temp1 );
425 ip = rhs.
Array() + (pivrow+1)*pivrow/2 + j-1;
427 for (i = pivrow+1; i <= nrow; ip += i,
iq += i++)
431 *ip =
static_cast<T>(temp1);
445template <
unsigned int idim,
unsigned int n>
449 if (idim !=
n)
return -1;
455 typedef T value_type;
460 value_type g1 = 1.0e-19, g2 = 1.0e19;
466 const value_type
epsilon = 0.0;
472 int normal = 0, imposs = -1;
473 int jrange = 0, jover = 1, junder = -1;
478 mIter mj = rhs.
Array();
480 for (
unsigned int j=1;j<=
n;j++) {
482 p = (std::abs(*mjj));
484 mIter mij = mj +
n + j - 1;
485 for (
unsigned int i=j+1;i<=
n;i++) {
486 q = (std::abs(*(mij)));
504 mIter mkl = rhs.
Array() + (k-1)*
n;
505 for (
unsigned int l=1;
l<=
n;
l++) {
508 *(mkl++) =
static_cast<T>(tf);
511 ir[nxch] = (((j)<<12)+(k));
525 if (jfail == jrange) jfail = junder;
528 if (jfail==jrange) jfail = jover;
534 for (k=j+1;k<=
n;k++) {
538 mIter mik = rhs.
Array() + k - 1;
539 mIter mijp = rhs.
Array() + j;
542 for (
unsigned int i=1;i<j;i++) {
543 s11 += (*mik) * (*(mji++));
544 s12 += (*mijp) * (*(mki++));
550 *(mjk++) =
static_cast<T>( - s11 * (*mjj) );
551 *(mkjp) =
static_cast<T> ( -(((*(mjj+1)))*((*(mkjp-1)))+(s12)) );
559 if (nxch%2==1) det = -det;
560 if (jfail !=jrange) det = 0.0;
575template <
unsigned int idim,
unsigned int n>
582 typedef T value_type;
586 if (idim !=
n)
return -1;
592 mIter m11 = rhs.
Array();
596 *m21 = -(*m22) * (*m11) * (*m21);
599 mIter mi = rhs.
Array() + 2 *
n;
600 mIter mii= rhs.
Array() + 2 *
n + 2;
601 mIter mimim = rhs.
Array() +
n + 1;
602 for (
unsigned int i=3;i<=
n;i++) {
603 unsigned int im2 = i - 2;
604 mIter mj = rhs.
Array();
605 mIter mji = mj + i - 1;
607 for (
unsigned int j=1;j<=im2;j++) {
610 mIter mkj = mj + j - 1;
611 mIter mik = mi + j - 1;
613 mIter mkpi = mj +
n + i - 1;
614 for (
unsigned int k=j;k<=im2;k++) {
615 s31 += (*mkj) * (*(mik++));
616 s32 += (*(mjkp++)) * (*mkpi);
620 *mij =
static_cast<T>( -(*mii) * (((*(mij-
n)))*( (*(mii-1)))+(s31)) );
621 *mji =
static_cast<T> ( -s32 );
626 *(mii-1) = -(*mii) * (*mimim) * (*(mii-1));
627 *(mimim+1) = -(*(mimim+1));
633 mIter mi = rhs.
Array();
634 mIter mii = rhs.
Array();
635 for (
unsigned int i=1;i<
n;i++) {
636 unsigned int ni =
n - i;
639 for (
unsigned j=1; j<=i;j++) {
641 mIter mikj = mi +
n + j - 1;
642 mIter miik = mii + 1;
643 mIter min_end = mi +
n;
644 for (;miik<min_end;) {
645 s33 += (*mikj) * (*(miik++));
648 *(mij++) =
static_cast<T> ( s33 );
650 for (
unsigned j=1;j<=ni;j++) {
652 mIter miik = mii + j;
653 mIter mikij = mii + j *
n + j;
654 for (
unsigned int k=j;k<=ni;k++) {
655 s34 += *mikij * (*(miik++));
663 unsigned int nxch = ir[
n];
664 if (nxch==0)
return 0;
665 for (
unsigned int mm=1;
mm<=nxch;
mm++) {
666 unsigned int k = nxch -
mm + 1;
670 mIter mki = rhs.
Array() + i - 1;
671 mIter mkj = rhs.
Array() + j - 1;
672 for (k=1; k<=
n;k++) {
static void InvertBunchKaufman(MatRepSym< T, idim > &rhs, int &ifail)
Bunch-Kaufman method for inversion of symmetric matrices.
static int DfactMatrix(MatRepStd< T, idim, n > &rhs, T &det, unsigned int *work)
LU Factorization method for inversion of general square matrices (see implementation in Math/MatrixIn...
static int DfinvMatrix(MatRepStd< T, idim, n > &rhs, unsigned int *work)
LU inversion of general square matrices.
Expression wrapper class for Matrix objects.
MatRepSym Matrix storage representation for a symmetric matrix of dimension NxN This class is a templ...
SVector: a generic fixed size Vector class.
iterator begin()
STL iterator interface.
Namespace for new Math classes and functions.
Namespace for new ROOT classes and functions.
static constexpr double s
static constexpr double mm