From eec8d6616c39e0789e095da9271a06030a2cc1b4 Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Sat, 9 May 2020 12:38:26 +0100 Subject: [PATCH] Datafilter - nozero() .. nozero(v1) returns a vector of indexes into v1 for non-zero values. Whilst it is possible to do this with sapply() this convenience function is faster - and the use-case crops up very often. --- src/Core/DataFilter.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Core/DataFilter.cpp b/src/Core/DataFilter.cpp index fc961de16..971045dea 100644 --- a/src/Core/DataFilter.cpp +++ b/src/Core/DataFilter.cpp @@ -245,6 +245,9 @@ static struct { { "match", 2 }, // match(vector1, vector2) - returns a vector of indexes. For every element in vector1 // that is in vector2, the index of the first occurrence is returned. + { "nonzero", 1 }, // nonzero(vector) - returns a vector of indexes to the zero values. this is a + // convenience function since it can be replicated using sapply, but this is much faster + // add new ones above this line { "", -1 } }; @@ -430,6 +433,10 @@ DataFilter::builtins() returning << "match(vector1, vector2)"; + } else if (i == 83) { + + returning << "nonzero(vector)"; + } else { QString function; @@ -3588,6 +3595,24 @@ Result Leaf::eval(DataFilterRuntime *df, Leaf *leaf, float x, long it, RideItem return returning; } + // non-zero - return index to non-zero values + if (leaf->function == "nonzero") { + + Result returning(0); + Result v = eval(df,leaf->fparms[0],x, it, m, p, c, s, d); // lhs might also be a symbol + + if (v.vector.count() > 0) { + for (int it=0; it < v.vector.count(); it++) { + if (v.vector[it] != 0) { + returning.vector << it; + returning.number += it; + } + } + } + + return returning; + } + // annotate if (leaf->function == "annotate") {