diff --git a/kmath-core/api/kmath-core.api b/kmath-core/api/kmath-core.api index a45f00a55..fc0905bd0 100644 --- a/kmath-core/api/kmath-core.api +++ b/kmath-core/api/kmath-core.api @@ -2745,6 +2745,34 @@ public class space/kscience/kmath/tensors/core/BufferedTensor : space/kscience/k public final fun vectorSequence ()Lkotlin/sequences/Sequence; } +public final class space/kscience/kmath/tensors/core/BufferedTensor1D : space/kscience/kmath/tensors/core/BufferedTensor, space/kscience/kmath/nd/MutableStructure1D { + public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public fun get (I)Ljava/lang/Object; + public fun get ([I)Ljava/lang/Object; + public fun getDimension ()I + public fun getSize ()I + public fun iterator ()Ljava/util/Iterator; + public fun set (ILjava/lang/Object;)V + public fun set ([ILjava/lang/Object;)V +} + +public final class space/kscience/kmath/tensors/core/BufferedTensor2D : space/kscience/kmath/tensors/core/BufferedTensor, space/kscience/kmath/nd/MutableStructure2D { + public fun elements ()Lkotlin/sequences/Sequence; + public fun get (II)Ljava/lang/Object; + public fun get ([I)Ljava/lang/Object; + public fun getColNum ()I + public fun getColumns ()Ljava/util/List; + public fun getRowNum ()I + public fun getRows ()Ljava/util/List; + public fun getShape ()[I + public fun set (IILjava/lang/Object;)V +} + +public final class space/kscience/kmath/tensors/core/BufferedTensorKt { + public static final fun as1D (Lspace/kscience/kmath/tensors/core/BufferedTensor;)Lspace/kscience/kmath/tensors/core/BufferedTensor1D; + public static final fun as2D (Lspace/kscience/kmath/tensors/core/BufferedTensor;)Lspace/kscience/kmath/tensors/core/BufferedTensor2D; +} + public final class space/kscience/kmath/tensors/core/DoubleAnalyticTensorAlgebra : space/kscience/kmath/tensors/core/DoubleTensorAlgebra, space/kscience/kmath/tensors/AnalyticTensorAlgebra { public fun ()V public synthetic fun acos (Lspace/kscience/kmath/nd/MutableStructureND;)Lspace/kscience/kmath/nd/MutableStructureND; diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt index 160c61260..aa6e58ef6 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt @@ -1,23 +1,26 @@ package space.kscience.kmath.tensors.core -import space.kscience.kmath.nd.* +import space.kscience.kmath.nd.MutableStructure1D +import space.kscience.kmath.nd.MutableStructure2D import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.TensorStructure -import kotlin.math.atanh + public open class BufferedTensor( override val shape: IntArray, public val buffer: MutableBuffer, internal val bufferStart: Int -) : TensorStructure -{ +) : TensorStructure { public val linearStructure: TensorLinearStructure get() = TensorLinearStructure(shape) public val numel: Int get() = linearStructure.size + internal constructor(tensor: BufferedTensor) : + this(tensor.shape, tensor.buffer, tensor.bufferStart) + override fun get(index: IntArray): T = buffer[bufferStart + linearStructure.offset(index)] override fun set(index: IntArray, value: T) { @@ -32,8 +35,8 @@ public open class BufferedTensor( override fun hashCode(): Int = 0 - public fun vectorSequence(): Sequence> = sequence { - check(shape.size >= 1) {"todo"} + public fun vectorSequence(): Sequence> = sequence { + check(shape.size >= 1) { "todo" } val n = shape.size val vectorOffset = shape[n - 1] val vectorShape = intArrayOf(shape.last()) @@ -43,8 +46,8 @@ public open class BufferedTensor( } } - public fun matrixSequence(): Sequence> = sequence { - check(shape.size >= 2) {"todo"} + public fun matrixSequence(): Sequence> = sequence { + check(shape.size >= 2) { "todo" } val n = shape.size val matrixOffset = shape[n - 1] * shape[n - 2] val matrixShape = intArrayOf(shape[n - 2], shape[n - 1]) //todo better way? @@ -54,14 +57,14 @@ public open class BufferedTensor( } } - public inline fun forEachVector(vectorAction : (MutableStructure1D) -> Unit): Unit { - for (vector in vectorSequence()){ + public inline fun forEachVector(vectorAction: (BufferedTensor1D) -> Unit): Unit { + for (vector in vectorSequence()) { vectorAction(vector) } } - public inline fun forEachMatrix(matrixAction : (MutableStructure2D) -> Unit): Unit { - for (matrix in matrixSequence()){ + public inline fun forEachMatrix(matrixAction: (BufferedTensor2D) -> Unit): Unit { + for (matrix in matrixSequence()) { matrixAction(matrix) } } @@ -74,21 +77,125 @@ public class IntTensor internal constructor( buffer: IntArray, offset: Int = 0 ) : BufferedTensor(shape, IntBuffer(buffer), offset) +{ + internal constructor(bufferedTensor: BufferedTensor): + this(bufferedTensor.shape, bufferedTensor.buffer.array(), bufferedTensor.bufferStart) +} public class LongTensor internal constructor( shape: IntArray, buffer: LongArray, offset: Int = 0 ) : BufferedTensor(shape, LongBuffer(buffer), offset) +{ + internal constructor(bufferedTensor: BufferedTensor): + this(bufferedTensor.shape, bufferedTensor.buffer.array(), bufferedTensor.bufferStart) +} public class FloatTensor internal constructor( shape: IntArray, buffer: FloatArray, offset: Int = 0 ) : BufferedTensor(shape, FloatBuffer(buffer), offset) +{ + internal constructor(bufferedTensor: BufferedTensor): + this(bufferedTensor.shape, bufferedTensor.buffer.array(), bufferedTensor.bufferStart) +} public class DoubleTensor internal constructor( shape: IntArray, buffer: DoubleArray, offset: Int = 0 -) : BufferedTensor(shape, DoubleBuffer(buffer), offset) \ No newline at end of file +) : BufferedTensor(shape, DoubleBuffer(buffer), offset) +{ + internal constructor(bufferedTensor: BufferedTensor): + this(bufferedTensor.shape, bufferedTensor.buffer.array(), bufferedTensor.bufferStart) +} + + +public class BufferedTensor2D internal constructor( + private val tensor: BufferedTensor, +) : BufferedTensor(tensor), MutableStructure2D { + init { + check(shape.size == 2) { + "Shape ${shape.toList()} not compatible with DoubleTensor2D" + } + } + + override val shape: IntArray + get() = tensor.shape + + override val rowNum: Int + get() = shape[0] + override val colNum: Int + get() = shape[1] + + override fun get(i: Int, j: Int): T = tensor[intArrayOf(i, j)] + + override fun get(index: IntArray): T = tensor[index] + + override fun elements(): Sequence> = tensor.elements() + + override fun set(i: Int, j: Int, value: T) { + tensor[intArrayOf(i, j)] = value + } + + override val rows: List> + get() = List(rowNum) { i -> + BufferedTensor1D( + BufferedTensor( + shape = intArrayOf(colNum), + buffer = VirtualMutableBuffer(colNum) { j -> get(i, j) }, + bufferStart = 0 + ) + ) + } + + override val columns: List> + get() = List(colNum) { j -> + BufferedTensor1D( + BufferedTensor( + shape = intArrayOf(rowNum), + buffer = VirtualMutableBuffer(rowNum) { i -> get(i, j) }, + bufferStart = 0 + ) + ) + } +} + +public class BufferedTensor1D internal constructor( + private val tensor: BufferedTensor +) : BufferedTensor(tensor), MutableStructure1D { + init { + check(shape.size == 1) { + "Shape ${shape.toList()} not compatible with DoubleTensor1D" + } + } + + override fun get(index: IntArray): T = tensor[index] + + override fun set(index: IntArray, value: T) { + tensor[index] = value + } + + override val size: Int + get() = tensor.linearStructure.size + + override fun get(index: Int): T = tensor[intArrayOf(index)] + + override fun set(index: Int, value: T) { + tensor[intArrayOf(index)] = value + } + + override fun copy(): MutableBuffer = tensor.buffer.copy() + +} + +internal fun BufferedTensor.asIntTensor(): IntTensor = IntTensor(this) +internal fun BufferedTensor.asLongTensor(): LongTensor = LongTensor(this) +internal fun BufferedTensor.asFloatTensor(): FloatTensor = FloatTensor(this) +internal fun BufferedTensor.asDoubleTensor(): DoubleTensor = DoubleTensor(this) + + +public fun BufferedTensor.as2D(): BufferedTensor2D = BufferedTensor2D(this) +public fun BufferedTensor.as1D(): BufferedTensor1D = BufferedTensor1D(this) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleLinearOpsTensorAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleLinearOpsTensorAlgebra.kt index d49fc941a..0916f0da8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleLinearOpsTensorAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleLinearOpsTensorAlgebra.kt @@ -1,10 +1,5 @@ package space.kscience.kmath.tensors.core -import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.nd.MutableStructure2D -import space.kscience.kmath.nd.Structure1D -import space.kscience.kmath.nd.Structure2D -import space.kscience.kmath.nd.asND import space.kscience.kmath.tensors.LinearOpsTensorAlgebra import kotlin.math.sqrt @@ -163,8 +158,7 @@ public class DoubleLinearOpsTensorAlgebra : TODO("ANDREI") } - private fun luMatrixDet(lu: Structure2D, pivots: Structure1D): Double { - // todo check + private fun luMatrixDet(lu: BufferedTensor2D, pivots: BufferedTensor1D): Double { val m = lu.shape[0] val sign = if((pivots[m] - m) % 2 == 0) 1.0 else -1.0 return (0 until m).asSequence().map { lu[it, it] }.fold(sign) { left, right -> left * right } @@ -191,9 +185,9 @@ public class DoubleLinearOpsTensorAlgebra : } private fun luMatrixInv( - lu: Structure2D, - pivots: Structure1D, - invMatrix : MutableStructure2D + lu: BufferedTensor2D, + pivots: BufferedTensor1D, + invMatrix : BufferedTensor2D ): Unit { //todo check val m = lu.shape[0] diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt index d77f33f9d..3a129b03c 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt @@ -1,7 +1,6 @@ package space.kscience.kmath.tensors.core import kotlin.math.abs -import kotlin.math.exp import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt index b12b08b52..40597f539 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt @@ -1,8 +1,5 @@ package space.kscience.kmath.tensors.core - -import space.kscience.kmath.nd.as1D -import space.kscience.kmath.nd.as2D import space.kscience.kmath.structures.toDoubleArray import kotlin.test.Test import kotlin.test.assertEquals