diff options
author | Jon Bratseth <bratseth@yahoo-inc.com> | 2017-01-10 16:30:02 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@yahoo-inc.com> | 2017-01-10 16:30:02 +0100 |
commit | 9574c0894ddbf88ad3ff311688e597a939df1a41 (patch) | |
tree | 67b3e2907c4451c50569ad573c96f00351376c79 /vespajlib/src | |
parent | 451e7cf03729b7a09c8e4f9457edf9ae1007ba8a (diff) |
Disallow empty tensors without dimensions
Diffstat (limited to 'vespajlib/src')
4 files changed, 23 insertions, 39 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/tensor/IndexedTensor.java b/vespajlib/src/main/java/com/yahoo/tensor/IndexedTensor.java index deee4aa02b6..bee93ddb4e0 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/IndexedTensor.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/IndexedTensor.java @@ -220,7 +220,7 @@ public class IndexedTensor implements Tensor { public TensorType type() { return type; } @Override - public abstract Tensor build(); + public abstract IndexedTensor build(); } @@ -247,7 +247,6 @@ public class IndexedTensor implements Tensor { throw new IllegalArgumentException("Must have a dimension size entry for each dimension in " + type); this.sizes = sizes; values = new double[sizes.totalSize()]; - Arrays.fill(values, Double.NaN); } @Override @@ -268,14 +267,7 @@ public class IndexedTensor implements Tensor { } @Override - public Tensor build() { - // Note that we do not check for no NaN's here for performance reasons. - // NaN's don't get lost so leaving them in place should be quite benign - - // An empty tensor with no dimensions is mapped - if (values.length == 1 && Double.isNaN(values[0]) && type.dimensions().isEmpty()) - return MappedTensor.Builder.of(type).build(); - + public IndexedTensor build() { IndexedTensor tensor = new IndexedTensor(type, sizes, values); // prevent further modification sizes = null; @@ -318,23 +310,21 @@ public class IndexedTensor implements Tensor { } @Override - public Tensor build() { - if (firstDimension == null && type.dimensions().isEmpty()) // empty - return MappedTensor.Builder.of(type).build(); + public IndexedTensor build() { + if (firstDimension == null) throw new IllegalArgumentException("Tensor of type " + type() + " has no values"); + if (type.dimensions().isEmpty()) // single number return new IndexedTensor(type, new DimensionSizes.Builder(type.dimensions().size()).build(), new double[] {(Double) firstDimension.get(0) }); DimensionSizes dimensionSizes = findDimensionSizes(firstDimension); double[] values = new double[dimensionSizes.totalSize()]; - if (firstDimension != null) - fillValues(0, 0, firstDimension, dimensionSizes, values); + fillValues(0, 0, firstDimension, dimensionSizes, values); return new IndexedTensor(type, dimensionSizes, values); } private DimensionSizes findDimensionSizes(List<Object> firstDimension) { List<Integer> dimensionSizeList = new ArrayList<>(type.dimensions().size()); - if (firstDimension != null) - findDimensionSizes(0, dimensionSizeList, firstDimension); + findDimensionSizes(0, dimensionSizeList, firstDimension); DimensionSizes.Builder b = new DimensionSizes.Builder(type.dimensions().size()); // may be longer than the list but that's correct for (int i = 0; i < b.dimensions(); i++) { if (i < dimensionSizeList.size()) diff --git a/vespajlib/src/test/java/com/yahoo/tensor/IndexedTensorTestCase.java b/vespajlib/src/test/java/com/yahoo/tensor/IndexedTensorTestCase.java index 01d1e6fc602..e150b1cf24f 100644 --- a/vespajlib/src/test/java/com/yahoo/tensor/IndexedTensorTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/tensor/IndexedTensorTestCase.java @@ -1,5 +1,6 @@ package com.yahoo.tensor; +import junit.framework.TestCase; import org.junit.Test; import java.util.HashMap; @@ -7,6 +8,7 @@ import java.util.Iterator; import java.util.Map; import static junit.framework.TestCase.assertTrue; +import static junit.framework.TestCase.fail; import static org.junit.Assert.assertEquals; /** @@ -21,6 +23,15 @@ public class IndexedTensorTestCase { private final int zSize = 5; @Test + public void testEmpty() { + Tensor empty = Tensor.Builder.of(TensorType.empty).build(); + assertEquals(1, empty.size()); + assertEquals((double)0.0, (double)empty.valueIterator().next(), 0.00000001); + Tensor emptyFromString = Tensor.from(TensorType.empty, "{}"); + assertEquals(empty, emptyFromString); + } + + @Test public void testSingleValue() { Tensor singleValue = Tensor.Builder.of(TensorType.empty).cell(TensorAddress.empty, 3.5).build(); assertTrue(singleValue instanceof IndexedTensor); @@ -32,22 +43,6 @@ public class IndexedTensorTestCase { } @Test - public void testSingleValueWithDimensions() { - TensorType type = new TensorType.Builder().indexed("x").indexed("y").build(); - Tensor emptyWithDimensions = Tensor.Builder.of(type).build(); - assertTrue(emptyWithDimensions instanceof IndexedTensor); - assertEquals("tensor(x[],y[]):{}", emptyWithDimensions.toString()); - Tensor emptyWithDimensionsFromString = Tensor.from("tensor(x[],y[]):{}"); - assertEquals("tensor(x[],y[]):{}", emptyWithDimensionsFromString.toString()); - assertTrue(emptyWithDimensionsFromString instanceof IndexedTensor); - assertEquals(emptyWithDimensions, emptyWithDimensionsFromString); - - IndexedTensor emptyWithDimensionsIndexed = (IndexedTensor)emptyWithDimensions; - assertEquals(0, emptyWithDimensionsIndexed.dimensionSizes().size(0)); - assertEquals(0, emptyWithDimensionsIndexed.dimensionSizes().size(1)); - } - - @Test public void testBoundBuilding() { TensorType type = new TensorType.Builder().indexed("v", vSize) .indexed("w", wSize) diff --git a/vespajlib/src/test/java/com/yahoo/tensor/MappedTensorTestCase.java b/vespajlib/src/test/java/com/yahoo/tensor/MappedTensorTestCase.java index a2df146c8e1..5c2c3b9db32 100644 --- a/vespajlib/src/test/java/com/yahoo/tensor/MappedTensorTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/tensor/MappedTensorTestCase.java @@ -20,12 +20,13 @@ public class MappedTensorTestCase { @Test public void testEmpty() { - Tensor empty = Tensor.Builder.of(TensorType.empty).build(); + TensorType type = new TensorType.Builder().mapped("x").build(); + Tensor empty = Tensor.Builder.of(type).build(); TestCase.assertTrue(empty instanceof MappedTensor); TestCase.assertTrue(empty.isEmpty()); - assertEquals("{}", empty.toString()); - Tensor emptyFromString = Tensor.from(TensorType.empty, "{}"); - assertEquals("{}", Tensor.from(TensorType.empty, "{}").toString()); + assertEquals("tensor(x{}):{}", empty.toString()); + Tensor emptyFromString = Tensor.from(type, "{}"); + assertEquals("tensor(x{}):{}", Tensor.from("tensor(x{}):{}").toString()); TestCase.assertTrue(emptyFromString.isEmpty()); TestCase.assertTrue(emptyFromString instanceof MappedTensor); assertEquals(empty, emptyFromString); diff --git a/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java b/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java index e649d3cde2a..b35220cf013 100644 --- a/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java @@ -29,8 +29,6 @@ public class TensorTestCase { @Test public void testStringForm() { - assertEquals("{}", Tensor.from("{}").toString()); - assertTrue(Tensor.from("{}") instanceof MappedTensor); assertEquals("{5.7}", Tensor.from("{5.7}").toString()); assertTrue(Tensor.from("{5.7}") instanceof IndexedTensor); assertEquals("{{d1:l1,d2:l1}:5.0,{d1:l1,d2:l2}:6.0}", Tensor.from("{ {d1:l1,d2:l1}: 5, {d2:l2, d1:l1}:6.0} ").toString()); |