mirror of
https://github.com/GoldenCheetah/GoldenCheetah.git
synced 2026-02-13 16:18:42 +00:00
DataFilter vectors - vectorize + - / * ^ operations
.. you can now use algebraic operators with vectors. If a vector is shorter it is repeated to match, e.g. a<-c(1,2); b<-c(1,2,3,4,5); d<- a * b; is calculated as; d<- c(1,2,1,2,1) * c(1,2,3,4,5) and will yield: 1,4,3,8,5
This commit is contained in:
@@ -2328,6 +2328,29 @@ void DataFilter::configChanged(qint32)
|
||||
static double myisinf(double x) { return std::isinf(x); }
|
||||
static double myisnan(double x) { return std::isnan(x); }
|
||||
|
||||
void
|
||||
Result::vectorize(int count)
|
||||
{
|
||||
|
||||
if (vector.count() >= count) return;
|
||||
|
||||
// ok, so must have at least 1 element to repeat
|
||||
if (vector.count() == 0) vector << number;
|
||||
|
||||
// repeat for size
|
||||
int it=0;
|
||||
int n=vector.count();
|
||||
|
||||
// repeat whatever we have
|
||||
while (vector.count() < count) {
|
||||
vector << vector[it];
|
||||
number += vector[it];
|
||||
|
||||
// loop thru wot we have
|
||||
it++; if (it == n) it=0;
|
||||
}
|
||||
}
|
||||
|
||||
Result Leaf::eval(DataFilterRuntime *df, Leaf *leaf, float x, long it, RideItem *m, RideFilePoint *p, const QHash<QString,RideMetric*> *c, Specification s, DateRange d)
|
||||
{
|
||||
// if error state all bets are off
|
||||
@@ -4212,39 +4235,57 @@ Result Leaf::eval(DataFilterRuntime *df, Leaf *leaf, float x, long it, RideItem
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
|
||||
// basic operations should all work with vectors or numbers
|
||||
case ADD:
|
||||
{
|
||||
if (lhs.isNumber) return Result(lhs.number + rhs.number);
|
||||
else return Result(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case SUBTRACT:
|
||||
{
|
||||
if (lhs.isNumber) return Result(lhs.number - rhs.number);
|
||||
else return Result(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case DIVIDE:
|
||||
{
|
||||
// avoid divide by zero
|
||||
if (lhs.isNumber && rhs.number) return Result(lhs.number / rhs.number);
|
||||
else return Result(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case MULTIPLY:
|
||||
{
|
||||
if (lhs.isNumber && rhs.isNumber) return Result(lhs.number * rhs.number);
|
||||
else return Result(0);
|
||||
}
|
||||
break;
|
||||
|
||||
case POW:
|
||||
{
|
||||
if (lhs.isNumber && rhs.number) return Result(pow(lhs.number,rhs.number));
|
||||
else return Result(0);
|
||||
Result returning(0);
|
||||
|
||||
// only if numberic on both sides
|
||||
if (lhs.isNumber && rhs.isNumber) {
|
||||
|
||||
|
||||
// its a vector operation...
|
||||
if (lhs.vector.count() || rhs.vector.count()) {
|
||||
|
||||
int size = lhs.vector.count() > rhs.vector.count() ? lhs.vector.count() : rhs.vector.count();
|
||||
|
||||
// coerce both into a vector of matching size
|
||||
lhs.vectorize(size);
|
||||
rhs.vectorize(size);
|
||||
|
||||
for(int i=0; i<size; i++) {
|
||||
double left = lhs.vector[i];
|
||||
double right = rhs.vector[i];
|
||||
double value = 0;
|
||||
|
||||
switch (leaf->op) {
|
||||
case ADD: value = left + right; break;
|
||||
case SUBTRACT: value = left - right; break;
|
||||
case DIVIDE: value = right ? left / right : 0; break;
|
||||
case MULTIPLY: value = left * right; break;
|
||||
case POW: value = pow(left,right); break;
|
||||
}
|
||||
returning.vector << value;
|
||||
returning.number += value;
|
||||
}
|
||||
|
||||
} else {
|
||||
switch (leaf->op) {
|
||||
case ADD: returning.number = lhs.number + rhs.number; break;
|
||||
case SUBTRACT: returning.number = lhs.number - rhs.number; break;
|
||||
case DIVIDE: returning.number = rhs.number ? lhs.number / rhs.number : 0; break;
|
||||
case MULTIPLY: returning.number = lhs.number * rhs.number; break;
|
||||
case POW: returning.number = pow(lhs.number, rhs.number); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return returning;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -45,6 +45,9 @@ class Result {
|
||||
Result (QString value) : isNumber(false), string(value), number(0.0f) {}
|
||||
Result () : isNumber(true), string(""), number(0) {}
|
||||
|
||||
// vectorize, turn into vector of size n
|
||||
void vectorize(int size);
|
||||
|
||||
// we can't use QString with union
|
||||
bool isNumber; // if true, value is numeric
|
||||
QString string;
|
||||
|
||||
Reference in New Issue
Block a user