Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modelica.Constants.Inf should be consistent with the Modelica Language Specification #4503

Open
casella opened this issue Nov 12, 2024 · 6 comments
Assignees
Labels
discussion Discussion issue that it not necessarily related to a concrete bug or feature specification Issue (also) addresses the Modelica language specification
Milestone

Comments

@casella
Copy link
Contributor

casella commented Nov 12, 2024

Follow-up of #4479.

I scanned the current MLS 3.6 for "inf" (relative to Real variables) and I found two places where it is mentioned. The first is the definition of the Real type, Section 4.8.1:

 type Real // Note: Defined with Modelica syntax although predefined
  RealType ⟨value⟩; // Not an attribute; only accessed without dot-notation
  parameter StringType quantity    = "";
  parameter StringType unit        = "" "Unit used in equations";
  parameter StringType displayUnit = "" "Default display unit";
  parameter RealType min = -Inf, max = +Inf; // Inf denotes a large value
  parameter RealType start;            // Initial value
  parameter BooleanType fixed = true,  // default for parameter/constant;
                              = false; // default for other variables
  parameter RealType nominal;            // Nominal value
  parameter BooleanType unbounded = false; // For error control
  parameter StateSelect stateSelect = StateSelect.default;
equation
  assert(min <= ⟨value⟩ and ⟨value⟩ <= max, "Variable value out of limit");
end Real; 

In the definition of the defaults for RealType.min and RealType.max, Inf "denotes a large value". This definition is a bit vague, but one could reasonably argue that this definition is some kind of meta-Modelica or pseudo-Modelica code, since the Real type is built-in, so a compiler developer could interpret the assert statement in the following way

if max is left to the default, don't check ⟨value⟩ <= max
if min is left to the default, don't check ⟨value⟩ >= min

which is, BTW, the most efficient way to handle that. So, there is really no need to have a numerical representation of Inf to support the definition of Real type. In fact, the elephant in the room here is that there is actually no definition of what RealType actually means. But that is not an issue for MAP-Lib to discuss.

The second is in Section 10.3.4.1 (reduction expressions). The caption for Table 10.3 reads:

Table 10.3: Reduction expressions with iterators. (The least and greatest values of Real are available as -Modelica.Constants.inf and Modelica.Constants.inf, respectively.)

In this case, the MLS mentions explicitly -Modelica.Constants.inf and Modelica.Constants.inf as the least and greatest value of Real (whatever Real means). So, unless we change the MLS, it is not entirely up to MAP-Lib to decide what these constants actually mean - they should be consistent with this definition. Note the interesting similarity (but not the identity) between the default min and max attributes of Real and the default value for empty min and max reductions.

Now, consider the following MWE, describing the deformation of a MEMS device, that has a certain stiffness k within certain bounds, but becomes s times stiffer outside those bounds. The model is implicit and requires some iterations to figure out the displacement, given the force amplitude.

model MWE
  Real x(nominal = 1e-6);
  Real F;
  parameter Real b[:] = fill(0.0, 0) "Array of bounds for x; leave empty for no bounds";
  parameter Real s = 100 "Stiffness parameter";
  parameter Real k = 1e-5 "Linear stiffness";
  parameter Real F_0 = 1e-4 "Force amplitude";
  parameter Real omega = 1e4 "Force angular frequency";
equation
  F = F_0*sin(omega*time);
  F = k*(if x > max(b) then max(b)+ s*(x - max(b))
            else if x < min(b) then min(b) + s*(x - min(b))
            else x);
end MWE;

Suppose now that the tool is using the nominal attribute for scaling purposes, as suggested by MLS 4.8.1, so it generates two scaled zero-crossing functions

zc1 = (x - max(b))/x.nominal
zc2 = (min(b) - x)/x.nominal

for improved precision in determining the exact point in time when the event should be triggered.

With the previous definition Modelica.Constant.inf = 1e60 this would work fine, assuming the code is eventually compiled into double-precision IEEE 754-compliant executable code. With the new definition of Modelica.Constant.inf = 1.7976931348623157E+308 there would be overflow and the behaviour would be undefined.

However, the new definition of Modelica.Constants.inf in #4042 is "Maximum representable finite floating-point number", which is finally assigned to ModelicaServices.Machine.inf also defined as "Maximum representable finite floating-point number". The actual value provided by ModelicaServices.Machine.inf is by definition "machine-dependent", where I understand that "machine" means the combination of the tool(s) that generate(s) the code and the hw architecture on which it runs. There is no explicit reference to IEEE 745 MAXVAL in these definitions.

So, when using Modelica.Constants.inf, a user of the MSL should not assume that it will get any specific numerical value. That will be an internal decision of the tool, based on whatever code generation methods and target architectures are selected. The only expectation of a MSL user is that eventually the tool should handle that value properly in all meaningful contexts.

Do I understand this correctly and do we have an agreement on that?

@HansOlsson, @dzimmer, @henrikt-ma

@casella casella added the discussion Discussion issue that it not necessarily related to a concrete bug or feature label Nov 12, 2024
@casella casella added this to the MSL4.1.0 milestone Nov 12, 2024
@casella casella self-assigned this Nov 12, 2024
@HansOlsson
Copy link
Contributor

No, that only indicates that tools shouldn't use nominal in such a bad way.

The goal with nominal is to get values closer to "1" - if that introduces an overflow, it's clearly not working and the code should be rewritten - without updating the models.

@henrikt-ma
Copy link
Contributor

I largely agree.

Regarding the MWE, I would say that it is the users responsibility to think carefully about how the model should work when there are no bounds. In this case, I think there is a fundamental mistake in the equation which does not have to do with exactly how big "a very large number" is: when there are no bounds one wants to always end up in the F = k * x case, but what happens here is completely different due to the often surprising fact that we can have max(b) < min(b). The "trick" of writing x > max(b) to compare against the optional upper bound is simply no good.

I also agree that it is not good that the specification speaks of some pseudo code Inf in one place, and Modelica.Constants.inf in another. The two should be related to each other, so that it is clear that the default requirement on a RealType value x is that both x and -x shall be representable on the machine.

@HansOlsson
Copy link
Contributor

Oh, I didn't realize that max(b) with an empty array was used for bounds in that way, I agree that it is very bad style and I will try to unsee it.

I think that the reason the specification used both pseudo code used Inf and Modelica.Constant.inf is left-over from the time that Modelica.Constant.inf was just sort of a placeholder. Now that it has been corrected we can use the same definition or value in both places.

@henrikt-ma
Copy link
Contributor

I would rather go in the other direction and make the MLS more self-contained instead of becoming even more dependent upon the MSL.

@HansOlsson
Copy link
Contributor

I would rather go in the other direction and make the MLS more self-contained instead of becoming even more dependent upon the MSL.

I see that one of the options I gave: Use the same definition for both, i.e., sort of "inline the Modelica.Constants.inf" definition in the specification in those two places (or once and referring to the other). That makes it consistent without having a dependency.

@henrikt-ma
Copy link
Contributor

Good. If we do that, then it might also be a good idea to relate the Modelica.Constants.inf to the default max of RealType in the specification, to keep the connection but in the other direction.

@AHaumer AHaumer changed the title Modelica.Constants.Inf should be consistent with the MLS Modelica.Constants.Inf should be consistent with the MSL Nov 12, 2024
@beutlich beutlich added the specification Issue (also) addresses the Modelica language specification label Nov 16, 2024
@beutlich beutlich changed the title Modelica.Constants.Inf should be consistent with the MSL Modelica.Constants.Inf should be consistent with the Modelica Language Specification Nov 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
discussion Discussion issue that it not necessarily related to a concrete bug or feature specification Issue (also) addresses the Modelica language specification
Projects
None yet
Development

No branches or pull requests

4 participants