diff --git a/CHANGELOG.md b/CHANGELOG.md index a19b1f467..857ed060b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,6 @@ - Integration between `MST` and Symja `IExpr` - Complex power - Separate methods for UInt, Int and Number powers. NaN safety. -- Tensorflow prototype ### Changed - Exponential operations merged with hyperbolic functions diff --git a/README.md b/README.md index 92260716e..8604873ae 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,35 @@ module definitions below. The module stability could have the following levels: with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool. * **STABLE**. The API stabilized. Breaking changes are allowed only in major releases. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## Modules
diff --git a/docs/templates/README-TEMPLATE.md b/docs/templates/README-TEMPLATE.md index b0c418697..e75d4c5ed 100644 --- a/docs/templates/README-TEMPLATE.md +++ b/docs/templates/README-TEMPLATE.md @@ -50,6 +50,35 @@ module definitions below. The module stability could have the following levels: with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool. * **STABLE**. The API stabilized. Breaking changes are allowed only in major releases. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ## Modules $modules diff --git a/gradle.properties b/gradle.properties index 7dd9e6d61..130d294a2 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,4 +12,4 @@ org.gradle.configureondemand=true org.gradle.parallel=true org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G -toolsVersion=0.11.1-kotlin-1.6.10 +toolsVersion=0.10.9-kotlin-1.6.10 diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt index d3c414838..77fe782a9 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt @@ -41,7 +41,7 @@ public val Complex.r: Double * An angle between vector represented by complex number and X axis. */ public val Complex.theta: Double - get() = atan(im / re) + get() = atan2(im, re) private val PI_DIV_2 = Complex(PI / 2, 0) diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt index 291284444..3e5d93768 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.histogram import kotlinx.atomicfu.atomic import kotlinx.atomicfu.getAndUpdate import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.Group +import space.kscience.kmath.operations.Ring /** * Common representation for atomic counters @@ -18,7 +18,7 @@ public interface Counter { public val value: T public companion object { - public fun double(): ObjectCounter = ObjectCounter(DoubleField) + public fun real(): ObjectCounter = ObjectCounter(DoubleField) } } @@ -32,16 +32,6 @@ public class IntCounter : Counter { override val value: Int get() = innerValue.value } -public operator fun IntCounter.inc(): IntCounter { - add(1) - return this -} - -public operator fun IntCounter.dec(): IntCounter { - add(-1) - return this -} - public class LongCounter : Counter { private val innerValue = atomic(0L) @@ -52,17 +42,7 @@ public class LongCounter : Counter { override val value: Long get() = innerValue.value } -public operator fun LongCounter.inc(): LongCounter { - add(1L) - return this -} - -public operator fun LongCounter.dec(): LongCounter { - add(-1L) - return this -} - -public class ObjectCounter(private val group: Group) : Counter { +public class ObjectCounter(public val group: Ring) : Counter { private val innerValue = atomic(group.zero) override fun add(delta: T) { diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/DoubleHistogramSpace.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/DoubleHistogramSpace.kt index 61d0b9f33..28eade060 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/DoubleHistogramSpace.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/DoubleHistogramSpace.kt @@ -74,7 +74,7 @@ public class DoubleHistogramSpace( } override fun produce(builder: HistogramBuilder.() -> Unit): IndexedHistogram { - val ndCounter = StructureND.auto(shape) { Counter.double() } + val ndCounter = StructureND.auto(shape) { Counter.real() } val hBuilder = HistogramBuilder { point, value -> val index = getIndex(point) ndCounter[index].add(value.toDouble()) diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramSpace.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramSpace.kt index 9275c1c5e..0c7dd81e1 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramSpace.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/IndexedHistogramSpace.kt @@ -41,6 +41,7 @@ public class IndexedHistogram, V : Any>( get() = DefaultStrides(context.shape).asSequence().map { context.produceBin(it, values[it]) }.asIterable() + } /** diff --git a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramSpace.kt b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramSpace.kt index 0853615e6..f8a3a6a8b 100644 --- a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramSpace.kt +++ b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramSpace.kt @@ -39,7 +39,7 @@ public class TreeHistogram( @PublishedApi internal class TreeHistogramBuilder(val binFactory: (Double) -> UnivariateDomain) : UnivariateHistogramBuilder { - internal class BinCounter(val domain: UnivariateDomain, val counter: Counter = Counter.double()) : + internal class BinCounter(val domain: UnivariateDomain, val counter: Counter = Counter.real()) : ClosedFloatingPointRange by domain.range private val bins: TreeMap = TreeMap() diff --git a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt index ac0576a8e..723577cd9 100644 --- a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt +++ b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/UnivariateHistogram.kt @@ -42,7 +42,7 @@ public interface UnivariateHistogram : Histogram { /** * Build and fill a [UnivariateHistogram]. Returns a read-only histogram. */ - public inline fun uniform( + public fun uniform( binSize: Double, start: Double = 0.0, builder: UnivariateHistogramBuilder.() -> Unit, @@ -51,7 +51,7 @@ public interface UnivariateHistogram : Histogram { /** * Build and fill a histogram with custom borders. Returns a read-only histogram. */ - public inline fun custom( + public fun custom( borders: DoubleArray, builder: UnivariateHistogramBuilder.() -> Unit, ): UnivariateHistogram = TreeHistogramSpace.custom(borders).fill(builder) diff --git a/kmath-tensorflow/build.gradle.kts b/kmath-tensorflow/build.gradle.kts deleted file mode 100644 index 9380a7308..000000000 --- a/kmath-tensorflow/build.gradle.kts +++ /dev/null @@ -1,15 +0,0 @@ -plugins { - id("ru.mipt.npm.gradle.jvm") -} - -description = "Google tensorflow connector" - -dependencies { - api(project(":kmath-tensors")) - api("org.tensorflow:tensorflow-core-api:0.4.0") - testImplementation("org.tensorflow:tensorflow-core-platform:0.4.0") -} - -readme { - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE -} \ No newline at end of file diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt deleted file mode 100644 index ecfd8d098..000000000 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt +++ /dev/null @@ -1,94 +0,0 @@ -package space.kscience.kmath.tensorflow - -import org.tensorflow.Graph -import org.tensorflow.Output -import org.tensorflow.ndarray.NdArray -import org.tensorflow.op.core.Constant -import org.tensorflow.types.TFloat64 -import space.kscience.kmath.expressions.Symbol -import space.kscience.kmath.misc.PerformancePitfall -import space.kscience.kmath.nd.DefaultStrides -import space.kscience.kmath.nd.Shape -import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.PowerOperations - -public class DoubleTensorFlowOutput( - graph: Graph, - output: Output, -) : TensorFlowOutput(graph, output) { - - override fun org.tensorflow.Tensor.actualizeTensor(): NdArray = this as TFloat64 - -} - -public class DoubleTensorFlowAlgebra internal constructor( - graph: Graph, -) : TensorFlowAlgebra(graph), PowerOperations> { - - override val elementAlgebra: DoubleField get() = DoubleField - - override fun structureND( - shape: Shape, - initializer: DoubleField.(IntArray) -> Double, - ): StructureND { - val res = TFloat64.tensorOf(org.tensorflow.ndarray.Shape.of(*shape.toLongArray())) { array -> - DefaultStrides(shape).forEach { index -> - array.setDouble(elementAlgebra.initializer(index), *index.toLongArray()) - } - } - return DoubleTensorFlowOutput(graph, ops.constant(res).asOutput()) - } - - override fun StructureND.asTensorFlow(): TensorFlowOutput = - if (this is TensorFlowOutput && output.type() == TFloat64::class.java) { - @Suppress("UNCHECKED_CAST") - this as TensorFlowOutput - } else { - val res = TFloat64.tensorOf(org.tensorflow.ndarray.Shape.of(*shape.toLongArray())) { array -> - @OptIn(PerformancePitfall::class) - elements().forEach { (index, value) -> - array.setDouble(value, *index.toLongArray()) - } - } - DoubleTensorFlowOutput(graph, ops.constant(res).asOutput()) - } - - override fun Output.wrap(): TensorFlowOutput = DoubleTensorFlowOutput(graph, this) - - override fun const(value: Double): Constant = ops.constant(value) - - override fun divide( - left: StructureND, - right: StructureND, - ): TensorFlowOutput = left.operate(right) { l, r -> - ops.math.div(l, r) - } - - override fun power(arg: StructureND, pow: Number): TensorFlowOutput = - arg.operate { ops.math.pow(it, const(pow.toDouble())) } -} - -/** - * Compute a tensor with TensorFlow in a single run. - * - * The resulting tensor is available outside of scope - */ -public fun DoubleField.produceWithTF( - block: DoubleTensorFlowAlgebra.() -> StructureND, -): StructureND = Graph().use { graph -> - val scope = DoubleTensorFlowAlgebra(graph) - scope.export(scope.block()) -} - -/** - * Compute several outputs with TensorFlow in a single run. - * - * The resulting tensors are available outside of scope - */ -public fun DoubleField.produceMapWithTF( - block: DoubleTensorFlowAlgebra.() -> Map>, -): Map> = Graph().use { graph -> - val scope = DoubleTensorFlowAlgebra(graph) - scope.block().mapValues { scope.export(it.value) } -} \ No newline at end of file diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt deleted file mode 100644 index 084a445e0..000000000 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt +++ /dev/null @@ -1,21 +0,0 @@ -package space.kscience.kmath.tensorflow - -import org.tensorflow.Graph -import org.tensorflow.Output -import org.tensorflow.ndarray.NdArray -import org.tensorflow.types.TInt32 -import org.tensorflow.types.TInt64 - -public class IntTensorFlowOutput( - graph: Graph, - output: Output, -) : TensorFlowOutput(graph, output) { - override fun org.tensorflow.Tensor.actualizeTensor(): NdArray = this as TInt32 -} - -public class LongTensorFlowOutput( - graph: Graph, - output: Output, -) : TensorFlowOutput(graph, output) { - override fun org.tensorflow.Tensor.actualizeTensor(): NdArray = this as TInt64 -} \ No newline at end of file diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt deleted file mode 100644 index e2541a73e..000000000 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt +++ /dev/null @@ -1,249 +0,0 @@ -package space.kscience.kmath.tensorflow - - -import org.tensorflow.Graph -import org.tensorflow.Operand -import org.tensorflow.Output -import org.tensorflow.Session -import org.tensorflow.ndarray.NdArray -import org.tensorflow.op.Ops -import org.tensorflow.op.core.Constant -import org.tensorflow.op.core.Max -import org.tensorflow.op.core.Min -import org.tensorflow.op.core.Sum -import org.tensorflow.types.TInt32 -import org.tensorflow.types.family.TNumber -import org.tensorflow.types.family.TType -import space.kscience.kmath.misc.PerformancePitfall -import space.kscience.kmath.misc.UnstableKMathAPI -import space.kscience.kmath.nd.Shape -import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.operations.Ring -import space.kscience.kmath.tensors.api.Tensor -import space.kscience.kmath.tensors.api.TensorAlgebra - -internal fun IntArray.toLongArray() = LongArray(size) { get(it).toLong() } -internal fun LongArray.toIntArray() = IntArray(size) { get(it).toInt() } - -internal val NdArray.scalar: T get() = getObject() - - -public sealed interface TensorFlowTensor : Tensor - -/** - * Static (eager) in-memory TensorFlow tensor - */ -@JvmInline -public value class TensorFlowArray(public val tensor: NdArray) : Tensor { - override val shape: Shape get() = tensor.shape().asArray().toIntArray() - - override fun get(index: IntArray): T = tensor.getObject(*index.toLongArray()) - - //TODO implement native element sequence - - override fun set(index: IntArray, value: T) { - tensor.setObject(value, *index.toLongArray()) - } -} - -/** - * Lazy graph-based TensorFlow tensor. The tensor is actualized on call. - * - * If the tensor is used for intermediate operations, actualizing it could impact performance. - */ -public abstract class TensorFlowOutput( - protected val graph: Graph, - output: Output, -) : TensorFlowTensor { - - public var output: Output = output - internal set - - override val shape: Shape get() = output.shape().asArray().toIntArray() - - protected abstract fun org.tensorflow.Tensor.actualizeTensor(): NdArray - - internal val actualTensor by lazy { - Session(graph).use { session -> - TensorFlowArray(session.runner().fetch(output).run().first().actualizeTensor()) - } - } - - override fun get(index: IntArray): T = actualTensor[index] - - @PerformancePitfall - override fun elements(): Sequence> = actualTensor.elements() - - override fun set(index: IntArray, value: T) { - actualTensor[index] = value - } - -} - - -public abstract class TensorFlowAlgebra> internal constructor( - protected val graph: Graph, -) : TensorAlgebra { - - public val ops: Ops by lazy { Ops.create(graph) } - - protected abstract fun StructureND.asTensorFlow(): TensorFlowOutput - - protected abstract fun Output.wrap(): TensorFlowOutput - - protected abstract fun const(value: T): Constant - - override fun StructureND.valueOrNull(): T? = if (shape contentEquals intArrayOf(1)) - get(Shape(0)) else null - - /** - * Perform binary lazy operation on tensor. Both arguments are implicitly converted - */ - public fun StructureND.operate( - other: StructureND, - operation: (left: Operand, right: Operand) -> Operand, - ): TensorFlowOutput { - val left = asTensorFlow().output - val right = other.asTensorFlow().output - return operation(left, right).asOutput().wrap() - } - - public fun T.operate( - other: StructureND, - operation: (left: Operand, right: Operand) -> Operand, - ): TensorFlowOutput { - val left = const(this) - val right = other.asTensorFlow().output - return operation(left, right).asOutput().wrap() - } - - public fun StructureND.operate( - value: T, - operation: (left: Operand, right: Operand) -> Operand, - ): TensorFlowOutput { - val left = asTensorFlow().output - val right = const(value) - return operation(left, right).asOutput().wrap() - } - - public fun Tensor.operateInPlace( - other: StructureND, - operation: (left: Operand, right: Operand) -> Operand, - ): Unit { - val origin = asTensorFlow() - val left = origin.output - val right = other.asTensorFlow().output - origin.output = operation(left, right).asOutput() - } - - public fun Tensor.operateInPlace( - value: T, - operation: (left: Operand, right: Operand) -> Operand, - ): Unit { - val origin = asTensorFlow() - val left = origin.output - val right = const(value) - origin.output = operation(left, right).asOutput() - } - - public fun StructureND.operate(operation: (Operand) -> Operand): TensorFlowOutput = - operation(asTensorFlow().output).asOutput().wrap() - - override fun T.plus(arg: StructureND): TensorFlowOutput = operate(arg, ops.math::add) - - override fun StructureND.plus(arg: T): TensorFlowOutput = operate(arg, ops.math::add) - - override fun StructureND.plus(arg: StructureND): TensorFlowOutput = operate(arg, ops.math::add) - - override fun Tensor.plusAssign(value: T): Unit = operateInPlace(value, ops.math::add) - - override fun Tensor.plusAssign(arg: StructureND): Unit = operateInPlace(arg, ops.math::add) - - override fun StructureND.minus(arg: T): TensorFlowOutput = operate(arg, ops.math::sub) - - override fun StructureND.minus(arg: StructureND): TensorFlowOutput = operate(arg, ops.math::sub) - - override fun T.minus(arg: StructureND): Tensor = operate(arg, ops.math::sub) - - override fun Tensor.minusAssign(value: T): Unit = operateInPlace(value, ops.math::sub) - - override fun Tensor.minusAssign(arg: StructureND): Unit = operateInPlace(arg, ops.math::sub) - - override fun T.times(arg: StructureND): TensorFlowOutput = operate(arg, ops.math::mul) - - override fun StructureND.times(arg: T): TensorFlowOutput = operate(arg, ops.math::mul) - - override fun StructureND.times(arg: StructureND): TensorFlowOutput = operate(arg, ops.math::mul) - - override fun Tensor.timesAssign(value: T): Unit = operateInPlace(value, ops.math::mul) - - override fun Tensor.timesAssign(arg: StructureND): Unit = operateInPlace(arg, ops.math::mul) - - override fun StructureND.unaryMinus(): TensorFlowOutput = operate(ops.math::neg) - - override fun Tensor.get(i: Int): Tensor = operate { - TODO("Not yet implemented") - } - - override fun Tensor.transpose(i: Int, j: Int): Tensor = operate { - ops.linalg.transpose(it, ops.constant(intArrayOf(i, j))) - } - - override fun Tensor.view(shape: IntArray): Tensor = operate { - ops.reshape(it, ops.constant(shape)) - } - - override fun Tensor.viewAs(other: StructureND): Tensor = operate(other) { l, r -> - ops.reshape(l, ops.shape(r)) - } - - override fun StructureND.dot(other: StructureND): TensorFlowOutput = operate(other) { l, r -> - ops.linalg.matMul( - if (l.asTensor().shape().numDimensions() == 1) ops.expandDims(l, ops.constant(0)) else l, - if (r.asTensor().shape().numDimensions() == 1) ops.expandDims(r, ops.constant(-1)) else r) - } - - override fun diagonalEmbedding( - diagonalEntries: Tensor, - offset: Int, - dim1: Int, - dim2: Int, - ): TensorFlowOutput = diagonalEntries.operate { - TODO("Not yet implemented") - } - - override fun StructureND.sum(): T = operate { - ops.sum(it, ops.constant(intArrayOf())) - }.value() - - override fun StructureND.sum(dim: Int, keepDim: Boolean): TensorFlowOutput = operate { - ops.sum(it, ops.constant(dim), Sum.keepDims(keepDim)) - } - - override fun StructureND.min(): T = operate { - ops.min(it, ops.constant(intArrayOf())) - }.value() - - override fun StructureND.min(dim: Int, keepDim: Boolean): Tensor = operate { - ops.min(it, ops.constant(dim), Min.keepDims(keepDim)) - } - - override fun StructureND.max(): T = operate { - ops.max(it, ops.constant(intArrayOf())) - }.value() - - override fun StructureND.max(dim: Int, keepDim: Boolean): Tensor = operate { - ops.max(it, ops.constant(dim), Max.keepDims(keepDim)) - } - - override fun StructureND.argMax(dim: Int, keepDim: Boolean): Tensor = IntTensorFlowOutput( - graph, - ops.math.argMax(asTensorFlow().output, ops.constant(dim), TInt32::class.java).output() - ).actualTensor - - @OptIn(UnstableKMathAPI::class) - override fun export(arg: StructureND): StructureND = - if (arg is TensorFlowOutput) arg.actualTensor else arg -} - -//TODO add TensorFlow expressions \ No newline at end of file diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/tfOperations.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/tfOperations.kt deleted file mode 100644 index 257d4d6ea..000000000 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/tfOperations.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2018-2021 KMath contributors. - * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. - */ - -package space.kscience.kmath.tensorflow - -import org.tensorflow.types.family.TNumber -import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.operations.Ring -import space.kscience.kmath.operations.TrigonometricOperations - -// - -// TODO add other operations - -public fun TensorFlowAlgebra.sin( - arg: StructureND, -): TensorFlowOutput where A : TrigonometricOperations, A : Ring = arg.operate { ops.math.sin(it) } - -public fun TensorFlowAlgebra.cos( - arg: StructureND, -): TensorFlowOutput where A : TrigonometricOperations, A : Ring = arg.operate { ops.math.cos(it) } diff --git a/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt b/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt deleted file mode 100644 index 805ad7c66..000000000 --- a/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt +++ /dev/null @@ -1,33 +0,0 @@ -package space.kscience.kmath.tensorflow - -import org.junit.jupiter.api.Test -import space.kscience.kmath.nd.get -import space.kscience.kmath.nd.structureND -import space.kscience.kmath.operations.DoubleField -import kotlin.test.assertEquals - -class DoubleTensorFlowOps { - @Test - fun basicOps() { - val res = DoubleField.produceWithTF { - val initial = structureND(2, 2) { 1.0 } - - initial + (initial * 2.0) - } - //println(StructureND.toString(res)) - assertEquals(3.0, res[0, 0]) - } - - @Test - fun extensionOps(){ - val res = DoubleField.produceWithTF { - val i = structureND(2, 2) { 0.5 } - - sin(i).pow(2) + cos(i).pow(2) - } - - assertEquals(1.0, res[0,0],0.01) - } - - -} \ No newline at end of file diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt index 86d4eaa4e..33889c2f8 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt @@ -208,7 +208,7 @@ public interface TensorAlgebra> : RingOpsND { * * 3. If the first argument is 1-dimensional and the second argument is 2-dimensional, * a 1 is prepended to its dimension for the purpose of the matrix multiply. - * After the matrix multiply, depending on the implementation the prepended dimension might be removed. + * After the matrix multiply, the prepended dimension is removed. * * 4. If the first argument is 2-dimensional and the second argument is 1-dimensional, * the matrix-vector product is returned. diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 50252ad31..dc3ec43e9 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -424,13 +424,13 @@ public open class DoubleTensorAlgebra : dotTo(a.as2D(), b.as2D(), res.as2D(), l, m1, n) } - return if (penultimateDim) { - resTensor.view(resTensor.shape.dropLast(2).toIntArray() + intArrayOf(resTensor.shape.last())) - } else if (lastDim) { - resTensor.view(resTensor.shape.dropLast(1).toIntArray()) - } else { - resTensor + if (penultimateDim) { + return resTensor.view(resTensor.shape.dropLast(2).toIntArray() + intArrayOf(resTensor.shape.last())) } + if (lastDim) { + return resTensor.view(resTensor.shape.dropLast(1).toIntArray()) + } + return resTensor } override fun diagonalEmbedding( diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt index 1d4d6cebd..dc0f1f97c 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt @@ -3,8 +3,6 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -@file:OptIn(PerformancePitfall::class) - package space.kscience.kmath.viktor import org.jetbrains.bio.viktor.F64Array diff --git a/settings.gradle.kts b/settings.gradle.kts index 3001d000c..7108b0cb4 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -29,7 +29,6 @@ include( ":kmath-commons", ":kmath-viktor", ":kmath-multik", - ":kmath-tensorflow", ":kmath-optimization", ":kmath-stat", ":kmath-nd4j",