DJUNITS is a set of Java classes that make life easy for scientific software writers by catching many common errors at compile time.
DJUNITS was developed at the Delft University of Technology as part of the Open Traffic Simulator project (started in 2014).
In August 2015 it became obvious that the units and values classes developed for the Open Traffic Simulator were sufficiently mature to be used in other projects.
The main authors/contributors of the DJUNITS project are Alexander Verbraeck and Peter Knoppers.
Values in DJUNITS are either Absolute or Relative.
An Absolute value is a value measured from a standard reference. For geographical directions North and East should be Absolute values. Adding two absolute values together makes no sense. Subtracting one absolute value from another does make sense (and results in a Relative value). Subtracting East from North should result in an angle of ±90° or ±π/2 (depending on the unit used to express the result). This means that an absolute unit needs to have a description of that reference to make it useful. Scalars subtracted from each other need to know their reference to be able to carry out the subtraction.
A Relative value expresses the difference between two (Absolute or Relative) values. The angle in the example above is a Relative value. Relative values can be added together and subtracted from each other (resulting in Relative values). Adding a Relative value to an Absolute value result in an Absolute value. Subtracting a Relative value from an Absolute value also results in an Absolute value.
In the geographical example, directions are Absolute and angles are Relative. Similarly, when applied to lengths, positions are Absolute and distances are Relative.
Generally, if adding a value to itself makes no sense, the value is Absolute; otherwise it is Relative.
Operation |
Right operand → ↓ Left operand |
Absolute |
Relative |
---|---|---|---|
+ (plus) | Absolute | Not allowed | Absolute |
Relative | Absolute | Relative | |
- (minus) | Absolute | Relative | Absolute |
Relative | Not allowed | Relative | |
* (times) | Absolute | Not allowed | Not allowed |
Relative | Not allowed | Relative | |
/ (divide) | Absolute | Not allowed | Not allowed |
Relative | Not allowed | Relative |
All quantities make sense as Relative values. The only quantities that make sense as Absolute values are listed in the table below.
Quantity | Absolute interpretation | Absolute class | Unit | Relative interpretation | Relative class | Unit |
---|---|---|---|---|---|---|
Length | Position | Position | PositionUnit | Distance | Length | LengthUnit |
Angle | Direction or Slope | Direction | DirectionUnit | Angle (direction/slope difference) | Angle | AngleUnit |
Temperature | Temperature | AbsoluteTemperature | AbsoluteTemperatureUnit | Temperature difference | Temperature | TemperatureUnit |
Time | Time (instant) | Time | TimeUnit | Duration | Duration | DurationUnit |
The use of Absolute in relation to Temperature here may be confusing. In the table above, an absolute temperature is not necessarily expressed in Kelvin. E.g. the melting temperature of water at normal atmospheric pressure is an Absolute value (it does not make sense to add this temperature to itself). In DJUNITS this value would internally be stored as 273.15K, but on display it may be converted (back) to Celsius and displayed as 0°C. A temperature difference of 5K (Kelvin) is a Relative, even though Kelvin is often called absolute temperature.
Dimensionless is a special relative unit in DJUNITS that has a unit of 1.
Speed speed1 = new Speed(20, SpeedUnit.METER_PER_SECOND); Speed speed2 = new Speed(10, SpeedUnit.MILE_PER_HOUR); Speed diff = speed1.minus(speed2); double d = diff.getInUnit(SpeedUnit.KNOT); double si = diff.si; System.out.println(d + " knot"); System.out.println(si + " m/s (si)"); System.out.println(diff); System.out.println(diff.toString(SpeedUnit.KM_PER_HOUR, false, true));This would create the following output:
30.187127429805614 knot 15.5296 m/s (si) 15.5296000m/s 55.9065600km/hWhen a class implements the interface UNITS (org.djunits.unit.UNITS), all defined units are available without the prefix XxxUnit. So, in that case a Length can be defined as new Length(12.0, METER).
Multiplying or dividing physical quantities produces a result in a different physical unit. There is no general way (we could think of) where the Java compiler can check the type of the result in the general case. Therefore DJUNITS has an extensive list of built-in multiplication and division operations with known result type. For instance
Speed speed = new Speed(50, SpeedUnit.KM_PER_HOUR); Duration duration = new Duration(0.5, DurationUnit.HOUR); Length distance = speed.multiplyBy(duration); Acceleration acc0 = speed.divideBy(duration); Area area = distance.multiplyBy(distance); Volume vol = area.multiplyBy(distance);DJUNITS knows that the result of multiplication of a speed and a time is a distance. The value of distance is 2500m.
Although we're not entirely sure, we believe that there is never a need for multiplication or division with an Absolute operand. It just does not make sense to multiply 23 September 2015, 3 PM (an absolute Time) by 2...
Dense vectors and matrices use arrays to store the values. Sparse vectors and matrices use an indexed structure to store only the non-zero values. Numeric 0.0 values are not stored explicitly in Sparse vectors and matrices. Very large vectors and matrices with lots of 0.0 values are more efficiently stored in Sparse organization.
Immutable vectors and matrices do not provide methods to change any of their values. Mutable vectors and matrices have methods to update their values.
The Java double precision floating point value takes 8 bytes of memory, the float value takes 4 bytes. Both are available in DJUNITS. The typed Double values are indicated without any prefix. So a Speed scalar is Double, and SpeedVector and SpeedMatrix are Double types. If the type differs from Double, and is, e.g., Float, the type is used as a prefix. The float speed scalar class is therefore FloatSpeed, and the equivalent vector and matrix classes are FloatSpeedVector and FloatSpeedMatrix.
Several extensions are planned: