]> AND Private Git Repository - loba.git/blobdiff - cost_func.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
Use static instead of volatile for variables that may be clobbered by a TRY..CATCH.
[loba.git] / cost_func.cpp
index 73111999216e837fe156e5dbc0eb23d0c6ef3f7c..d6cba8c88ed667484b1f6af6ce0b95a3ec9244da 100644 (file)
@@ -1,58 +1,49 @@
 #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)
 {
-    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';
-        std::istringstream(tmp) >> factor[i];
-        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 + "\"");
     }
-    std::istringstream(tmp) >> factor[0];
+    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 result = factor[degree];
-    for (int i = degree - 1; i >= 0 ; i--)
-        result = amount * result + factor[i];
-    return result;
+    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();
 }