ad
ad copied to clipboard
nesting: diff (\x -> diff (*x) 1) 1
Was showing off nesting, simplest example I could think of, oops.
tldr: ad
4.3.2.1, ghc
8.0.1, diff (\x -> diff (*x) 1) 1
gets a type error.
$ cabal update
Downloading the latest package list from hackage.haskell.org
$ cabal install --user ad
Resolving dependencies...
Downloading base-orphans-0.5.4...
...
Installed free-4.12.4
Downloading ad-4.3.2.1...
Configuring ad-4.3.2.1...
Building ad-4.3.2.1...
Installed ad-4.3.2.1
$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> :m + Numeric.AD
Prelude Numeric.AD> diff (*2) 1
2
Prelude Numeric.AD> diff sin 0
1.0
Prelude Numeric.AD> diff (\x -> diff (*x) 1) 1
<interactive>:6:20: error:
• Occurs check: cannot construct the infinite type:
a ~ AD s (Numeric.AD.Internal.Forward.Forward a)
Expected type: AD
s1
(Numeric.AD.Internal.Forward.Forward
(AD s (Numeric.AD.Internal.Forward.Forward a)))
Actual type: AD s (Numeric.AD.Internal.Forward.Forward a)
• In the second argument of ‘(*)’, namely ‘x’
In the first argument of ‘diff’, namely ‘(* x)’
In the expression: diff (* x) 1
• Relevant bindings include
x :: AD s (Numeric.AD.Internal.Forward.Forward a)
(bound at <interactive>:6:8)
it :: a (bound at <interactive>:6:1)
This happens even without nesting.
> diff (pi*) 1
3.141592653589793
> (\x -> diff (x*) 1) pi
error: ...
> let x=pi in diff (x*) 1
3.141592653589793
and yes, I know auto
makes it okay
Prelude Numeric.AD> diff (\x -> diff (auto x*) 2) 3
1
Prelude Numeric.AD> (\x -> diff (auto x*) 2) 3
3
But it's still a pretty big wart on an otherwise lovely countenance.
I don't know if this is helpful, but this works fine if you use the diff
from Numeric.AD.Rank1.Forward
Not entirely.
Prelude Numeric.AD.Rank1.Forward> :t diff
diff :: Num a => (Forward a -> Forward a) -> a -> a
Prelude Numeric.AD.Rank1.Forward> diff (\x -> diff (x*) 2) 3
<interactive>:10:13: error:
• Occurs check: cannot construct the infinite type: a ~ Forward a
• In the expression: diff (x *) 2
In the first argument of ‘diff’, namely ‘(\ x -> diff (x *) 2)’
In the expression: diff (\ x -> diff (x *) 2) 3
• Relevant bindings include
x :: Forward a (bound at <interactive>:10:8)
it :: a (bound at <interactive>:10:1)
Prelude Numeric.AD.Rank1.Forward> diff (\x -> diff (auto x*) 2) 3
1
I don't see this issue ever going away with Haskell's notion of (*) :: Num a => a -> a -> a
requiring both sides to have the same type. We can work around it by offering folks auto
or (*^)
and (^*)
, but without a custom numeric prelude that blurs the lines between scalars and vectors and then only infers forward not backwards, and is literally incompatible with the desugaring applied to integers, and so is incompatible with literally all other haskell numerics this seems fundamentally unsolvable.
What would the types of the *^ be?
On Sun, Feb 14, 2021 at 11:47 PM Edward Kmett [email protected] wrote:
I don't see this issue ever going away with Haskell's notion of () :: Num a => a -> a -> a requiring both sides to have the same type. We can work around it by offering folks auto or (^) and (^*), but without a custom numeric prelude that blurs the lines between scalars and vectors and then only infers forward not backwards, and is literally incompatible with the desugaring applied to integers, and so is incompatible with literally all other haskell numerics this seems fundamentally unsolvable.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ekmett/ad/issues/60#issuecomment-778934674, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAABBQUZ33YVC775QMOIPIDS7CRORANCNFSM4CYOG26Q .
(*^)
multiplies whatever the 'scalar' type is for the mode, treating the ad type as an algebra over the basic scalar. It already exists inside Numeric.AD.Mode (or Jacobian). basically it is equivalent to x *^ y = auto x * y