2017-11-14 209 views
5

Bazı kuantum dönüşüm matrislerini uygulamak için Haskell'i kullanıyorum. Bir kare matrisin, ters ve bitişik matrisler oluşturarak ve her ikisini de test ederek üniter olup olmadığını test etmek için tasarlanmış bir işlevim var. sarma iki değer test için kullanılan basit bir işlevi olan işlevi aşağıda gösterilmiştirHaskell Matrix eşitliği başarısız oluyor

, ters döndü. matrisler aşağıda gösterilen alma sırasında Doğru dönen sorunsuz çalışıyor bazı basit bir test matrisleri için

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)) 

Sorunum A. Edison ((kullanarak inşa matrisi dönüşümü için işlev false döndürür olmasıdır 1/sqrt (2): + 0) ve ((-1/sqrt (2)): + 0))

başarısız matrislerin ikinci çift eşitlik testi neden olabilir ne
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)) 

? Koddaki karmaşık sayıları sunmam için daha doğru bir yol var mı?

+2

Bir mantıklı nedeni kayan noktalı aritmetik nedeniyle yığmak hataları bazı sorunlar olabilir ki? o olsaydı Haskell bir yeni gelen meraktan –

cevap

3

Double kayan nokta sayıları edilir ve kayan noktalı sayılar doğal olarak yanlıştır. ==, "yeterince yakın" eşitlik kontrolü isteyebileceğiniz tam bir eşitlik kontrolü gerçekleştirecektir.

Alternatif olarak, sınırsız hassas bir ya da 1) hassas sabit olduğu farklı bir sayısal tipi (gibi, ya da 2) sınırsız bellek kullanımı kullanabilir. scientific, fixed gibi iyi bir seçimdir.

+1

, o ifadeyi ya da 'tembel' değerlendirerek önlemek ve bu bir diğer aynı ifadesidir bkz değerlendirerek eşitlik test olacağını, bunun yerine V2 için bir ifade yazmak için? – bjd2385

+1

@ bjd2385 Haskell, yarattığı ifadeye dayalı olarak eşitlik yapmayı denemez. Hesaplamayı yapar ve sonra eşitliği kontrol eder. Aritmetik ifadeleri temsil eden sayısal bir tür tanımlayabilir ve bu türden eşitliği normalleştirilmiş ifadelerin eşitliği olarak tanımlayabilirsiniz, ancak bu, Double'in nasıl çalıştığını açıklamamıştır :) – ephrion

+0

Aha, bunu açıklar. Her çifte açıkça sabit bir hale getirilmesi sorunu çözer. Teşekkürler! –