Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: Thomas Gazagnaire <thomas@gazagnaire.org>
To: Shayne Fletcher <shayne.fletcher.50@gmail.com>
Cc: "caml-list@inria.fr users" <caml-list@inria.fr>
Subject: Re: [Caml-list] Dimensional Analysis question
Date: Thu, 16 Oct 2014 19:10:56 +0100	[thread overview]
Message-ID: <EB5D22A2-A852-49F2-B953-E7AF3F93BFF6@gazagnaire.org> (raw)
In-Reply-To: <CAMsAzy_LvL-cUzsgfX+pPMioSBjb=70n28yQcw9UiP04YTq5KQ@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 5851 bytes --]

You might be interested by http://akabe.github.io/slap/

Thomas

On 16 Oct 2014, at 17:37, Shayne Fletcher <shayne.fletcher.50@gmail.com> wrote:

> Dear OCamlers,
> 
> 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.
> 
> 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].
> 
> The key properties of the system (as I see it) are:
>   - Encoding of integers as types; 
>   - Compile time manipulation of sequences of these integer encodings
>     to deduce/produce 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 program for this problem and leaves me feeling like C++
> has "got something over on us" here ;)
> 
> My question therefore is: Does anyone have suggestions/pointers
> on how to approach automatic dimensional analysis via the OCaml type
> system? 
> 
> Best,
> 
> -- 
> Shayne Fletcher
> 
> [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.
> 
> [2] Wikipedia http://en.wikipedia.org/wiki/Dimensional_analysis
> 
> [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.
> 
> [4] Code listing:
> 
>     //"c:/program files (x86)/Microsoft Visual Studio 10.0/vc/vcvarsall.bat" x64
>     //cl /Fedimension.exe /EHsc /I d:/boost_1_55_0 dimension.cpp
>     
>     #include <boost/mpl/vector_c.hpp>
>     #include <boost/mpl/transform.hpp>
>     #include <boost/mpl/placeholders.hpp>
>     #include <boost/mpl/equal.hpp>
>     #include <boost/mpl/plus.hpp>
>     #include <boost/mpl/minus.hpp>
>     #include <boost/static_assert.hpp>
>     
>     typedef boost::mpl::vector_c<int,1,0,0,0,0,0,0> mass;
>     typedef boost::mpl::vector_c<int,0,1,0,0,0,0,0> length;
>     typedef boost::mpl::vector_c<int,0,0,1,0,0,0,0> time;
>     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;
>     typedef boost::mpl::vector_c<int,0,0,0,0,0,0,1> angle;
>     typedef boost::mpl::vector_c<int,0,1,-1,0,0,0,0> velocity;     // l/t
>     typedef boost::mpl::vector_c<int,0,1,-2,0,0,0,0> acceleration; // l/(t2)
>     typedef 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, class Dimensions>
>     class quantity
>     {
>     public:
>       explicit quantity (T val) 
>         : val (val)
>       {}
>       template <class OtherDimensions>
>       quantity (quantity<T, OtherDimensions> const& other)
>         : val (other.value ()) {
>         BOOST_MPL_ASSERT( (boost::mpl::equal<Dimensions, OtherDimensions>));
>       }
>       T value () const { return val; }
>     private:
>       T val;
>     };
>     
>     template <class T, class D>
>     quantity<T, D>
>     operator + (quantity<T, D> x, quantity<T, D> y )
>     {
>       return quantity<T, D>(x.value () + y.value ());
>     }
>     
>     template <class T, class D>
>     quantity<T, D>
>     operator - (quantity<T, D> x, quantity<T, D> y )
>     {
>       return quantity<T, D>(x.value () - y.value ());
>     }
>     
>     template <class T, class D1, class D2>
>     quantity <
>       T
>     , typename boost::mpl::transform<
>         D1, D2, boost::mpl::plus<
>                   boost::mpl::placeholders::_1
>                 , boost::mpl::placeholders::_2> >::type 
>     >
>     operator* (quantity<T, D1> x, quantity <T, D2> y)
>     {
>       typedef typename boost::mpl::transform<
>         D1, D2, boost::mpl::plus<
>                   boost::mpl::placeholders::_1
>                   , boost::mpl::placeholders::_2> >::type D;
>     
>       return quantity<T, D> (x.value () * y.value ());
>     }
>     
>     template <class T, class D1, class D2>
>     quantity <
>       T
>     , typename boost::mpl::transform<
>         D1, D2, boost::mpl::minus<
>                   boost::mpl::placeholders::_1
>                 , boost::mpl::placeholders::_2> >::type 
>     >
>     operator/ (quantity<T, D1> x, quantity <T, D2> y)
>     {
>       typedef typename boost::mpl::transform<
>         D1, D2, boost::mpl::minus<
>                   boost::mpl::placeholders::_1
>                   , boost::mpl::placeholders::_2> >::type D;
>     
>       return quantity<T, D> (x.value () / y.value ());
>     }
>     
>     // -- test
>     
>     #include <iostream>
>     #include <limits>
>     #include <cassert>
>     
>     int main ()
>     {
>       quantity<float, mass> m (5.0f);
>       quantity<float, acceleration> a(9.8f);
>       quantity<float, force> f = m * a;
>       quantity<float, mass> m2 = f / a;
>     
>       assert ((std::abs ((m2 - m).value ())) <= std::numeric_limits<double>::epsilon ());
>     
>       return 0;
>     }
> 


[-- Attachment #2: Type: text/html, Size: 20288 bytes --]

  parent reply	other threads:[~2014-10-16 18:11 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-10-16 16:37 Shayne Fletcher
2014-10-16 17:21 ` Octachron
2014-10-16 17:35 ` Mario Alvarez Picallo
2014-10-17  5:58   ` Octachron
2014-11-10 18:14   ` Shayne Fletcher
2014-10-16 18:10 ` Thomas Gazagnaire [this message]
2014-10-17 10:22   ` David MENTRE
2014-10-16 19:36 ` Shayne Fletcher
2014-10-17  6:50 ` Roberto Di Cosmo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=EB5D22A2-A852-49F2-B953-E7AF3F93BFF6@gazagnaire.org \
    --to=thomas@gazagnaire.org \
    --cc=caml-list@inria.fr \
    --cc=shayne.fletcher.50@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox