2012-11-05 2 views
0

저는 C++에서 dgesv 및 dgemm fortran 서브 루틴을 사용하여 간단한 행렬 곱셈과 왼쪽 나누기를 수행합니다. 임의의 행렬 A와 B에 대한dgesv의 반올림 오류?

, 내가 할 :

*이 dgesv 사용하여 \ DGEMM를 사용하여 정의
A\(A\(A*B)); 

. 분명히이 표현식은 항등 행렬로 단순화되어야합니다. MATLAB에 대한 답을 테스트하고 있으며 대각선 길이가 1보다 길어 지지만 다른 항목은 매우 약간 벗어났습니다 (숫자는 e-15 정도의 크기이므로 0에 가까움) .

이 결과가 예상되는지 궁금합니다. 왜냐하면 내가 이렇게하면 :

C = A+B; 
D = A*B; 

D\(C\(C*C)); 

결과가 D \ C에 나와야합니다. 기본적으로 C (C * C)는 매우 정확합니다 (MATLAB과 완벽하게 일치합니다).하지만 두 번째로는 e-1 또는 e + 00으로 벗어나는 무언가를 얻습니다. 그런 일이 일어나지 않을 것 같아요?

+0

자립형 컴파일 가능한 예를 제공 할 수 있습니까? 일반적으로 MATLAB은 똑같은 BLAS/LAPACK 호출을 사용할 것으로 기대합니다. –

+0

아이덴티티 매트릭스는 정확히 어떻게 단순화됩니까? 내가 오해를하지 않는 한'D \ (C \ (A * B))와 같이 A \ (I * B) == A \ B'와 단순히 같지 않습니다. C * C))''D \ C'와 동일합니까? 'A == B'가 아니라면 어떻게 단위 행렬을 기대할 수 있는지 모르겠습니다. 귀하의 구술 "무작위 매트릭스 A와 B"는 이것에 대해 너무 명확하지 않지만, jimvonmoon의 대답은 가장 적절합니다. MATLAB에서도 'A \ (A \ (A * A)) - A \ A'를 계산하여이를 확인할 수 있습니다. 내부 괄호는 MATLAB이'A \ A = eye (size (A)) '를 지름길로 만들지 못하게하여 정확도를 떨어 뜨립니다. – sigma

답변

2

문제점은 C/C++에서 부동 소수점 변수의 유한 정밀도와 관련이있는 것으로 보입니다. 자세한 내용은 here을 참조하십시오. 그 효과를 최소화하는 몇 가지 기술이 있지만 (일부는 위키 문서에 설명되어 있음), 몇 가지 작업을 수행 한 후에도 항상 약간의 정확성을 잃을 수 있습니다. 임의의 정밀도 (예 : GMP)를 지원하는 제 3 자 수학 라이브러리를 사용할 수 있습니다. 그러나 여전히 - 숫자로 접근하는 한 계산의 정확도는 항상 오염 될 것입니다.