diff --git a/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMMatrix.kt index 49888f8d6..a40657cfb 100644 --- a/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMMatrix.kt @@ -3,15 +3,45 @@ package kscience.kmath.commons.linear import kscience.kmath.linear.* import kscience.kmath.structures.Matrix import kscience.kmath.structures.NDStructure +import kscience.kmath.structures.RealBuffer import org.apache.commons.math3.linear.* -public class CMMatrix(public val origin: RealMatrix, features: Set? = null) : FeaturedMatrix { +public class CMMatrix(public val origin: RealMatrix, features: Set = emptySet()) : + FeaturedMatrix { public override val rowNum: Int get() = origin.rowDimension public override val colNum: Int get() = origin.columnDimension - public override val features: Set = features ?: sequence { - if (origin is DiagonalMatrix) yield(DiagonalFeature) - }.toHashSet() + public override val features: Set = features union hashSetOf( + *if (origin is DiagonalMatrix) arrayOf(DiagonalFeature) else emptyArray(), + object : DeterminantFeature, LupDecompositionFeature { + private val lup by lazy { LUDecomposition(origin) } + override val determinant: Double by lazy { lup.determinant } + override val l: FeaturedMatrix by lazy { CMMatrix(lup.l, setOf(LFeature)) } + override val u: FeaturedMatrix by lazy { CMMatrix(lup.u, setOf(UFeature)) } + override val p: FeaturedMatrix by lazy { CMMatrix(lup.p) } + }, + + object : CholeskyDecompositionFeature { + override val l: FeaturedMatrix by lazy { + val cholesky = CholeskyDecomposition(origin) + CMMatrix(cholesky.l, setOf(LFeature)) + } + }, + + object : QRDecompositionFeature { + private val qr by lazy { QRDecomposition(origin) } + override val q: FeaturedMatrix by lazy { CMMatrix(qr.q, setOf(OrthogonalFeature)) } + override val r: FeaturedMatrix by lazy { CMMatrix(qr.r, setOf(UFeature)) } + }, + + object : SingularValueDecompositionFeature { + private val sv by lazy { SingularValueDecomposition(origin) } + override val u: FeaturedMatrix by lazy { CMMatrix(sv.u) } + override val s: FeaturedMatrix by lazy { CMMatrix(sv.s) } + override val v: FeaturedMatrix by lazy { CMMatrix(sv.v) } + override val singularValues: Point by lazy { RealBuffer(sv.singularValues) } + }, + ) public override fun suggestFeature(vararg features: MatrixFeature): CMMatrix = CMMatrix(origin, this.features + features) diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixFeatures.kt index 767b58eba..81e734949 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixFeatures.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixFeatures.kt @@ -35,6 +35,8 @@ public interface InverseMatrixFeature : MatrixFeature { /** * Matrices with this feature can compute their determinant. + * + * @param T the type of matrices' items. */ public interface DeterminantFeature : MatrixFeature { /** diff --git a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt index 5b7d0a01b..0fb361040 100644 --- a/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/kscience/kmath/ejml/EjmlMatrix.kt @@ -48,8 +48,12 @@ public class EjmlMatrix(public val origin: SimpleMatrix, features: Set by lazy { EjmlMatrix(SimpleMatrix(qr.getQ(null, false))) } - override val r: FeaturedMatrix by lazy { EjmlMatrix(SimpleMatrix(qr.getR(null, false))) } + override val q: FeaturedMatrix by lazy { + EjmlMatrix(SimpleMatrix(qr.getQ(null, false)), setOf(OrthogonalFeature)) + } + override val r: FeaturedMatrix by lazy { + EjmlMatrix(SimpleMatrix(qr.getR(null, false)), setOf(UFeature)) + } }, object : CholeskyDecompositionFeature {