Unit Analysis
Unit consistency
By associating a unit with every relevant identifier in your model, you enable AIMMS to automatically verify whether all terms in the assignments and constraints of your model are unit consistent. When AIMMS detects unit inconsistencies, this may help you to solve conceptual problems in your model, which could otherwise have remained undetected for a long time.
…always in atomic units
With every derived unit or compound unit symbol, it is possible to associate a unique unit expression consisting of a constant scale factor and atomic units only. All assignments and definitions in AIMMS are interpreted as formulas expressed in terms of these atomic unit expressions, and unit consistency checking is based on this interpretation. While ignoring the constant scale factors, AIMMS will verify that the atomic unit expression for every term in either an assignment statement or a constraint is identical. If the resulting unit check identifies an inconsistency, an error or warning will be generated.
Example
Consider the identifiers a
, b
, and c
having units [m]
,
[km]
, and [10*m]
respectively, all with [m]
as their
corresponding associated atomic unit expression, and scale factors 1,
1000 and 10, respectively. Then the assignment
c := a + b ;
is unit consistent, because all terms share the same atomic unit
expression [m]
.
Constant expressions
If an expression on the right-hand side of an assignment consists of a
constant scalar term or a data expression (preceded by the keyword
DATA
), AIMMS will assume by default that such expressions have the
same unit as the identifier on the left-hand side. If the intended unit
of the right-hand side is different than the declared unit of the
identifier on the left, you should explicitly specify the appropriate
unit for this term, by locally overriding the unit as explained in
Locally Overriding Units.
Constant terms in expressions
On the other hand, if a non-constant expression contains a constant term, then AIMMS will make no assumption about the intended unit of the constant term. In fact, it is considered unitless. If a unit inconsistency occurs for that reason, you should explicitly add a unit to the constant term to resolve the inconsistency, as explained in Locally Overriding Units.
Example
Given parameters a
([m]
and b
([km]
), as well as a
1-dimensional parameter d(i)
with associated unit [m]
, the
following assignments illustrate the interpretation of constant numbers
by AIMMS.
a := 10; ! OK: constant number 10 interpreted as [m]
a := 10 [km]; ! OK: constant number 10 interpreted as [km]
d(i) := DATA { 1: 10, 2: 20 }; ! OK: all data interpreted as [m]
a := 10*b; ! OK: constant number 10 considered unitless
a := b + 10; ! ERROR: unit inconsistency, constant term 10 unitless
a := b + 10 [km]; ! OK: unit inconsistency resolved
Automatic unit checking on or off
By default, the global AIMMS option to perform automatic unit analysis is on and inconsistencies are detected. AIMMS will produce either warning messages or error messages (the former is the default). You can find the full details on all unit-related options in the help file that comes with your AIMMS system.
Automatic scale consistency
The assignment c := a + b
of the first example in this section is
unit consistent, but it does not appear to be scale consistent since
the units of a
, b
and c
have different scales. In AIMMS,
however, a unit consistent assignment is automatically scale consistent,
because AIMMS translates and stores all data in terms of the underlying
atomic unit expression. In the example, this implies that the use of the
values of a
, b
, and c
as well as the assignment are in the
atomic unit [m]
. Consequently, AIMMS can now directly execute the
assignment, and the scale consistency is automatically ensured. Of
course, any display of values of a
, b
and c
will be again
in terms of the units associated with these identifiers.
Advanced example…
This example illustrates a number of identifiers with compound unit
definitions. It is based on the SI units for weight, velocity and
energy, and uses the derived units ton
, km
, h
and MJ
.
Variable WeightOfItem {
IndexDomain : i;
Unit : ton;
}
Variable VelocityOfItem {
IndexDomain : i;
Unit : Velocity: km/h;
}
Variable KineticEnergyOfItem {
IndexDomain : i;
Unit : MJ;
Definition : 1/2 * WeightofItem(i) * VelocityOfItem(i)^2;
}
Any display of these variables will be in terms of ton
, km/h
and
MJ
, respectively, but internally AIMMS uses the units kg
,
m/s
and kg*m^2/s^2
for storage. The latter represent the
corresponding unique atomic unit expressions associated with weight,
velocity and energy.
…is unit consistent
As a consequence of specifying units, there will be an automatic
consistency check on the defined variable KineticEnergyOfItem(i)
.
AIMMS interprets the definition of KineticEnergyOfItem(i)
as a
formula expressed in terms of the atomic units. The relevant unit
components are:
[ton ] = 10^3 * [kg ]
,[km/h] = (1/3.6) * [m/s ]
, and[MJ ] = 10^6 * [kg*m^2/s^2]
.
The definition of KineticEnergyOfItem(i)
as expressed in terms of
atomic units is kg*(m/s)^2
, while its own unit in terms of atomic
units is kg*m^2/
s^2
. These two unit expressions are
consistent.
Beware of non-absolute units
If the unit conversion between a derived unit and its corresponding atomic unit not only consists of a scale factor, but also contains a constant term, such a derived unit is referred to as a non-absolute unit. If an arithmetic expression in your model refers to identifiers or constants expressed in a non-absolute unit, you should pay special attention to make sure that the result of the computation is what you intended. The following example makes the point.
Example
Consider the following quantity declaration.
Quantity Temperature {
BaseUnit : K;
Conversions : degC -> K : # -> # + 273.15;
}
Given this declaration, what is the result of the assignment
x := 1 [degC] + 2 [degC];
where x
is a scalar parameter with unit degC
? Following the
rules explained above-AIMMS stores all data and performs all
computations in terms of atomic units- AIMMS performs the following
computation internally
x := 274.15 [K] + 275.15 [K];
resulting in an assignment to x
of \(549.3\)
[K]
\({}= 276.15\) [degC]
, which is probably not the
intended answer. The key observation is that in an addition only one of
the operands should be expressed in a non-absolute unit. Similarly, in a
multiplication or division probably none of the operands should be
expressed in a non-absolute unit. The mistake in the above assignment is
that the second argument in fact should be a temperature difference
(e.g. between 3 [degC]
and 1 [degC]
), which precisely yields an
expression in terms of the corresponding absolute unit K
:
x := 1 [degC] + (3 [degC] - 1 [degC]); ! equals 274.15 [K] + 2 [K] = 3 [degC]
Using temperature differences is more common in assignments to
identifiers like LengthIncreasePerDegC
(expressed in [m/degC]
),
which probably takes the form of a difference quotient, as illustrated
below.
LengthIncreasePerDegC := (Length1 - Length0) / (Temperature1 - Temperature0);
Units and intrinsic functions
When you use an intrinsic AIMMS function (see Arithmetic Functions) inside an expression in your model, the unit associated with the corresponding function call will in general depend on its arguments. The unit relationship between the arguments and the result of the function falls into one of the following function categories.
Unitless functions, for which both the arguments and the result are dimensionless. Examples are:
exp
,log
,log10
,errorf
,atan
,cos
,sin
,tan
,degrees
,radians
,atanh
,cosh
,sinh
,tanh
, and the exponential operator with a non-constant exponent.Transparent functions that do not alter units. Examples are:
abs
,max
,min
,mod
,ceil
,floor
,precision
,round
, andtrunc
.Conversion functions that convert units in a predictable way. Examples are:
sqr
,sqrt
, and the exponential operator with a constant integer exponent.
Explicit units in expressions
In some exceptional cases, one or more terms in an expression may not be unit consistent with the other terms in the expression. To restore unit consistency, AIMMS allows you to explicitly specify a unit for the inconsistent term(s) as an emergency measure. The syntax for such unit overrides is explained in Locally Overriding Units. You should make sure, however, that these explicit unit overrides do not affect the scale consistency of the expression (see Locally Overriding Units).
Unit Analysis of Procedures and Functions
Unit analysis of procedures and functions
Once you have associated units of measurement with the global identifiers in your model, you will also need to associate units of measurement with the arguments, local identifiers and result values of procedures and functions. When you do so, you enable AIMMS to perform the common unit analysis on the statements in the bodies of all internal procedures and functions. For external procedures and functions, AIMMS cannot perform a unit analysis on the function and procedure bodies, but will use the assigned units for scaling purposes as explained in Unit-based Scaling.
Two procedure types
In general, one can distinguish two types of procedures and functions, namely
procedures and functions of a very specific nature, whose arguments and result values have associated units of measurement that are constant and known a priori, and
procedures and functions of a very general nature, whose arguments and result values can have any associated unit of measurement.
An example of the latter type is a function with a single one-dimensional argument to compute the average of all values contained in its argument. For such a function, the specific units associated with the argument and the result values are not known a priori, but it is known that they must be equal.
Express units in local unit parameters
To let you declare procedure and functions of the second type, AIMMS allows you to express the units of measurement of its arguments and the result values in terms of unit parameters (see also Unit-valued Parameters) declared locally within the procedure or function. At runtime, AIMMS will dynamically determine the value of the unit parameter, based on the actual arguments passed to the procedure or function. In addition, AIMMS will verify that the unit of a function value is commensurate with the remainder of the statement or expression from which it was called.
Example
The function MyAverage
in this example computes the average of a
general one-dimensional identifier. It combines AIMMS’ ability to define
arguments over local sets (see Internal Procedures), with a unit
expressed in term of a local unit parameter. Its declaration is given by
Function MyAverage {
Arguments : (Ident);
Unit : LocalUnit;
Body : {
MyAverage := sum(i, Ident(i)) / Card(LocalSet)
}
}
The single argument Ident(i)
of the function MyAverage
is
defined by
Parameter Ident {
IndexDomain : i;
Unit : LocalUnit;
}
Set LocalSet {
Index : i;
}
UnitParameter LocalUnit;
Note that Ident(i)
is defined over a local set LocalSet
and that
its unit is expressed in terms of a local unit parameter LocalUnit
,
both of which are determined at runtime. Because the unit of the
function MyAverage
itself is also equal to LocalUnit
, the
assignment in the body of MyAverage
is unit consistent.