diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/BufferedTensor.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/BufferedTensor.kt index 68fc0412e..264692d0c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/BufferedTensor.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/BufferedTensor.kt @@ -1,32 +1,34 @@ package space.kscience.kmath.tensors -import space.kscience.kmath.nd.MutableNDBuffer import space.kscience.kmath.structures.* public open class BufferedTensor( override val shape: IntArray, - buffer: MutableBuffer -) : - TensorStructure, - MutableNDBuffer( - TensorStrides(shape), - buffer - ) { + public val buffer: MutableBuffer, + internal val bufferStart: Int +) : TensorStructure +{ + public val strides: TensorStrides + get() = TensorStrides(shape) + override fun get(index: IntArray): T = buffer[bufferStart + strides.offset(index)] - public operator fun get(i: Int, j: Int): T { - check(this.dimension == 2) { "Not matrix" } - return this[intArrayOf(i, j)] + override fun set(index: IntArray, value: T) { + buffer[bufferStart + strides.offset(index)] = value } - public operator fun set(i: Int, j: Int, value: T): Unit { - check(this.dimension == 2) { "Not matrix" } - this[intArrayOf(i, j)] = value + override fun elements(): Sequence> = strides.indices().map { + it to this[it] } + override fun equals(other: Any?): Boolean = false + + override fun hashCode(): Int = 0 + } +/* //todo make generator mb nextMatrixIndex? public class InnerMatrix(private val tensor: BufferedTensor){ private var offset: Int = 0 @@ -75,25 +77,29 @@ public class InnerVector(private val tensor: BufferedTensor){ offset += step } } - - //todo default buffer = arrayOf(0)??? + */ + public class IntTensor( shape: IntArray, - buffer: IntArray -) : BufferedTensor(shape, IntBuffer(buffer)) + buffer: IntArray, + offset: Int = 0 +) : BufferedTensor(shape, IntBuffer(buffer), offset) public class LongTensor( shape: IntArray, - buffer: LongArray -) : BufferedTensor(shape, LongBuffer(buffer)) + buffer: LongArray, + offset: Int = 0 +) : BufferedTensor(shape, LongBuffer(buffer), offset) public class FloatTensor( shape: IntArray, - buffer: FloatArray -) : BufferedTensor(shape, FloatBuffer(buffer)) + buffer: FloatArray, + offset: Int = 0 +) : BufferedTensor(shape, FloatBuffer(buffer), offset) public class DoubleTensor( shape: IntArray, - buffer: DoubleArray -) : BufferedTensor(shape, RealBuffer(buffer)) \ No newline at end of file + buffer: DoubleArray, + offset: Int = 0 +) : BufferedTensor(shape, RealBuffer(buffer), offset) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/DoubleLinearOpsTensorAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/DoubleLinearOpsTensorAlgebra.kt index 1aaf8df9d..eceb28459 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/DoubleLinearOpsTensorAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/DoubleLinearOpsTensorAlgebra.kt @@ -9,6 +9,7 @@ public class DoubleLinearOpsTensorAlgebra : } override fun DoubleTensor.lu(): Pair { + /* // todo checks val luTensor = this.copy() val lu = InnerMatrix(luTensor) @@ -69,11 +70,13 @@ public class DoubleLinearOpsTensorAlgebra : pivot.makeStep() } - return Pair(luTensor, pivotsTensor) + return Pair(luTensor, pivotsTensor)*/ + + TODO("Andrei, first we need to view and get(Int)") } override fun luPivot(lu: DoubleTensor, pivots: IntTensor): Triple { - + /* // todo checks val n = lu.shape[0] val p = lu.zeroesLike() @@ -97,7 +100,8 @@ public class DoubleLinearOpsTensorAlgebra : } } - return Triple(p, l, u) + return Triple(p, l, u)*/ + TODO("Andrei, first we need implement get(Int)") } override fun DoubleTensor.cholesky(): DoubleTensor { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/DoubleTensorAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/DoubleTensorAlgebra.kt index 76a3c4c9c..391c2895f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/DoubleTensorAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/DoubleTensorAlgebra.kt @@ -7,11 +7,11 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra - other.buffer.unsafeToDoubleArray()[i] + this + val resBuffer = DoubleArray(other.strides.linearSize) { i -> + other.buffer.unsafeToDoubleArray()[other.bufferStart + i] + this } return DoubleTensor(other.shape, resBuffer) } @@ -60,35 +60,36 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra + val resBuffer = DoubleArray(newThis.strides.linearSize) { i -> newThis.buffer.unsafeToDoubleArray()[i] + newOther.buffer.unsafeToDoubleArray()[i] } return DoubleTensor(newThis.shape, resBuffer) } override fun DoubleTensor.plusAssign(value: Double) { - for (i in this.buffer.unsafeToDoubleArray().indices) { - this.buffer.unsafeToDoubleArray()[i] += value + for (i in 0 until this.strides.linearSize) { + this.buffer.unsafeToDoubleArray()[this.bufferStart + i] += value } } override fun DoubleTensor.plusAssign(other: DoubleTensor) { //todo should be change with broadcasting - for (i in this.buffer.unsafeToDoubleArray().indices) { - this.buffer.unsafeToDoubleArray()[i] += other.buffer.unsafeToDoubleArray()[i] + for (i in 0 until this.strides.linearSize) { + this.buffer.unsafeToDoubleArray()[this.bufferStart + i] += + other.buffer.unsafeToDoubleArray()[this.bufferStart + i] } } override fun Double.minus(other: DoubleTensor): DoubleTensor { - val resBuffer = DoubleArray(other.buffer.size) { i -> - this - other.buffer.unsafeToDoubleArray()[i] + val resBuffer = DoubleArray(other.strides.linearSize) { i -> + this - other.buffer.unsafeToDoubleArray()[other.bufferStart + i] } return DoubleTensor(other.shape, resBuffer) } override fun DoubleTensor.minus(value: Double): DoubleTensor { - val resBuffer = DoubleArray(this.buffer.size) { i -> - this.buffer.unsafeToDoubleArray()[i] - value + val resBuffer = DoubleArray(this.strides.linearSize) { i -> + this.buffer.unsafeToDoubleArray()[this.bufferStart + i] - value } return DoubleTensor(this.shape, resBuffer) } @@ -97,15 +98,15 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra + val resBuffer = DoubleArray(newThis.strides.linearSize) { i -> newThis.buffer.unsafeToDoubleArray()[i] - newOther.buffer.unsafeToDoubleArray()[i] } return DoubleTensor(newThis.shape, resBuffer) } override fun DoubleTensor.minusAssign(value: Double) { - for (i in this.buffer.unsafeToDoubleArray().indices) { - this.buffer.unsafeToDoubleArray()[i] -= value + for (i in 0 until this.strides.linearSize) { + this.buffer.unsafeToDoubleArray()[this.bufferStart + i] -= value } } @@ -115,8 +116,8 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra - other.buffer.unsafeToDoubleArray()[i] * this + val resBuffer = DoubleArray(other.strides.linearSize) { i -> + other.buffer.unsafeToDoubleArray()[other.bufferStart + i] * this } return DoubleTensor(other.shape, resBuffer) } @@ -126,36 +127,38 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra - this.buffer.unsafeToDoubleArray()[i] * other.buffer.unsafeToDoubleArray()[i] + val resBuffer = DoubleArray(this.strides.linearSize) { i -> + this.buffer.unsafeToDoubleArray()[other.bufferStart + i] * + other.buffer.unsafeToDoubleArray()[other.bufferStart + i] } return DoubleTensor(this.shape, resBuffer) } override fun DoubleTensor.timesAssign(value: Double) { //todo should be change with broadcasting - for (i in this.buffer.unsafeToDoubleArray().indices) { - this.buffer.unsafeToDoubleArray()[i] *= value + for (i in 0 until this.strides.linearSize) { + this.buffer.unsafeToDoubleArray()[this.bufferStart + i] *= value } } override fun DoubleTensor.timesAssign(other: DoubleTensor) { //todo should be change with broadcasting - for (i in this.buffer.unsafeToDoubleArray().indices) { - this.buffer.unsafeToDoubleArray()[i] *= other.buffer.unsafeToDoubleArray()[i] + for (i in 0 until this.strides.linearSize) { + this.buffer.unsafeToDoubleArray()[this.bufferStart + i] *= + other.buffer.unsafeToDoubleArray()[this.bufferStart + i] } } override fun DoubleTensor.unaryMinus(): DoubleTensor { - val resBuffer = DoubleArray(this.buffer.size) { i -> - this.buffer.unsafeToDoubleArray()[i].unaryMinus() + val resBuffer = DoubleArray(this.strides.linearSize) { i -> + this.buffer.unsafeToDoubleArray()[this.bufferStart + i].unaryMinus() } return DoubleTensor(this.shape, resBuffer) } override fun DoubleTensor.transpose(i: Int, j: Int): DoubleTensor { checkTranspose(this.dimension, i, j) - val n = this.buffer.size + val n = this.strides.linearSize val resBuffer = DoubleArray(n) val resShape = this.shape.copyOf() @@ -169,14 +172,16 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra