summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLester Solbakken <lesters@users.noreply.github.com>2021-04-28 20:28:26 +0200
committerGitHub <noreply@github.com>2021-04-28 20:28:26 +0200
commitc1f94ef7e3f9cdfc2fbcb65812c95c742aed3c56 (patch)
tree2638179695e2ecd4126f6d517bae9ed41654b387
parenta0ffa7801cd72fd9892f2427ddb6e2dfead449e0 (diff)
parent5fbf264b99b1f2647d55dbf2adead440f38db956 (diff)
Merge pull request #17630 from vespa-engine/lesters/java-tensor-empty-reduce
Don't expose initial aggregator values when reducing empty tensors
-rw-r--r--vespajlib/src/main/java/com/yahoo/tensor/functions/Reduce.java4
-rw-r--r--vespajlib/src/test/java/com/yahoo/tensor/functions/ReduceTestCase.java12
2 files changed, 14 insertions, 2 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/tensor/functions/Reduce.java b/vespajlib/src/main/java/com/yahoo/tensor/functions/Reduce.java
index 86f23487efb..879daefaf72 100644
--- a/vespajlib/src/main/java/com/yahoo/tensor/functions/Reduce.java
+++ b/vespajlib/src/main/java/com/yahoo/tensor/functions/Reduce.java
@@ -114,7 +114,9 @@ public class Reduce<NAMETYPE extends Name> extends PrimitiveTensorFunction<NAMET
// Special case: Reduce all
if (dimensions.isEmpty() || dimensions.size() == argument.type().dimensions().size())
- if (argument.type().dimensions().size() == 1 && argument instanceof IndexedTensor)
+ if (argument.isEmpty())
+ return Tensor.from(0.0);
+ else if (argument.type().dimensions().size() == 1 && argument instanceof IndexedTensor)
return reduceIndexedVector((IndexedTensor)argument, aggregator);
else
return reduceAllGeneral(argument, aggregator);
diff --git a/vespajlib/src/test/java/com/yahoo/tensor/functions/ReduceTestCase.java b/vespajlib/src/test/java/com/yahoo/tensor/functions/ReduceTestCase.java
index 21fed1745b9..f96852df377 100644
--- a/vespajlib/src/test/java/com/yahoo/tensor/functions/ReduceTestCase.java
+++ b/vespajlib/src/test/java/com/yahoo/tensor/functions/ReduceTestCase.java
@@ -16,7 +16,6 @@ public class ReduceTestCase {
@Test
public void testReduce() {
- assertNan(Tensor.from("tensor(x{})", "{}").median());
assertEquals(1.0, Tensor.from("tensor(x[1])", "[1]").median().asDouble(), delta);
assertEquals(1.5, Tensor.from("tensor(x[2])", "[1, 2]").median().asDouble(), delta);
assertEquals(3.0, Tensor.from("tensor(x[7])", "[3, 1, 1, 1, 4, 4, 4]").median().asDouble(), delta);
@@ -28,6 +27,17 @@ public class ReduceTestCase {
assertNan(Tensor.Builder.of("tensor(x[1])").cell(Double.NaN, 0).build().median());
}
+ @Test
+ public void testEmptyReduce() {
+ assertEquals(0.0, Tensor.from("tensor(x[3],y{})", "{}").avg().asDouble(), delta);
+ assertEquals(0.0, Tensor.from("tensor(x[3],y{})", "{}").max().asDouble(), delta);
+ assertEquals(0.0, Tensor.from("tensor(x[3],y{})", "{}").median().asDouble(), delta);
+ assertEquals(0.0, Tensor.from("tensor(x[3],y{})", "{}").min().asDouble(), delta);
+ assertEquals(0.0, Tensor.from("tensor(x[3],y{})", "{}").prod().asDouble(), delta);
+ assertEquals(0.0, Tensor.from("tensor(x[3],y{})", "{}").sum().asDouble(), delta);
+ assertEquals(0.0, Tensor.from("tensor(x[3],y{})", "{}").count().asDouble(), delta);
+ }
+
private void assertNan(Tensor tensor) {
assertTrue(tensor + " is NaN", Double.isNaN(tensor.asDouble()));
}