{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
module Numeric.LAPACK.Matrix.Mosaic.Basic (
   Mosaic.fromList,
   Mosaic.autoFromList,

   Mosaic.transpose,
   Mosaic.adjoint,

   Mosaic.repack,
   pack,
   unpack,
   reunpack,
   Mosaic.unpackDirty,

   Mos.takeUpper,
   Mos.fromUpper,

   takeDiagonal,
   toSquare,
   square,
   power,
   powers1,
   ) where

import qualified Numeric.LAPACK.Matrix.Symmetric.Unified as Symmetric
import qualified Numeric.LAPACK.Matrix.Mosaic.Unpacked as Unpacked
import qualified Numeric.LAPACK.Matrix.Mosaic.Packed as Packed
import qualified Numeric.LAPACK.Matrix.Mosaic.Generic as Mosaic
import qualified Numeric.LAPACK.Matrix.Mosaic.Private as Mos
import qualified Numeric.LAPACK.Matrix.Triangular.Basic as Triangular
import qualified Numeric.LAPACK.Matrix.Square.Basic as Square
import qualified Numeric.LAPACK.Matrix.Basic as Basic
import qualified Numeric.LAPACK.Matrix.Layout.Private as Layout
import Numeric.LAPACK.Matrix.Mosaic.Private (Mosaic)
import Numeric.LAPACK.Matrix.Shape.Omni (TriDiag, DiagSingleton)
import Numeric.LAPACK.Matrix.Private (Square)
import Numeric.LAPACK.Vector (Vector)

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.Stream (Stream)


takeDiagonal ::
   (Layout.UpLo uplo, Shape.C sh, Class.Floating a) =>
   Mosaic pack mirror uplo sh a -> Vector sh a
takeDiagonal :: Mosaic pack mirror uplo sh a -> Vector sh a
takeDiagonal Mosaic pack mirror uplo sh a
a =
   case Mosaic pack mirror uplo sh -> PackingSingleton pack
forall pack mirror uplo size.
Mosaic pack mirror uplo size -> PackingSingleton pack
Layout.mosaicPack (Mosaic pack mirror uplo sh -> PackingSingleton pack)
-> Mosaic pack mirror uplo sh -> PackingSingleton pack
forall a b. (a -> b) -> a -> b
$ Mosaic pack mirror uplo sh a -> Mosaic pack mirror uplo sh
forall sh a. Array sh a -> sh
Array.shape Mosaic pack mirror uplo sh a
a of
      PackingSingleton pack
Layout.Unpacked -> Square sh a -> Vector sh a
forall sh a. (C sh, Floating a) => Square sh a -> Vector sh a
Square.takeDiagonal (Square sh a -> Vector sh a) -> Square sh a -> Vector sh a
forall a b. (a -> b) -> a -> b
$ Mosaic mirror uplo sh a -> Square sh a
forall mirror uplo sh a. Mosaic mirror uplo sh a -> Square sh a
Unpacked.toSquare Mosaic pack mirror uplo sh a
Mosaic mirror uplo sh a
a
      PackingSingleton pack
Layout.Packed -> Mosaic mirror uplo sh a -> Vector sh a
forall uplo sh a mirror.
(UpLo uplo, C sh, Floating a) =>
Mosaic mirror uplo sh a -> Vector sh a
Packed.takeDiagonal Mosaic pack mirror uplo sh a
Mosaic mirror uplo sh a
a

toSquare ::
   (Layout.UpLo uplo, Shape.C sh, Class.Floating a) =>
   Packed.Mosaic mirror uplo sh a -> Square sh a
toSquare :: Mosaic mirror uplo sh a -> Square sh a
toSquare Mosaic mirror uplo sh a
a =
   let shape :: Mosaic Packed mirror uplo sh
shape = Mosaic mirror uplo sh a -> Mosaic Packed mirror uplo sh
forall sh a. Array sh a -> sh
Array.shape Mosaic mirror uplo sh a
a
   in case Mosaic Packed mirror uplo sh -> MirrorSingleton mirror
forall pack mirror uplo size.
Mosaic pack mirror uplo size -> MirrorSingleton mirror
Layout.mosaicMirror Mosaic Packed mirror uplo sh
shape of
         MirrorSingleton mirror
Layout.NoMirror -> Triangular uplo sh a -> Square sh a
forall uplo sh a.
(UpLo uplo, C sh, Floating a) =>
Triangular uplo sh a -> Square sh a
Triangular.toSquare Mosaic mirror uplo sh a
Triangular uplo sh a
a
         MirrorSingleton mirror
Layout.SimpleMirror ->
            case Mosaic Packed mirror uplo sh -> UpLoSingleton uplo
forall pack mirror uplo size.
Mosaic pack mirror uplo size -> UpLoSingleton uplo
Layout.mosaicUplo Mosaic Packed mirror uplo sh
shape of
               UpLoSingleton uplo
Layout.Upper -> Mosaic mirror Upper sh a -> Square sh a
forall mirror sh a.
(Mirror mirror, C sh, Floating a) =>
Mosaic mirror Upper sh a -> Square sh a
Symmetric.toSquare Mosaic mirror uplo sh a
Mosaic mirror Upper sh a
a
               UpLoSingleton uplo
Layout.Lower ->
                  Square sh a -> Square sh a
forall meas vert horiz height width a.
(Measure meas, C vert, C horiz) =>
Full meas vert horiz height width a
-> Full meas horiz vert width height a
Basic.transpose (Square sh a -> Square sh a) -> Square sh a -> Square sh a
forall a b. (a -> b) -> a -> b
$ Mosaic mirror Upper sh a -> Square sh a
forall mirror sh a.
(Mirror mirror, C sh, Floating a) =>
Mosaic mirror Upper sh a -> Square sh a
Symmetric.toSquare (Mosaic mirror Upper sh a -> Square sh a)
-> Mosaic mirror Upper sh a -> Square sh a
forall a b. (a -> b) -> a -> b
$ Mosaic mirror uplo sh a
-> Mosaic Packed mirror (TriTransposed uplo) sh a
forall uplo pack mirror sh a.
UpLo uplo =>
Mosaic pack mirror uplo sh a
-> Mosaic pack mirror (TriTransposed uplo) sh a
Mosaic.transpose Mosaic mirror uplo sh a
a
         MirrorSingleton mirror
Layout.ConjugateMirror ->
            case Mosaic Packed mirror uplo sh -> UpLoSingleton uplo
forall pack mirror uplo size.
Mosaic pack mirror uplo size -> UpLoSingleton uplo
Layout.mosaicUplo Mosaic Packed mirror uplo sh
shape of
               UpLoSingleton uplo
Layout.Upper -> Mosaic mirror Upper sh a -> Square sh a
forall mirror sh a.
(Mirror mirror, C sh, Floating a) =>
Mosaic mirror Upper sh a -> Square sh a
Symmetric.toSquare Mosaic mirror uplo sh a
Mosaic mirror Upper sh a
a
               UpLoSingleton uplo
Layout.Lower ->
                  Square sh a -> Square sh a
forall meas vert horiz height width a.
(Measure meas, C vert, C horiz) =>
Full meas vert horiz height width a
-> Full meas horiz vert width height a
Basic.transpose (Square sh a -> Square sh a) -> Square sh a -> Square sh a
forall a b. (a -> b) -> a -> b
$ Mosaic mirror Upper sh a -> Square sh a
forall mirror sh a.
(Mirror mirror, C sh, Floating a) =>
Mosaic mirror Upper sh a -> Square sh a
Symmetric.toSquare (Mosaic mirror Upper sh a -> Square sh a)
-> Mosaic mirror Upper sh a -> Square sh a
forall a b. (a -> b) -> a -> b
$ Mosaic mirror uplo sh a
-> Mosaic Packed mirror (TriTransposed uplo) sh a
forall uplo pack mirror sh a.
UpLo uplo =>
Mosaic pack mirror uplo sh a
-> Mosaic pack mirror (TriTransposed uplo) sh a
Mosaic.transpose Mosaic mirror uplo sh a
a

pack ::
   (Layout.UpLo uplo, Shape.C sh, Class.Floating a) =>
   Mosaic pack mirror uplo sh a -> Packed.Mosaic mirror uplo sh a
pack :: Mosaic pack mirror uplo sh a -> Mosaic mirror uplo sh a
pack Mosaic pack mirror uplo sh a
a =
   case Mosaic pack mirror uplo sh -> PackingSingleton pack
forall pack mirror uplo size.
Mosaic pack mirror uplo size -> PackingSingleton pack
Layout.mosaicPack (Mosaic pack mirror uplo sh -> PackingSingleton pack)
-> Mosaic pack mirror uplo sh -> PackingSingleton pack
forall a b. (a -> b) -> a -> b
$ Mosaic pack mirror uplo sh a -> Mosaic pack mirror uplo sh
forall sh a. Array sh a -> sh
Array.shape Mosaic pack mirror uplo sh a
a of
      PackingSingleton pack
Layout.Packed -> Mosaic pack mirror uplo sh a
Mosaic mirror uplo sh a
a
      PackingSingleton pack
Layout.Unpacked -> MosaicUnpacked mirror uplo sh a -> Mosaic mirror uplo sh a
forall uplo sh a mirror.
(UpLo uplo, C sh, Floating a) =>
MosaicUnpacked mirror uplo sh a -> MosaicPacked mirror uplo sh a
Mosaic.pack Mosaic pack mirror uplo sh a
MosaicUnpacked mirror uplo sh a
a

unpack ::
   (Layout.UpLo uplo, Shape.C sh, Class.Floating a) =>
   Mosaic pack mirror uplo sh a -> Unpacked.Mosaic mirror uplo sh a
unpack :: Mosaic pack mirror uplo sh a -> Mosaic mirror uplo sh a
unpack Mosaic pack mirror uplo sh a
a =
   let shape :: Mosaic pack mirror uplo sh
shape = Mosaic pack mirror uplo sh a -> Mosaic pack mirror uplo sh
forall sh a. Array sh a -> sh
Array.shape Mosaic pack mirror uplo sh a
a in
   case Mosaic pack mirror uplo sh -> PackingSingleton pack
forall pack mirror uplo size.
Mosaic pack mirror uplo size -> PackingSingleton pack
Layout.mosaicPack Mosaic pack mirror uplo sh
shape of
      PackingSingleton pack
Layout.Unpacked -> Mosaic pack mirror uplo sh a
Mosaic mirror uplo sh a
a
      PackingSingleton pack
Layout.Packed ->
         MirrorSingleton mirror -> Square sh a -> Mosaic mirror uplo sh a
forall uplo mirror sh a.
UpLo uplo =>
MirrorSingleton mirror -> Square sh a -> Mosaic mirror uplo sh a
Unpacked.fromSquare (Mosaic pack mirror uplo sh -> MirrorSingleton mirror
forall pack mirror uplo size.
Mosaic pack mirror uplo size -> MirrorSingleton mirror
Layout.mosaicMirror Mosaic pack mirror uplo sh
shape) (Square sh a -> Mosaic mirror uplo sh a)
-> Square sh a -> Mosaic mirror uplo sh a
forall a b. (a -> b) -> a -> b
$ Mosaic mirror uplo sh a -> Square sh a
forall uplo sh a mirror.
(UpLo uplo, C sh, Floating a) =>
Mosaic mirror uplo sh a -> Square sh a
toSquare Mosaic pack mirror uplo sh a
Mosaic mirror uplo sh a
a

reunpack ::
   (Layout.Packing pack, Layout.UpLo uplo, Shape.C sh, Class.Floating a) =>
   Packed.Mosaic mirror uplo sh a -> Mosaic pack mirror uplo sh a
reunpack :: Mosaic mirror uplo sh a -> Mosaic pack mirror uplo sh a
reunpack Mosaic mirror uplo sh a
a = (PackingSingleton pack -> Mosaic pack mirror uplo sh a)
-> Mosaic pack mirror uplo sh a
forall pack mirror uplo sh a.
Packing pack =>
(PackingSingleton pack -> Mosaic pack mirror uplo sh a)
-> Mosaic pack mirror uplo sh a
Mosaic.withPack ((PackingSingleton pack -> Mosaic pack mirror uplo sh a)
 -> Mosaic pack mirror uplo sh a)
-> (PackingSingleton pack -> Mosaic pack mirror uplo sh a)
-> Mosaic pack mirror uplo sh a
forall a b. (a -> b) -> a -> b
$ \PackingSingleton pack
packing ->
   case PackingSingleton pack
packing of
      PackingSingleton pack
Layout.Unpacked -> Mosaic mirror uplo sh a -> Mosaic mirror uplo sh a
forall uplo sh a pack mirror.
(UpLo uplo, C sh, Floating a) =>
Mosaic pack mirror uplo sh a -> Mosaic mirror uplo sh a
unpack Mosaic mirror uplo sh a
a
      PackingSingleton pack
Layout.Packed -> Mosaic pack mirror uplo sh a
Mosaic mirror uplo sh a
a


square ::
   (Layout.Packing pack, TriDiag diag, Layout.UpLo uplo,
    Shape.C sh, Class.Floating a) =>
   DiagSingleton diag ->
   Mosaic pack mirror uplo sh a -> Mosaic pack mirror uplo sh a
square :: DiagSingleton diag
-> Mosaic pack mirror uplo sh a -> Mosaic pack mirror uplo sh a
square DiagSingleton diag
diag = MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a
forall pack uplo sh a mirror.
(Packing pack, UpLo uplo, C sh, Floating a) =>
MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a
Mosaic.repack (MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a)
-> (Mosaic pack mirror uplo sh a
    -> MosaicUnpacked mirror uplo sh a)
-> Mosaic pack mirror uplo sh a
-> Mosaic pack mirror uplo sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiagSingleton diag
-> MosaicUnpacked mirror uplo sh a
-> MosaicUnpacked mirror uplo sh a
forall diag uplo sh a mirror.
(TriDiag diag, UpLo uplo, C sh, Floating a) =>
DiagSingleton diag
-> Mosaic mirror uplo sh a -> Mosaic mirror uplo sh a
Unpacked.square DiagSingleton diag
diag (MosaicUnpacked mirror uplo sh a
 -> MosaicUnpacked mirror uplo sh a)
-> (Mosaic pack mirror uplo sh a
    -> MosaicUnpacked mirror uplo sh a)
-> Mosaic pack mirror uplo sh a
-> MosaicUnpacked mirror uplo sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mosaic pack mirror uplo sh a -> MosaicUnpacked mirror uplo sh a
forall uplo sh a pack mirror.
(UpLo uplo, C sh, Floating a) =>
Mosaic pack mirror uplo sh a -> Mosaic mirror uplo sh a
unpack

power ::
   (Layout.Packing pack, TriDiag diag, Layout.UpLo uplo,
    Shape.C sh, Class.Floating a) =>
   DiagSingleton diag ->
   Integer -> Mosaic pack mirror uplo sh a -> Mosaic pack mirror uplo sh a
power :: DiagSingleton diag
-> Integer
-> Mosaic pack mirror uplo sh a
-> Mosaic pack mirror uplo sh a
power DiagSingleton diag
diag Integer
n = MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a
forall pack uplo sh a mirror.
(Packing pack, UpLo uplo, C sh, Floating a) =>
MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a
Mosaic.repack (MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a)
-> (Mosaic pack mirror uplo sh a
    -> MosaicUnpacked mirror uplo sh a)
-> Mosaic pack mirror uplo sh a
-> Mosaic pack mirror uplo sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiagSingleton diag
-> Integer
-> MosaicUnpacked mirror uplo sh a
-> MosaicUnpacked mirror uplo sh a
forall uplo diag sh a mirror.
(UpLo uplo, TriDiag diag, C sh, Floating a) =>
DiagSingleton diag
-> Integer -> Mosaic mirror uplo sh a -> Mosaic mirror uplo sh a
Unpacked.power DiagSingleton diag
diag Integer
n (MosaicUnpacked mirror uplo sh a
 -> MosaicUnpacked mirror uplo sh a)
-> (Mosaic pack mirror uplo sh a
    -> MosaicUnpacked mirror uplo sh a)
-> Mosaic pack mirror uplo sh a
-> MosaicUnpacked mirror uplo sh a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mosaic pack mirror uplo sh a -> MosaicUnpacked mirror uplo sh a
forall uplo sh a pack mirror.
(UpLo uplo, C sh, Floating a) =>
Mosaic pack mirror uplo sh a -> Mosaic mirror uplo sh a
unpack

powers1 ::
   (Layout.Packing pack, TriDiag diag, Layout.UpLo uplo,
    Shape.C sh, Class.Floating a) =>
   DiagSingleton diag ->
   Mosaic pack mirror uplo sh a -> Stream (Mosaic pack mirror uplo sh a)
powers1 :: DiagSingleton diag
-> Mosaic pack mirror uplo sh a
-> Stream (Mosaic pack mirror uplo sh a)
powers1 DiagSingleton diag
diag = (MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a)
-> Stream (MosaicUnpacked mirror uplo sh a)
-> Stream (Mosaic pack mirror uplo sh a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a
forall pack uplo sh a mirror.
(Packing pack, UpLo uplo, C sh, Floating a) =>
MosaicUnpacked mirror uplo sh a -> Mosaic pack mirror uplo sh a
Mosaic.repack (Stream (MosaicUnpacked mirror uplo sh a)
 -> Stream (Mosaic pack mirror uplo sh a))
-> (Mosaic pack mirror uplo sh a
    -> Stream (MosaicUnpacked mirror uplo sh a))
-> Mosaic pack mirror uplo sh a
-> Stream (Mosaic pack mirror uplo sh a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DiagSingleton diag
-> MosaicUnpacked mirror uplo sh a
-> Stream (MosaicUnpacked mirror uplo sh a)
forall uplo diag sh a mirror.
(UpLo uplo, TriDiag diag, C sh, Floating a) =>
DiagSingleton diag
-> Mosaic mirror uplo sh a -> Stream (Mosaic mirror uplo sh a)
Unpacked.powers1 DiagSingleton diag
diag (MosaicUnpacked mirror uplo sh a
 -> Stream (MosaicUnpacked mirror uplo sh a))
-> (Mosaic pack mirror uplo sh a
    -> MosaicUnpacked mirror uplo sh a)
-> Mosaic pack mirror uplo sh a
-> Stream (MosaicUnpacked mirror uplo sh a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Mosaic pack mirror uplo sh a -> MosaicUnpacked mirror uplo sh a
forall uplo sh a pack mirror.
(UpLo uplo, C sh, Floating a) =>
Mosaic pack mirror uplo sh a -> Mosaic mirror uplo sh a
unpack