Keno / SIUnits.jl

Efficient unit-checked computation
Other
70 stars 26 forks source link

support fractional powers? #32

Open stevengj opened 10 years ago

stevengj commented 10 years ago

I wonder whether it is worthwhile to support fractional unit powers, which would require that SIQuantity be parameterized by a numerator/denominator pair for each unit.

e.g. the lack of fractional powers makes Cholesky factorizations of dimensionful matrices problematic (JuliaLang/julia#7623).

F# decided not to support fractional powers of units, apparently mainly on philosophical grounds, but I'm not sure I can agree with their reasoning. Fractional powers of units are indubitably used in real problems and have a well-defined meaning; metaphysical discussions about whether they are "real" seem to me to be a medieval waste of time (akin to the centuries of pointless wrangling over whether negative numbers are "real").

Haskell's dimensional package also limits itself "to integer powers of Dimensionals as fractional powers make little physical sense," again a philosophical rather than practical argument.

I'm not certain whether Fortress supported fractional powers of units, but I get the impression that it did not (the Fortress manual says that dimensionful quantitites can be "compared, added, subtracted, multiplied and divided" but says nothing about exponentiation).

To me, the main question here is practical: is there a substantial performance penalty to supporting rational powers of units?

cc: @jiahao

timholy commented 10 years ago

I think this should just be supported in base. Since this issue got closed, I forgot about it (and then started working on different projects in my own research). I won't have time to get back to it in the near future, but if you want to do it, go for it.

stevengj commented 10 years ago

See also #22.

timholy commented 10 years ago

Should also have said: loved the medieval analogy in your analysis of other languages' decisions on this topic. "Per root-Hz" is so common in power-spectrum-aware conversations that I keep wondering when someone will come up with an abbreviation for it.

StefanKarpinski commented 10 years ago

cc: @JeffBezanson, re performance implications. I suspect this is ok from a performance perspective but does potentially cause an even greater explosion of types and specializations thereupon.

jiahao commented 10 years ago

I want this so bad.

ivarne commented 10 years ago

To me the choice of datatype for the exponents seems rather arbitrary. The more complicated you make the system, the more flexible (and slow) it becomes. The rabbit hole is deep.

Most usages will do fine with only small integers. Others need square roots (or other fractions of exponents of 2), and will do fine with a floating point exponent. Fewer people will find it convenient with arbitrary fractions (eg. cube roots). Crazy people (eg. my previous advisor), want the system to be fully flexible, and want irrational exponents so that logarithms can be handled directly without creating unitless groups.

stevengj commented 10 years ago

I think it's reasonable to draw the line at rational exponents with Int64 numerators and denominators. Wider integers would be too slow to be practical and are too rarely useful. Using floating point is not practical because you really want things like 1/3 to be represented exactly, and checking exponents for exact equality is really important with units.

jiahao commented 10 years ago

I think it's reasonable to draw the line at rational exponents with Int64 numerators and denominators.

+1

StefanKarpinski commented 10 years ago

If we support arbitrary immutable values as type parameters (or arbitrary values with === comparison), then you could just use rational powers and I suspect much of the existing SIUnits code would just work. This has the advantage of not complicating the integer-power use case at all.

ivarne commented 10 years ago

Arbitrary exponent types seems like a good idea. Then you could put in any exponent type you want, and they will just propagate using normal promotion rules. If you need sqareroots, you can use Float64, cube roots could be supported by a rational implementation and if we have a symbolic datatype for irrational numbers, you could use that for logarithms.

stevengj commented 10 years ago

See also JuliaLang/julia#6081

stevengj commented 10 years ago

Now that this has been implemented in Julia, we can use rational (and floating-point) exponents.

SIUnits just needs to implement this in sqrt, ^, etcetera.