```{-# LANGUAGE Unsafe #-}
{-# LANGUAGE ViewPatterns #-}

--------------------------------------------------------------------------------------------
-- |
-- Copyright   :  (C) 2018 Nathan Waivio
-- Maintainer  :  Nathan Waivio <nathan.waivio@gmail.com>
-- Stability   :  Stable
-- Portability :  unportable
--
-- Interface functions of Cl3 types to/from HMatrix.
--
-------------------------------------------------------------------

module Algebra.Geometric.Cl3.HMatrixInterface
(
toHMatrix,
fromHMatrix
) where

import safe Algebra.Geometric.Cl3 (Cl3(..), toAPS, reduce)
import Numeric.LinearAlgebra.Data (Matrix, atIndex, (><))
import safe Data.Complex (Complex(..))

-- | 'toHMatrix' Convert a Cl3 Cliffor to a HMatrix Matrix
toHMatrix :: Cl3 -> Matrix (Complex Double)
toHMatrix (toAPS -> APS a0 a1 a2 a3 a23 a31 a12 a123) =
let a = (a0+a3) :+ (a123+a12)
b = (a1+a31) :+ (a23-a2)
c = (a1-a31) :+ (a23+a2)
d = (a0-a3) :+ (a123-a12)
in (2><2) [a,b,c,d]
toHMatrix _ = error "Pattern Matching failure of toHMatrix for the toAPS/APS View Pattern"

-- | 'fromHMatrix' Convert from a HMatrix Matrix (2x2 Complex Double hopefully...) to a Cl3 Cliffor
fromHMatrix :: Matrix (Complex Double) -> Cl3
fromHMatrix mat =
let (a :+ ai) = mat `atIndex` (0,0)
(b :+ bi) = mat `atIndex` (0,1)
(c :+ ci) = mat `atIndex` (1,0)
(d :+ di) = mat `atIndex` (1,1)
a0 = (a + d) / 2
a1 = (b + c) / 2
a2 = (ci - bi) / 2
a3 = (a - d) / 2
a23 = (ci + bi) / 2
a31 = (b - c) / 2
a12 = (ai - di) / 2
a123 = (ai + di) / 2
in reduce (APS a0 a1 a2 a3 a23 a31 a12 a123)

```