Boost logo

Boost :

From: Corwin Joy (cjoy_at_[hidden])
Date: 2001-06-30 14:27:26

----- Original Message -----
From: <Deane_Yang_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, June 29, 2001 10:54 PM
Subject: [boost] Re: Units (and operators.hpp, too)

> --- In boost_at_y..., "Corwin Joy" <cjoy_at_h...> wrote:
> > I think that having a nice templated units library
> > would be cool. One thing that seems to be missing
> > from this discussion, however, is that the templates
> > should have virtual base classes which expose operator
> > + and * such that developers can
> > use the units classes for either compile time checks or runtime
> > checks. In my work, I do a lot of units conversions
> > but these have to be checked and cast at runtime
> > for three reasons:
> > 1. I'm reading the values and units from a database and I
> > don't always know what possible units are allowed in advance.
> > 2. I often have to cast and format out reports in different
> > units of measure depending on how the end users
> > prefer to view their results.
> > 3. The unit conversion ratios for me will often change at runtime,
> > potentially minute-by-minute
> > e.g. how much is a Mexican Peso worth in US $ today, (exchange
> rate)
> > . how much is a Mexican Peso to be delivered in 1 year worth in US
> $ today
> > (exchange rate) * (Mex discount factor at 1 year).
> > These kind conversions all benefit from a strict units regimen, but
> it needs
> > to happen at runtime.
> >
> I've thought about this, too. But allowing dynamic types to be defined
> at runtime makes things way too complicated for me. I'll leave that
> to the experts. I concede that foreign currencies are a bit
> of a headache to implement using template unit classes.

Actually allowing support for runtime checks & constuction would be pretty
easy to do. Consider

// prototype here - never compiled!

enum UnitTypes {meter, foot, mile, centimeter, etc.}
class UnitsBase {
    virtual UnitsBase operator +=(UnitsBase &rhs)
    virtual UnitsBase operator *=(UnitsBase &rhs)
    virtual vector<pair<UnitType, int>> get_units(); // return a vector of
units in form pair<unit, exponent>
... etc...

// Here I'm just guessing at what your unit class might look like
template<...> class Units {
    virtual Units operator += (Units &rhs) {... actual + operation here}
    virtual Units operator +=(UnitsBase &rhs) {
        double conversion_ratio = convert(rhs.get_units(), get_units()); //
throw if rhs not convertible to lhs units
        *this += conversion_ratio * rhs.value();


> >(stuff deleted)
> > Sort of, there are different time units, tho, depending on the
> interest
> > rate convention. Example daycounts that are applied to
> > interest rates include
> >
> > Actual/365, 30/360, Actual/Actual, business/260 etc.
> > >
> I don't agree with this. I've spent more time thinking about daycount
> conventions than I care to admit. I finally decided that different
> daycount conventions do NOT correspond to different units of time.
> Rather a daycount convention is simply a function that takes two
> dates and returns a value in years. I implement daycounts in a
> separate class that uses but is not derived from
> any of my unit classes.

I still disagree with you. It depends on how heavily you want to use
your units classes. Here if you define time distances as having units
(which I believe they should - after all Mar 1, 2000 - Feb 1, 2000 will
give a different ratio for Actual/365 versus 30/360) you can make
sure that interest rates expressed in a certain unit can only be combined
time distances expressed in the same units - which is what unit checking is
all about.

> > > 3) Transcendental functions
> > I'm not sure I agree with sin & cos, but I definitely *disagree*
> for logs.
> > It seems to me that the log of a unit has well defined units.
> > e.g.
> > distance d1 = 5*meters;
> > distance d2 = 10*meters;
> > distance d3 = exp(log(d1 + d2)); // 15 meters
> > area a1 = exp(log(d1) + log(d2)); // 50 meters^2
> >
> > i.e. in general log(measurement) has a unit that is the log()
> operator
> > applied
> > to the individual units. Naturally supporting these is more
> complicated
> > since taking the log of a measurement then swaps the role that
> > multiplication
> > and addition play. I can certainly see why one might draw the line
> > at function checking.
> I've never seen exp() and log() used to compute areas like this.
> And I've never seen log(meters) used anywhere in physics or anywhere
> else. You can kind of see how awkward log(meters) are, if you think
> about how to change from log(meters) to log(feet). It's not the usual
> "multiply by a constant factor" rule. Instead, it's "add by a
> constant term". So clearly these are different animals.
> Another interesting case study is finance. There are lots of
> logarithms and exponentials used in discounting with interest rates
> and in option pricing models.
> If you look at it all carefully, you'll find that the arguments to exp
> () and log() are always unitless and so are the exp()'s and log()'s
> themselves. In fact, this is the setting where my unit
> classes have been most useful.

No, I disagree. The results from exp() are definitely not unitless and in
fact imply very specific unit ratios about where the option lies on the
discount curve. Consider an
option on natural gas prices at Toronto City Gate. The underlying gas
price in in Nominal Can $/ GJ, strike in Nominal Can $, discount factor in
 NPV Can $ [T] = Fwd Can $ at time [T] / Curr Can $ etc.
From this, the option prices and greeks must inherit the following units:

Option Price = NPV Can $ [T].
Option Delta = NPV Can $ [T]. * GJ
etc. etc. (others are harder - and I would have to get into whole financial
units discussion to explain which I spare you).

The point is, here we are performing logs and exponents and the resulting
units are very much implied by the math. (Now whether a units class
can reasonably be expected to handle this is another matter).

Boost list run by bdawes at, gregod at, cpdaniel at, john at