-
Notifications
You must be signed in to change notification settings - Fork 13
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
Automatically divide by gcd when needed #35
Comments
We'd have to check the performance implications pretty carefully, but that's something we could consider. One thing to know: the reason for the existence of this package is Interpolations.jl, and I won't make changes that cause it significant harm. However, as with the discussion of FixedPointNumbers, perhaps one could add another type parameter and make the arithmetic configurable. |
In between: Always divide by greatest common power of two.
This should cost <10 simple instructions. No branching at all. |
Right, but interpolation is If we find that there's a conflict in goals, keep in mind that the whole reason I called this |
For instruction read RISC-like machine instruction. All operations will get a small but constant extra cost. As an advantage, we should safe conditional evaluation (which can take longer than a few instructions on most modern machines). Some weeks ago I tried profile my approach against the current version implemented here. Than I tried to compare the errors with each implementation against exact |
So what I ended up doing in DynamicQuantities.jl was just having a fixed denominator rational number (@oscardssmith suggestion). (Kind of like FixedPointNumbers but a different emphasis) The default type used to represent the exponent of a physical dimension is It's fast at the things that are important for physical quantities, like equality checks (=> check equality of numerators = fast), and addition/subtraction (=> add the numerators = fast). But it's slower at multiplication and division because it has to divide by the denominator, but those are less common here because it's only used in power laws. It also avoids having to compute the gcd frequently which is good. It's a bit different in terms of what numbers it can represent. e.g., 1/11 is not possible to represent exactly with the above defaults (a tradeoff in what numbers are representable with a fixed number of bits). However, it's fine for unit calculations. I'd be happy to move it somewhere else like Ratios.jl if @timholy is interested and thinks it would be of general interest. Having it in a specific package for rational numbers seems like a more maintainable strategy than having an internal type I have to verify and test. |
Seems reasonable. My only concern is whether someone might create an unlimited number of denominators? In your application, are there only a few relevant denominators or is it "anything goes"? (Type explosions are a bit concerning...) |
For representing the exponent of units I think people will create essentially 1 denominator (the default one). It's very rare to need meters^129/127ths for example. |
I think we could add that to this package if you'd like. We could include a warning in the docs about the potential for abuse and encourage people to limit the number of different denominators. |
I should mention that there are no methods available for FixedRationals that have different denominators, so to run into type explosions you would have to do so explicitly. (The design assumption is that someone would pick a single denominator and use it throughout their code.) |
I am wondering whether Ratios.jl might be able to automatically divide by the gcd whenever an overflow would otherwise occur. Perhaps this could be done through an extension to SafeIntegers.jl?
With @oscardssmith we've been looking at using
SimpleRatio{Int8}
for storing dimensions in DynamicQuantities.jl: SymbolicML/DynamicQuantities.jl#4. In other words, the power of each physical dimension would be a SimpleRatio, like(length)^(::SimpleRatio{Int8})
.However, this can easily hit overflows, especially if a user is performing many calculations on a single quantity. So I am wondering if there is a way we automatically divide by the gcd, but only when needed. (Rather than every calculation, with Rational, or never, with the normal SimpleRatio).
The text was updated successfully, but these errors were encountered: