もうひとつ
次はegg.lazyでstd::powをlazy化してみる
#ifndef LAZY_POW_DWA20071016_HPP #if _MSC_VER >= 1020 # pragma once #endif // _MSC_VER >= 1020 # define LAZY_POW_DWA20071016_HPP # include <pstade/egg/lazy.hpp> namespace nlptr { namespace detail_lazy_pow { struct base { template< class Myself, class Arg1, class Arg2> struct apply { typedef Arg1 type; // base::apply::typeが戻り値? }; template< class Result, class Arg1, class Arg2> Result call(Arg1 a1, Arg2 a2) const // const忘れると駄目 { return std::pow(a1, a2); } }; typedef pstade::egg::function<base> op; } // namespace detail_lazy_pow PSTADE_ADL_BARRIER(nlptr_lazy_pow) { namespace egg = pstade::egg; PSTADE_POD_CONSTANT( (egg::result_of_lazy< detail_lazy_pow::op>::type) , pow_lz ) = PSTADE_EGG_LAZY_L {{}} PSTADE_EGG_LAZY_R; } // adl barrier } // namespace nlptr # endif // LAZY_POW_DWA20071016_HPP
上のaccumulateと併わせて使ってみる
#include <pstade/vodka/drink.hpp> #include <nlptr/algos/numeric.hpp> #include <nlptr/progress.hpp> #include <nlptr/math/lazy_pow.hpp> #include <boost/range.hpp> #include <pstade/oven/initial_values.hpp> #include <pstade/oven/transformed.hpp> #include <pstade/oven/regular.hpp> #include <pstade/oven/copied.hpp> #include <pstade/oven/foreach.hpp> #include <boost/lambda/lambda.hpp> #include <boost/lambda/bind.hpp> #include <iostream> #include <vector> #include <boost/format.hpp> #include <cmath> #include <boost/typeof/typeof.hpp> /////////////////////////////////////////////////////////////// // MACRO ALIASES /////////////////////////////////////////////////////////////// // Boost.TypeOf #ifdef BOOST_TYPEOF_TYPEOF_HPP_INCLUDED # define btypeof_ BOOST_TYPEOF # define bauto_ BOOST_AUTO // テンポラリを取得するときに便利かも… # ifdef BOOST_CALL_TRAITS_HPP # define auto_ref_(Name,Expr) \ boost::call_traits<BOOST_TYPEOF(Expr)>::param_type Name = Expr; # endif #endif // Pstade.Oven #ifdef PSTADE_OVEN_FOREACH # define foreach_oven PSTADE_OVEN_FOREACH #endif // Boost.Foreach #ifdef BOOST_FOREACH # define foreach_ BOOST_FOREACH #endif int main(void) { namespace oven = pstade::oven; namespace bll = boost::lambda; nlptr::progress_timer timer; std::vector<double> src_data = oven::initial_values( 3.14, 5.00, 3.57, 5.44 , 2.14, 7.00, 5.00, 3.33 ); bauto_( src_sum , src_data | nlptr::accumulate(0.0) ); bauto_( src_num, boost::size(src_data) ); bauto_( src_average , src_sum / static_cast<btypeof_(src_sum)>(src_num) ); // 標準偏差の公式の分母 btypeof_(src_data) denom = ( src_data | oven::transformed( oven::regular( nlptr::pow_lz(bll::_1 - bll::constant(src_average), 2.0) )) | oven::copied ); // 標本標準偏差 bauto_( stdev , std::sqrt( ( denom | nlptr::accumulate(0.0) )/ src_num ) ); // 母集団標準偏差 bauto_( stdevp , std::sqrt( ( denom | nlptr::accumulate(0.0) ) / (src_num - 1) ) ); std::cout << boost::format("標本標準偏差\t: %f\n母集団標準偏差\t: %f\n") %stdev %stdevp ; return EXIT_SUCCESS; }
データは(というかネタも)匿名掲示板のスレから頂いてきた
ただ単に色々使ってみただけってコードだけど、まぁいいか