{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ConstraintKinds #-}
module Numeric.LAPACK.Matrix.Plain.Format where

import qualified Numeric.LAPACK.Matrix.Shape.Private as MatrixShape
import qualified Numeric.LAPACK.Matrix.Extent.Private as Extent
import qualified Numeric.LAPACK.Vector as Vector
import qualified Numeric.LAPACK.Output as Output
import Numeric.LAPACK.Output (Output, formatRow, (<+>))
import Numeric.LAPACK.Matrix.Shape.Private
         (Order(RowMajor, ColumnMajor), Filled(Filled), UnaryProxy)
import Numeric.LAPACK.Matrix.Private (Full)
import Numeric.LAPACK.Scalar (conjugate)
import Numeric.LAPACK.Private (caseRealComplexFunc)

import qualified Numeric.Netlib.Class as Class

import qualified Type.Data.Num.Unary.Literal as TypeNum
import qualified Type.Data.Num.Unary as Unary
import Type.Data.Num (integralFromProxy)

import qualified Data.Array.Comfort.Storable.Unchecked as Array
import qualified Data.Array.Comfort.Boxed as BoxedArray
import qualified Data.Array.Comfort.Shape as Shape
import Data.Array.Comfort.Storable (Array)
import Data.Array.Comfort.Shape ((:+:))

import Text.Printf (PrintfArg, printf)

import qualified Data.List.Match as Match
import qualified Data.List.HT as ListHT
import Data.Functor.Compose (Compose(Compose, getCompose))
import Data.Foldable (Foldable, fold)
import Data.List (mapAccumL, transpose)
import Data.Complex (Complex((:+)))
import Data.Ix (Ix)


deflt :: String
deflt :: String
deflt = String
"%.4g"


class (Shape.C sh) => FormatArray sh where
   {-
   We use constraint @(Class.Floating a)@ and not @(Format a)@
   because it allows us to align the components of complex numbers.
   -}
   formatArray :: (Class.Floating a, Output out) => String -> Array sh a -> out

instance (Integral i) => FormatArray (Shape.ZeroBased i) where
   formatArray :: String -> Array (ZeroBased i) a -> out
formatArray = String -> Array (ZeroBased i) a -> out
forall sh a out.
(C sh, Floating a, Output out) =>
String -> Array sh a -> out
formatVector

instance (Integral i) => FormatArray (Shape.OneBased i) where
   formatArray :: String -> Array (OneBased i) a -> out
formatArray = String -> Array (OneBased i) a -> out
forall sh a out.
(C sh, Floating a, Output out) =>
String -> Array sh a -> out
formatVector

instance (Ix i) => FormatArray (Shape.Range i) where
   formatArray :: String -> Array (Range i) a -> out
formatArray = String -> Array (Range i) a -> out
forall sh a out.
(C sh, Floating a, Output out) =>
String -> Array sh a -> out
formatVector

instance (Integral i) => FormatArray (Shape.Shifted i) where
   formatArray :: String -> Array (Shifted i) a -> out
formatArray = String -> Array (Shifted i) a -> out
forall sh a out.
(C sh, Floating a, Output out) =>
String -> Array sh a -> out
formatVector

instance (Enum enum, Bounded enum) => FormatArray (Shape.Enumeration enum) where
   formatArray :: String -> Array (Enumeration enum) a -> out
formatArray = String -> Array (Enumeration enum) a -> out
forall sh a out.
(C sh, Floating a, Output out) =>
String -> Array sh a -> out
formatVector

instance (FormatArray sh) => FormatArray (Shape.Deferred sh) where
   formatArray :: String -> Array (Deferred sh) a -> out
formatArray String
fmt =
      String -> Array sh a -> out
forall sh a out.
(FormatArray sh, Floating a, Output out) =>
String -> Array sh a -> out
formatArray String
fmt (Array sh a -> out)
-> (Array (Deferred sh) a -> Array sh a)
-> Array (Deferred sh) a
-> out
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Deferred sh -> sh) -> Array (Deferred sh) a -> Array sh a
forall sh0 sh1 a. (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
Array.mapShape (\(Shape.Deferred sh
sh) -> sh
sh)

instance (FormatArray sh0, FormatArray sh1) => FormatArray (sh0:+:sh1) where
   formatArray :: String -> Array (sh0 :+: sh1) a -> out
formatArray String
fmt Array (sh0 :+: sh1) a
v =
      String -> Array sh0 a -> out
forall sh a out.
(FormatArray sh, Floating a, Output out) =>
String -> Array sh a -> out
formatArray String
fmt (Array (sh0 :+: sh1) a -> Array sh0 a
forall sh0 sh1 a.
(C sh0, C sh1, Storable a) =>
Array (sh0 :+: sh1) a -> Array sh0 a
Vector.takeLeft Array (sh0 :+: sh1) a
v)
      out -> out -> out
forall out. Output out => out -> out -> out
<+>
      String -> Array sh1 a -> out
forall sh a out.
(FormatArray sh, Floating a, Output out) =>
String -> Array sh a -> out
formatArray String
fmt (Array (sh0 :+: sh1) a -> Array sh1 a
forall sh0 sh1 a.
(C sh0, C sh1, Storable a) =>
Array (sh0 :+: sh1) a -> Array sh1 a
Vector.takeRight Array (sh0 :+: sh1) a
v)

formatVector ::
   (Shape.C sh, Class.Floating a, Output out) => String -> Array sh a -> out
formatVector :: String -> Array sh a -> out
formatVector String
fmt =
   [out] -> out
forall out. Output out => [out] -> out
formatRow ([out] -> out) -> (Array sh a -> [out]) -> Array sh a -> out
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> out) -> [a] -> [out]
forall a b. (a -> b) -> [a] -> [b]
map (String -> out
forall out. Output out => String -> out
Output.text (String -> out) -> (a -> String) -> a -> out
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array (TupleShape a) String -> String
forall (t :: * -> *) m. (Foldable t, Monoid m) => t m -> m
fold (Array (TupleShape a) String -> String)
-> (a -> Array (TupleShape a) String) -> a -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> a -> Array (TupleShape a) String
forall a. Floating a => String -> a -> Tuple a String
printfFloating String
fmt) ([a] -> [out]) -> (Array sh a -> [a]) -> Array sh a -> [out]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Array sh a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList

instance
   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>
      FormatArray (MatrixShape.Full vert horiz height width) where
   formatArray :: String -> Array (Full vert horiz height width) a -> out
formatArray = String -> Array (Full vert horiz height width) a -> out
forall vert horiz height width out a.
(C vert, C horiz, C height, C width, Output out, Floating a) =>
String -> Full vert horiz height width a -> out
formatFull

formatFull ::
   (Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,
    Output out, Class.Floating a) =>
   String -> Full vert horiz height width a -> out
formatFull :: String -> Full vert horiz height width a -> out
formatFull String
fmt Full vert horiz height width a
m =
   let MatrixShape.Full Order
order Extent vert horiz height width
extent = Full vert horiz height width a -> Full vert horiz height width
forall sh a. Array sh a -> sh
Array.shape Full vert horiz height width a
m
   in  (a -> Array (TupleShape a) String) -> [[a]] -> out
forall (f :: * -> *) out a.
(Functor f, Foldable f, Output out) =>
(a -> f String) -> [[a]] -> out
formatAligned (String -> a -> Array (TupleShape a) String
forall a. Floating a => String -> a -> Tuple a String
printfFloating String
fmt) ([[a]] -> out) -> [[a]] -> out
forall a b. (a -> b) -> a -> b
$
       Order -> (height, width) -> [a] -> [[a]]
forall height width a.
(C height, C width) =>
Order -> (height, width) -> [a] -> [[a]]
splitRows Order
order (Extent vert horiz height width -> (height, width)
forall vert horiz height width.
(C vert, C horiz) =>
Extent vert horiz height width -> (height, width)
Extent.dimensions Extent vert horiz height width
extent) ([a] -> [[a]]) -> [a] -> [[a]]
forall a b. (a -> b) -> a -> b
$ Full vert horiz height width a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Full vert horiz height width a
m

instance
   (Eq lower, Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>
      FormatArray (MatrixShape.Split lower vert horiz height width) where
   formatArray :: String -> Array (Split lower vert horiz height width) a -> out
formatArray = String -> Array (Split lower vert horiz height width) a -> out
forall lower vert horiz height width a out.
(Eq lower, C vert, C horiz, C height, C width, Floating a,
 Output out) =>
String -> Array (Split lower vert horiz height width) a -> out
formatHouseholder

formatHouseholder ::
   (Eq lower, Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width,
    Class.Floating a, Output out) =>
   String -> Array (MatrixShape.Split lower vert horiz height width) a -> out
formatHouseholder :: String -> Array (Split lower vert horiz height width) a -> out
formatHouseholder String
fmt Array (Split lower vert horiz height width) a
m =
   let MatrixShape.Split lower
_ Order
order Extent vert horiz height width
extent = Array (Split lower vert horiz height width) a
-> Split lower vert horiz height width
forall sh a. Array sh a -> sh
Array.shape Array (Split lower vert horiz height width) a
m
   in (a -> Array (TupleShape a) String) -> [[a]] -> out
forall (f :: * -> *) out a.
(Functor f, Foldable f, Output out) =>
(a -> f String) -> [[a]] -> out
formatSeparateTriangle (String -> a -> Array (TupleShape a) String
forall a. Floating a => String -> a -> Tuple a String
printfFloating String
fmt) ([[a]] -> out) -> [[a]] -> out
forall a b. (a -> b) -> a -> b
$
      Order -> (height, width) -> [a] -> [[a]]
forall height width a.
(C height, C width) =>
Order -> (height, width) -> [a] -> [[a]]
splitRows Order
order (Extent vert horiz height width -> (height, width)
forall vert horiz height width.
(C vert, C horiz) =>
Extent vert horiz height width -> (height, width)
Extent.dimensions Extent vert horiz height width
extent) ([a] -> [[a]]) -> [a] -> [[a]]
forall a b. (a -> b) -> a -> b
$ Array (Split lower vert horiz height width) a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Split lower vert horiz height width) a
m

instance (Shape.C size) => FormatArray (MatrixShape.Hermitian size) where
   formatArray :: String -> Array (Hermitian size) a -> out
formatArray = String -> Array (Hermitian size) a -> out
forall size a out.
(C size, Floating a, Output out) =>
String -> Array (Hermitian size) a -> out
formatHermitian

formatHermitian ::
   (Shape.C size, Class.Floating a, Output out) =>
   String -> Array (MatrixShape.Hermitian size) a -> out
formatHermitian :: String -> Array (Hermitian size) a -> out
formatHermitian String
fmt Array (Hermitian size) a
m =
   let MatrixShape.Hermitian Order
order size
size = Array (Hermitian size) a -> Hermitian size
forall sh a. Array sh a -> sh
Array.shape Array (Hermitian size) a
m
   in  (a -> Array (TupleShape a) String) -> [[a]] -> out
forall (f :: * -> *) out a.
(Functor f, Foldable f, Output out) =>
(a -> f String) -> [[a]] -> out
formatSeparateTriangle (String -> a -> Array (TupleShape a) String
forall a. Floating a => String -> a -> Tuple a String
printfFloating String
fmt) ([[a]] -> out) -> [[a]] -> out
forall a b. (a -> b) -> a -> b
$
       (a -> a) -> Order -> Int -> [a] -> [[a]]
forall a. Floating a => (a -> a) -> Order -> Int -> [a] -> [[a]]
complementTriangle a -> a
forall a. Floating a => a -> a
conjugate Order
order (size -> Int
forall sh. C sh => sh -> Int
Shape.size size
size) ([a] -> [[a]]) -> [a] -> [[a]]
forall a b. (a -> b) -> a -> b
$ Array (Hermitian size) a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Hermitian size) a
m

formatSymmetric ::
   (Shape.C size, Class.Floating a, Output out) =>
   String -> Array (MatrixShape.Symmetric size) a -> out
formatSymmetric :: String -> Array (Symmetric size) a -> out
formatSymmetric String
fmt Array (Symmetric size) a
m =
   let MatrixShape.Triangular NonUnit
_diag (Filled
Filled, Filled
Filled) Order
order size
size = Array (Symmetric size) a -> Symmetric size
forall sh a. Array sh a -> sh
Array.shape Array (Symmetric size) a
m
   in  (a -> Array (TupleShape a) String) -> [[a]] -> out
forall (f :: * -> *) out a.
(Functor f, Foldable f, Output out) =>
(a -> f String) -> [[a]] -> out
formatSeparateTriangle (String -> a -> Array (TupleShape a) String
forall a. Floating a => String -> a -> Tuple a String
printfFloating String
fmt) ([[a]] -> out) -> [[a]] -> out
forall a b. (a -> b) -> a -> b
$
       (a -> a) -> Order -> Int -> [a] -> [[a]]
forall a. Floating a => (a -> a) -> Order -> Int -> [a] -> [[a]]
complementTriangle a -> a
forall a. a -> a
id Order
order (size -> Int
forall sh. C sh => sh -> Int
Shape.size size
size) ([a] -> [[a]]) -> [a] -> [[a]]
forall a b. (a -> b) -> a -> b
$ Array (Symmetric size) a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Symmetric size) a
m

complementTriangle ::
   (Class.Floating a) => (a -> a) -> Order -> Int -> [a] -> [[a]]
complementTriangle :: (a -> a) -> Order -> Int -> [a] -> [[a]]
complementTriangle a -> a
adapt Order
order Int
n [a]
xs =
   let mergeTriangles :: [[a]] -> [[a]] -> [[a]]
mergeTriangles [[a]]
lower [[a]]
upper =
         ([a] -> [a] -> [a]) -> [[a]] -> [[a]] -> [[a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) (([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map a -> a
adapt ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
init) [[a]]
lower) [[a]]
upper
   in case Order
order of
         Order
RowMajor ->
            let tri :: [[a]]
tri = [Int] -> [a] -> [[a]]
forall a. [Int] -> [a] -> [[a]]
slice (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ (Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate Int -> Int
forall a. Enum a => a -> a
pred Int
n) [a]
xs
                trans :: [[a]]
trans = [[a]] -> [[a]]
forall a. [a] -> [a]
reverse ([[a]] -> [[a]]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> a -> b
$ [[a]] -> [[a]]
forall a. [[a]] -> [[a]]
transpose ([[a]] -> [[a]]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> a -> b
$ ([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map [a] -> [a]
forall a. [a] -> [a]
reverse [[a]]
tri
            in  [[a]] -> [[a]] -> [[a]]
mergeTriangles [[a]]
trans [[a]]
tri
         Order
ColumnMajor ->
            let tri :: [[a]]
tri = [Int] -> [a] -> [[a]]
forall a. [Int] -> [a] -> [[a]]
slice (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n [Int
1..]) [a]
xs
            in  [[a]] -> [[a]] -> [[a]]
mergeTriangles [[a]]
tri ([[a]] -> [[a]]
forall a. [[a]] -> [[a]]
transpose [[a]]
tri)

instance
   (MatrixShape.Content lo, MatrixShape.Content up,
    MatrixShape.TriDiag diag, Shape.C size) =>
      FormatArray (MatrixShape.Triangular lo diag up size) where
   formatArray :: String -> Array (Triangular lo diag up size) a -> out
formatArray String
fmt =
      FormatTriangular diag size a out lo up
-> Array (Triangular lo diag up size) a -> out
forall diag size a b lo up.
FormatTriangular diag size a b lo up
-> Array (Triangular lo diag up size) a -> b
getFormatTriangular (FormatTriangular diag size a out lo up
 -> Array (Triangular lo diag up size) a -> out)
-> FormatTriangular diag size a out lo up
-> Array (Triangular lo diag up size) a
-> out
forall a b. (a -> b) -> a -> b
$
      FormatTriangular diag size a out Empty Empty
-> FormatTriangular diag size a out Empty Filled
-> FormatTriangular diag size a out Filled Empty
-> FormatTriangular diag size a out Filled Filled
-> FormatTriangular diag size a out lo up
forall lo up (f :: * -> * -> *).
(Content lo, Content up) =>
f Empty Empty
-> f Empty Filled -> f Filled Empty -> f Filled Filled -> f lo up
MatrixShape.switchDiagUpLoSym
         ((Array (Triangular Empty diag Empty size) a -> out)
-> FormatTriangular diag size a out Empty Empty
forall diag size a b lo up.
(Array (Triangular lo diag up size) a -> b)
-> FormatTriangular diag size a b lo up
FormatTriangular ((Array (Triangular Empty diag Empty size) a -> out)
 -> FormatTriangular diag size a out Empty Empty)
-> (Array (Triangular Empty diag Empty size) a -> out)
-> FormatTriangular diag size a out Empty Empty
forall a b. (a -> b) -> a -> b
$ \Array (Triangular Empty diag Empty size) a
m ->
            let MatrixShape.Triangular diag
_diag (Empty, Empty)
_uplo Order
order size
size = Array (Triangular Empty diag Empty size) a
-> Triangular Empty diag Empty size
forall sh a. Array sh a -> sh
Array.shape Array (Triangular Empty diag Empty size) a
m
            in String -> Order -> size -> [a] -> out
forall size a out.
(C size, Floating a, Output out) =>
String -> Order -> size -> [a] -> out
formatDiagonal String
fmt Order
order size
size ([a] -> out) -> [a] -> out
forall a b. (a -> b) -> a -> b
$ Array (Triangular Empty diag Empty size) a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Triangular Empty diag Empty size) a
m)
         ((Array (Triangular Empty diag Filled size) a -> out)
-> FormatTriangular diag size a out Empty Filled
forall diag size a b lo up.
(Array (Triangular lo diag up size) a -> b)
-> FormatTriangular diag size a b lo up
FormatTriangular ((Array (Triangular Empty diag Filled size) a -> out)
 -> FormatTriangular diag size a out Empty Filled)
-> (Array (Triangular Empty diag Filled size) a -> out)
-> FormatTriangular diag size a out Empty Filled
forall a b. (a -> b) -> a -> b
$ String -> Array (Triangular Empty diag Filled size) a -> out
forall diag lo up size a out.
(TriDiag diag, UpLo lo up, C size, Floating a, Output out) =>
String -> Array (Triangular lo diag up size) a -> out
formatTriangular String
fmt)
         ((Array (Triangular Filled diag Empty size) a -> out)
-> FormatTriangular diag size a out Filled Empty
forall diag size a b lo up.
(Array (Triangular lo diag up size) a -> b)
-> FormatTriangular diag size a b lo up
FormatTriangular ((Array (Triangular Filled diag Empty size) a -> out)
 -> FormatTriangular diag size a out Filled Empty)
-> (Array (Triangular Filled diag Empty size) a -> out)
-> FormatTriangular diag size a out Filled Empty
forall a b. (a -> b) -> a -> b
$ String -> Array (Triangular Filled diag Empty size) a -> out
forall diag lo up size a out.
(TriDiag diag, UpLo lo up, C size, Floating a, Output out) =>
String -> Array (Triangular lo diag up size) a -> out
formatTriangular String
fmt)
         ((Array (Triangular Filled diag Filled size) a -> out)
-> FormatTriangular diag size a out Filled Filled
forall diag size a b lo up.
(Array (Triangular lo diag up size) a -> b)
-> FormatTriangular diag size a b lo up
FormatTriangular ((Array (Triangular Filled diag Filled size) a -> out)
 -> FormatTriangular diag size a out Filled Filled)
-> (Array (Triangular Filled diag Filled size) a -> out)
-> FormatTriangular diag size a out Filled Filled
forall a b. (a -> b) -> a -> b
$
            String -> Array (Symmetric size) a -> out
forall size a out.
(C size, Floating a, Output out) =>
String -> Array (Symmetric size) a -> out
formatSymmetric String
fmt (Array (Symmetric size) a -> out)
-> (Array (Triangular Filled diag Filled size) a
    -> Array (Symmetric size) a)
-> Array (Triangular Filled diag Filled size) a
-> out
forall b c a. (b -> c) -> (a -> b) -> a -> c
.
            (Triangular Filled diag Filled size -> Symmetric size)
-> Array (Triangular Filled diag Filled size) a
-> Array (Symmetric size) a
forall sh0 sh1 a. (sh0 -> sh1) -> Array sh0 a -> Array sh1 a
Array.mapShape Triangular Filled diag Filled size -> Symmetric size
forall diag lo up sh.
TriDiag diag =>
Triangular lo diag up sh -> Triangular lo NonUnit up sh
MatrixShape.strictNonUnitDiagonal)

formatDiagonal ::
   (Shape.C size, Class.Floating a, Output out) =>
   String -> Order -> size -> [a] -> out
formatDiagonal :: String -> Order -> size -> [a] -> out
formatDiagonal String
fmt Order
order size
size [a]
xs =
   let n0 :: Proxy (Un U0)
n0 = Proxy U0 -> Proxy (Un U0)
forall n. Proxy n -> Proxy (Un n)
Unary.unary Proxy U0
TypeNum.u0
   in (Maybe a -> Array (TupleShape a) String) -> [[Maybe a]] -> out
forall (f :: * -> *) out a.
(Functor f, Foldable f, Output out) =>
(a -> f String) -> [[a]] -> out
formatAligned (String -> Maybe a -> Array (TupleShape a) String
forall a. Floating a => String -> Maybe a -> Tuple a String
printfFloatingMaybe String
fmt) ([[Maybe a]] -> out) -> [[Maybe a]] -> out
forall a b. (a -> b) -> a -> b
$
      (Proxy (Un U0), Proxy (Un U0))
-> Order -> (size, size) -> [a] -> [[Maybe a]]
forall height width sub super a.
(C height, C width, Natural sub, Natural super) =>
(UnaryProxy sub, UnaryProxy super)
-> Order -> (height, width) -> [a] -> [[Maybe a]]
padBanded (Proxy (Un U0)
n0,Proxy (Un U0)
n0) Order
order (size
size,size
size) [a]
xs


newtype FormatTriangular diag size a b lo up =
   FormatTriangular {
      FormatTriangular diag size a b lo up
-> Array (Triangular lo diag up size) a -> b
getFormatTriangular ::
         Array (MatrixShape.Triangular lo diag up size) a -> b
   }

formatTriangular ::
   (MatrixShape.TriDiag diag, MatrixShape.UpLo lo up,
    Shape.C size, Class.Floating a, Output out) =>
   String -> Array (MatrixShape.Triangular lo diag up size) a -> out
formatTriangular :: String -> Array (Triangular lo diag up size) a -> out
formatTriangular String
fmt Array (Triangular lo diag up size) a
m =
   let MatrixShape.Triangular diag
_diag (lo, up)
uplo Order
order size
size = Array (Triangular lo diag up size) a -> Triangular lo diag up size
forall sh a. Array sh a -> sh
Array.shape Array (Triangular lo diag up size) a
m
   in  (Maybe a -> Array (TupleShape a) String) -> [[Maybe a]] -> out
forall (f :: * -> *) out a.
(Functor f, Foldable f, Output out) =>
(a -> f String) -> [[a]] -> out
formatAligned (String -> Maybe a -> Array (TupleShape a) String
forall a. Floating a => String -> Maybe a -> Tuple a String
printfFloatingMaybe String
fmt) ([[Maybe a]] -> out) -> [[Maybe a]] -> out
forall a b. (a -> b) -> a -> b
$
       (lo, up)
-> (Order -> Int -> [a] -> [[Maybe a]])
-> (Order -> Int -> [a] -> [[Maybe a]])
-> Order
-> Int
-> [a]
-> [[Maybe a]]
forall lo up a. UpLo lo up => (lo, up) -> a -> a -> a
MatrixShape.caseLoUp (lo, up)
uplo
         Order -> Int -> [a] -> [[Maybe a]]
forall a. Order -> Int -> [a] -> [[Maybe a]]
padLowerTriangle Order -> Int -> [a] -> [[Maybe a]]
forall a. Order -> Int -> [a] -> [[Maybe a]]
padUpperTriangle Order
order (size -> Int
forall sh. C sh => sh -> Int
Shape.size size
size) ([a] -> [[Maybe a]]) -> [a] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$
       Array (Triangular lo diag up size) a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Triangular lo diag up size) a
m

padUpperTriangle :: Order -> Int -> [a] -> [[Maybe a]]
padUpperTriangle :: Order -> Int -> [a] -> [[Maybe a]]
padUpperTriangle Order
order Int
n [a]
xs =
   let mxs :: [Maybe a]
mxs = (a -> Maybe a) -> [a] -> [Maybe a]
forall a b. (a -> b) -> [a] -> [b]
map a -> Maybe a
forall a. a -> Maybe a
Just [a]
xs
       nothings :: [[Maybe a]]
nothings = ([Maybe a] -> [Maybe a]) -> [Maybe a] -> [[Maybe a]]
forall a. (a -> a) -> a -> [a]
iterate (Maybe a
forall a. Maybe a
NothingMaybe a -> [Maybe a] -> [Maybe a]
forall a. a -> [a] -> [a]
:) []
   in case Order
order of
         Order
RowMajor ->
            ([Maybe a] -> [Maybe a] -> [Maybe a])
-> [[Maybe a]] -> [[Maybe a]] -> [[Maybe a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [Maybe a] -> [Maybe a] -> [Maybe a]
forall a. [a] -> [a] -> [a]
(++) [[Maybe a]]
forall a. [[Maybe a]]
nothings ([Int] -> [Maybe a] -> [[Maybe a]]
forall a. [Int] -> [a] -> [[a]]
slice (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ (Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate Int -> Int
forall a. Enum a => a -> a
pred Int
n) [Maybe a]
mxs)
         Order
ColumnMajor ->
            [[Maybe a]] -> [[Maybe a]]
forall a. [[a]] -> [[a]]
transpose ([[Maybe a]] -> [[Maybe a]]) -> [[Maybe a]] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$
            ([Maybe a] -> [Maybe a] -> [Maybe a])
-> [[Maybe a]] -> [[Maybe a]] -> [[Maybe a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [Maybe a] -> [Maybe a] -> [Maybe a]
forall a. [a] -> [a] -> [a]
(++)
               ([Int] -> [Maybe a] -> [[Maybe a]]
forall a. [Int] -> [a] -> [[a]]
slice (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n [Int
1..]) [Maybe a]
mxs)
               ([[Maybe a]] -> [[Maybe a]]
forall a. [a] -> [a]
reverse ([[Maybe a]] -> [[Maybe a]]) -> [[Maybe a]] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$ Int -> [[Maybe a]] -> [[Maybe a]]
forall a. Int -> [a] -> [a]
take Int
n [[Maybe a]]
forall a. [[Maybe a]]
nothings)

padLowerTriangle :: Order -> Int -> [a] -> [[Maybe a]]
padLowerTriangle :: Order -> Int -> [a] -> [[Maybe a]]
padLowerTriangle Order
order Int
n [a]
xs =
   ([a] -> [Maybe a]) -> [[a]] -> [[Maybe a]]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> Maybe a) -> [a] -> [Maybe a]
forall a b. (a -> b) -> [a] -> [b]
map a -> Maybe a
forall a. a -> Maybe a
Just) ([[a]] -> [[Maybe a]]) -> [[a]] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$
   case Order
order of
      Order
RowMajor -> [Int] -> [a] -> [[a]]
forall a. [Int] -> [a] -> [[a]]
slice (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n [Int
1..]) [a]
xs
      Order
ColumnMajor ->
         ([a] -> [[a]] -> [[a]]) -> [[a]] -> [[a]] -> [[a]]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(a
y:[a]
ys) [[a]]
zs -> [a
y] [a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
: (a -> [a] -> [a]) -> [a] -> [[a]] -> [[a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (:) [a]
ys [[a]]
zs) []
            ([Int] -> [a] -> [[a]]
forall a. [Int] -> [a] -> [[a]]
slice (Int -> [Int] -> [Int]
forall a. Int -> [a] -> [a]
take Int
n ([Int] -> [Int]) -> [Int] -> [Int]
forall a b. (a -> b) -> a -> b
$ (Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate Int -> Int
forall a. Enum a => a -> a
pred Int
n) [a]
xs)

slice :: [Int] -> [a] -> [[a]]
slice :: [Int] -> [a] -> [[a]]
slice [Int]
ns [a]
xs =
   ([a], [[a]]) -> [[a]]
forall a b. (a, b) -> b
snd (([a], [[a]]) -> [[a]]) -> ([a], [[a]]) -> [[a]]
forall a b. (a -> b) -> a -> b
$ ([a] -> Int -> ([a], [a])) -> [a] -> [Int] -> ([a], [[a]])
forall (t :: * -> *) a b c.
Traversable t =>
(a -> b -> (a, c)) -> a -> t b -> (a, t c)
mapAccumL (\[a]
ys Int
n -> let ([a]
vs,[a]
ws) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt Int
n [a]
ys in ([a]
ws,[a]
vs)) [a]
xs [Int]
ns


instance
   (Unary.Natural sub, Unary.Natural super,
    Extent.C vert, Extent.C horiz, Shape.C height, Shape.C width) =>
      FormatArray (MatrixShape.Banded sub super vert horiz height width) where
   formatArray :: String -> Array (Banded sub super vert horiz height width) a -> out
formatArray String
fmt Array (Banded sub super vert horiz height width) a
m =
      let MatrixShape.Banded (UnaryProxy sub, UnaryProxy super)
offDiag Order
order Extent vert horiz height width
extent = Array (Banded sub super vert horiz height width) a
-> Banded sub super vert horiz height width
forall sh a. Array sh a -> sh
Array.shape Array (Banded sub super vert horiz height width) a
m
      in  (Maybe a -> Array (TupleShape a) String) -> [[Maybe a]] -> out
forall (f :: * -> *) out a.
(Functor f, Foldable f, Output out) =>
(a -> f String) -> [[a]] -> out
formatAligned (String -> Maybe a -> Array (TupleShape a) String
forall a. Floating a => String -> Maybe a -> Tuple a String
printfFloatingMaybe String
fmt) ([[Maybe a]] -> out) -> [[Maybe a]] -> out
forall a b. (a -> b) -> a -> b
$
          (UnaryProxy sub, UnaryProxy super)
-> Order -> (height, width) -> [a] -> [[Maybe a]]
forall height width sub super a.
(C height, C width, Natural sub, Natural super) =>
(UnaryProxy sub, UnaryProxy super)
-> Order -> (height, width) -> [a] -> [[Maybe a]]
padBanded (UnaryProxy sub, UnaryProxy super)
offDiag Order
order (Extent vert horiz height width -> (height, width)
forall vert horiz height width.
(C vert, C horiz) =>
Extent vert horiz height width -> (height, width)
Extent.dimensions Extent vert horiz height width
extent) ([a] -> [[Maybe a]]) -> [a] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$
          Array (Banded sub super vert horiz height width) a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (Banded sub super vert horiz height width) a
m

padBanded ::
   (Shape.C height, Shape.C width, Unary.Natural sub, Unary.Natural super) =>
   (UnaryProxy sub, UnaryProxy super) -> Order ->
   (height, width) -> [a] -> [[Maybe a]]
padBanded :: (UnaryProxy sub, UnaryProxy super)
-> Order -> (height, width) -> [a] -> [[Maybe a]]
padBanded (UnaryProxy sub
sub,UnaryProxy super
super) Order
order (height
height,width
width) [a]
xs =
   let slices :: [[a]]
slices =
         Int -> [a] -> [[a]]
forall a. Int -> [a] -> [[a]]
ListHT.sliceVertical ((UnaryProxy sub, UnaryProxy super) -> Int
forall sub super.
(Natural sub, Natural super) =>
(UnaryProxy sub, UnaryProxy super) -> Int
MatrixShape.bandedBreadth (UnaryProxy sub
sub,UnaryProxy super
super)) [a]
xs
       m :: Int
m = height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height
       n :: Int
n = width -> Int
forall sh. C sh => sh -> Int
Shape.size width
width
   in case Order
order of
         Order
RowMajor ->
            ([Maybe a] -> [Maybe a]) -> [[Maybe a]] -> [[Maybe a]]
forall a b. (a -> b) -> [a] -> [b]
map (Int -> [Maybe a] -> [Maybe a]
forall a. Int -> [a] -> [a]
take Int
n) ([[Maybe a]] -> [[Maybe a]]) -> [[Maybe a]] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$
            (Int -> [Maybe a] -> [Maybe a])
-> [Int] -> [[Maybe a]] -> [[Maybe a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Maybe a -> Int -> [Maybe a] -> [Maybe a]
forall a. a -> Int -> [a] -> [a]
shiftRow Maybe a
forall a. Maybe a
Nothing)
               ((Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate (Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+) (- UnaryProxy sub -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy sub
sub))
               (([a] -> [Maybe a]) -> [[a]] -> [[Maybe a]]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> Maybe a) -> [a] -> [Maybe a]
forall a b. (a -> b) -> [a] -> [b]
map a -> Maybe a
forall a. a -> Maybe a
Just) [[a]]
slices)
         Order
ColumnMajor ->
            let ku :: Int
ku = UnaryProxy super -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy super
super
            in Int -> [[Maybe a]] -> [[Maybe a]]
forall a. Int -> [a] -> [a]
take Int
m ([[Maybe a]] -> [[Maybe a]]) -> [[Maybe a]] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$ Int -> [[Maybe a]] -> [[Maybe a]]
forall a. Int -> [a] -> [a]
drop Int
ku ([[Maybe a]] -> [[Maybe a]]) -> [[Maybe a]] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$
               ([a] -> [[Maybe a]] -> [[Maybe a]])
-> [[Maybe a]] -> [[a]] -> [[Maybe a]]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
                  (\[a]
col [[Maybe a]]
mat ->
                     (Maybe a -> [Maybe a] -> [Maybe a])
-> [Maybe a] -> [[Maybe a]] -> [[Maybe a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (:) ((a -> Maybe a) -> [a] -> [Maybe a]
forall a b. (a -> b) -> [a] -> [b]
map a -> Maybe a
forall a. a -> Maybe a
Just [a]
col [Maybe a] -> [Maybe a] -> [Maybe a]
forall a. [a] -> [a] -> [a]
++ Maybe a -> [Maybe a]
forall a. a -> [a]
repeat Maybe a
forall a. Maybe a
Nothing) ([][Maybe a] -> [[Maybe a]] -> [[Maybe a]]
forall a. a -> [a] -> [a]
:[[Maybe a]]
mat))
                  (Int -> [Maybe a] -> [[Maybe a]]
forall a. Int -> a -> [a]
replicate (Int
ku Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
m Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [])
                  [[a]]
slices


instance
   (Unary.Natural offDiag, Shape.C size) =>
      FormatArray (MatrixShape.BandedHermitian offDiag size) where
   formatArray :: String -> Array (BandedHermitian offDiag size) a -> out
formatArray String
fmt Array (BandedHermitian offDiag size) a
m =
      let MatrixShape.BandedHermitian UnaryProxy offDiag
offDiag Order
order size
size = Array (BandedHermitian offDiag size) a
-> BandedHermitian offDiag size
forall sh a. Array sh a -> sh
Array.shape Array (BandedHermitian offDiag size) a
m
      in  (Maybe a -> Array (TupleShape a) String) -> [[Maybe a]] -> out
forall (f :: * -> *) out a.
(Functor f, Foldable f, Output out) =>
(a -> f String) -> [[a]] -> out
formatSeparateTriangle (String -> Maybe a -> Array (TupleShape a) String
forall a. Floating a => String -> Maybe a -> Tuple a String
printfFloatingMaybe String
fmt) ([[Maybe a]] -> out) -> [[Maybe a]] -> out
forall a b. (a -> b) -> a -> b
$
          UnaryProxy offDiag -> Order -> size -> [a] -> [[Maybe a]]
forall offDiag size a.
(Natural offDiag, C size, Floating a) =>
UnaryProxy offDiag -> Order -> size -> [a] -> [[Maybe a]]
padBandedHermitian UnaryProxy offDiag
offDiag Order
order size
size ([a] -> [[Maybe a]]) -> [a] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$ Array (BandedHermitian offDiag size) a -> [a]
forall sh a. (C sh, Storable a) => Array sh a -> [a]
Array.toList Array (BandedHermitian offDiag size) a
m

padBandedHermitian ::
   (Unary.Natural offDiag, Shape.C size, Class.Floating a) =>
   UnaryProxy offDiag -> Order -> size -> [a] -> [[Maybe a]]
padBandedHermitian :: UnaryProxy offDiag -> Order -> size -> [a] -> [[Maybe a]]
padBandedHermitian UnaryProxy offDiag
offDiag Order
order size
_size [a]
xs =
   let k :: Int
k = UnaryProxy offDiag -> Int
forall x y. (Integer x, Num y) => Proxy x -> y
integralFromProxy UnaryProxy offDiag
offDiag
       slices :: [[a]]
slices = Int -> [a] -> [[a]]
forall a. Int -> [a] -> [[a]]
ListHT.sliceVertical (Int
k Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) [a]
xs
   in case Order
order of
         Order
RowMajor ->
            ([a] -> [[Maybe a]] -> [[Maybe a]])
-> [[Maybe a]] -> [[a]] -> [[Maybe a]]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
               (\[a]
row [[Maybe a]]
square ->
                  [[Maybe a]] -> [Maybe a] -> [Maybe a]
forall b a. [b] -> [a] -> [a]
Match.take ([][Maybe a] -> [[Maybe a]] -> [[Maybe a]]
forall a. a -> [a] -> [a]
:[[Maybe a]]
square) ((a -> Maybe a) -> [a] -> [Maybe a]
forall a b. (a -> b) -> [a] -> [b]
map a -> Maybe a
forall a. a -> Maybe a
Just [a]
row)
                  [Maybe a] -> [[Maybe a]] -> [[Maybe a]]
forall a. a -> [a] -> [a]
:
                  (Maybe a -> [Maybe a] -> [Maybe a])
-> [Maybe a] -> [[Maybe a]] -> [[Maybe a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (:)
                     ([Maybe a] -> [Maybe a]
forall a. [a] -> [a]
tail ([Maybe a] -> [Maybe a]) -> [Maybe a] -> [Maybe a]
forall a b. (a -> b) -> a -> b
$ (a -> Maybe a) -> [a] -> [Maybe a]
forall a b. (a -> b) -> [a] -> [b]
map (a -> Maybe a
forall a. a -> Maybe a
Just (a -> Maybe a) -> (a -> a) -> a -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> a
forall a. Floating a => a -> a
conjugate) [a]
row [Maybe a] -> [Maybe a] -> [Maybe a]
forall a. [a] -> [a] -> [a]
++ Maybe a -> [Maybe a]
forall a. a -> [a]
repeat Maybe a
forall a. Maybe a
Nothing)
                     [[Maybe a]]
square)
               [] [[a]]
slices
         Order
ColumnMajor ->
            (Int -> [Maybe a] -> [Maybe a])
-> [Int] -> [[Maybe a]] -> [[Maybe a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (Maybe a -> Int -> [Maybe a] -> [Maybe a]
forall a. a -> Int -> [a] -> [a]
shiftRow Maybe a
forall a. Maybe a
Nothing) ((Int -> Int) -> Int -> [Int]
forall a. (a -> a) -> a -> [a]
iterate (Int
1Int -> Int -> Int
forall a. Num a => a -> a -> a
+) (-Int
k)) ([[Maybe a]] -> [[Maybe a]]) -> [[Maybe a]] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$ ([a] -> [Maybe a]) -> [[a]] -> [[Maybe a]]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> Maybe a) -> [a] -> [Maybe a]
forall a b. (a -> b) -> [a] -> [b]
map a -> Maybe a
forall a. a -> Maybe a
Just) ([[a]] -> [[Maybe a]]) -> [[a]] -> [[Maybe a]]
forall a b. (a -> b) -> a -> b
$
            ([a] -> [a] -> [a]) -> [[a]] -> [[a]] -> [[a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++)
               (([a] -> [a]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> a) -> [a] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map a -> a
forall a. Floating a => a -> a
conjugate ([a] -> [a]) -> ([a] -> [a]) -> [a] -> [a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> [a]
forall a. [a] -> [a]
init) [[a]]
slices)
               (Int -> [[a]] -> [[a]]
forall a. Int -> [a] -> [a]
drop Int
k ([[a]] -> [[a]]) -> [[a]] -> [[a]]
forall a b. (a -> b) -> a -> b
$
                ([a] -> [[a]] -> [[a]]) -> [[a]] -> [[a]] -> [[a]]
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr
                  (\[a]
column [[a]]
band ->
                     ([a] -> [a] -> [a]) -> [[a]] -> [[a]] -> [[a]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
(++) ((a -> [a]) -> [a] -> [[a]]
forall a b. (a -> b) -> [a] -> [b]
map (a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[]) [a]
column [[a]] -> [[a]] -> [[a]]
forall a. [a] -> [a] -> [a]
++ [a] -> [[a]]
forall a. a -> [a]
repeat []) ([][a] -> [[a]] -> [[a]]
forall a. a -> [a] -> [a]
:[[a]]
band))
                  (Int -> [a] -> [[a]]
forall a. Int -> a -> [a]
replicate Int
k [])
                  [[a]]
slices)

shiftRow :: a -> Int -> [a] -> [a]
shiftRow :: a -> Int -> [a] -> [a]
shiftRow a
pad Int
k = if Int
kInt -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<=Int
0 then Int -> [a] -> [a]
forall a. Int -> [a] -> [a]
drop (-Int
k) else (Int -> a -> [a]
forall a. Int -> a -> [a]
replicate Int
k a
pad [a] -> [a] -> [a]
forall a. [a] -> [a] -> [a]
++)

splitRows ::
   (Shape.C height, Shape.C width) =>
   Order -> (height, width) -> [a] -> [[a]]
splitRows :: Order -> (height, width) -> [a] -> [[a]]
splitRows Order
order (height
height,width
width) =
   case Order
order of
      Order
RowMajor -> Int -> [a] -> [[a]]
forall a. Int -> [a] -> [[a]]
ListHT.sliceVertical (width -> Int
forall sh. C sh => sh -> Int
Shape.size width
width)
      Order
ColumnMajor -> Int -> [a] -> [[a]]
forall a. Int -> [a] -> [[a]]
ListHT.sliceHorizontal (height -> Int
forall sh. C sh => sh -> Int
Shape.size height
height)


formatAligned ::
   (Functor f, Foldable f) => Output out => (a -> f String) -> [[a]] -> out
formatAligned :: (a -> f String) -> [[a]] -> out
formatAligned a -> f String
printFmt =
   [[f out]] -> out
forall out (f :: * -> *).
(Output out, Foldable f) =>
[[f out]] -> out
Output.formatAligned ([[f out]] -> out) -> ([[a]] -> [[f out]]) -> [[a]] -> out
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [f out]) -> [[a]] -> [[f out]]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> f out) -> [a] -> [f out]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> out) -> f String -> f out
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> out
forall out. Output out => String -> out
Output.text (f String -> f out) -> (a -> f String) -> a -> f out
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f String
printFmt))

formatSeparateTriangle ::
   (Functor f, Foldable f) => Output out => (a -> f String) -> [[a]] -> out
formatSeparateTriangle :: (a -> f String) -> [[a]] -> out
formatSeparateTriangle a -> f String
printFmt =
   [[f out]] -> out
forall out (f :: * -> *).
(Output out, Foldable f) =>
[[f out]] -> out
Output.formatSeparateTriangle ([[f out]] -> out) -> ([[a]] -> [[f out]]) -> [[a]] -> out
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([a] -> [f out]) -> [[a]] -> [[f out]]
forall a b. (a -> b) -> [a] -> [b]
map ((a -> f out) -> [a] -> [f out]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> out) -> f String -> f out
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> out
forall out. Output out => String -> out
Output.text (f String -> f out) -> (a -> f String) -> a -> f out
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> f String
printFmt))



data TupleShape a = TupleShape

instance (Class.Floating a) => Shape.C (TupleShape a) where
   size :: TupleShape a -> Int
size TupleShape a
sh = TupleShape a -> Int -> Int -> Int
forall a (f :: * -> *) b. Floating a => f a -> b -> b -> b
caseRealComplexFunc TupleShape a
sh Int
1 Int
2

type Tuple a = BoxedArray.Array (TupleShape a)

fillTuple :: (Class.Floating a) => b -> Tuple a b
fillTuple :: b -> Tuple a b
fillTuple = TupleShape a -> b -> Tuple a b
forall sh a. C sh => sh -> a -> Array sh a
BoxedArray.replicate TupleShape a
forall a. TupleShape a
TupleShape


newtype ToTuple a = ToTuple {ToTuple a -> a -> Tuple a String
getToTuple :: a -> Tuple a String}

printfFloating :: (Class.Floating a) => String -> a -> Tuple a String
printfFloating :: String -> a -> Tuple a String
printfFloating String
fmt =
   ToTuple a -> a -> Tuple a String
forall a. ToTuple a -> a -> Tuple a String
getToTuple (ToTuple a -> a -> Tuple a String)
-> ToTuple a -> a -> Tuple a String
forall a b. (a -> b) -> a -> b
$
   ToTuple Float
-> ToTuple Double
-> ToTuple (Complex Float)
-> ToTuple (Complex Double)
-> ToTuple a
forall a (f :: * -> *).
Floating a =>
f Float
-> f Double -> f (Complex Float) -> f (Complex Double) -> f a
Class.switchFloating
      ((Float -> Tuple Float String) -> ToTuple Float
forall a. (a -> Tuple a String) -> ToTuple a
ToTuple ((Float -> Tuple Float String) -> ToTuple Float)
-> (Float -> Tuple Float String) -> ToTuple Float
forall a b. (a -> b) -> a -> b
$ String -> Tuple Float String
forall a b. Floating a => b -> Tuple a b
fillTuple (String -> Tuple Float String)
-> (Float -> String) -> Float -> Tuple Float String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Float -> String
forall r. PrintfType r => String -> r
printf String
fmt)
      ((Double -> Tuple Double String) -> ToTuple Double
forall a. (a -> Tuple a String) -> ToTuple a
ToTuple ((Double -> Tuple Double String) -> ToTuple Double)
-> (Double -> Tuple Double String) -> ToTuple Double
forall a b. (a -> b) -> a -> b
$ String -> Tuple Double String
forall a b. Floating a => b -> Tuple a b
fillTuple (String -> Tuple Double String)
-> (Double -> String) -> Double -> Tuple Double String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Double -> String
forall r. PrintfType r => String -> r
printf String
fmt)
      ((Complex Float -> Tuple (Complex Float) String)
-> ToTuple (Complex Float)
forall a. (a -> Tuple a String) -> ToTuple a
ToTuple ((Complex Float -> Tuple (Complex Float) String)
 -> ToTuple (Complex Float))
-> (Complex Float -> Tuple (Complex Float) String)
-> ToTuple (Complex Float)
forall a b. (a -> b) -> a -> b
$ String -> Complex Float -> Tuple (Complex Float) String
forall a. Real a => String -> Complex a -> Tuple (Complex a) String
printfComplex String
fmt)
      ((Complex Double -> Tuple (Complex Double) String)
-> ToTuple (Complex Double)
forall a. (a -> Tuple a String) -> ToTuple a
ToTuple ((Complex Double -> Tuple (Complex Double) String)
 -> ToTuple (Complex Double))
-> (Complex Double -> Tuple (Complex Double) String)
-> ToTuple (Complex Double)
forall a b. (a -> b) -> a -> b
$ String -> Complex Double -> Tuple (Complex Double) String
forall a. Real a => String -> Complex a -> Tuple (Complex a) String
printfComplex String
fmt)

printfFloatingMaybe ::
   (Class.Floating a) => String -> Maybe a -> Tuple a String
printfFloatingMaybe :: String -> Maybe a -> Tuple a String
printfFloatingMaybe = Tuple a String
-> (a -> Tuple a String) -> Maybe a -> Tuple a String
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (String -> Tuple a String
forall a b. Floating a => b -> Tuple a b
fillTuple String
"") ((a -> Tuple a String) -> Maybe a -> Tuple a String)
-> (String -> a -> Tuple a String)
-> String
-> Maybe a
-> Tuple a String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> a -> Tuple a String
forall a. Floating a => String -> a -> Tuple a String
printfFloating

printfComplex ::
   (Class.Real a) => String -> Complex a -> Tuple (Complex a) String
printfComplex :: String -> Complex a -> Tuple (Complex a) String
printfComplex String
fmt =
   ToTuple (Complex a) -> Complex a -> Tuple (Complex a) String
forall a. ToTuple a -> a -> Tuple a String
getToTuple (ToTuple (Complex a) -> Complex a -> Tuple (Complex a) String)
-> ToTuple (Complex a) -> Complex a -> Tuple (Complex a) String
forall a b. (a -> b) -> a -> b
$ Compose ToTuple Complex a -> ToTuple (Complex a)
forall k1 (f :: k1 -> *) k2 (g :: k2 -> k1) (a :: k2).
Compose f g a -> f (g a)
getCompose (Compose ToTuple Complex a -> ToTuple (Complex a))
-> Compose ToTuple Complex a -> ToTuple (Complex a)
forall a b. (a -> b) -> a -> b
$
   Compose ToTuple Complex Float
-> Compose ToTuple Complex Double -> Compose ToTuple Complex a
forall a (f :: * -> *). Real a => f Float -> f Double -> f a
Class.switchReal
      (ToTuple (Complex Float) -> Compose ToTuple Complex Float
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (ToTuple (Complex Float) -> Compose ToTuple Complex Float)
-> ToTuple (Complex Float) -> Compose ToTuple Complex Float
forall a b. (a -> b) -> a -> b
$ (Complex Float -> Tuple (Complex Float) String)
-> ToTuple (Complex Float)
forall a. (a -> Tuple a String) -> ToTuple a
ToTuple ((Complex Float -> Tuple (Complex Float) String)
 -> ToTuple (Complex Float))
-> (Complex Float -> Tuple (Complex Float) String)
-> ToTuple (Complex Float)
forall a b. (a -> b) -> a -> b
$ String -> Complex Float -> Tuple (Complex Float) String
forall a.
(PrintfArg a, Real a) =>
String -> Complex a -> Tuple (Complex a) String
printfComplexAux String
fmt)
      (ToTuple (Complex Double) -> Compose ToTuple Complex Double
forall k k1 (f :: k -> *) (g :: k1 -> k) (a :: k1).
f (g a) -> Compose f g a
Compose (ToTuple (Complex Double) -> Compose ToTuple Complex Double)
-> ToTuple (Complex Double) -> Compose ToTuple Complex Double
forall a b. (a -> b) -> a -> b
$ (Complex Double -> Tuple (Complex Double) String)
-> ToTuple (Complex Double)
forall a. (a -> Tuple a String) -> ToTuple a
ToTuple ((Complex Double -> Tuple (Complex Double) String)
 -> ToTuple (Complex Double))
-> (Complex Double -> Tuple (Complex Double) String)
-> ToTuple (Complex Double)
forall a b. (a -> b) -> a -> b
$ String -> Complex Double -> Tuple (Complex Double) String
forall a.
(PrintfArg a, Real a) =>
String -> Complex a -> Tuple (Complex a) String
printfComplexAux String
fmt)

printfComplexAux ::
   (PrintfArg a, Class.Real a) =>
   String -> Complex a -> Tuple (Complex a) String
printfComplexAux :: String -> Complex a -> Tuple (Complex a) String
printfComplexAux String
fmt (a
r:+a
i) =
   if a
ia -> a -> Bool
forall a. Ord a => a -> a -> Bool
<a
0 Bool -> Bool -> Bool
|| a -> Bool
forall a. RealFloat a => a -> Bool
isNegativeZero a
i
     then String -> String -> Tuple (Complex a) String
forall a b. Real a => b -> b -> Tuple (Complex a) b
complexTuple (String -> a -> String
forall r. PrintfType r => String -> r
printf (String
fmt String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"-") a
r) (String -> a -> String
forall r. PrintfType r => String -> r
printf (String
fmt String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"i") (-a
i))
     else String -> String -> Tuple (Complex a) String
forall a b. Real a => b -> b -> Tuple (Complex a) b
complexTuple (String -> a -> String
forall r. PrintfType r => String -> r
printf (String
fmt String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"+") a
r) (String -> a -> String
forall r. PrintfType r => String -> r
printf (String
fmt String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"i") a
i)

complexTuple :: (Class.Real a) => b -> b -> Tuple (Complex a) b
complexTuple :: b -> b -> Tuple (Complex a) b
complexTuple b
b0 b
b1 = TupleShape (Complex a) -> [b] -> Tuple (Complex a) b
forall sh a. C sh => sh -> [a] -> Array sh a
BoxedArray.fromList TupleShape (Complex a)
forall a. TupleShape a
TupleShape [b
b0,b
b1]