std::vectorを拡張してみた

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

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

```c++: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);
    }
};
```

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

```c++: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);
}
```