brush-strokes-0.1.0.0: src/lib/Math/Algebra/Dual.hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RebindableSyntax #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans -O2 #-}
module Math.Algebra.Dual
( C(..), D, Dim
, Differential(..)
, HasChainRule(..), chainRule
, uncurryD2, uncurryD3
, linear, fun, var
, chainRuleN1Q, chainRule1NQ
, ApModule(..)
, DiffModule(..)
, DπΈ0(..)
, D1πΈ1(..), D2πΈ1(..), D3πΈ1(..)
, D1πΈ2(..), D2πΈ2(..), D3πΈ2(..)
, D1πΈ3(..), D2πΈ3(..), D3πΈ3(..)
, D1πΈ4(..), D2πΈ4(..), D3πΈ4(..)
) where
-- base
import Prelude
hiding
( Num(..), Floating(..)
, (^), recip, fromInteger, fromRational )
import Data.Coerce
( coerce )
import Data.Kind
( Constraint, Type )
import GHC.TypeNats
( Nat )
-- brush-strokes
import Math.Algebra.Dual.Internal
import Math.Interval.Internal
import Math.Linear
import Math.Module
import Math.Monomial
import Math.Ring
--------------------------------------------------------------------------------
-- | @C n u v@ is the space of @C^k@-differentiable maps from @u@ to @v@.
type C :: Nat -> Type -> Type -> Type
newtype C k u v = D { runD :: u -> D k ( Dim u ) v }
deriving stock instance Functor ( D k ( Dim u ) ) => Functor ( C k u )
type Dim :: k -> Nat
type family Dim u
type instance Dim ( β n ) = n
-- | @D k u v@ is the space of @k@-th order germs of functions from @u@ to @v@,
-- represented by the algebra:
--
-- \[ \mathbb{Z}[x_1, \ldots, x_n]/(x_1, \ldots, x_n)^{k+1} \otimes_\mathbb{Z} v \]
--
-- when @u@ is of dimension @n@.
type D :: Nat -> Nat -> Type -> Type
type family D k u
type instance D k 0 = DπΈ0
type instance D 0 1 = DπΈ0
type instance D 0 2 = DπΈ0
type instance D 0 3 = DπΈ0
type instance D 0 4 = DπΈ0
type instance D 1 1 = D1πΈ1
type instance D 1 2 = D1πΈ2
type instance D 1 3 = D1πΈ3
type instance D 1 4 = D1πΈ4
type instance D 2 1 = D2πΈ1
type instance D 2 2 = D2πΈ2
type instance D 2 3 = D2πΈ3
type instance D 2 4 = D2πΈ4
type instance D 3 1 = D3πΈ1
type instance D 3 2 = D3πΈ2
type instance D 3 3 = D3πΈ3
type instance D 3 4 = D3πΈ4
--------------------------------------------------------------------------------
-- Weird instance needed in just one place;
-- see use of chain in 'Math.Bezier.Stroke.brushStrokeData'.
instance ( Applicative ( D k ( Dim u ) ), Module r ( T v ) )
=> Module r ( T ( C k u v ) ) where
origin = T $ D \ _ -> pure $ coerce $ origin @r @( T v )
T ( D f ) ^+^ T ( D g ) = T $ D \ t -> liftA2 ( coerce $ (^+^) @r @( T v ) ) ( f t ) ( g t )
T ( D f ) ^-^ T ( D g ) = T $ D \ t -> liftA2 ( coerce $ (^-^) @r @( T v ) ) ( f t ) ( g t )
a *^ T ( D f ) = T $ D \ t -> fmap ( coerce $ (*^) @r @( T v ) a ) $ f t
newtype DiffModule k n v = DiffModule { getDiffModule :: D k n v }
instance ( Applicative ( D k n ), Module r ( T v ) )
=> Module r ( T ( DiffModule k n v ) ) where
origin = T $ DiffModule $ pure $ coerce $ origin @r @( T v )
T ( DiffModule f ) ^+^ T ( DiffModule g ) = T $ DiffModule $ liftA2 ( coerce $ (^+^) @r @( T v ) ) f g
T ( DiffModule f ) ^-^ T ( DiffModule g ) = T $ DiffModule $ liftA2 ( coerce $ (^-^) @r @( T v ) ) f g
a *^ T ( DiffModule f ) = T $ DiffModule $ fmap ( coerce $ (*^) @r @( T v ) a ) f
--------------------------------------------------------------------------------
type Differential :: Nat -> Nat -> Constraint
class Differential k n where
konst :: AbelianGroup w => w -> D k n w
value :: D k n w -> w
-- | @HasChainRule r k v@ means we have a chain rule
-- with @D k v w@ in the middle, for any @r@-module @w@.
class Differential k ( Dim v ) => HasChainRule r k v where
chain :: Module r ( T w )
=> D k 1 v -> D k ( Dim v ) w -> D k 1 w
linearD :: Module r ( T w ) => ( v -> w ) -> v -> D k ( Dim v ) w
linear :: forall k r v w
. ( HasChainRule r k v, Module r ( T w ) )
=> ( v -> w ) -> C k v w
linear f = D \ x -> linearD @r @k @v @w f x
chainRule :: forall r k u v w
. ( HasChainRule r k v, Module r ( T w )
, Dim u ~ 1, HasChainRule r k u
)
=> C k u v -> C k v w -> C k u w
chainRule ( D df ) ( D dg ) =
D \ x ->
case df x of
df_x ->
chain @r @k @v df_x ( dg $ value @k @( Dim u ) df_x )
uncurryD2 :: D 2 1 ( D 2 1 b ) -> D 2 2 b
uncurryD2 ( D21 ( b_t0 ) ( T ( dbdt_t0 ) ) ( T ( d2bdt2_t0 ) ) ) =
let D21 b_t0s0 dbds_t0s0 d2bds2_t0s0 = b_t0
D21 dbdt_t0s0 d2bdtds_t0s0 _ = dbdt_t0
D21 d2bdt2_t0s0 _ _ = d2bdt2_t0
in D22
b_t0s0
( T dbdt_t0s0 ) dbds_t0s0
( T d2bdt2_t0s0 ) d2bdtds_t0s0 d2bds2_t0s0
uncurryD3 :: D 3 1 ( D 3 1 b ) -> D 3 2 b
uncurryD3 ( D31 b_t0 ( T dbdt_t0 ) ( T d2bdt2_t0 ) ( T d3bdt3_t0 ) ) =
let D31 b_t0s0 dbds_t0s0 d2bds2_t0s0 d3bds3_t0s0 = b_t0
D31 dbdt_t0s0 d2bdtds_t0s0 d3bdtds2_t0s0 _ = dbdt_t0
D31 d2bdt2_t0s0 d3bdt2ds_t0s0 _ _ = d2bdt2_t0
D31 d3bdt3_t0s0 _ _ _ = d3bdt3_t0
in D32
b_t0s0
( T dbdt_t0s0 ) dbds_t0s0
( T d2bdt2_t0s0 ) d2bdtds_t0s0 d2bds2_t0s0
( T d3bdt3_t0s0 ) d3bdt2ds_t0s0 d3bdtds2_t0s0 d3bds3_t0s0
-- | Recover the underlying function, discarding all infinitesimal information.
fun :: forall k v w. Differential k ( Dim v ) => C k v w -> ( v -> w )
fun ( D df ) = value @k @( Dim v ) . df
{-# INLINE fun #-}
-- | The differentiable germ of a coordinate variable.
var :: forall r k v
. ( Module r ( T r ), Representable r v, HasChainRule r k v )
=> Fin ( RepDim v ) -> C k v r
var i = D $ linearD @r @k @v ( `index` i )
{-# INLINE var #-}
--------------------------------------------------------------------------------
-- | Newtype for the module instance @Module r v => Module ( dr r ) ( dr v )@.
type ApModule :: Type -> ( Type -> Type ) -> Type -> Type
newtype ApModule r dr v = ApModule { unApModule :: dr v }
instance ( Ring ( dr r ), Module r ( T v ), Applicative dr )
=> Module ( dr r ) ( ApModule r dr v ) where
ApModule !u ^+^ ApModule !v = ApModule $ liftA2 ( coerce $ (^+^) @r @( T v ) ) u v
ApModule !u ^-^ ApModule !v = ApModule $ liftA2 ( coerce $ (^-^) @r @( T v ) ) u v
origin = ApModule $ pure $ coerce $ origin @r @( T v )
!k *^ ApModule !u = ApModule $ liftA2 ( coerce $ (*^) @r @( T v ) ) k u
deriving via ApModule r DπΈ0 v
instance Module r ( T v ) => Module ( DπΈ0 r ) ( DπΈ0 v )
--deriving via ApModule r D1πΈ1 v
-- instance Module r ( T v ) => Module ( D1πΈ1 r ) ( D1πΈ1 v )
deriving via ApModule r D2πΈ1 v
instance Module r ( T v ) => Module ( D2πΈ1 r ) ( D2πΈ1 v )
deriving via ApModule r D3πΈ1 v
instance Module r ( T v ) => Module ( D3πΈ1 r ) ( D3πΈ1 v )
--deriving via ApModule r D1πΈ2 v
-- instance Module r ( T v ) => Module ( D1πΈ2 r ) ( D1πΈ2 v )
deriving via ApModule r D2πΈ2 v
instance Module r ( T v ) => Module ( D2πΈ2 r ) ( D2πΈ2 v )
deriving via ApModule r D3πΈ2 v
instance Module r ( T v ) => Module ( D3πΈ2 r ) ( D3πΈ2 v )
--deriving via ApModule r D1πΈ3 v
-- instance Module r ( T v ) => Module ( D1πΈ3 r ) ( D1πΈ3 v )
deriving via ApModule r D2πΈ3 v
instance Module r ( T v ) => Module ( D2πΈ3 r ) ( D2πΈ3 v )
deriving via ApModule r D3πΈ3 v
instance Module r ( T v ) => Module ( D3πΈ3 r ) ( D3πΈ3 v )
--deriving via ApModule r D1πΈ4 v
-- instance Module r ( T v ) => Module ( D1πΈ4 r ) ( D1πΈ4 v )
deriving via ApModule r D2πΈ4 v
instance Module r ( T v ) => Module ( D2πΈ4 r ) ( D2πΈ4 v )
deriving via ApModule r D3πΈ4 v
instance Module r ( T v ) => Module ( D3πΈ4 r ) ( D3πΈ4 v )
--------------------------------------------------------------------------------
-- AbelianGroup instances
newtype ApAp2 k u r = ApAp2 { unApAp2 :: D k ( Dim u ) r }
instance ( Applicative ( D k ( Dim u ) )
, AbelianGroup r
, HasChainRule Double k u
) => AbelianGroup ( ApAp2 k u r ) where
ApAp2 !x + ApAp2 !y = ApAp2 $ liftA2 ( (+) @r ) x y
ApAp2 !x - ApAp2 !y = ApAp2 $ liftA2 ( (-) @r ) x y
negate ( ApAp2 !x ) = ApAp2 $ fmap ( negate @r ) x
-- DO NOT USE PURE!!
fromInteger !i = ApAp2 $ konst @k @( Dim u ) ( fromInteger @r i )
deriving newtype instance AbelianGroup r => AbelianGroup ( DπΈ0 r )
deriving via ApAp2 2 ( β 1 ) r
instance AbelianGroup r => AbelianGroup ( D2πΈ1 r )
deriving via ApAp2 3 ( β 1 ) r
instance AbelianGroup r => AbelianGroup ( D3πΈ1 r )
deriving via ApAp2 2 ( β 2 ) r
instance AbelianGroup r => AbelianGroup ( D2πΈ2 r )
deriving via ApAp2 3 ( β 2 ) r
instance AbelianGroup r => AbelianGroup ( D3πΈ2 r )
deriving via ApAp2 2 ( β 3 ) r
instance AbelianGroup r => AbelianGroup ( D2πΈ3 r )
deriving via ApAp2 3 ( β 3 ) r
instance AbelianGroup r => AbelianGroup ( D3πΈ3 r )
deriving via ApAp2 2 ( β 4 ) r
instance AbelianGroup r => AbelianGroup ( D2πΈ4 r )
deriving via ApAp2 3 ( β 4 ) r
instance AbelianGroup r => AbelianGroup ( D3πΈ4 r )
--------------------------------------------------------------------------------
-- Ring instances.
d1pow :: Ring r => Word -> r -> D1πΈ1 r
d1pow i x =
let !j = fromInteger $ fromIntegral i
in D11
( x ^ i )
( T $ j * x ^ (i - 1) )
{-# INLINE d1pow #-}
d2pow :: Ring r => Word -> r -> D2πΈ1 r
d2pow i x =
let !j = fromInteger $ fromIntegral i
in D21
( x ^ i )
( T $ j * x ^ (i - 1) )
( T $ j * (j - 1) * x ^ ( i - 2 ) )
{-# INLINE d2pow #-}
d3pow :: Ring r => Word -> r -> D3πΈ1 r
d3pow i x =
let !j = fromInteger $ fromIntegral i
in D31
( x ^ i )
( T $ j * x ^ (i - 1) )
( T $ j * (j - 1) * x ^ ( i - 2 ) )
( T $ j * (j - 1) * (j - 2) * x ^ ( i - 3 ) )
{-# INLINE d3pow #-}
deriving newtype instance Ring r => Ring ( DπΈ0 r )
--instance Ring r => Ring ( D1πΈ1 r ) where
--instance Ring r => Ring ( D1πΈ2 r ) where
--instance Ring r => Ring ( D1πΈ3 r ) where
--instance Ring r => Ring ( D1πΈ4 r ) where
instance Ring r => Ring ( D2πΈ1 r ) where
!dr1 * !dr2 =
let
o :: r
!o = fromInteger 0
p :: r -> r -> r
!p = (+) @r
m :: r -> r -> r
!m = (*) @r
in
$$( prodRuleQ
[|| o ||] [|| p ||] [|| m ||]
[|| dr1 ||] [|| dr2 ||] )
df ^ i =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2pow @r i ( _D21_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Ring ( D2πΈ1 Double ) #-}
{-# SPECIALISE instance Ring ( D2πΈ1 π ) #-}
instance Ring r => Ring ( D2πΈ2 r ) where
!dr1 * !dr2 =
let
o :: r
!o = fromInteger 0
p :: r -> r -> r
!p = (+) @r
m :: r -> r -> r
!m = (*) @r
in
$$( prodRuleQ
[|| o ||] [|| p ||] [|| m ||]
[|| dr1 ||] [|| dr2 ||] )
df ^ i =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2pow @r i ( _D22_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Ring ( D2πΈ2 Double ) #-}
{-# SPECIALISE instance Ring ( D2πΈ2 π ) #-}
instance Ring r => Ring ( D2πΈ3 r ) where
!dr1 * !dr2 =
let
o :: r
!o = fromInteger 0
p :: r -> r -> r
!p = (+) @r
m :: r -> r -> r
!m = (*) @r
in
$$( prodRuleQ
[|| o ||] [|| p ||] [|| m ||]
[|| dr1 ||] [|| dr2 ||] )
df ^ i =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2pow @r i ( _D23_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Ring ( D2πΈ3 Double ) #-}
{-# SPECIALISE instance Ring ( D2πΈ3 π ) #-}
instance Ring r => Ring ( D2πΈ4 r ) where
!dr1 * !dr2 =
let
o :: r
!o = fromInteger 0
p :: r -> r -> r
!p = (+) @r
m :: r -> r -> r
!m = (*) @r
in
$$( prodRuleQ
[|| o ||] [|| p ||] [|| m ||]
[|| dr1 ||] [|| dr2 ||] )
df ^ i =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2pow @r i ( _D24_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Ring ( D2πΈ4 Double ) #-}
{-# SPECIALISE instance Ring ( D2πΈ4 π ) #-}
instance Ring r => Ring ( D3πΈ1 r ) where
!dr1 * !dr2 =
let
o :: r
!o = fromInteger 0
p :: r -> r -> r
!p = (+) @r
m :: r -> r -> r
!m = (*) @r
in
$$( prodRuleQ
[|| o ||] [|| p ||] [|| m ||]
[|| dr1 ||] [|| dr2 ||] )
df ^ i =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3pow @r i ( _D31_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Ring ( D3πΈ1 Double ) #-}
{-# SPECIALISE instance Ring ( D3πΈ1 π ) #-}
instance Ring r => Ring ( D3πΈ2 r ) where
!dr1 * !dr2 =
let
o :: r
!o = fromInteger 0
p :: r -> r -> r
!p = (+) @r
m :: r -> r -> r
!m = (*) @r
in
$$( prodRuleQ
[|| o ||] [|| p ||] [|| m ||]
[|| dr1 ||] [|| dr2 ||] )
df ^ i =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3pow @r i ( _D32_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Ring ( D3πΈ2 Double ) #-}
{-# SPECIALISE instance Ring ( D3πΈ2 π ) #-}
instance Ring r => Ring ( D3πΈ3 r ) where
!dr1 * !dr2 =
let
o :: r
!o = fromInteger 0
p :: r -> r -> r
!p = (+) @r
m :: r -> r -> r
!m = (*) @r
in
$$( prodRuleQ
[|| o ||] [|| p ||] [|| m ||]
[|| dr1 ||] [|| dr2 ||] )
df ^ i =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3pow @r i ( _D33_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Ring ( D3πΈ3 Double ) #-}
{-# SPECIALISE instance Ring ( D3πΈ3 π ) #-}
instance Ring r => Ring ( D3πΈ4 r ) where
!dr1 * !dr2 =
let
o :: r
!o = fromInteger 0
p :: r -> r -> r
!p = (+) @r
m :: r -> r -> r
!m = (*) @r
in
$$( prodRuleQ
[|| o ||] [|| p ||] [|| m ||]
[|| dr1 ||] [|| dr2 ||] )
df ^ i =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2pow @r i ( _D34_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Ring ( D3πΈ4 Double ) #-}
{-# SPECIALISE instance Ring ( D3πΈ4 π ) #-}
--------------------------------------------------------------------------------
-- Field, floating & transcendental instances
d1recip :: Field r => r -> D1πΈ1 r
d1recip x =
let !d = recip x
in D11 d ( T $ -1 * d ^ 2 )
{-# INLINE d1recip #-}
d2recip :: Field r => r -> D2πΈ1 r
d2recip x =
let !d = recip x
in D21 d ( T $ -1 * d ^ 2 ) ( T $ 2 * d ^ 3 )
{-# INLINE d2recip #-}
d3recip :: Field r => r -> D3πΈ1 r
d3recip x =
let !d = recip x
in D31 d ( T $ -1 * d ^ 2 ) ( T $ 2 * d ^ 3 ) ( T $ -6 * d ^ 4 )
{-# INLINE d3recip #-}
deriving newtype instance Field r => Field ( DπΈ0 r )
--instance Field r => Field ( D1πΈ1 r ) where
--instance Field r => Field ( D1πΈ2 r ) where
--instance Field r => Field ( D1πΈ3 r ) where
--instance Field r => Field ( D1πΈ4 r ) where
instance Field r => Field ( D2πΈ1 r ) where
fromRational q = konst @2 @1 ( fromRational q )
recip df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2recip @r ( _D21_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Field ( D2πΈ1 Double ) #-}
{-# SPECIALISE instance Field ( D2πΈ1 π ) #-}
instance Field r => Field ( D2πΈ2 r ) where
fromRational q = konst @2 @2 ( fromRational q )
recip df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2recip @r ( _D22_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Field ( D2πΈ2 Double ) #-}
{-# SPECIALISE instance Field ( D2πΈ2 π ) #-}
instance Field r => Field ( D2πΈ3 r ) where
fromRational q = konst @2 @3 ( fromRational q )
recip df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2recip @r ( _D23_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Field ( D2πΈ3 Double ) #-}
{-# SPECIALISE instance Field ( D2πΈ3 π ) #-}
instance Field r => Field ( D2πΈ4 r ) where
fromRational q = konst @2 @4 ( fromRational q )
recip df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2recip @r ( _D24_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Field ( D2πΈ4 Double ) #-}
{-# SPECIALISE instance Field ( D2πΈ4 π ) #-}
instance Field r => Field ( D3πΈ1 r ) where
fromRational q = konst @3 @1 ( fromRational q )
recip df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3recip @r ( _D31_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Field ( D3πΈ1 Double ) #-}
{-# SPECIALISE instance Field ( D3πΈ1 π ) #-}
instance Field r => Field ( D3πΈ2 r ) where
fromRational q = konst @3 @2 ( fromRational q )
recip df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3recip @r ( _D32_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Field ( D3πΈ2 Double ) #-}
{-# SPECIALISE instance Field ( D3πΈ2 π ) #-}
instance Field r => Field ( D3πΈ3 r ) where
fromRational q = konst @3 @3 ( fromRational q )
recip df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3recip @r ( _D33_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Field ( D3πΈ3 Double ) #-}
{-# SPECIALISE instance Field ( D3πΈ3 π ) #-}
instance Field r => Field ( D3πΈ4 r ) where
fromRational q = konst @3 @4 ( fromRational q )
recip df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3recip @r ( _D34_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Field ( D3πΈ4 Double ) #-}
{-# SPECIALISE instance Field ( D3πΈ4 π ) #-}
d1sqrt :: Floating r => r -> D1πΈ1 r
d1sqrt x =
let !v = sqrt x
!d = recip v
in D11 v ( T $ 0.5 * d )
{-# INLINE d1sqrt #-}
d2sqrt :: Floating r => r -> D2πΈ1 r
d2sqrt x =
let !v = sqrt x
!d = recip v
in D21 v ( T $ 0.5 * d ) ( T $ -0.25 * d ^ 2 )
{-# INLINE d2sqrt #-}
d3sqrt :: Floating r => r -> D3πΈ1 r
d3sqrt x =
let !v = sqrt x
!d = recip v
in D31 v ( T $ 0.5 * d ) ( T $ -0.25 * d ^ 2 ) ( T $ 0.375 * d ^ 3 )
{-# INLINE d3sqrt #-}
deriving newtype instance Floating r => Floating ( DπΈ0 r )
--instance Floating r => Floating ( D1πΈ1 r ) where
--instance Floating r => Floating ( D1πΈ2 r ) where
--instance Floating r => Floating ( D1πΈ3 r ) where
--instance Floating r => Floating ( D1πΈ4 r ) where
instance Floating r => Floating ( D2πΈ1 r ) where
sqrt df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2sqrt @r ( _D21_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Floating ( D2πΈ1 Double ) #-}
{-# SPECIALISE instance Floating ( D2πΈ1 π ) #-}
instance Floating r => Floating ( D2πΈ2 r ) where
sqrt df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2sqrt @r ( _D22_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Floating ( D2πΈ2 Double ) #-}
{-# SPECIALISE instance Floating ( D2πΈ2 π ) #-}
instance Floating r => Floating ( D2πΈ3 r ) where
sqrt df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2sqrt @r ( _D23_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Floating ( D2πΈ3 Double ) #-}
{-# SPECIALISE instance Floating ( D2πΈ3 π ) #-}
instance Floating r => Floating ( D2πΈ4 r ) where
sqrt df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2sqrt @r ( _D24_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Floating ( D2πΈ4 Double ) #-}
{-# SPECIALISE instance Floating ( D2πΈ4 π ) #-}
instance Floating r => Floating ( D3πΈ1 r ) where
sqrt df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3sqrt @r ( _D31_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Floating ( D3πΈ1 Double ) #-}
{-# SPECIALISE instance Floating ( D3πΈ1 π ) #-}
instance Floating r => Floating ( D3πΈ2 r ) where
sqrt df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3sqrt @r ( _D32_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Floating ( D3πΈ2 Double ) #-}
{-# SPECIALISE instance Floating ( D3πΈ2 π ) #-}
instance Floating r => Floating ( D3πΈ3 r ) where
sqrt df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3sqrt @r ( _D33_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Floating ( D3πΈ3 Double ) #-}
{-# SPECIALISE instance Floating ( D3πΈ3 π ) #-}
instance Floating r => Floating ( D3πΈ4 r ) where
sqrt df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3sqrt @r ( _D34_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Floating ( D3πΈ4 Double ) #-}
{-# SPECIALISE instance Floating ( D3πΈ4 π ) #-}
d1sin, d1cos, d1atan :: Transcendental r => r -> D1πΈ1 r
d1sin x =
let !s = sin x
!c = cos x
in D11 s ( T c )
d1cos x =
let !s = sin x
!c = cos x
in D11 c ( T -s )
d1atan x
= let !d = recip $ 1 + x ^ 2
in D11
( atan x )
( T $ d )
{-# INLINE d1sin #-}
{-# INLINE d1cos #-}
{-# INLINE d1atan #-}
d2sin, d2cos, d2atan :: Transcendental r => r -> D2πΈ1 r
d2sin x =
let !s = sin x
!c = cos x
in D21 s ( T c ) ( T -s )
d2cos x =
let !s = sin x
!c = cos x
in D21 c ( T -s ) ( T -c )
d2atan x
= let !d = recip $ 1 + x ^ 2
in D21
( atan x )
( T $ d )
( T $ -2 * x * d ^ 2 )
{-# INLINE d2sin #-}
{-# INLINE d2cos #-}
{-# INLINE d2atan #-}
d3sin, d3cos, d3atan :: Transcendental r => r -> D3πΈ1 r
d3sin x =
let !s = sin x
!c = cos x
in D31 s ( T c ) ( T -s ) ( T -c )
d3cos x =
let !s = sin x
!c = cos x
in D31 c ( T -s ) ( T -c ) ( T s )
d3atan x
= let !d = recip $ 1 + x ^ 2
in D31
( atan x )
( T $ d )
( T $ -2 * x * d ^ 2 )
( T $ ( -2 + 6 * x ^ 2 ) * d ^ 3 )
{-# INLINE d3sin #-}
{-# INLINE d3cos #-}
{-# INLINE d3atan #-}
deriving newtype instance Transcendental r => Transcendental ( DπΈ0 r )
--instance Transcendental r => Transcendental ( D1πΈ1 r ) where
--instance Transcendental r => Transcendental ( D1πΈ2 r ) where
--instance Transcendental r => Transcendental ( D1πΈ3 r ) where
--instance Transcendental r => Transcendental ( D1πΈ4 r ) where
instance Transcendental r => Transcendental ( D2πΈ1 r ) where
pi = konst @2 @1 pi
sin df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2sin @r ( _D21_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
cos df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2cos @r ( _D21_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
atan df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2atan @r ( _D21_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Transcendental ( D2πΈ1 Double ) #-}
{-# SPECIALISE instance Transcendental ( D2πΈ1 π ) #-}
instance Transcendental r => Transcendental ( D2πΈ2 r ) where
pi = konst @2 @2 pi
sin df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2sin @r ( _D22_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
cos df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2cos @r ( _D22_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
atan df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2atan @r ( _D22_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Transcendental ( D2πΈ2 Double ) #-}
{-# SPECIALISE instance Transcendental ( D2πΈ2 π ) #-}
instance Transcendental r => Transcendental ( D2πΈ3 r ) where
pi = konst @2 @3 pi
sin df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2sin @r ( _D23_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
cos df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2cos @r ( _D23_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
atan df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2atan @r ( _D23_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Transcendental ( D2πΈ3 Double ) #-}
{-# SPECIALISE instance Transcendental ( D2πΈ3 π ) #-}
instance Transcendental r => Transcendental ( D2πΈ4 r ) where
pi = konst @2 @4 pi
sin df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2sin @r ( _D24_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
cos df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2cos @r ( _D24_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
atan df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d2atan @r ( _D24_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Transcendental ( D2πΈ4 Double ) #-}
{-# SPECIALISE instance Transcendental ( D2πΈ4 π ) #-}
instance Transcendental r => Transcendental ( D3πΈ1 r ) where
pi = konst @3 @1 pi
sin df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3sin @r ( _D31_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
cos df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3cos @r ( _D31_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
atan df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3atan @r ( _D31_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Transcendental ( D3πΈ1 Double ) #-}
{-# SPECIALISE instance Transcendental ( D3πΈ1 π ) #-}
instance Transcendental r => Transcendental ( D3πΈ2 r ) where
pi = konst @3 @2 pi
sin df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3sin @r ( _D32_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
cos df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3cos @r ( _D32_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
atan df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3atan @r ( _D32_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Transcendental ( D3πΈ2 Double ) #-}
{-# SPECIALISE instance Transcendental ( D3πΈ2 π ) #-}
instance Transcendental r => Transcendental ( D3πΈ3 r ) where
pi = konst @3 @3 pi
sin df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3sin @r ( _D33_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
cos df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3cos @r ( _D33_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
atan df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3atan @r ( _D33_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Transcendental ( D3πΈ3 Double ) #-}
{-# SPECIALISE instance Transcendental ( D3πΈ3 π ) #-}
instance Transcendental r => Transcendental ( D3πΈ4 r ) where
pi = konst @3 @4 pi
sin df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3sin @r ( _D34_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
cos df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3cos @r ( _D34_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
atan df =
let
fromInt = fromInteger @r
add = (+) @r
times = (*) @r
pow = (^) @r
dg = d3atan @r ( _D34_v df )
in $$( chainRuleN1Q [|| fromInt ||] [|| add ||] [|| times ||] [|| pow ||]
[|| df ||] [|| dg ||] )
{-# SPECIALISE instance Transcendental ( D3πΈ4 Double ) #-}
{-# SPECIALISE instance Transcendental ( D3πΈ4 π ) #-}
--------------------------------------------------------------------------------
-- HasChainRule instances.
instance Differential 2 0 where
konst w = D0 w
value ( D0 v ) = v
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 2 ( β 0 ) where
linearD f v = D0 ( f v )
chain _ ( D0 gfx ) = D21 gfx origin origin
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}
instance Differential 3 0 where
konst w = D0 w
value ( D0 v ) = v
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 3 ( β 0 ) where
linearD f v = D0 ( f v )
chain _ ( D0 gfx ) = D31 gfx origin origin origin
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}
instance Differential 2 1 where
konst :: forall w. AbelianGroup w => w -> D2πΈ1 w
konst w =
let !o = fromInteger @w 0
in $$( monTabulateQ \ mon -> if isZeroMonomial mon then [|| w ||] else [|| o ||] )
value df = $$( monIndexQ [|| df ||] zeroMonomial )
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 2 ( β 1 ) where
linearD :: forall w. Module Double ( T w ) => ( β 1 -> w ) -> β 1 -> D2πΈ1 w
linearD f v =
let !o = origin @Double @( T w )
in $$( monTabulateQ \ mon ->
if | isZeroMonomial mon
-> [|| f v ||]
| Just i <- isLinear mon
-> [|| f $$( tabulateQ \ j ->
if | j == i
-> [|| 1 ||]
| otherwise
-> [|| 0 ||]
) ||]
| otherwise
-> [|| unT o ||]
)
chain :: forall w. Module Double ( T w ) => D2πΈ1 ( β 1 ) -> D2πΈ1 w -> D2πΈ1 w
chain !df !dg =
let !o = origin @Double @( T w )
!p = (^+^) @Double @( T w )
!s = (^*) @Double @( T w )
in $$( chainRule1NQ
[|| o ||] [|| p ||] [|| s ||]
[|| df ||] [|| dg ||] )
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}
instance Differential 3 1 where
konst :: forall w. AbelianGroup w => w -> D3πΈ1 w
konst w =
let !o = fromInteger @w 0
in $$( monTabulateQ \ mon -> if isZeroMonomial mon then [|| w ||] else [|| o ||] )
value df = $$( monIndexQ [|| df ||] zeroMonomial )
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 3 ( β 1 ) where
chain :: forall w. Module Double ( T w ) => D3πΈ1 ( β 1 ) -> D3πΈ1 w -> D3πΈ1 w
chain !df !dg =
let !o = origin @Double @( T w )
!p = (^+^) @Double @( T w )
!s = (^*) @Double @( T w )
in $$( chainRule1NQ
[|| o ||] [|| p ||] [|| s ||]
[|| df ||] [|| dg ||] )
linearD :: forall w. Module Double ( T w ) => ( β 1 -> w ) -> β 1 -> D3πΈ1 w
linearD f v =
let !o = origin @Double @( T w )
in $$( monTabulateQ \ mon ->
if | isZeroMonomial mon
-> [|| f v ||]
| Just i <- isLinear mon
-> [|| f $$( tabulateQ \ j ->
if | j == i
-> [|| 1 ||]
| otherwise
-> [|| 0 ||]
) ||]
| otherwise
-> [|| unT o ||]
)
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}
instance Differential 2 2 where
konst :: forall w. AbelianGroup w => w -> D2πΈ2 w
konst w =
let !o = fromInteger @w 0
in $$( monTabulateQ \ mon -> if isZeroMonomial mon then [|| w ||] else [|| o ||] )
value df = $$( monIndexQ [|| df ||] zeroMonomial )
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 2 ( β 2 ) where
linearD :: forall w. Module Double ( T w ) => ( β 2 -> w ) -> β 2 -> D2πΈ2 w
linearD f v =
let !o = origin @Double @( T w )
in $$( monTabulateQ \ mon ->
if | isZeroMonomial mon
-> [|| f v ||]
| Just i <- isLinear mon
-> [|| f $$( tabulateQ \ j ->
if | j == i
-> [|| 1 ||]
| otherwise
-> [|| 0 ||]
) ||]
| otherwise
-> [|| unT o ||]
)
chain :: forall w. Module Double ( T w ) => D2πΈ1 ( β 2 ) -> D2πΈ2 w -> D2πΈ1 w
chain !df !dg =
let !o = origin @Double @( T w )
!p = (^+^) @Double @( T w )
!s = (^*) @Double @( T w )
in $$( chainRule1NQ
[|| o ||] [|| p ||] [|| s ||]
[|| df ||] [|| dg ||] )
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}
instance Differential 3 2 where
konst :: forall w. AbelianGroup w => w -> D3πΈ2 w
konst w =
let !o = fromInteger @w 0
in $$( monTabulateQ \ mon -> if isZeroMonomial mon then [|| w ||] else [|| o ||] )
value df = $$( monIndexQ [|| df ||] zeroMonomial )
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 3 ( β 2 ) where
linearD :: forall w. Module Double ( T w ) => ( β 2 -> w ) -> β 2 -> D3πΈ2 w
linearD f v =
let !o = origin @Double @( T w )
in $$( monTabulateQ \ mon ->
if | isZeroMonomial mon
-> [|| f v ||]
| Just i <- isLinear mon
-> [|| f $$( tabulateQ \ j ->
if | j == i
-> [|| 1 ||]
| otherwise
-> [|| 0 ||]
) ||]
| otherwise
-> [|| unT o ||]
)
chain :: forall w. Module Double ( T w ) => D3πΈ1 ( β 2 ) -> D3πΈ2 w -> D3πΈ1 w
chain !df !dg =
let !o = origin @Double @( T w )
!p = (^+^) @Double @( T w )
!s = (^*) @Double @( T w )
in $$( chainRule1NQ
[|| o ||] [|| p ||] [|| s ||]
[|| df ||] [|| dg ||] )
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}
instance Differential 2 3 where
konst :: forall w. AbelianGroup w => w -> D2πΈ3 w
konst w =
let !o = fromInteger @w 0
in $$( monTabulateQ \ mon -> if isZeroMonomial mon then [|| w ||] else [|| o ||] )
value df = $$( monIndexQ [|| df ||] zeroMonomial )
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 2 ( β 3 ) where
linearD :: forall w. Module Double ( T w ) => ( β 3 -> w ) -> β 3 -> D2πΈ3 w
linearD f v =
let !o = origin @Double @( T w )
in $$( monTabulateQ \ mon ->
if | isZeroMonomial mon
-> [|| f v ||]
| Just i <- isLinear mon
-> [|| f $$( tabulateQ \ j ->
if | j == i
-> [|| 1 ||]
| otherwise
-> [|| 0 ||]
) ||]
| otherwise
-> [|| unT o ||]
)
chain :: forall w. Module Double ( T w ) => D2πΈ1 ( β 3 ) -> D2πΈ3 w -> D2πΈ1 w
chain !df !dg =
let !o = origin @Double @( T w )
!p = (^+^) @Double @( T w )
!s = (^*) @Double @( T w )
in $$( chainRule1NQ
[|| o ||] [|| p ||] [|| s ||]
[|| df ||] [|| dg ||] )
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}
instance Differential 3 3 where
konst :: forall w. AbelianGroup w => w -> D3πΈ3 w
konst w =
let !o = fromInteger @w 0
in $$( monTabulateQ \ mon -> if isZeroMonomial mon then [|| w ||] else [|| o ||] )
value df = $$( monIndexQ [|| df ||] zeroMonomial )
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 3 ( β 3 ) where
linearD :: forall w. Module Double ( T w ) => ( β 3 -> w ) -> β 3 -> D3πΈ3 w
linearD f v =
let !o = origin @Double @( T w )
in $$( monTabulateQ \ mon ->
if | isZeroMonomial mon
-> [|| f v ||]
| Just i <- isLinear mon
-> [|| f $$( tabulateQ \ j ->
if | j == i
-> [|| 1 ||]
| otherwise
-> [|| 0 ||]
) ||]
| otherwise
-> [|| unT o ||]
)
chain :: forall w. Module Double ( T w ) => D3πΈ1 ( β 3 ) -> D3πΈ3 w -> D3πΈ1 w
chain !df !dg =
let !o = origin @Double @( T w )
!p = (^+^) @Double @( T w )
!s = (^*) @Double @( T w )
in $$( chainRule1NQ
[|| o ||] [|| p ||] [|| s ||]
[|| df ||] [|| dg ||] )
{-# INLINEABLE chain #-}
{-# INLINEABLE linearD #-}
instance Differential 2 4 where
konst :: forall w. AbelianGroup w => w -> D2πΈ4 w
konst w =
let !o = fromInteger @w 0
in $$( monTabulateQ \ mon -> if isZeroMonomial mon then [|| w ||] else [|| o ||] )
value df = $$( monIndexQ [|| df ||] zeroMonomial )
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 2 ( β 4 ) where
linearD :: forall w. Module Double ( T w ) => ( β 4 -> w ) -> β 4 -> D2πΈ4 w
linearD f v =
let !o = origin @Double @( T w )
in $$( monTabulateQ \ mon ->
if | isZeroMonomial mon
-> [|| f v ||]
| Just i <- isLinear mon
-> [|| f $$( tabulateQ \ j ->
if | j == i
-> [|| 1 ||]
| otherwise
-> [|| 0 ||]
) ||]
| otherwise
-> [|| unT o ||]
)
chain :: forall w. Module Double ( T w ) => D2πΈ1 ( β 4 ) -> D2πΈ4 w -> D2πΈ1 w
chain !df !dg =
let !o = origin @Double @( T w )
!p = (^+^) @Double @( T w )
!s = (^*) @Double @( T w )
in $$( chainRule1NQ
[|| o ||] [|| p ||] [|| s ||]
[|| df ||] [|| dg ||] )
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}
instance Differential 3 4 where
konst :: forall w. AbelianGroup w => w -> D3πΈ4 w
konst w =
let !o = fromInteger @w 0
in $$( monTabulateQ \ mon -> if isZeroMonomial mon then [|| w ||] else [|| o ||] )
value df = $$( monIndexQ [|| df ||] zeroMonomial )
{-# INLINEABLE konst #-}
{-# INLINEABLE value #-}
instance HasChainRule Double 3 ( β 4 ) where
linearD :: forall w. Module Double ( T w ) => ( β 4 -> w ) -> β 4 -> D3πΈ4 w
linearD f v =
let !o = origin @Double @( T w )
in $$( monTabulateQ \ mon ->
if | isZeroMonomial mon
-> [|| f v ||]
| Just i <- isLinear mon
-> [|| f $$( tabulateQ \ j ->
if | j == i
-> [|| 1 ||]
| otherwise
-> [|| 0 ||]
) ||]
| otherwise
-> [|| unT o ||]
)
chain :: forall w. Module Double ( T w ) => D3πΈ1 ( β 4 ) -> D3πΈ4 w -> D3πΈ1 w
chain !df !dg =
let !o = origin @Double @( T w )
!p = (^+^) @Double @( T w )
!s = (^*) @Double @( T w )
in $$( chainRule1NQ
[|| o ||] [|| p ||] [|| s ||]
[|| df ||] [|| dg ||] )
{-# INLINEABLE linearD #-}
{-# INLINEABLE chain #-}