LCOV - code coverage report
Current view: top level - src/utils/emissions - CharacteristicMap.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 100.0 % 1 1
Test Date: 2024-12-21 15:45:41 Functions: - 0 0

            Line data    Source code
       1              : /****************************************************************************/
       2              : // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
       3              : // Copyright (C) 2002-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              : /****************************************************************************/
      14              : /// @file    CharacteristicMap.h
      15              : /// @author  Kevin Badalian (badalian_k@mmp.rwth-aachen.de)
      16              : /// @date    2021-02
      17              : ///
      18              : // Characteristic map for vehicle type parameters as needed by the MMPEVEM model
      19              : // Teaching and Research Area Mechatronics in Mobile Propulsion (MMP), RWTH Aachen
      20              : /****************************************************************************/
      21              : 
      22              : 
      23              : /******************************************************************************
      24              :  * ============================= Example Usage ============================== *
      25              :  ******************************************************************************
      26              :  *                                                                            *
      27              :  * Assume a function f which maps from R^2 to R^1 according to...             *
      28              :  *                                                                            *
      29              :  *     |  0 |  1 |  2 |  3 |  4   -> x_1                                      *
      30              :  * ----|------------------------                                              *
      31              :  *  -1 |  1 |  3 |  1 | -2 |                                                  *
      32              :  *   1 |  1 | -2 | -3 |  7 |  5                                               *
      33              :  *   3 | -2 | -1 |  0 |  1 |  3                                               *
      34              :  *   5 |    |  0 |  8 |  4 |  4                                               *
      35              :  *                                                                            *
      36              :  *   |                                                                        *
      37              :  *   v                                                                        *
      38              :  *  x_2                                                                       *
      39              :  *                                                                            *
      40              :  * ... so that, for example, f(3, 1) = 7. Note that f is not defined at       *
      41              :  * (4, -1) and (0, 5). There are two ways to create a CharacteristicMap       *
      42              :  * object for this function.                                                  *
      43              :  * 1) Using the standard constructor:                                         *
      44              :  *      // Axes                                                               *
      45              :  *      std::vector<std::vector<double>> axes;                                *
      46              :  *      axes.push_back(std::vector<double>{0, 1, 2, 3, 4});  // Axis 1        *
      47              :  *      axes.push_back(std::vector<double>{-1, 1, 3, 5});    // Axis 2        *
      48              :  *      // Flattened row-major map entries                                    *
      49              :  *      std::vector<double> flattenedMap{1, 3, 1, -2, std::nan(""),           *
      50              :  *          1, -2, -3, 7, 5, -2, -1, 0, 1, 3, std::nan(""), 0, 8, 4, 4};      *
      51              :  *                                                                            *
      52              :  *      CharacteristicMap map1(2,              // Mapping from R^2...         *
      53              :  *                             1,              // ... to R^1                  *
      54              :  *                             axes,                                          *
      55              :  *                             flattenedMap);                                 *
      56              :  *                                                                            *
      57              :  * 2) Using a string-encoding of the map:                                     *
      58              :  *      CharacteristicMap map2("2,1|0,1,2,3,4;-1,1,3,5|1,3,1,-2,nan,"         *
      59              :  *          "1,-2,-3,7,5,-2,-1,0,1,3,nan,0,8,4,4");                           *
      60              :  *                                                                            *
      61              :  *    See below for an in-depth explanation of the format.                    *
      62              :  *                                                                            *
      63              :  *                                                                            *
      64              :  * To evaluate the map at, for instance, p = (2.2, 2), one must call:         *
      65              :  *   std::vector<double> res = map1.eval(std::vector<double>{2.2, 2},  // p   *
      66              :  *                                       1e-3);  // eps                       *
      67              :  *   if(std::isnan(res[0]))                                                   *
      68              :  *     std::cout << "[WARNING] Couldn't evaluate the map." << std::endl;      *
      69              :  *   else                                                                     *
      70              :  *     std::cout << "res = " << res[0] << std::endl;                          *
      71              :  *                                                                            *
      72              :  * The epsilon value is used for numerical reasons and decides how much a     *
      73              :  * point must deviate from its nearest neighbor before linear interpolation   *
      74              :  * is applied or when a point is considered outside of the map. The default   *
      75              :  * is 1e-6.                                                                   *
      76              :  *                                                                            *
      77              :  *                                                                            *
      78              :  * The string-encoding of a CharacteristicMap that maps from R^m to R^n is    *
      79              :  * formally defined as                                                        *
      80              :  *   "m,n|A_1[1],A_1[2],...,A_1[l1];A_2[1],A_2[2],...,A_2[l2];...;\           *
      81              :  *       A_m[1],A_m[2],...,A_m[lm]|\                                          *
      82              :  *       M_flat[1],M_flat[2],...,M_flat[l1*l2*...*lm]"                        *
      83              :  * where A_i[j] denotes the j-th value of the i-th axis (which has li values  *
      84              :  * total) and M_flat[i] stands for the i-th entry in the row-major flattened  *
      85              :  * map. To be more specific, given a map M, its flattened version is          *
      86              :  * computed as follows (using pseudo code):                                   *
      87              :  *   M_flat = ""                                                              *
      88              :  *   for i_m in {1,2,...,lm}:        // Last axis                             *
      89              :  *     ...                                                                    *
      90              :  *       for i_2 in {1,2,...,l2}:    // Second axis                           *
      91              :  *         for i_1 in {1,2,...,l1}:  // First axis (i.e. row axis)            *
      92              :  *           for d in {1,2,...,n}:   // Image dimensions                      *
      93              :  *             M_flat += M[i_1,i_2,...,i_m][d] + ","                          *
      94              :  *   removeTrailingComma(M_flat)                                              *
      95              :  *                                                                            *
      96              :  ******************************************************************************/
      97              : #pragma once
      98              : 
      99              : #include <vector>
     100              : #include <string>
     101              : 
     102              : 
     103              : /**
     104              :  * \class CharacteristicMap
     105              :  * \brief The purpose of this class is to store a characteristic map (German:
     106              :  *        Kennfeld) of arbitrary dimensions and to provide functions in order to
     107              :  *        evaluate/interpolate points in it.
     108              :  */
     109       322568 : class CharacteristicMap {
     110              : private:
     111              :     /// Dimension of the map's domain
     112              :     int domainDim;
     113              : 
     114              :     /// Image dimension of the map
     115              :     int imageDim;
     116              : 
     117              :     /// Vector containing the values along each domain axis in ascending order
     118              :     std::vector<std::vector<double>> axes;
     119              : 
     120              :     /// Flattened map entries
     121              :     std::vector<double> flattenedMap;
     122              : 
     123              :     /// Stride for each domain dimension in the flattened map
     124              :     std::vector<int> strides;
     125              : 
     126              :     /**
     127              :      * \brief Determine the stride for each map dimension in the flattened map.
     128              :      */
     129              :     void determineStrides();
     130              : 
     131              :     /**
     132              :      * \brief Compute the index of a map entry in the flattened map.
     133              :      *
     134              :      * \param[in] ref_idxs Non-flattened map indices
     135              :      * \returns Flattened map index
     136              :      * \throws std::runtime_error
     137              :      */
     138              :     int calcFlatIdx(const std::vector<int>& ref_idxs) const;
     139              : 
     140              :     /**
     141              :      * \brief Determine the indices of the nearest neighbor of a point in the map.
     142              :      *
     143              :      * A point has no such neighbor if it lies outside of the range of an axis
     144              :      * with respect to some epsilon.
     145              :      * \param[in] ref_p A point
     146              :      * \param[out] ref_idxs A vector into which the indices shall be written
     147              :      * \param[in] eps An epsilon value
     148              :      * \returns 0 if a nearest neighbor could be found, else -1
     149              :      * \throws std::runtime_error
     150              :      */
     151              :     int findNearestNeighborIdxs(const std::vector<double>& ref_p,
     152              :                                 std::vector<int>& ref_idxs, double eps = 1e-6) const;
     153              : 
     154              :     /**
     155              :      * \brief Access a map entry using its indices.
     156              :      *
     157              :      * \param[in] ref_idxs A vector containing indices
     158              :      * \returns A vector containing the image values of the map at the specified
     159              :      *          location
     160              :      * \throws std::runtime_error
     161              :      */
     162              :     std::vector<double> at(const std::vector<int>& ref_idxs) const;
     163              : 
     164              : 
     165              : 
     166              : public:
     167              :     /**
     168              :      * \brief Constructor
     169              :      *
     170              :      * \param[in] domainDim The map's domain dimension
     171              :      * \param[in] imageDim The map's image dimension
     172              :      * \param[in] ref_axes A vector of vectors containing the entries of their
     173              :      *            respective axes in ascending order
     174              :      * \param[in] ref_flattenedMap The row-major flattened entries of the map
     175              :      *            (i.e. the map is flattened along its first axis)
     176              :      * \throws std::runtime_error
     177              :      */
     178              :     CharacteristicMap(int domainDim, int imageDim,
     179              :                       const std::vector<std::vector<double>>& ref_axes,
     180              :                       const std::vector<double>& ref_flattenedMap);
     181              : 
     182              :     /**
     183              :      * \brief Constructor
     184              :      *
     185              :      * \param[in] ref_mapString A string representation of a characteristic map
     186              :      *            (cf. example at the top of the file)
     187              :      * throws std::runtime_error
     188              :      */
     189              :     CharacteristicMap(const std::string& ref_mapString);
     190              : 
     191              :     /**
     192              :      * \brief Encode the map as a string.
     193              :      *
     194              :      * \returns A string representation of the characteristic map (cf. example at
     195              :      *          the top of the file)
     196              :      */
     197              :     std::string toString() const;
     198              : 
     199              :     /**
     200              :      * \brief Get the dimension of the map's domain.
     201              :      *
     202              :      * \returns The domain's dimension
     203              :      */
     204              :     int getDomainDim() const;
     205              : 
     206              :     /**
     207              :      * \brief Get the image dimension of the map.
     208              :      *
     209              :      * \returns The image dimension of the characteristic map
     210              :      */
     211              :     int getImageDim() const;
     212              : 
     213              :     /**
     214              :      * \brief Evaluate a point in the map using linear interpolation.
     215              :      *
     216              :      * Please note that the result may contain NaNs. That happens when...
     217              :      * a) ... the point in question has no nearest neighbor (that is, it lies
     218              :      *    outside of the domain). In that case, all entries of the vector are set
     219              :      *    to NaN.
     220              :      * b) ... an image value of the nearest neighbor is NaN. Then, the result is
     221              :      *    also NaN in that image dimension.
     222              :      * c) ... evaluation would require interpolating with a support point which is
     223              :      *    NaN in an image dimension. The corresponding result entry is set to NaN
     224              :      *    in that case.
     225              :      * \param[in] ref_p A point
     226              :      * \param[in] eps An epsilon value
     227              :      * \returns The (interpolated) image values of the map at the specified point
     228              :      * \throws std::runtime_error
     229              :      */
     230              :     std::vector<double> eval(const std::vector<double>& ref_p,
     231              :                              double eps = 1e-6) const;
     232              : };
        

Generated by: LCOV version 2.0-1