{-# LANGUAGE CPP                 #-}
{-# LANGUAGE FlexibleContexts    #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications    #-}
{-# LANGUAGE TypeOperators       #-}

#if MIN_VERSION_base(4,12,0)
{-# LANGUAGE NoStarIsType         #-}
#endif

-- |
-- Module      : Numeric.LinearAlgebra.Static.Vector
-- Copyright   : (c) Justin Le 2018
-- License     : BSD3
--
-- Maintainer  : justin@jle.im
-- Stability   : experimental
-- Portability : non-portable
--
-- Conversions between statically sized types in
-- "Numeric.LinearAlgebra.Static" from /hmatrix/ and /vector-sized/.
--
-- This module is intentionally minimal, exporting only functions that
-- cannot be written without "unsafe" operations.  With these, however, you
-- can easily write other useful combinators by using type-safe operations
-- like 'fmap', 'VS.map', 'liftA2', 'Data.Vector.Generic.Sized.convert',
-- etc.
--

module Numeric.LinearAlgebra.Static.Vector (
  -- * Vector
  -- ** Real
    rVec
  , grVec
  , vecR
  , gvecR
  -- ** Complex
  , cVec
  , gcVec
  , vecC
  , gvecC
  -- * Matrix
  -- ** Real
  , lRows
  , rowsL
  , lCols
  , colsL
  , lVec
  , glVec
  , vecL
  , gvecL
  -- ** Complex
  , mRows
  , rowsM
  , mCols
  , colsM
  , mVec
  , gmVec
  , vecM
  , gvecM
  ) where

import           Data.Foldable
import           Data.Proxy
import           GHC.TypeLits
import           Unsafe.Coerce
import qualified Data.Vector                  as UV
import qualified Data.Vector.Generic          as UVG
import qualified Data.Vector.Generic.Sized    as VG
import qualified Data.Vector.Sized            as V
import qualified Data.Vector.Storable.Sized   as VS
import qualified Numeric.LinearAlgebra        as HU
import qualified Numeric.LinearAlgebra.Static as H

-- | Convert an /hmatrix/ vector (parameterized by its lenth) to
-- a /vector-sized/ storable vector of 'Double's.
--
-- This is normally /O(1)/, but will be /O(n)/ if the 'H.R' was contructed
-- with 'H.konst' or any other replicated-value constructor (like literals
-- and 'fromInteger'/'fromRational').
rVec :: KnownNat n => H.R n -> VS.Vector n H.ℝ
rVec :: R n -> Vector n ℝ
rVec = Vector ℝ -> Vector n ℝ
forall a b. a -> b
unsafeCoerce (Vector ℝ -> Vector n ℝ) -> (R n -> Vector ℝ) -> R n -> Vector n ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. R n -> Vector ℝ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract

-- | 'rVec', but generalized to work for all types of sized vectors.
--
-- Usually /O(n)/, but if using this with storable vectors, should have the
-- same characteristics as 'rVec' due to rewrite rules.
--
-- @since 0.1.3.0
grVec :: (KnownNat n, UVG.Vector v H.ℝ) => H.R n -> VG.Vector v n H.ℝ
grVec :: R n -> Vector v n ℝ
grVec = Vector Vector n ℝ -> Vector v n ℝ
forall (v :: Type -> Type) a (w :: Type -> Type) (n :: Nat).
(Vector v a, Vector w a) =>
Vector v n a -> Vector w n a
VG.convert (Vector Vector n ℝ -> Vector v n ℝ)
-> (R n -> Vector Vector n ℝ) -> R n -> Vector v n ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. R n -> Vector Vector n ℝ
forall (n :: Nat). KnownNat n => R n -> Vector n ℝ
rVec
{-# NOINLINE[1] grVec #-}
{-# RULES "grVec" grVec = rVec #-}

-- | Convert a /vector-sized/ storable vector to an /hmatrix/ vector
-- (parameterized by its lenth).
--
-- /O(1)/
vecR :: VS.Vector n H.ℝ -> H.R n
vecR :: Vector n ℝ -> R n
vecR = Vector n ℝ -> R n
forall a b. a -> b
unsafeCoerce

-- | 'vecR', but generalized to work for all types of sized vectors.
--
-- Usually /O(n)/, but if using this with storable vectors, should be /O(1)/
-- due to rewrite rules (but don't rely on this).
--
-- @since 0.1.3.0
gvecR :: UVG.Vector v H.ℝ => VG.Vector v n H.ℝ -> H.R n
gvecR :: Vector v n ℝ -> R n
gvecR = Vector n ℝ -> R n
forall (n :: Nat). Vector n ℝ -> R n
vecR (Vector n ℝ -> R n)
-> (Vector v n ℝ -> Vector n ℝ) -> Vector v n ℝ -> R n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector v n ℝ -> Vector n ℝ
forall (v :: Type -> Type) a (w :: Type -> Type) (n :: Nat).
(Vector v a, Vector w a) =>
Vector v n a -> Vector w n a
VG.convert
{-# NOINLINE[1] gvecR #-}
{-# RULES "gvecR" gvecR = vecR #-}

-- | Convert an /hmatrix/ complex vector (parameterized by its lenth) to
-- a /vector-sized/ storable vector of 'Complex Double's, preserving the
-- length in the type.
--
-- This is normally /O(1)/, but will be /O(n)/ if the 'H.C' was contructed
-- with 'H.konst' or any other replicated-value constructor (like literals
-- and 'fromInteger'/'fromRational').
cVec :: KnownNat n => H.C n -> VS.Vector n H.ℂ
cVec :: C n -> Vector n ℂ
cVec = Vector ℂ -> Vector n ℂ
forall a b. a -> b
unsafeCoerce (Vector ℂ -> Vector n ℂ) -> (C n -> Vector ℂ) -> C n -> Vector n ℂ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. C n -> Vector ℂ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract

-- | 'cVec', but generalized to work for all types of sized vectors.
--
-- Usually /O(n)/, but if using this with storable vectors, should have the
-- same characteristics as 'cVec' due to rewrite rules.
--
-- @since 0.1.3.0
gcVec :: (KnownNat n, UVG.Vector v H.ℂ) => H.C n -> VG.Vector v n H.ℂ
gcVec :: C n -> Vector v n ℂ
gcVec = Vector Vector n ℂ -> Vector v n ℂ
forall (v :: Type -> Type) a (w :: Type -> Type) (n :: Nat).
(Vector v a, Vector w a) =>
Vector v n a -> Vector w n a
VG.convert (Vector Vector n ℂ -> Vector v n ℂ)
-> (C n -> Vector Vector n ℂ) -> C n -> Vector v n ℂ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. C n -> Vector Vector n ℂ
forall (n :: Nat). KnownNat n => C n -> Vector n ℂ
cVec
{-# NOINLINE[1] gcVec #-}
{-# RULES "gcVec" gcVec = cVec #-}

-- | Convert a /vector-sized/ storable vector to an /hmatrix/ complex
-- vector (parameterized by its lenth), preserving the length in the type.
--
-- /O(1)/
vecC :: VS.Vector n H.ℂ -> H.C n
vecC :: Vector n ℂ -> C n
vecC = Vector n ℂ -> C n
forall a b. a -> b
unsafeCoerce

-- | 'vecC', but generalized to work for all types of sized vectors.
--
-- Usually /O(n)/, but if using this with storable vectors, should be /O(1)/
-- due to rewrite rules (but don't rely on this).
--
-- @since 0.1.3.0
gvecC :: UVG.Vector v H.ℂ => VG.Vector v n H.ℂ -> H.C n
gvecC :: Vector v n ℂ -> C n
gvecC = Vector n ℂ -> C n
forall (n :: Nat). Vector n ℂ -> C n
vecC (Vector n ℂ -> C n)
-> (Vector v n ℂ -> Vector n ℂ) -> Vector v n ℂ -> C n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector v n ℂ -> Vector n ℂ
forall (v :: Type -> Type) a (w :: Type -> Type) (n :: Nat).
(Vector v a, Vector w a) =>
Vector v n a -> Vector w n a
VG.convert
{-# NOINLINE[1] gvecC #-}
{-# RULES "gvecC" gvecC = vecC #-}

-- | Split an /hmatrix/ matrix (parameterized by its dimensions) to
-- a /vector-sized/ boxed vector of its rows (as /hmatrix/ vectors).
--
-- This is normally /O(m*n)/, but can sometimes be /O(m)/ depending on the
-- representation of the 'H.L' being used.
lRows
    :: (KnownNat m, KnownNat n)
    => H.L m n
    -> V.Vector m (H.R n)
lRows :: L m n -> Vector m (R n)
lRows = Vector (Vector ℝ) -> Vector m (R n)
forall a b. a -> b
unsafeCoerce
      (Vector (Vector ℝ) -> Vector m (R n))
-> (L m n -> Vector (Vector ℝ)) -> L m n -> Vector m (R n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector ℝ] -> Vector (Vector ℝ)
forall a. [a] -> Vector a
UV.fromList
      ([Vector ℝ] -> Vector (Vector ℝ))
-> (L m n -> [Vector ℝ]) -> L m n -> Vector (Vector ℝ)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix ℝ -> [Vector ℝ]
forall t. Element t => Matrix t -> [Vector t]
HU.toRows
      (Matrix ℝ -> [Vector ℝ])
-> (L m n -> Matrix ℝ) -> L m n -> [Vector ℝ]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. L m n -> Matrix ℝ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract

-- | Join together a /vector-sized/ boxed vector of /hmatrix/ vectors to an
-- /hmatrix/ matrix as its rows.
--
-- /O(m*n)/
rowsL
    :: forall m n. KnownNat n
    => V.Vector m (H.R n)
    -> H.L m n
rowsL :: Vector m (R n) -> L m n
rowsL = (Matrix ℝ -> L m n
forall a b. a -> b
unsafeCoerce :: HU.Matrix Double -> H.L m n)
      (Matrix ℝ -> L m n)
-> (Vector m (R n) -> Matrix ℝ) -> Vector m (R n) -> L m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector ℝ] -> Matrix ℝ
forall t. Element t => [Vector t] -> Matrix t
HU.fromRows
      ([Vector ℝ] -> Matrix ℝ)
-> (Vector m (R n) -> [Vector ℝ]) -> Vector m (R n) -> Matrix ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (R n -> Vector ℝ) -> [R n] -> [Vector ℝ]
forall a b. (a -> b) -> [a] -> [b]
map R n -> Vector ℝ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract
      ([R n] -> [Vector ℝ])
-> (Vector m (R n) -> [R n]) -> Vector m (R n) -> [Vector ℝ]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector m (R n) -> [R n]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList

-- | Split an /hmatrix/ matrix (parameterized by its dimensions) to
-- a /vector-sized/ boxed vector of its columns (as /hmatrix/ vectors).
--
-- This is normally /O(m*n)/, but can sometimes be /O(n)/ depending on the
-- representation of the 'H.L' being used.
lCols
    :: forall m n. (KnownNat m, KnownNat n)
    => H.L m n
    -> V.Vector n (H.R m)
lCols :: L m n -> Vector n (R m)
lCols = Vector (Vector ℝ) -> Vector n (R m)
forall a b. a -> b
unsafeCoerce
      (Vector (Vector ℝ) -> Vector n (R m))
-> (L m n -> Vector (Vector ℝ)) -> L m n -> Vector n (R m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector ℝ] -> Vector (Vector ℝ)
forall a. [a] -> Vector a
UV.fromList
      ([Vector ℝ] -> Vector (Vector ℝ))
-> (L m n -> [Vector ℝ]) -> L m n -> Vector (Vector ℝ)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix ℝ -> [Vector ℝ]
forall t. Element t => Matrix t -> [Vector t]
HU.toColumns
      (Matrix ℝ -> [Vector ℝ])
-> (L m n -> Matrix ℝ) -> L m n -> [Vector ℝ]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. L m n -> Matrix ℝ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract

-- | Join together a /vector-sized/ boxed vector of /hmatrix/ vectors to an
-- /hmatrix/ matrix as its columns.
--
-- /O(m*n)/
colsL
    :: forall m n. KnownNat m
    => V.Vector n (H.R m)
    -> H.L m n
colsL :: Vector n (R m) -> L m n
colsL = (Matrix ℝ -> L m n
forall a b. a -> b
unsafeCoerce :: HU.Matrix Double -> H.L m n)
      (Matrix ℝ -> L m n)
-> (Vector n (R m) -> Matrix ℝ) -> Vector n (R m) -> L m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector ℝ] -> Matrix ℝ
forall t. Element t => [Vector t] -> Matrix t
HU.fromColumns
      ([Vector ℝ] -> Matrix ℝ)
-> (Vector n (R m) -> [Vector ℝ]) -> Vector n (R m) -> Matrix ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (R m -> Vector ℝ) -> [R m] -> [Vector ℝ]
forall a b. (a -> b) -> [a] -> [b]
map R m -> Vector ℝ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract
      ([R m] -> [Vector ℝ])
-> (Vector n (R m) -> [R m]) -> Vector n (R m) -> [Vector ℝ]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector n (R m) -> [R m]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList

-- | Split an /hmatrix/ complex matrix (parameterized by its dimensions) to
-- a /vector-sized/ boxed vector of its rows (as /hmatrix/ complex
-- vectors).
--
-- This is normally /O(m*n)/, but can sometimes be /O(m)/ depending on the
-- representation of the 'H.C' being used.
mRows
    :: forall m n. (KnownNat m, KnownNat n)
    => H.M m n
    -> V.Vector m (H.C n)
mRows :: M m n -> Vector m (C n)
mRows = Vector (Vector ℂ) -> Vector m (C n)
forall a b. a -> b
unsafeCoerce
      (Vector (Vector ℂ) -> Vector m (C n))
-> (M m n -> Vector (Vector ℂ)) -> M m n -> Vector m (C n)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector ℂ] -> Vector (Vector ℂ)
forall a. [a] -> Vector a
UV.fromList
      ([Vector ℂ] -> Vector (Vector ℂ))
-> (M m n -> [Vector ℂ]) -> M m n -> Vector (Vector ℂ)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix ℂ -> [Vector ℂ]
forall t. Element t => Matrix t -> [Vector t]
HU.toRows
      (Matrix ℂ -> [Vector ℂ])
-> (M m n -> Matrix ℂ) -> M m n -> [Vector ℂ]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M m n -> Matrix ℂ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract

-- | Join together a /vector-sized/ boxed vector of /hmatrix/ complex
-- vectors to an /hmatrix/ complex matrix as its rows.
--
-- /O(m*n)/
rowsM
    :: forall m n. KnownNat n
    => V.Vector m (H.C n)
    -> H.M m n
rowsM :: Vector m (C n) -> M m n
rowsM = (Matrix ℂ -> M m n
forall a b. a -> b
unsafeCoerce :: HU.Matrix H.ℂ -> H.M m n)
      (Matrix ℂ -> M m n)
-> (Vector m (C n) -> Matrix ℂ) -> Vector m (C n) -> M m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector ℂ] -> Matrix ℂ
forall t. Element t => [Vector t] -> Matrix t
HU.fromRows
      ([Vector ℂ] -> Matrix ℂ)
-> (Vector m (C n) -> [Vector ℂ]) -> Vector m (C n) -> Matrix ℂ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (C n -> Vector ℂ) -> [C n] -> [Vector ℂ]
forall a b. (a -> b) -> [a] -> [b]
map C n -> Vector ℂ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract
      ([C n] -> [Vector ℂ])
-> (Vector m (C n) -> [C n]) -> Vector m (C n) -> [Vector ℂ]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector m (C n) -> [C n]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList

-- | Split an /hmatrix/ complex matrix (parameterized by its dimensions) to
-- a /vector-sized/ boxed vector of its columns (as /hmatrix/ complex
-- vectors).
--
-- This is normally /O(m*n)/, but can sometimes be /O(n)/ depending on the
-- representation of the 'H.C' being used.
mCols
    :: forall m n. (KnownNat m, KnownNat n)
    => H.M m n
    -> V.Vector n (H.C m)
mCols :: M m n -> Vector n (C m)
mCols = Vector (Vector ℂ) -> Vector n (C m)
forall a b. a -> b
unsafeCoerce
      (Vector (Vector ℂ) -> Vector n (C m))
-> (M m n -> Vector (Vector ℂ)) -> M m n -> Vector n (C m)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector ℂ] -> Vector (Vector ℂ)
forall a. [a] -> Vector a
UV.fromList
      ([Vector ℂ] -> Vector (Vector ℂ))
-> (M m n -> [Vector ℂ]) -> M m n -> Vector (Vector ℂ)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix ℂ -> [Vector ℂ]
forall t. Element t => Matrix t -> [Vector t]
HU.toColumns
      (Matrix ℂ -> [Vector ℂ])
-> (M m n -> Matrix ℂ) -> M m n -> [Vector ℂ]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M m n -> Matrix ℂ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract

-- | Join together a /vector-sized/ boxed vector of /hmatrix/ complex
-- vectors to an /hmatrix/ complex matrix as its columns.
--
-- /O(m*n)/
colsM
    :: forall m n. KnownNat m
    => V.Vector n (H.C m)
    -> H.M m n
colsM :: Vector n (C m) -> M m n
colsM = (Matrix ℂ -> M m n
forall a b. a -> b
unsafeCoerce :: HU.Matrix H.ℂ -> H.M m n)
      (Matrix ℂ -> M m n)
-> (Vector n (C m) -> Matrix ℂ) -> Vector n (C m) -> M m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Vector ℂ] -> Matrix ℂ
forall t. Element t => [Vector t] -> Matrix t
HU.fromColumns
      ([Vector ℂ] -> Matrix ℂ)
-> (Vector n (C m) -> [Vector ℂ]) -> Vector n (C m) -> Matrix ℂ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (C m -> Vector ℂ) -> [C m] -> [Vector ℂ]
forall a b. (a -> b) -> [a] -> [b]
map C m -> Vector ℂ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract
      ([C m] -> [Vector ℂ])
-> (Vector n (C m) -> [C m]) -> Vector n (C m) -> [Vector ℂ]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector n (C m) -> [C m]
forall (t :: Type -> Type) a. Foldable t => t a -> [a]
toList

-- | Shape a /vector-sized/ storable vector of elements into an /hmatrix/
-- matrix.
--
-- /O(1)/
--
-- @since 0.1.1.0
vecL
    :: forall m n. KnownNat n
    => VS.Vector (m * n) H.ℝ
    -> H.L m n
vecL :: Vector (m * n) ℝ -> L m n
vecL = (Matrix ℝ -> L m n
forall a b. a -> b
unsafeCoerce :: HU.Matrix H.ℝ -> H.L m n)
     (Matrix ℝ -> L m n)
-> (Vector (m * n) ℝ -> Matrix ℝ) -> Vector (m * n) ℝ -> L m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Vector ℝ -> Matrix ℝ
forall t. Storable t => Int -> Vector t -> Matrix t
HU.reshape (Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)))
     (Vector ℝ -> Matrix ℝ)
-> (Vector (m * n) ℝ -> Vector ℝ) -> Vector (m * n) ℝ -> Matrix ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (m * n) ℝ -> Vector ℝ
forall a b. a -> b
unsafeCoerce

-- | 'vecL', but generalized to work for all types of sized vectors.
--
-- Usually /O(n)/, but if using this with storable vectors, should be /O(1)/
-- due to rewrite rules (but don't rely on this).
--
-- @since 0.1.3.0
gvecL
    :: (KnownNat n, UVG.Vector v H.ℝ)
    => VG.Vector v (m * n) H.ℝ
    -> H.L m n
gvecL :: Vector v (m * n) ℝ -> L m n
gvecL = Vector (m * n) ℝ -> L m n
forall (m :: Nat) (n :: Nat).
KnownNat n =>
Vector (m * n) ℝ -> L m n
vecL (Vector (m * n) ℝ -> L m n)
-> (Vector v (m * n) ℝ -> Vector (m * n) ℝ)
-> Vector v (m * n) ℝ
-> L m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector v (m * n) ℝ -> Vector (m * n) ℝ
forall (v :: Type -> Type) a (w :: Type -> Type) (n :: Nat).
(Vector v a, Vector w a) =>
Vector v n a -> Vector w n a
VG.convert
{-# NOINLINE[1] gvecL #-}
{-# RULES "gvecL" gvecL = vecL #-}

-- | Flatten an /hmatrix/ matrix into a /vector-sized/ storable vector of
-- its items.
--
-- This is normally /O(m*n)/, but can sometimes be /O(1)/ depending on the
-- representation of the 'H.L' being used.
--
-- @since 0.1.1.0
lVec
    :: forall m n. (KnownNat m, KnownNat n)
    => H.L m n
    -> VS.Vector (m * n) H.ℝ
lVec :: L m n -> Vector (m * n) ℝ
lVec = Vector ℝ -> Vector (m * n) ℝ
forall a b. a -> b
unsafeCoerce
     (Vector ℝ -> Vector (m * n) ℝ)
-> (L m n -> Vector ℝ) -> L m n -> Vector (m * n) ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix ℝ -> Vector ℝ
forall t. Element t => Matrix t -> Vector t
HU.flatten
     (Matrix ℝ -> Vector ℝ) -> (L m n -> Matrix ℝ) -> L m n -> Vector ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. L m n -> Matrix ℝ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract

-- | 'lVec', but generalized to work for all types of sized vectors.
--
-- Usually /O(m*n)/, but if using this with storable vectors, should have the
-- same characteristics as 'lVec' due to rewrite rules.
--
-- @since 0.1.3.0
glVec
    :: (KnownNat m, KnownNat n, UVG.Vector v H.ℝ)
    => H.L m n
    -> VG.Vector v (m * n) H.ℝ
glVec :: L m n -> Vector v (m * n) ℝ
glVec = Vector Vector (m * n) ℝ -> Vector v (m * n) ℝ
forall (v :: Type -> Type) a (w :: Type -> Type) (n :: Nat).
(Vector v a, Vector w a) =>
Vector v n a -> Vector w n a
VG.convert (Vector Vector (m * n) ℝ -> Vector v (m * n) ℝ)
-> (L m n -> Vector Vector (m * n) ℝ)
-> L m n
-> Vector v (m * n) ℝ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. L m n -> Vector Vector (m * n) ℝ
forall (m :: Nat) (n :: Nat).
(KnownNat m, KnownNat n) =>
L m n -> Vector (m * n) ℝ
lVec
{-# NOINLINE[1] glVec #-}
{-# RULES "glVec" glVec = lVec #-}

-- | Shape a /vector-sized/ storable vector of elements into an /hmatrix/
-- complex matrix.
--
-- /O(1)/
--
-- @since 0.1.1.0
vecM
    :: forall m n. KnownNat n
    => VS.Vector (m * n) H.ℂ
    -> H.M m n
vecM :: Vector (m * n) ℂ -> M m n
vecM = (Matrix ℂ -> M m n
forall a b. a -> b
unsafeCoerce :: HU.Matrix H.ℂ -> H.M m n)
     (Matrix ℂ -> M m n)
-> (Vector (m * n) ℂ -> Matrix ℂ) -> Vector (m * n) ℂ -> M m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Vector ℂ -> Matrix ℂ
forall t. Storable t => Int -> Vector t -> Matrix t
HU.reshape (Integer -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Proxy n -> Integer
forall (n :: Nat) (proxy :: Nat -> Type).
KnownNat n =>
proxy n -> Integer
natVal (Proxy n
forall k (t :: k). Proxy t
Proxy @n)))
     (Vector ℂ -> Matrix ℂ)
-> (Vector (m * n) ℂ -> Vector ℂ) -> Vector (m * n) ℂ -> Matrix ℂ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector (m * n) ℂ -> Vector ℂ
forall a b. a -> b
unsafeCoerce

-- | 'vecM', but generalized to work for all types of sized vectors.
--
-- Usually /O(m*n)/, but if using this with storable vectors, should be /O(1)/
-- due to rewrite rules (but don't rely on this).
--
-- @since 0.1.3.0
gvecM
    :: (KnownNat n, UVG.Vector v H.ℂ)
    => VG.Vector v (m * n) H.ℂ
    -> H.M m n
gvecM :: Vector v (m * n) ℂ -> M m n
gvecM = Vector (m * n) ℂ -> M m n
forall (m :: Nat) (n :: Nat).
KnownNat n =>
Vector (m * n) ℂ -> M m n
vecM (Vector (m * n) ℂ -> M m n)
-> (Vector v (m * n) ℂ -> Vector (m * n) ℂ)
-> Vector v (m * n) ℂ
-> M m n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector v (m * n) ℂ -> Vector (m * n) ℂ
forall (v :: Type -> Type) a (w :: Type -> Type) (n :: Nat).
(Vector v a, Vector w a) =>
Vector v n a -> Vector w n a
VG.convert
{-# NOINLINE[1] gvecM #-}
{-# RULES "gvecM" gvecM = vecM #-}

-- | Flatten an /hmatrix/ complex matrix into a /vector-sized/ storable
-- vector of its items.
--
-- This is normally /O(m*n)/, but can sometimes be /O(1)/ depending on the
-- representation of the 'H.M' being used.
--
-- @since 0.1.1.0
mVec
    :: forall m n. (KnownNat m, KnownNat n)
    => H.M m n
    -> VS.Vector (m * n) H.ℂ
mVec :: M m n -> Vector (m * n) ℂ
mVec = Vector ℂ -> Vector (m * n) ℂ
forall a b. a -> b
unsafeCoerce
     (Vector ℂ -> Vector (m * n) ℂ)
-> (M m n -> Vector ℂ) -> M m n -> Vector (m * n) ℂ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Matrix ℂ -> Vector ℂ
forall t. Element t => Matrix t -> Vector t
HU.flatten
     (Matrix ℂ -> Vector ℂ) -> (M m n -> Matrix ℂ) -> M m n -> Vector ℂ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M m n -> Matrix ℂ
forall t s (d :: Type -> Type). Sized t s d => s -> d t
H.extract

-- | 'mVec', but generalized to work for all types of sized vectors.
--
-- Usually /O(m*n)/, but if using this with storable vectors, should have the
-- same characteristics as 'mVec' due to rewrite rules.
--
-- @since 0.1.3.0
gmVec
    :: (KnownNat m, KnownNat n, UVG.Vector v H.ℂ)
    => H.M m n
    -> VG.Vector v (m * n) H.ℂ
gmVec :: M m n -> Vector v (m * n) ℂ
gmVec = Vector Vector (m * n) ℂ -> Vector v (m * n) ℂ
forall (v :: Type -> Type) a (w :: Type -> Type) (n :: Nat).
(Vector v a, Vector w a) =>
Vector v n a -> Vector w n a
VG.convert (Vector Vector (m * n) ℂ -> Vector v (m * n) ℂ)
-> (M m n -> Vector Vector (m * n) ℂ)
-> M m n
-> Vector v (m * n) ℂ
forall b c a. (b -> c) -> (a -> b) -> a -> c
. M m n -> Vector Vector (m * n) ℂ
forall (m :: Nat) (n :: Nat).
(KnownNat m, KnownNat n) =>
M m n -> Vector (m * n) ℂ
mVec
{-# NOINLINE[1] gmVec #-}
{-# RULES "gmVec" gmVec = mVec #-}