Solve and NSolve not working well with Quantity and Units?

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]};

Examples of Problems with Quantity and NSolve.nb (2.47 MB)
The Quantity BUG in V12.nb (256 KB)
Units.nb (83.8 KB)

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

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

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]

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.

Examples of Problems with Quantity and NSolve.nb (2.47 MB)

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

Examples of Problems with Quantity and NSolve.nb (2.47 MB)

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.

Thanks Neil. I understand the suspicion of the Notation package and
Symbolize, but I have been using this package since V4, twenty years
ago, and never had a problem with it.

That said, I think I have spotted a pattern. I will update the example notebook
I attached to this discuss with the following example. Again, sorry for the
JPEG. It is used to show typesetting. Code is in the notebook.

The pattern I have noted is that if a “variable” first appears as an argument
to Quantity, then the Unit will never be correctly deduced by Solve or NSolve.
Instead, the unit for such a variable will be lost. However, other variables,
like my “force 2” variable in the JPEG below, that scalar too is never defined
as a specific Quantity unit. But, Solve and NSolve correctly “deduce” the unit.
I have examined a few dozen examples in my code, and the variable whose
unit can not be deduced always appears as an argument to Quantity.

Is this a flaw in Quantity or am I misusing this function somehow?

This is not a bug. Ay is actually unitless. When you define a value as Quantity[Ay, “Unit”]. Ay is a scalar BUT the whole expression is a Quantity with units. If you solve for Ay, its always scalar. If on the other hand, you define Ay = Quantity[AyScalar,“Unit”] then Ay is a Quantity object with units and if you solve for Ay, it will have the right units.

I your example, this will work in your notebook:

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

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.

Also, this works:

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

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.

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 :wink:

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.

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.

The problem is that you are mixing scalar and unit variables. In your example, ax is a scalar but you are integrating over a Quantity[]. For example, something like this works:

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]

Out[215]= {{Quantity[bxscalar, ("Meters")/("Seconds")^2] -> 
   Quantity[11/4, ("Meters")/("Seconds")^2]}}

In[216]:= Subscript[
\!\(\*OverscriptBox[\(v\), \(\[RightVector]\)]\), 0] + 
 Integrate[bvector, Quantity[t, "Seconds"]]

Out[216]= {Quantity[(2.8  + bxscalar t), ("Meters")/("Seconds")], 
 Quantity[(0.  + byscalar t), ("Meters")/("Seconds")]}

You can probably make a wrapper function to make this easier – I’ll think about it a bit.

Regards,

Neil

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!

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

Again, sorry for the JPEG. It is just that V4 is a “dead language” and this is my only readable options for showing how easy working with “home-rolled” units was in V4. I could easily do things in V4 that are next to impossible in V12. How could that be? Would it not be better to have Quantity as a “Package” that could be used or ignored, at the discretion of the programmer? Just a thought!

That is, would it not have been better for Wolfram to get a foundational concept like Units working completely, and flawlessly, before adding to that weakness new objects, entities, alphas, betas and bags of potatoes? :wink:

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 :wink:
Regards,

  • Joe

In a last ditch effort to illustrate the shortcomings in V12 and Quantity function,
I have attached a notebook below that codes a solution to a single problem
in Newtonian Mechanics.

I show three implementations, two in V12 and one in V4.

Only the V4 version works in a complete and correct sense.
Interestingly, the V4 version contains 1/2 the “keystrokes” to code
as the V12 version. Clearly was V4 superior to V12 in this regard.

I find the Quantity function in V12 prevents a complete solution.

This seems quite ironic, since the intention of the Quantity function was to
add “units” to Mathematica, but the actual implementation of the
Quantity function makes it impossible to correctly use
units in V12 in a complete, accurate and easy way. Instead, it merely doubles
the keystrokes necessary to express a problem, up the chances of syntax
errors, and prevents Solve/NSolve from correctly outputting units to
some variables.

JPEGS below are shown for typesetting and additional commentary.
All code is contained in the notebook, even the V4 (which of course
can not be “re-evalutated” but is included, with the original V4 output,
in CodeText cells).

The Quantity BUG in V12.nb (256 KB)