Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/utils/common/LinearApproxHelpers.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 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
/****************************************************************************/
14
/// @file LinearApproxHelpers.cpp
15
/// @author Mirko Barthauer
16
/// @date 17 May 2024
17
///
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>
25
#include <utils/common/MsgHandler.h>
26
#include <utils/common/StringTokenizer.h>
27
#include <utils/common/UtilExceptions.h>
28
#include "LinearApproxHelpers.h"
29
30
31
double
32
LinearApproxHelpers::getMinimumValue(const LinearApproxMap& map) {
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
47
LinearApproxHelpers::getMaximumValue(const LinearApproxMap& map) {
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
62
LinearApproxHelpers::getInterpolatedValue(const LinearApproxMap& map, double axisValue) {
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
123
LinearApproxHelpers::scaleValues(LinearApproxMap& map, const double factor) {
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
}
142
143