Eclipse SUMO - Simulation of Urban MObility
LinearApproxHelpers.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Provides a tabular data points map with parsing and interpolation support
19 /****************************************************************************/
20 #include <config.h>
21 
22 #include <string>
23 #include <map>
24 #include <algorithm>
28 #include "LinearApproxHelpers.h"
29 
30 
31 double
33  if (map.empty()) {
34  throw ProcessError(TL("Cannot determine the minimum value from an empty map."));
35  }
36  double minValue = std::numeric_limits<double>::max();
37  for (const auto& item : map) {
38  if (item.second < minValue) {
39  minValue = item.second;
40  }
41  }
42  return minValue;
43 }
44 
45 
46 double
48  if (map.empty()) {
49  throw ProcessError(TL("Cannot determine the maximum value from an empty map."));
50  }
51  double maxValue = std::numeric_limits<double>::min();
52  for (const auto& item : map) {
53  if (item.second > maxValue) {
54  maxValue = item.second;
55  }
56  }
57  return maxValue;
58 }
59 
60 
61 double
63  LinearApproxHelpers::LinearApproxMap::const_iterator low, prev;
64  low = map.lower_bound(axisValue);
65  if (low == map.end()) {
66  return (map.rbegin())->second;
67  }
68  if (low == map.begin()) {
69  return low->second;
70  }
71  prev = low;
72  --prev;
73  double range = low->first - prev->first;
74  double dist = axisValue - prev->first;
75  assert(range > 0);
76  assert(dist > 0);
77  double weight = dist / range;
78  double res = (1 - weight) * prev->second + weight * low->second;
79  return res;
80 }
81 
82 
83 std::vector<double>
84 LinearApproxHelpers::getValueTable(const std::string& dataString) {
85  std::vector<double> result;
86  if (!dataString.empty()) {
87  for (std::string value : StringTokenizer(dataString).getVector()) {
88  result.push_back(StringUtils::toDouble(value));
89  }
90  }
91  return result;
92 }
93 
94 
95 bool
96 LinearApproxHelpers::setPoints(LinearApproxMap& map, const std::string& axisString, const std::string& heightString) {
97  std::vector<double> axisData = getValueTable(axisString);
98  std::vector<double> heightData = getValueTable(heightString);
99  if (heightData.size() > 0 && heightData.size() != axisData.size()) {
100  throw ProcessError(TLF("Mismatching data rows of % axis and % height values.", axisData.size(), heightData.size()));
101  } else {
102  auto itA = axisData.begin();
103  auto itB = heightData.begin();
104  for (; itA != axisData.end() && itB != heightData.end(); ++itA, ++itB) {
105  map.insert({ *itA, *itB });
106  }
107  }
108  return true;
109 }
110 
111 
112 void
113 LinearApproxHelpers::scalePoints(LinearApproxMap& map, double keyFactor, double valueFactor) {
114  LinearApproxMap map2;
115  for (const auto& item : map) {
116  map2[item.first * keyFactor] = item.second * valueFactor;
117  }
118  map.swap(map2);
119 }
120 
121 
122 void
124  for (auto& p : map) {
125  p.second *= factor;
126  }
127 }
128 
129 
130 void LinearApproxHelpers::setValues(LinearApproxMap& map, const std::string& heightString) {
131  std::vector<double> heightData = getValueTable(heightString);
132  if (heightData.size() > 0 && heightData.size() != map.size()) {
133  throw ProcessError(TLF("Mismatching data rows of % axis and % height values.", map.size(), heightData.size()));
134  } else {
135  std::vector<double>::const_iterator heightIt = heightData.begin();
136  for (auto& p : map) {
137  p.second = *heightIt;
138  ++heightIt;
139  }
140  }
141 }
#define TL(string)
Definition: MsgHandler.h:315
#define TLF(string,...)
Definition: MsgHandler.h:317
std::map< double, double > LinearApproxMap
static double getInterpolatedValue(const LinearApproxMap &map, double axisValue)
Get interpolated value.
static void setValues(LinearApproxMap &map, const std::string &heightString)
Set height values for existing axis values.
static void scalePoints(LinearApproxMap &map, double keyFactor, double valueFactor)
Scale both key and values.
static void scaleValues(LinearApproxMap &map, const double factor)
Scale values.
static bool setPoints(LinearApproxMap &map, const std::string &axisString, const std::string &heightString)
Set data points.
static std::vector< double > getValueTable(const std::string &dataString)
split string into data values
static double getMaximumValue(const LinearApproxMap &map)
Get the largest height value.
static double getMinimumValue(const LinearApproxMap &map)
Get the smallest height value.
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter