Как проверить, диагональна ли матрица?
Мне нужно проверить, является ли одна матрица дисперсии диагональной. Если нет, я сделаю ЛПНП разложения Холецкого. Но мне было интересно, какой самый надежный и быстрый способ проверить диагональ матрицы? Я использую Фортран.
Первое, что приходит мне на ум, - это взять сумму всех элементов матрицы и вычесть диагональные элементы из этой суммы. Если ответ равен 0, матрица диагональна. Есть идеи получше?
в Fortran я напишу
!A is my matrix
k=0.0d0
do i in 1:n #n is the number of rows/colums
k = k + A(i,i)
end do
if(abs(sum(A)-k) < epsilon(k)*sum(A)) then
#do cholesky LDL, which I have to write myself, haven't found any subroutines for that in Lapack or anywhere else
end if
2 ответов
Поиск матрицы для ненулевых значений
logical :: not_diag
integer :: i, j
not_diag = .false.
outer: do i = 2, size(A,1)
do j = i, size(A, 2)
if (A(i,j) > PRECISION) then
not_diag = .true.
exit outer
end if
end
end outer
if (not_diag) then
! DO LDL' decomposition
end if
для использования процедур двойной точности LAPACK замените первую "s" на "d". Так spotrf становится dpotrf
было бы намного лучше просто пересечь все диагональные элементы и проверить, близки ли они к нулю (сравнение числа с плавающей запятой для неравенства склонно к ошибкам округления и может привести к ошибочным результатам).
во-первых, как только вы найдете любой нарушающий элемент, вы можете немедленно прекратить прохождение, и это может привести к значительному уменьшению времени, если нарушающие матрицы типичны.
во-вторых, это потенциально позволит лучше развернуть цикл компилятор (компиляторы Fortran известны хорошими стратегиями оптимизации) и более быстрым выполнением на чипе из-за меньших зависимостей между командами.
добавьте к этому тот факт, что ваш предлагаемый алгоритм склонен к переполнениям и накоплению ошибок, а алгоритм "траверс-и-тест" - нет.