diff --git a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt index fd00a0255..df21a8c06 100644 --- a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt +++ b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/matricesCodegen.kt @@ -51,7 +51,7 @@ private fun KtPsiFactory.createMatrixClass( ${fn("gsl_matrixRset")}(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): $className { - val new = requireNotNull(${fn("gsl_matrixRalloc")}(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(${fn("gsl_matrixRalloc")}(rowNum.toULong(), colNum.toULong())) ${fn("gsl_matrixRmemcpy")}(new, nativeHandle) return $className(new, scope) } diff --git a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt index 513d05727..c39b2b8f6 100644 --- a/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt +++ b/buildSrc/src/main/kotlin/kscience/kmath/gsl/codegen/vectorsCodegen.kt @@ -31,7 +31,7 @@ private fun KtPsiFactory.createVectorClass( ${fn("gsl_vectorRset")}(nativeHandle, index.toULong(), value) override fun copy(): $className { - val new = requireNotNull(${fn("gsl_vectorRalloc")}(size.toULong())) + val new = checkNotNull(${fn("gsl_vectorRalloc")}(size.toULong())) ${fn("gsl_vectorRmemcpy")}(new, nativeHandle) return ${className}(new, scope) } diff --git a/kmath-gsl/build.gradle.kts b/kmath-gsl/build.gradle.kts index df405326f..83859130c 100644 --- a/kmath-gsl/build.gradle.kts +++ b/kmath-gsl/build.gradle.kts @@ -12,7 +12,7 @@ kotlin { val nativeTarget = when (System.getProperty("os.name")) { // "Mac OS X" -> macosX64() - "Linux" -> linuxX64() + "Linux" -> linuxX64("native") else -> { logger.warn("Current OS cannot build any of kmath-gsl targets.") @@ -29,7 +29,7 @@ kotlin { val test by nativeTarget.compilations.getting sourceSets { - val nativeMain by creating { + val nativeMain by getting { val codegen by tasks.creating { matricesCodegen(kotlin.srcDirs.first().absolutePath + "/kscience/kmath/gsl/_Matrices.kt") vectorsCodegen(kotlin.srcDirs.first().absolutePath + "/kscience/kmath/gsl/_Vectors.kt") @@ -42,11 +42,11 @@ kotlin { } } - val nativeTest by creating { + val nativeTest by getting { dependsOn(nativeMain) } - main.defaultSourceSet.dependsOn(nativeMain) - test.defaultSourceSet.dependsOn(nativeTest) +// main.defaultSourceSet.dependsOn(nativeMain) +// test.defaultSourceSet.dependsOn(nativeTest) } } diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslComplex.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslComplex.kt index 6881bb0e4..4a48e432a 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslComplex.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslComplex.kt @@ -44,7 +44,7 @@ internal class GslComplexMatrix(override val rawNativeHandle: CPointer() { override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = GslRealMatrix( - rawNativeHandle = requireNotNull(gsl_matrix_alloc(rows.toULong(), columns.toULong())), + rawNativeHandle = checkNotNull(gsl_matrix_alloc(rows.toULong(), columns.toULong())), scope = scope, ) override fun produceDirtyVector(size: Int): GslVector = - GslRealVector(rawNativeHandle = requireNotNull(gsl_vector_alloc(size.toULong())), scope = scope) + GslRealVector(rawNativeHandle = checkNotNull(gsl_vector_alloc(size.toULong())), scope = scope) public override fun Matrix.dot(other: Matrix): GslMatrix { val x = toGsl().nativeHandle val a = other.toGsl().nativeHandle - val result = requireNotNull(gsl_matrix_calloc(a.pointed.size1, a.pointed.size2)) + val result = checkNotNull(gsl_matrix_calloc(a.pointed.size1, a.pointed.size2)) gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, x, a, 1.0, result) return GslRealMatrix(result, scope = scope) } @@ -81,7 +81,7 @@ public class GslRealMatrixContext(internal val scope: AutofreeScope) : public override fun Matrix.dot(vector: Point): GslVector { val x = toGsl().nativeHandle val a = vector.toGsl().nativeHandle - val result = requireNotNull(gsl_vector_calloc(a.pointed.size)) + val result = checkNotNull(gsl_vector_calloc(a.pointed.size)) gsl_blas_dgemv(CblasNoTrans, 1.0, x, a, 1.0, result) return GslRealVector(result, scope = scope) } @@ -118,12 +118,11 @@ public class GslRealMatrixContext(internal val scope: AutofreeScope) : private val lups by lazy { val lu = m.toGsl().copy() val n = m.rowNum - val perm = gsl_permutation_alloc(n.toULong()) - scope.defer { gsl_permutation_free(perm) } + val perm = GslPermutation(checkNotNull(gsl_permutation_alloc(n.toULong())), scope) val signum = memScoped { val i = alloc() - gsl_linalg_LU_decomp(lu.nativeHandle, perm, i.ptr) + gsl_linalg_LU_decomp(lu.nativeHandle, perm.nativeHandle, i.ptr) i.value } @@ -135,11 +134,8 @@ public class GslRealMatrixContext(internal val scope: AutofreeScope) : val one = produce(n, n) { i, j -> if (i == j) 1.0 else 0.0 } val perm = produce(n, n) { _, _ -> 0.0 } - for (j in 0 until lups.second!!.pointed.size.toInt()) { - val k = gsl_permutation_get(lups.second!!, j.toULong()).toInt() - val col = one.columns[k] - gsl_matrix_set_col(perm.nativeHandle, j.toULong(), col.toGsl().nativeHandle) - } + for (j in 0 until lups.second.size) + gsl_matrix_set_col(perm.nativeHandle, j.toULong(), one.columns[lups.second[j]].toGsl().nativeHandle) perm } @@ -165,7 +161,7 @@ public class GslRealMatrixContext(internal val scope: AutofreeScope) : override val inverse by lazy { val inv = lups.first.copy() - gsl_linalg_LU_invx(inv.nativeHandle, lups.second) + gsl_linalg_LU_invx(inv.nativeHandle, lups.second.nativeHandle) inv } } @@ -194,17 +190,17 @@ public fun GslRealMatrixContext(block: GslRealMatrixContext.() -> R): R = public class GslFloatMatrixContext(internal val scope: AutofreeScope) : GslMatrixContext() { override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = GslFloatMatrix( - rawNativeHandle = requireNotNull(gsl_matrix_float_alloc(rows.toULong(), columns.toULong())), + rawNativeHandle = checkNotNull(gsl_matrix_float_alloc(rows.toULong(), columns.toULong())), scope = scope, ) override fun produceDirtyVector(size: Int): GslVector = - GslFloatVector(rawNativeHandle = requireNotNull(value = gsl_vector_float_alloc(size.toULong())), scope = scope) + GslFloatVector(rawNativeHandle = checkNotNull(value = gsl_vector_float_alloc(size.toULong())), scope = scope) public override fun Matrix.dot(other: Matrix): GslMatrix { val x = toGsl().nativeHandle val a = other.toGsl().nativeHandle - val result = requireNotNull(gsl_matrix_float_calloc(a.pointed.size1, a.pointed.size2)) + val result = checkNotNull(gsl_matrix_float_calloc(a.pointed.size1, a.pointed.size2)) gsl_blas_sgemm(CblasNoTrans, CblasNoTrans, 1f, x, a, 1f, result) return GslFloatMatrix(rawNativeHandle = result, scope = scope) } @@ -212,7 +208,7 @@ public class GslFloatMatrixContext(internal val scope: AutofreeScope) : public override fun Matrix.dot(vector: Point): GslVector { val x = toGsl().nativeHandle val a = vector.toGsl().nativeHandle - val result = requireNotNull(gsl_vector_float_calloc(a.pointed.size)) + val result = checkNotNull(gsl_vector_float_calloc(a.pointed.size)) gsl_blas_sgemv(CblasNoTrans, 1f, x, a, 1f, result) return GslFloatVector(rawNativeHandle = result, scope = scope) } @@ -254,17 +250,17 @@ public fun GslFloatMatrixContext(block: GslFloatMatrixContext.() -> R): R = public class GslComplexMatrixContext(internal val scope: AutofreeScope) : GslMatrixContext() { override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix = GslComplexMatrix( - rawNativeHandle = requireNotNull(gsl_matrix_complex_alloc(rows.toULong(), columns.toULong())), + rawNativeHandle = checkNotNull(gsl_matrix_complex_alloc(rows.toULong(), columns.toULong())), scope = scope, ) override fun produceDirtyVector(size: Int): GslVector = - GslComplexVector(rawNativeHandle = requireNotNull(gsl_vector_complex_alloc(size.toULong())), scope = scope) + GslComplexVector(rawNativeHandle = checkNotNull(gsl_vector_complex_alloc(size.toULong())), scope = scope) public override fun Matrix.dot(other: Matrix): GslMatrix { val x = toGsl().nativeHandle val a = other.toGsl().nativeHandle - val result = requireNotNull(gsl_matrix_complex_calloc(a.pointed.size1, a.pointed.size2)) + val result = checkNotNull(gsl_matrix_complex_calloc(a.pointed.size1, a.pointed.size2)) gsl_blas_zgemm(CblasNoTrans, CblasNoTrans, ComplexField.one.toGsl(), x, a, ComplexField.one.toGsl(), result) return GslComplexMatrix(rawNativeHandle = result, scope = scope) } @@ -272,7 +268,7 @@ public class GslComplexMatrixContext(internal val scope: AutofreeScope) : public override fun Matrix.dot(vector: Point): GslVector { val x = toGsl().nativeHandle val a = vector.toGsl().nativeHandle - val result = requireNotNull(gsl_vector_complex_calloc(a.pointed.size)) + val result = checkNotNull(gsl_vector_complex_calloc(a.pointed.size)) gsl_blas_zgemv(CblasNoTrans, ComplexField.one.toGsl(), x, a, ComplexField.one.toGsl(), result) return GslComplexVector(result, scope) } @@ -309,12 +305,11 @@ public class GslComplexMatrixContext(internal val scope: AutofreeScope) : private val lups by lazy { val lu = m.toGsl().copy() val n = m.rowNum - val perm = gsl_permutation_alloc(n.toULong()) - scope.defer { gsl_permutation_free(perm) } + val perm = GslPermutation(checkNotNull(gsl_permutation_alloc(n.toULong())), scope) val signum = memScoped { val i = alloc() - gsl_linalg_complex_LU_decomp(lu.nativeHandle, perm, i.ptr) + gsl_linalg_complex_LU_decomp(lu.nativeHandle, perm.nativeHandle, i.ptr) i.value } @@ -326,11 +321,8 @@ public class GslComplexMatrixContext(internal val scope: AutofreeScope) : val one = produce(n, n) { i, j -> if (i == j) 1.0.toComplex() else 0.0.toComplex() } val perm = produce(n, n) { _, _ -> 0.0.toComplex() } - for (j in 0 until lups.second!!.pointed.size.toInt()) { - val k = gsl_permutation_get(lups.second!!, j.toULong()).toInt() - val col = one.columns[k] - gsl_matrix_complex_set_col(perm.nativeHandle, j.toULong(), col.toGsl().nativeHandle) - } + for (j in 0 until lups.second.size) + gsl_matrix_complex_set_col(perm.nativeHandle, j.toULong(), one.columns[lups.second[j]].toGsl().nativeHandle) perm } @@ -352,13 +344,11 @@ public class GslComplexMatrixContext(internal val scope: AutofreeScope) : ) { i, j -> if (j >= i) lups.first[i, j] else 0.0.toComplex() } + UFeature } - override val determinant by lazy { - gsl_linalg_complex_LU_det(lups.first.nativeHandle, lups.third).toKMath() - } + override val determinant by lazy { gsl_linalg_complex_LU_det(lups.first.nativeHandle, lups.third).toKMath() } override val inverse by lazy { val inv = lups.first.copy() - gsl_linalg_complex_LU_invx(inv.nativeHandle, lups.second) + gsl_linalg_complex_LU_invx(inv.nativeHandle, lups.second.nativeHandle) inv } } diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslPermutation.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslPermutation.kt new file mode 100644 index 000000000..3d5c4a3a4 --- /dev/null +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/GslPermutation.kt @@ -0,0 +1,16 @@ +package kscience.kmath.gsl + +import kotlinx.cinterop.AutofreeScope +import kotlinx.cinterop.CPointer +import kotlinx.cinterop.pointed +import org.gnu.gsl.gsl_permutation +import org.gnu.gsl.gsl_permutation_free +import org.gnu.gsl.gsl_permutation_get + +internal class GslPermutation(override val rawNativeHandle: CPointer, scope: AutofreeScope) : + GslMemoryHolder(scope) { + val size get() = nativeHandle.pointed.size.toInt() + + operator fun get(i: Int) = gsl_permutation_get(nativeHandle, i.toULong()).toInt() + override fun close() = gsl_permutation_free(nativeHandle) +} diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt index 1a826d493..7dbab66d7 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Matrices.kt @@ -37,7 +37,7 @@ internal class GslRealMatrix( gsl_matrix_set(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): GslRealMatrix { - val new = requireNotNull(gsl_matrix_alloc(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(gsl_matrix_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_memcpy(new, nativeHandle) return GslRealMatrix(new, scope) } @@ -85,7 +85,7 @@ internal class GslFloatMatrix( gsl_matrix_float_set(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): GslFloatMatrix { - val new = requireNotNull(gsl_matrix_float_alloc(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(gsl_matrix_float_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_float_memcpy(new, nativeHandle) return GslFloatMatrix(new, scope) } @@ -133,7 +133,7 @@ internal class GslShortMatrix( gsl_matrix_short_set(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): GslShortMatrix { - val new = requireNotNull(gsl_matrix_short_alloc(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(gsl_matrix_short_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_short_memcpy(new, nativeHandle) return GslShortMatrix(new, scope) } @@ -181,7 +181,7 @@ internal class GslUShortMatrix( gsl_matrix_ushort_set(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): GslUShortMatrix { - val new = requireNotNull(gsl_matrix_ushort_alloc(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(gsl_matrix_ushort_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_ushort_memcpy(new, nativeHandle) return GslUShortMatrix(new, scope) } @@ -229,7 +229,7 @@ internal class GslLongMatrix( gsl_matrix_long_set(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): GslLongMatrix { - val new = requireNotNull(gsl_matrix_long_alloc(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(gsl_matrix_long_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_long_memcpy(new, nativeHandle) return GslLongMatrix(new, scope) } @@ -277,7 +277,7 @@ internal class GslULongMatrix( gsl_matrix_ulong_set(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): GslULongMatrix { - val new = requireNotNull(gsl_matrix_ulong_alloc(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(gsl_matrix_ulong_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_ulong_memcpy(new, nativeHandle) return GslULongMatrix(new, scope) } @@ -325,7 +325,7 @@ internal class GslIntMatrix( gsl_matrix_int_set(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): GslIntMatrix { - val new = requireNotNull(gsl_matrix_int_alloc(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(gsl_matrix_int_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_int_memcpy(new, nativeHandle) return GslIntMatrix(new, scope) } @@ -373,7 +373,7 @@ internal class GslUIntMatrix( gsl_matrix_uint_set(nativeHandle, i.toULong(), j.toULong(), value) override fun copy(): GslUIntMatrix { - val new = requireNotNull(gsl_matrix_uint_alloc(rowNum.toULong(), colNum.toULong())) + val new = checkNotNull(gsl_matrix_uint_alloc(rowNum.toULong(), colNum.toULong())) gsl_matrix_uint_memcpy(new, nativeHandle) return GslUIntMatrix(new, scope) } diff --git a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt index 5b5236242..42ecb2fca 100644 --- a/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt +++ b/kmath-gsl/src/nativeMain/kotlin/kscience/kmath/gsl/_Vectors.kt @@ -15,7 +15,7 @@ internal class GslRealVector(override val rawNativeHandle: CPointer, gsl_vector_set(nativeHandle, index.toULong(), value) override fun copy(): GslRealVector { - val new = requireNotNull(gsl_vector_alloc(size.toULong())) + val new = checkNotNull(gsl_vector_alloc(size.toULong())) gsl_vector_memcpy(new, nativeHandle) return GslRealVector(new, scope) } @@ -42,7 +42,7 @@ internal class GslFloatVector(override val rawNativeHandle: CPointer