![]() |
Home | Libraries | People | FAQ | More |
This example provides a fairly extensive set of tests covering most of the
quantity
functionality. It uses the SI unit system defined in boost/units/systems/si.hpp
.
If we define a few units and associated quantities,
/// scalar const double s1 = 2; const long x1 = 2; const static_rational<4,3> x2; /// define some units force u1 = newton; energy u2 = joule; /// define some quantities quantity<force> q1(1.0*u1); quantity<energy> q2(2.0*u2);
the various algebraic operations between scalars, units, and quantities give
S1 : 2 X1 : 2 X2 : (4/3) U1 : N U2 : J Q1 : 1 N Q2 : 2 J
Scalar/unit operations :
U1*S1 : 2 N S1*U1 : 2 N U1/S1 : 0.5 N S1/U1 : 2 m^-1 kg^-1 s^2
Unit/unit operations and integral/rational powers of units :
U1+U1 : N U1-U1 : N U1*U1 : m^2 kg^2 s^-4 U1/U1 : dimensionless U1*U2 : m^3 kg^2 s^-4 U1/U2 : m^-1 U1^X : m^2 kg^2 s^-4 X1vU1 : m^(1/2) kg^(1/2) s^-1 U1^X2 : m^(4/3) kg^(4/3) s^(-8/3) X2vU1 : m^(3/4) kg^(3/4) s^(-3/2)
Scalar/quantity operations :
Q1*S1 : 2 N S1*Q1 : 2 N Q1/S1 : 0.5 N S1/Q1 : 2 m^-1 kg^-1 s^2
Unit/quantity operations :
U1*Q1 : 1 m^2 kg^2 s^-4 Q1*U1 : 1 m^2 kg^2 s^-4 U1/Q1 : 1 dimensionless Q1/U1 : 1 dimensionless
Quantity/quantity operations and integral/rational powers of quantities :
+Q1 : 1 N -Q1 : -1 N Q1+Q1 : 2 N Q1-Q1 : 0 N Q1*Q1 : 1 m^2 kg^2 s^-4 Q1/Q1 : 1 dimensionless Q1*Q2 : 2 m^3 kg^2 s^-4 Q1/Q2 : 0.5 m^-1 Q1^X1 : 1 m^2 kg^2 s^-4 X1vQ1 : 1 m^(1/2) kg^(1/2) s^-1 Q1^X2 : 1 m^(4/3) kg^(4/3) s^(-8/3) X2vQ1 : 1 m^(3/4) kg^(3/4) s^(-3/2)
Logical comparison operators are also defined between quantities :
/// check comparison tests quantity<length> l1(1.0*meter), l2(2.0*meters);
giving
l1 == l2 false l1 != l2 true l1 <= l2 true l1 < l2 true l1 >= l2 false l1 > l2 false
Implicit conversion is allowed between dimensionless quantities and their corresponding value types :
/// check implicit unit conversion from dimensionless to value_type const double dimless = (q1/q1);
A generic function for computing mechanical work can be defined that takes force and distance arguments in an arbitrary unit system and returns energy in the same system:
/// the physical definition of work - computed for an arbitrary unit system template<class System,class Y> quantity<unit<energy_dimension,System>,Y> work(quantity<unit<force_dimension,System>,Y> F, quantity<unit<length_dimension,System>,Y> dx) { return F*dx; }
/// test calcuation of work quantity<force> F(1.0*newton); quantity<length> dx(1.0*meter); quantity<energy> E(work(F,dx));
which functions as expected for SI quantities :
F = 1 N dx = 1 m E = 1 J
The ideal gas law can also be implemented in SI units :
/// the ideal gas law in si units template<class Y> quantity<si::amount,Y> idealGasLaw(const quantity<si::pressure,Y>& P, const quantity<si::volume,Y>& V, const quantity<si::temperature,Y>& T) { using namespace boost::units::si; using namespace constants::codata; return (P*V/(R*T)); }
/// test ideal gas law quantity<temperature> T = (273.+37.)*kelvin; quantity<pressure> P = 1.01325e5*pascals; quantity<length> r = 0.5e-6*meters; quantity<volume> V = (4.0/3.0)*3.141592*pow<3>(r); quantity<amount> n(idealGasLaw(P,V,T));
with the resulting output :
r = 5e-07 m P = 101325 Pa V = 5.23599e-19 m^3 T = 310 K n = 2.05835e-17 mol R = 8.314472 m^2 kg s^-2 K^-1 mol^-1 (rel. unc. = 1.8e-06)
Trigonometric and inverse trigonometric functions can be implemented for
any unit system that provides an angular base dimension. For radians, these
functions are found in boost/units/cmath.hpp
These behave as one expects, with trigonometric functions taking an angular
quantity and returning a dimensionless quantity, while the inverse trigonometric
functions take a dimensionless quantity and return an angular quantity :
Defining a few angular quantities,
/// test trig stuff quantity<plane_angle> theta = 0.375*radians; quantity<dimensionless> sin_theta = sin(theta); quantity<plane_angle> thetap = asin(sin_theta);
yields
theta = 0.375 rd sin(theta) = 0.366273 dimensionless asin(sin(theta)) = 0.375 rd
Dealing with complex quantities is trivial. Here is the calculation of complex impedance :
quantity<electric_potential,complex_type> v = complex_type(12.5,0.0)*volts; quantity<current,complex_type> i = complex_type(3.0,4.0)*amperes; quantity<resistance,complex_type> z = complex_type(1.5,-2.0)*ohms;
giving
V = (12.5,0) V I = (3,4) A Z = (1.5,-2) Ohm I*Z = (12.5,0) V
User-defined value types that support the appropriate arithmetic operations
are automatically supported as quantity value types. The operators that
are supported by default for quantity value types are unary plus, unary
minus, addition, subtraction, multiplication, division, equal-to, not-equal-to,
less-than, less-or-equal-to, greater-than, and greater-or-equal-to. Support
for rational powers and roots can be added by overloading the power_typeof_helper
and root_typeof_helper
classes. Here we implement a user-defined measurement
class that models a numerical measurement with an associated measurement
error and the appropriate algebra and demonstrates its use as a quantity
value type; the full code is found in measurement.hpp.
Then, defining some measurement
quantity
variables
quantity<length,measurement<double> > u(measurement<double>(1.0,0.0)*meters), w(measurement<double>(4.52,0.02)*meters), x(measurement<double>(2.0,0.2)*meters), y(measurement<double>(3.0,0.6)*meters);
gives
x+y-w = 0.48(+/-0.632772) m w*x = 9.04(+/-0.904885) m^2 x/y = 0.666667(+/-0.149071) dimensionless
If we implement the overloaded helper classes for rational powers and roots then we can also compute rational powers of measurement quantities :
w*y^2/(u*x)^2 = 10.17(+/-3.52328) m^-1 w/(u*x)^(1/2) = 3.19612(+/-0.160431) dimensionless