exprkt: Add sumIgnoreNaN to ignore the NaN value
Arithmetic with `nan` values is not expected in virtual sensor's case.
Adding a new exprkt function `sumIgnoreNaN` to handle this case,
that it ignores all `nan` values. If all values are `nan` then it
returns `nan`, otherwise it returns the sum of the valid values.
Example usage in json config:
```
"Expression": "sumIgnoreNaN(T0, T1, T2, T3)"
```
Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I0cbd87f038499b4ea3ab722c003adc795a11c2b3
diff --git a/exprtkTools.hpp b/exprtkTools.hpp
index c26a1b1..a11e10a 100644
--- a/exprtkTools.hpp
+++ b/exprtkTools.hpp
@@ -69,3 +69,24 @@
});
}
};
+
+template <typename T>
+struct FuncSumIgnoreNaN : public exprtk::ivararg_function<T>
+{
+ inline T operator()(const std::vector<T>& argList)
+ {
+ return std::reduce(std::begin(argList), std::end(argList),
+ std::numeric_limits<double>::quiet_NaN(),
+ [](auto a, auto b) {
+ if (std::isnan(b))
+ {
+ return a;
+ }
+ if (std::isnan(a))
+ {
+ return b;
+ }
+ return a + b;
+ });
+ }
+};
diff --git a/virtualSensor.cpp b/virtualSensor.cpp
index 2e58c3c..ea18c61 100644
--- a/virtualSensor.cpp
+++ b/virtualSensor.cpp
@@ -45,6 +45,7 @@
{
FuncMaxIgnoreNaN<double> VirtualSensor::funcMaxIgnoreNaN;
+FuncSumIgnoreNaN<double> VirtualSensor::funcSumIgnoreNaN;
void printParams(const VirtualSensor::ParamMap& paramMap)
{
@@ -367,6 +368,7 @@
symbols.add_constants();
symbols.add_package(vecopsPackage);
symbols.add_function("maxIgnoreNaN", funcMaxIgnoreNaN);
+ symbols.add_function("sumIgnoreNaN", funcSumIgnoreNaN);
expression.register_symbol_table(symbols);
diff --git a/virtualSensor.hpp b/virtualSensor.hpp
index bce5116..6c4bbb7 100644
--- a/virtualSensor.hpp
+++ b/virtualSensor.hpp
@@ -170,6 +170,7 @@
std::unique_ptr<AssociationObject> associationIface;
static FuncMaxIgnoreNaN<double> funcMaxIgnoreNaN;
+ static FuncSumIgnoreNaN<double> funcSumIgnoreNaN;
/** @brief Read config from json object and initialize sensor data
* for each virtual sensor