From cdebe2fc4f26fb66477b75b6f0519203791ac7e8 Mon Sep 17 00:00:00 2001 From: Iaroslav Postovalov Date: Sun, 20 Dec 2020 00:06:40 +0700 Subject: [PATCH] Add API documentation, fix hashCode --- .../kotlin/kscience/kmath/gsl/GslException.kt | 7 +++++-- .../kotlin/kscience/kmath/gsl/GslMatrix.kt | 19 +++++++++++++++---- .../kscience/kmath/gsl/GslMatrixContext.kt | 18 ++++++++++++++++++ .../kscience/kmath/gsl/GslMemoryHolder.kt | 6 ++++++ .../kotlin/kscience/kmath/gsl/GslVector.kt | 3 +++ kmath-gsl/src/nativeTest/kotlin/RealTest.kt | 8 +++----- 6 files changed, 50 insertions(+), 11 deletions(-) diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslException.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslException.kt index 65e466015..8897b1427 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslException.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslException.kt @@ -29,7 +29,7 @@ internal enum class GslErrnoValue(val code: Int, val text: String) { GSL_EBADTOL(org.gnu.gsl.GSL_EBADTOL, "user specified an invalid tolerance"), GSL_ETOL(org.gnu.gsl.GSL_ETOL, "failed to reach the specified tolerance"), GSL_EUNDRFLW(org.gnu.gsl.GSL_EUNDRFLW, "underflow"), - GSL_EOVRFLW(org.gnu.gsl.GSL_EOVRFLW, "overflow "), + GSL_EOVRFLW(org.gnu.gsl.GSL_EOVRFLW, "overflow"), GSL_ELOSS(org.gnu.gsl.GSL_ELOSS, "loss of accuracy"), GSL_EROUND(org.gnu.gsl.GSL_EROUND, "failed because of roundoff error"), GSL_EBADLEN(org.gnu.gsl.GSL_EBADLEN, "matrix, vector lengths are not conformant"), @@ -54,7 +54,10 @@ internal enum class GslErrnoValue(val code: Int, val text: String) { } } -internal class GslException internal constructor(file: String, line: Int, reason: String, errno: Int) : +/** + * Wraps all the errors reported by GSL. + */ +public class GslException internal constructor(file: String, line: Int, reason: String, errno: Int) : RuntimeException("$file:$line: $reason. errno - $errno, ${GslErrnoValue.valueOf(errno)}") { } diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrix.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrix.kt index 619372eef..e08c0c0d1 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrix.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrix.kt @@ -5,6 +5,9 @@ import kotlinx.cinterop.DeferScope import kscience.kmath.linear.FeaturedMatrix import kscience.kmath.structures.NDStructure +/** + * Wraps gsl_matrix_* objects from GSL. + */ public abstract class GslMatrix internal constructor(scope: DeferScope) : GslMemoryHolder(scope), FeaturedMatrix { @@ -15,9 +18,17 @@ public abstract class GslMatrix internal constructor(sc return NDStructure.equals(this, other as? NDStructure<*> ?: return false) } - public final override fun hashCode(): Int { - var result = nativeHandle.hashCode() - result = 31 * result + features.hashCode() - return result + public override fun hashCode(): Int { + var ret = 7 + val nRows = rowNum + val nCols = colNum + ret = ret * 31 + nRows + ret = ret * 31 + nCols + + for (row in 0 until nRows) + for (col in 0 until nCols) + ret = ret * 31 + (11 * (row + 1) + 17 * (col + 1)) * this[row, col].hashCode() + + return ret } } diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrixContext.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrixContext.kt index de7e4868e..a1f3445ca 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrixContext.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMatrixContext.kt @@ -19,6 +19,9 @@ internal inline fun GslMatrix.fill(initializer: internal inline fun GslVector.fill(initializer: (Int) -> T): GslVector = apply { (0 until size).forEach { index -> this[index] = initializer(index) } } +/** + * Represents matrix context implementing where all the operations are delegated to GSL. + */ public abstract class GslMatrixContext internal constructor( internal val scope: DeferScope ) : MatrixContext> { @@ -26,12 +29,18 @@ public abstract class GslMatrixContext.toGsl(): GslMatrix = (if (this is GslMatrix<*, *>) this as GslMatrix else produce(rowNum, colNum) { i, j -> this[i, j] }).copy() + /** + * Converts this point to GSL one. + */ @Suppress("UNCHECKED_CAST") public fun Point.toGsl(): GslVector = (if (this is GslVector<*, *>) this as GslVector else produceDirtyVector(size).fill { this[it] }).copy() @@ -43,6 +52,9 @@ public abstract class GslMatrixContext(scope) { override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = GslRealMatrix( @@ -88,6 +100,9 @@ public class GslRealMatrixContext(scope: DeferScope) : GslMatrixContext(scope) { override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = @@ -131,6 +146,9 @@ public class GslFloatMatrixContext(scope: DeferScope) : } } +/** + * Represents [Complex] matrix context implementing where all the operations are delegated to GSL. + */ public class GslComplexMatrixContext(scope: DeferScope) : GslMatrixContext(scope) { override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt index d52b78ccc..15ee384b5 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslMemoryHolder.kt @@ -4,6 +4,12 @@ import kotlinx.cinterop.CPointer import kotlinx.cinterop.CStructVar import kotlinx.cinterop.DeferScope +/** + * Represents managed native GSL object. The only property this class holds is pointer to the GSL object. In order to be + * freed this class's object must be added to [DeferScope]. + * + * @param scope the scope where this object is declared. + */ public abstract class GslMemoryHolder internal constructor(internal val scope: DeferScope) { internal abstract val nativeHandle: CPointer diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslVector.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslVector.kt index 65b81f0d7..0033c47a1 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslVector.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslVector.kt @@ -4,6 +4,9 @@ import kotlinx.cinterop.CStructVar import kotlinx.cinterop.DeferScope import kscience.kmath.linear.Point +/** + * Wraps gsl_vector_* objects from GSL. + */ public abstract class GslVector internal constructor(scope: DeferScope) : GslMemoryHolder(scope), Point { internal abstract operator fun set(index: Int, value: T) diff --git a/kmath-gsl/src/nativeTest/kotlin/RealTest.kt b/kmath-gsl/src/nativeTest/kotlin/RealTest.kt index a2af95dfc..e0a7eadb7 100644 --- a/kmath-gsl/src/nativeTest/kotlin/RealTest.kt +++ b/kmath-gsl/src/nativeTest/kotlin/RealTest.kt @@ -3,9 +3,7 @@ package kscience.kmath.gsl import kotlinx.cinterop.memScoped import kscience.kmath.linear.RealMatrixContext import kscience.kmath.operations.invoke -import kscience.kmath.structures.RealBuffer -import kscience.kmath.structures.asIterable -import kscience.kmath.structures.asSequence +import kscience.kmath.structures.* import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -38,8 +36,8 @@ internal class RealTest { (GslRealMatrixContext(this)) { val ma = produce(2, 2) { _, _ -> 100.0 } val mb = produce(2, 2) { _, _ -> 100.0 } - val res1 = ma dot mb - val res2 = RealMatrixContext { ma dot mb } + val res1: Matrix = ma dot mb + val res2: Matrix = RealMatrixContext { ma dot mb } println(res1.rows.asIterable().map { it.asSequence() }.flatMap(Sequence<*>::toList)) println(res2.rows.asIterable().map { it.asSequence() }.flatMap(Sequence<*>::toList)) assertEquals(res1, res2)