しばしば,実験データから何らかの統計値(平均,分散,...)を求めたい場合があります.今回も,RMSE(Root Mean Square Error:平均2乗平方根誤差)を求めなければならない場面に遭遇しました.それで,せっかくなので汎用的に使える関数として残しておこうと思い,以下のような関数を書きました.
template <class Type, class InputIterator, class ValueT> Type mse(InputIterator first, const InputIterator& last, ValueT correct) { Type sum = 0; Type n = 0; while (first != last) { Type tmp = static_cast<Type>(*first++) - static_cast<Type>(correct); sum += std::pow(tmp, 2); n++; } return sum / n; } template <class Type, class InputIterator, class ValueT> Type rmse(InputIterator first, const InputIterator& last, ValueT correct) { return std::sqrt(mse(first, last, correct)); }
使い方としては,rmse < test.datのようにデータファイルをリダイレクトで渡すような形を考えていました.それで,メインプログラムをどのような形で書こうかな,と.最初に思いついたのは,streambuf_iteratorを使う方法だったのですが,これだと一文字づつ読み込んでしまい(100 200 300の場合,'1', '0', '0', ' ', '2', ...)期待した動きをしてくれませんでした.しばらくWebを彷徨っていたところ,stream_iteratorを利用すればうまくいく模様(100 200 300の場合,"100", "200", "300").そういう訳で,最終的なプログラム.
int main(int argc, char* argv[]) { if (argc < 2) exit(-1); int correct = std::atoi(argv[1]); std::istream_iterator<double> input(std::cin); std::istream_iterator<double> last; double val = rmse<double>(input, last, correct); std::cout << "RMSE: " << val << std::endl; return 0; } |<