novacrazy / dual_num

Dual Number library for Rust
https://docs.rs/dual_num/
17 stars 4 forks source link

Add benruijl's hyperdual math #17

Closed ChristopherRabotin closed 5 years ago

ChristopherRabotin commented 5 years ago

This is a merge (and some minor changes) from benruijl's implementation.

I have bumped the version to 0.3.0 as well.

Note that I have renamed DualN to Hyperdual. As per the paper Forward Mode Differentiation in Julia by by Revel et al.:

Algebraically, the above example is equivalent to the use of hyper-dual numbers described by Fike and Alonso [7]. In fact, a Dual instance with d levels of nesting implements a dth-order hyper-dual number, with the added advantage of scaling to arbitrary dimensions.

It is only in this paper that I have found any reference to "multi-dual" numbers. Also note that Fike was my main reference when working with these numbers a few months back, so I'm slightly biased here. To help in maintaining code, I've created an alias for DualN to Hyperdual.

novacrazy commented 5 years ago

Awesome, I'll take a closer look at this in the morning.

novacrazy commented 5 years ago

Finally had a chance to look through this in detail, and it looks quite good. The overall API is more or less identical.

However, dual_ref and dual_mut appear to have been removed. They should be added back onto the Dual<T> type alias at the end.

One thing I am curious about is when there is a "wasted" operation when mapping the underlying vector, where the first element, the real part, is then overwritten immediately after. I'm curious is Rust/LLVM can see that it's effectively dead code and eliminate that first single operation. I may do some testing of that later. Ideally, it would recognize that for N <= 3, but for N >= 4 it may do it anyway with an SIMD operation.

ChristopherRabotin commented 5 years ago

Good call! I've re-added those just now.

novacrazy commented 5 years ago

Something else to consider is whether we should rename the crate. I’d be cool with creating a hyperdual crate and then re-exporting Dual<T> from it for dual_num, just to maintain backwards compatibility.

What do you think of that? You can be the primary owner of that crate, and I’ll just rename/restructure this repository for that. Frankly I’m amazed you didn’t do that already, with how distant I’ve been here lately.

ChristopherRabotin commented 5 years ago

I think you're more knowledgeable in Rust than I am, and like having your review of code changes, so I actually prefer keeping everything in a single crate. But if you think that having two separate crates would allow the compiler to do better optimizations, then I'm okay with the fork.

AFAIK, there should still be backward compatibility using the Dual<T> type.

novacrazy commented 5 years ago

Well, I'll open an issue soon to discuss that before publishing this new version. For now, this PR looks perfectly fine to me, so I'm going to go ahead and merge it.