2009-06-02 60 views
6

Tôi cần kiểm tra nếu một ma trận phương sai là đường chéo. Nếu không, tôi sẽ phân tích LDL Cholesky. Nhưng tôi đã tự hỏi đó sẽ là cách đáng tin cậy nhất và nhanh nhất để kiểm tra là ma trận chéo? Tôi đang sử dụng Fortran.Làm thế nào để kiểm tra nếu ma trận là đường chéo?

Điều đầu tiên đến với tâm trí của tôi là lấy tổng của tất cả các phần tử ma trận và trừ các phần tử đường chéo từ tổng đó. Nếu câu trả lời là 0, ma trận là đường chéo. Bất kỳ ý tưởng tốt hơn?

Trong Fortran Tôi sẽ viết

!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 
+0

Chỉ cần để nitpick: bạn có nghĩa là LDL' phân hủy, không LDL. ;-) – Stobor

+0

Ngoài ra, ví dụ đơn giản: [[1, -1], [1, 1]] vượt qua bài kiểm tra của bạn. – Stobor

+0

Ngoài ra: LAPACK LDL 'decomp: http://www.netlib.org/lapack/single/ssptrf.f LAPACK Cholesky LL' decomp: http://www.netlib.org/lapack/single/spotrf.f – Stobor

Trả lời

0

Tìm ma trận cho phi zero đánh giá cao

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 

Để sử dụng chính xác đôi thói quen LAPACK thay thế đầu tiên 's' với 'd'. Vì vậy, spotrf trở thành dpotrf

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

+0

Đúng, nhưng không có dsptrf.f, chỉ ssptrf.f làm phân hủy LDL. dpotrf phân tích LL '. –

10

Sẽ tốt hơn nhiều để chỉ đi qua tất cả các yếu tố off-đường chéo và kiểm tra xem họ là gần bằng không (so sánh một số dấu chấm động cho sự bất bình đẳng là dễ bị làm tròn lỗi và có thể dẫn đến kết quả sai).

Trước tiên, khi bạn tìm thấy bất kỳ phần tử vi phạm nào, bạn có thể dừng chuyển động ngay lập tức và điều này có thể cho phép giảm thời gian đáng kể nếu vi phạm ma trận là điển hình.

Thứ hai, nó có khả năng cho phép trình biên dịch vòng lặp tốt hơn bởi trình biên dịch (các trình biên dịch Fortran được biết đến với các chiến lược tối ưu hóa tốt) và thực thi trên chip nhanh hơn do ít phụ thuộc giữa các lệnh.

Thêm vào thực tế rằng thuật toán được đề xuất của bạn dễ bị tràn và tích lũy lỗi và thuật toán "đi qua và thử nghiệm" không phải là.

+0

Cảm ơn bạn rất nhiều, tôi sẽ làm theo cách đó. –

+0

+1. Thêm vào đó, nó đa xử lý thân thiện! – Stobor

+0

Và A là đối xứng vì vậy tôi chỉ cần đi qua một nửa ma trận ... Cảm ơn bạn một lần nữa, tôi không phải là một lập trình viên "thực sự", vì vậy không thể nói về đa bộ vi xử lý, phụ thuộc lẫn nhau vv .. D Chỉ thống kê thôi. ;) –

Các vấn đề liên quan