-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Behavior of evaluate for units changed between minor versions #2518
Comments
Sadly, there is literally no way to get this right. In 10.4.0, the expression That said, the apparent wrongness/rightness of
@josdejong , thoughts? |
Thanks Glen for your in-depth reply. Man this is really tricky stuff. Your option (2) is indeed the proper one: make a clear distinction between absolute temperature and a relative temperature, and do not allow adding absolute temperatures but, and force adding a relative temperature to an absolute one. It feels though like overkill to me, and before we would go that route, we should get a clear overview on the normal use cases and see how that would work out. I think right now, we will serve most "typical" use cases if we apply your option (3). That's a small and pragmatic solution. Shall we go for that? |
(Same issue holds for |
@gwhitney Thank you so much for that explanation. I was able to get by for now with option 3, but this does make me appreciate the complexity at play here even more. |
OK, given Michael's comments, it seems like (3) is OK to try at least as a temporary band-aid until UnitMath is available. (That's @ericman314, right? Eric, are you aware of the absolute-relative temperature issues that need to be handled in some consistent fashion in UnitMath?) I'll try to work up a PR for (3) as soon as I can, but if publishing that leads to another round of concerns surfacing, there's probably no choice but to bite the bullet and do (2). |
Personally, I have always used degC and degF for absolute temperatures, and K and R for relative temperatures. So for me at least, the problem's already been solved. Any other usage of degC and degF is ambiguous, so we just need to choose a behavior (my vote is treat them as always absolute) and document that very clearly. Then K and R could be used in things like J/K. |
Since a relative Celsius degree is identical to a Kelvin degree (and similarly for Fahrenheit and Rankin), that is one way to go, with degC and degF as always absolute. @josdejong given that it seems like UnitMath is going to go that way, should mathjs follow suit and head that direction right now? In that case, the solution here would be to revert #2501, and instead:
Have I missed anything? Let me know if I should embark on this direction. |
P.S. Note of course this latter proposal would mean that the "resolution" of the problem in #2499 would be that the second multiplication that the poster there tried would throw an error (presumably suggesting use of K) rather than return a spurious result. That would definitely be better than the prior behavior, but presumably not what the poster was hoping for... To make this a little nicer, we could perhaps also make the "pure" unit degC (i.e. a valueless instance) automatically convert to K when it is used in a product or quotient. Then at least it would be easier to see that 5 J/K * 2 degC is an error (and 5 J/degC would have automatically converted to 5 J/K by the time you got to the explicit multiplication in 5 J/degC * 2 degC, so again it would perhaps be clearer why it's an error.) Anyhow, let me know your thoughts. In case it wasn't clear, this latest proposal is basically the same as option (2) above, just without introducing new units Cdeg and Fdeg, but instead using K and R for temperature changes. |
Yes, it makes sense to me, it sounds like the proper solution to separate absolute from relative temperatures 👍 @gwhitney your list with changes looks complete to me, thanks. I'm thinking about how to make sure that there are still practical ways to do real-world calculations with temperatures. Do we need special conversion functions to convert from absolute to relative temperatures and vice versa? |
Well, Kelvin (and Rankin) is both absolute and relative, thanks to the existence of absolute 0. So the conversion functions you need are |
Oh, and we need to disallow scalar multiples of degF and degC as well; it makes no sense to double or halve, for example, an absolute temperature like 20degC. |
That sounds straightforward 👍
Yes, could be. But does it really harm if you want to multiply an absolute temperature like |
Well, the harm is that the client might want the answer to be 40 degC but the only answer consistent with how Unit is implemented is 313.15 degC. How would that answer be useful? Also, we agree that 20 degC + 20 degC is disallowed (makes no sense to add two specific temperatures), but this is equivalent to 2(20 degC), so the latter should be disallowed as well. I started working on an implementation last night and ran into a code organization question: currently many operations on units are just defined in the various operation implementations, like add, subtract, etc. -- there is no Unit.add() method. So these operations use a bit of the innards of Unit, i.e. Unit is not tightly encapsulated. That leads to some repeated code in these operations. With making degC etc being only specific temperatures, there will be more internal checking that needs to be added to these operations, so my inclination will be to move them into Unit, where this code can be more easily shared. But then look what will happen with something like unaryMinus. The code for signature 'Unit' will become just 'u.unaryMinus()' . That function will do its checks, but typically eventually will have to negate its value, so presumably it will call |
You're right, makes sense indeed to disable these kind of operations with misleading outcome. Thanks It makes sense to me to move these basic operations like Yeah I understand what you mean with the circular issue. It should go "alright" (ie. not causing an infinite loop) as long as you only use these functions passing numeric values. So far I've solved a similar circularity in calculating on matrices vs scalars by introducing |
Hi, Recently I was having an issue with this while checking if a certain temperature was lower than another (I already solved my issue just wanted to share some tests). On versions newer than freezing = 0 degC to [degC, K, degR, degF];
freezing == transpose([freezing])
# yields
# [[true, false, false, false],
# [false, true, true, false],
# [false, true, true, false],
# [false, false, false, true]]
oneCelsius = 1 degC to [[degC], [K], [degR],[degF]];
minusOneCelsius = -1 degC to [[degC], [K], [degR],[degF]];
(minusOneCelsius < freezing) and (freezing < oneCelsius)
# yields
# [[true, false, false, false],
# [false, true, true, false],
# [false, true, true, false],
# [false, false, false, true]] All of these shall be true, which were ok on version I see it was intended as a solution for #2499 but I think it was an issue by the user as it's known that for example From other software I've used in the past; deltas or increments shall be managed in |
Yes, I think the response planned here would solve your issues, but it never got implemented. It got sidelined by the effort to reorganize mathjs in a TypeScript-friendly way, and then that stalled with some type reflection issues, and then I took on a visiting professor position so I didn't have time to devote to mathjs, and I haven't yet really gotten back into things. But as far as I know a PR implementing the final plan settled on here would still be welcome. But see the code-organization questions I raised the last time I tried to create such a PR. |
Oh ok, got it, thanks! I've read some of the discussions regarding Typescript and types and it seems like a huge effort. I recently left a part time professor position due to a personal time related situation. Now I've had a few chances to participate in this project which I've been wanting to do since a few years. I will review this discussion better to see if it's something I can work with as my programming skills are limited. |
It seems that somewhere between versions 10.4.0 and 10.4.2, the behavior of the evaluate function for unit types has changed and is inconsistent. A small reproduction case is this:
10.4.0:
evaluate( '37 degC == 98.6 degF' ) ===> true
10.4.2:
evaluate( '37 degC == 98.6 degF' ) ===> false
The text was updated successfully, but these errors were encountered: