// Boost.Units - A C++ library for zero-overhead dimensional analysis and // unit/quantity manipulation and conversion // // Copyright (C) 2003-2008 Matthias Christian Schabel // Copyright (C) 2008 Steven Watanabe // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // $Id: math_functional_lambda.cpp 46 2008-08-19 16:47:23Z maehne $ //////////////////////////////////////////////////////////////////////// /// /// \file math_functional_lambda.cpp /// /// \brief Example demonstrating the usage of Boost.Units' quantity, /// unit, and absolute types in functors created with the /// Boost.Lambda library and stored in Boost.Function objects. /// /// \author Torsten Maehne /// \date 2008-06-20 /// /// Mechanical, thermal, geometrical, and electrical examples /// demonstrate how to use Boost.Units' quantity, unit, and absolute /// types in lambda expressions. The resulting functors can be stored /// in boost::function objects. It is also shown how to work around a /// limitation of Boost.Lambda's bind() to help it to find the correct /// overloaded function by specifying its signature with a /// static_cast. This tedious task can be avoided by using the the /// functor wrappers defined in \. /// //////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include // Include functor wrappers for common mathematical function found in // \, Boost.Math, or \. #include // Include \ instead of // \ for a convenient usage of Boost.Units' // quantity, unit, and absolute types in lambda expressions. The // header augments Boost.Lambda's return type deduction system to // recognize the new types so that not for each arithmetic operation // the return type needs to be explicitely specified. #include #include int main(int argc, char **argv) { // namespace aliases namespace bl = boost::lambda; namespace bu = boost::units; namespace si = boost::units::si; namespace bmf = boost::math::functional; namespace buf = boost::units::functional; // pull in some namespaces and frequently used defintions using namespace std; using namespace bmf; using namespace buf; using bu::quantity; using bu::absolute; using bl::bind; using bl::_1; using bl::_2; using bl::_3; //////////////////////////////////////////////////////////////////////// // Mechanical example: linear accelerated movement //////////////////////////////////////////////////////////////////////// // Initial condition variables for acceleration, speed, and displacement quantity a = 2.0 * si::meters_per_second_squared; quantity v = 1.0 * si::meters_per_second; quantity s0 = 0.5 * si::meter; // Displacement over time boost::function (quantity) > s = 0.5 * bl::var(a) * _1 * _1 + bl::var(v) * _1 + bl::var(s0); cout << "Linear accelerated movement:" << endl << "a = " << a << ", v = " << v << ", s0 = " << s0 << endl << "s(1.0 * si::second) = " << s(1.0 * si::second) << endl << endl; // Change initial conditions a = 1.0 * si::meters_per_second_squared; v = 2.0 * si::meters_per_second; s0 = -1.5 * si::meter; cout << "a = " << a << ", v = " << v << ", s0 = " << s0 << endl << "s(1.0 * si::second) = " << s(1.0 * si::second) << endl << endl; //////////////////////////////////////////////////////////////////////// // Thermal example: temperature difference of two absolute temperatures //////////////////////////////////////////////////////////////////////// // Absolute temperature constants const quantity > Tref = 273.15 * absolute(); const quantity > Tamb = 300.00 * absolute(); boost::function (quantity >, quantity >)> dT = _2 - _1; cout << "Temperature difference of two absolute temperatures:" << endl << "dT(" << Tref << ", " << Tamb << ") = " << dT(Tref, Tamb) << endl << endl; //////////////////////////////////////////////////////////////////////// // Geometric example: area calculation for a square //////////////////////////////////////////////////////////////////////// // Length constant const quantity l = 1.5 * si::meter; // The invocation of the pow<2> function needs to be postponed // using bind to calculate the square area at each functor call. A // lengthy static_cast to the function pointer referencing // boost::units::pow<2>() is needed to avoid an "unresolved // overloaded function type" error. boost::function (quantity) > A = bind(static_cast (*)(const quantity&)>(bu::pow<2>), _1); cout << "Area of a square:" << endl << "A(" << l <<") = " << A(l) << endl << endl; //////////////////////////////////////////////////////////////////////// // Electrical example: oscillating current //////////////////////////////////////////////////////////////////////// // Constants for the current amplitude, frequency, and offset current const quantity iamp = 1.5 * si::ampere; const quantity f = 1.0e3 * si::hertz; const quantity i0 = 0.5 * si::ampere; // In this example we use the functor wrapper sin_t defined in // \ for sin and can thus avoid // the static_cast in the bind call. boost::function (quantity) > i = iamp * bind(sin_t(), 2.0 * M_PI * si::radian * f * _1) + i0; cout << "Oscillating current:" << endl << "iamp = " << iamp << ", f = " << f << ", i0 = " << i0 << endl << "i(1.25e-3 * si::second) = " << i(1.25e-3 * si::second) << endl << endl; return 0; }