Eclipse SUMO - Simulation of Urban MObility
Loading...
Searching...
No Matches
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
31double
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
46double
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
61double
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
83std::vector<double>
84LinearApproxHelpers::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
95bool
96LinearApproxHelpers::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
112void
113LinearApproxHelpers::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
122void
124 for (auto& p : map) {
125 p.second *= factor;
126 }
127}
128
129
130void 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.
std::vector< std::string > getVector()
return vector of strings
static double toDouble(const std::string &sData)
converts a string into the double value described by it by calling the char-type converter