Как проверить, диагональна ли матрица?

Мне нужно проверить, является ли одна матрица дисперсии диагональной. Если нет, я сделаю ЛПНП разложения Холецкого. Но мне было интересно, какой самый надежный и быстрый способ проверить диагональ матрицы? Я использую Фортран.

Первое, что приходит мне на ум, - это взять сумму всех элементов матрицы и вычесть диагональные элементы из этой суммы. Если ответ равен 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

http://www.netlib.org/lapack/double/


было бы намного лучше просто пересечь все диагональные элементы и проверить, близки ли они к нулю (сравнение числа с плавающей запятой для неравенства склонно к ошибкам округления и может привести к ошибочным результатам).

во-первых, как только вы найдете любой нарушающий элемент, вы можете немедленно прекратить прохождение, и это может привести к значительному уменьшению времени, если нарушающие матрицы типичны.

во-вторых, это потенциально позволит лучше развернуть цикл компилятор (компиляторы Fortran известны хорошими стратегиями оптимизации) и более быстрым выполнением на чипе из-за меньших зависимостей между командами.

добавьте к этому тот факт, что ваш предлагаемый алгоритм склонен к переполнениям и накоплению ошибок, а алгоритм "траверс-и-тест" - нет.