From 57e72ce5aa59b12e6d883b39b0822bf6d76fdbb7 Mon Sep 17 00:00:00 2001 From: Sergei Lebedev Date: Mon, 5 Sep 2016 12:34:41 +0300 Subject: [PATCH] Fixed a bug in 'StridedMatrix2.toString' --- CHANGES | 6 +++ .../jetbrains/bio/viktor/StridedMatrix2.kt | 40 +++++++++++-------- .../jetbrains/bio/viktor/StridedMatrix3.kt | 36 +++++++++++++++-- .../org/jetbrains/bio/viktor/StridedVector.kt | 6 +-- .../bio/viktor/StridedMatrix2Tests.kt | 10 ++++- .../bio/viktor/StridedMatrix3Tests.kt | 15 +++++++ 6 files changed, 90 insertions(+), 23 deletions(-) diff --git a/CHANGES b/CHANGES index bef708a..4e01d8b 100644 --- a/CHANGES +++ b/CHANGES @@ -3,6 +3,12 @@ viktor Changelog Here you can see the full list of changes between each viktor release. +Version 0.3.4 +------------- + +- Fixed a bug in 'StridedMatrix2.toString', which incorrectly rendered + large matrices, and unified the implementation with 'StridedMatrix3'. + Version 0.3.3 ------------- diff --git a/src/main/kotlin/org/jetbrains/bio/viktor/StridedMatrix2.kt b/src/main/kotlin/org/jetbrains/bio/viktor/StridedMatrix2.kt index 8eff2dd..aaed0ff 100644 --- a/src/main/kotlin/org/jetbrains/bio/viktor/StridedMatrix2.kt +++ b/src/main/kotlin/org/jetbrains/bio/viktor/StridedMatrix2.kt @@ -1,6 +1,5 @@ package org.jetbrains.bio.viktor -import java.util.* import java.util.stream.IntStream import java.util.stream.Stream @@ -150,25 +149,34 @@ class StridedMatrix2 internal constructor( fun toArray() = Array(rowsNumber) { rowView(it).toArray() } - private fun toString(maxDisplay: Int): String { - if (Math.max(rowsNumber, columnsNumber) <= maxDisplay) { - return Arrays.deepToString(toArray()) - } else { - val numRows = Math.min(rowsNumber, maxDisplay) - val sb = StringBuilder() - sb.append('[') - for (r in 0..numRows - 1) { - sb.append(rowView(r)) + internal fun toString(maxDisplay: Int): String { + val sb = StringBuilder() + sb.append('[') + if (maxDisplay < rowsNumber) { + for (r in 0..maxDisplay / 2 - 1) { + sb.append(this[r].toString(maxDisplay)).append(", ") } - if (numRows > maxDisplay) { - sb.append(", ...]") - } else { - sb.append(']') - } + sb.append("..., ") - return sb.toString() + val leftover = maxDisplay - maxDisplay / 2 + for (r in rowsNumber - leftover..rowsNumber - 1) { + sb.append(this[r].toString(maxDisplay)) + if (r < rowsNumber - 1) { + sb.append(", ") + } + } + } else { + for (r in 0..rowsNumber - 1) { + sb.append(this[r].toString(maxDisplay)) + if (r < rowsNumber - 1) { + sb.append(", ") + } + } } + + sb.append(']') + return sb.toString() } override fun toString() = toString(8) diff --git a/src/main/kotlin/org/jetbrains/bio/viktor/StridedMatrix3.kt b/src/main/kotlin/org/jetbrains/bio/viktor/StridedMatrix3.kt index 3700924..6bf5a12 100644 --- a/src/main/kotlin/org/jetbrains/bio/viktor/StridedMatrix3.kt +++ b/src/main/kotlin/org/jetbrains/bio/viktor/StridedMatrix3.kt @@ -1,7 +1,5 @@ package org.jetbrains.bio.viktor -import java.util.* - /** * A specialization of [StridedMatrix] for 3-D data. * @@ -106,7 +104,39 @@ class StridedMatrix3 internal constructor( fun toArray() = Array(depth) { view(it).toArray() } - override fun toString() = Arrays.deepToString(toArray()) + // XXX: abstract this copy-paste into an interface? See + // [StridedMatrix2.toString]. + internal fun toString(maxDisplay: Int): String { + val sb = StringBuilder() + sb.append('[') + if (maxDisplay < rowsNumber) { + for (r in 0..maxDisplay / 2 - 1) { + sb.append(this[r].toString(maxDisplay)).append(", ") + } + + sb.append("..., ") + + val leftover = maxDisplay - maxDisplay / 2 + for (r in rowsNumber - leftover..rowsNumber - 1) { + sb.append(this[r].toString(maxDisplay)) + if (r < rowsNumber - 1) { + sb.append(", ") + } + } + } else { + for (r in 0..rowsNumber - 1) { + sb.append(this[r].toString(maxDisplay)) + if (r < rowsNumber - 1) { + sb.append(", ") + } + } + } + + sb.append(']') + return sb.toString() + } + + override fun toString() = toString(8) override fun equals(other: Any?): Boolean { if (this === other) { diff --git a/src/main/kotlin/org/jetbrains/bio/viktor/StridedVector.kt b/src/main/kotlin/org/jetbrains/bio/viktor/StridedVector.kt index f1e2a41..fef609b 100644 --- a/src/main/kotlin/org/jetbrains/bio/viktor/StridedVector.kt +++ b/src/main/kotlin/org/jetbrains/bio/viktor/StridedVector.kt @@ -440,8 +440,8 @@ open class StridedVector internal constructor( else -> format(value) } - fun toString(maxDisplay: Int, - format: DecimalFormat = DecimalFormat("#.####")): String { + internal fun toString(maxDisplay: Int, + format: DecimalFormat = DecimalFormat("#.####")): String { val sb = StringBuilder() sb.append('[') @@ -472,7 +472,7 @@ open class StridedVector internal constructor( return sb.toString() } - override fun toString() = toString(16) + override fun toString() = toString(8) override fun equals(other: Any?): Boolean { if (this === other) { diff --git a/src/test/kotlin/org/jetbrains/bio/viktor/StridedMatrix2Tests.kt b/src/test/kotlin/org/jetbrains/bio/viktor/StridedMatrix2Tests.kt index 6ea8e14..f1c9ea3 100644 --- a/src/test/kotlin/org/jetbrains/bio/viktor/StridedMatrix2Tests.kt +++ b/src/test/kotlin/org/jetbrains/bio/viktor/StridedMatrix2Tests.kt @@ -141,6 +141,14 @@ class StridedMatrix2OpsTest { @Test fun _toString() { assertEquals("[]", StridedMatrix(0, 0).toString()) assertEquals("[[]]", StridedMatrix(1, 0).toString()) - assertEquals("[[0.0], [0.0]]", StridedMatrix(2, 1).toString()) + assertEquals("[[0], [0]]", StridedMatrix(2, 1).toString()) + } + + @Test fun toStringLarge() { + val v = StridedVector(1024) { it.toDouble() } + assertEquals("[[0, 1], [2, 3], ..., [1020, 1021], [1022, 1023]]", + v.reshape(512, 2).toString(4)) + assertEquals("[[0, 1, ..., 510, 511], [512, 513, ..., 1022, 1023]]", + v.reshape(2, 512).toString(4)) } } \ No newline at end of file diff --git a/src/test/kotlin/org/jetbrains/bio/viktor/StridedMatrix3Tests.kt b/src/test/kotlin/org/jetbrains/bio/viktor/StridedMatrix3Tests.kt index 1e3501e..e736382 100644 --- a/src/test/kotlin/org/jetbrains/bio/viktor/StridedMatrix3Tests.kt +++ b/src/test/kotlin/org/jetbrains/bio/viktor/StridedMatrix3Tests.kt @@ -134,4 +134,19 @@ class StridedMatrix3GetSet { assertEquals(m[d], copy[d]) } } +} + +class StridedMatrix3OpsTest { + @Test fun equals() { + val m = StridedMatrix(2, 3, 4) { i, j, k -> 1.0 * i + 2 * j + 3 * k } + + assertEquals(m, m) + assertEquals(m, m.copy()) + assertNotEquals(m, m.exp()) + } + + @Test fun _toString() { + assertEquals("[]", StridedMatrix(0, 0, 0).toString()) + assertEquals("[[[0]]]", StridedMatrix(1, 1, 1).toString()) + } } \ No newline at end of file