2017-11-14 21 views
5

일부 양자 변환 행렬을 구현하기 위해 Haskell을 사용하는 것이 엉망입니다. 나는 square matrix가 unitary인지 아닌지를 테스트하기위한 함수를 가지고있다. 역행렬과 adjoint 행렬을 만들고 둘 다 테스트하면된다. 가 어느 값을 테스트하는데 사용되는 간단한 함수 인 함수가 다음과 같다Haskell 행렬 평등 실패

로부터 반환. 행렬은 다음과 같이하기 때 진정한 반환 잘 작동 몇 가지 간단한 테스트 매트릭스에 대한

isUnitary :: [[Copmlex Double]] -> Bool 
isUnitary lists = let mat = fromLists lists --Create matrix from lists 
         conjugateTranspose = fmap conjugate $ Data.Matrix.transpose mat --Conjugate Transpose Matrix 
         inverseMat = debug("ConjugateTranspose: \n" ++ show conjugateTranspose ++ "\n") 
            wrap $ inverse mat --The inverse matrix 
         in if (conjugateTranspose) == inverseMat then debug("InverseMat: \n" ++ show inverseMat ++ "\n") 
                     True 
         else debug("InverseMat: \n" ++ show inverseMat ++ "\n") 
           False 

:

ConjugateTranspose: 
( 1.0 :+ (-0.0)     0.0 :+ (-0.0)) 
( 0.0 :+ (-0.0)     (-1.0) :+ (-0.0)) 

InverseMat: 
( 1.0 :+ 0.0      0.0 :+ 0.0) 
( 0.0 :+ (-0.0)     (-1.0) :+ (-0.0)) 

내 문제는 마드가 ((사용하여 내장 된 변환 행렬에 대한 함수가 False를 반환한다는 것입니다 1/SQRT (2) + 0) 및 ((- 1/sqrt (2))와 같다 : + 0))

실패 행렬의 두 번째 쌍 항등 테스트를 야기 할 수있는 것을
ConjugateTranspose: 
( 0.7071067811865475 :+ (-0.0) 0.7071067811865475 :+ (-0.0)) 
( 0.7071067811865475 :+ (-0.0) (-0.7071067811865475) :+ (-0.0)) 

InverseMat: 
( 0.7071067811865476 :+ 0.0  0.7071067811865476 :+ 0.0) 
( 0.7071067811865476 :+ 0.0  (-0.7071067811865476) :+ (-0.0)) 

? 코드에 복소수를 표현하는 더 정확한 방법이 있습니까?

+2

하나의 그럴듯한 이유는 누적 된 오류로 인해 부동 소수점 산술에 몇 가지 문제가있을 수 있다는 것입니다. –

답변

3

Double은 부동 소수점 숫자이며 부동 소수점 수는 본질적으로 정확하지 않습니다. ==은 정확한 평등성 검사를 수행 할 것입니다. 여기서 "충분히 근접한"평등 검사가 필요할 것입니다.

또는 1) 무제한 정밀도를 위해 무제한 메모리 사용과 같은 고정 정밀도 (2 또는 같은)가있는 다른 숫자 유형을 사용할 수 있습니다. fixed과 같이 scientific가 좋은 선택입니다.

+1

신입생에서 하스켈에 이르기까지 호기심에서 벗어나 √2에 대한 표현을 대신 작성한다면, 그 표현을 평가함으로써 평등을 테스트 할 것인가, 아니면 '느슨하게'평가를 피하고 하나가 다른 표현과 동일한 표현이라는 것을 보는가? – bjd2385

+1

@ bjd2385 하스켈은 생성하는 표현식을 기반으로 용어에 대한 평등을 시도하지 않습니다. 그것은 계산을 수행하고 평등을 점검 할 것입니다. 당신은 산술 표현식을 표현하는 숫자 형을 정의 할 수 있고, 정규화 된 표현식의 평등이되도록 그 형평성을 정의 할 수 있습니다. 그러나 어떻게'Double'이 작동하는지는 알 수 없습니다. – ephrion

+0

아하, 설명합니다. 모든 이중을 명시 적으로 고정시켜 문제를 해결하십시오. 감사! –