Call¶
関数一覧¶
いずれもtlnc
名前空間に属する。
-
call
(Func&&, Arg&&)¶
-
call
(Func&&, Tuple&&)¶
-
call
(Func&&, Arg&&, Memo&&)¶
使い方¶
数式の書き方についてはExpressionsの使い方を参照。
#include <bcl/literals.hpp>
using namespace bcl::literals;
using tlnc::x;
using tlnc::cos;
using tlnc::sin;
using tlnc::_1;
auto f = 2.0_dc * x<>;
auto g = 2.0_dc * x<0> * x<1> + cos(sin(x<0>));
auto h = _1 * x<0> * x<1> + cos(sin(x<0>));
このような定義の関数f
、g
、h
を使って呼び出しの方法について説明する。
f
は1変数関数、g
は2変数関数である。
h
はプレースホルダーが含まれる2変数関数である。
プレースホルダーのない関数¶
f
やg
にはプレースホルダーが含まれていない。
このような関数は単純にtlnc::call()
に関数と引数を渡すだけで呼び出すことができる。
1変数関数¶
f
はプレースホルダーのない1変数関数なので単純に値を渡すだけで呼び出すことができる。
#include <kv/interval.hpp>
tlnc::call(f, 1.0);
tlnc::call(f, kv::interval<double>(1.0));
2変数関数¶
g
のような多変数関数の場合はBoost.uBLASのベクトルを引数に渡さなければならない。
#include <boost/numeric/ublas/vector.hpp>
boost::numeric::ublas::bounded_vector<double, 2> v(2);
v(0) = 1.0;
v(1) = 2.0;
tlnc::call(g, v);
g
にはプレースホルダーが0個含まれているとみなして、
プレースホルダーの含まれる関数と同じように呼び出すこともできる。
#include <boost/numeric/ublas/vector.hpp>
#include <bcl/tuple.hpp>
boost::numeric::ublas::bounded_vector<double, 2> v(2);
v(0) = 1.0;
v(1) = 2.0;
tlnc::call(g, bcl::make_tuple(v));
プレースホルダーの含まれる関数¶
プレースホルダーの含まれる関数はタプルを渡すことで呼び出すことができる。
tlnc::_1
はタプルの1番目(bcl::get<1>(tuple)
)に置き換えられる。
タプルの要素数はプレースホルダーの番号の最大値より大きくなければならない。
#include <boost/numeric/ublas/vector.hpp>
#include <bcl/tuple.hpp>
boost::numeric::ublas::bounded_vector<double, 2> v(2);
v(0) = 1.0;
v(1) = 2.0;
tlnc::call(h, bcl::make_tuple(v, 2.0));
メモ化¶
メモ化をすると関数の呼び出しを高速化することができる。
#include <boost/numeric/ublas/vector.hpp>
#include <bcl/tuple.hpp>
boost::numeric::ublas::bounded_vector<double, 2> v(2);
v(0) = 1.0;
v(1) = 2.0;
auto result1 = tlnc::call(g, v, tlnc::memo());
auto result2 = tlnc::call(h, bcl::make_tuple(v, 1.0), tlnc::memo());
メモを渡したときは呼び出し結果と新しいメモのペア(std::pair
)が返る。
引数が一定の時はメモを使いまわすことができ、
そうすることで前に呼び出した関数と重複する部分の評価を省略することができる。
#include <boost/numeric/ublas/vector.hpp>
boost::numeric::ublas::bounded_vector<double, 2> v(2);
v(0) = 1.0;
v(1) = 2.0;
auto g2 = 2.0_dc * x<0> * x<1> + tan(x<0>);
auto result1 = tlnc::call(g, v, tlnc::memo());
// gと重複する部分(2.0_dc * x<0> * x<1>)の評価を省略できる
auto result2 = tlnc::call(g2, v, result1.second);