diff options
Diffstat (limited to 'vespajlib')
3 files changed, 85 insertions, 16 deletions
diff --git a/vespajlib/src/main/java/com/yahoo/tensor/IndexedTensor.java b/vespajlib/src/main/java/com/yahoo/tensor/IndexedTensor.java index bc351b45b28..8c1f4bda92c 100644 --- a/vespajlib/src/main/java/com/yahoo/tensor/IndexedTensor.java +++ b/vespajlib/src/main/java/com/yahoo/tensor/IndexedTensor.java @@ -210,7 +210,36 @@ public abstract class IndexedTensor implements Tensor { } @Override - public String toString() { return Tensor.toStandardString(this); } + public String toString() { + if (type.rank() == 0) return Tensor.toStandardString(this); + if (type.dimensions().stream().anyMatch(d -> d.size().isEmpty())) return Tensor.toStandardString(this); + + Indexes indexes = Indexes.of(dimensionSizes); + + StringBuilder b = new StringBuilder(type.toString()).append(":"); + for (int index = 0; index < size(); index++) { + indexes.next(); + + // start brackets + for (int i = 0; i < indexes.rightDimensionsWhichAreAtStart(); i++) + b.append("["); + + // value + if (type.valueType() == TensorType.Value.DOUBLE) + b.append(get(index)); + else if (type.valueType() == TensorType.Value.FLOAT) + b.append(getFloat(index)); + else + throw new IllegalStateException("Unexpected value type " + type.valueType()); + + // end bracket and comma + for (int i = 0; i < indexes.rightDimensionsWhichAreAtEnd(); i++) + b.append("]"); + if (index < size() - 1) + b.append(", "); + } + return b.toString(); + } @Override public boolean equals(Object other) { @@ -829,6 +858,27 @@ public abstract class IndexedTensor implements Tensor { public abstract void next(); + /** Returns the number of dimensions from the right which are currently at the start position (0) */ + int rightDimensionsWhichAreAtStart() { + int dimension = indexes.length - 1; + int atStartCount = 0; + while (dimension >= 0 && indexes[dimension] == 0) { + atStartCount++; + dimension--; + } + return atStartCount; + } + + /** Returns the number of dimensions from the right which are currently at the end position */ + int rightDimensionsWhichAreAtEnd() { + int dimension = indexes.length - 1; + int atEndCount = 0; + while (dimension >= 0 && indexes[dimension] == dimensionSizes().size(dimension) - 1) { + atEndCount++; + dimension--; + } + return atEndCount; + } } private final static class EmptyIndexes extends Indexes { diff --git a/vespajlib/src/test/java/com/yahoo/tensor/TensorParserTestCase.java b/vespajlib/src/test/java/com/yahoo/tensor/TensorParserTestCase.java index 63fe40565bd..1928971820c 100644 --- a/vespajlib/src/test/java/com/yahoo/tensor/TensorParserTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/tensor/TensorParserTestCase.java @@ -23,37 +23,42 @@ public class TensorParserTestCase { @Test public void testDenseParsing() { - assertEquals(Tensor.Builder.of(TensorType.fromSpec("tensor()")).build(), - Tensor.from("tensor():[]")); - assertEquals(Tensor.Builder.of(TensorType.fromSpec("tensor(x[1])")).cell(1.0, 0).build(), - Tensor.from("tensor(x[1]):[1.0]")); - assertEquals(Tensor.Builder.of(TensorType.fromSpec("tensor(x[2])")).cell(1.0, 0).cell(2.0, 1).build(), - Tensor.from("tensor(x[2]):[1.0, 2.0]")); - assertEquals(Tensor.Builder.of(TensorType.fromSpec("tensor(x[2],y[3])")) + assertDense(Tensor.Builder.of(TensorType.fromSpec("tensor()")).build(), + "tensor():{0.0}"); + assertDense(Tensor.Builder.of(TensorType.fromSpec("tensor()")).cell(1.3).build(), + "tensor():{1.3}"); + assertDense(Tensor.Builder.of(TensorType.fromSpec("tensor(x[])")).cell(1.0, 0).build(), + "tensor(x[]):{{x:0}:1.0}"); + assertDense(Tensor.Builder.of(TensorType.fromSpec("tensor(x[1])")).cell(1.0, 0).build(), + "tensor(x[1]):[1.0]"); + assertDense(Tensor.Builder.of(TensorType.fromSpec("tensor(x[2])")).cell(1.0, 0).cell(2.0, 1).build(), + "tensor(x[2]):[1.0, 2.0]"); + assertDense(Tensor.Builder.of(TensorType.fromSpec("tensor(x[2],y[3])")) .cell(1.0, 0, 0) .cell(2.0, 0, 1) .cell(3.0, 0, 2) .cell(4.0, 1, 0) .cell(5.0, 1, 1) .cell(6.0, 1, 2).build(), - Tensor.from("tensor(x[2],y[3]):[[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]]")); - assertEquals(Tensor.Builder.of(TensorType.fromSpec("tensor(x[1],y[2],z[3])")) + "tensor(x[2],y[3]):[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]"); + assertDense(Tensor.Builder.of(TensorType.fromSpec("tensor(x[1],y[2],z[3])")) .cell(1.0, 0, 0, 0) .cell(2.0, 0, 0, 1) .cell(3.0, 0, 0, 2) .cell(4.0, 0, 1, 0) .cell(5.0, 0, 1, 1) .cell(6.0, 0, 1, 2).build(), - Tensor.from("tensor(x[1],y[2],z[3]):[[[1.0], [2.0]], [[3.0], [4.0]], [[5.0], [6.0]]]")); - assertEquals(Tensor.Builder.of(TensorType.fromSpec("tensor(x[3],y[2],z[1])")) + "tensor(x[1],y[2],z[3]):[[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]]"); + assertDense(Tensor.Builder.of(TensorType.fromSpec("tensor(x[3],y[2],z[1])")) .cell(1.0, 0, 0, 0) .cell(2.0, 0, 1, 0) .cell(3.0, 1, 0, 0) .cell(4.0, 1, 1, 0) .cell(5.0, 2, 0, 0) .cell(6.0, 2, 1, 0).build(), - Tensor.from("tensor(x[3],y[2],z[1]):[[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]]")); - assertEquals(Tensor.Builder.of(TensorType.fromSpec("tensor(x[3],y[2],z[1])")) + "tensor(x[3],y[2],z[1]):[[[1.0], [2.0]], [[3.0], [4.0]], [[5.0], [6.0]]]"); + assertEquals("Messy input", + Tensor.Builder.of(TensorType.fromSpec("tensor(x[3],y[2],z[1])")) .cell( 1.0, 0, 0, 0) .cell( 2.0, 0, 1, 0) .cell( 3.0, 1, 0, 0) @@ -61,6 +66,20 @@ public class TensorParserTestCase { .cell( 5.0, 2, 0, 0) .cell(-6.0, 2, 1, 0).build(), Tensor.from("tensor( x[3],y[2],z[1]) : [ [ [1.0, 2.0, 3.0] , [4.0, 5,-6.0] ] ]")); + assertEquals("Skipping syntactic sugar", + Tensor.Builder.of(TensorType.fromSpec("tensor(x[3],y[2],z[1])")) + .cell( 1.0, 0, 0, 0) + .cell( 2.0, 0, 1, 0) + .cell( 3.0, 1, 0, 0) + .cell( 4.0, 1, 1, 0) + .cell( 5.0, 2, 0, 0) + .cell(-6.0, 2, 1, 0).build(), + Tensor.from("tensor( x[3],y[2],z[1]) : [1.0, 2.0, 3.0 , 4.0, 5, -6.0]")); + } + + private void assertDense(Tensor expectedTensor, String denseFormat) { + assertEquals(denseFormat, expectedTensor, Tensor.from(denseFormat)); + assertEquals(denseFormat, expectedTensor.toString()); } @Test diff --git a/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java b/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java index c53db160806..3d5d8d1f5ae 100644 --- a/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java +++ b/vespajlib/src/test/java/com/yahoo/tensor/TensorTestCase.java @@ -89,9 +89,9 @@ public class TensorTestCase { @Test public void testCombineInDimensionIndexed() { - Tensor input = Tensor.from("tensor(input[]):{{input:0}:3, {input:1}:7}"); + Tensor input = Tensor.from("tensor(input[2]):{{input:0}:3, {input:1}:7}"); Tensor result = input.concat(11, "input"); - assertEquals("tensor(input[]):{{input:0}:3.0,{input:1}:7.0,{input:2}:11.0}", result.toString()); + assertEquals("tensor(input[3]):[3.0, 7.0, 11.0]", result.toString()); } /** All functions are more throughly tested in searchlib EvaluationTestCase */ |