しかし
人に見せるコードじゃないなこれ
それにコードは別の場所に置いてそこにリンクする方がいいような
もうひとつ
次は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;
}
データは(というかネタも)匿名掲示板のスレから頂いてきた
ただ単に色々使ってみただけってコードだけど、まぁいいか
コード記法
id:mb2sync氏の:p-stadeライブラリを使ってstd::accumulateをpipableにしてみる
見様見真似なので正しいかどうかはわからない
#ifndef NUMERIC_DWA20071016_HPP
#if (_MSC_VER >= 1020)
# pragma once
#endif
# define NUMERIC_DWA20071016_HPP
#include <numeric>
#include <boost/range/value_type.hpp>
#include <pstade/adl_barrier.hpp>
#include <pstade/egg/auxiliary.hpp>
#include <pstade/egg/function.hpp>
#include <pstade/pod_constant.hpp>
#include <pstade/egg/pipable.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_convertible.hpp>
// 独自名前空間でpipable objectの定義を行う
namespace nlptr {
namespace accumulate_detail
{
struct baby
{
// 戻り値とテンプレートパラメータ(関数オブジェクトの指定は任意なのでdefault値void)
template< class Myself, class Range, class Value, class Function = void>
struct apply :
boost::range_value<Range>
{ };
// 関数本体
template< class Result, class Range, class Value, class Function >
Result call(Range& rng, Value const& init, Function const& func) const
{
// range_value<Range> == Value
BOOST_STATIC_ASSERT((
boost::is_convertible<
typename boost::range_value<Range>::type, Value
>::value
));
return std::accumulate(boost::begin(rng), boost::end(rng), init, func);
}
// デフォルトの関数オブジェクト
template< class Result, class Range, class Value>
Result call(Range& rng, Value const& init) const
{
// range_value<Range> == Value
BOOST_STATIC_ASSERT((
boost::is_convertible<
typename boost::range_value<Range>::type, Value
>::value
));
return std::accumulate(boost::begin(rng), boost::end(rng), init);
}
};
typedef pstade::egg::function<baby> op;
} // namespace accumulate_detail
// std::accumulateと名前が被る?
PSTADE_ADL_BARRIER(nlptr_accumulate) {
namespace egg = pstade::egg;
PSTADE_POD_CONSTANT(
(egg::result_of_pipable< accumulate_detail::op >::type)
, accumulate
) = PSTADE_EGG_PIPABLE_L {{}} PSTADE_EGG_PIPABLE_R;
} // adl barrier
} // namespace nlptr
# endif
// NUMERIC_DWA20071016_HPP
使用例
#include <nlptr/algos/numeric.hpp>
#include <iostream>
#include <pstade/oven/counting.hpp>
#include <boost/lambda/lambda.hpp>
int main(void) {
namespace oven = pstade::oven;
using boost::lambda::_1;
using boost::lambda::_2;
assert(
( (oven::counting(0,10)|nlptr::accumulate(0)) == 45 ) &&
( (oven::counting(0,10)|nlptr::accumulate(0, _1 + _2)) == 45 )
);
}いい加減にboost.testの使い方も覚えなければならない
hatedaraインストール
これでEmacsから更新ができる
emacs-unicode2
どうやらalignのような空白を補間して位置をそろえるような機能がうまく動作しないようだ。
23.0.50はまだ恐いしとりあえず22を入れる事にする。
.emacs弄りまではまだまだ遠い。