もうひとつ

次は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;
}

データは(というかネタも)匿名掲示板のスレから頂いてきた
ただ単に色々使ってみただけってコードだけど、まぁいいか