Skip to content

International System of Quantities (ISQ): Part 6 - Challenges

This article might be the last one from our series. This time, we will discuss the challenges and issues with modeling of the ISQ in software.

Articles from this series

Ambiguity

Some quantity names are ambiguous. It is not a problem of ISQ but of the English language and the way we communicate things. When I say: "Every width is a length, but not every length is a width" most people understand this right away. However, the same people trying to model our 3D box problem try to do it as follows:

class Box {
  quantity<isq::length[m]> length_;
  quantity<isq::width[m]> width_;
  quantity<isq::height[m]> height_;
public:
  // ...
};

This looks correct at first sight. Only when we think about the sentence mentioned above will we realize that this implementation has a problem. We intended to specify three orthogonal dimensions of the box, each of which will be a strong quantity that is not convertible to others. But we've failed.

When we look at the tree of quantities of length we immediately see that both width and height are special lengths so they are convertible to it.

To implement our task correctly, we had to define and use a new quantity of kind length:

inline constexpr struct horizontal_length final : quantity_spec<isq::length> {} horizontal_length;

We do not propose adding horizontal length to ISO 80000-3. There are probably other similar cases as well, but so far, this was the most common and obvious one we've encountered.

No common quantities

ISO 80000-1:2009 explicitly states:

Quote

Two or more quantities cannot be added or subtracted unless they belong to the same category of mutually comparable quantities.

This means that we should be able to add and subtract any quantities as long as they belong to the same kind. However, ISO/IEC documents do not provide any rules or even hints about what should be the result of such operations.

If it is possible to add radius and distance, then what quantity should be provided in return? Undoubtedly, the resulting quantity type can't be the same as any of the arguments. It is not a radius or distance. It is some closer unspecified length, though.

Info

Finding the correct solution took us many months of experimentation and implementation. Based on the hierarchy tree of quantities, we can define conversion rules and what a common quantity should be.

Lack of consistency

The documents of ISO/IEC 80000 are not 100% consistent, and programming languages do not like inconsistencies.

For example:

  • time is mentioned as a base quantity of ISQ in ISO 80000-1 chapter 4.5.
  • ISO 80000-3 "Space and time", does not define a quantity of time. It provides a duration quantity (item 3-9) with symbol t, and states in the Remarks section:

    Quote

    Duration is often just called time.

  • Other parts (e.g., IEC 80000-6 "Electromagnetism") often say:

    Quote

    ... t is time (ISO 80000-3)

To be consistent, ISO/IEC should either:

  • change ISO 80000-1 chapter 4.5 and all references in other parts to use duration (unlikely),
  • or add time as an alias name to duration in the definition 3-9 of ISO 80000-3.

Lack of definitions

ISQ defines derived quantities in terms of other quantities provided in the series. However, some definitions mention quantities that are not defined in the ISQ at all.

For example, weight is defined as \(F_\textsf{g} = m\;g\), where \(m\) is the mass of the body (item 4-1 of ISO 80000-4 "Mechanics"), and \(g\) is the local acceleration of free fall (ISO 80000-3).

The problem here is that ISO 80000-3 never defines a quantity with a symbol \(g\) or named as a local acceleration of free fall. The closest one we have is acceleration (item 3-11) with a symbol \(a\).

Info

To have a proper definition of weight in mp-units that is not defined in terms of just any kind of acceleration, we have added isq::acceleration_of_free_fall in our definitions as an extension to the original ISQ set of quantities.

Not engineering-friendly

Many quantities have proper physical definitions, but they are sometimes not engineering-friendly.

For example, velocity is defined as a rate of change of position vector \(v = \frac{\textsf{d}r}{\textsf{d}t}\), where \(r\) denotes the position vector (item 3‑1.10) and \(t\) the duration (item 3‑9).

Next, a speed quantity is defined as the magnitude of velocity. Despite being physically correct, requiring every speed to be derived from the vector quantity of velocity in software would be inconvenient. If this was the only case, people would always need to use vector representations of position vectors to talk about speeds, which differs from what we do in practice. In practice, we divide any kind of length by time to get some kind of speed.

ISO 80000-3 provides length, height, distance and other quantities of kind length that when divided by duration can serve really well to calculate speed.

Info

This is why in mp-units, we decided to divert from the official definition of speed and define it as:

inline constexpr struct speed : quantity_spec<speed, length / time> {} speed;

This allows us to create a quantity of kind speed from any quantity of length divided by time.

Additionally, it is essential to note that for the needs of our library, defining velocity as position_vector / duration would be wrong. We miss the delta part here. Even though it is not mentioned in ISO 80000-3, the delta of position vectors is actually a displacement. This is why our velocity is defined as:

inline constexpr struct velocity : quantity_spec<speed, displacement / duration> {} velocity;

Please also note that velocity is defined as a more specialized quantity of speed.

Affine space agnostic

The affine space is a powerful abstraction, allowing us to model some problems safer or more accurately. It has two types of entities:

  • point - a position specified with coordinate values (e.g., location, address, etc.),
  • displacement vector - the difference between two points (e.g., shift, offset, displacement, duration, etc.).

Vectors support all the arithmetics operations, but points have some limitations. It is not possible to:

  • add two points,
  • subtract a point from a vector,
  • multiply nor divide points with anything else.

ISO/IEC series does not acknowledge this abstraction even though it would be really useful in some cases. Let's discuss the following two examples.

What does it mean to add two altitudes? It is not meaningful. On the other hand, subtracting those should not result in an altitude, but in a quantity of height. Adding or subtracting height to/from altitude results in altitude. Subtracting altitude from height is meaningless again. Those quantities clearly model affine space. Maybe this is why ISQ defines them as one quantity type height/depth/altitude?

What does it mean to add two position vectors? It is not meaningful again. However, subtracting those results in a displacement as we noted in the previous chapter. Adding or subtracting displacement to/from position vector results in another position vector, and subtracting position vector from displacement does not have physical sense. Again, those quantities perfectly model affine space. However, this time, those are defined as separate and independent quantities (i.e., displacement is not modeled as delta position vector or position vector is not modeled as a displacement from the origin of a coordinate system).

Info

Currently, mp-units does not enforce the affine space behavior for such quantities. Today, subtracting two altitudes result in an altitude and subtracting two position vectors result in a position vector. However, we plan to support automatic conversion to a proper quantity type on subtraction and addition shortly.

Non-negative quantities

Some quantities in the ISQ are defined as non-negative. This is a really interesting property that may be checked at runtime to increase safety. However, the number of such quantities is minimal. From a few hundred quantities provided by the ISO/IEC series, only the following have this property mentioned explicitly:

  • width/breadth,
  • thickness,
  • diameter,
  • radius.

If height was defined separately from altitude, it could probably also join this group.

Let's think a bit more about this. What does it mean that a quantity is non-negative? Indeed, it is hard to imagine something of a negative width or radius. However, if we subtract two widths, the second one may be larger. This will result in a negative quantity of width, violating our precondition. So, is it non-negative or not?

Again, we have to talk about the affine space abstractions. Every empirical measurement can be expressed as a point. Such points for some quantities may be non-negative indeed.

Non-negative quantities do not end on the ones provided above. For example, speed is a good example here as well. In general, all magnitudes of vector quantities will also have this property.

When subtracting two points, we end up with a delta/displacement type, which may be negative even for quantities listed as non-negative in the ISQ. As stated in the previous chapter, having affine space abstractions acknowledged in ISQ would greatly help here.

Lack of quantity recipes

Definition of many derived quantities provides their recipes in the form of quantity equations (e.g., weight equation in the previous chapter). However, some of them do not. Instead, they often provide a very generic description.

For example, force is defined as:

Quote

vector (ISO 80000-2) quantity describing interaction between bodies or particles.

This is not helpful for programming languages that like explicit definitions. Different vendors may interpret the above differently, which will result in different implementations that will not be compatible with each other.

As the derived quantity of force has to be a vector quantity, it has to be defined in terms of at least one other vector quantity. We have a few to choose from:

  • displacement (\(\Delta{r}\)),
  • velocity (\(v\)),
  • acceleration (\(a\)).

It is not stated explicitly in ISQ which one of those should be used and how.

Info

In mp-units we decided to define force as \(F = m\;a\).

Lack of generic quantities and name conflicts

In the previous chapter, we complained about some definitions needing to be more complex or generic. On the other hand, we also lack some generic quantities in ISQ that could serve as a root for a quantity hierarchy tree.

For example:

  • ISO 80000-4 "Mechanics" defines power <mechanics> as \(P = F\;v\) (scalar product of force \(F\) (item 4-9.1) acting to a body and its velocity \(v\) (ISO 80000-3)),
  • ISO 80000-6 "Electromagnetism" defines power as \(p = u\;i\) (scalar quantity given by the product of instantaneous voltage \(u\) (item 6-11.3) and instantaneous electric current \(i\) (item 6-1)).

First, the above definitions have somehow conflicting names which makes it hard for the programming languages to name them consistently by different vendors.

Info

In mp-units, we chose mechanical_power and electromagnetism_power for those.

Second, we do not have any other more generic definition of power to put above those in the tree. Not having it makes it hard to answer what should be the result of:

quantity q = isq::mechanical_power(42 * W) + isq::electromagnetism_power(60 * W);

Info

To solve the above problem, we have added isq::power in mp-units, that has a really generic definition of:

inline constexpr struct power : quantity_spec<mass* pow<2>(length) / pow<3>(time)> {} power;

Invalid definitions order

Energy is defined a bit better than power, but still not without issues.

The first time ISQ mentions energy is in the ISO 80000-4 "Mechanics". It defines potential energy, kinetic energy, and a mechanical energy as the sum of the first two. Right after that a mechanical work/work is defined.

Then ISO 80000-5 "Thermodynamics" defines energy <thermodynamics> as:

Quote

ability of a system to do work (ISO 80000-4).

Next, internal energy/thermodynamic energy is defined in terms of the change of heat.

From the above, it seems that what is called energy <thermodynamics> should actually be the root of our tree and probably be provided in Part 4 before the mechanical energy is defined.

Hierarchies of derived quantities

Derived quantities of the same kind are often independently defined in the ISQ. The ISO/IEC 80000 series often does not suggest any hierarchy between those. Even more, it states:

ISO/IEC Guide 99

The division of ‘quantity’ according to ‘kind of quantity’ is, to some extent, arbitrary.

Because of this, it is unknown or ambiguous how to form a hierarchy tree for such quantities.

To get some sense of the complexity here, let's look again at our tree of quantities of a kind energy:

flowchart TD
    energy["<b>energy</b><br><i>(mass * length<sup>2</sup> / time<sup>2</sup>)</i><br>[J]"]
    energy --- mechanical_energy["<b>mechanical_energy</b>"]
    mechanical_energy --- potential_energy["<b>potential_energy</b>"]
    mechanical_energy --- kinetic_energy["<b>kinetic_energy</b>"]
    energy --- enthalpy["<b>enthalpy</b>"]
    enthalpy --- internal_energy["<b>internal_energy</b> / <b>thermodynamic_energy</b>"]
    internal_energy --- Helmholtz_energy["<b>Helmholtz_energy</b> / <b>Helmholtz_function</b>"]
    enthalpy --- Gibbs_energy["<b>Gibbs_energy</b> / <b>Gibbs_function</b>"]
    energy --- active_energy["<b>active_energy</b>"]

Not being exact means that every vendor may implement it differently. This will result in:

  • different convertibility rules among quantities:

    static_assert(implicitly_convertible(isq::potential_energy, isq::mechanical_energy));
    static_assert(explicitly_convertible(isq::mechanical_energy, isq::potential_energy));
    
  • different common quantities resulting from the arithmetics on various quantities of the same kind:

    static_assert((isq::potential_energy(1 * J) + isq::kinetic_energy(1 * J)).quantity_spec == isq::mechanical_energy);
    

It would be great if ISQ could provide specific division of quantities into kinds and more information about the position of each quantity within the hierarchy of quantities of the same kind.

Important

We can try to do this by ourselves, but it is tough. Probably no one, for sure we are not, is an expert in all the fields of ISO/IEC 80000 applicability.

We need the help of subject matter experts who will help us build those trees for their domains and then verify that everything works as expected.

The same or a different kind?

Some quantities are more complicated than others. For example, power has:

  • scalar quantities expressed in:
    • W (watts) (e.g., mechanical power, active power),
    • VA (volt-ampere) (e.g., apparent power),
    • var (e.g., reactive power),
  • complex quantities expressed in VA (volt-ampere) (e.g., complex power).

How should we model this? Maybe those should be two or three independent trees of quantities, each having its own unit?

flowchart TD
    power["<b>power</b><br><i>(mass * length<sup>2</sup> / time<sup>3</sup>)</i><br>[W]"]
    power --- mechanical_power["<b>mechanical_power</b><br><i>(scalar_product(force, velocity))</i>"]
    power --- electromagnetism_power["<b>electromagnetism_power</b> | <b>instantaneous_power</b><br><i>(instantaneous_voltage * instantaneous_electric_current)</i>"]
    power --- active_power["<b>active_power</b><br><i>(1 / period * instantaneous_power * time)<br>(re(complex_power))</i>"]

    nonactive_power["<b>nonactive_power</b><br><i>(mass * length<sup>2</sup> / time<sup>3</sup>)</i><br>[VA]"]
    nonactive_power --- reactive_power["<b>reactive_power</b><br><i>(im(complex_power))</i><br>[var]"]

    complex_power["<b>complex_power</b><br>{complex}<br><i>(voltage_phasor * electric_current_phasor)<br>(active_power + j * reactive_power)</i><br>[VA]"]
    complex_power --- apparent_power["<b>apparent_power</b><br><i>(voltage * electric_current)<br>(mod(complex_power))</i>"]

This will mean that we will not be able to add or compare active power, reactive power, and apparent power, which probably makes a lot of sense. However, it also means that the following will fail to compile:

quantity apparent = isq::apparent_power(100 * VA);
quantity active = isq::active_power(60 * W);
quantity<isq::nonactive_power[VA]> q = sqrt(pow<2>(apparent) - pow<2>(active)); // Compile-time error

Also the following will not work:

quantity active = isq::active_power(60 * W);
quantity reactive = isq::reactive_power(40 * var);
quantity<isq::apparent_power[VA]> q = sqrt(pow<2>(active) + pow<2>(reactive)); // Compile-time error

If we want the above to work maybe we need to implement the tree as follows?

flowchart TD
    power["<b>power</b><br><i>(mass * length<sup>2</sup> / time<sup>3</sup>)</i><br>[W]"]
    power --- mechanical_power["<b>mechanical_power</b><br><i>(scalar_product(force, velocity))</i>"]
    power --- electromagnetism_power["<b>electromagnetism_power</b> | <b>instantaneous_power</b><br><i>(instantaneous_voltage * instantaneous_electric_current)</i>"]
    power --- apparent_power["<b>apparent_power</b><br><i>(voltage * electric_current)<br>(mod(complex_power))</i><br>[VA]"]
    apparent_power --- active_power["<b>active_power</b><br><i>(1 / period * instantaneous_power * time)<br>(re(complex_power))</i>"]
    apparent_power --- nonactive_power["<b>nonactive_power</b><br><i>(sqrt(apparent_power<sup>2</sup> - active_power<sup>2</sup>))</i><br>"]
    nonactive_power --- reactive_power["<b>reactive_power</b><br><i>(im(complex_power))</i><br>[var]"]
    apparent_power --- complex_power["<b>complex_power</b><br>{complex}<br><i>(voltage_phasor * electric_current_phasor)<br>(active_power + j * reactive_power)</i>"]

However, the above allows direct addition and comparison of active power and nonactive power, and also will not complain if someone will try to use watt (W) as a unit of apparent power or reactive power.

Again, ISQ does not provide a direct answer here.

More base quantities?

Is ISQ really based on only seven base quantities? Let's look at the definition of traffic intensity in IEC 80000-13 "Information science and technology":

Quote

number of simultaneously busy resources in a particular pool of resources.

It looks like a definition of a specialized dimensionless quantity or, more correctly, a quantity of dimension one. This would not be the only such case. Even in the same Part 13, we can find quantities like storage capacity with a similar property.

Only when we look closer do we start to see differences. All dimensionless quantities, even if they have their own dedicated units, can also be measured in a unit of one (1). This is true for storage capacity (also measured in bits), angular measure (also measured in radians), _solid angular measure (also measured in steradians), and more.

However, traffic intensity can only be measured in erlangs (E), not in a unit one (1). Does it mean that it is a "hidden" 8-th base quantity in ISQ? If so, should it have its own dimension as well?

Angular quantities are another interesting case here. Scientists have written petitions and papers for years to make them an additional dimension in ISQ and SI. More about this can be found in our documentation's Strong Angular System chapter.

Summary

ISQ is tremendous and solves many problems we had in modeling various subjects for years in software. As a result, we have more powerful tools in our hands that allow us to deliver safer products.

Unfortunately, ISQ, contrarily to SI, is not widely recognized, and no libraries besides mp-units model it in any programming language. Keeping it behind a paywall does not help either. We hope that posts from this series will spread in the community, raise awareness of ISQ and its benefits, and encourage authors of other libraries to implement it in their products.

Despite all the benefits, it is essential to realize that ISQ has many problems. International standards should be specified in such a way that there is no room for ambiguity in their interpretation by different parties trying to use them. As described above, this is not the case here.

ISQ is not ready to be unambiguously modeled in software by various vendors. Here are the most important problems to solve to allow this:

  1. ISQ needs to define basic operations on quantities:

- what the result of addition and subtraction should be when arguments differ,     - convertibility rules.

  1. The exact quantity equation recipe needs to be included for many derived quantities.
  2. Many ISQ quantities do not provide their exact relation versus other quantities of the same kind (no strict hierarchy).
  3. Some missing quantities need to be included. Others would benefit from corrected names.

Additionally:

  • extending ISQ with affine space abstractions,
  • specifying more quantities as non-negative,
  • adding more base quantities (i.e., angle)

could improve the safety of our programs and products that people depend on with their lives on a daily basis.

I hope you enjoyed following this series and learned more about the International System of Quantities. Please try it out in your domain and share feedback with us. We always love to hear about the projects in which our library is being used and about use cases it helps address.

Comments