-- |
-- Module      : ConClusion.Array.Conversion
-- Description : Type castings and conversions of array types
-- Copyright   : Phillip Seeber, 2022
-- License     : AGPL-3
-- Maintainer  : phillip.seeber@googlemail.com
-- Stability   : experimental
-- Portability : POSIX, Windows
module ConClusion.Array.Conversion
  ( vecH2M,
    vecM2H,
    matH2M,
    matM2H,
  )
where

import Data.Massiv.Array as Massiv hiding (IndexException)
import Data.Massiv.Array.Manifest.Vector as Massiv
import Numeric.LinearAlgebra as LA hiding (magnitude, (<>))
import RIO
import qualified RIO.Vector.Storable as VectorS

-- | Converts a vector from the HMatrix package to the Massiv representation.
{-# SCC vecH2M #-}
vecH2M :: (Element e, Manifest r e, Load r Ix1 e) => VectorS.Vector e -> Massiv.Vector r e
vecH2M :: forall e r.
(Element e, Manifest r e, Load r Ix1 e) =>
Vector e -> Vector r e
vecH2M Vector e
hVec = forall (v :: * -> *) a ix r.
(HasCallStack, Typeable v, Vector v a, Load (ARepr v) ix a,
 Load r ix a, Manifest r a) =>
Comp -> Sz ix -> v a -> Array r ix a
fromVector' Comp
Seq (forall ix. Index ix => ix -> Sz ix
Sz forall a b. (a -> b) -> a -> b
$ forall a. Storable a => Vector a -> Ix1
VectorS.length Vector e
hVec) Vector e
hVec

-- | Converts a vector from the Massiv representation to the HMatrix representation.
{-# SCC vecM2H #-}
vecM2H :: (Manifest r e, Load r Ix1 e, Element e) => Massiv.Vector r e -> LA.Vector e
vecM2H :: forall r e.
(Manifest r e, Load r Ix1 e, Element e) =>
Vector r e -> Vector e
vecM2H = forall r ix e (v :: * -> *).
(Manifest r e, Load r ix e, Manifest (ARepr v) e, Vector v e,
 VRepr (ARepr v) ~ v) =>
Array r ix e -> v e
Massiv.toVector

-- | Converts a matrix from the HMatrix representation to the Massiv representation.
{-# SCC matH2M #-}
matH2M :: (Manifest r e, Load r Ix1 e, Element e) => LA.Matrix e -> Massiv.Matrix r e
matH2M :: forall r e.
(Manifest r e, Load r Ix1 e, Element e) =>
Matrix e -> Matrix r e
matH2M Matrix e
hMat = forall r ix ix' e.
(HasCallStack, Index ix', Index ix, Size r) =>
Sz ix' -> Array r ix e -> Array r ix' e
Massiv.resize' (forall ix. Index ix => ix -> Sz ix
Sz forall a b. (a -> b) -> a -> b
$ Ix1
nRows Ix1 -> Ix1 -> Ix2
:. Ix1
nCols) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall e r.
(Element e, Manifest r e, Load r Ix1 e) =>
Vector e -> Vector r e
vecH2M forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall t. Element t => Matrix t -> Vector t
LA.flatten forall a b. (a -> b) -> a -> b
$ Matrix e
hMat
  where
    nRows :: Ix1
nRows = forall t. Matrix t -> Ix1
LA.rows Matrix e
hMat
    nCols :: Ix1
nCols = forall t. Matrix t -> Ix1
LA.cols Matrix e
hMat

-- | Converts a matrix from Massiv to HMatrix representation.
{-# SCC matM2H #-}
matM2H :: (Element e, Manifest r e, Load r Ix1 e) => Massiv.Matrix r e -> LA.Matrix e
matM2H :: forall e r.
(Element e, Manifest r e, Load r Ix1 e) =>
Matrix r e -> Matrix e
matM2H Matrix r e
mMat = forall t. Storable t => Ix1 -> Vector t -> Matrix t
LA.reshape Ix1
nCols forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r e.
(Manifest r e, Load r Ix1 e, Element e) =>
Vector r e -> Vector e
vecM2H forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall r ix e. (Index ix, Size r) => Array r ix e -> Vector r e
Massiv.flatten forall a b. (a -> b) -> a -> b
$ Matrix r e
mMat
  where
    Sz (Ix1
_nRows :. Ix1
nCols) = forall r ix e. Size r => Array r ix e -> Sz ix
Massiv.size Matrix r e
mMat