Call

概要

Expressionsで定義した関数を呼び出すための機能を提供する。

  • ヘッダ
#include <tlnc/call.hpp>

関数一覧

いずれもtlnc名前空間に属する。

call(Func&&, Arg&&)
call(Func&&, Tuple&&)
call(Func&&, Arg&&, Memo&&)
call(Func&&, Tuple&&, Memo&&)

プレースホルダーが含まれる関数を呼ぶときは2番目の引数にタプルを渡す。 詳細は使い方を参照。 引数にMemoが含まれている関数についてはメモ化を参照。

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>));

このような定義の関数fghを使って呼び出しの方法について説明する。 fは1変数関数、gは2変数関数である。 hプレースホルダーが含まれる2変数関数である。

プレースホルダーのない関数

fgにはプレースホルダーが含まれていない。 このような関数は単純に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);