Path: blob/main/src/utils/common/LinearApproxHelpers.cpp
169678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file LinearApproxHelpers.cpp14/// @author Mirko Barthauer15/// @date 17 May 202416///17// Provides a tabular data points map with parsing and interpolation support18/****************************************************************************/19#include <config.h>2021#include <string>22#include <map>23#include <algorithm>24#include <utils/common/MsgHandler.h>25#include <utils/common/StringTokenizer.h>26#include <utils/common/UtilExceptions.h>27#include "LinearApproxHelpers.h"282930double31LinearApproxHelpers::getMinimumValue(const LinearApproxMap& map) {32if (map.empty()) {33throw ProcessError(TL("Cannot determine the minimum value from an empty map."));34}35double minValue = std::numeric_limits<double>::max();36for (const auto& item : map) {37if (item.second < minValue) {38minValue = item.second;39}40}41return minValue;42}434445double46LinearApproxHelpers::getMaximumValue(const LinearApproxMap& map) {47if (map.empty()) {48throw ProcessError(TL("Cannot determine the maximum value from an empty map."));49}50double maxValue = std::numeric_limits<double>::min();51for (const auto& item : map) {52if (item.second > maxValue) {53maxValue = item.second;54}55}56return maxValue;57}585960double61LinearApproxHelpers::getInterpolatedValue(const LinearApproxMap& map, double axisValue) {62LinearApproxHelpers::LinearApproxMap::const_iterator low, prev;63low = map.lower_bound(axisValue);64if (low == map.end()) {65return (map.rbegin())->second;66}67if (low == map.begin()) {68return low->second;69}70prev = low;71--prev;72double range = low->first - prev->first;73double dist = axisValue - prev->first;74assert(range > 0);75assert(dist > 0);76double weight = dist / range;77double res = (1 - weight) * prev->second + weight * low->second;78return res;79}808182std::vector<double>83LinearApproxHelpers::getValueTable(const std::string& dataString) {84std::vector<double> result;85if (!dataString.empty()) {86for (std::string value : StringTokenizer(dataString).getVector()) {87result.push_back(StringUtils::toDouble(value));88}89}90return result;91}929394bool95LinearApproxHelpers::setPoints(LinearApproxMap& map, const std::string& axisString, const std::string& heightString) {96std::vector<double> axisData = getValueTable(axisString);97std::vector<double> heightData = getValueTable(heightString);98if (heightData.size() > 0 && heightData.size() != axisData.size()) {99throw ProcessError(TLF("Mismatching data rows of % axis and % height values.", axisData.size(), heightData.size()));100} else {101auto itA = axisData.begin();102auto itB = heightData.begin();103for (; itA != axisData.end() && itB != heightData.end(); ++itA, ++itB) {104map.insert({ *itA, *itB });105}106}107return true;108}109110111void112LinearApproxHelpers::scalePoints(LinearApproxMap& map, double keyFactor, double valueFactor) {113LinearApproxMap map2;114for (const auto& item : map) {115map2[item.first * keyFactor] = item.second * valueFactor;116}117map.swap(map2);118}119120121void122LinearApproxHelpers::scaleValues(LinearApproxMap& map, const double factor) {123for (auto& p : map) {124p.second *= factor;125}126}127128129void LinearApproxHelpers::setValues(LinearApproxMap& map, const std::string& heightString) {130std::vector<double> heightData = getValueTable(heightString);131if (heightData.size() > 0 && heightData.size() != map.size()) {132throw ProcessError(TLF("Mismatching data rows of % axis and % height values.", map.size(), heightData.size()));133} else {134std::vector<double>::const_iterator heightIt = heightData.begin();135for (auto& p : map) {136p.second = *heightIt;137++heightIt;138}139}140}141142143