{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.Permutation (
   Permutation,
   size,
   identity,
   Mod.Inversion(NonInverted,Inverted),
   Perm.inversionFromTransposition,
   fromPermutation,
   toPermutation,
   toSquare,
   determinant,
   transpose,
   multiplyVector,
   multiplyFull,
   ) where

import qualified Numeric.LAPACK.Matrix.Array.Private as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Type.Private as Matrix
import qualified Numeric.LAPACK.Matrix.Shape.Omni as Omni
import qualified Numeric.LAPACK.Matrix.Layout.Private as Layout
import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import qualified Numeric.LAPACK.Matrix.Modifier as Mod
import qualified Numeric.LAPACK.Permutation.Private as Plain
import qualified Numeric.LAPACK.Permutation as Perm
import Numeric.LAPACK.Matrix.Type.Private (Matrix(Permutation))
import Numeric.LAPACK.Vector (Vector)

import qualified Numeric.Netlib.Class as Class

import qualified Data.Array.Comfort.Shape as Shape


type Permutation sh =
      FlexPermutation Layout.Filled Layout.Filled sh
type FlexPermutation lower upper sh =
      Matrix.Quadratic Matrix.Permutation () () lower upper sh

size :: FlexPermutation lower upper sh a -> sh
size :: FlexPermutation lower upper sh a -> sh
size (Permutation perm) = Permutation sh -> sh
forall sh. Permutation sh -> sh
Perm.size Permutation sh
perm

identity :: (Shape.C sh) => sh -> FlexPermutation lower upper sh a
identity :: sh -> FlexPermutation lower upper sh a
identity = Permutation sh -> FlexPermutation lower upper sh a
forall sh lower upper a.
Permutation sh -> Quadratic Permutation () () lower upper sh a
Permutation (Permutation sh -> FlexPermutation lower upper sh a)
-> (sh -> Permutation sh) -> sh -> FlexPermutation lower upper sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. sh -> Permutation sh
forall sh. C sh => sh -> Permutation sh
Perm.identity

fromPermutation ::
   (Shape.C sh) => Perm.Permutation sh -> Permutation sh a
fromPermutation :: Permutation sh -> Permutation sh a
fromPermutation = Permutation sh -> Permutation sh a
forall sh lower upper a.
Permutation sh -> Quadratic Permutation () () lower upper sh a
Permutation

toPermutation ::
   (Shape.C sh) => FlexPermutation lower upper sh a -> Perm.Permutation sh
toPermutation :: FlexPermutation lower upper sh a -> Permutation sh
toPermutation (Permutation perm) = Permutation sh
perm

determinant ::
   (Shape.C sh, Class.Floating a) => FlexPermutation lower upper sh a -> a
determinant :: FlexPermutation lower upper sh a -> a
determinant (Permutation perm) = Sign -> a
forall a. Floating a => Sign -> a
Perm.numberFromSign (Sign -> a) -> Sign -> a
forall a b. (a -> b) -> a -> b
$ Permutation sh -> Sign
forall sh. C sh => Permutation sh -> Sign
Perm.determinant Permutation sh
perm


transpose ::
   (Shape.C sh) =>
   FlexPermutation lower upper sh a -> FlexPermutation upper lower sh a
transpose :: FlexPermutation lower upper sh a
-> FlexPermutation upper lower sh a
transpose (Permutation perm) = Permutation sh -> FlexPermutation upper lower sh a
forall sh lower upper a.
Permutation sh -> Quadratic Permutation () () lower upper sh a
Permutation (Permutation sh -> FlexPermutation upper lower sh a)
-> Permutation sh -> FlexPermutation upper lower sh a
forall a b. (a -> b) -> a -> b
$ Permutation sh -> Permutation sh
forall sh. C sh => Permutation sh -> Permutation sh
Perm.transpose Permutation sh
perm

toSquare ::
   (Omni.Strip lower, Omni.Strip upper, Shape.C sh, Class.Floating a) =>
   FlexPermutation lower upper sh a ->
   ArrMatrix.Quadratic Layout.Unpacked Omni.Arbitrary lower upper sh a
toSquare :: FlexPermutation lower upper sh a
-> Quadratic Unpacked Arbitrary lower upper sh a
toSquare (Permutation perm) = FullArray Shape Small Small sh sh a
-> Quadratic Unpacked Arbitrary lower upper sh a
forall propertyA lowerA upperA measA vertA horizA heightA widthA a.
(Property propertyA, Strip lowerA, Strip upperA) =>
FullArray measA vertA horizA heightA widthA a
-> UnpackedMatrix
     propertyA lowerA upperA measA vertA horizA heightA widthA a
ArrMatrix.liftUnpacked0 (FullArray Shape Small Small sh sh a
 -> Quadratic Unpacked Arbitrary lower upper sh a)
-> FullArray Shape Small Small sh sh a
-> Quadratic Unpacked Arbitrary lower upper sh a
forall a b. (a -> b) -> a -> b
$ Permutation sh -> FullArray Shape Small Small sh sh a
forall sh a. (C sh, Floating a) => Permutation sh -> Square sh a
Plain.toMatrix Permutation sh
perm

multiplyVector ::
   (Shape.C size, Eq size, Class.Floating a) =>
   Mod.Inversion -> FlexPermutation lower upper size a ->
   Vector size a -> Vector size a
multiplyVector :: Inversion
-> FlexPermutation lower upper size a
-> Vector size a
-> Vector size a
multiplyVector Inversion
inverted (Permutation perm) =
   Order
-> (General size () a -> General size () a)
-> Vector size a
-> Vector size a
forall height0 a height1 b.
Order
-> (General height0 () a -> General height1 () b)
-> Vector height0 a
-> Vector height1 b
ArrMatrix.unliftColumn Order
Layout.ColumnMajor (Inversion
-> Permutation size -> General size () a -> General size () a
forall meas vert horiz height width a.
(Measure meas, C vert, C horiz, C height, Eq height, C width,
 Floating a) =>
Inversion
-> Permutation height
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
Perm.apply Inversion
inverted Permutation size
perm)

multiplyFull ::
   (Extent.Measure meas, Extent.C vert, Extent.C horiz,
    Shape.C height, Eq height, Shape.C width, Class.Floating a) =>
   Mod.Inversion -> FlexPermutation lower upper height a ->
   ArrMatrix.Full meas vert horiz height width a ->
   ArrMatrix.Full meas vert horiz height width a
multiplyFull :: Inversion
-> FlexPermutation lower upper height a
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
multiplyFull Inversion
inverted (Permutation perm) = Inversion
-> Permutation height
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
forall meas vert horiz height width a.
(Measure meas, C vert, C horiz, C height, Eq height, C width,
 Floating a) =>
Inversion
-> Permutation height
-> Full meas vert horiz height width a
-> Full meas vert horiz height width a
Perm.apply Inversion
inverted Permutation height
perm