LoginSignup
8

More than 5 years have passed since last update.

std::vector間の演算を定義したら快適になった

Last updated at Posted at 2018-12-05

std::vector間の演算を定義したら快適になった

C++で行列やベクトルを扱いたいときは, Eigenを使うことが多い.
しかし, 非常に簡単なプログラムの場合, Eigenを使うまでも無いような場合も多々ある.
そこで, #include<vector>std::vector間の演算を定義することで, シンプルでカスタマイズ性の高い機能を提供する.

コメントをいただきました: std::valarrayという数値演算に特化した一次元配列クラスがあるようです

vec_op

githubにvec_opを公開した.
vec_op.hpp#include "vec_op.hpp"するだけで使用可能.
使用例は, sample.cppを参照.
その実行結果は, こちらを参照.

これらのリンク先のみで理解できるが, 一部抜粋して説明する.

vec_op.hpp

例えば, std::vector間の+は, 以下のように実装されている.

template <class T>
std::vector<T> operator+(const std::vector<T> &v1, const std::vector<T> &v2) {
    std::vector<T> ans = v1;
    for (size_t i = 0, size = ans.size(); i < size; ++i)
        ans[i] += v2[i];
    return ans;
}

演算子の他に, よく使いそうな機能として名前空間vec_opに関数を定義した.
例えば, 内積dotは以下の通り.

namespace vec_op {
    // (...略...)
    template <class T>
    T dot(const std::vector<T> &v1, const std::vector<T> &v2) {
        T ans(0);
        for (size_t i = 0, size = v1.size(); i < size; ++i)
            ans += v1[i] * v2[i];
        return ans;
    }
    // (...略...)
}

sample.cpp

四則演算+, -, *, /や, べき乗^の使用例.
matlabの+, -, .*, ./, .^に対応している.

    cout << "v1 + v2 = " << v1 + v2 << endl;
    cout << "v1 - v2 = " << v1 - v2 << endl;
    cout << "v1 * v2 = " << v1 * v2 << endl;
    cout << "v1 / v2 = " << v1 / v2 << endl;
    cout << "v1 ^ v2 = " << (v1 ^ v2) << endl;

ベクトルとスカラーの演算にも対応.


    cout << "v1 + c = " << v1 + c << endl;
    cout << "v1 - c = " << v1 - c << endl;
    cout << "v1 * c = " << v1 * c << endl;
    cout << "v1 / c = " << v1 / c << endl;
    cout << "v1 ^ c = " << (v1 ^ c) << endl;
    cout << "c ^ v1 = " << (c ^ v1) << endl;

その他機能の利用例.


    cout << "dot(v1, v2) = " << vec_op::dot(v1, v2) << endl;
    cout << "sum(v1) = " << vec_op::sum(v1) << endl;
    cout << "prod(v1) = " << vec_op::prod(v1) << endl;
    cout << "cast<double, int>(v1) = " << vec_op::cast<double, int>(v1) << endl;
    cout << "concat(v1, v2) = " << vec_op::concat(v1, v2) << endl;
    cout << "sort(v1) = " << vec_op::sort(v1) << endl;
    cout << "argsort(v1) = " << vec_op::argsort(v1) << endl;
    cout << "randomIndex(10) = " << vec_op::randomIndex(10) << endl;
    cout << "range(10) = " << vec_op::range(10) << endl;
    cout << "range(2,10,2) = " << vec_op::range(2, 10, 2) << endl;

実行結果

メリット

  • Includeするだけで関数/演算が使えるようになる
  • カスタマイズ性が高い
    • 並列化したければ自分でoperator定義のforループにopenmpをつければよい
    • 気軽に関数/演算子を追加していける

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8