Golub-Kahan SVD algorithm for KMP tensors #499
@ -882,6 +882,34 @@ public open class DoubleTensorAlgebra :
|
|||||||
return Triple(uTensor.transpose(), sTensor, vTensor.transpose())
|
return Triple(uTensor.transpose(), sTensor, vTensor.transpose())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun StructureND<Double>.svdGolabKahan(): Triple<DoubleTensor, DoubleTensor, DoubleTensor> {
|
||||||
|
val size = tensor.dimension
|
||||||
|
val commonShape = tensor.shape.sliceArray(0 until size - 2)
|
||||||
|
val (n, m) = tensor.shape.sliceArray(size - 2 until size)
|
||||||
|
val uTensor = zeros(commonShape + intArrayOf(min(n, m), n))
|
||||||
|
val sTensor = zeros(commonShape + intArrayOf(min(n, m)))
|
||||||
|
val vTensor = zeros(commonShape + intArrayOf(min(n, m), m))
|
||||||
|
|
||||||
|
val matrices = tensor.matrices
|
||||||
|
val uTensors = uTensor.matrices
|
||||||
|
val sTensorVectors = sTensor.vectors
|
||||||
|
val vTensors = vTensor.matrices
|
||||||
|
|
||||||
|
for (index in matrices.indices) {
|
||||||
|
val matrix = matrices[index]
|
||||||
|
val matrixSize = matrix.shape.reduce { acc, i -> acc * i }
|
||||||
|
val curMatrix = DoubleTensor(
|
||||||
|
matrix.shape,
|
||||||
|
matrix.mutableBuffer.array()
|
||||||
|
.slice(matrix.bufferStart until matrix.bufferStart + matrixSize)
|
||||||
|
.toDoubleArray()
|
||||||
|
)
|
||||||
|
curMatrix.as2D().svdGolabKahanHelper(uTensors[index].as2D(), sTensorVectors[index], vTensors[index].as2D())
|
||||||
|
}
|
||||||
|
|
||||||
|
return Triple(uTensor.transpose(), sTensor, vTensor)
|
||||||
|
}
|
||||||
|
|
||||||
override fun StructureND<Double>.symEig(): Pair<DoubleTensor, DoubleTensor> = symEigJacobi(maxIteration = 50, epsilon = 1e-15)
|
override fun StructureND<Double>.symEig(): Pair<DoubleTensor, DoubleTensor> = symEigJacobi(maxIteration = 50, epsilon = 1e-15)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user