forked from kscience/kmath
Rename files, improve error handling, minor codegen update
This commit is contained in:
parent
657dbcb829
commit
f341d02941
@ -18,8 +18,8 @@ private fun KtPsiFactory.createVectorClass(
|
|||||||
val structName = sn("gsl_vectorR", cTypeName)
|
val structName = sn("gsl_vectorR", cTypeName)
|
||||||
|
|
||||||
@Language("kotlin") val text =
|
@Language("kotlin") val text =
|
||||||
"""internal class $className(override val nativeHandle: CPointer<$structName>, scope: DeferScope)
|
"""internal class $className(override val nativeHandle: CPointer<$structName>, scope: DeferScope) :
|
||||||
: GslVector<$kotlinTypeName, $structName>(scope) {
|
GslVector<$kotlinTypeName, $structName>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ kotlin {
|
|||||||
|
|
||||||
val nativeTarget = when (System.getProperty("os.name")) {
|
val nativeTarget = when (System.getProperty("os.name")) {
|
||||||
"Mac OS X" -> macosX64()
|
"Mac OS X" -> macosX64()
|
||||||
"Linux" -> linuxX64()
|
"Linux" -> linuxX64("native")
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
logger.warn("Current OS cannot build any of kmath-gsl targets.")
|
logger.warn("Current OS cannot build any of kmath-gsl targets.")
|
||||||
@ -29,7 +29,7 @@ kotlin {
|
|||||||
val test by nativeTarget.compilations.getting
|
val test by nativeTarget.compilations.getting
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
val nativeMain by creating {
|
val nativeMain by getting {
|
||||||
val codegen by tasks.creating {
|
val codegen by tasks.creating {
|
||||||
matricesCodegen(kotlin.srcDirs.first().absolutePath + "/kscience/kmath/gsl/_Matrices.kt")
|
matricesCodegen(kotlin.srcDirs.first().absolutePath + "/kscience/kmath/gsl/_Matrices.kt")
|
||||||
vectorsCodegen(kotlin.srcDirs.first().absolutePath + "/kscience/kmath/gsl/_Vectors.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)
|
dependsOn(nativeMain)
|
||||||
}
|
}
|
||||||
|
|
||||||
main.defaultSourceSet.dependsOn(nativeMain)
|
// main.defaultSourceSet.dependsOn(nativeMain)
|
||||||
test.defaultSourceSet.dependsOn(nativeTest)
|
// test.defaultSourceSet.dependsOn(nativeTest)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
package kscience.kmath.gsl
|
||||||
|
|
||||||
|
import kotlinx.cinterop.staticCFunction
|
||||||
|
import kotlinx.cinterop.toKString
|
||||||
|
import org.gnu.gsl.gsl_set_error_handler
|
||||||
|
import org.gnu.gsl.gsl_set_error_handler_off
|
||||||
|
import kotlin.native.concurrent.AtomicInt
|
||||||
|
|
||||||
|
private object Container {
|
||||||
|
val isKmathHandlerRegistered = AtomicInt(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum class GslErrnoValue(val code: Int, val text: String) {
|
||||||
|
GSL_SUCCESS(org.gnu.gsl.GSL_SUCCESS, ""),
|
||||||
|
GSL_FAILURE(org.gnu.gsl.GSL_FAILURE, ""),
|
||||||
|
GSL_CONTINUE(org.gnu.gsl.GSL_CONTINUE, "iteration has not converged"),
|
||||||
|
GSL_EDOM(org.gnu.gsl.GSL_EDOM, "input domain error, e.g sqrt(-1)"),
|
||||||
|
GSL_ERANGE(org.gnu.gsl.GSL_ERANGE, "output range error, e.g. exp(1e100)"),
|
||||||
|
GSL_EFAULT(org.gnu.gsl.GSL_EFAULT, "invalid pointer"),
|
||||||
|
GSL_EINVAL(org.gnu.gsl.GSL_EINVAL, "invalid argument supplied by user"),
|
||||||
|
GSL_EFAILED(org.gnu.gsl.GSL_EFAILED, "generic failure"),
|
||||||
|
GSL_EFACTOR(org.gnu.gsl.GSL_EFACTOR, "factorization failed"),
|
||||||
|
GSL_ESANITY(org.gnu.gsl.GSL_ESANITY, "sanity check failed - shouldn't happen"),
|
||||||
|
GSL_ENOMEM(org.gnu.gsl.GSL_ENOMEM, "malloc failed"),
|
||||||
|
GSL_EBADFUNC(org.gnu.gsl.GSL_EBADFUNC, "problem with user-supplied function"),
|
||||||
|
GSL_ERUNAWAY(org.gnu.gsl.GSL_ERUNAWAY, "iterative process is out of control"),
|
||||||
|
GSL_EMAXITER(org.gnu.gsl.GSL_EMAXITER, "exceeded max number of iterations"),
|
||||||
|
GSL_EZERODIV(org.gnu.gsl.GSL_EZERODIV, "tried to divide by zero"),
|
||||||
|
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_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"),
|
||||||
|
GSL_ENOTSQR(org.gnu.gsl.GSL_ENOTSQR, "matrix not square"),
|
||||||
|
GSL_ESING(org.gnu.gsl.GSL_ESING, "apparent singularity detected"),
|
||||||
|
GSL_EDIVERGE(org.gnu.gsl.GSL_EDIVERGE, "integral or series is divergent"),
|
||||||
|
GSL_EUNSUP(org.gnu.gsl.GSL_EUNSUP, "requested feature is not supported by the hardware"),
|
||||||
|
GSL_EUNIMPL(org.gnu.gsl.GSL_EUNIMPL, "requested feature not (yet) implemented"),
|
||||||
|
GSL_ECACHE(org.gnu.gsl.GSL_ECACHE, "cache limit exceeded"),
|
||||||
|
GSL_ETABLE(org.gnu.gsl.GSL_ETABLE, "table limit exceeded"),
|
||||||
|
GSL_ENOPROG(org.gnu.gsl.GSL_ENOPROG, "iteration is not making progress towards solution"),
|
||||||
|
GSL_ENOPROGJ(org.gnu.gsl.GSL_ENOPROGJ, "jacobian evaluations are not improving the solution"),
|
||||||
|
GSL_ETOLF(org.gnu.gsl.GSL_ETOLF, "cannot reach the specified tolerance in F"),
|
||||||
|
GSL_ETOLX(org.gnu.gsl.GSL_ETOLX, "cannot reach the specified tolerance in X"),
|
||||||
|
GSL_ETOLG(org.gnu.gsl.GSL_ETOLG, "cannot reach the specified tolerance in gradient"),
|
||||||
|
GSL_EOF(org.gnu.gsl.GSL_EOF, "end of file");
|
||||||
|
|
||||||
|
override fun toString(): String = "${name}('$text')"
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun valueOf(code: Int): GslErrnoValue? = values().find { it.code == code }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class GslException internal constructor(file: String, line: Int, reason: String, errno: Int) :
|
||||||
|
RuntimeException("$file:$line: $reason. errno - $errno, ${GslErrnoValue.valueOf(errno)}") {
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun ensureHasGslErrorHandler() {
|
||||||
|
if (Container.isKmathHandlerRegistered.value == 1) return
|
||||||
|
gsl_set_error_handler_off()
|
||||||
|
|
||||||
|
gsl_set_error_handler(staticCFunction { reason, file, line, errno ->
|
||||||
|
throw GslException(checkNotNull(file).toKString(), line, checkNotNull(reason).toKString(), errno)
|
||||||
|
})
|
||||||
|
|
||||||
|
Container.isKmathHandlerRegistered.value = 1
|
||||||
|
}
|
@ -1,7 +1,175 @@
|
|||||||
package kscience.kmath.gsl
|
package kscience.kmath.gsl
|
||||||
|
|
||||||
import kotlinx.cinterop.CStructVar
|
import kotlinx.cinterop.CStructVar
|
||||||
|
import kotlinx.cinterop.DeferScope
|
||||||
|
import kotlinx.cinterop.pointed
|
||||||
import kscience.kmath.linear.MatrixContext
|
import kscience.kmath.linear.MatrixContext
|
||||||
import kscience.kmath.linear.Point
|
import kscience.kmath.linear.Point
|
||||||
|
import kscience.kmath.operations.Complex
|
||||||
|
import kscience.kmath.operations.ComplexField
|
||||||
|
import kscience.kmath.operations.toComplex
|
||||||
import kscience.kmath.structures.Matrix
|
import kscience.kmath.structures.Matrix
|
||||||
|
import org.gnu.gsl.*
|
||||||
|
|
||||||
|
internal inline fun <T : Any, H : CStructVar> GslMatrix<T, H>.fill(initializer: (Int, Int) -> T): GslMatrix<T, H> =
|
||||||
|
apply {
|
||||||
|
(0 until rowNum).forEach { row -> (0 until colNum).forEach { col -> this[row, col] = initializer(row, col) } }
|
||||||
|
}
|
||||||
|
|
||||||
|
internal inline fun <T : Any, H : CStructVar> GslVector<T, H>.fill(initializer: (Int) -> T): GslVector<T, H> =
|
||||||
|
apply { (0 until size).forEach { index -> this[index] = initializer(index) } }
|
||||||
|
|
||||||
|
public abstract class GslMatrixContext<
|
||||||
|
T : Any,
|
||||||
|
H1 : CStructVar,
|
||||||
|
H2 : CStructVar> internal constructor(internal val scope: DeferScope) : MatrixContext<T> {
|
||||||
|
init {
|
||||||
|
ensureHasGslErrorHandler()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
public fun Matrix<T>.toGsl(): GslMatrix<T, H1> = (if (this is GslMatrix<*, *>)
|
||||||
|
this as GslMatrix<T, H1>
|
||||||
|
else
|
||||||
|
produce(rowNum, colNum) { i, j -> this[i, j] }).copy()
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
public fun Point<T>.toGsl(): GslVector<T, H2> =
|
||||||
|
(if (this is GslVector<*, *>) this as GslVector<T, H2> else produceDirtyVector(size).fill { this[it] }).copy()
|
||||||
|
|
||||||
|
internal abstract fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix<T, H1>
|
||||||
|
internal abstract fun produceDirtyVector(size: Int): GslVector<T, H2>
|
||||||
|
|
||||||
|
public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): GslMatrix<T, H1> =
|
||||||
|
produceDirtyMatrix(rows, columns).fill(initializer)
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GslRealMatrixContext(scope: DeferScope) : GslMatrixContext<Double, gsl_matrix, gsl_vector>(scope) {
|
||||||
|
override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix<Double, gsl_matrix> =
|
||||||
|
GslRealMatrix(nativeHandle = requireNotNull(gsl_matrix_alloc(rows.toULong(), columns.toULong())), scope = scope)
|
||||||
|
|
||||||
|
override fun produceDirtyVector(size: Int): GslVector<Double, gsl_vector> =
|
||||||
|
GslRealVector(nativeHandle = requireNotNull(gsl_vector_alloc(size.toULong())), scope = scope)
|
||||||
|
|
||||||
|
public override fun Matrix<Double>.dot(other: Matrix<Double>): GslMatrix<Double, gsl_matrix> {
|
||||||
|
val x = toGsl().nativeHandle
|
||||||
|
val a = other.toGsl().nativeHandle
|
||||||
|
val result = requireNotNull(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun Matrix<Double>.dot(vector: Point<Double>): GslVector<Double, gsl_vector> {
|
||||||
|
val x = toGsl().nativeHandle
|
||||||
|
val a = vector.toGsl().nativeHandle
|
||||||
|
val result = requireNotNull(gsl_vector_calloc(a.pointed.size))
|
||||||
|
gsl_blas_dgemv(CblasNoTrans, 1.0, x, a, 1.0, result)
|
||||||
|
return GslRealVector(result, scope = scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun Matrix<Double>.times(value: Double): GslMatrix<Double, gsl_matrix> {
|
||||||
|
val g1 = toGsl()
|
||||||
|
gsl_matrix_scale(g1.nativeHandle, value)
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun add(a: Matrix<Double>, b: Matrix<Double>): GslMatrix<Double, gsl_matrix> {
|
||||||
|
val g1 = a.toGsl()
|
||||||
|
gsl_matrix_add(g1.nativeHandle, b.toGsl().nativeHandle)
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun multiply(a: Matrix<Double>, k: Number): GslMatrix<Double, gsl_matrix> {
|
||||||
|
val g1 = a.toGsl()
|
||||||
|
gsl_matrix_scale(g1.nativeHandle, k.toDouble())
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GslFloatMatrixContext(scope: DeferScope) :
|
||||||
|
GslMatrixContext<Float, gsl_matrix_float, gsl_vector_float>(scope) {
|
||||||
|
override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix<Float, gsl_matrix_float> =
|
||||||
|
GslFloatMatrix(requireNotNull(gsl_matrix_float_alloc(rows.toULong(), columns.toULong())), scope = scope)
|
||||||
|
|
||||||
|
override fun produceDirtyVector(size: Int): GslVector<Float, gsl_vector_float> =
|
||||||
|
GslFloatVector(requireNotNull(gsl_vector_float_alloc(size.toULong())), scope)
|
||||||
|
|
||||||
|
public override fun Matrix<Float>.dot(other: Matrix<Float>): GslMatrix<Float, gsl_matrix_float> {
|
||||||
|
val x = toGsl().nativeHandle
|
||||||
|
val a = other.toGsl().nativeHandle
|
||||||
|
val result = requireNotNull(gsl_matrix_float_calloc(a.pointed.size1, a.pointed.size2))
|
||||||
|
gsl_blas_sgemm(CblasNoTrans, CblasNoTrans, 1f, x, a, 1f, result)
|
||||||
|
return GslFloatMatrix(nativeHandle = result, scope = scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun Matrix<Float>.dot(vector: Point<Float>): GslVector<Float, gsl_vector_float> {
|
||||||
|
val x = toGsl().nativeHandle
|
||||||
|
val a = vector.toGsl().nativeHandle
|
||||||
|
val result = requireNotNull(gsl_vector_float_calloc(a.pointed.size))
|
||||||
|
gsl_blas_sgemv(CblasNoTrans, 1f, x, a, 1f, result)
|
||||||
|
return GslFloatVector(nativeHandle = result, scope = scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun Matrix<Float>.times(value: Float): GslMatrix<Float, gsl_matrix_float> {
|
||||||
|
val g1 = toGsl()
|
||||||
|
gsl_matrix_float_scale(g1.nativeHandle, value.toDouble())
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun add(a: Matrix<Float>, b: Matrix<Float>): GslMatrix<Float, gsl_matrix_float> {
|
||||||
|
val g1 = a.toGsl()
|
||||||
|
gsl_matrix_float_add(g1.nativeHandle, b.toGsl().nativeHandle)
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun multiply(a: Matrix<Float>, k: Number): GslMatrix<Float, gsl_matrix_float> {
|
||||||
|
val g1 = a.toGsl()
|
||||||
|
gsl_matrix_float_scale(g1.nativeHandle, k.toDouble())
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class GslComplexMatrixContext(scope: DeferScope) :
|
||||||
|
GslMatrixContext<Complex, gsl_matrix_complex, gsl_vector_complex>(scope) {
|
||||||
|
override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix<Complex, gsl_matrix_complex> = GslComplexMatrix(
|
||||||
|
nativeHandle = requireNotNull(gsl_matrix_complex_alloc(rows.toULong(), columns.toULong())),
|
||||||
|
scope = scope
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun produceDirtyVector(size: Int): GslVector<Complex, gsl_vector_complex> =
|
||||||
|
GslComplexVector(requireNotNull(gsl_vector_complex_alloc(size.toULong())), scope)
|
||||||
|
|
||||||
|
public override fun Matrix<Complex>.dot(other: Matrix<Complex>): GslMatrix<Complex, gsl_matrix_complex> {
|
||||||
|
val x = toGsl().nativeHandle
|
||||||
|
val a = other.toGsl().nativeHandle
|
||||||
|
val result = requireNotNull(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(nativeHandle = result, scope = scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun Matrix<Complex>.dot(vector: Point<Complex>): GslVector<Complex, gsl_vector_complex> {
|
||||||
|
val x = toGsl().nativeHandle
|
||||||
|
val a = vector.toGsl().nativeHandle
|
||||||
|
val result = requireNotNull(gsl_vector_complex_calloc(a.pointed.size))
|
||||||
|
gsl_blas_zgemv(CblasNoTrans, ComplexField.one.toGsl(), x, a, ComplexField.one.toGsl(), result)
|
||||||
|
return GslComplexVector(result, scope)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun Matrix<Complex>.times(value: Complex): GslMatrix<Complex, gsl_matrix_complex> {
|
||||||
|
val g1 = toGsl()
|
||||||
|
gsl_matrix_complex_scale(g1.nativeHandle, value.toGsl())
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun add(a: Matrix<Complex>, b: Matrix<Complex>): GslMatrix<Complex, gsl_matrix_complex> {
|
||||||
|
val g1 = a.toGsl()
|
||||||
|
gsl_matrix_complex_add(g1.nativeHandle, b.toGsl().nativeHandle)
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun multiply(a: Matrix<Complex>, k: Number): GslMatrix<Complex, gsl_matrix_complex> {
|
||||||
|
val g1 = a.toGsl()
|
||||||
|
gsl_matrix_complex_scale(g1.nativeHandle, k.toComplex().toGsl())
|
||||||
|
return g1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,170 +0,0 @@
|
|||||||
package kscience.kmath.gsl
|
|
||||||
|
|
||||||
import kotlinx.cinterop.CStructVar
|
|
||||||
import kotlinx.cinterop.DeferScope
|
|
||||||
import kotlinx.cinterop.pointed
|
|
||||||
import kscience.kmath.linear.MatrixContext
|
|
||||||
import kscience.kmath.linear.Point
|
|
||||||
import kscience.kmath.operations.Complex
|
|
||||||
import kscience.kmath.operations.ComplexField
|
|
||||||
import kscience.kmath.operations.toComplex
|
|
||||||
import kscience.kmath.structures.Matrix
|
|
||||||
import org.gnu.gsl.*
|
|
||||||
|
|
||||||
internal inline fun <T : Any, H : CStructVar> GslMatrix<T, H>.fill(initializer: (Int, Int) -> T): GslMatrix<T, H> =
|
|
||||||
apply {
|
|
||||||
(0 until rowNum).forEach { row -> (0 until colNum).forEach { col -> this[row, col] = initializer(row, col) } }
|
|
||||||
}
|
|
||||||
|
|
||||||
internal inline fun <T : Any, H : CStructVar> GslVector<T, H>.fill(initializer: (Int) -> T): GslVector<T, H> =
|
|
||||||
apply { (0 until size).forEach { index -> this[index] = initializer(index) } }
|
|
||||||
|
|
||||||
public abstract class GslMatrixContext<T : Any, H1 : CStructVar, H2 : CStructVar> internal constructor(
|
|
||||||
internal val scope: DeferScope
|
|
||||||
) : MatrixContext<T> {
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public fun Matrix<T>.toGsl(): GslMatrix<T, H1> = (if (this is GslMatrix<*, *>)
|
|
||||||
this as GslMatrix<T, H1>
|
|
||||||
else
|
|
||||||
produce(rowNum, colNum) { i, j -> this[i, j] }).copy()
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public fun Point<T>.toGsl(): GslVector<T, H2> =
|
|
||||||
(if (this is GslVector<*, *>) this as GslVector<T, H2> else produceDirtyVector(size).fill { this[it] }).copy()
|
|
||||||
|
|
||||||
internal abstract fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix<T, H1>
|
|
||||||
internal abstract fun produceDirtyVector(size: Int): GslVector<T, H2>
|
|
||||||
|
|
||||||
public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): GslMatrix<T, H1> =
|
|
||||||
produceDirtyMatrix(rows, columns).fill(initializer)
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GslRealMatrixContext(scope: DeferScope) : GslMatrixContext<Double, gsl_matrix, gsl_vector>(scope) {
|
|
||||||
override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix<Double, gsl_matrix> =
|
|
||||||
GslRealMatrix(nativeHandle = requireNotNull(gsl_matrix_alloc(rows.toULong(), columns.toULong())), scope = scope)
|
|
||||||
|
|
||||||
override fun produceDirtyVector(size: Int): GslVector<Double, gsl_vector> =
|
|
||||||
GslRealVector(nativeHandle = requireNotNull(gsl_vector_alloc(size.toULong())), scope = scope)
|
|
||||||
|
|
||||||
public override fun Matrix<Double>.dot(other: Matrix<Double>): GslMatrix<Double, gsl_matrix> {
|
|
||||||
val x = toGsl().nativeHandle
|
|
||||||
val a = other.toGsl().nativeHandle
|
|
||||||
val result = requireNotNull(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)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun Matrix<Double>.dot(vector: Point<Double>): GslVector<Double, gsl_vector> {
|
|
||||||
val x = toGsl().nativeHandle
|
|
||||||
val a = vector.toGsl().nativeHandle
|
|
||||||
val result = requireNotNull(gsl_vector_calloc(a.pointed.size))
|
|
||||||
gsl_blas_dgemv(CblasNoTrans, 1.0, x, a, 1.0, result)
|
|
||||||
return GslRealVector(result, scope = scope)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun Matrix<Double>.times(value: Double): GslMatrix<Double, gsl_matrix> {
|
|
||||||
val g1 = toGsl()
|
|
||||||
gsl_matrix_scale(g1.nativeHandle, value)
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun add(a: Matrix<Double>, b: Matrix<Double>): GslMatrix<Double, gsl_matrix> {
|
|
||||||
val g1 = a.toGsl()
|
|
||||||
gsl_matrix_add(g1.nativeHandle, b.toGsl().nativeHandle)
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun multiply(a: Matrix<Double>, k: Number): GslMatrix<Double, gsl_matrix> {
|
|
||||||
val g1 = a.toGsl()
|
|
||||||
gsl_matrix_scale(g1.nativeHandle, k.toDouble())
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GslFloatMatrixContext(scope: DeferScope) :
|
|
||||||
GslMatrixContext<Float, gsl_matrix_float, gsl_vector_float>(scope) {
|
|
||||||
override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix<Float, gsl_matrix_float> =
|
|
||||||
GslFloatMatrix(requireNotNull(gsl_matrix_float_alloc(rows.toULong(), columns.toULong())), scope = scope)
|
|
||||||
|
|
||||||
override fun produceDirtyVector(size: Int): GslVector<Float, gsl_vector_float> =
|
|
||||||
GslFloatVector(requireNotNull(gsl_vector_float_alloc(size.toULong())), scope)
|
|
||||||
|
|
||||||
public override fun Matrix<Float>.dot(other: Matrix<Float>): GslMatrix<Float, gsl_matrix_float> {
|
|
||||||
val x = toGsl().nativeHandle
|
|
||||||
val a = other.toGsl().nativeHandle
|
|
||||||
val result = requireNotNull(gsl_matrix_float_calloc(a.pointed.size1, a.pointed.size2))
|
|
||||||
gsl_blas_sgemm(CblasNoTrans, CblasNoTrans, 1f, x, a, 1f, result)
|
|
||||||
return GslFloatMatrix(nativeHandle = result, scope = scope)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun Matrix<Float>.dot(vector: Point<Float>): GslVector<Float, gsl_vector_float> {
|
|
||||||
val x = toGsl().nativeHandle
|
|
||||||
val a = vector.toGsl().nativeHandle
|
|
||||||
val result = requireNotNull(gsl_vector_float_calloc(a.pointed.size))
|
|
||||||
gsl_blas_sgemv(CblasNoTrans, 1f, x, a, 1f, result)
|
|
||||||
return GslFloatVector(nativeHandle = result, scope = scope)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun Matrix<Float>.times(value: Float): GslMatrix<Float, gsl_matrix_float> {
|
|
||||||
val g1 = toGsl()
|
|
||||||
gsl_matrix_float_scale(g1.nativeHandle, value.toDouble())
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun add(a: Matrix<Float>, b: Matrix<Float>): GslMatrix<Float, gsl_matrix_float> {
|
|
||||||
val g1 = a.toGsl()
|
|
||||||
gsl_matrix_float_add(g1.nativeHandle, b.toGsl().nativeHandle)
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun multiply(a: Matrix<Float>, k: Number): GslMatrix<Float, gsl_matrix_float> {
|
|
||||||
val g1 = a.toGsl()
|
|
||||||
gsl_matrix_float_scale(g1.nativeHandle, k.toDouble())
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GslComplexMatrixContext(scope: DeferScope) :
|
|
||||||
GslMatrixContext<Complex, gsl_matrix_complex, gsl_vector_complex>(scope) {
|
|
||||||
override fun produceDirtyMatrix(rows: Int, columns: Int): GslMatrix<Complex, gsl_matrix_complex> = GslComplexMatrix(
|
|
||||||
nativeHandle = requireNotNull(gsl_matrix_complex_alloc(rows.toULong(), columns.toULong())),
|
|
||||||
scope = scope
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun produceDirtyVector(size: Int): GslVector<Complex, gsl_vector_complex> =
|
|
||||||
GslComplexVector(requireNotNull(gsl_vector_complex_alloc(size.toULong())), scope)
|
|
||||||
|
|
||||||
public override fun Matrix<Complex>.dot(other: Matrix<Complex>): GslMatrix<Complex, gsl_matrix_complex> {
|
|
||||||
val x = toGsl().nativeHandle
|
|
||||||
val a = other.toGsl().nativeHandle
|
|
||||||
val result = requireNotNull(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(nativeHandle = result, scope = scope)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun Matrix<Complex>.dot(vector: Point<Complex>): GslVector<Complex, gsl_vector_complex> {
|
|
||||||
val x = toGsl().nativeHandle
|
|
||||||
val a = vector.toGsl().nativeHandle
|
|
||||||
val result = requireNotNull(gsl_vector_complex_calloc(a.pointed.size))
|
|
||||||
gsl_blas_zgemv(CblasNoTrans, ComplexField.one.toGsl(), x, a, ComplexField.one.toGsl(), result)
|
|
||||||
return GslComplexVector(result, scope)
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun Matrix<Complex>.times(value: Complex): GslMatrix<Complex, gsl_matrix_complex> {
|
|
||||||
val g1 = toGsl()
|
|
||||||
gsl_matrix_complex_scale(g1.nativeHandle, value.toGsl())
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun add(a: Matrix<Complex>, b: Matrix<Complex>): GslMatrix<Complex, gsl_matrix_complex> {
|
|
||||||
val g1 = a.toGsl()
|
|
||||||
gsl_matrix_complex_add(g1.nativeHandle, b.toGsl().nativeHandle)
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun multiply(a: Matrix<Complex>, k: Number): GslMatrix<Complex, gsl_matrix_complex> {
|
|
||||||
val g1 = a.toGsl()
|
|
||||||
gsl_matrix_complex_scale(g1.nativeHandle, k.toComplex().toGsl())
|
|
||||||
return g1
|
|
||||||
}
|
|
||||||
}
|
|
@ -8,6 +8,7 @@ public abstract class GslMemoryHolder<H : CStructVar> internal constructor(inter
|
|||||||
internal abstract val nativeHandle: CPointer<H>
|
internal abstract val nativeHandle: CPointer<H>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
ensureHasGslErrorHandler()
|
||||||
scope.defer(::close)
|
scope.defer(::close)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package kscience.kmath.gsl
|
package kscience.kmath.gsl
|
||||||
|
|
||||||
import kotlinx.cinterop.*
|
import kotlinx.cinterop.CPointer
|
||||||
|
import kotlinx.cinterop.DeferScope
|
||||||
|
import kotlinx.cinterop.pointed
|
||||||
import org.gnu.gsl.*
|
import org.gnu.gsl.*
|
||||||
|
|
||||||
internal class GslRealVector(override val nativeHandle: CPointer<gsl_vector>, scope: DeferScope)
|
internal class GslRealVector(override val nativeHandle: CPointer<gsl_vector>, scope: DeferScope) :
|
||||||
: GslVector<Double, gsl_vector>(scope) {
|
GslVector<Double, gsl_vector>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
@ -25,8 +27,8 @@ internal class GslRealVector(override val nativeHandle: CPointer<gsl_vector>, sc
|
|||||||
override fun close(): Unit = gsl_vector_free(nativeHandle)
|
override fun close(): Unit = gsl_vector_free(nativeHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GslFloatVector(override val nativeHandle: CPointer<gsl_vector_float>, scope: DeferScope)
|
internal class GslFloatVector(override val nativeHandle: CPointer<gsl_vector_float>, scope: DeferScope) :
|
||||||
: GslVector<Float, gsl_vector_float>(scope) {
|
GslVector<Float, gsl_vector_float>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
@ -47,8 +49,8 @@ internal class GslFloatVector(override val nativeHandle: CPointer<gsl_vector_flo
|
|||||||
override fun close(): Unit = gsl_vector_float_free(nativeHandle)
|
override fun close(): Unit = gsl_vector_float_free(nativeHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GslShortVector(override val nativeHandle: CPointer<gsl_vector_short>, scope: DeferScope)
|
internal class GslShortVector(override val nativeHandle: CPointer<gsl_vector_short>, scope: DeferScope) :
|
||||||
: GslVector<Short, gsl_vector_short>(scope) {
|
GslVector<Short, gsl_vector_short>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
@ -69,8 +71,8 @@ internal class GslShortVector(override val nativeHandle: CPointer<gsl_vector_sho
|
|||||||
override fun close(): Unit = gsl_vector_short_free(nativeHandle)
|
override fun close(): Unit = gsl_vector_short_free(nativeHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GslUShortVector(override val nativeHandle: CPointer<gsl_vector_ushort>, scope: DeferScope)
|
internal class GslUShortVector(override val nativeHandle: CPointer<gsl_vector_ushort>, scope: DeferScope) :
|
||||||
: GslVector<UShort, gsl_vector_ushort>(scope) {
|
GslVector<UShort, gsl_vector_ushort>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
@ -91,8 +93,8 @@ internal class GslUShortVector(override val nativeHandle: CPointer<gsl_vector_us
|
|||||||
override fun close(): Unit = gsl_vector_ushort_free(nativeHandle)
|
override fun close(): Unit = gsl_vector_ushort_free(nativeHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GslLongVector(override val nativeHandle: CPointer<gsl_vector_long>, scope: DeferScope)
|
internal class GslLongVector(override val nativeHandle: CPointer<gsl_vector_long>, scope: DeferScope) :
|
||||||
: GslVector<Long, gsl_vector_long>(scope) {
|
GslVector<Long, gsl_vector_long>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
@ -113,8 +115,8 @@ internal class GslLongVector(override val nativeHandle: CPointer<gsl_vector_long
|
|||||||
override fun close(): Unit = gsl_vector_long_free(nativeHandle)
|
override fun close(): Unit = gsl_vector_long_free(nativeHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GslULongVector(override val nativeHandle: CPointer<gsl_vector_ulong>, scope: DeferScope)
|
internal class GslULongVector(override val nativeHandle: CPointer<gsl_vector_ulong>, scope: DeferScope) :
|
||||||
: GslVector<ULong, gsl_vector_ulong>(scope) {
|
GslVector<ULong, gsl_vector_ulong>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
@ -135,8 +137,8 @@ internal class GslULongVector(override val nativeHandle: CPointer<gsl_vector_ulo
|
|||||||
override fun close(): Unit = gsl_vector_ulong_free(nativeHandle)
|
override fun close(): Unit = gsl_vector_ulong_free(nativeHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GslIntVector(override val nativeHandle: CPointer<gsl_vector_int>, scope: DeferScope)
|
internal class GslIntVector(override val nativeHandle: CPointer<gsl_vector_int>, scope: DeferScope) :
|
||||||
: GslVector<Int, gsl_vector_int>(scope) {
|
GslVector<Int, gsl_vector_int>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
@ -157,8 +159,8 @@ internal class GslIntVector(override val nativeHandle: CPointer<gsl_vector_int>,
|
|||||||
override fun close(): Unit = gsl_vector_int_free(nativeHandle)
|
override fun close(): Unit = gsl_vector_int_free(nativeHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class GslUIntVector(override val nativeHandle: CPointer<gsl_vector_uint>, scope: DeferScope)
|
internal class GslUIntVector(override val nativeHandle: CPointer<gsl_vector_uint>, scope: DeferScope) :
|
||||||
: GslVector<UInt, gsl_vector_uint>(scope) {
|
GslVector<UInt, gsl_vector_uint>(scope) {
|
||||||
override val size: Int
|
override val size: Int
|
||||||
get() = nativeHandle.pointed.size.toInt()
|
get() = nativeHandle.pointed.size.toInt()
|
||||||
|
|
||||||
|
23
kmath-gsl/src/nativeTest/kotlin/ErrorHandler.kt
Normal file
23
kmath-gsl/src/nativeTest/kotlin/ErrorHandler.kt
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package kscience.kmath.gsl
|
||||||
|
|
||||||
|
import kotlinx.cinterop.memScoped
|
||||||
|
import org.gnu.gsl.gsl_block_calloc
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
|
internal class ErrorHandler {
|
||||||
|
@Test
|
||||||
|
fun blockAllocation() {
|
||||||
|
assertFailsWith<GslException> {
|
||||||
|
ensureHasGslErrorHandler()
|
||||||
|
gsl_block_calloc(ULong.MAX_VALUE)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun matrixAllocation() {
|
||||||
|
assertFailsWith<GslException> {
|
||||||
|
memScoped { GslRealMatrixContext(this).produce(Int.MAX_VALUE, Int.MAX_VALUE) { _, _ -> 0.0 } }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user