JuliaDiff / ChainRules.jl

forward and reverse mode automatic differentiation primitives for Julia Base + StdLibs
Other
435 stars 89 forks source link

Non-associative number types #594

Open sethaxen opened 2 years ago

sethaxen commented 2 years ago

I was recently reminded that some number types are not even associative under multiplication, e.g. Quaternions.Octonion. So fixes like #504, #540, which would support numbers that don't commute under multiplication, like quaternions, would still do the wrong thing for octonions. On the other hand, there are number types like Unitful.Quantity, which are Numbers, for which we want our rules to work.

So I see 2 ways forward:

  1. Implement only rules that make no additional assumptions about the properties of the numbers beyond the primal, and only in cases where the primal is define in base.
  2. Try to implement rules generically, but assume that numbers that violate basic properties like associativity are rare and require (and document) that devs of packages with such numbers need to opt out of these rules for compatibility with ChainRules-compatible ADs.
SBuercklin commented 2 years ago

Would a trait system identifying numerical types as being commutative/associative/etc. be tractable to solve this?

SBuercklin commented 2 years ago

To elaborate: I'm not familiar with just how many rules require commutativity/associativity, but the properties are inferrable at the type level. Checks like iscommutative and isassociative should essentially compile away, and asserting the presence of these properties should also compile away, if I understand correctly.

Depending on how many rules require these properties, it might start to built up a large amount of boilerplate. Is there a technical reason to avoid asserting the presence of properties?

oxinabox commented 2 years ago

Asserting the behavour is less useful than dispatching on the behavour. Dispatching on the behavour is an unreasonable amount of boiler plate. But yes were such properties implemented i would be down with adding some @asserts on them for defensive programming purposes.

sethaxen commented 2 years ago

And asserting the properties is better than just assuming everything is commutative, because at least an error is thrown instead of derivatives being silently wrong.

To elaborate: I'm not familiar with just how many rules require commutativity/associativity,

540 should give a sense for how many rules assume commutativity. And most rules with a product assume associativity, so such an assertion would basically ensure that no ChainRules-compatible AD can handle such number types, even as a collection of real numbers, without the package reimplementing a lot of our rules. Which would be unfortunate.