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