13

Soft question: are Quantity - and newly added MixedUnit and MixedMagnitude - needed in a symbolic manipulation language?

Quantity is the product of magnitude and unit, so couldn't even mixed ones be represented as polynomials, eg:

t1 = 1*Unit["Hours"] + 30*Unit["Minutes"];

t2 = 30*Unit["Minutes"] + 1*Unit["Seconds"];

Note there is no Unit head in WL - using upper case U to make it look legit. What technical hurdles stand in the way of evaluating, say:

t1-t2 --> 59*Unit["Minutes"] + 59*Unit["Seconds"]

versus the current, awkward representation:

Quantity[MixedMagnitude[{1, 30}], MixedUnit[{"Hours", "Minutes"}]] - 
 Quantity[MixedMagnitude[{30, 1}], MixedUnit[{"Minutes", "Seconds"}]]
J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
alancalvitti
  • 15,143
  • 3
  • 27
  • 92
  • What about derivatives and other operations? – Baran Cimen May 11 '16 at 14:10
  • 4
    I started from the version of Mma, in which Quantity still did not exist. At that time we very efficiently used the constructs as 5*kg*10*m /. kg -> Nw/m with the effect 50 Nw. The advantage is that the units notations are shorter and closer to the ones we use in real "scientific" life. – Alexei Boulbitch May 11 '16 at 14:18
  • 4
    What about multiplying by 0? 0 isn't 0 for a lot of units. 0 is different in Kelvin and Farenheit. – Searke May 11 '16 at 16:32
  • Use Ctrl + = to enter units. If you use the unit system as it was meant to be used, it's less awkward. – Searke May 11 '16 at 16:32
  • 2
    @Searke, apart from temperature units (which also had special handling in the old Miscellaneous`Units`​ package), I'm hard-pressed to think of a unit example where $0$ was "special". – J. M.'s missing motivation May 11 '16 at 17:07
  • 1
    @Searke what about folks who write packages, they can't Ctrl + = in IDEs. – Kuba May 11 '16 at 17:22
  • I guess it could also come down to how you define "needed". – chuy May 11 '16 at 18:10
  • @J.M. Unless you want to redefine multiplication by zero, you need it to prevent incompatible unit mixing as well – Searke May 11 '16 at 23:38
  • 2
    @Kuba Honestly, there probably aren't enough people using Mathematica through an IDE to worry. Lots of nice things won't work outside a notebook like :esc: dist :esc: and other such characters. For me at least, having to write out "Distributed" and "Quantity" are the least of my programming woes. – Searke May 11 '16 at 23:45
  • @thedude, how are derivatives &c handled currently with Quantity? – alancalvitti May 12 '16 at 18:53
  • @Searke, re "multiplying by 0" - what's the problem? just like 1/0 throws an exception "Power::infy", so 0*Unit["Kelvins"] could be handled as a special case as Quantity[0,"Kelvins"]. Conditionals are a fundamental aspect of all programming languages, why couldn't the evaluator distinguish such patterns. – alancalvitti May 12 '16 at 18:57
  • @chuy, "needed" as in can we do without it, as what I'm suggesting seems simpler, more orthogonal. – alancalvitti May 12 '16 at 18:59
  • @AlexeiBoulbitch, you're right, even better if each unit were an internal symbol, avoids writing Unit. – alancalvitti May 12 '16 at 19:04
  • 2
    @alancalvitti You want to add special rules to prevent 0 * x from not equaling 0 unless there's evidence that x isn't a "Unit"? Or would you prefer to have some other (worse) inconsistancy? And what about cannonicalization? You want to build the rules cannonicalizing units into the operations of Multiplication and Addition? That's a nightmare. No thank you. – Searke May 12 '16 at 19:55
  • @Searke I think our comments will make a good answer. – Kuba May 13 '16 at 08:04
  • Who's voting to close? I use Quantity constantly in my work and think the issue is important. I'm going to raise it to SW and others at WRI. This idea that it would be a nightmare is fanciful - it's expression manipulation like everything else in WL. – alancalvitti May 13 '16 at 16:31
  • @Searke: at least in v10.0, 0 Quantity["Celsius"] evaluates correctly (e.g., UnitConvert[0. Quantity["Celsius"], Quantity["Kelvins"]] gives 273.15K), so your concern is not applicable. This could even be implemented by user-define heads by using UpValues: after quan/: x_ quan[y_]:=quan[x,y], one has that 0 quan["Celsius"] evaluates to quan[0,"Celsius"]. – Bruno Le Floch Jun 01 '16 at 15:08

1 Answers1

6

(The code in this answer is tested using Mathematica 10.0, in which MixedUnit and MixedMagnitude are not available. However, the online help is pretty clear, and I explain why these functions are needed.)

When two quantities are summed, it seems like a reasonable default to convert them to the same unit, as otherwise one would quickly end up with expressions involving (say) meters, nanometers, Angstroms, etc., which would have to explicitly be converted to some target unit in order to have any idea what the magnitude actually is.

So, given this default, t1 = 1 Quantity["Hours"] + 30 Quantity["Minutes"] gives Quantity[90, "Minutes"] (by the way, the choice of unit in sums seems to be such as to make (the log of) the magnitude as close to (the log of) 30 as possible), and t2 = 30 Quantity["Minutes"] + 1 Quantity["Seconds"] gives Quantity[1801/60, "Minutes"]. Their difference t1-t2 is naturally Quantity[3599/60, "Minutes"].

This result can be converted to seconds using UnitConvert[t1-t2, "Seconds"], but one may want it to be split in terms of minutes and seconds. It would have been possible to implement UnitConvert such that UnitConvert[t1-t2, {"Minutes","Seconds"}] would split t1-t2. However, UnitConvert was made Listable, which enables nice constructions such as UnitConvert[{t1,t2,t1-t2}, "Seconds"] to convert several times into seconds, or UnitConvert[t1,{"Years","Hours","Nanoseconds"}] to see a time expressed in different units, or UnitConvert[{quantities},{units}] to convert several quantities to several units (same number of quantities and units). This behaviour is consistent with very many Mathematica builtins.

Since UnitConvert[t1-t2, {"Minutes","Seconds"}] already is defined as giving t1-t2 twice, once in minutes and once in seconds, we need another way of splitting. Furthermore, it would be better if the split result Quantity[59, "Minutes"] + Quantity[59, "Seconds"] did not automatically recombine as soon as it is evaluated again (e.g., copied and pasted into a new calculation/table/etc.) So the output as a sum of Quantity is not great (one could have had a bunch of Hold, but that's horrible). The choice of expressing the split result as Quantity[MixedMagnitude[{59,59}], MixedUnit[{"Minutes", "Seconds"}]] is quite long-winded, I agree, but it has the advantages of preserving the fact that Quantity have 2 arguments in all cases (plus options), the first being the magnitude and the second the unit. This also gives a natural way to express that some quantity should be split in terms of several units: simply use MixedUnit[{"Minutes", "Seconds"}] as the unit argument of UnitConvert.

One way to implement a short-hand to express things like 1 hour and 30 minutes is the following (I used && as a notation for a sum that preserves units using MixedUnit and MixedMagnitude; however, I cannot test because my version of Mathematica is too old):

Unprotect[Quantity];
HoldPattern[And[x__Quantity]] ^:= 
  Quantity[MixedMagnitude[QuantityMagnitude[{x}]], 
   MixedUnit[QuantityUnit[{x}]]];
Protect[Quantity];
1 Quantity["Hours"] && 30 Quantity["Minutes"]

(*=> Quantity[MixedMagnitude[{1, 30}], MixedUnit[{"Hours", "Minutes"}]]*)

By the way, it is very easy to define shorthands for Quantity["Hours"] etc by doing

Clear[Mili, Kilo];
Mili = 1/1000;
Kilo = 1000;
Protect[Mili, Kilo];
Scan[(Clear[#]; # = Quantity[ToString[#]]; Protect[#]) &,
  {Meters, Feet, Grams, Pounds, Kelvins, Fahrenheit}];


{UnitConvert[0 Fahrenheit, Kelvins], 2 Kilo Grams / (Mili Meters), 2 Feet + 3 Meters + 1 Kilo Feet}

(*=> {Quantity[45967/180, "Kelvins"], Quantity[2000000, ("Grams")/("Meters")], Quantity[192756/625, "Meters"]}*)
Bruno Le Floch
  • 1,959
  • 10
  • 23
  • Bruno, thanks for this approach. I'm giving this provisional thumbs up until I get to test it. Though ideally there would be no more need for MixedMagnitude or MixedUnit, than for SecondOrderPolynomial. – alancalvitti Jun 01 '16 at 18:58