-
Notifications
You must be signed in to change notification settings - Fork 0
Experiment with differentiation via typeclasses #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| -- | | ||
| -- Module : MLambda.Differentiable | ||
| -- Description : Implements differentiation machinery. | ||
| -- Copyright : (c) neclitoris, 2026 | ||
| -- License : BSD-3-Clause | ||
| -- Maintainer : nas140301@gmail.com | ||
| -- Stability : experimental | ||
| -- Portability : portable | ||
| -- | ||
| -- This module contains definition of `Differentiable` type class. | ||
| {-# LANGUAGE AllowAmbiguousTypes #-} | ||
| {-# LANGUAGE PatternSynonyms #-} | ||
| module MLambda.Differentiable | ||
| ( Functional(..) | ||
| , Differentiable(..) | ||
| , Matmul(..) | ||
| ) where | ||
|
|
||
| import MLambda.Index | ||
| import MLambda.Matrix | ||
| import MLambda.NDArr | ||
| import MLambda.TypeLits | ||
|
|
||
| import Data.Kind | ||
| import Data.List.Singletons | ||
| import Data.Vinyl | ||
| import Numeric.Netlib.Class | ||
|
|
||
| import Prelude hiding (Floating) | ||
|
|
||
|
|
||
| type family ArgsL (i :: [[Natural]]) e :: [Type] where | ||
| ArgsL '[] e = '[] | ||
| ArgsL (x ': xs) e = NDArr x e : ArgsL xs e | ||
|
|
||
| type family Args (i :: [[Natural]]) e :: Type where | ||
| Args i e = Rec At (Fins @(ArgsL i e) (ArgsL i e)) | ||
|
|
||
| type family Fun (i :: [[Natural]]) (o :: [Natural]) e :: Type where | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. можно просто |
||
| Fun i o e = Args i e -> NDArr o e | ||
|
|
||
| class Functional f i o e where | ||
| ($$) :: f -> Fun i o e | ||
|
|
||
| class Functional f i o e => Differentiable f i o e where | ||
| d :: f -> Args i e -> Index o -> Args i e | ||
|
TurtlePU marked this conversation as resolved.
|
||
|
|
||
| data Matmul = Matmul | ||
|
|
||
| instance (KnownNat m, KnownNat n, KnownNat k, Floating e) => Functional Matmul '[[m,n], [n,k]] '[m,k] e where | ||
| _ $$ (At a :& At b :& RNil) = a `cross` b | ||
|
|
||
| instance (1 <= m, 1 <= n, 1 <= k, KnownNat m, KnownNat n, KnownNat k, Floating e) => Differentiable Matmul '[[m,n], [n,k]] '[m,k] e where | ||
| d _ (At a :& At b :& RNil) (i :. j) = At a' :& At b' :& RNil | ||
| where | ||
| a' = fromIndex \(k :. l) -> if k == i then b `at` (l :. j) else 0 | ||
| b' = fromIndex \(k :. l) -> if l == j then a `at` (i :. k) else 0 | ||
|
|
||
| data (:.:) f1 f2 = f1 :.: f2 | ||
|
|
||
| instance (Functional f1 i1 o1 e, Functional f2 (o1 : i2) o2 e, i ~ i1 ++ i2) => Functional (f1 :.: f2) i o2 e where | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Почему не просто (Functional f i j e, Functional g j k e) => Functional (f :.: g) i k e
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. В текущей постановке тебе нужно как-то прокинуть в этот инстанс свидетель разделения
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Потому что кайнды не сходятся. В конце концов, хочется иметь отображение из многих тензоров в один (таковым является, например, матмул), а тут
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Тогда, видимо, в качестве первого шага в композиции нужно класть список "функций", а не одну функцию. Либо сорить вспомогательной штукой которая переставляет входные аргументы
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Либо делать так, чтобы "функция" могла возвращать много тензоров, а не один, но это без гетерогенных индексов не выражается |
||
| (f1 :.: f2) $$ r = undefined | ||
|
Check warning on line 62 in src/MLambda/Differentiable.hs
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| {-# LANGUAGE RequiredTypeArguments #-} | ||
| {-# LANGUAGE StandaloneKindSignatures #-} | ||
|
|
||
| -- | | ||
| -- Module : MLambda.TypeLits | ||
|
|
@@ -22,11 +23,16 @@ module MLambda.TypeLits | |
| , Peano | ||
| , RNat (..) | ||
| , RPNat (..) | ||
| , Fin (..) | ||
| , Fins | ||
| , At(..) | ||
| , type (!) | ||
| , ReifiedNat | ||
| , rnat | ||
| , rpnat | ||
| ) where | ||
|
|
||
| import Data.Kind | ||
| import Data.Proxy (Proxy (Proxy)) | ||
| import GHC.TypeError (ErrorMessage (..), TypeError) | ||
| import GHC.TypeNats hiding (natVal) | ||
|
|
@@ -67,6 +73,32 @@ data RPNat n where | |
| RPZ :: RPNat PZ | ||
| RPS :: RPNat n -> RPNat (PS n) | ||
|
|
||
| -- | Finite list index. | ||
| type Fin :: [k] -> Type | ||
| data Fin (l :: [k :: Type]) where | ||
| FZ :: Fin (x : xs) | ||
| FS :: Fin xs -> Fin (x : xs) | ||
|
|
||
| type (!) :: forall l -> Fin l -> Type | ||
| type family (!) (l :: [k :: Type]) (i :: Fin l) where | ||
| (x ': _) ! FZ = x | ||
| (_ ': xs) ! (FS i) = xs ! i | ||
|
|
||
| type At :: forall {k} {l :: [k]} . Fin l -> Type | ||
| data At (i :: Fin l) where | ||
| At :: l ! i -> At i | ||
|
|
||
| type Map :: forall k l . (k -> l) -> [k] -> [l] | ||
| type family Map f l where | ||
| Map _ '[] = '[] | ||
| Map f (x ': xs) = f x ': Map f xs | ||
|
|
||
| -- | Creates a list of indices into a type-level list. | ||
| type Fins :: forall {k} (l :: [k]) . [k] -> [Fin l] | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Кажется, тут лучше type Fins :: forall {k}. forall (l :: [k]) -> [Fin l]если такое компилируется
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Или просто |
||
| type family Fins (l :: [k :: Type]) where | ||
| Fins '[] = '[] | ||
| Fins (x ': xs) = FZ ': Map FS (Fins xs) | ||
|
|
||
| -- | A stronger variant of 'KnownNat' which enables induction on type-level naturals. | ||
| class ReifiedNat n where | ||
| rnat0 :: RNat n | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут бтв тоже просто
typeвместоtype familyможно