1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
|
/* Copyright (c) 2020, Dyssol Development Team.
* Copyright (c) 2024, DyssolTEC GmbH.
* All rights reserved. This file is part of Dyssol. See LICENSE file for license information. */
#pragma once
#include "TwoWayMap.h"
/* Bidirectional lookup table to find the correspondence between two lists of values in a mixture of components.
* The values are denoted as [left] and [right].
* Each component has its weight and is defined for a set of [left:right] values. All weights are summed up to 1.
* Each set of components - [left] and [right] - must contain only unique values.
* After all the components are filled with values, it is possible to read 'Table[left] = right' and 'Table[right] = left' of the weighted mixture.
* For values that do not directly defined, interpolation is applied.
* If two components C1 and C2 with weights W_1 and W_2 are filled as follows
* C1 = [X1_1:Y1_1, X1_2:Y1_2], W_1
* C2 = [X2_1:Y2_1, X2_2:Y2_2], W_2
* the resulting mixture table is calculated as
* M = [X1_1:Y1(X1_M)*W_1+Y2(X1_1)*W_1,
* X1_2:Y1(X1_M)*W_2+Y2(X1_2)*W_2,
* X2_1:Y1(X1_M)*W_1+Y2(X2_1)*W_1,
* X2_2:Y1(X1_M)*W_2+Y2(X2_2)*W_2]
*/
class CMixtureLookup
{
// A version of CTwoWayMap extended with required arithmetic operations.
class CTwoWayMapExt : public CTwoWayMap
{
public:
// Adds a _value to all _right elements, so that [_left:_right+_value].
void Add(double _value);
// Adds a _table to all _right elements, so that [_left:_right+_table(_left)].
void Add(const CDependentValues& _table);
// Adds a weighted _table to all _right elements, so that [_left:_right+T(_left)*_value].
void AddMult(const CDependentValues& _table, double _value);
// Multiplies a _value with all _right elements, so that [_left:_right*_value].
void Mult(double _value);
};
CTwoWayMapExt m_table; // Main lookup table.
std::vector<CDependentValues> m_componets; // All components.
std::vector<double> m_weights; // Weights of all components.
public:
// Creates an empty mixture lookup table.
CMixtureLookup() = default;
// Creates a mixture lookup table with defined _components and equal weights.
CMixtureLookup(std::vector<CDependentValues> _components);
// Creates a mixture lookup table with defined _components and their _weights. Both vectors must have the same size.
CMixtureLookup(std::vector<CDependentValues> _components, std::vector<double> _weights);
// Adds a new _component with _weight.
void AddComponent(const CDependentValues& _component, double _weight = 1.);
// Removes a component and its weight entry.
void RemoveComponent(size_t _index);
// Returns the number of defined components.
[[nodiscard]] size_t ComponentsNumber() const;
// Returns the number of entries in the lookup table.
[[nodiscard]] size_t Size() const;
// Sets new _weights for all components. _weights must have the same size as the number of defined components.
void SetWeights(const std::vector<double>& _weights);
// Returns weights of all components.
[[nodiscard]] std::vector<double> GetWeights() const;
// Returns _left element of the [_left:_right] pair. Performs linear interpolation is _right is not defined explicitly. Returns 0, if there are no data at all.
[[nodiscard]] double GetLeft(double _right) const;
// Returns _right element of the [_left:_right] pair. Performs linear interpolation is _left is not defined explicitly. Returns 0, if there are no data at all.
[[nodiscard]] double GetRight(double _left) const;
// Sets a _component with some _weight as a mixture.
void Set(const CDependentValues& _component, double _weight = 1.);
// Adds _value to each _right (dependent) entry of the mixture table.
void Add(double _value);
// Adds a _component with some _weight to each _right (dependent) entry of the mixture table.
void Add(const CDependentValues& _component, double _weight = 1.);
// Adds another mixture _table with some _weight to each _right (dependent) entry of the mixture table. _table must have the same number of components.
void Add(const CMixtureLookup& _table, double _weight = 1.);
// Multiplies each _right (dependent) entry of the mixture table with a _value.
void Multiply(double _value);
bool operator==(const CMixtureLookup& _other) const;
// Removes all data.
void Clear();
private:
// Updates the values in lookup table according to set components and weights.
void Update();
};
|