From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 6687D7EFCD for ; Thu, 16 Oct 2014 20:11:01 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of thomas.gazagnaire@gmail.com) identity=pra; client-ip=74.125.82.52; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="thomas.gazagnaire@gmail.com"; x-sender="thomas.gazagnaire@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of thomas.gazagnaire@gmail.com designates 74.125.82.52 as permitted sender) identity=mailfrom; client-ip=74.125.82.52; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="thomas.gazagnaire@gmail.com"; x-sender="thomas.gazagnaire@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-wg0-f52.google.com) identity=helo; client-ip=74.125.82.52; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="thomas.gazagnaire@gmail.com"; x-sender="postmaster@mail-wg0-f52.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AtgBAIoJQFRKfVI0lGdsb2JhbABbg2HLDoFuiGcWAREBAQEBBwsLCRIwhAMBAQMBEi4BOAEDAQsBBQU4DiETAQUBDg4GEyKICAMJCAQBCKlQbpAyiRcnDYZCAQEIAQEBAQEBFgEFDo4LhWiBHgWFFZEwhQGDfYV8h14DhGFBgWyDPWsBgkkBAQE X-IPAS-Result: AtgBAIoJQFRKfVI0lGdsb2JhbABbg2HLDoFuiGcWAREBAQEBBwsLCRIwhAMBAQMBEi4BOAEDAQsBBQU4DiETAQUBDg4GEyKICAMJCAQBCKlQbpAyiRcnDYZCAQEIAQEBAQEBFgEFDo4LhWiBHgWFFZEwhQGDfYV8h14DhGFBgWyDPWsBgkkBAQE X-IronPort-AV: E=Sophos;i="5.04,733,1406584800"; d="scan'208,217";a="83524286" Received: from mail-wg0-f52.google.com ([74.125.82.52]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 16 Oct 2014 20:11:00 +0200 Received: by mail-wg0-f52.google.com with SMTP id a1so4348085wgh.23 for ; Thu, 16 Oct 2014 11:10:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:content-type:mime-version:subject:from:in-reply-to:date:cc :message-id:references:to; bh=3dL5dRJiRgHq0HgbLREfiKEf0xvTDHcoiXAZIDIQQsQ=; b=uo3WAp29oEMGD6SCnt4qylUSJyCo9EdcRPcBRVwJsdxEwCAB07w4Zl1C2XUy4tinqE 5DDfFzQaQutWu3LNjaEZ6p+T8sNFiXHKeVuhTPfuzcop65CitMNbc17QZG3VByidyxjN GWOyOMOW51T6fUQRubsC1hF06Xa9WV6sKEXhdCNvwgfKsbiZos9LcW3cgeHQ+t8NqZ/Q hxG/7v69u8uVk801XCWsJDPn8rrnyr9+XI72dGxGY58awwG4LMHFIBgsYb8D5FM+qnv6 D9XmMPUM1zhZesNW547xx1RiO9vWiMrkvtFt0ztU2xfi0cKyJTSVpC69oxoh3P0mhBrC 3GAQ== X-Received: by 10.180.218.136 with SMTP id pg8mr14400171wic.37.1413483059722; Thu, 16 Oct 2014 11:10:59 -0700 (PDT) Received: from [192.168.0.2] (cpc25-cmbg14-2-0-cust121.5-4.cable.virginm.net. [213.106.112.122]) by mx.google.com with ESMTPSA id ic4sm2819921wid.19.2014.10.16.11.10.57 for (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Thu, 16 Oct 2014 11:10:58 -0700 (PDT) Sender: Thomas Gazagnaire Content-Type: multipart/alternative; boundary="Apple-Mail=_E6E53CB7-9E97-40D1-BE88-7A816AD7E02E" Mime-Version: 1.0 (Mac OS X Mail 7.3 \(1878.6\)) From: Thomas Gazagnaire In-Reply-To: Date: Thu, 16 Oct 2014 19:10:56 +0100 Cc: "caml-list@inria.fr users" Message-Id: References: To: Shayne Fletcher X-Mailer: Apple Mail (2.1878.6) Subject: Re: [Caml-list] Dimensional Analysis question --Apple-Mail=_E6E53CB7-9E97-40D1-BE88-7A816AD7E02E Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset=us-ascii You might be interested by http://akabe.github.io/slap/ Thomas On 16 Oct 2014, at 17:37, Shayne Fletcher wr= ote: > Dear OCamlers, >=20 > In 1994, Barton and Nackman in their book 'Scientific Engineering in > C++' [1] demonstrated how one could encode the rules of Dimensional > Analysis [2] into the C++ type system enabling compile-time checking > (no runtime-cost) of the plausibility (at least up to the dimensional > correctness) of computations. >=20 > In 2004, Abrahams & Gurtovy in 'C++ Template Metaprogramming' [3] > showed the Barton Nackman technique to be elegantly implementable > using compile time type sequences encoding integer constants. At the > end of this post, I provide a complete listing of their example > program [4]. >=20 > The key properties of the system (as I see it) are: > - Encoding of integers as types;=20 > - Compile time manipulation of sequences of these integer encodings > to deduce/produce new derived types. >=20 > Now, it is not immediately obvious to me how to approach this problem > in OCaml. It irks me some that I can't immediately produce a yet more > elegant OCaml program for this problem and leaves me feeling like C++ > has "got something over on us" here ;) >=20 > My question therefore is: Does anyone have suggestions/pointers > on how to approach automatic dimensional analysis via the OCaml type > system?=20 >=20 > Best, >=20 > --=20 > Shayne Fletcher >=20 > [1] John J. Barton and Lee R. Nackman. Scientific and Engineering C++: > an Introduction with Advanced Techniques and Examples. Reading, > MA: Addison Wesley. ISBN 0-201-53393-6. 1994. >=20 > [2] Wikipedia http://en.wikipedia.org/wiki/Dimensional_analysis >=20 > [3] David Abrahams and Aleksey Gurtovy C++ Template Metaprogramming: > Concepts, Tools, and Techniques from Boost and Beyond (C++ in > Depth Series), Addison-Wesley Professional. ISBN:0321227255. 2004. >=20 > [4] Code listing: >=20 > //"c:/program files (x86)/Microsoft Visual Studio 10.0/vc/vcvarsall.b= at" x64 > //cl /Fedimension.exe /EHsc /I d:/boost_1_55_0 dimension.cpp >=20=20=20=20=20 > #include > #include > #include > #include > #include > #include > #include >=20=20=20=20=20 > typedef boost::mpl::vector_c mass; > typedef boost::mpl::vector_c length; > typedef boost::mpl::vector_c time; > typedef boost::mpl::vector_c charge; > typedef boost::mpl::vector_c temperature; > typedef boost::mpl::vector_c intensity; > typedef boost::mpl::vector_c angle; > typedef boost::mpl::vector_c velocity; // l/t > typedef boost::mpl::vector_c acceleration; // l/(= t2) > typedef boost::mpl::vector_c momentum; // ml/t > typedef boost::mpl::vector_c force; // ml/= (t2) > typedef boost::mpl::vector_c scalar; >=20=20=20=20=20 > template > class quantity > { > public: > explicit quantity (T val)=20 > : val (val) > {} > template > quantity (quantity const& other) > : val (other.value ()) { > BOOST_MPL_ASSERT( (boost::mpl::equal= )); > } > T value () const { return val; } > private: > T val; > }; >=20=20=20=20=20 > template > quantity > operator + (quantity x, quantity y ) > { > return quantity(x.value () + y.value ()); > } >=20=20=20=20=20 > template > quantity > operator - (quantity x, quantity y ) > { > return quantity(x.value () - y.value ()); > } >=20=20=20=20=20 > template > quantity < > T > , typename boost::mpl::transform< > D1, D2, boost::mpl::plus< > boost::mpl::placeholders::_1 > , boost::mpl::placeholders::_2> >::type=20 > > > operator* (quantity x, quantity y) > { > typedef typename boost::mpl::transform< > D1, D2, boost::mpl::plus< > boost::mpl::placeholders::_1 > , boost::mpl::placeholders::_2> >::type D; >=20=20=20=20=20 > return quantity (x.value () * y.value ()); > } >=20=20=20=20=20 > template > quantity < > T > , typename boost::mpl::transform< > D1, D2, boost::mpl::minus< > boost::mpl::placeholders::_1 > , boost::mpl::placeholders::_2> >::type=20 > > > operator/ (quantity x, quantity y) > { > typedef typename boost::mpl::transform< > D1, D2, boost::mpl::minus< > boost::mpl::placeholders::_1 > , boost::mpl::placeholders::_2> >::type D; >=20=20=20=20=20 > return quantity (x.value () / y.value ()); > } >=20=20=20=20=20 > // -- test >=20=20=20=20=20 > #include > #include > #include >=20=20=20=20=20 > int main () > { > quantity m (5.0f); > quantity a(9.8f); > quantity f =3D m * a; > quantity m2 =3D f / a; >=20=20=20=20=20 > assert ((std::abs ((m2 - m).value ())) <=3D std::numeric_limits::epsilon ()); >=20=20=20=20=20 > return 0; > } >=20 --Apple-Mail=_E6E53CB7-9E97-40D1-BE88-7A816AD7E02E Content-Transfer-Encoding: quoted-printable Content-Type: text/html; charset=us-ascii You might be interested by=  http://akabe.github.io/slap/=

Thomas

On 16 Oct 2014, at 1= 7:37, Shayne Fletcher <s= hayne.fletcher.50@gmail.com> wrote:

Dear OCamlers,

In 1994, Ba= rton and Nackman in their book 'Scientific Engineering in
C++' [= 1] demonstrated how one could encode the rules of Dimensional
Analysis [2] into the C++ type system enabling compile-time checkin= g
(no runtime-cost) of the plausibility (at least up t= o the dimensional
correctness) of computations.

<= /font>
In 2004, Abrahams & Gurtovy in 'C++ Template Metaprogramming= ' [3]
showed the Barton Nackman technique to be elegantly implem= entable
using compile time type sequences encoding integer const= ants. At the
end of this post, I provide a complete listing of t= heir example
program [4].

The key pro= perties of the system (as I see it) are:
  - Encoding of in= tegers as types; 
=   - Compile time manipulation of seq= uences of these integer encodings
    to deduce/produc= e new derived types.

Now, it is not immediately = obvious to me how to approach this problem
in OCaml. It irks me = some that I can't immediately produce a yet more
elegant OCaml p= rogram for this problem and leaves me feeling like C++
has "got = something over on us" here ;)

My question theref= ore is: Does anyone have suggestions/pointers
on how to approach= automatic dimensional analysis via the OCaml type
system?&nbs= p;

Best,

-- 
Shayne Fletcher

[1] John J. Barton and Lee R. Nackm= an. Scientific and Engineering C++:
    an Introductio= n with Advanced Techniques and Examples. Reading,
    = MA: Addison Wesley. ISBN 0-201-53393-6. 1994.

<= div class=3D"gmail_default" style=3D"">[2= ] Wikipedia h= ttp://en.wikipedia.org/wiki/Dimensional_analysis

=
[3] David Abrahams and Aleksey Gurtovy C++ Template Metaprogramming:
    Concepts, Tools, and Techniques from Boost and Beyo= nd (C++ in
    Depth Series), Addison-Wesley Profess= ional. ISBN:0321227255. 2004.

[4] Code listing:<= /font>

    //"c:/program files (x86)/Microsof= t Visual Studio 10.0/vc/vcvarsall.bat" x64
    //cl /F= edimension.exe /EHsc /I d:/boost_1_55_0 dimension.cpp
  &nb= sp; 
    #include <boost/mpl/vector_c.hpp><= /font>
    #include <boost/mpl/transform.hpp>
&nbs= p;   #include <boost/mpl/equal.hpp>
    #in= clude <boost/mpl/plus.hpp>
    #include <boos= t/mpl/minus.hpp>
    #include <boost/static_asse= rt.hpp>
    
    typede= f boost::mpl::vector_c<int,1,0,0,0,0,0,0> mass;
  &nb= sp; typedef boost::mpl::vector_c<int,0,1,0,0,0,0,0> length;
    typedef boost::mpl::vector_c<int,0,0,0,1,0,0,0= > charge;
    typedef boost::mpl::vector_c<int,0= ,0,0,0,1,0,0> temperature;
    typedef boost::mpl::= vector_c<int,0,0,0,0,0,1,0> intensity;
    typed= ef boost::mpl::vector_c<int,0,0,0,0,0,0,1> angle;
  &= nbsp; typedef boost::mpl::vector_c<int,0,1,-1,0,0,0,0> velocity; &nbs= p;   // l/t
    typedef boost::mpl::vector_c<i= nt,0,1,-2,0,0,0,0> acceleration; // l/(t2)
    type= def boost::mpl::vector_c<int,1,1,-1,0,0,0,0> momentum;     = // ml/t
    typedef boost::mpl::vector_c<int,1,1,-2= ,0,0,0,0> force;        // ml/(t2)
 =   typedef boost::mpl::vector_c<int,0,0,0,0,0,0,0> scalar;
    
    template <class T, cl= ass Dimensions>
    class quantity
 = ;   {
    public:
    &nbs= p; explicit quantity (T val) 
        := val (val)
      {}
    &n= bsp; template <class OtherDimensions>
     = quantity (quantity<T, OtherDimensions> const& other)
=         : val (other.value ()) {
  &nbs= p;     BOOST_MPL_ASSERT( (boost::mpl::equal<Dimensions, OtherD= imensions>));
      }
  &nbs= p;   T value () const { return val; }
    private= :
      T val;
    };=
    
    template <class T, cla= ss D>
    quantity<T, D>
  &n= bsp; operator + (quantity<T, D> x, quantity<T, D> y )
      return quantity<T, D&g= t;(x.value () + y.value ());
    }
  &= nbsp; 
    template <class T, class D>
    quantity<T, D>
    operato= r - (quantity<T, D> x, quantity<T, D> y )
  &nb= sp; {
      return quantity<T, D>(x.value (= ) - y.value ());
    }
    <= /font>
    template <class T, class D1, class D2>
    quantity <
      T<= /div>
    , typename boost::mpl::transform<
  &n= bsp;     D1, D2, boost::mpl::plus<
    &n= bsp;             boost::mpl::placeholders::_1=
                , boost= ::mpl::placeholders::_2> >::type 
    ><= /font>
    operator* (quantity<T, D1> x, quantity <T= , D2> y)
    {
      typ= edef typename boost::mpl::transform<
      &nb= sp; D1, D2, boost::mpl::plus<
        &nb= sp;         boost::mpl::placeholders::_1
&nb= sp;                 , boost::mpl::p= laceholders::_2> >::type D;
    
      return quantity<T, D> (x.value () * y.value ())= ;
    }
    
&nbs= p;   template <class T, class D1, class D2>
  &n= bsp; quantity <
      T
  &nbs= p; , typename boost::mpl::transform<
      &nb= sp; D1, D2, boost::mpl::minus<
        &n= bsp;         boost::mpl::placeholders::_1
<= div class=3D"gmail_default" style=3D"">&n= bsp;               , boost::mpl::placeho= lders::_2> >::type 
    >
&nb= sp;   operator/ (quantity<T, D1> x, quantity <T, D2> y)
    {
      typedef typename b= oost::mpl::transform<
        D1, D2, boo= st::mpl::minus<
            &nb= sp;     boost::mpl::placeholders::_1
    &nb= sp;             , boost::mpl::placeholders::_= 2> >::type D;
    
  &nbs= p;   return quantity<T, D> (x.value () / y.value ());
    }
    
    //= -- test
    
    #include &= lt;iostream>
    #incl= ude <limits>
    #include <cassert>
=     
    int main ()
  =   {
      quantity<float, mass> m (5.0= f);
      quantity<float, acceleration> a(9= .8f);
      quantity<float, force> f =3D m = * a;
      quantity<float, mass> m2 =3D f /= a;
    
      assert (= (std::abs ((m2 - m).value ())) <=3D std::numeric_limits<double>::e= psilon ());
    
     = return 0;
    }


= --Apple-Mail=_E6E53CB7-9E97-40D1-BE88-7A816AD7E02E--