#include <algorithm>
-#include <cstdlib>
-#include <cstring>
+#include <functional>
+#include <numeric>
#include <iterator>
#include <sstream>
+#include <stdexcept>
+
#include "cost_func.h"
-cost_func::cost_func(const char *param)
+cost_func::cost_func(const char* param)
{
- int len = strlen(param);
- char tmpbuf[len + 1];
- char *tmp = tmpbuf;
- memcpy(tmp, param, len + 1);
- degree = std::count(tmp, tmp + len, ',');
- factor = new double[degree + 1];
- for (int i = degree ; i > 0 ; i--) {
- char *next = strchr(tmp, ',');
- *next++ = '\0';
- factor[i] = atof(tmp);
- tmp = next;
+ std::istringstream paramstream(param);
+ std::string token;
+ while (std::getline(paramstream, token, ',')) {
+ std::istringstream str(token);
+ double f;
+ if ((str >> f) && str.eof())
+ factors.push_back(f);
+ else
+ throw std::invalid_argument("cost_func(): "
+ "cannot parse \"" + token + "\"");
}
- factor[0] = atof(tmp);
+ if (factors.empty())
+ throw std::invalid_argument("cost_func(): no factor");
}
cost_func::~cost_func()
{
- delete[] factor;
-}
-
-cost_func& cost_func::operator=(const cost_func& ref)
-{
- if (&ref != this) {
- degree = ref.degree;
- delete[] factor;
- factor = new double[degree + 1];
- memcpy(factor, ref.factor, (degree + 1) * sizeof *factor);
- }
- return *this;
}
double cost_func::operator()(double amount) const
{
- double ret = factor[degree];
- for (int i = degree - 1; i >= 0 ; i--)
- ret = amount * ret + factor[i];
- return ret;
+ using std::placeholders::_1;
+ using std::placeholders::_2;
+ return std::accumulate(++factors.begin(), factors.end(), factors.front(),
+ std::bind(std::plus<double>(),
+ std::bind(std::multiplies<double>(),
+ amount, _1), _2));
}
std::string cost_func::to_string()
{
std::ostringstream oss;
- std::reverse_copy(factor + 1, factor + degree + 1,
- std::ostream_iterator<double>(oss, ", "));
- oss << factor[0];
+ std::copy(factors.begin(), --factors.end(),
+ std::ostream_iterator<double>(oss, ", "));
+ oss << factors.back();
return oss.str();
}