```module HAHP.Algorithm.Consistency
(
computeTreeConsistencies
) where

import           Control.Parallel.Strategies
import           HAHP.Data
import           Numeric.LinearAlgebra.HMatrix

-- trick : http://stackoverflow.com/a/7897595
computeTreeConsistencies :: AHPTree -> AHPTree
computeTreeConsistencies ahpTree =
case ahpTree of
(AHPTree _ prefMat _ _ _ children) -> ahpTree
{ consistencyValue = Just \$ matrixConsistency prefMat
, children = parMap rseq computeTreeConsistencies children
}
AHPLeaf {} -> ahpTree

-- |A matrix with consistency=0 is consistent.
matrixConsistency :: PairwiseMatrix -> Double
matrixConsistency prefMat
| matrixSize <= 2 = 0
| otherwise = consistencyIndicator / randomIndexValue
where randomIndexValue = randomIndex matrixSize
consistencyIndicator = (lambdaMax - matrixSize) / (matrixSize - 1)
lambdaMax = maxEigenValue prefMat
matrixSize = fromIntegral . rows \$ prefMat

maxEigenValue :: PairwiseMatrix -> Double
maxEigenValue prefMat = realPart . maxElement . eigenvalues \$ prefMat

randomIndex :: Double -> Double
randomIndex size
| size <= 15 = randomIndexSaaty size
| otherwise = randomIndexCalculated size

randomIndexSaaty :: Double -> Double
randomIndexSaaty matrixSize = saatyTable !! (round matrixSize - 1)
where saatyTable = [0.00, 0.00, 0.58, 0.90, 1.12, 1.24, 1.32, 1.41, 1.45, 1.49, 1.51, 1.48, 1.56, 1.57, 1.59]

-- |Random Index estimation function taken from :
-- "Consistency in the AHP : A new approach"
-- JosÃ© Antonio ALONSO and Teresa LAMATA,
-- IJUFKBS 2006
randomIndexCalculated :: Double -> Double
randomIndexCalculated matrixSize = ( 0.00149   * (matrixSize^3))
+ (- 0.05121) * (matrixSize^2)
+ (  0.59150  *  matrixSize)
+ (- 0.79124)
```