safe-tensor-0.1.0.0: src/Math/Tensor/Basic/Delta.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE ExistentialQuantification #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoStarIsType #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
-----------------------------------------------------------------------------
{-|
Module : Math.Tensor.Basic.Delta
Description : Definitions of Kronecker deltas.
Copyright : (c) Nils Alex, 2020
License : MIT
Maintainer : nils.alex@fau.de
Stability : experimental
Definitions of Kronecker deltas \(\delta^{a}_{\hphantom ab}\)
(identity automorphisms) for arbitrary vector spaces.
-}
-----------------------------------------------------------------------------
module Math.Tensor.Basic.Delta
( -- * Kronecker delta
delta
, delta'
, someDelta
) where
import Math.Tensor
import Math.Tensor.Safe
import Math.Tensor.Safe.TH
import Math.Tensor.Basic.TH
import Data.Singletons
( Sing
, SingI (sing)
, Demote
, withSomeSing
)
import Data.Singletons.Prelude
( SList (SNil)
, SBool (STrue)
)
import Data.Singletons.Decide
( (:~:) (Refl)
, Decision (Proved)
, (%~)
)
import Data.Singletons.TypeLits
( Symbol
, Nat
, KnownNat
, withKnownNat
, natVal
, withKnownSymbol
)
import Data.List.NonEmpty (NonEmpty ((:|)))
-- |The Kronecker delta \(\delta^a_{\hphantom ab} \) for a given
-- @'VSpace' id n@ with contravariant
-- index label @a@ and covariant index label @b@. Labels and dimension
-- are passed explicitly as singletons.
delta' :: forall (id :: Symbol) (n :: Nat) (a :: Symbol) (b :: Symbol) (r :: Rank) v.
(
KnownNat n,
Num v,
'[ '( 'VSpace id n, 'ConCov (a ':| '[]) (b ':| '[])) ] ~ r,
Tail' (Tail' r) ~ '[],
Sane (Tail' r) ~ 'True
) =>
Sing id -> Sing n -> Sing a -> Sing b ->
Tensor r v
delta' _ _ _ _ = delta
-- |The Kronecker delta \(\delta^a_{\hphantom ab} \) for a given
-- @'VSpace' id n@ with contravariant
-- index label @a@ and covariant index label @b@.
delta :: forall (id :: Symbol) (n :: Nat) (a :: Symbol) (b :: Symbol) (r :: Rank) v.
(
'[ '( 'VSpace id n, 'ConCov (a ':| '[]) (b ':| '[]))] ~ r,
Tail' (Tail' r) ~ '[],
Sane (Tail' r) ~ 'True,
SingI n,
Num v
) => Tensor r v
delta = case (sing :: Sing n) of
sn -> let x = fromIntegral $ withKnownNat sn $ natVal sn
in Tensor (f x)
where
f :: Int -> [(Int, Tensor (Tail' r) v)]
f x = map (\i -> (i, Tensor [(i, Scalar 1)])) [0..x - 1]
-- |The Kronecker delta \(\delta^a_{\hphantom ab} \) for a given
-- @'VSpace' id n@ with contravariant
-- index label @a@ and covariant index label @b@. Labels and dimension
-- are passed as values. Result is existentially quantified.
someDelta :: Num v =>
Demote Symbol -> Demote Nat -> Demote Symbol -> Demote Symbol ->
T v
someDelta vid vdim a b =
withSomeSing vid $ \svid ->
withSomeSing vdim $ \svdim ->
withSomeSing a $ \sa ->
withSomeSing b $ \sb ->
withKnownNat svdim $
withKnownSymbol svid $
withKnownSymbol sa $
withKnownSymbol sb $
let sl = sDeltaRank svid svdim sa sb
in case sTail' (sTail' sl) of
SNil -> case sSane (sTail' sl) %~ STrue of
Proved Refl -> T $ delta' svid svdim sa sb