-
Notifications
You must be signed in to change notification settings - Fork 112
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
Need better handling of temperatures #137
Comments
+1. I've been bitten by this a few times recently. But I also have a few awful empirical equations that actually need to multiply by degrees C, so the answer isn't totally clear cut. But I would lean to defaulting to Kelvins by default with a display in C. |
The basic problem is that whenever a unit has an offset (as for a Temperature), then it must be defined whether the variable is an absolute or a relative quantity and the unit conversion has to take this additional information into account. For example, assume that |
I agree with @MartinOtter: absolute and relative temperatures are fundamentally different things, and guessing which is which is very dangerous. |
Yep, this is analogous to the difference between vector spaces and affine spaces. I implemented something like this in my std.units draft for D some years ago (docs, source – this is ancient code, so not reflective of D's current capabilities). When working on this, I debated whether the added complexity of properly supporting such affine units was worth it for quite a while, but came to the conclusion that if units such as °C are to be supported at all, they should be represented properly. Otherwise, the unit system might actually end up increasing the likelihood of unit conversion mistakes, as it instills a false sense of security (immunity to mistakes) in users, while it doesn't help with what is otherwise a favourite source of unit conversion mistakes already. |
This is interesting because it could also solve a dangerous situation in Media descriptions: Quantities such as the specific enthalpy h (with unit
is fine, if both h2 and h1 are defined with respect to the same reference point. However, if they have different reference points, the result is wrong. Unfortunately, such a situation can occur because tables of specific enthalpies might be defined with respect to different reference points (e.g. reference point is 0K or 293.15K, and 1bar or 1atm). So, to summarize, it would be nice if "affine" units could be defined with respect to 1 or more reference points and addition/subtraction would be only allowed if the involved variables are defined with respect to the same reference points. |
Another example of problematic behavior: addition is non-associative. julia> u"1.3°C+1°C+1K"
276.45 K
julia> u"1.3°C+(1°C+1K)"
549.5999999999999 K |
Here's a puzzle if we have both absolute and relative temperature. The law of perfect gases states: PV = nRT # T in "absolute" Kelvin and thus PΔV = nRΔT # ΔT in "relative" Kelvin/Celsius Should R be expressed in per-absolute-temperature-unit, or in per-relative-temperature-unit? One solution is to use relative temperature, but that implies writing the first version of the law as PV = n*R*(T - 0absoluteK) It's nicely explicit, in a way, but it's not so aesthetically pleasing. |
Some substance initially at 10°C is heated up at a rate of 2°C/hour, for 60 minutes, then is heated up once more at a rate of 3°C/hour for one hour. What is its final temperature? julia> using Unitful: °C, hr, minute
julia> 10°C + 2.0°C/hr * 60minute + 3.0°C/hr * hr
565.8525 K
julia> 10°C + 2.0°C/hr * 60minute + 3.0°C/hr * 60minute
297.255 K Using |
That last example is truly frightening. |
Many of the issues brought up here are resolved in #177. I'm sure it is not perfect, but I welcome feedback. |
@cstjean: Regarding your ideal gas law example, the crucial point is to realise that "absolute" Kelvin and "relative" Kelvin are the same thing. Writing A small tangent: Incidentally, this nicely illustrates why many equations in the sciences are customarily written in differential form. For instance, one would have to pick an arbitrary point in time as reference in order to be able to write Newton's second law In a Julia version of the D library I mentioned above, your second example would read: julia> using Unitful: °C, K, hr, minute
julia> 10°C + 2.0K/hr * 60minute + 3.0K/hr * 60minute
15 °C |
@klickverbot Do you mean by
I like the idea that |
Yes, and #177 in it's current state indeed differs from what I'd propose.
There is only a single unit |
I like your proposal and have mostly implemented it already on my end, just editing the docs to reflect the changes. |
I like it too! Very neat. Some questions
|
You can unit convert between them. I don't think it is actually an issue since some operations on affine quantities are restricted. If you want to try it out, let me know if you have any problems.
That would be an error, yes. There's no constant |
For us a big part of the appeal of Unitful is to prevent stupid mistakes. Some users might think about "an increase of 10°C", and have it converted to "an increase of 283K". struct Explosion
temperature_increase::typeof(K)
end
ex = Explosion(10°C) Plus, |
I guess it is ultimately a question of which mistakes you think are most likely. If Thank you for taking the initiative with your PR, which was very helpful in getting things going. |
I wasn't clear enough. I was suggesting not having any const abs_zero = -273.15°C
10°C + 2K --> 12°C
10°C - 2°C --> 8K
10°C - abs_zero --> 283.15K # effectively this is how conversion is done
283.15K + abs_zero --> 10°C
uconvert(°C, 12K) --> DimensionError
uconvert(K, 12°C) --> DimensionError If there was an agreed upon symbol for absolute zero, it would be more satisfying, but unfortunately @klickverbot How did it work in the D library? |
@cstjean, some responses:
|
Alright, I've updated the PR, now the following is possible:
This allows users to decide if they'd prefer
|
Thank you for the detailed and considerate reply. I understand the tradeoffs, it's a reasonable position. With the latest changes to your PR, it should work great for our purpose. |
I wanted to add that I'm impressed with the design of this package. It made me rethink how I structure type relationships in my own work. |
Closed by #177. Feel free to open new issues to address remaining specific concerns. |
We've used temperatures extensively since #177 was merged. It works great, and the K vs °C distinction is very elegant. |
Right now, it seems that temperature conversions have been made correct on a case by case basis, but its easy to find cases where things go wrong. For instance,
if 1°C is 274.15 K, then it should not be the case that 1°C^-1 is 1 K^-1.
It seems that the handling of temperature conversions needs to be made more general. However, this is a really fraught area. I think this package needs to choose a philosophy and stick to it consistently for offset units. This is a hard choice to make though. For instance, what does it mean to multiply an offset unit by a number? Is 5°C really 5 times warmer than 1°C, or is it only 1.015 times warmer? If one thinks that it should be treated as 5 times warmer, then one then has to commit to the position that 1°C is infinitely warmer than 0°C which soon becomes a problematic position. It's really not obvious what the optimal choice is to make here, but I think that whatever choice is made should at least be well documented and consistent.
My suggestion would be to always internally represent offset units on an absolute scale but then display them as offset units such that 5°C is only 1.015 times warmer than 1°C but provide an opt-in option to treat them as if they were absolute if that's what a user needs.
The text was updated successfully, but these errors were encountered: