# Should 0 * 5ft be 0 or 0ft?

After playing with the new quantity system in Mathematica 9 for a while, I keep stumbling over this issue:

0 * Quantity[1, "Meters"]


is not the same as

1 * Quantity[0, "Meters"]


The first is dimensionless 0, the second is 0 meters, and a dimensionless quantity can't be added to or converted to a length like meters.

Take e.g. this simplified example:

startPoint = Quantity[1, "Meters"];
endPoint = Quantity[5, "Meters"];
Manipulate[
UnitConvert[a*endPoint + (1 - a)*startPoint, "Inches"], {a, 0, 1}]


The manipulate converts a point along a line to inches. It works for any setting of a, except 0. and 1., where I get UnitConvert[0. + Quantity[1., "Meters"], "Inches"] instead of a proper length. Generally speaking, it seems that any expression that contains a dimensionless subexpression that can be 0 might break somewhere in your Manipulate, Table or Animate. This seems extremely fragile to me.

Is this a bug? Or am I using Quantity wrong? Should I avoid dimensionless expressions completely? Or avoid Quantity inside dynamic code?

• Of course it should be 0ft! IMO new unit system is very incomplete. I would recommend this package, it works way more better. – swish Nov 29 '12 at 13:53
• @swish: I'm actually thinking about using the old package instead of the new quantites. Less verbose and apparently less buggy. But I would have liked the deep integration into plots, calculus and so on. – Niki Estner Nov 29 '12 at 14:02
• Old package has the same integration. And this new TargetUnits for plots is buggy anyways. – swish Nov 29 '12 at 14:07
• @swish: Seems as if AutomaticUnits doesn't work in version 9 any more... I'll probably keep using the built-in Units package – Niki Estner Nov 29 '12 at 14:21
• @swish try putting Internal\$DisableQuantityUnits = True; in your init.m. This prevents the package from loading without forcing you to actually remove it. AutomaticUnits  will then work completely normally. – Oleksandr R. Jan 27 '13 at 0:39

While it would've been nice if the package handled it automatically, it can be fixed with a simple overloading of Quantity:

Unprotect@Quantity;
Quantity /: (0 | 0.) Quantity[_, unit_] := Quantity[0, unit]
Protect@Quantity;


You can add this to your init.m, so that you don't have to define it each time. You can test your examples with this:

0. Quantity[1, "Meters"]
(* 0 m *)

0 Quantity[1, "Meters"]
(* 0 m *)

• Is this a safe overload. It sure looks like nothing could go wrong, but are there any catches? – Ajasja Nov 29 '12 at 16:38
• +1, this looks very promising. But wouldn't it make more sense to tag the assignment to Quantity instead of Times? Then ordinary multiplications not involving quantities wouldn't be slower or behave differently, right? I've tried Quantity /: (0 | 0.) Quantity[_, unit_] := Quantity[0, unit] and it seems to work just as well. – Niki Estner Nov 29 '12 at 16:40
• @nikie Yes, overloading Quantity is preferable. I'll update it. – rm -rf Nov 29 '12 at 17:00
• This code looks strangely familiar :) +1. – Leonid Shifrin Nov 29 '12 at 23:29
• @LeonidShifrin Not sure what you mean, but I'll take the +1 :) – rm -rf Nov 29 '12 at 23:36

Not a full answer since I need to sleep :) but more of an observation, which might help. It seems to have to do with the fact that 0 and 0. are not the same in Mathematica. This simple example shows it

     UnitConvert[0. + Quantity[5, "Meters"], "Inches"]
(*-->  UnitConvert[0. + Quantity[5, "Meters"], "Inches"]  *)


while

     UnitConvert[0 + Quantity[5, "Meters"], "Inches"]
(*---> Quantity[25000/127, Inches]  *)


So, to get your Manipulate to work, just do this

startPoint = Quantity[1, "Meters"];
endPoint = Quantity[5, "Meters"];
Manipulate[UnitConvert[Rationalize[a]*endPoint + (1 - Rationalize[a])*startPoint,
"Inches"], {a, 0, 1}]


And now no problems at any end.

PS. see the Trott book, page 149-150 "For programming" , very useful on differences between 0 and 0. in Mathematica.

edit

The reason why

UnitConvert[0*Quantity[1,"Meters"],"Inches"]


fails with

During evaluation of In[153]:= Quantity::compat: 0 and Inches are incompatible units >>


Is the same reason why

UnitConvert[0,"Inches"]


fails

During evaluation of In[154]:= Quantity::compat: 0 and Inches are incompatible units >>


Since 0 times almost anything in Mathematica gives 0, and 0 has no units. So conversion failed. I think this is different from the above examples, where the issue above was in the addition as can be seen

0. + Quantity[5,"Meters"]  (*---> 0. +5m *)


while

0 + Quantity[5,"Meters"] (* ---> 5m *)

• Only in this special case. Take UnitConvert[a * startPoint, "Inches"] instead - this will not work for 0 or 0. – Niki Estner Nov 29 '12 at 14:04
• (I think) Rationalizing 0. to 0 works because 0 + _ is automatically simplified to _, but 0. + _ is not. the bug is still there, it's just masked in this special case. – Niki Estner Nov 29 '12 at 14:23
• 0 times almost anything in Mathematica gives 0. That's exactly the problem. If any dimensionless subexpression becomes 0, Mathematica will throw away all the units and further calculations might fail (although they won't always fail, as you demonstrated). – Niki Estner Nov 29 '12 at 14:26
• This has come up in the past. I posted the following message on comp.soft-sys.math.mathematica back in 2010: "While testing Mathematica 8 on some heritage code, I found a problem which a colleague traced to a behavioral change in Times[]. Specifically, the documentation for Times[] states that "0 x evaluates to 0, but 0.0 x is left unchanged." This appears to be true in Mathematica 7 but not in Mathematica 8 (at least not under Mac OS X 10.6.4). I have informed Wolfram about this change (bug?)" I don't think I ever received a satisfactory answer (they acknowledged the problem, but no fix). – Cassini Nov 29 '12 at 14:37
• There would be two ways to fix this: Either make sure that Times[0, Quantity] doesn't simplify to 0, or make sure that Quantity and UnitConvert treat 0 as a value that can have any dimension. That would have been possible without changing the whole core. That's how the old Units package and AutomaticUnits apparently solved the same problem. – Niki Estner Nov 29 '12 at 14:55