Should 0 * 5ft be 0 or 0ft?

29

6

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?

Niki Estner

Posted 2012-11-29T13:27:53.360

Reputation: 34 978

1

Of course it should be 0ft! IMO new unit system is very incomplete. I would recommend this package, it works way more better.

– swish – 2012-11-29T13:53:13.327

@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 – 2012-11-29T14:02:49.613

Old package has the same integration. And this new TargetUnits for plots is buggy anyways. – swish – 2012-11-29T14:07:27.610

@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 – 2012-11-29T14:21:06.793

I just removed QuantityUnits folder from AddOns/Applications. I don't know how to remove it properly :(. – swish – 2012-11-29T14:36:25.627

3@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. – 2013-01-27T00:39:48.353

Answers

15

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 *)

rm -rf

Posted 2012-11-29T13:27:53.360

Reputation: 85 395

1Is this a safe overload. It sure looks like nothing could go wrong, but are there any catches? – Ajasja – 2012-11-29T16:38:57.000

2+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 – 2012-11-29T16:40:59.860

@nikie Yes, overloading Quantity is preferable. I'll update it. – rm -rf – 2012-11-29T17:00:01.660

This code looks strangely familiar :) +1. – Leonid Shifrin – 2012-11-29T23:29:05.433

@LeonidShifrin Not sure what you mean, but I'll take the +1 :) – rm -rf – 2012-11-29T23:36:09.937

I meant this answer fo mine :)

– Leonid Shifrin – 2012-11-29T23:37:34.923

@LeonidShifrin Ha! Hadn't seen that one yet... well, now I must upvote that :) – rm -rf – 2012-11-29T23:39:41.023

@rm-rf Great minds think alike? Thanks for the upvote :) – Leonid Shifrin – 2012-11-29T23:40:56.173

5

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 *)

Nasser

Posted 2012-11-29T13:27:53.360

Reputation: 92 661

Only in this special case. Take UnitConvert[a * startPoint, "Inches"] instead - this will not work for 0 or 0. – Niki Estner – 2012-11-29T14:04:29.333

(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 – 2012-11-29T14:23:44.363

20 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 – 2012-11-29T14:26:29.653

1This 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 – 2012-11-29T14:37:20.903

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 – 2012-11-29T14:55:35.123

@NasserM.Abbasi: the fact that the behavior changed from MMA7 to MMA8 leads me to think that the problem can be fixed. – Cassini – 2012-11-29T20:26:56.923