ModelicaSpecification icon indicating copy to clipboard operation
ModelicaSpecification copied to clipboard

Need built-in function for n'th root

Open henrikt-ma opened this issue 3 years ago • 15 comments

The semantics of a ^ b with separation of Real and Integer exponents is a good start for also specifying unit semantics of exponentiation. However, for the inverse operation of taking roots, the language only has sqrt to offer.

I suggest that we introduce the nthRoot function now as I can see the need coming when we get to standardization of unit checking.

Here's a sketch of semantics to show in some more detail what this is all about:

  • nthRoot(a, b) takes a Real a, an Integer b, and produces a Real result.
  • It is an error for b to be zero.
  • For b < 0, the result is defined as 1 / nthRoot(a, -b)
  • If b is even, it is required that a >= 0, and the result is the y >= 0 such that y ^ b = a.
  • If b is odd, and the result is the y such that y ^ b = a (y will have same sign as a).

If the idea is of interest, I suggest that further discussions of detailed semantics should be made in a PR rather than in this issue.

henrikt-ma avatar Apr 05 '23 07:04 henrikt-ma

However, Modelica is equation-based! And in equations we can generally replace nthRoot(x, n) = a; by a^n = x; and tools can then symbolically solve that - which involves the nthRoot in most cases.

Thus I'm not convinced that we need this.

HansOlsson avatar Apr 05 '23 09:04 HansOlsson

Some reasons against relying on equations:

  • The equation rewrite is likely to blur the purpose of the code when eliminating an n'th root in the middle of a bigger expression/equation.
  • The equation requires an auxiliary variable to be introduced, and it may not even be possible to express the unit of that variable due to rational exponents in the units.
  • The equation solution can't be used to define a nthRoot function in user code.
  • The equation solution doesn't give any guarantees on which root to get.

henrikt-ma avatar Apr 05 '23 11:04 henrikt-ma

Phone meeting: Better name! Maple has: root(x, n) (risk of ambiguity with user models). surd in Wolfram (hard to understand). Thus nthRoot has some advantages compared to these.

HansOlsson avatar Apr 12 '23 14:04 HansOlsson

Would be good with more convincing examples (might be related to unit-checking). Should fail on even roots of negative numbers.

HansOlsson avatar Apr 12 '23 14:04 HansOlsson

After some investigation I found that surd isn't the right term for this, as it seems √8 is a surd - but ∛8 isn't a surd; basically it refers to irrational numbers formed using roots; which is important in symbolic math packages (as they are normally kept in that form).

HansOlsson avatar Apr 13 '23 06:04 HansOlsson

Would be good with more convincing examples (might be related to unit-checking).

How about a MultiBody ball parameterized by mass and density?

henrikt-ma avatar Nov 06 '23 14:11 henrikt-ma

In case we need more name alternatives: reciprocalPower. (I still prefer nthRoot, just trying to get some progress here.)

henrikt-ma avatar Nov 06 '23 14:11 henrikt-ma

Here are some more examples of what the (essentially same) function is called in other software:

To summarize, I think nthRoot would be a rather well recognized name from start.

henrikt-ma avatar Nov 07 '23 07:11 henrikt-ma

To summarize, I think nthRoot would be a rather well recognized name from start.

And we already have some operators using that style (lower camel case) for noEvent, ticksInState etc.

In some world combing it with sqrt by having root(x, n=2) would have made sense, but based on the current spec and other languages it is too distracting without any major benefit.

How about a MultiBody ball parameterized by mass and density?

Computing cube-roots in general seems relevant, in particular since the obvious x^(1/3) will fail for negative numbers. Following C (and C++) and merely adding cbrtl for cube roots would be less clear.

However, in the specific case I would normally write something like parameter Real mass=...;parameter Real density=...;protected parameter Real r(fixed=false);parameter Real computedMass=4*pi*density*r^3/3;initial equation mass=computedMass; since that formula is somewhat well-known.

Understanding that r=nthRoot(0.75*mass/(density*pi), 3) is the same requires some comments.

(BTW: I don't think we need to consider other fractional powers like x^(2/3) - both since it is less common, and also because nthRoot(x,3)^2 should just work. However, it is still relevant for units.)

HansOlsson avatar Nov 17 '23 15:11 HansOlsson

(BTW: I don't think we need to consider other fractional powers like x^(2/3) - both since it is less common, and also because nthRoot(x,3)^2 should just work. However, it is still relevant for units.)

Yes, and a good reason to avoid an operator like pow(x, num = 3, den = 2) is that one would be tempted to also overload it with pow(x, 1.5), but the overloaded semantics are actually so unrelated that it is just confusing to use the same overloaded operator. Also, rationalPow(x, num = 1, den = 3) seems like a cumbersome way to express nthRoot(x, 3). Finally, I find it more natural to specify semantics for negative x in nthRoot(x, 3) than for rationalPow(x, num = 1, den = 3).

henrikt-ma avatar Nov 22 '23 07:11 henrikt-ma

Looking through MSL I actually noticed that x^(2/3) is currently used - in Modelica.Fluid.Vessels.ClosedVolume to compute the area based on volume. (And in Modelica.Media.IdealGases.Common.Functions.dynamicViscosityLowPressure for something)

HansOlsson avatar Mar 20 '24 08:03 HansOlsson

Good! Are we ready to go ahead with nthRoot then?

henrikt-ma avatar Mar 21 '24 13:03 henrikt-ma

Why does this need to be a built-in function? Would it not be better to put it in the standard library?

MarkusOlssonModelon avatar Mar 21 '24 13:03 MarkusOlssonModelon

It is not possible to make a user-defined function with special unit semantics for constant Integer arguments.

henrikt-ma avatar Mar 21 '24 14:03 henrikt-ma

Phone meeting: Agreement to go with nthRoot.

HansOlsson avatar Mar 26 '24 14:03 HansOlsson