.. _expressions: Expressions =========== 概要 ---- 数式を記述するための機能を提供する。 * ヘッダ .. code-block:: cpp #include 関数一覧 -------- いずれも\ ``tlnc``\ 名前空間に属する。 詳しい使い方は\ :ref:`expr-usage`\ を参照。 特に説明のない関数は、 引数として\ ``double``\ 型や\ ``kv::interval``\ 等の通常の値型を渡すと :ref:`generic`\ の関数と同様の動作をする。 いずれの関数も引数として式を渡すと数式となる。 .. cpp:function:: cos(Expr &&) .. cpp:function:: sin(Expr &&) .. cpp:function:: tan(Expr &&) .. cpp:function:: log(Expr &&) .. cpp:function:: pow(Base &&, Exponent &&) .. cpp:function:: prod(Expr1 &&, Expr2 &&) Boost.uBLASの\ ``prod``\ と同様な動作をする。 ベクトルや行列の積を計算する。 .. cpp:function:: element_prod(Expr1 &&, Expr2 &&) Boost.uBLASの\ ``element_prod``\ と同様な動作をする。 同じ大きさのベクトルや行列を渡すと要素ごとの積を計算する。 .. cpp:function:: at(Expr &&) ベクトルや行列を返す式を受け取り、 式の評価結果から\ ``Is...``\ 要素を取り出す式を返す。 ``Is...``\ が1個の時はベクトルを返す式を、 ``Is...``\ が2個の時は行列を返す式を渡さなければならない。 .. cpp:function:: c(T &&) 定数関数を返す。 ``T``\ は何らかの値を表す型で、\ ``T::value``\ で保持している値を取得できるものとする。 変数一覧 -------- いずれも\ ``tlnc``\ 名前空間に属する。 詳しい使い方は\ :ref:`expr-usage`\ を参照。 .. cpp:var:: unspecified x ``std::size_t``\ 型の非型テンプレートパラメータ\ ``Is...``\ を受け取る変数テンプレート。 ``Is...``\ が空の時は引数そのものを表し、 ``Is...``\ が1個の時は引数として渡されるベクトルのある要素を表し、 ``Is...``\ が2個の時は引数として渡される行列のある要素を指す。 ``Is...``\ が3個以上の時はコンパイルエラーとなる。 .. cpp:var:: unspecified _1 プレースホルダーを表す。同様の変数が\ ``_10``\ まで定義されている。 使い方は\ :ref:`expr-usage-placeholders`\ を参照。 .. cpp:var:: unspecified holder プレースホルダーが10個で足りないときに使う。 .. _expr-usage: 使い方 ------ 呼び出し方については\ :ref:`call-`\ を、 微分については\ :ref:`derivative-`\ を参照。 定数関数 ^^^^^^^^ :math:`2x`\ の係数\ :math:`2`\ のようなものも含めて、式内の全ての定数は定数関数とみなす。 つまり\ :math:`f(x) = 2x`\ という関数は、 .. math:: &f_1(x) = 2\\ &f_2(x) = x\\ &f(x) = f_1(x) \cdot f_2(x) のような関数の積だと考える。 定数関数はマクロかユーザー定義リテラルと関数の組み合わせによって記述する。 ``double``\ 型の定数か\ ``double``\ 型を要素とする区間を記述することができる。 マクロ """""" .. code-block:: cpp #include auto f = TLNC_C(1.0); auto g = TLNC_I(1.0); auto h = TLNC_I(1.0, 2.0); ``f``\ は\ ``double``\ 型の定数\ ``1.0``\ を返す関数、 ``g``\ は\ ``kv::interval``\ 型の点区間\ :math:`[1.0, 1.0]`\ を返す関数、 ``h``\ は\ ``kv::interval``\ 型の区間\ :math:`[1.0, 2.0]`\ を返す関数を表す。 ``TLNC_C``\ マクロに対して\ ``C_``\ 、\ ``TLNC_I``\ マクロに対して\ ``I_``\ という別名も定義される。 .. _expr-usage-constant-literal: ユーザー定義リテラルと関数 """""""""""""""""""""""""" ユーザー定義リテラルを用いると、(定数関数ではなく)定数を表す特殊なオブジェクトを作ることができる。 そのオブジェクトを\ ``tlnc::c``\ 関数に渡すと定数関数を生成することができるが、 実際には純粋な定数関数を生成する場合以外は\ ``tlnc::c``\ を使わなくても期待した動作をする。 .. code-block:: cpp #include // double型の定数を生成する #include // double型の点区間を生成する #include // double型の区間を生成する using bcl::literals; // _dcリテラルを使えるようにする using cti::literals; // _diリテラルを使えるようにする using cti::operators; // _dcリテラルに対するoperator,を使えるようにする { // (定数関数ではない)定数 auto f = 1.0_dc; // 定数1.0 auto g = 1.0_di; // 点区間[1.0, 1.0] auto h = (1.0_dc, 2.0_dc); // 区間[1.0, 2.0] } { // 定数関数 auto f = tlnc::c(1.0_dc); auto g = tlnc::c(1.0_di); auto h = tlnc::c((1.0_dc, 2.0_dc)); } { // 関数 using tlnc::x; auto f = 1.0_dc * x<>; auto g = tlnc::c(1.0_dc) * x<>; } 関数を含む式 ^^^^^^^^^^^^ 多項式\ :math:`f(x) = x^2 + 2x + 1`\ は、関数\ ``pow``\ を用いて以下のように書ける。 .. code-block:: cpp using tlnc::x; using tlnc::pow; auto f = pow(x<>, 2_dc) + 2_dc * x<> + 1_dc; :math:`g(x) = \cos(\sin(x))`\ のように入れ子にすることもできる。 .. code-block:: cpp using tlnc::x; using tlnc::cos; using tlnc::sin; auto g = cos(sin(x<>)); 多変数関数 ^^^^^^^^^^ 多変数関数は、ベクトルを受け取る関数として定義する。 例えば、\ :math:`f(x_0, x_1) = x_0 x_1 + \cos(\sin(x_0))`\ は次のように定義する。 .. code-block:: cpp using tlnc::x; using tlnc::cos; using tlnc::sin; auto f = x<0> * x<1> + cos(sin(x<0>)); ``x<0>``\ は「引数として渡されたベクトルの0番目の要素を取り出す」という意味である。 :cpp:func:`element_prod`\ のようなベクトルを受け取る関数に引数を渡す時は、 ``element_prod(x<>, x<>)``\ のように\ ``x<>``\ を使えばよい。 ``x<0, 0>``\ のように書けば行列を受け取る関数も記述できる。 行列やベクトルはBoost uBLASのものを使うことを前提としている。 .. _expr-usage-vector-matrix: ベクトルや行列を返す関数 ^^^^^^^^^^^^^^^^^^^^^^^^ 関数を\ ``,``\ でつなぐとベクトルを返す関数を記述でき、 ベクトルを返す関数を\ ``,``\ でつなぐと行列を返す関数を記述できる。 .. code-block:: cpp using bcl::literals; using tlnc::x; auto f = (x<>, 2.0_dc * x<>); auto g = (f, (3.0_dc * x<>, 4.0_dc * x<>)); ``f``\ や\ ``g``\ はそれぞれ .. math:: \begin{align} f(x)&=[x\;\;2x]^T\\ g(x)&= \left[ \begin{matrix} x & 2x\\ 3x & 4x \end{matrix} \right] \end{align} という関数を表す。 行列やベクトルはBoost uBLASのものを利用する。 .. _expr-usage-placeholders: プレースホルダー ^^^^^^^^^^^^^^^^ プレースホルダーを使うと式の一部に仮の値のようなものを置いておき、 評価時に具体的な値に置き換えるということができる。 プレースホルダーはあらかじめ\ ``tlnc::_1``\ から\ ``tlnc::_10``\ までが用意されていて、 それ以上必要な場合は\ ``tlnc::holder``\ を使うことができる。 .. code-block:: cpp #include #include using tlnc::_1; using tlnc::x; auto f = _1 * x<>; auto v = tlnc::call(f, bcl::make_tuple(1.0, 2.0)); 関数\ ``f``\ の定義の中にある\ ``_1``\ がプレースホルダーである。 上のように呼び出すと評価時に\ ``_1``\ が\ ``2.0``\ に置き換えられる。 呼び出しの詳細については\ :ref:`call-`\ を参照。