v0.3.0-dev-9 #324

Merged
altavir merged 265 commits from dev into master 2021-05-08 17:16:29 +03:00
8 changed files with 22 additions and 22 deletions
Showing only changes of commit d73d03c055 - Show all commits

View File

@ -69,7 +69,7 @@ fun main () {
val n = l.shape[0] val n = l.shape[0]
val x = zeros(intArrayOf(n)) val x = zeros(intArrayOf(n))
for (i in 0 until 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 return x
} }

View File

@ -60,7 +60,7 @@ fun main() {
require(yTrue.shape contentEquals yPred.shape) require(yTrue.shape contentEquals yPred.shape)
val diff = yTrue - yPred val diff = yTrue - yPred
return diff.dot(diff).sqrt().value() return diff.dot(diff).sqrt().valueOrNull()!!
} }
println("MSE: ${mse(alpha, alphaOLS)}") println("MSE: ${mse(alpha, alphaOLS)}")

View File

@ -16,11 +16,12 @@ import space.kscience.kmath.operations.Algebra
public interface TensorAlgebra<T>: Algebra<Tensor<T>> { public interface TensorAlgebra<T>: Algebra<Tensor<T>> {
/** /**
*
* Returns a single tensor value of unit dimension. The tensor shape must be equal to [1]. * Returns a single tensor value of unit dimension. The tensor shape must be equal to [1].
* *
* @return the value of a scalar tensor. * @return the value of a scalar tensor.
*/ */
public fun Tensor<T>.value(): T public fun Tensor<T>.valueOrNull(): T?
/** /**
* Each element of the tensor [other] is added to this value. * Each element of the tensor [other] is added to this value.

View File

@ -35,12 +35,10 @@ public open class DoubleTensorAlgebra :
public companion object : DoubleTensorAlgebra() public companion object : DoubleTensorAlgebra()
override fun Tensor<Double>.value(): Double { override fun Tensor<Double>.valueOrNull(): Double? = if(tensor.shape contentEquals intArrayOf(1)) {
check(tensor.shape contentEquals intArrayOf(1)) { // Inconsistent value for tensor of with this shape
"Inconsistent value for tensor of shape ${shape.toList()}" tensor.mutableBuffer.array()[tensor.bufferStart]
} } else null
return tensor.mutableBuffer.array()[tensor.bufferStart]
}
/** /**
* Constructs a tensor with the specified shape and data. * Constructs a tensor with the specified shape and data.

View File

@ -58,7 +58,7 @@ internal fun DoubleTensorAlgebra.checkSymmetric(
internal fun DoubleTensorAlgebra.checkPositiveDefinite(tensor: DoubleTensor, epsilon: Double = 1e-6) { internal fun DoubleTensorAlgebra.checkPositiveDefinite(tensor: DoubleTensor, epsilon: Double = 1e-6) {
checkSymmetric(tensor, epsilon) checkSymmetric(tensor, epsilon)
for (mat in tensor.matrixSequence()) for (mat in tensor.matrixSequence())
check(mat.asTensor().detLU().value() > 0.0) { check(mat.asTensor().detLU().valueOrNull()!! > 0.0) {
"Tensor contains matrices which are not positive definite ${mat.asTensor().detLU().value()}" "Tensor contains matrices which are not positive definite ${mat.asTensor().detLU().valueOrNull()!!}"
} }
} }

View File

@ -12,6 +12,7 @@ import space.kscience.kmath.nd.as2D
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.tensors.core.* import space.kscience.kmath.tensors.core.*
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.valueOrNull
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.min import kotlin.math.min
import kotlin.math.sign import kotlin.math.sign
@ -239,14 +240,14 @@ internal fun DoubleTensorAlgebra.qrHelper(
val vv = v.as1D() val vv = v.as1D()
if (j > 0) { if (j > 0) {
for (i in 0 until j) { 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) { for (k in 0 until n) {
val qTi = qT[i].as1D() val qTi = qT[i].as1D()
vv[k] = vv[k] - r[i, j] * qTi[k] 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) { for (i in 0 until n) {
qM[i, j] = vv[i] / r[j, j] qM[i, j] = vv[i] / r[j, j]
} }
@ -269,9 +270,9 @@ internal fun DoubleTensorAlgebra.svd1d(a: DoubleTensor, epsilon: Double = 1e-10)
while (true) { while (true) {
lastV = v lastV = v
v = b.dot(lastV) 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) v = v.times(1.0 / norm)
if (abs(v.dot(lastV).value()) > 1 - epsilon) { if (abs(v.dot(lastV).valueOrNull()!!) > 1 - epsilon) {
return v return v
} }
} }
@ -292,7 +293,7 @@ internal fun DoubleTensorAlgebra.svdHelper(
val outerProduct = DoubleArray(u.shape[0] * v.shape[0]) val outerProduct = DoubleArray(u.shape[0] * v.shape[0])
for (i in 0 until u.shape[0]) { for (i in 0 until u.shape[0]) {
for (j in 0 until v.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)) a = a - singularValue.times(DoubleTensor(intArrayOf(u.shape[0], v.shape[0]), outerProduct))
@ -303,12 +304,12 @@ internal fun DoubleTensorAlgebra.svdHelper(
if (n > m) { if (n > m) {
v = svd1d(a, epsilon) v = svd1d(a, epsilon)
u = matrix.dot(v) u = matrix.dot(v)
norm = DoubleTensorAlgebra { (u dot u).sqrt().value() } norm = DoubleTensorAlgebra { (u dot u).sqrt().valueOrNull()!! }
u = u.times(1.0 / norm) u = u.times(1.0 / norm)
} else { } else {
u = svd1d(a, epsilon) u = svd1d(a, epsilon)
v = matrix.transpose(0, 1).dot(u) 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) v = v.times(1.0 / norm)
} }

View File

@ -46,7 +46,7 @@ internal class TestDoubleLinearOpsTensorAlgebra {
) )
) )
assertTrue { abs(m.det().value() - expectedValue) < 1e-5 } assertTrue { abs(m.det().valueOrNull()!! - expectedValue) < 1e-5 }
} }
@Test @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 @Test
@ -90,7 +90,7 @@ internal class TestDoubleLinearOpsTensorAlgebra {
fun testScalarProduct() = DoubleTensorAlgebra { fun testScalarProduct() = DoubleTensorAlgebra {
val a = fromArray(intArrayOf(3), doubleArrayOf(1.8, 2.5, 6.8)) val a = fromArray(intArrayOf(3), doubleArrayOf(1.8, 2.5, 6.8))
val b = fromArray(intArrayOf(3), doubleArrayOf(5.5, 2.6, 6.4)) 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 @Test

View File

@ -21,7 +21,7 @@ internal class TestDoubleTensor {
fun testValue() = DoubleTensorAlgebra { fun testValue() = DoubleTensorAlgebra {
val value = 12.5 val value = 12.5
val tensor = fromArray(intArrayOf(1), doubleArrayOf(value)) val tensor = fromArray(intArrayOf(1), doubleArrayOf(value))
assertEquals(tensor.value(), value) assertEquals(tensor.valueOrNull()!!, value)
} }
@Test @Test