Mikolaj / horde-ad

Higher Order Reverse Derivatives Efficiently - Automatic Differentiation library based on the paper "Provably correct, asymptotically efficient, higher-order reverse-mode automatic differentiation"
BSD 3-Clause "New" or "Revised" License
34 stars 6 forks source link

implement equality testing with explicit error margin #67

Closed sfindeisen closed 2 years ago

sfindeisen commented 2 years ago

Implements fp-equality testing with the error margin explicitly passed as a parameter from the caller. For example:

testFoo :: Assertion
testFoo =
  assertEqualUpToEpsilon (1e-10 :: Double)
    (rev foo (1.1, 2.2, 3.3) :: (Double,Double,Double))
    (2.4396285219055063, -1.953374825727421, 0.9654825811012627)

This enables us to specify different error margins for different comparisons. If you want to keep it simple, you can still rely on the default error margin specified on the command line using --eq-epsilon. In that case, you can use the binary @?~ operator:

res @?~ ([3.5e-44,3.5e-44],5.0 :: Float)

This also improves error messages in accordance with #70 .

Fixes #65 #70

Mikolaj commented 2 years ago

When you reach the point of writing AssertClose instances, to be used in assertEqualUpToEps, for Vector or MonoTraversable (it's the same thing), let me know, I'd share what I know.

sfindeisen commented 2 years ago

When you reach the point of writing AssertClose instances, to be used in assertEqualUpToEps, for Vector or MonoTraversable (it's the same thing), let me know, I'd share what I know.

Yes please. I was looking into that, and it looks we cannot simply use Traversable because it doesn't work with pairs (they way we do):

ghci> import Data.Foldable 
ghci> traverse_ (\x -> print x) ("abc", "def")
"def"

This is fine:

ghci> traverse_ (\x -> print x) ["abc", "def"]
"abc"
"def"

and could be used.

EDIT: BTW I was not goint to modify AssertClose. That class is there for the (binary) (@?~) operator.

Mikolaj commented 2 years ago

Yes, unfortunately, we probably can't do better than have 10 instances of the type class for tuples up to 10. A pity. We should have something like Traversable for tuples, but it may be too hard to type, because it's not tuples of the same type. But even something using Dynamic would help.

sfindeisen commented 2 years ago

Yes, unfortunately, we probably can't do better than have 10 instances of the type class for tuples up to 10. A pity. We should have something like Traversable for tuples, but it may be too hard to type, because it's not tuples of the same type. But even something using Dynamic would help.

One could perhaps squeeze those tuples into HasShape and Linearizable, if that makes sense...

Mikolaj commented 2 years ago

One could perhaps squeeze those tuples into HasShape and Linearizable, if that makes sense...

Linearizable indeed should be more succinct than AssertEqualUpToEpsilon.

sfindeisen commented 2 years ago

Linearizable indeed should be more succinct than AssertEqualUpToEpsilon.

... well but this will not work of course, because tuples can be heterogenous whereas Linearizable gives [a]. Sorry for the wrong suggestion.

sfindeisen commented 2 years ago

I only implemented the tuples up to 4. More boilerplate, anyone? Up to 10? 12?

sfindeisen commented 2 years ago

Speaking of those tuples.... perhaps we could implement Linearizable and HasShape instances for homogenous tuples (i.e. (a,a,a,a) etc.) which would be quite compact, and then not worry about heterogenous tuples longer than 4 until they're needed in practice?

Mikolaj commented 2 years ago

Speaking of those tuples.... perhaps we could implement Linearizable and HasShape instances for homogenous tuples (i.e. (a,a,a,a) etc.) which would be quite compact, and then not worry about heterogenous tuples longer than 4 until they're needed in practice?

The current examples, which I'd like to rewrite in the new style, have 7-tuples or more, IIRC. Not homogeneous. We may want to nest them somehow, but a 5-tuple sounds likely, anyway. I think up to 10, inclusive, would be good to have, just so that users feel provided for.