4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

std::vectorを拡張してみた

Posted at

std::vector<double>を拡張して、四則演算やmean,sd,normが計算できるようにしてみた。

  • 継承をprivateにするとstd::vector<double>への変換ができなくなる。
  • 継承をpublicにしてもメモリリークはしなさそう。
  • doubleによる除算を乗算で代用すると計算結果がかなり変わる。
my_vector.h
#include <vector>
#include <math.h>

class my_vector : public std::vector<double> {
public:
    using std::vector<double>::vector;
public:
    my_vector(const std::vector<double>& obj) : std::vector<double>(obj) {}
public:
    my_vector& operator+=(const my_vector& lhs) {
        int size = this->size();
        for (int i = 0; i < size; i++) {
            (*this)[i] += lhs[i];
        }
        return *this;
    }
    my_vector& operator-=(const my_vector& lhs) {
        int size = this->size();
        for (int i = 0; i < size; i++) {
            (*this)[i] -= lhs[i];
        }
        return *this;
    }
    my_vector& operator+=(const double& lhs) {
        int size = this->size();
        for (int i = 0; i < size; i++) {
            (*this)[i] += lhs;
        }
        return *this;
    }
    my_vector& operator-=(const double& lhs) {
        int size = this->size();
        for (int i = 0; i < size; i++) {
            (*this)[i] -= lhs;
        }
        return *this;
    }
    my_vector& operator*=(const double& lhs) {
        int size = this->size();
        for (int i = 0; i < size; i++) {
            (*this)[i] *= lhs;
        }
        return *this;
    }
    my_vector& operator/=(const double& lhs) {
        int size = this->size();
        for (int i = 0; i < size; i++) {
            (*this)[i] /= lhs;
        }
        return *this;
    }
    my_vector operator+(const my_vector& lhs) {
        return my_vector(*this) += lhs;
    }
    my_vector operator-(const my_vector& lhs) {
        return my_vector(*this) -= lhs;
    }
    my_vector operator+(const double& lhs) {
        return my_vector(*this) += lhs;
    }
    my_vector operator-(const double& lhs) {
        return my_vector(*this) -= lhs;
    }
    my_vector operator*(const double& lhs) {
        return my_vector(*this) *= lhs;
    }
    my_vector operator/(const double& lhs) {
        return my_vector(*this) /= lhs;
    }
public:
    double mean() {
        int size = this->size();
        if (size == 0) return 0;
        double t = 0;
        for (int i = 0; i < size; i++) {
            t += (*this)[i];
        }
        return t / size;
    }
    double sd() {
        int size = this->size();
        if (size < 2) return 0;
        double m = this->mean();
        double t = 0;
        for (int i = 0; i < size; i++) {
            double s = (*this)[i] - m;
            t += s * s;
        }
        return sqrt(t / (size - 1));
    }
    double norm() {
        int size = this->size();
        if (size == 0) return 0;
        double t = 0;
        for (int i = 0; i < size; i++) {
            t += (*this)[i] * (*this)[i];
        }
        return sqrt(t);
    }
};

色々試行錯誤してみたが、エイリアスとグローバル関数を定義する方が素直で速い。

my_vector.h
#include <vector>
#include <math.h>

using my_vector = std::vector<double>;

inline my_vector& operator+=(my_vector& rhs, const my_vector& lhs) {
    int size = rhs.size();
    for (int i = 0; i < size; i++) {
        rhs[i] += lhs[i];
    }
    return rhs;
}
inline my_vector& operator-=(my_vector& rhs, const my_vector& lhs) {
    int size = rhs.size();
    for (int i = 0; i < size; i++) {
        rhs[i] -= lhs[i];
    }
    return rhs;
}
inline my_vector& operator+=(my_vector& rhs, const double& lhs) {
    int size = rhs.size();
    for (int i = 0; i < size; i++) {
        rhs[i] += lhs;
    }
    return rhs;
}
inline my_vector& operator-=(my_vector& rhs, const double& lhs) {
    int size = rhs.size();
    for (int i = 0; i < size; i++) {
        rhs[i] -= lhs;
    }
    return rhs;
}
inline my_vector& operator*=(my_vector& rhs, const double& lhs) {
    int size = rhs.size();
    for (int i = 0; i < size; i++) {
        rhs[i] *= lhs;
    }
    return rhs;
}
inline my_vector& operator/=(my_vector& rhs, const double& lhs) {
    int size = rhs.size();
    for (int i = 0; i < size; i++) {
        rhs[i] /= lhs;
    }
    return rhs;
}

inline my_vector operator+(const my_vector& rhs, const my_vector& lhs) {
    return my_vector(rhs) += lhs;
}
inline my_vector operator-(const my_vector& rhs, const my_vector& lhs) {
    return my_vector(rhs) -= lhs;
}
inline my_vector operator+(const my_vector& rhs, const double& lhs) {
    return my_vector(rhs) += lhs;
}
inline my_vector operator-(const my_vector& rhs, const double& lhs) {
    return my_vector(rhs) -= lhs;
}
inline my_vector operator*(const my_vector& rhs, const double& lhs) {
    return my_vector(rhs) *= lhs;
}
inline my_vector operator/(const my_vector& rhs, const double& lhs) {
    return my_vector(rhs) /= lhs;
}

inline double mean(const my_vector& obj) {
    int size = obj.size();
    if (size == 0) return 0;
    double t = 0;
    for (int i = 0; i < size; i++) {
        t += obj[i];
    }
    return t / size;
}
inline double sd(const my_vector& obj) {
    int size = obj.size();
    if (size < 2) return 0;
    double m = mean(obj);
    double t = 0;
    for (int i = 0; i < size; i++) {
        double s = obj[i] - m;
        t += s * s;
    }
    return sqrt(t / (size - 1));
}
inline double norm(const my_vector& obj) {
    int size = obj.size();
    if (size == 0) return 0;
    double t = 0;
    for (int i = 0; i < size; i++) {
        t += obj[i] * obj[i];
    }
    return sqrt(t);
}
4
8
2

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
4
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?