diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/RealTensorAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/RealTensorAlgebra.kt index cad01c4d0..13c57fc18 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/RealTensorAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/RealTensorAlgebra.kt @@ -3,6 +3,8 @@ package space.kscience.kmath.tensors import space.kscience.kmath.nd.MutableNDBuffer import space.kscience.kmath.structures.RealBuffer import space.kscience.kmath.structures.array +import kotlin.js.JsName +import kotlin.math.abs public class RealTensor( @@ -13,46 +15,80 @@ public class RealTensor( MutableNDBuffer( TensorStrides(shape), RealBuffer(buffer) - ) { - /* - * TODO: Andrei remove item() - */ - override fun item(): Double { - check(buffer.size > 0) { "The tensor is empty" } - return buffer[0] - } -} - + ) public class RealTensorAlgebra : TensorPartialDivisionAlgebra { + //rename to item? override fun RealTensor.value(): Double { - TODO("Andrei") + check(this.dimension == 0) { + // todo change message + "This tensor has shape ${shape.toList()}" + } + return this.buffer.array[0] + } + + override fun eye(n: Int): RealTensor { + val shape = intArrayOf(n, n) + val buffer = DoubleArray(n * n) { 0.0 } + val res = RealTensor(shape, buffer) + for (i in 0 until n) { + res[intArrayOf(i, i)] = 1.0 + } + return res + } + + override fun zeros(shape: IntArray): RealTensor { + TODO("Not yet implemented") + } + + override fun zeroesLike(other: RealTensor): RealTensor { + TODO("Not yet implemented") + } + + override fun ones(shape: IntArray): RealTensor { + TODO("Not yet implemented") + } + + override fun onesLike(shape: IntArray): RealTensor { + TODO("Not yet implemented") + } + + override fun RealTensor.copy(): RealTensor { + TODO("Not yet implemented") } override fun Double.plus(other: RealTensor): RealTensor { - val n = other.buffer.size - val arr = other.buffer.array - val res = DoubleArray(n) - for (i in 1..n) - res[i - 1] = arr[i - 1] + this - return RealTensor(other.shape, res) + //todo should be change with broadcasting + val resBuffer = DoubleArray(other.buffer.size) { i -> + other.buffer.array[i] + this + } + return RealTensor(other.shape, resBuffer) } - override fun RealTensor.plus(value: Double): RealTensor { - TODO("Andrei") - } + //todo should be change with broadcasting + override fun RealTensor.plus(value: Double): RealTensor = value + this override fun RealTensor.plus(other: RealTensor): RealTensor { - TODO("Andrei") + //todo should be change with broadcasting + val resBuffer = DoubleArray(this.buffer.size) { i -> + this.buffer.array[i] + other.buffer.array[i] + } + return RealTensor(this.shape, resBuffer) } override fun RealTensor.plusAssign(value: Double) { - TODO("Andrei") + //todo should be change with broadcasting + for (i in this.buffer.array.indices) { + this.buffer.array[i] += value + } } override fun RealTensor.plusAssign(other: RealTensor) { - TODO("Andrei") + //todo should be change with broadcasting + for (i in this.buffer.array.indices) { + this.buffer.array[i] += other.buffer.array[i] + } } override fun Double.minus(other: RealTensor): RealTensor { @@ -76,27 +112,43 @@ public class RealTensorAlgebra : TensorPartialDivisionAlgebra + other.buffer.array[i] * this + } + return RealTensor(other.shape, resBuffer) } - override fun RealTensor.times(value: Double): RealTensor { - TODO("Andrei") - } + //todo should be change with broadcasting + override fun RealTensor.times(value: Double): RealTensor = value * this override fun RealTensor.times(other: RealTensor): RealTensor { - TODO("Andrei") + //todo should be change with broadcasting + val resBuffer = DoubleArray(this.buffer.size) { i -> + this.buffer.array[i] * other.buffer.array[i] + } + return RealTensor(this.shape, resBuffer) } override fun RealTensor.timesAssign(value: Double) { - TODO("Andrei") + //todo should be change with broadcasting + for (i in this.buffer.array.indices) { + this.buffer.array[i] *= value + } } override fun RealTensor.timesAssign(other: RealTensor) { - TODO("Andrei") + //todo should be change with broadcasting + for (i in this.buffer.array.indices) { + this.buffer.array[i] *= other.buffer.array[i] + } } override fun RealTensor.unaryMinus(): RealTensor { - TODO("Andrei") + val resBuffer = DoubleArray(this.buffer.size) { i -> + this.buffer.array[i].unaryMinus() + } + return RealTensor(this.shape, resBuffer) } override fun RealTensor.dot(other: RealTensor): RealTensor { @@ -124,11 +176,11 @@ public class RealTensorAlgebra : TensorPartialDivisionAlgebra { - /** - * Main first task for @AndreiKingsley - * Compare with the implementation of [LupDecomposition] - * and provide a common API - */ - TODO("Not yet implemented") + TODO() } - override fun lu_unpack(A_LU: RealTensor, pivots: RealTensor): Triple { + override fun luUnpack(A_LU: RealTensor, pivots: RealTensor): Triple { TODO("Not yet implemented") } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorAlgebra.kt index b2586e1e9..6f42623e0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorAlgebra.kt @@ -5,6 +5,14 @@ public interface TensorAlgebra> { public fun TensorType.value(): T + public fun eye(n: Int): TensorType + public fun zeros(shape: IntArray): TensorType + public fun zeroesLike(other: TensorType): TensorType + public fun ones(shape: IntArray): TensorType + public fun onesLike(shape: IntArray): TensorType + + public fun TensorType.copy(): TensorType + public operator fun T.plus(other: TensorType): TensorType public operator fun TensorType.plus(value: T): TensorType public operator fun TensorType.plus(other: TensorType): TensorType @@ -42,7 +50,7 @@ public interface TensorAlgebra> { //https://pytorch.org/docs/stable/tensor_view.html public fun TensorType.view(shape: IntArray): TensorType - public fun TensorType.view_as(other: TensorType): TensorType + public fun TensorType.viewAs(other: TensorType): TensorType //https://pytorch.org/docs/stable/generated/torch.abs.html public fun TensorType.abs(): TensorType @@ -57,7 +65,9 @@ public interface TensorAlgebra> { public interface TensorPartialDivisionAlgebra> : TensorAlgebra { + public operator fun TensorType.div(value: T): TensorType public operator fun TensorType.div(other: TensorType): TensorType + public operator fun TensorType.divAssign(value: T) public operator fun TensorType.divAssign(other: TensorType) //https://pytorch.org/docs/stable/generated/torch.exp.html @@ -72,7 +82,7 @@ public interface TensorPartialDivisionAlgebra public fun TensorType.lu(): Pair //https://pytorch.org/docs/stable/generated/torch.lu_unpack.html - public fun lu_unpack(A_LU: TensorType, pivots: TensorType): Triple + public fun luUnpack(A_LU: TensorType, pivots: TensorType): Triple //https://pytorch.org/docs/stable/generated/torch.svd.html public fun TensorType.svd(): Triple diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorStrides.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorStrides.kt index 3ea8f4bf0..dbaefe907 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorStrides.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorStrides.kt @@ -5,7 +5,7 @@ import space.kscience.kmath.nd.offsetFromIndex import kotlin.math.max -inline public fun stridesFromShape(shape: IntArray): IntArray { +public inline fun stridesFromShape(shape: IntArray): IntArray { val nDim = shape.size val res = IntArray(nDim) if (nDim == 0) @@ -22,7 +22,7 @@ inline public fun stridesFromShape(shape: IntArray): IntArray { } -inline public fun indexFromOffset(offset: Int, strides: IntArray, nDim: Int): IntArray { +public inline fun indexFromOffset(offset: Int, strides: IntArray, nDim: Int): IntArray { val res = IntArray(nDim) var current = offset var strideIndex = 0 diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorStructure.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorStructure.kt index 3775ea2e5..5463877ce 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorStructure.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/tensors/TensorStructure.kt @@ -2,26 +2,5 @@ package space.kscience.kmath.tensors import space.kscience.kmath.nd.MutableNDStructure -public interface TensorStructure : MutableNDStructure { +public typealias TensorStructure = MutableNDStructure - /* - * TODO: Andrei remove item() and value() - */ - public fun item(): T - - // A tensor can have empty shape, in which case it represents just a value - public fun value(): T { - checkIsValue() - return item() - } -} - -public inline fun TensorStructure.isValue(): Boolean { - return (dimension == 0) -} - -public inline fun TensorStructure.isNotValue(): Boolean = !this.isValue() - -public inline fun TensorStructure.checkIsValue(): Unit = check(this.isValue()) { - "This tensor has shape ${shape.toList()}" -} \ No newline at end of file