diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/algebras/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/algebras/DoubleTensorAlgebra.kt index 74ef63ab7..8c76de0de 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/algebras/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/algebras/DoubleTensorAlgebra.kt @@ -23,6 +23,9 @@ import space.kscience.kmath.tensors.core.getRandomNormals import space.kscience.kmath.tensors.core.minusIndexFrom import kotlin.math.abs +/** + * Implementation of basic operations over double tensors and basic algebra operations on them. + */ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra { public companion object : DoubleTensorAlgebra() @@ -34,6 +37,13 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra { return tensor.mutableBuffer.array()[tensor.bufferStart] } + /** + * Constructs a tensor with the specified shape and data. + * + * @param shape the desired shape for the tensor. + * @param buffer one-dimensional data array. + * @return tensor with the [shape] shape and [buffer] data. + */ public fun fromArray(shape: IntArray, buffer: DoubleArray): DoubleTensor { checkEmptyShape(shape) checkEmptyDoubleBuffer(buffer) @@ -48,26 +58,67 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra { return DoubleTensor(newShape, tensor.mutableBuffer.array(), newStart) } + /** + * Creates a tensor of a given shape and fills all elements with a given value. + * + * @param value the value to fill the output tensor with. + * @param shape array of integers defining the shape of the output tensor. + * @return tensor with the [shape] shape and filled with [value]. + */ public fun full(value: Double, shape: IntArray): DoubleTensor { checkEmptyShape(shape) val buffer = DoubleArray(shape.reduce(Int::times)) { value } return DoubleTensor(shape, buffer) } + /** + * Returns a tensor with the same shape as `input` filled with [value]. + * + * @param value the value to fill the output tensor with. + * @return tensor with the `input` tensor shape and filled with [value]. + */ public fun Tensor.fullLike(value: Double): DoubleTensor { val shape = tensor.shape val buffer = DoubleArray(tensor.numElements) { value } return DoubleTensor(shape, buffer) } + /** + * Returns a tensor filled with the scalar value 0.0, with the shape defined by the variable argument [shape]. + * + * @param shape array of integers defining the shape of the output tensor. + * @return tensor filled with the scalar value 0.0, with the [shape] shape. + */ public fun zeros(shape: IntArray): DoubleTensor = full(0.0, shape) + /** + * Returns a tensor filled with the scalar value 0.0, with the same shape as a given array. + * + * @return tensor filled with the scalar value 0.0, with the same shape as `input` tensor. + */ public fun Tensor.zeroesLike(): DoubleTensor = tensor.fullLike(0.0) + /** + * Returns a tensor filled with the scalar value 1.0, with the shape defined by the variable argument [shape]. + * + * @param shape array of integers defining the shape of the output tensor. + * @return tensor filled with the scalar value 1.0, with the [shape] shape. + */ public fun ones(shape: IntArray): DoubleTensor = full(1.0, shape) + /** + * Returns a tensor filled with the scalar value 1.0, with the same shape as a given array. + * + * @return tensor filled with the scalar value 1.0, with the same shape as `input` tensor. + */ public fun Tensor.onesLike(): DoubleTensor = tensor.fullLike(1.0) + /** + * Returns a 2-D tensor with shape ([n], [n]), with ones on the diagonal and zeros elsewhere. + * + * @param n the number of rows and columns + * @return a 2-D tensor with ones on the diagonal and zeros elsewhere. + */ public fun eye(n: Int): DoubleTensor { val shape = intArrayOf(n, n) val buffer = DoubleArray(n * n) { 0.0 } @@ -78,6 +129,11 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra { return res } + /** + * Return a copy of the tensor. + * + * @return a copy of the `input` tensor with a copied buffer. + */ public fun Tensor.copy(): DoubleTensor { return DoubleTensor(tensor.shape, tensor.mutableBuffer.array().copyOf(), tensor.bufferStart) } @@ -359,7 +415,12 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra { return resTensor.tensor } - + /** + * Applies the [transform] function to each element of the tensor and returns the resulting modified tensor. + * + * @param transform the function to be applied to each element of the tensor. + * @return the resulting tensor after applying the function. + */ public fun Tensor.map(transform: (Double) -> Double): DoubleTensor { return DoubleTensor( tensor.shape, @@ -368,10 +429,24 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra { ) } + /** + * Compares element-wise two tensors with a specified precision. + * + * @param other the tensor to compare with `input` tensor. + * @param epsilon permissible error when comparing two Double values. + * @return true if two tensors have the same shape and elements, false otherwise. + */ public fun Tensor.eq(other: Tensor, epsilon: Double): Boolean { return tensor.eq(other) { x, y -> abs(x - y) < epsilon } } + /** + * Compares element-wise two tensors. + * Comparison of two Double values occurs with 1e-5 precision. + * + * @param other the tensor to compare with `input` tensor. + * @return true if two tensors have the same shape and elements, false otherwise. + */ public infix fun Tensor.eq(other: Tensor): Boolean = tensor.eq(other, 1e-5) private fun Tensor.eq( @@ -395,9 +470,25 @@ public open class DoubleTensorAlgebra : TensorPartialDivisionAlgebra { return true } + /** + * Returns a tensor of random numbers drawn from normal distributions with 0.0 mean and 1.0 standard deviation. + * + * @param shape the desired shape for the output tensor. + * @param seed the random seed of the pseudo-random number generator. + * @return tensor of a given shape filled with numbers from the normal distribution + * with 0.0 mean and 1.0 standard deviation. + */ public fun randomNormal(shape: IntArray, seed: Long = 0): DoubleTensor = DoubleTensor(shape, getRandomNormals(shape.reduce(Int::times), seed)) + /** + * Returns a tensor with the same shape as `input` of random numbers drawn from normal distributions + * with 0.0 mean and 1.0 standard deviation. + * + * @param seed the random seed of the pseudo-random number generator. + * @return tensor with the same shape as `input` filled with numbers from the normal distribution + * with 0.0 mean and 1.0 standard deviation. + */ public fun Tensor.randomNormalLike(seed: Long = 0): DoubleTensor = DoubleTensor(tensor.shape, getRandomNormals(tensor.shape.reduce(Int::times), seed))