module Numeric.LAPACK.Matrix.Layout (
   General,
   Tall,
   Wide,
   Square,
   Full(..), fullHeight, fullWidth,
   Order(..), flipOrder,
   general,
   square,
   liberalSquare,
   wide,
   tall,

   Split,
   SplitGeneral,
   Triangle(..),
   Reflector(..),
   splitGeneral,
   splitFromFull,

   Mosaic(..),
   Packing(..), PackingSingleton(..), Packed, Unpacked,
   Mirror(..), MirrorSingleton(..),
   autoUplo,
   Triangular,
   LowerTriangular, LowerTriangularP,
   lowerTriangular, lowerTriangularP,
   UpperTriangular, UpperTriangularP,
   upperTriangular, upperTriangularP,
   Symmetric,       SymmetricP,
   symmetric,       symmetricP,
   Hermitian,       HermitianP,
   hermitian,       hermitianP,

   Diagonal,
   diagonal,
   Banded(..),
   BandedGeneral,
   BandedSquare,
   BandedLowerTriangular,
   BandedUpperTriangular,
   BandedIndex(..),
   bandedGeneral,
   bandedSquare,
   bandedFromFull,
   UnaryProxy,
   addOffDiagonals,

   BandedHermitian(..),
   bandedHermitian,
   ) where

import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import Numeric.LAPACK.Matrix.Layout.Private


type SplitGeneral lower height width =
      Split lower Extent.Size Extent.Big Extent.Big height width

splitGeneral ::
   lower -> Order -> height -> width -> SplitGeneral lower height width
splitGeneral lowerPart order height width =
   Split lowerPart order $ Extent.general height width

splitFromFull ::
   lower ->
   Full meas vert horiz height width ->
   Split lower meas vert horiz height width
splitFromFull lowerPart (Full order extent) = Split lowerPart order extent


diagonal :: Order -> size -> Diagonal size
diagonal order = Banded (u0,u0) order . Extent.square


bandedFromFull ::
   (UnaryProxy sub, UnaryProxy super) ->
   Full meas vert horiz height width ->
   Banded sub super meas vert horiz height width
bandedFromFull offDiag (Full order extent) = Banded offDiag order extent


bandedHermitian :: UnaryProxy off -> Order -> size -> BandedHermitian off size
bandedHermitian = BandedHermitian