44 #ifndef SQUAREROOTINFORMATION_MATRICIES_INCLUDE
45 #define SQUAREROOTINFORMATION_MATRICIES_INCLUDE
124 void SrifMU(Matrix<T>& R, Vector<T>& Z, Matrix<T>& A,
unsigned int M = 0);
145 void SrifMU(Matrix<T>& R, Vector<T>& Z,
const Matrix<T>& H, Vector<T>& D,
176 Matrix<T>
lowerCholesky(
const Matrix<T>& A,
const T ztol = T(1.e-16));
187 Matrix<T>
upperCholesky(
const Matrix<T>& A,
const T ztol = T(1.e-16));
258 template <
class T> Matrix<T>
LDL(
const Matrix<T>& A, Vector<T>& D);
270 template <
class T> Matrix<T>
UDU(
const Matrix<T>& A, Vector<T>& D);
353 std::ostringstream oss;
354 oss <<
"Invalid input dimensions:\n R has dimension " << R.
rows()
355 <<
"x" << R.
cols() <<
",\n Z has length " << Z.
size()
356 <<
",\n and A has dimension " << A.
rows() <<
"x" << A.
cols();
361 const T EPS = -T(1.e-200);
362 unsigned int m = M, n = R.
rows();
363 if (m == 0 || m > A.
rows())
367 unsigned int np1 = n + 1;
368 unsigned int i, j, k;
371 for (j = 0; j < n; j++)
374 for (i = 0; i < m; i++)
384 sum = (dum > T(0) ? -T(1) : T(1)) * ::sqrt(
sum);
400 for (k = j + 1; k < np1; k++)
402 sum = delta * (k == n ? Z(j) : R(j, k));
403 for (i = 0; i < m; i++)
404 sum += A(i, j) * A(i, k);
417 R(j, k) +=
sum * delta;
420 for (i = 0; i < m; i++)
421 A(i, k) +=
sum * A(i, j);
462 catch (MatrixException& me)
501 std::ostringstream oss;
502 oss <<
"Invalid input dimensions: " << A.
rows() <<
"x" << A.
cols();
506 const unsigned int n = A.
rows();
507 unsigned int i, j, k;
510 for (j = 0; j < n; j++)
513 for (k = 0; k < j; k++)
514 d -= L(j, k) * L(j, k);
517 std::ostringstream oss;
518 oss <<
"Non-positive eigenvalue " << std::scientific << d
520 <<
": lowerCholesky() requires positive-definite input";
524 for (i = j + 1; i < n; i++)
527 for (k = 0; k < j; k++)
528 d -= L(i, k) * L(j, k);
529 L(i, j) = d / L(j, j);
550 std::ostringstream oss;
551 oss <<
"Invalid input dimensions: " << A.
rows() <<
"x" << A.
cols();
555 const unsigned int n = A.
cols();
556 unsigned int i, j, k;
561 for (j = n - 1; j >= 0; j--)
566 std::ostringstream oss;
567 oss <<
"Non-positive eigenvalue " << std::scientific << d
569 <<
": upperCholesky() requires positive-definite input";
575 for (k = 0; k < j; k++)
576 U(k, j) = d *
P(k, j);
577 for (k = 0; k < j; k++)
579 for (i = 0; i <= k; i++)
580 P(i, k) -= U(k, j) * U(i, j);
610 catch (MatrixException& me)
612 me.addText(
"Called by inverseCholesky()");
640 std::ostringstream oss;
641 oss <<
"Invalid input dimensions: " << UT.
rows() <<
"x" << UT.
cols();
645 unsigned int i, j, k, n = UT.
rows();
646 T big(0), small(0),
sum, dum;
650 dum = UT(n - 1, n - 1);
653 GNSSTK_THROW(SingularMatrixException(
"Singular matrix at element 0"));
656 big = small = fabs(dum);
657 Inv(n - 1, n - 1) = T(1) / dum;
662 for (i = 0; i < n - 1; i++)
666 for (i = n - 2;; i--)
668 if (UT(i, i) == T(0))
670 std::ostringstream oss;
671 oss <<
"Singular matrix at element " << i;
675 if (fabs(UT(i, i)) > big)
677 big = fabs(UT(i, i));
679 if (fabs(UT(i, i)) < small)
681 small = fabs(UT(i, i));
683 dum = T(1) / UT(i, i);
687 for (j = i + 1; j < n; j++)
690 for (k = i + 1; k <= j; k++)
691 sum += Inv(k, j) * UT(i, k);
692 Inv(i, j) = -
sum * dum;
694 for (j = 0; j < i; j++)
727 const unsigned int n = UT.
rows();
728 if (n == 0 || UT.
cols() != n)
730 std::ostringstream oss;
731 oss <<
"Invalid input dimensions: " << UT.
rows() <<
"x" << UT.
cols();
735 unsigned int i, j, k;
739 for (i = 0; i < n - 1; i++)
742 for (j = i; j < n; j++)
743 sum += UT(i, j) * UT(i, j);
745 for (j = i + 1; j < n; j++)
748 for (k = j; k < n; k++)
749 sum += UT(i, k) * UT(j, k);
750 S(i, j) = S(j, i) =
sum;
754 UT(n - 1, n - 1) * UT(n - 1, n - 1);
777 std::ostringstream oss;
778 oss <<
"Invalid input dimensions: " << LT.
rows() <<
"x" << LT.
cols();
782 unsigned int i, j, k, n = LT.
rows();
783 T big(0), small(0),
sum, dum;
790 SingularMatrixException e(
"Singular matrix at element 0");
794 big = small = fabs(dum);
795 Inv(0, 0) = T(1) / dum;
804 for (i = 1; i < n; i++)
806 if (LT(i, i) == T(0))
809 SingularMatrixException(
"Singular matrix at element 0"));
812 if (fabs(LT(i, i)) > big)
814 big = fabs(LT(i, i));
816 if (fabs(LT(i, i)) < small)
818 small = fabs(LT(i, i));
820 dum = T(1) / LT(i, i);
824 for (j = 0; j < i; j++)
827 for (k = j; k < i; k++)
828 sum += LT(i, k) * Inv(k, j);
831 Inv(i, j) = -
sum * dum;
866 std::ostringstream oss;
867 oss <<
"Invalid input dimensions: " << A.
rows() <<
"x" << A.
cols();
871 const unsigned int N(A.
rows());
877 catch (MatrixException& me)
879 me.addText(
"lowerCholesky failed");
887 for (j = 0; j < N; j++)
893 for (i = j + 1; i < N; i++)
899 catch (MatrixException& me)
901 me.addText(
"Called by LDL()");
923 std::ostringstream oss;
924 oss <<
"Invalid input dimensions: " << A.
rows() <<
"x" << A.
cols();
928 const unsigned int N(A.
rows());
934 catch (MatrixException& me)
936 me.addText(
"upperCholesky failed");
944 for (j = 0; j < N; j++)
950 for (i = 0; i < j; i++)
956 catch (MatrixException& me)
958 me.addText(
"Called by UDU()");
965 #endif // SQUAREROOTINFORMATION_MATRICIES_INCLUDE