diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt index 78370b517..4494d6799 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LinearSystemSolvingWithLUP.kt @@ -69,7 +69,7 @@ fun main () { val n = l.shape[0] val x = zeros(intArrayOf(n)) for (i in 0 until n){ - x[intArrayOf(i)] = (b[intArrayOf(i)] - l[i].dot(x).value()) / l[intArrayOf(i, i)] + x[intArrayOf(i)] = (b[intArrayOf(i)] - l[i].dot(x).valueOrNull()!!) / l[intArrayOf(i, i)] } return x } diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt index 42a0a4ba1..5d1883e7c 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt @@ -60,7 +60,7 @@ fun main() { require(yTrue.shape contentEquals yPred.shape) val diff = yTrue - yPred - return diff.dot(diff).sqrt().value() + return diff.dot(diff).sqrt().valueOrNull()!! } println("MSE: ${mse(alpha, alphaOLS)}") 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 e7f8dc7ae..78a36e229 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 @@ -16,11 +16,12 @@ import space.kscience.kmath.operations.Algebra public interface TensorAlgebra: Algebra> { /** + * * Returns a single tensor value of unit dimension. The tensor shape must be equal to [1]. * * @return the value of a scalar tensor. */ - public fun Tensor.value(): T + public fun Tensor.valueOrNull(): T? /** * Each element of the tensor [other] is added to this value. 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 5baf6c7ad..bf27a2690 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 @@ -35,12 +35,10 @@ public open class DoubleTensorAlgebra : public companion object : DoubleTensorAlgebra() - override fun Tensor.value(): Double { - check(tensor.shape contentEquals intArrayOf(1)) { - "Inconsistent value for tensor of shape ${shape.toList()}" - } - return tensor.mutableBuffer.array()[tensor.bufferStart] - } + override fun Tensor.valueOrNull(): Double? = if(tensor.shape contentEquals intArrayOf(1)) { + // Inconsistent value for tensor of with this shape + tensor.mutableBuffer.array()[tensor.bufferStart] + } else null /** * Constructs a tensor with the specified shape and data. diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/checks.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/checks.kt index f1c158770..bfbc6334d 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/checks.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/checks.kt @@ -58,7 +58,7 @@ internal fun DoubleTensorAlgebra.checkSymmetric( internal fun DoubleTensorAlgebra.checkPositiveDefinite(tensor: DoubleTensor, epsilon: Double = 1e-6) { checkSymmetric(tensor, epsilon) for (mat in tensor.matrixSequence()) - check(mat.asTensor().detLU().value() > 0.0) { - "Tensor contains matrices which are not positive definite ${mat.asTensor().detLU().value()}" + check(mat.asTensor().detLU().valueOrNull()!! > 0.0) { + "Tensor contains matrices which are not positive definite ${mat.asTensor().detLU().valueOrNull()!!}" } } \ No newline at end of file diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index ff78ca64c..5c120c05f 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -12,6 +12,7 @@ import space.kscience.kmath.nd.as2D import space.kscience.kmath.operations.invoke import space.kscience.kmath.tensors.core.* import space.kscience.kmath.tensors.core.DoubleTensorAlgebra +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.valueOrNull import kotlin.math.abs import kotlin.math.min import kotlin.math.sign @@ -239,14 +240,14 @@ internal fun DoubleTensorAlgebra.qrHelper( val vv = v.as1D() if (j > 0) { for (i in 0 until j) { - r[i, j] = (qT[i] dot matrixT[j]).value() + r[i, j] = (qT[i] dot matrixT[j]).valueOrNull()!! for (k in 0 until n) { val qTi = qT[i].as1D() vv[k] = vv[k] - r[i, j] * qTi[k] } } } - r[j, j] = DoubleTensorAlgebra { (v dot v).sqrt().value() } + r[j, j] = DoubleTensorAlgebra { (v dot v).sqrt().valueOrNull()!! } for (i in 0 until n) { qM[i, j] = vv[i] / r[j, j] } @@ -269,9 +270,9 @@ internal fun DoubleTensorAlgebra.svd1d(a: DoubleTensor, epsilon: Double = 1e-10) while (true) { lastV = v v = b.dot(lastV) - val norm = DoubleTensorAlgebra { (v dot v).sqrt().value() } + val norm = DoubleTensorAlgebra { (v dot v).sqrt().valueOrNull()!! } v = v.times(1.0 / norm) - if (abs(v.dot(lastV).value()) > 1 - epsilon) { + if (abs(v.dot(lastV).valueOrNull()!!) > 1 - epsilon) { return v } } @@ -292,7 +293,7 @@ internal fun DoubleTensorAlgebra.svdHelper( val outerProduct = DoubleArray(u.shape[0] * v.shape[0]) for (i in 0 until u.shape[0]) { for (j in 0 until v.shape[0]) { - outerProduct[i * v.shape[0] + j] = u[i].value() * v[j].value() + outerProduct[i * v.shape[0] + j] = u[i].valueOrNull()!! * v[j].valueOrNull()!! } } a = a - singularValue.times(DoubleTensor(intArrayOf(u.shape[0], v.shape[0]), outerProduct)) @@ -303,12 +304,12 @@ internal fun DoubleTensorAlgebra.svdHelper( if (n > m) { v = svd1d(a, epsilon) u = matrix.dot(v) - norm = DoubleTensorAlgebra { (u dot u).sqrt().value() } + norm = DoubleTensorAlgebra { (u dot u).sqrt().valueOrNull()!! } u = u.times(1.0 / norm) } else { u = svd1d(a, epsilon) v = matrix.transpose(0, 1).dot(u) - norm = DoubleTensorAlgebra { (v dot v).sqrt().value() } + norm = DoubleTensorAlgebra { (v dot v).sqrt().valueOrNull()!! } v = v.times(1.0 / norm) } diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt index fddb37251..99f00edbf 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt @@ -46,7 +46,7 @@ internal class TestDoubleLinearOpsTensorAlgebra { ) ) - assertTrue { abs(m.det().value() - expectedValue) < 1e-5 } + assertTrue { abs(m.det().valueOrNull()!! - expectedValue) < 1e-5 } } @Test @@ -58,7 +58,7 @@ internal class TestDoubleLinearOpsTensorAlgebra { ) ) - assertTrue { abs(m.det().value() - expectedValue) < 1e-5 } + assertTrue { abs(m.det().valueOrNull()!! - expectedValue) < 1e-5 } } @Test @@ -90,7 +90,7 @@ internal class TestDoubleLinearOpsTensorAlgebra { fun testScalarProduct() = DoubleTensorAlgebra { val a = fromArray(intArrayOf(3), doubleArrayOf(1.8, 2.5, 6.8)) val b = fromArray(intArrayOf(3), doubleArrayOf(5.5, 2.6, 6.4)) - assertEquals(a.dot(b).value(), 59.92) + assertEquals(a.dot(b).valueOrNull()!!, 59.92) } @Test diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt index d39b5c365..1afdb2263 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt @@ -21,7 +21,7 @@ internal class TestDoubleTensor { fun testValue() = DoubleTensorAlgebra { val value = 12.5 val tensor = fromArray(intArrayOf(1), doubleArrayOf(value)) - assertEquals(tensor.value(), value) + assertEquals(tensor.valueOrNull()!!, value) } @Test