4 #ifndef ROOT_Math_MatrixInversion_icc
5 #define ROOT_Math_MatrixInversion_icc
34 template <
unsigned int idim,
unsigned int N>
67 pivIter piv = pivv.
begin();
70 value_type temp1, temp2;
72 value_type lambda, sigma;
73 const value_type alpha = .6404;
83 for (i = 0; i < nrow; i++)
92 for (j=1; j < nrow; j+=s)
94 mjj = rhs.
Array() + j*(j-1)/2 + j-1;
97 ip = rhs.
Array() + (j+1)*j/2 + j-1;
98 for (i=j+1; i <= nrow ; ip += i++)
125 ip = rhs.
Array() + pivrow*(pivrow-1)/2+j-1;
126 for (k=j; k < pivrow; k++)
133 if (
std::abs(*mjj) >= alpha * lambda * (lambda/ sigma) )
138 else if (
std::abs(*(rhs.
Array()+pivrow*(pivrow-1)/2+pivrow-1))
152 temp2 = *mjj = 1.0f/ *mjj;
155 for (i=j+1; i <= nrow; i++)
157 temp1 = *(rhs.
Array() + i*(i-1)/2 + j-1) * temp2;
158 ip = rhs.
Array()+i*(i-1)/2+j;
159 for (k=j+1; k<=i; k++)
161 *ip -=
static_cast<T> ( temp1 * *(rhs.
Array() + k*(k-1)/2 + j-1) );
168 ip = rhs.
Array() + (j+1)*j/2 + j-1;
169 for (i=j+1; i <= nrow; ip += i++)
170 *ip *= static_cast<T> ( temp2 );
178 ip = rhs.
Array() + pivrow*(pivrow-1)/2 + j;
179 for (i=j+1; i < pivrow; i++, ip++)
181 temp1 = *(rhs.
Array() + i*(i-1)/2 + j-1);
182 *(rhs.
Array() + i*(i-1)/2 + j-1)= *ip;
183 *ip =
static_cast<T> ( temp1 );
186 *mjj = *(rhs.
Array()+pivrow*(pivrow-1)/2+pivrow-1);
187 *(rhs.
Array()+pivrow*(pivrow-1)/2+pivrow-1) =
static_cast<T> (temp1 );
188 ip = rhs.
Array() + (pivrow+1)*pivrow/2 + j-1;
190 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
194 *ip =
static_cast<T>( temp1 );
202 temp2 = *mjj = 1.0f / *mjj;
205 for (i = j+1; i <= nrow; i++)
207 temp1 = *(rhs.
Array() + i*(i-1)/2 + j-1) * temp2;
208 ip = rhs.
Array()+i*(i-1)/2+j;
209 for (k=j+1; k<=i; k++)
211 *ip -=
static_cast<T> (temp1 * *(rhs.
Array() + k*(k-1)/2 + j-1) );
218 ip = rhs.
Array() + (j+1)*j/2 + j-1;
219 for (i=j+1; i<=nrow; ip += i++)
220 *ip *= static_cast<T>( temp2 );
231 ip = rhs.
Array() + pivrow*(pivrow-1)/2 + j+1;
232 for (i=j+2; i < pivrow; i++, ip++)
234 temp1 = *(rhs.
Array() + i*(i-1)/2 + j);
235 *(rhs.
Array() + i*(i-1)/2 + j) = *ip;
236 *ip =
static_cast<T>( temp1 );
238 temp1 = *(mjj + j + 1);
240 *(rhs.
Array() + pivrow*(pivrow-1)/2 + pivrow-1);
241 *(rhs.
Array() + pivrow*(pivrow-1)/2 + pivrow-1) =
static_cast<T>( temp1 );
243 *(mjj + j) = *(rhs.
Array() + pivrow*(pivrow-1)/2 + j-1);
244 *(rhs.
Array() + pivrow*(pivrow-1)/2 + j-1) =
static_cast<T>( temp1 );
245 ip = rhs.
Array() + (pivrow+1)*pivrow/2 + j;
246 iq = ip + pivrow-(j+1);
247 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
251 *ip =
static_cast<T>( temp1 );
255 temp2 = *mjj * *(mjj + j + 1) - *(mjj + j) * *(mjj + j);
258 <<
"SymMatrix::bunch_invert: error in pivot choice"
264 *mjj =
static_cast<T>( *(mjj + j + 1) * temp2 );
265 *(mjj + j + 1) = static_cast<T>( temp1 * temp2 );
266 *(mjj + j) = static_cast<T>( - *(mjj + j) * temp2 );
271 for (i=j+2; i <= nrow ; i++)
273 ip = rhs.
Array() + i*(i-1)/2 + j-1;
274 temp1 = *ip * *mjj + *(ip + 1) * *(mjj + j);
277 temp2 = *ip * *(mjj + j) + *(ip + 1) * *(mjj + j + 1);
280 for (k = j+2; k <= i ; k++)
282 ip = rhs.
Array() + i*(i-1)/2 + k-1;
283 iq = rhs.
Array() + k*(k-1)/2 + j-1;
284 *ip -=
static_cast<T>( temp1 * *iq + temp2 * *(iq+1) );
290 for (i=j+2; i <= nrow ; i++)
292 ip = rhs.
Array() + i*(i-1)/2 + j-1;
293 temp1 = *ip * *mjj + *(ip+1) * *(mjj + j);
296 *(ip+1) = *ip * *(mjj + j)
297 + *(ip+1) * *(mjj + j + 1);
300 *ip =
static_cast<T>( temp1 );
309 mjj = rhs.
Array() + j*(j-1)/2 + j-1;
321 for (j = nrow ; j >= 1 ; j -= s)
323 mjj = rhs.
Array() + j*(j-1)/2 + j-1;
329 ip = rhs.
Array() + (j+1)*j/2 + j-1;
330 for (i=0; i < nrow-j; ip += 1+j+i++)
332 for (i=j+1; i<=nrow ; i++)
335 ip = rhs.
Array() + i*(i-1)/2 + j;
336 for (k=0; k <= i-j-1; k++)
337 temp2 += *ip++ * x[k];
338 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
340 *(rhs.
Array()+ i*(i-1)/2 + j-1) =
static_cast<T>( -temp2 );
343 ip = rhs.
Array() + (j+1)*j/2 + j-1;
344 for (k=0; k < nrow-j; ip += 1+j+k++)
346 *mjj -=
static_cast<T>( temp2 );
352 std::cerr <<
"error in piv" << piv[j-1] << std::endl;
356 ip = rhs.
Array() + (j+1)*j/2 + j-1;
357 for (i=0; i < nrow-j; ip += 1+j+i++)
359 for (i=j+1; i<=nrow ; i++)
362 ip = rhs.
Array() + i*(i-1)/2 + j;
363 for (k=0; k <= i-j-1; k++)
364 temp2 += *ip++ * x[k];
365 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
367 *(rhs.
Array()+ i*(i-1)/2 + j-1) =
static_cast<T>( -temp2 );
370 ip = rhs.
Array() + (j+1)*j/2 + j-1;
371 for (k=0; k < nrow-j; ip += 1+j+k++)
373 *mjj -=
static_cast<T>( temp2 );
375 ip = rhs.
Array() + (j+1)*j/2 + j-2;
376 for (i=j+1; i <= nrow; ip += i++)
377 temp2 += *ip * *(ip+1);
378 *(mjj-1) -= static_cast<T>( temp2 );
379 ip = rhs.
Array() + (j+1)*j/2 + j-2;
380 for (i=0; i < nrow-j; ip += 1+j+i++)
382 for (i=j+1; i <= nrow ; i++)
385 ip = rhs.
Array() + i*(i-1)/2 + j;
386 for (k=0; k <= i-j-1; k++)
387 temp2 += *ip++ * x[k];
388 for (ip += i-1; k < nrow-j; ip += 1+j+k++)
390 *(rhs.
Array()+ i*(i-1)/2 + j-2)=
static_cast<T>( -temp2 );
393 ip = rhs.
Array() + (j+1)*j/2 + j-2;
394 for (k=0; k < nrow-j; ip += 1+j+k++)
396 *(mjj-j) -= static_cast<T>( temp2 );
403 pivrow = (piv[j-1]==0)? -piv[j-2] : piv[j-1];
404 ip = rhs.
Array() + pivrow*(pivrow-1)/2 + j;
405 for (i=j+1;i < pivrow; i++, ip++)
407 temp1 = *(rhs.
Array() + i*(i-1)/2 + j-1);
408 *(rhs.
Array() + i*(i-1)/2 + j-1) = *ip;
409 *ip =
static_cast<T>( temp1 );
412 *mjj = *(rhs.
Array() + pivrow*(pivrow-1)/2 + pivrow-1);
413 *(rhs.
Array() + pivrow*(pivrow-1)/2 + pivrow-1) =
static_cast<T>( temp1 );
417 *(mjj-1) = *( rhs.
Array() + pivrow*(pivrow-1)/2 + j-2);
418 *( rhs.
Array() + pivrow*(pivrow-1)/2 + j-2) =
static_cast<T>( temp1 );
421 ip = rhs.
Array() + (pivrow+1)*pivrow/2 + j-1;
423 for (i = pivrow+1; i <= nrow; ip += i, iq += i++)
427 *ip =
static_cast<T>(temp1);
441 template <
unsigned int idim,
unsigned int n>
445 if (idim !=
n)
return -1;
451 typedef T value_type;
456 value_type g1 = 1.0e-19, g2 = 1.0e19;
462 const value_type
epsilon = 0.0;
468 int normal = 0, imposs = -1;
469 int jrange = 0, jover = 1, junder = -1;
474 mIter mj = rhs.
Array();
476 for (
unsigned int j=1;j<=
n;j++) {
480 mIter mij = mj +
n + j - 1;
481 for (
unsigned int i=j+1;i<=
n;i++) {
500 mIter mkl = rhs.
Array() + (k-1)*
n;
501 for (
unsigned int l=1;
l<=
n;
l++) {
504 *(mkl++) = static_cast<T>(tf);
507 ir[nxch] = (((j)<<12)+(k));
521 if (jfail == jrange) jfail = junder;
524 if (jfail==jrange) jfail = jover;
530 for (k=j+1;k<=
n;k++) {
534 mIter mik = rhs.
Array() + k - 1;
535 mIter mijp = rhs.
Array() + j;
538 for (
unsigned int i=1;i<j;i++) {
539 s11 += (*mik) * (*(mji++));
540 s12 += (*mijp) * (*(mki++));
546 *(mjk++) = static_cast<T>( - s11 * (*mjj) );
547 *(mkjp) = static_cast<T> ( -(((*(mjj+1)))*((*(mkjp-1)))+(s12)) );
555 if (nxch%2==1) det = -det;
556 if (jfail !=jrange) det = 0.0;
571 template <
unsigned int idim,
unsigned int n>
578 typedef T value_type;
582 if (idim !=
n)
return -1;
588 mIter m11 = rhs.
Array();
592 *m21 = -(*m22) * (*m11) * (*m21);
595 mIter mi = rhs.
Array() + 2 *
n;
596 mIter mii= rhs.
Array() + 2 * n + 2;
597 mIter mimim = rhs.
Array() + n + 1;
598 for (
unsigned int i=3;i<=
n;i++) {
599 unsigned int im2 = i - 2;
600 mIter mj = rhs.
Array();
601 mIter mji = mj + i - 1;
603 for (
unsigned int j=1;j<=im2;j++) {
606 mIter mkj = mj + j - 1;
607 mIter mik = mi + j - 1;
609 mIter mkpi = mj + n + i - 1;
610 for (
unsigned int k=j;k<=im2;k++) {
611 s31 += (*mkj) * (*(mik++));
612 s32 += (*(mjkp++)) * (*mkpi);
616 *mij =
static_cast<T>( -(*mii) * (((*(mij-
n)))*( (*(mii-1)))+(s31)) );
617 *mji =
static_cast<T> ( -s32 );
622 *(mii-1) = -(*mii) * (*mimim) * (*(mii-1));
623 *(mimim+1) = -(*(mimim+1));
629 mIter mi = rhs.
Array();
630 mIter mii = rhs.
Array();
631 for (
unsigned int i=1;i<
n;i++) {
632 unsigned int ni = n - i;
635 for (
unsigned j=1; j<=i;j++) {
637 mIter mikj = mi + n + j - 1;
638 mIter miik = mii + 1;
639 mIter min_end = mi +
n;
640 for (;miik<min_end;) {
641 s33 += (*mikj) * (*(miik++));
644 *(mij++) = static_cast<T> ( s33 );
646 for (
unsigned j=1;j<=ni;j++) {
648 mIter miik = mii + j;
649 mIter mikij = mii + j * n + j;
650 for (
unsigned int k=j;k<=ni;k++) {
651 s34 += *mikij * (*(miik++));
659 unsigned int nxch = ir[
n];
660 if (nxch==0)
return 0;
661 for (
unsigned int mm=1;mm<=nxch;mm++) {
662 unsigned int k = nxch - mm + 1;
666 mIter mki = rhs.
Array() + i - 1;
667 mIter mkj = rhs.
Array() + j - 1;
668 for (k=1; k<=
n;k++) {
static int DfinvMatrix(MatRepStd< T, idim, n > &rhs, unsigned int *work)
LU inversion of general square matrices.
Namespace for new ROOT classes and functions.
MatRepSym Matrix storage representation for a symmetric matrix of dimension NxN This class is a templ...
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 void InvertBunchKaufman(MatRepSym< T, idim > &rhs, int &ifail)
Bunch-Kaufman method for inversion of symmetric matrices.
static Vc_ALWAYS_INLINE Vector< T > abs(const Vector< T > &x)
iterator begin()
STL iterator interface.
Expression wrapper class for Matrix objects.
Namespace for new Math classes and functions.
SVector: a generic fixed size Vector class.