Group Abstract Group Abstract

Message Boards Message Boards

Solve and NSolve not working well with Quantity and Units?

Posted 5 years ago

I am trying to update 100k lines of Mathematica I wrote 15-20 years ago in Version 4. I am struggling with getting Quantity, Solve/NSolve and Integrate to correctly deal with units. Solve/NSolve always return the correct numerical values, but the "Units" are quite often lost. I can not figure out why. But it seems related to the Integrate function and places where variable definitions first appear in the code as arguments to the Quantity function. The Plus function may also be failing. Also of note, is how "unit-less" variable name definitions seem the direct cause of the errors produced by the Integrate function. And perhaps at the root of my programming dilemma is the way multiplying a scalar Quantity by zero wrongly preserves Units.

In V4:

   200 kg times 0 equals 0

In V12

   200 kg times 0 equals 0 kg

This bug/feature, breaks simple vector calculus computations in countless ways. See the detailed examples given far below in this thread, where V12's forcing of units on values of zero magnitude causes simple exercises in Newtonian Mechanics to "blow up".

Any help would be appreciated. See attached notebook for examples of this behavior. JPEG attached for easy demonstration of typesetting. Code is in the attached notebook.

\!\(\*OverscriptBox[\(a\), \(\[RightVector]\)]\) = {Quantity[0, (
    "Meters")/("Seconds")^2], Quantity[0, ("Meters")/("Seconds")^2]};

Solve not returning Units

NSolve working almost correctly

POSTED BY: Francis Bush
44 Replies

I have posted a new thread summarizing issues with Quantity that have been raised here. Further responses should go to that thread. This one has a considerable noise-to-signal fraction and we need to close it. We ask that responses in the new thread be kept to the point. The issues in question involve handling of units. I remark that version 4 had no built-in handling of units. Comparisons to version 4 are thus not regarded as on point.

POSTED BY: Daniel Lichtblau
POSTED BY: Francis Bush

Francis, I don't think that my solutions to your examples contain 'pages of extra code' over your presentations in your earlier posting. To me they seem about the same length or maybe even shorter. And they work. In my opinion it's not good practice to teach students to mix input values and units into their equations. If one looks into any advanced physics book or paper they just don't do it. If one plans to run them through algebraic derivations the units act like a pack of barking dogs. Units are not necessary there and they contribute nothing there.

(You talk about Mathematica as being code. Mathematica is NOT a programming language. It is a new active and dynamic medium for developing and publishing ideas that have a mathematical content. We have to learn how to use it - even the developers. If you want to be a programmer use MatLab, if you want to be a scientist/intellectual use Mathematica.)

If you are truly interested in advancing STEM education then I can show you how you can make a significant contribution if you wish to contact me by email through my profile page.

POSTED BY: Francis Bush

On an unrelated note, in the early 80's ('81 to be exact) I worked on a Jovial compiler project. It was a subcontract from Singer I believe, and intended for use in simulators for training pilots. I have since seen one or two such simulators in a museum (maybe I also belong in a museum...)

POSTED BY: Daniel Lichtblau

Wow, I bet your code was running on the simulators in Fort Worth.

I will never forget watching the Airforce brass show up informally on weekends, dive into a couple, interlinked, full cockpit, 360 degree simulators and dogfight away on a Saturday afternoon. In the days of "Pong" this represented the best, multi-million dollar video game on the planet!

POSTED BY: Francis Bush
POSTED BY: Francis Bush
POSTED BY: Daniel Lichtblau
POSTED BY: Hans Dolhaine
POSTED BY: Francis Bush
POSTED BY: Francis Bush

If I understand things correctly you say Solve cannot handle units, but:

Solve/NSolve always return the correct numerical values,

Well, is it possible that Solve evaluates expressions as far as possible and then it could occur that units are cancelled on both sides of an equation. Look at this with "unit" b

Solve[a g b == x b, g]
POSTED BY: Hans Dolhaine

Francis,

I think there is a big misunderstanding. I also do not see a bug here -- I think it is a misunderstanding of what Quantity does and how it is supposed to work. Please let me try to explain:

This expression:

Quantity[t,"Seconds"] 

DOES NOT declare t as a variable with units of seconds. t ramains a scalar number without units. If I define

vart = Quantity[t,"Seconds"] 

In this case, "vart" DOES have units of Seconds (but "t" is still scalar). You MUST use vart everywhere you want a variable with units (in the Solve and in the Integrate. Here is some sample code with the subscripts removed to make it clear.

bbx :=  Quantity[bxscalar, "Meters"/"Seconds"^2];
bby :=  Quantity[byscalar, "Meters"/"Seconds"^2];

bvector = {bbx, bby};
Solve[bbx ==  
    Quantity[33, "Meters"/"Seconds"]/Quantity[12, "Seconds"] , bbx]

 Integrate[bvector, Quantity[t, "Seconds"]]

Both these examples work and are consistent do I don't understand the problem. Can you point out what I am missing with my simple example above? Maybe then, Daniel or I could be more helpful.

Regards

Neil

POSTED BY: Neil Singer

Neil,

I am sorry I have been unable to make this issue clear. It is a subtle point, made more confusing by my rather ornate use of variable names.

So, as requested, I will try here to illustrate it with code that is more easy to copy. I hope that helps. I will, as always, attach a notebook for convenience.

For comparison, here is a simple example where Solve, quite properly I believe, deduces the correct units. Notice in this first example the vector aVec is defined in a unit-less fashion. None the less, Solve will still correctly determine the units from the calculation.

m = Quantity[40, "Kilograms"];
g = Quantity[9.8, ("Meters")/("Seconds")^2];
aVec = {ax, ay};
Fw = m*g;
FwVec = AngleVector[{Fw,  270 Degree}];                                         
F1Vec = AngleVector[{Quantity[20, "Newtons"], 0 Degree}];  
FnVec = AngleVector[{Fw, 90 Degree}];                                            
RVec = F1Vec + FnVec +  FwVec;                                                          
Solve[RVec == m*aVec, aVec]

This produces the following output:

{ax -> Quantity[0.5, ("Meters")/("Seconds")^2], 
 ay -> Quantity[0., ("Meters")/("Seconds")^2]}

So far so good. Notice that although aVec in the simple example above was defined without units, Solve could determine the units from the calculation and the lack of units is not a show-stopper. This seems to me to be reasonable and correct Mathematica behavior.

Now consider a similar calculation that requires the Integrate function.

r0Vec = {Quantity[0, "Meters"], Quantity[0, "Meters"]};
r1Vec = {Quantity[1, "Meters"], Quantity[0, "Meters"]};
v0Vec = AngleVector[{Quantity[2.8, ("Meters")/("Seconds")], 0 Degree}];
v1Vec = AngleVector[{Quantity[0, ("Meters")/("Seconds")], 0 Degree}];
aVec = {ax, ay}; 
m = Quantity[0.45, "Kilograms"];
g = Quantity[9.8, ("Meters")/("Seconds")^2];
Fw = m*g;
FwVec = AngleVector[{Fw, 270 Degree}];                                             
FkVec = AngleVector[{Fk, 180 Degree}];
FnVec = AngleVector[{Fw,  90 Degree}];                                              
RVec = FkVec + FnVec + FwVec;                                   

In this example, the lack of units for the aVec appears to be a complete showstopper for Integrate. The following will produce many Quantity related errors.

v0Vec + Integrate[aVec, Quantity[t, "Seconds"]]

So, executing the following line, which is a valid mathematical description of the solution, will never work in V12, for the reasons outlined.

 NSolve[{RVec == m*aVec, r1Vec ==  r0Vec + Integrate[v0Vec, Quantity[t, "Seconds"]] +     Integrate[Integrate[aVec, Quantity[t, "Seconds"]], Quantity[t, "Seconds"]], v1Vec == v0Vec + Integrate[aVec, Quantity[t, "Seconds"]]}, {t, ax,  ay, Fk}] // First 

It seems to me that it most definitely should work in V12, like it so beautifully did in V4. But it does not. The lack of units in the definition of the aVec vector seems to cause a whole class of solution expressions, that are perfectly valid mathematically, to no longer be calculable in Mathematica V12. How could such a fault be anything less than a "flaw" or "bug" or "mistake" in the architecture of units in V12 via the Quantity function?

So, in conclusion, here is why this strikes me as a "flaw" in V12.

Because in V4 (see example in attached notebook or JPEG below) these sort of unit-less variables did not stop the Integrate function from completing it's task. In V4, before the Quantity function was introduced and before functions like Plus, Integrate, etc... were re-coded/updated, the units for aVec were easily deduced from the calculation itself. Is this not superior? This is how it worked in V4. I found such functionality both beautiful and effective. But I can not find a way to make V12 behave in this V4 superior manner, and deduce the units of variables not explicitly defined with Quantity. Part 1

It feels like I am saying the same thing, over and over.

Does this make any sense? Regards, - Joe

POSTED BY: Francis Bush
POSTED BY: Daniel Lichtblau
POSTED BY: Francis Bush
POSTED BY: Daniel Lichtblau
POSTED BY: Francis Bush
POSTED BY: Daniel Lichtblau
POSTED BY: Francis Bush

All code examples are in the attached notebooks. The examples are all "three cells" in length. Practically "one-liners". I can not demonstrate these issues with less code. Because I using "built in" Mathematica typesetting, like the integral sign, there is now way to show such code on this website, short of an attached notebook.

POSTED BY: Francis Bush

The integral that I see from several messages back appears to work just fine. The message arose from an attempt to add quantities of nonconforming units.

You are making this quite difficult to even follow, let alone diagnose. I will suggest that you provide full code in the post, avoiding Subscript unless that is absolutely needed to reproduce the problematic behavior. It should be copy-pastable. I for one am not going to rekey from images because that is both laborious and error-prone.

POSTED BY: Daniel Lichtblau
Attachments:
POSTED BY: Francis Bush
POSTED BY: Francis Bush
POSTED BY: Neil Singer

Do you still have Version 4 on your computer? If so you might be able to use the old MiscellaneousUnits and MiscellaneousPhysicalConstants. I thought I had saved a copy of them at the time WRI switched over but I can't find them now. I do have an extension Units2` done by Ted Ersek that substitutes for the old Units but it still requires PhysicalConstants.

The old system also allowed one to install their own units, which I don't think can be done now.

Maybe you could get those packages from Wolfram.

I don't think there are any real benefits from dragging Units through all the algebraic routines. It doesn't guarantee that the units are correct because it's possibly to use wrong units consistently. If Mathematica is going to let you use units everywhere then you are right that it should be better implemented.

No, David. I do not have a working copy of V4. Sure wish I did ;-) I know the Units package to which you refer. Many such packages are no longer "optional" and are now just built into the kernel, like it or not. The package architecture was a good one I believe. I wish Quantity was in some package, that I could delete from my laptop and return to beautiful V4 functionality. ;-) Pero, por desgracia, V4 es un idioma muerto ;-) Tenga buen dia, - Joe

POSTED BY: Francis Bush
POSTED BY: Neil Singer

Thanks Neil. Yes, only variables assigned the output of a Quantity function have the quantity head. And you are also correct that redefining some variables can make this work (quite often). But the approach only works in simple cases. And F2, in the example above, is never assigned a Quantity head, and yet, Solve and NSolve can correctly deduce the units. Why?

For example, here are two cases where the change you suggested produces the correct output from Solve.

Example of working definitions

Also, this works:

enter image description here

However, this syntactical approach seems to still fail in the following example. For example, my original approach works (except for units output by Solve).

enter image description here

But if we attempt the same sort of thing you are suggesting here, then the total lack of Quantity definitions causes the simple functions like Integrate and Plus to "choke".

So, for this kind of calculation I am still at a loss for the correct approach.

enter image description here

POSTED BY: Francis Bush

As I believe the code and discussions have easily shown, Mathematica V12 and the unavoidable forced incorporation of the Quantity function has "broken" Mathematica in an important way. THIS IS A BUG!

From what I can determine, there is NO WAY to get Mathematica V12 to work flawlessly with Units from the built-in Quantity function. The best results I have been able to obtain have correct numerical values but Units are lost by functions such as Solve and NSolve. This would seem to be a MAJOR BUG in V12.

Also, curiously, for a guy like me who as been out of the Wolfram universe for decades, no one on sites like this one, or StackExchange, or even Wolfram Tech Support know the answer.

Instead, the experts in the field all (1) avoid using units and Quantity at all cost, or (2) add 1000's of lines of "rewrite rules" to clean up the faulty V12 output, or (3) try unpredictable overloading of the Quantity function in a last act of desperation.

No one I have discussed this with seem to know how to use Quantity and obtain valid results.

Lastly, no where in the Wolfram docs can I find anything but the most trivial example of Units and Quantity. In simple cases it can work. In more complex cases, from my money, Quantity simply does not work.

With the addition of the Quantity functions and all the modifications to prevously existing functions, like Plus or Integrate or Solve or NSolve, (all new or "updated" in V9, I believe), Mathematica now limps down the road like a car with a flat tire.

Very sad ;-)

POSTED BY: Francis Bush
POSTED BY: Francis Bush

Hard to say with an image instead of the actual code, but it looks like you redefined a to be a vector comprised of two scalar components, because the subscripted elements Subscript[a,x] and Subscript[a,y] are not themselves quantities with associated units. So that would lead to a quantity incompatibility.

On a different note, you did provide a notebook showing problematic computations. But it is huge and has nothing remotely resembling a minimal example of the shortcoming(s). It is simply not something I would be prepared to wade through. I'll take a look at the example provided by @Neil Singer when time permits.

POSTED BY: Daniel Lichtblau

I understand. Thanks for your time and input.

My example notebook contained 5 simple examples, clearly sub-sectioned and each example represents a simple "freshman" Newtonian Physics problem, expressed in "vector calculus", should you find the time to explore this issue.

I heard back from Wolfram Tech Support and sadly, they could not resolve these issues with Quantity and related functions. The "Units.nb" is from Wolfram Tech Support. See attached. It does not improve on the issue and seems to confirm my complaint that Mathematica is "broken" or "limited" in this regard. Seems like a huge step backward.

Regarding a working copy of V4, no, unfortunately my laptop with a working copy of V4 died decades ago. I do have the original V4 code and the original V4 output. 100k plus lines of code that worked fine in V4 but fails miserably in V12.

The sad thing is, what was a piece of cake and pleasure in V4 is now a pain in the backside, made worse by the fact that there is no way to avoid these issues with Quantity except perform complete "unit-less" calculations.

Should there not be a "global switch" that tells the kernel to ignore anything related to Quantity, and permit "home rolled" V4 style units?

Just a thought!

POSTED BY: Francis Bush

You forgot to attache the Units.nb file. However, doesn't what I last posted solve your problem for both integration and Solve?

Regards,

Neil

POSTED BY: Neil Singer

Hi Neil, No I did attach the Wolfram Tech Support notebook called Units. It can be found in the first attachment section of this discussion. Start at the top and scroll down. In the notebook, you can see that Wolfram Tech Support was unable to produce the correct units via Solve and NSolve. You will also not how ridiculously easy such a task was in V4. See JPEGS above! How I miss V4 ;-) Regards, - Joe

POSTED BY: Francis Bush

Using the notation package and symbolizing expressions is generally fine but can have pattern matching issues if that is not taken into account in other code. I would suggest trying some simple examples with and without symbolized notation to see if that is the source of the problem. I could imagine (with no evidence whatsoever) that the Solve pattern matching with units could have a bug in treating those symbols. If so, tech support is very responsive and it might get it fixed fairly quickly if you can isolate the behavior.

POSTED BY: Neil Singer
POSTED BY: Francis Bush

I just did a quick test and the Subscript with units threw an error. The main variable and the subscript can both have units so I am not surprised that Mathematica gets confused.

This works:

In[10]:= R = Quantity[f1, "Newtons"];
m = Quantity[12, "Kilograms"];
Solve[R == m*a, a]


Out[12]= {{a -> f1 (Quantity[1/12, ("Meters")/("Seconds")^2])}}

This does not:

In[13]:= R = Quantity[Subscript[f, 1], "Newtons"];
m = Quantity[12, "Kilograms"];
Solve[R == m*a, a]


During evaluation of In[13]:= Solve::units: Solve was unable to determine the units of quantities that appear in the input.

Out[15]= Solve[
 Quantity[Subscript[f, 1], "Newtons"] == 
  a (Quantity[12, "Kilograms"]), a]
POSTED BY: Neil Singer

It is my experience subscripts DO NOT work correctly in variable names UNLESS "Symbolized". See the attached notebook to see how this is done. You will note that my subscripted symbols are all interpreted correcly (because I used Symbolize). They cause no errors in my example notebook. It is only the UNITS that get screwed up by Solve and NSolve

Attachments:
POSTED BY: Francis Bush

Francis,

I believe your problem is the subscripts and not the units. Solve handles the units properly as long as there are no subscripts in the variables. I have noticed that Solve never handles subscripts well even without units and I have gotten strange results over the years using subscripts. I would use f1 instead of Subscript[f,1] etc.

I hope this helps,

Regards,

Neil

POSTED BY: Neil Singer

Thanks. Yes, ordinarily that might be a problem. But you can see that Solve and NSolve DO NOT get confused about my construction of variable names.

See the output from my attached JPEG examples in this discussion.

The variables "names", complete with Subscripts and Overbars, are all interpreted correctly, as the output from Solve and NSolve and the correct numerical values demonstrate. Only the Units get lost.

FYI, to get this rather LaTex looking typesetting (one of Mathematica's coolest features for my money) I use "Symbolize" from the Notation Package.

There are no examples where such variables written in this lovely sort of typesetting are misidentified by Mathematica. This feature of Mathematica has worked correctly since V1.

See below. Sorry for the JPEG, simply an easy way to show the correct typesetting. I have updated the attached notebook to include this code.

Code for Symbolize

Attachments:
POSTED BY: Francis Bush

I find that a smoother way to handle units is to avoid putting them into expressions at the beginning of a calculation but only put them in at the last steps.

Write a set of rules that give the numerical and unit values for each of your variables. Then do your algebraic calculations symbolically, using these rules at the conclusion.

I've written an application called UnitsHelper that helps with these problems, If you write to me I can send you a Dropbox link.

One of the routines, Deunitize, will remove the units from an expression in such a way to have implied input units and an implied output unit (and checks for consistency.).

UnitsHelper also has provision for defining reduced unit systems such as geometrical units or atomic units, general decibel units, and handy palettes.

Thanks David. I have used this kind of late stage rewrite rules, to clean up output.

But I was hoping to avoid such an approach as it defeats the purpose of having units in a calculation in the first place. Ie., Units are like "strong typing" in a programming language, in the sense that it helps flag errors in calculations. If the units are "wrong" in the output of a calculation, that is a good clue that the whole calculation is somehow flawed, no? That is my main reason for wanting to use units in the first place. In V4, I could happily define my own, and things worked perfectly (see JPEGS of V4 syntax below). In V12, Quantity and the way Solve/NSolve check for unit consistency means no "home rolled" solution will work. Makes me think Quantity should be a "Package" and not part of the kernel.

My hope was Mathematica could do this correctly, and maybe it does and I have just yet to figure out how.

Should not a "units" feature in Mathematica be both working and central to it's function? As bullet proof as the Plus or Times function?

Wolfram apparently added this Quantity head somewhere around V9, 10 years later, and from what I can tell, it is still not working correctly. But, I will admit, I have not used Mathematica since V4, so I am no expert.

I have even looked from some "global switch", to tell all the functions like Solve to ignore all Quantity heads. But, sadly, I have not found one. The "Quantity" bag is firmly glued on to the side of V12. It just does not appear to work correctly. (or I am still missing a key idea).

POSTED BY: Francis Bush