packages feed

downhill 0.3.0.0 → 0.4.0.0

raw patch · 9 files changed

+216/−70 lines, 9 filesdep −template-haskelldep −th-abstractionPVP ok

version bump matches the API change (PVP)

Dependencies removed: template-haskell, th-abstraction

API changes (from Hackage documentation)

- Downhill.BVar: instance (Data.VectorSpace.VectorSpace v, Downhill.Grad.HasGrad v, Downhill.Grad.Grad v GHC.Types.~ v, Downhill.Grad.Tang v GHC.Types.~ v, Downhill.Linear.Expr.BasicVector (Downhill.Grad.MScalar v), Downhill.Grad.Grad (Downhill.Grad.MScalar v) GHC.Types.~ Downhill.Grad.MScalar v, Data.VectorSpace.InnerSpace v, Downhill.Grad.HasGrad (Downhill.Grad.MScalar v)) => Data.VectorSpace.InnerSpace (Downhill.BVar.BVar r v)
- Downhill.BVar: instance (Data.VectorSpace.VectorSpace v, Downhill.Grad.HasGrad v, Downhill.Grad.Tang v GHC.Types.~ v, Downhill.Linear.Expr.BasicVector (Downhill.Grad.MScalar v), Downhill.Grad.Grad (Downhill.Grad.MScalar v) GHC.Types.~ Downhill.Grad.MScalar v) => Data.VectorSpace.VectorSpace (Downhill.BVar.BVar r v)
- Downhill.BVar.Num: instance GHC.Num.Num a => Downhill.Grad.HasGrad (Downhill.BVar.Num.AsNum a)
- Downhill.BVar.Traversable: instance Downhill.Grad.HasGrad a => Downhill.Grad.HasGrad (Downhill.BVar.Traversable.TraversableVar f a)
- Downhill.Grad: class (Dual (Tang p) (Grad p), BasicVector (Grad p), Scalar (Tang p) ~ Scalar (Grad p)) => HasGrad p where {
- Downhill.Grad: instance (Downhill.Grad.HasGrad a, Downhill.Grad.HasGrad b, Downhill.Grad.HasGrad c, Downhill.Grad.MScalar b GHC.Types.~ Downhill.Grad.MScalar a, Downhill.Grad.MScalar c GHC.Types.~ Downhill.Grad.MScalar a) => Downhill.Grad.HasGrad (a, b, c)
- Downhill.Grad: instance (Downhill.Grad.HasGrad a, Downhill.Grad.HasGrad b, Downhill.Grad.MScalar b GHC.Types.~ Downhill.Grad.MScalar a) => Downhill.Grad.HasGrad (a, b)
- Downhill.Grad: instance Downhill.Grad.HasGrad GHC.Num.Integer.Integer
- Downhill.Grad: instance Downhill.Grad.HasGrad GHC.Types.Double
- Downhill.Grad: instance Downhill.Grad.HasGrad GHC.Types.Float
+ Downhill.BVar: instance (Data.VectorSpace.VectorSpace v, Downhill.Grad.HasGrad v, Downhill.Grad.Tang v GHC.Types.~ v, Downhill.Grad.HasGrad (Downhill.Grad.MScalar v), Downhill.Grad.Grad (Data.VectorSpace.Scalar v) GHC.Types.~ Data.VectorSpace.Scalar v) => Data.VectorSpace.VectorSpace (Downhill.BVar.BVar r v)
+ Downhill.BVar: instance (Data.VectorSpace.VectorSpace v, Downhill.Grad.HasGrad v, Downhill.Grad.Tang v GHC.Types.~ v, Downhill.Grad.HilbertSpace (Downhill.Grad.Tang v) (Downhill.Grad.Grad v), Downhill.Linear.Expr.BasicVector (Downhill.Grad.MScalar v), Downhill.Grad.Grad (Downhill.Grad.MScalar v) GHC.Types.~ Downhill.Grad.MScalar v, Data.VectorSpace.InnerSpace v, Downhill.Grad.HasGrad (Downhill.Grad.MScalar v)) => Data.VectorSpace.InnerSpace (Downhill.BVar.BVar r v)
+ Downhill.BVar: instance (Downhill.Grad.HasGrad (Data.VectorSpace.Scalar v), Downhill.Grad.HasGrad v, Downhill.Grad.HasGrad dv, Downhill.Grad.Dual v dv, Downhill.Grad.Grad dv GHC.Types.~ v, Downhill.Grad.Grad v GHC.Types.~ dv, Downhill.Grad.Tang v GHC.Types.~ v, Downhill.Grad.Tang dv GHC.Types.~ dv, Downhill.Grad.Grad (Data.VectorSpace.Scalar dv) GHC.Types.~ Data.VectorSpace.Scalar dv) => Downhill.Grad.Dual (Downhill.BVar.BVar r v) (Downhill.BVar.BVar r dv)
+ Downhill.BVar: instance (Downhill.Grad.HasGrad (Downhill.Grad.MScalar p), Downhill.Grad.HasGrad (Downhill.Grad.Tang p), Downhill.Grad.HasGrad (Downhill.Grad.Grad p), Downhill.Grad.Grad (Downhill.Grad.Grad p) GHC.Types.~ Downhill.Grad.Tang p, Downhill.Grad.Tang (Downhill.Grad.Grad p) GHC.Types.~ Downhill.Grad.Grad p, Downhill.Grad.Tang (Downhill.Grad.Tang p) GHC.Types.~ Downhill.Grad.Tang p, Downhill.Grad.Grad (Downhill.Grad.Tang p) GHC.Types.~ Downhill.Grad.Grad p, Downhill.Grad.Grad (Downhill.Grad.MScalar p) GHC.Types.~ Downhill.Grad.MScalar p, Data.VectorSpace.Scalar (Downhill.Grad.Grad p) GHC.Types.~ Data.VectorSpace.Scalar (Downhill.Grad.Tang p), Downhill.Grad.Manifold p) => Downhill.Grad.Manifold (Downhill.BVar.BVar r p)
+ Downhill.BVar: instance (Downhill.Grad.HilbertSpace v dv, Downhill.Grad.HasGrad (Data.VectorSpace.Scalar v), Downhill.Grad.HasGrad v, Downhill.Grad.HasGrad dv, Downhill.Grad.Grad dv GHC.Types.~ v, Downhill.Grad.Grad v GHC.Types.~ dv, Downhill.Grad.Tang v GHC.Types.~ v, Downhill.Grad.Tang dv GHC.Types.~ dv, Downhill.Grad.Grad (Data.VectorSpace.Scalar dv) GHC.Types.~ Data.VectorSpace.Scalar dv) => Downhill.Grad.HilbertSpace (Downhill.BVar.BVar r v) (Downhill.BVar.BVar r dv)
+ Downhill.BVar.Num: instance GHC.Num.Num a => Downhill.Grad.Manifold (Downhill.BVar.Num.AsNum a)
+ Downhill.BVar.Traversable: instance Downhill.Grad.Manifold a => Downhill.Grad.Manifold (Downhill.BVar.Traversable.TraversableVar f a)
+ Downhill.BVar.Traversable: instance Downhill.Grad.Manifold v => Downhill.Grad.Manifold (Downhill.BVar.Traversable.IntmapVector f v)
+ Downhill.Grad: class Dual v dv => HilbertSpace v dv
+ Downhill.Grad: class (Dual (Tang p) (Grad p), Scalar (Tang p) ~ Scalar (Grad p)) => Manifold p where {
+ Downhill.Grad: coriesz :: HilbertSpace v dv => dv -> v
+ Downhill.Grad: instance (Downhill.Grad.HasGrad a, Downhill.Grad.HasGrad b, Downhill.Grad.HasGrad c, Downhill.Grad.MScalar b GHC.Types.~ Downhill.Grad.MScalar a, Downhill.Grad.MScalar c GHC.Types.~ Downhill.Grad.MScalar a) => Downhill.Grad.Manifold (a, b, c)
+ Downhill.Grad: instance (Downhill.Grad.HasGrad a, Downhill.Grad.HasGrad b, Downhill.Grad.MScalar b GHC.Types.~ Downhill.Grad.MScalar a) => Downhill.Grad.Manifold (a, b)
+ Downhill.Grad: instance Downhill.Grad.Manifold GHC.Num.Integer.Integer
+ Downhill.Grad: instance Downhill.Grad.Manifold GHC.Types.Double
+ Downhill.Grad: instance Downhill.Grad.Manifold GHC.Types.Float
+ Downhill.Grad: riesz :: HilbertSpace v dv => v -> dv
+ Downhill.Grad: type HasGrad p = (Manifold p, BasicVector (Grad p))

Files

CHANGELOG.md view
@@ -1,5 +1,8 @@ # Revision history for downhill +## 0.4.0.0+* `Manifold` class+ ## 0.2.0.0 * `MetricTensor` is no longer required to be a `VectorSpace` * `T2`, `T3` pattern synonyms for `BVar`
downhill.cabal view
@@ -1,7 +1,7 @@ cabal-version:       2.4  name:                downhill-version:             0.3.0.0+version:             0.4.0.0 synopsis:            Reverse mode automatic differentiation homepage:            https://andriusstank.github.io/downhill/ description:@@ -39,9 +39,7 @@   build-depends:       base                  >= 4.12.0.0 && <4.18,                        containers            >= 0.6.5 && < 0.7,                        reflection            >= 2.1.6 && < 2.2,-                       template-haskell      >= 2.16.0 && < 2.20,                        transformers          >= 0.5.6 && < 0.7,-                       th-abstraction        >= 0.4.3 && < 0.5,                        unordered-containers  >= 0.2.14 && < 0.3,                        vector-space          >= 0.16 && < 0.17,   hs-source-dirs:      src
src/Downhill/BVar.hs view
@@ -6,13 +6,13 @@ {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ViewPatterns #-}  module Downhill.BVar@@ -20,9 +20,10 @@     var,     constant,     backprop,+     -- * Pattern synonyms     pattern T2,-    pattern T3+    pattern T3,   ) where @@ -32,23 +33,25 @@ import Data.VectorSpace   ( AdditiveGroup (..),     InnerSpace ((<.>)),-    VectorSpace ((*^)),+    VectorSpace (Scalar, (*^)),   )-import qualified Data.VectorSpace as VectorSpace import Downhill.Grad   ( Dual (evalGrad),-    HasGrad (Grad, Tang),-    HasGradAffine, MScalar+    HasGrad,+    HasGradAffine,+    HilbertSpace (coriesz, riesz),+    MScalar,+    Manifold (Grad, Tang),   ) import Downhill.Linear.BackGrad   ( BackGrad (..),     realNode,   ) import qualified Downhill.Linear.Backprop as BP-import Downhill.Linear.Expr (BasicVector, Expr (ExprVar))-import Downhill.Linear.Lift (lift2_dense)-import Prelude hiding (id, (.))+import Downhill.Linear.Expr (BasicVector (..), Expr (ExprVar))+import Downhill.Linear.Lift (lift1_dense, lift2_dense) import qualified Downhill.Linear.Prelude as Linear+import Prelude hiding (id, (.))  -- | Variable is a value paired with derivative. data BVar r a = BVar@@ -103,8 +106,8 @@   ( VectorSpace v,     HasGrad v,     Tang v ~ v,-    BasicVector (MScalar v),-    Grad (MScalar v) ~ MScalar v+    HasGrad (MScalar v),+    Grad (Scalar v) ~ Scalar v   ) =>   VectorSpace (BVar r v)   where@@ -121,11 +124,60 @@   BVar y0 dy .+^ BVar z0 dz = BVar (y0 .+^ z0) (dy ^+^ dz)   BVar y0 dy .-. BVar z0 dz = BVar (y0 .-. z0) (dy ^-^ dz) +-- maybe move all those equality constraints to Dual class? instance+  ( HasGrad (Scalar v),+    HasGrad v,+    HasGrad dv,+    Dual v dv,+    Grad dv ~ v,+    Grad v ~ dv,+    Tang v ~ v,+    Tang dv ~ dv,+    Grad (Scalar dv) ~ Scalar dv+  ) =>+  Dual (BVar r v) (BVar r dv)+  where+  evalGrad (BVar dv d_dv) (BVar v d_v) = BVar (evalGrad dv v) (lift2_dense (*^ v) (*^ dv) d_dv d_v)++instance+  ( HasGrad (MScalar p),+    HasGrad (Tang p),+    HasGrad (Grad p),+    Grad (Grad p) ~ Tang p,+    Tang (Grad p) ~ Grad p,+    Tang (Tang p) ~ Tang p,+    Grad (Tang p) ~ Grad p,+    Grad (MScalar p) ~ MScalar p,+    Scalar (Grad p) ~ Scalar (Tang p),+    Manifold p+  ) =>+  Manifold (BVar r p)+  where+  type Tang (BVar r p) = BVar r (Tang p)+  type Grad (BVar r p) = BVar r (Grad p)++instance+  ( HilbertSpace v dv,+    HasGrad (Scalar v),+    HasGrad v,+    HasGrad dv,+    Grad dv ~ v,+    Grad v ~ dv,+    Tang v ~ v,+    Tang dv ~ dv,+    Grad (Scalar dv) ~ Scalar dv+  ) =>+  HilbertSpace (BVar r v) (BVar r dv)+  where+  riesz (BVar v dv) = BVar (riesz v) (lift1_dense riesz dv)+  coriesz (BVar v dv) = BVar (coriesz v) (lift1_dense coriesz dv)++instance   ( VectorSpace v,     HasGrad v,-    Grad v ~ v,     Tang v ~ v,+    HilbertSpace (Tang v) (Grad v),     BasicVector (MScalar v),     Grad (MScalar v) ~ MScalar v,     InnerSpace v,@@ -136,9 +188,9 @@   BVar u du <.> BVar v dv = BVar (u <.> v) (lift2_dense bpU bpV du dv)     where       bpU :: MScalar v -> Grad v-      bpU dz = dz *^ v+      bpU dz = dz *^ riesz v       bpV :: MScalar v -> Grad v-      bpV dz = dz *^ u+      bpV dz = dz *^ riesz u  -- | A variable with derivative of zero. constant :: forall r a. (BasicVector (Grad a), AdditiveGroup (Grad a)) => a -> BVar r a@@ -148,27 +200,30 @@ var :: a -> BVar (Grad a) a var x = BVar x (realNode ExprVar) ---backprop :: forall a p. (HasGrad p, BasicVector a) => BVar a p -> GradBuilder p -> a---backprop (BVar _y0 x) = BP.backprop x- -- | Reverse mode differentiation.------  backprop :: forall r a. (HasGrad a, BasicVector r) => BVar r a -> Grad a -> r backprop (BVar _y0 x) = BP.backprop x - splitPair :: (BasicVector (Grad a), BasicVector (Grad b)) => BVar r (a, b) -> (BVar r a, BVar r b) splitPair (BVar (a, b) (Linear.T2 da db)) = (BVar a da, BVar b db)  pattern T2 :: forall r a b. (BasicVector (Grad a), BasicVector (Grad b)) => BVar r a -> BVar r b -> BVar r (a, b)-pattern T2 a b <- (splitPair -> (a, b))-  where T2 (BVar a da) (BVar b db) = BVar (a, b) (Linear.T2 da db)+pattern T2 a b <-+  (splitPair -> (a, b))+  where+    T2 (BVar a da) (BVar b db) = BVar (a, b) (Linear.T2 da db)  splitTriple :: (BasicVector (Grad a), BasicVector (Grad b), BasicVector (Grad c)) => BVar r (a, b, c) -> (BVar r a, BVar r b, BVar r c) splitTriple (BVar (a, b, c) (Linear.T3 da db dc)) = (BVar a da, BVar b db, BVar c dc) -pattern T3 :: forall r a b c. (BasicVector (Grad a), BasicVector (Grad b), BasicVector (Grad c))- => BVar r a -> BVar r b -> BVar r c -> BVar r (a, b, c)-pattern T3 a b c <- (splitTriple -> (a, b, c))-  where T3 (BVar a da) (BVar b db) (BVar c dc) = BVar (a, b, c) (Linear.T3 da db dc)+pattern T3 ::+  forall r a b c.+  (BasicVector (Grad a), BasicVector (Grad b), BasicVector (Grad c)) =>+  BVar r a ->+  BVar r b ->+  BVar r c ->+  BVar r (a, b, c)+pattern T3 a b c <-+  (splitTriple -> (a, b, c))+  where+    T3 (BVar a da) (BVar b db) (BVar c dc) = BVar (a, b, c) (Linear.T3 da db dc)
src/Downhill/BVar/Num.hs view
@@ -34,7 +34,7 @@ import qualified Downhill.BVar as BVar import Downhill.Grad   ( Dual (evalGrad),-    HasGrad (Grad, Tang)+    Manifold (Grad, Tang)   ) import Downhill.Linear.Expr (BasicVector (..)) import Downhill.Metric (MetricTensor (evalMetric))@@ -49,7 +49,7 @@ instance Num a => Dual (AsNum a) (AsNum a) where   evalGrad = (*) -instance Num a => HasGrad (AsNum a) where+instance Num a => Manifold (AsNum a) where   type Grad (AsNum a) = AsNum a   type Tang (AsNum a) = AsNum a 
src/Downhill/BVar/Traversable.hs view
@@ -63,7 +63,7 @@ import Downhill.BVar (BVar (BVar, bvarGrad, bvarValue), backprop, var) import Downhill.Grad   ( Dual (evalGrad),-    HasGrad (Grad, Tang)+    Manifold (Grad, Tang), HasGrad   ) import Downhill.Linear.BackGrad (BackGrad (BackGrad), castBackGrad, realNode) import Downhill.Linear.Expr@@ -92,13 +92,17 @@   evalMetric (TraversableMetric m) (IntmapVector da) =     IntmapVector (IntMap.map (evalMetric @p @g m) da) -instance HasGrad a => HasGrad (TraversableVar f a) where+instance Manifold a => Manifold (TraversableVar f a) where   type Tang (TraversableVar f a) = IntmapVector f (Tang a)   type Grad (TraversableVar f a) = IntmapVector f (Grad a)  -- | @IntmapVector@ serves as a gradient of 'TraversableVar'. newtype IntmapVector (f :: Type -> Type) v = IntmapVector {unIntmapVector :: IntMap v}   deriving (Show)++instance Manifold v => Manifold (IntmapVector f v) where+  type Tang (IntmapVector f v) = IntmapVector f (Tang v)+  type Grad (IntmapVector f v) = IntmapVector f (Grad v)  instance AdditiveGroup a => AdditiveGroup (IntmapVector f a) where   zeroV = IntmapVector IntMap.empty
src/Downhill/Grad.hs view
@@ -13,8 +13,8 @@ {-# LANGUAGE UndecidableInstances #-}  module Downhill.Grad-  ( Dual (..),-    HasGrad (..), MScalar,+  ( Dual (..), HilbertSpace(..),+    Manifold(..), HasGrad, MScalar,     GradBuilder,     HasGradAffine,   )@@ -41,16 +41,20 @@   default evalGrad :: (GDual (Scalar v) (Rep v) (Rep dv), Generic dv, Generic v) => dv -> v -> Scalar v   evalGrad dv v = gevalGrad (from dv) (from v) +-- | u <.> v = evalDual (riesz u) v+-- | du <.> dv = evalDual du (coriesz dv)+class Dual v dv => HilbertSpace v dv where+  riesz :: v -> dv+  coriesz :: dv -> v++ type MScalar p = Scalar (Tang p) --- | Differentiable functions don't need to be constrained to vector spaces, they--- can be defined on other smooth manifolds, too. class   ( Dual (Tang p) (Grad p),-    BasicVector (Grad p),     Scalar (Tang p) ~ Scalar (Grad p)   ) =>-  HasGrad p+  Manifold p   where   -- | Tangent space.   type Tang p :: Type@@ -58,6 +62,10 @@   -- | Cotangent space.   type Grad p :: Type +-- | Differentiable functions don't need to be constrained to vector spaces, they+-- can be defined on other smooth manifolds, too.+type HasGrad p = (Manifold p, BasicVector (Grad p))+ type GradBuilder v = VecBuilder (Grad v)  type HasGradAffine p =@@ -72,7 +80,7 @@ instance Dual Integer Integer where   evalGrad = (*) -instance HasGrad Integer where+instance Manifold Integer where   type Tang Integer = Integer   type Grad Integer = Integer @@ -87,7 +95,7 @@     HasGrad b,     MScalar b ~ MScalar a   ) =>-  HasGrad (a, b)+  Manifold (a, b)   where   type Grad (a, b) = (Grad a, Grad b)   type Tang (a, b) = (Tang a, Tang b)@@ -99,7 +107,7 @@     MScalar b ~ MScalar a,     MScalar c ~ MScalar a   ) =>-  HasGrad (a, b, c)+  Manifold (a, b, c)   where   type Grad (a, b, c) = (Grad a, Grad b, Grad c)   type Tang (a, b, c) = (Tang a, Tang b, Tang c)@@ -107,14 +115,14 @@ instance Dual Float Float where   evalGrad = (*) -instance HasGrad Float where+instance Manifold Float where   type Grad Float = Float   type Tang Float = Float  instance Dual Double Double where   evalGrad = (*) -instance HasGrad Double where+instance Manifold Double where   type Grad Double = Double   type Tang Double = Double 
src/Downhill/Metric.hs view
@@ -14,7 +14,7 @@ where  import Data.VectorSpace ((^+^))-import Downhill.Grad (Dual (evalGrad), HasGrad (Grad, Tang), MScalar)+import Downhill.Grad (Dual (evalGrad), Manifold(..), MScalar)  -- | @MetricTensor@ converts gradients to vectors. --
test/DownhillTest/Bilinear.hs view
@@ -1,40 +1,73 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE RankNTypes #-}-{-# LANGUAGE TypeApplications #-}-{-# LANGUAGE DerivingVia #-} {-# LANGUAGE DeriveGeneric #-}-{-# LANGUAGE UndecidableInstances #-}-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE DerivingVia #-}+{-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}  module DownhillTest.Bilinear where  import Data.AffineSpace ((.+^))-import Data.VectorSpace (AdditiveGroup, VectorSpace ((*^), Scalar), (^+^))+import Data.VectorSpace (AdditiveGroup, VectorSpace (Scalar, (*^)), (^+^)) import Downhill.BVar (BVar (bvarValue)) import qualified Downhill.BVar as BVar-import Downhill.Grad (Dual (evalGrad), HasGrad (Grad), MScalar)+import Downhill.Grad (Dual (evalGrad), HasGrad, MScalar, Manifold (Grad))+import Downhill.Linear.Expr (BasicVector, DenseVector (DenseVector))+import GHC.Base (VecElem (DoubleElemRep))+import GHC.Generics (Generic) import Hedgehog   ( Gen,     Property,+    PropertyT,     forAll,     property,     (===),   )-import Test.Tasty (TestTree, testGroup)-import Test.Tasty.Hedgehog (testProperty, testPropertyNamed)-import GHC.Base (VecElem(DoubleElemRep))-import Hedgehog.Internal.Show (Value(Integer))-import qualified Hedgehog.Internal.Show as Gen import qualified Hedgehog.Gen as Gen+import Hedgehog.Internal.Show (Value (Integer))+import qualified Hedgehog.Internal.Show as Gen import qualified Hedgehog.Range as Range-import GHC.Generics (Generic)-import Downhill.Linear.Expr (BasicVector, DenseVector (DenseVector))+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.Hedgehog (testProperty, testPropertyNamed) +testLinear ::+  forall m r u z.+  ( Show u,+    HasGrad u,+    Show (Grad z),+    HasGrad z,+    Eq z,+    AdditiveGroup u,+    Show z,+    AdditiveGroup z,+    Dual (Grad u) u,+    Eq (Scalar u),+    Show (Scalar u),+    Scalar u ~ Scalar z,+    Dual (Grad z) z,+    Show (MScalar z),+    Monad m+  ) =>+  (u -> z) ->+  (forall r. BVar r u -> BVar r z) ->+  Gen u ->+  Gen (Grad z) ->+  PropertyT m ()+testLinear f bf genU genDZ = do+  u <- forAll genU+  dz <- forAll genDZ+  let z = f u+      bu = BVar.var u+      bz = bf bu+      du = BVar.backprop bz dz+  bvarValue bz === z -- check that `f` and `bf` is the same function+  evalGrad u du === evalGrad z dz+ testBilinear ::   ( Show u,     Show v,@@ -51,7 +84,10 @@     Show (Scalar u),     Scalar u ~ Scalar z,     Scalar v ~ Scalar z,-    Dual (Grad z) z, Show (MScalar z), Dual (Grad v) v) =>+    Dual (Grad z) z,+    Show (MScalar z),+    Dual (Grad v) v+  ) =>   (u -> v -> z) ->   (forall r. BVar r u -> BVar r v -> BVar r z) ->   Gen u ->@@ -70,10 +106,52 @@   evalGrad u du === evalGrad z dz   evalGrad v dv === evalGrad z dz +testBilinear' ::+  ( Show u,+    Show v,+    HasGrad u,+    HasGrad v,+    Show (Grad z),+    HasGrad z,+    Eq z,+    AdditiveGroup u,+    Show z,+    AdditiveGroup z,+    Dual (Grad u) u,+    Eq (Scalar u),+    Show (Scalar u),+    Scalar u ~ Scalar z,+    Scalar v ~ Scalar z,+    Dual (Grad z) z,+    Show (MScalar z),+    Dual (Grad v) v+  ) =>+  (u -> v -> z) ->+  (forall r. BVar r u -> BVar r v -> BVar r z) ->+  Gen u ->+  Gen v ->+  Gen (Grad z) ->+  Property+testBilinear' f bf genU genV genDZ = property $ do+  u <- forAll genU+  v <- forAll genV+  dz <- forAll genDZ+  let z = f u v+      BVar.T2 bu bv = BVar.var (u, v)+      bz = bf bu bv+      (du, dv) = BVar.backprop bz dz+  bvarValue bz === z -- check that `f` and `bf` is the same function+  evalGrad u du === evalGrad z dz+  evalGrad v dv === evalGrad z dz++  testLinear (\x -> f x v) (\bx -> bf bx (BVar.constant v)) genU genDZ+  testLinear (\x -> f u x) (\bx -> bf (BVar.constant u) bx) genV genDZ+ data Vector = Vector Integer Integer-  deriving Generic+  deriving (Generic)  instance AdditiveGroup Vector+ instance VectorSpace Vector  bilinearIntMulProperty :: Property@@ -84,10 +162,10 @@     genInt :: Gen Integer     genInt = Gen.integral (Range.linear (-100) 100) - bilinearTests :: TestTree bilinearTests =-   testGroup "Bilinear operations"-     [ testPropertyNamed "Scalar multiplication" "bilinearIntMulProperty" bilinearIntMulProperty-       -- TODO: scalar-vector product, inner product-     ]+  testGroup+    "Bilinear operations"+    [ testPropertyNamed "Scalar multiplication" "bilinearIntMulProperty" bilinearIntMulProperty+    -- TODO: scalar-vector product, inner product+    ]
test/DownhillTest/Traversable.hs view
@@ -8,7 +8,7 @@  import Downhill.BVar.Traversable (TraversableVar (TraversableVar), backpropTraversable, splitTraversable) import Downhill.BVar (BVar (BVar), backprop, var)-import Downhill.Grad (HasGrad (Grad))+import Downhill.Grad (Manifold (Grad), HasGrad) import Test.Tasty (TestTree) import Test.Tasty.HUnit (testCase, (@?=)) @@ -18,7 +18,7 @@   }   deriving (Eq, Functor, Foldable, Traversable, Show) -deriving via (TraversableVar MyRecord a) instance HasGrad a => HasGrad (MyRecord a)+deriving via (TraversableVar MyRecord a) instance Manifold a => Manifold (MyRecord a)  test_r :: MyRecord Integer test_r = MyRecord (10, 11) [12, 13, 14]