Boost logo

Boost :

From: Andy Little (andy_at_[hidden])
Date: 2004-10-27 14:06:00


"Noah Stein" <noah_at_[hidden]> wrote
> > -----Original Message-----
> > From: boost-bounces_at_[hidden]
[mailto:boost-bounces_at_[hidden]]
> > On Behalf Of Andy Little
> > Sent: Friday, October 22, 2004 6:09 AM
> > To: boost_at_[hidden]
> > Subject: [boost] pqs - physical quantities library
> >
> > Hi,
> >
> > I have been continuing with my physical-quantities library over the last
> > year,
> > http://www.servocomm.freeserve.co.uk/Cpp/physical_quantity/index.html
> > and I am now seeking feedback as to whether it is worth putting this
> > forward
> > as a boost library proposal....
> >
>
> I've looked over your library a little. Overall, I like it. Having
started
> one a few years ago, I understand how much work has gone into it. I have
> some feedback:
>
> * I would appreciate a little more depth in the glossary. The definitions
> are very much about the mechanics.

I opted to just say what the things are, rather than to try to describe the
'metaphysics'. That is surprisingly hard to do IMO. What is and what isnt a
physical-quantity?. However I accept the point. I have found documenting the
work extremely difficult. A complete overhaul is required.

> A "coherent-quantity" is a
> concrete-quantity with an incoherent-multiplier of 1. Does that mean a
> kilometer is incoherent since its incoherent-multiplier must be different
> than the meter?

No. The incoherent-multiplier is a conversion factor required to scale an
incoherent quantity to a coherent quantity. length::km is a
coherent-quantity. Therefore: The incoherent-multiplier of length::km is
also 1.

Note However that there is another constant in the quantity-unit, the
'coherent exponent'. In length::m the coherent exponent is 0, while in
length::km the coherent-exponent is 3. The coherent-exponent is closely
related to the si-prefixes eg cm -->-2, um --> -6 , km --> 3 etc

In a multiplication on two coherent-quantities ( as opposed to
incoherent-quantities, ie those where the incoherent-multiplier is != 1) as
defined above, the coherent exponents are added at compile time, rather than
runtime, thus making multiplication/division more efficient. IOW this works
similarly to hand calculations.

However incoherent-quantities (non SI quantities eg kgf, in, etc) must be
converted to coherent-quantities first(N, cm) in some cases, making
calculations less efficient. Examples of incoherent-quantities are
length::mi, length::in, length::ft etc. IOW 'coherent-quantities' are those
in practise referred to in the SI system as coherent units.

Overall there are 3 parts to the quantity-unit. A typical declaration looks
like so:
quantity_unit<
    coherent_exponent<Numerator, Denominator>,
    incoherent_multiplier<MultiplicationConstant * 1000000>,
    quantity_unit_tag<ID>
>
the last part is required for corner cases eg:
It is used to differentiate quantities for output purposes.
For example in the following pressure::mmH20, and pressure::kgf_div_m2 are
actually the same unit, (both 'incoherent-quantities' here) ,but note that
output is diffferent.

    std::cout << pqs::pressure::mmH20(1) <<'\n';
    std::cout << pqs::pressure::kgf_div_m2(1) <<'\n';

    // to show they are in fact the same underlying unit
    std::cout << pqs::pressure::mmH20(1)
                        /
                        pqs::pressure::kgf_div_m2(1)
   << '\n';

    // as opposed to
    std::cout << pqs::pressure::kgf_div_m2(1)
                       /
                       pqs::pressure::bar(1)
    <<'\n';

output :
1 mmH20 // note different output of two types
1 kgf.m-2
1 // dividing one by the other shows these are same unit
9.80665e-5 //otoh division of different units

> Or is it coherent because it is part of the SI system, but
> feet, miles, etc. are incoherent? Looking through the code I believe the
> latter to be true, but the documentation doesn't succinctly explain that.

Ok the latter analysis is correct :-), but requires clearer documentation on
my part obviously.

> In following links regarding coherent and incoherent quantities it felt
like
> circular definitions.

Yes the docs need a restart. Criticism totally accepted :-)

>
> * Unless I missed it, I think you need to add a term to your nomenclature.
> What's between an abstract and a concrete quantity? length::m is an
> abstract-quantity with quantity-unit but no value thus it's neither
abstract
> nor concrete. I would guess that this kind of quantity will probably be
> discussed a bit.

Not exactly... abstract-quantities have no numeric-value. They are useful
only for dimensional-analysis. To perform any calculation on
concrete-quantities the units are required. Without units the numeric-value
is meaningless. IOW "I will arrive in 12". means nothing. "I will arrive in
12 minutes" does.

> * I believe the system is too SI-centric, resulting in this point and the
> two following. I would like to see the library move away from the SI units
> taking 7 of 9 prime-unit slots.
> I can envision a number of applications
> that could benefit from a quantities library but aren't based heavily on
SI
> units. For example, if I'm modeling the business side of a networking
> company, my units could include computers, megabytes, and dollars. So
there
> would be a lot of tracking of dimensions I don't care about and currently
> not enough available dimensions currently to track what I do care about.

See the attached file "main.cpp". See also the
AnonymousAbstractQuantityImplementation Concept.
Anything conforming can be substituted, eg the anon_q1 struct in the above
file. OTOH could be 700 dimensions if your compiler can handle it.
Of course you will need to provide output and so on, however calcs work ok.

> * The coherent prime-dimension-unit should be selectable. I don't want
any
> precision issues beyond those that are strictly required. I'd prefer to
see
> a system where I can specify a "coherency-set", e.g. S.I., Imperial, etc.
> Each coherency-set should be completely encapsulated from other sets. If
I
> need conversions from one set to another, I can specialize a conversion
> template class for the two sets.

OK. Except that the SI is arguably The coherent set. There are no widely
used others. The major purpose of the SI system has been to tie together
disparate partially complete systems.

> * I'm a little leery of the structure of of_length, etc. It's not
> extensible to adding new unit types. To bring up a system I mentioned
once
> before in a different thread, how would I add length::cubit without
mucking
> around in the library files themselves?

The current plan wiith these is that you Do just add in custom member
typedefs within the of_length_<Value_type> struct. There are two versions of
each. Obviously the one templated on the Value_type must be a struct, but
the default Value_type version could be a namespace. However I found it
considerably more convenient to make it a ' forwarding' class of the other:

struct length : length_<of_quantity::default_value_type>{};

This can be extended:

struct my_length : length {
    typedef some_type cubit;
};

etc. OTOH it may be more convenient to create your own and add only those
required, or use the ct_quantity raw. It is merely a convenience.
In fact it might be better to put the actual containers in the background
eg:
namespace hidden{

       struct length {...};
}
typedef hidden::length length ;

etc.
Obviously it would be easy to replace the typedef with your own custom
version. In fact I could do this
pretty simply I guess. In fact Should do this.... next version :-)

> * of_quantity seems a little limiting regarding conversion issues. If my
> underlying value type is a UDT (such as an arbitrary precision type), I
> would like to have conversion numbers be objects of that UDT to maximize
> precision.

The SI lays down conversion factors to 6 decimal places. + exponent Some
things are limited by compile time constant issues. eg the
incoherent-multiplier fits into a long. (eg the long template param of
incoherent-multiplier == Constant * 1,000,000.) However extending this to
arbitrary precision is possible perhaps, though I havent looked into it.
Bearing in mind compile time as an issue too, however it may be possible
using a different quantity_unit class. Personally though I have little
interest in this, and generally use coherent-quantities which have 0
conversion error by design, so will leave that to others to implement.

> * What's the plan for non-ICE pow()? A compile-time solution is clearly
not
> an option. For completeness, it would be nice to see an example of how to
> deal with the situations where quantity information is lost.

Because multiplication of two quantities result in a particular Type the
power-to-exponent has to be available at compile time for the current setup.
(however powers can be rational eg pow<-1,2>(t) etc. ) When its not you will
need to use a run-time type, eg with all the dimension information available
and modifiable at runtime. This would certainly be a useful addition, eg a
'universal-quantity' and I may get round to implementing that. The compile
time quantities certainly give good background and its merely a question of
transferring (some) compile-time calcs to run-time. The current types would
also be extremely useful here because they encapsulated the data in a
concise way eg:

universal_quantity x = length::m(1);
x *= time::s (2);
x = 1 ; //dimensionless
    if ( x.dimension_powers() == dimension_powers<of_length>() ){
       length::m len = x;
    }
//etc

The data for the compile time types could also be reused. One way to look at
the types in the"pqs/ct_quantity/types/ " headers is as a database of
information. This has already beeen done to some extent in the rt_quantity,
which has modifiable units and 'maps' the various units for output (see
"pqs/examples/mapped_rt_quantity.cpp" and
"pqs/rt_quantity/rt_units_map.hpp"), but the dimensions are fixed.

 However the rt_quantity has already proved useful. Hmm... maybe it would be
fun to implement that. It might end up being the most useful type of all
:-)

regards
Andy Little

begin 666 main.cpp
M+R\@($-O<'ER:6=H=" H0RD_at_06YD>2!,:71T;&4L(%=H:71E($QI9VAT($1E
M=FEC92 R,# S+@T*+R\@(&%N9'E <V5R=F]C;VUM+F9R965S97)V92YC;RYU
M:PT*+R\@(%!E<FUI<W-I;VX@=&\@8V]P>2P@=7-E+"!M;V1I9GDL('-E;&P@
M86YD(&1I<W1R:6)U=&4@=&AI<R!S;V9T=V%R90T*+R\@(&ES(&=R86YT960@
M<')O=FED960@=&AI<R!C;W!Y<FEG:'0@;F]T:6-E(&%P<&5A<G,@:6X_at_86QL
M(&-O<&EE<RX-"B\O("!4:&ES('-O9G1W87)E(&ES('!R;W9I9&5D(")A<R!I
M<R(@=VET:&]U="!E>'!R97-S(&]R(&EM<&QI960@=V%R<F%N='DL#0HO+R @
M86YD('=I=&@@;F\@8VQA:6T_at_87,@=&\@:71S('-U:71A8FEL:71Y(&9O<B!A
M;GD@<'5R<&]S92X-"B-I;F-L=61E(")P<7,O<'%S+FAP<"(-"@T*;F%M97-P
M86-E('!Q<WL-"@T*(" @("\O(&-U<W1O;2!A;F]N>6UP;W5S7V%B<W1R86-T
M+7%U86YT:71Y#0H@(" @+R\@8V]N9F]R;6EN9R!T;R!T:&4_at_06YO;GEM;W5S
M06)S=')A8W11=6%N=&ET>4EM<&QE;65N=&%T:6]N($-O;F-E<'0-"B @(" O
M+R!R97%U:7)E<R!A;'-O(&)I;F%R>5]O<&5R871I;VX@=&\@8F4@<W!E8VEA
M;&ES960_at_87,@8F5L;W<-"B @("!T96UP;&%T93P-"B @(" @(" @='EP96YA
M;64_at_1FER<W14>7!E+ T*(" @(" @("!T>7!E;F%M92!396-O;F14>7!E+ T*
M(" @(" @("!T>7!E;F%M92!4:&ER9%1Y<&4-"B @(" ^#0H@(" @<W1R=6-T
M(&%N;VY?<3%[#0H@(" @(" @('1Y<&5D968_at_1FER<W14>7!E(" @(" @(" @
M(&9I<G-T7W1Y<&4[#0H@(" @(" @('1Y<&5D968_at_4V5C;VYD5'EP92 @(" @
M(" @('-E8V]N9%]T>7!E(#L-"B @(" @(" @='EP961E9B!4:&ER9%1Y<&4@
M(" @(" @(" @=&AI<F1?='EP93L-"@T*#0H@(" @(" @('1Y<&5D968_at_86YO
M;E]Q,2 @='EP93L-"B @(" @(" @96YU;7L@:7-?9&EM96YS:6]N;&5S<R -
M"B @(" @(" @/2 @("!F:7)S=%]T>7!E.CII<U]Z97)O#0H@(" @(" @("8F
M("!S96-O;F1?='EP93HZ:7-?>F5R;PT*(" @(" @(" F)B @=&AI<F1?='EP
M93HZ:7-?>F5R;WT_at_[hidden]*(" @('T[#0I]+R]P<7,-"@T*;F%M97-P86-E('!Q
M<WL-"FYA;65S<&%C92!M971A>PT*#0H@(" @+R]&;VQL;W=I;6<@(')E<75I
M<F5D(&9O<B!A;F]N7W$Q('1O(&-O;F9O<FT@#0H@(" @+R\@=&\@=&AE($-O
M;7!I;&5T:6UE0FEN87)Y3W!E<F%T:6)L92!#;VYC97!T#0H@(" @+R\@86YD
M($-O;7!I;&5T:6UE(%5N87)Y3W!E<F%T:6)L92!#;VYC97!T#0H@(" @('1E
M;7!L871E(#P@#0H@(" @(" @('1Y<&5N86UE($9I<G-T5'EP92P-"B @(" @
M(" @='EP96YA;64_at_4V5C;VYD5'EP92P-"B @(" @(" @='EP96YA;64_at_5&AI
M<F14>7!E+ T*(" @(" @("!I;G0_at_3BP-"B @(" @(" @:6YT($0-"B @(" ^
M#0H@(" @<W1R=6-T(&)I;F%R>5]O<&5R871I;VX\#0H@(" @(" @('1Y<&5N
M86UE('!Q<SHZ86YO;E]Q,3P-"B @(" @(" @(" @($9I<G-T5'EP92P-"B @
M(" @(" @(" @(%-E8V]N9%1Y<&4L#0H@(" @(" @(" @("!4:&ER9%1Y<&4-
M"B @(" @(" @/BP-"B @(" @(" @<'%S.CIT;U]P;W=E<BP-"B @(" @(" @
M<'%S.CIM971A.CIR871I;VYA;%]C/&EN="P_at_3BQ$/@T*(" @(#Y[#0H@(" @
M(" @('1Y<&5D968@='EP96YA;64@<'%S.CIM971A.CIR871I;VYA;%]C/&EN
M="P_at_3BQ$/CHZ='EP92!R870[#0H@(" @(" @("!T>7!E9&5F('!Q<SHZ86YO
M;E]Q,3P-"B @(" @(" @(" @('1Y<&5N86UE(&)I;F%R>5]O<&5R871I;VX\
M1FER<W14>7!E+'-T9#HZ;75L=&EP;&EE<RQR870^.CIR97-U;'1?='EP92P-
M"B @(" @(" @(" @('1Y<&5N86UE(&)I;F%R>5]O<&5R871I;VX\4V5C;VYD
M5'EP92QS=&0Z.FUU;'1I<&QI97,L<F%T/CHZ<F5S=6QT7W1Y<&4L#0H@(" @
M(" @(" @("!T>7!E;F%M92!B:6YA<GE?;W!E<F%T:6]N/%1H:7)D5'EP92QS
M=&0Z.FUU;'1I<&QI97,L<F%T/CHZ<F5S=6QT7W1Y<&4-"B @(" @(" @/B!R
M97-U;'1?='EP93L-"B @("!].PT*(" @(" @(" -"B @(" @=&5M<&QA=&4@
M/" -"B @(" @(" @='EP96YA;64_at_1FER<W14>7!E02P-"B @(" @(" @='EP
M96YA;64_at_4V5C;VYD5'EP94$L#0H@(" @(" @('1Y<&5N86UE(%1H:7)D5'EP
M94$L#0H@(" @(" @('1E;7!L871E(#QT>7!E;F%M93X_at_8VQA<W,@3W L#0H@
M(" @(" @('1Y<&5N86UE($9I<G-T5'EP94(L#0H@(" @(" @('1Y<&5N86UE
M(%-E8V]N9%1Y<&5"+ T*(" @(" @("!T>7!E;F%M92!4:&ER9%1Y<&5"#0H@
M(" ^(" @(" @(" -"B @("!S=')U8W0_at_8FEN87)Y7V]P97)A=&EO;CP-"B @
M(" @(" @='EP96YA;64@<'%S.CIA;F]N7W$Q/ T*(" @(" @(" @(" @1FER
M<W14>7!E02P-"B @(" @(" @(" @(%-E8V]N9%1Y<&5!+ T*(" @(" @(" @
M(" @5&AI<F14>7!E00T*(" @(" @(" ^+ T*(" @(" @("!/<"P-"B @(" @
M(" @='EP96YA;64@<'%S.CIA;F]N7W$Q/ T*(" @(" @(" @(" @1FER<W14
M>7!E0BP-"B @(" @(" @(" @(%-E8V]N9%1Y<&5"+ T*(" @(" @(" @(" @
M5&AI<F14>7!E0_at_T*(" @(" @(" ^+ T*(" @(" @("!T>7!E;F%M92!B;V]S
M=#HZ96YA8FQE7VEF/ T*(" @(" @(" @(" @8F]O<W0Z.FUP;#HZ86YD7SP-
M"B @(" @(" @(" @(" @("!P<7,Z.FUE=&$Z.F1E=&%I;#HZ:7-?=F%L:61?
M8FEN87)Y7VQO9U]T<F%N<V9O<FT\#0H@(" @(" @(" @(" @(" @(" @($9I
M<G-T5'EP94$L3W L1FER<W14>7!E0_at_T*(" @(" @(" @(" @(" @(#XL#0H@
M(" @(" @(" @(" @(" @<'%S.CIM971A.CID971A:6PZ.FES7W9A;&ED7V)I
M;F%R>5]L;V=?=')A;G-F;W)M/ T*(" @(" @(" @(" @(" @(" @("!396-O
M;F14>7!E02Q/<"Q396-O;F14>7!E0_at_T*(" @(" @(" @(" @(" @(#XL#0H@
M(" @(" @(" @(" @(" @<'%S.CIM971A.CID971A:6PZ.FES7W9A;&ED7V)I
M;F%R>5]L;V=?=')A;G-F;W)M/ T*(" @(" @(" @(" @(" @(" @("!4:&ER
M9%1Y<&5!+$]P+%1H:7)D5'EP94(-"B @(" @(" @(" @(" @(" ^+ T*(" @
M(" @(" @(" @(" @(&)O;W-T.CIM<&PZ.FYO=%\\#0H@(" @(" @(" @(" @
M(" @(" @('!Q<SHZ:7-?<&]W7V]P97)A=&]R/$]P/@T*(" @(" @(" @(" @
M(" @(#X-"B @(" @(" @(" @(#X-"B @(" @(" @/CHZ='EP90T*(" @(" @
M(" @(" @(" @( T*(" @/GL-"B @(" @(" @='EP961E9B!P<7,Z.F%N;VY?
M<3$\#0H@(" @(" @(" @("!T>7!E;F%M92!P<7,Z.FUE=&$Z.F)I;F%R>5]L
M;V=?=')A;G-F;W)M/$9I<G-T5'EP94$L3W L1FER<W14>7!E0CXZ.G)E<W5L
M=%]T>7!E+ T*(" @(" @(" @(" @='EP96YA;64@<'%S.CIM971A.CIB:6YA
M<GE?;&]G7W1R86YS9F]R;3Q396-O;F14>7!E02Q/<"Q396-O;F14>7!E0CXZ
M.G)E<W5L=%]T>7!E+ T*(" @(" @(" @(" @='EP96YA;64@<'%S.CIM971A
M.CIB:6YA<GE?;&]G7W1R86YS9F]R;3Q4:&ER9%1Y<&5!+$]P+%1H:7)D5'EP
M94(^.CIR97-U;'1?='EP90T*(" @(" @(" ^(')E<W5L=%]T>7!E.PT*(" @
M(" @(" @(" @#0H@("!].PT*#0H@(" @=&5M<&QA=&4\#0H@(" @(" @('1Y
M<&5N86UE($9I<G-T5'EP92 L#0H@(" @(" @('1Y<&5N86UE(%-E8V]N9%1Y
M<&4L#0H@(" @(" @('1Y<&5N86UE(%1H:7)D5'EP90T*(" @(#X-"B @("!S
M=')U8W0@=6YA<GE?;W!E<F%T:6]N/ T*(" @(" @("!P<7,Z.G)E8VEP<F]C
M86PL#0H@(" @(" @('1Y<&5N86UE('!Q<SHZ86YO;E]Q,3P-"B @(" @(" @
M(" @($9I<G-T5'EP92P-"B @(" @(" @(" @(%-E8V]N9%1Y<&4L#0H@(" @
M(" @(" @("!4:&ER9%1Y<&4-"B @(" @(" @/@T*(" @(#Y[#0H@(" @(" @
M('1Y<&5D968@='EP96YA;64@<'%S.CIA;F]N7W$Q/ T*(" @(" @(" @(" @
M='EP96YA;64@=6YA<GE?;W!E<F%T:6]N/'-T9#HZ;F5G871E+$9I<G-T5'EP
M93XZ.G)E<W5L=%]T>7!E+ T*(" @(" @(" @(" @='EP96YA;64@=6YA<GE?
M;W!E<F%T:6]N/'-T9#HZ;F5G871E+%-E8V]N9%1Y<&4^.CIR97-U;'1?='EP
M92P-"B @(" @(" @(" @('1Y<&5N86UE('5N87)Y7V]P97)A=&EO;CQS=&0Z
M.FYE9V%T92Q4:&ER9%1Y<&4^.CIR97-U;'1?='EP90T*(" @(" @/B!R97-U
M;'1?='EP93L-"B @('T[#0H-"GTO+VUE=&$-"GTO+W!Q<PT*"@II;G0@;6%I
M;B_at_I"GL*(" @('1Y<&5D968@<'%S.CIC=%]Q=6%N=&ET>3P*(" @(" @("!P
M<7,Z.FYA;65D7V%B<W1R86-T7W%U86YT:71Y/ H@(" @(" @(" @("!P<7,Z
M.F%N;VY?<3$\"B @(" @(" @(" @(" @("!P<7,Z.FUE=&$Z.G)A=&EO;F%L
M7V,\:6YT+#$^+ H@(" @(" @(" @(" @(" @<'%S.CIM971A.CIR871I;VYA
M;%]C/&EN="PP/BP*(" @(" @(" @(" @(" @('!Q<SHZ;65T83HZ<F%T:6]N
M86Q?8SQI;G0L,#X*(" @(" @(" @(" @/BP*(" @(" @(" @(" @<'%S.CIN
M86UE9%]Q=6%N=&ET>5]T86<\,#X*(" @(" @(" ^+ H@(" @(" @('!Q<SHZ
M<75A;G1I='E?=6YI=#P*(" @(" @(" @(" @<'%S.CIC;VAE<F5N=%]E>'!O
M;F5N=#PP/BP*(" @(" @(" @(" @<'%S.CII;F-O:&5R96YT7VUU;'1I<&QI
M97(\,3 P,# P,#X*(" @(" @(" ^+ H@(" @(" @(&1O=6)L92 *(" @(#X@
M("!T97-T7W1Y<&4Q.PH*(" @('1Y<&5D968@<'%S.CIC=%]Q=6%N=&ET>3P*
M(" @(" @("!P<7,Z.FYA;65D7V%B<W1R86-T7W%U86YT:71Y/ H@(" @(" @
M(" @("!P<7,Z.F%N;VY?<3$\"B @(" @(" @(" @(" @("!P<7,Z.FUE=&$Z
M.G)A=&EO;F%L7V,\:6YT+# ^+ H@(" @(" @(" @(" @(" @<'%S.CIM971A
M.CIR871I;VYA;%]C/&EN="PQ/BP*(" @(" @(" @(" @(" @('!Q<SHZ;65T
M83HZ<F%T:6]N86Q?8SQI;G0L,#X*(" @(" @(" @(" @/BP*(" @(" @(" @
M(" @<'%S.CIN86UE9%]Q=6%N=&ET>5]T86<\,#X*(" @(" @(" ^+ H@(" @
M(" @('!Q<SHZ<75A;G1I='E?=6YI=#P*(" @(" @(" @(" @<'%S.CIC;VAE
M<F5N=%]E>'!O;F5N=#PP/BP*(" @(" @(" @(" @<'%S.CII;F-O:&5R96YT
M7VUU;'1I<&QI97(\,3 P,# P,#X*(" @(" @(" ^+ H@(" @(" @(&EN=" *
M(" @(#X@("!T97-T7W1Y<&4R.PH*"B @("!T97-T7W1Y<&4Q('0Q*#$I.PH@
M(" @=&5S=%]T>7!E,B!T,B_at_R*3L*(" @('!Q<SHZ;65T83HZ8FEN87)Y7V]P
M97)A=&EO;CP*(" @(" @("!T97-T7W1Y<&4Q+ H@(" @(" @('-T9#HZ;75L
M=&EP;&EE<RP*(" @(" @("!T97-T7W1Y<&4R"B @(" ^.CIR97-U;'1?='EP
M92!T,6UU;'0R(#T@=#$@*B!T,CL*"B @("!S=&0Z.F-O=70@/#P@(G0Q("H@
M=#(@;G5M97)I8U]V86QU92 ]("(@/#P@=#%M=6QT,BYN=6UE<FEC7W9A;'5E
M*"D@/#PG7&XG.PH@(" @<W1D.CIC;W5T(#P\("!T>7!E:60H=#%M=6QT,BDN
M;F%M92_at_I(#P\("=<;B<["B @("!P<7,Z.FUE=&$Z.F)I;F%R>5]O<&5R871I
M;VX\"B @(" @(" @=&5S=%]T>7!E,2P*(" @(" @("!S=&0Z.F1I=FED97,L
M"B @(" @(" @=&5S=%]T>7!E,@H@(" @/CHZ<F5S=6QT7W1Y<&4@=#%D:79T
M,B ]('0Q("\@=#(["B @("!S=&0Z.F-O=70@/#P@(G0Q("\@=#(@;G5M97)I
M8U]V86QU92 ]("(@/#P@=#%D:79T,BYN=6UE<FEC7W9A;'5E*"D@/#PG7&XG
M.PH@(" @<W1D.CIC;W5T(#P\('1Y<&5I9"AT,61I=G0R*2YN86UE*"D@/#PG
M7&XG.PH*(" @("!P<7,Z.FUE=&$Z.F)I;F%R>5]O<&5R871I;VX\"B @(" @
M(" @=&5S=%]T>7!E,2P*(" @(" @("!S=&0Z.F1I=FED97,L"B @(" @(" @
M=&5S=%]T>7!E,0H@(" @/CHZ<F5S=6QT7W1Y<&4@=#%D:79T,2 ]('0Q("\@
M=#$["B @("!S=&0Z.F-O=70@/#P@(G0Q("\@=#$@;G5M97)I8U]V86QU92 ]
M("(@/#P@=#%D:79T,2 \/"=<;B<["B @("!S=&0Z.F-O=70@/#P@='EP96ED
M*'0Q9&EV=#$I+FYA;64H*2 \/"=<;B<["B @(" *(" @( H@(" @<'%S.CIM
M971A.CIB:6YA<GE?;W!E<F%T:6]N/ H@(" @(" @('1E<W1?='EP93$L"B @
M(" @(" @<W1D.CIP;'5S+ H@(" @(" @('1E<W1?='EP93$*(" @(#XZ.G)E
M<W5L=%]T>7!E('0Q<&QT,2 ]('0Q("L@=#$["@H@(" @<W1D.CIC;W5T(#P\
M(")T,2 K('0Q(&YU;65R:6-?=F%L=64@/2 B(#P\('0Q<&QT,2YN=6UE<FEC
M7W9A;'5E*"D@/#PG7&XG.PH@(" @<W1D.CIC;W5T(#P\('1Y<&5I9"AT,7!L
M=#$I+FYA;64H*2 \/"=<;B<["@H*(" @('!Q<SHZ;65T83HZ8FEN87)Y7V]P
M97)A=&EO;CP*(" @(" @("!T97-T7W1Y<&4R+ H@(" @(" @('-T9#HZ;6EN
M=7,L"B @(" @(" @=&5S=%]T>7!E,@H@(" @/CHZ<F5S=6QT7W1Y<&4@=#)M
M:6YU<W0R(#T@=#(@+2!T,CL*(" @('-T9#HZ8V]U=" \/" B=#(@+2!T,B!N
M=6UE<FEC7W9A;'5E(#T@(B \/"!T,FUI;G5S=#(N;G5M97)I8U]V86QU92_at_I
M(#P\)UQN)SL*(" @('-T9#HZ8V]U=" \/"!T>7!E:60H=#)M:6YU<W0R*2YN
M86UE*"D@/#PG7&XG.PH*(" @("!P<7,Z.FUE=&$Z.F)I;F%R>5]O<&5R871I
M;VX\"B @(" @(" @=&5S=%]T>7!E,BP*(" @(" @("!P<7,Z.G1O7W!O=V5R
M+ H@(" @(" @('!Q<SHZ;65T83HZ<F%T:6]N86Q?8SQI;G0L,BPQ/@H@(" @
M/CHZ<F5S=6QT7W1Y<&4@=#)P;W<R(#T@<'%S.CIP;W<\,CXH=#(I.PH@(" @
M<W1D.CIC;W5T(#P\(")P;W%S/#(^*'0R*2!N=6UE<FEC7W9A;'5E(#T@(B \
M/"!T,G!O=S(N;G5M97)I8U]V86QU92_at_I(#P\)UQN)SL*(" @('-T9#HZ8V]U
M=" \/"!T>7!E:60H=#)P;W<R*2YN86UE*"D@/#PG7&XG.PH@("\O("!S=&0Z
?.F-O=70@/#P@=#)P;W<R(#P\)UQN)SL*(" @( I]"@``
`
end


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk