{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.Indexed where

import qualified Numeric.LAPACK.Matrix.Array.Indexed as ArrIndexed
import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import qualified Numeric.LAPACK.Matrix.Array.Private as ArrMatrix
import qualified Numeric.LAPACK.Matrix.Type.Private as Matrix
import qualified Numeric.LAPACK.Permutation as Perm
import Numeric.LAPACK.Matrix.Type.Private (Matrix)
import Numeric.LAPACK.Scalar (one, zero)
import Numeric.LAPACK.Permutation.Private (Permutation(Permutation))

import qualified Numeric.Netlib.Class as Class

import qualified Data.Array.Comfort.Storable.Unchecked as Array
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable ((!))


infixl 9 #!

class (Matrix.Box typ) => Indexed typ where
   (#!) ::
      (Extent.Measure meas, Extent.C vert, Extent.C horiz,
       Shape.Indexed height, Shape.Indexed width, Class.Floating a) =>
      Matrix typ xl xu lower upper meas vert horiz height width a ->
      (Shape.Index height, Shape.Index width) -> a

instance Indexed (ArrMatrix.Array pack property) where
   #! :: Matrix
  (Array pack property)
  xl
  xu
  lower
  upper
  meas
  vert
  horiz
  height
  width
  a
-> (Index height, Index width) -> a
(#!) a :: Matrix
  (Array pack property)
  xl
  xu
  lower
  upper
  meas
  vert
  horiz
  height
  width
  a
a@(ArrMatrix.Array _) = ArrayMatrix
  pack property lower upper meas vert horiz height width a
-> (Index height, Index width) -> a
forall meas vert horiz height width a pack property lower upper.
(Measure meas, C vert, C horiz, Indexed height, Indexed width,
 Floating a) =>
ArrayMatrix
  pack property lower upper meas vert horiz height width a
-> (Index height, Index width) -> a
(ArrIndexed.#!) Matrix
  (Array pack property)
  xl
  xu
  lower
  upper
  meas
  vert
  horiz
  height
  width
  a
ArrayMatrix
  pack property lower upper meas vert horiz height width a
a

instance Indexed Matrix.Scale where
   Matrix.Scale sh a #! :: Matrix Scale xl xu lower upper meas vert horiz height width a
-> (Index height, Index width) -> a
#! (Index height
i,Index width
j) =
      if height -> Index height -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset height
sh Index height
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== height -> Index height -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset height
sh Index height
Index width
j then a
a else a
forall a. Floating a => a
zero

instance Indexed Matrix.Permutation where
   Matrix.Permutation (Permutation perm) #! :: Matrix Permutation xl xu lower upper meas vert horiz height width a
-> (Index height, Index width) -> a
#! (Index height
i,Index width
j) =
      let psh :: Shape height
psh@(Perm.Shape height
sh) = Array (Shape height) (Element height) -> Shape height
forall sh a. Array sh a -> sh
Array.shape Array (Shape height) (Element height)
perm
          reindex :: Index height -> Element height
reindex = Shape height -> Int -> Index (Shape height)
forall sh. InvIndexed sh => sh -> Int -> Index sh
Shape.indexFromOffset Shape height
psh (Int -> Element height)
-> (Index height -> Int) -> Index height -> Element height
forall b c a. (b -> c) -> (a -> b) -> a -> c
. height -> Index height -> Int
forall sh. Indexed sh => sh -> Index sh -> Int
Shape.offset height
sh
      in if Array (Shape height) (Element height)
perm Array (Shape height) (Element height)
-> Index (Shape height) -> Element height
forall sh a.
(Indexed sh, Storable a) =>
Array sh a -> Index sh -> a
! Index height -> Element height
reindex Index height
i Element height -> Element height -> Bool
forall a. Eq a => a -> a -> Bool
== Index height -> Element height
reindex Index height
Index width
j then a
forall a. Floating a => a
one else a
forall a. Floating a => a
zero