Merge pull request #241 from mipt-npm/refactor/linear-algebra
Refactor/linear algebra
This commit is contained in:
commit
8af2f5eb31
@ -9,6 +9,7 @@
|
||||
- Exponential operations merged with hyperbolic functions
|
||||
- Space is replaced by Group. Space is reserved for vector spaces.
|
||||
- VectorSpace is now a vector space
|
||||
-
|
||||
|
||||
### Deprecated
|
||||
|
||||
|
@ -92,6 +92,14 @@ benchmark {
|
||||
iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
|
||||
include("ExpressionsInterpretersBenchmark")
|
||||
}
|
||||
|
||||
configurations.register("matrixInverse") {
|
||||
warmups = 1 // number of warmup iterations
|
||||
iterations = 3 // number of iterations
|
||||
iterationTime = 500 // time in seconds per iteration
|
||||
iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
|
||||
include("MatrixInverseBenchmark")
|
||||
}
|
||||
}
|
||||
|
||||
kotlin.sourceSets.all {
|
||||
|
@ -4,14 +4,11 @@ import kotlinx.benchmark.Benchmark
|
||||
import kotlinx.benchmark.Blackhole
|
||||
import kotlinx.benchmark.Scope
|
||||
import kotlinx.benchmark.State
|
||||
import space.kscience.kmath.commons.linear.CMMatrixContext
|
||||
import space.kscience.kmath.ejml.EjmlMatrixContext
|
||||
import space.kscience.kmath.linear.BufferMatrixContext
|
||||
import space.kscience.kmath.linear.Matrix
|
||||
import space.kscience.kmath.linear.RealMatrixContext
|
||||
import space.kscience.kmath.commons.linear.CMLinearSpace
|
||||
import space.kscience.kmath.ejml.EjmlLinearSpace
|
||||
import space.kscience.kmath.linear.LinearSpace
|
||||
import space.kscience.kmath.linear.invoke
|
||||
import space.kscience.kmath.operations.RealField
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import kotlin.random.Random
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@ -21,47 +18,47 @@ internal class DotBenchmark {
|
||||
const val dim = 1000
|
||||
|
||||
//creating invertible matrix
|
||||
val matrix1 = Matrix.real(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
||||
val matrix2 = Matrix.real(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
||||
val matrix1 = LinearSpace.real.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
||||
val matrix2 = LinearSpace.real.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
||||
|
||||
val cmMatrix1 = CMMatrixContext { matrix1.toCM() }
|
||||
val cmMatrix2 = CMMatrixContext { matrix2.toCM() }
|
||||
val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
|
||||
val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
|
||||
|
||||
val ejmlMatrix1 = EjmlMatrixContext { matrix1.toEjml() }
|
||||
val ejmlMatrix2 = EjmlMatrixContext { matrix2.toEjml() }
|
||||
val ejmlMatrix1 = EjmlLinearSpace { matrix1.toEjml() }
|
||||
val ejmlMatrix2 = EjmlLinearSpace { matrix2.toEjml() }
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun cmDot(blackhole: Blackhole) {
|
||||
CMMatrixContext {
|
||||
CMLinearSpace.run {
|
||||
blackhole.consume(cmMatrix1 dot cmMatrix2)
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun ejmlDot(blackhole: Blackhole) {
|
||||
EjmlMatrixContext {
|
||||
EjmlLinearSpace {
|
||||
blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun ejmlDotWithConversion(blackhole: Blackhole) {
|
||||
EjmlMatrixContext {
|
||||
EjmlLinearSpace {
|
||||
blackhole.consume(matrix1 dot matrix2)
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun bufferedDot(blackhole: Blackhole) {
|
||||
BufferMatrixContext(RealField, Buffer.Companion::real).invoke {
|
||||
LinearSpace.auto(RealField).invoke {
|
||||
blackhole.consume(matrix1 dot matrix2)
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun realDot(blackhole: Blackhole) {
|
||||
RealMatrixContext {
|
||||
LinearSpace.real {
|
||||
blackhole.consume(matrix1 dot matrix2)
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,7 @@ internal class ExpressionsInterpretersBenchmark {
|
||||
fun mstExpression(blackhole: Blackhole) {
|
||||
val expr = algebra.mstInField {
|
||||
val x = bindSymbol(x)
|
||||
x * 2.0 + 2.0 / x - 16.0
|
||||
x * 2.0 + number(2.0) / x - 16.0
|
||||
}
|
||||
|
||||
invokeAndSum(expr, blackhole)
|
||||
@ -40,7 +40,7 @@ internal class ExpressionsInterpretersBenchmark {
|
||||
fun asmExpression(blackhole: Blackhole) {
|
||||
val expr = algebra.mstInField {
|
||||
val x = bindSymbol(x)
|
||||
x * 2.0 + 2.0 / x - 16.0
|
||||
x * 2.0 + number(2.0) / x - 16.0
|
||||
}.compile()
|
||||
|
||||
invokeAndSum(expr, blackhole)
|
||||
|
@ -4,44 +4,44 @@ import kotlinx.benchmark.Benchmark
|
||||
import kotlinx.benchmark.Blackhole
|
||||
import kotlinx.benchmark.Scope
|
||||
import kotlinx.benchmark.State
|
||||
import space.kscience.kmath.commons.linear.CMMatrixContext
|
||||
import space.kscience.kmath.commons.linear.CMMatrixContext.dot
|
||||
import space.kscience.kmath.commons.linear.CMLinearSpace
|
||||
import space.kscience.kmath.commons.linear.inverse
|
||||
import space.kscience.kmath.ejml.EjmlMatrixContext
|
||||
import space.kscience.kmath.ejml.EjmlLinearSpace
|
||||
import space.kscience.kmath.ejml.inverse
|
||||
import space.kscience.kmath.linear.Matrix
|
||||
import space.kscience.kmath.linear.MatrixContext
|
||||
import space.kscience.kmath.linear.LinearSpace
|
||||
import space.kscience.kmath.linear.inverseWithLup
|
||||
import space.kscience.kmath.linear.real
|
||||
import space.kscience.kmath.linear.invoke
|
||||
import kotlin.random.Random
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
internal class LinearAlgebraBenchmark {
|
||||
internal class MatrixInverseBenchmark {
|
||||
companion object {
|
||||
val random = Random(1224)
|
||||
const val dim = 100
|
||||
|
||||
private val space = LinearSpace.real
|
||||
|
||||
//creating invertible matrix
|
||||
val u = Matrix.real(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
||||
val l = Matrix.real(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
|
||||
val matrix = l dot u
|
||||
val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
|
||||
val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
|
||||
val matrix = space { l dot u }
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun kmathLupInversion(blackhole: Blackhole) {
|
||||
blackhole.consume(MatrixContext.real.inverseWithLup(matrix))
|
||||
blackhole.consume(LinearSpace.real.inverseWithLup(matrix))
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun cmLUPInversion(blackhole: Blackhole) {
|
||||
with(CMMatrixContext) {
|
||||
with(CMLinearSpace) {
|
||||
blackhole.consume(inverse(matrix))
|
||||
}
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun ejmlInverse(blackhole: Blackhole) {
|
||||
with(EjmlMatrixContext) {
|
||||
with(EjmlLinearSpace) {
|
||||
blackhole.consume(inverse(matrix))
|
||||
}
|
||||
}
|
@ -15,7 +15,7 @@ import space.kscience.kmath.viktor.ViktorNDField
|
||||
internal class ViktorLogBenchmark {
|
||||
@Benchmark
|
||||
fun realFieldLog(blackhole: Blackhole) {
|
||||
with(realField) {
|
||||
with(realNdField) {
|
||||
val fortyTwo = produce { 42.0 }
|
||||
var res = one
|
||||
repeat(n) { res = ln(fortyTwo) }
|
||||
@ -47,7 +47,7 @@ internal class ViktorLogBenchmark {
|
||||
|
||||
// automatically build context most suited for given type.
|
||||
private val autoField = NDAlgebra.auto(RealField, dim, dim)
|
||||
private val realField = NDAlgebra.real(dim, dim)
|
||||
private val realNdField = NDAlgebra.real(dim, dim)
|
||||
private val viktorField = ViktorNDField(intArrayOf(dim, dim))
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,28 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.real.*
|
||||
import space.kscience.kmath.structures.RealBuffer
|
||||
|
||||
fun main() {
|
||||
val x0 = Point(0.0, 0.0, 0.0)
|
||||
val sigma = Point(1.0, 1.0, 1.0)
|
||||
|
||||
val gaussian: (Point<Double>) -> Double = { x ->
|
||||
require(x.size == x0.size)
|
||||
kotlin.math.exp(-((x - x0) / sigma).square().sum())
|
||||
}
|
||||
|
||||
fun ((Point<Double>) -> Double).grad(x: Point<Double>): Point<Double> {
|
||||
require(x.size == x0.size)
|
||||
return RealBuffer(x.size) { i ->
|
||||
val h = sigma[i] / 5
|
||||
val dVector = RealBuffer(x.size) { if (it == i) h else 0.0 }
|
||||
val f1 = invoke(x + dVector / 2)
|
||||
val f0 = invoke(x - dVector / 2)
|
||||
(f1 - f0) / h
|
||||
}
|
||||
}
|
||||
|
||||
println(gaussian.grad(x0))
|
||||
|
||||
}
|
@ -7,7 +7,7 @@ import kotlin.system.measureTimeMillis
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
fun main() {
|
||||
val n = 6000
|
||||
val structure = NDStructure.build(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 }
|
||||
val structure = NDStructure.buffered(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 }
|
||||
structure.mapToBuffer { it + 1 } // warm-up
|
||||
val time1 = measureTimeMillis { val res = structure.mapToBuffer { it + 1 } }
|
||||
println("Structure mapping finished in $time1 millis")
|
||||
|
@ -5,7 +5,7 @@ import space.kscience.kmath.dimensions.D3
|
||||
import space.kscience.kmath.dimensions.DMatrixContext
|
||||
import space.kscience.kmath.dimensions.Dimension
|
||||
|
||||
private fun DMatrixContext<Double>.simple() {
|
||||
private fun DMatrixContext<Double, *>.simple() {
|
||||
val m1 = produce<D2, D3> { i, j -> (i + j).toDouble() }
|
||||
val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() }
|
||||
|
||||
@ -17,7 +17,7 @@ private object D5 : Dimension {
|
||||
override val dim: UInt = 5u
|
||||
}
|
||||
|
||||
private fun DMatrixContext<Double>.custom() {
|
||||
private fun DMatrixContext<Double, *>.custom() {
|
||||
val m1 = produce<D2, D5> { i, j -> (i + j).toDouble() }
|
||||
val m2 = produce<D5, D2> { i, j -> (i - j).toDouble() }
|
||||
val m3 = produce<D2, D2> { i, j -> (i - j).toDouble() }
|
||||
|
@ -54,7 +54,7 @@ public object MstRing : Ring<MST>, NumbersAddOperations<MST>, ScaleOperations<MS
|
||||
public override val one: MST.Numeric = number(1.0)
|
||||
|
||||
public override fun number(value: Number): MST.Numeric = MstGroup.number(value)
|
||||
public override fun bindSymbol(value: String): MST.Symbolic = MstGroup.bindSymbol(value)
|
||||
public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value)
|
||||
public override fun add(a: MST, b: MST): MST.Binary = MstGroup.add(a, b)
|
||||
|
||||
public override fun scale(a: MST, value: Double): MST.Binary =
|
||||
@ -83,7 +83,7 @@ public object MstField : Field<MST>, NumbersAddOperations<MST>, ScaleOperations<
|
||||
|
||||
public override val one: MST.Numeric get() = MstRing.one
|
||||
|
||||
public override fun bindSymbol(value: String): MST.Symbolic = MstRing.bindSymbol(value)
|
||||
public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value)
|
||||
public override fun number(value: Number): MST.Numeric = MstRing.number(value)
|
||||
public override fun add(a: MST, b: MST): MST.Binary = MstRing.add(a, b)
|
||||
|
||||
@ -112,7 +112,7 @@ public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> {
|
||||
public override val zero: MST.Numeric get() = MstField.zero
|
||||
public override val one: MST.Numeric get() = MstField.one
|
||||
|
||||
public override fun bindSymbol(value: String): MST.Symbolic = MstField.bindSymbol(value)
|
||||
public override fun bindSymbol(value: String): MST.Symbolic = MstAlgebra.bindSymbol(value)
|
||||
public override fun number(value: Number): MST.Numeric = MstRing.number(value)
|
||||
public override fun sin(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg)
|
||||
public override fun cos(arg: MST): MST.Unary = unaryOperationFunction(TrigonometricOperations.COS_OPERATION)(arg)
|
||||
|
@ -3,11 +3,13 @@ package space.kscience.kmath.commons.linear
|
||||
import org.apache.commons.math3.linear.*
|
||||
import space.kscience.kmath.linear.*
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.nd.NDStructure
|
||||
import space.kscience.kmath.operations.RealField
|
||||
import space.kscience.kmath.structures.RealBuffer
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.cast
|
||||
|
||||
public inline class CMMatrix(public val origin: RealMatrix) : Matrix<Double> {
|
||||
public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> {
|
||||
public override val rowNum: Int get() = origin.rowDimension
|
||||
public override val colNum: Int get() = origin.columnDimension
|
||||
|
||||
@ -50,12 +52,17 @@ public inline class CMMatrix(public val origin: RealMatrix) : Matrix<Double> {
|
||||
}?.let(type::cast)
|
||||
|
||||
public override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is NDStructure<*>) return false
|
||||
return NDStructure.contentEquals(this, other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int = origin.hashCode()
|
||||
}
|
||||
|
||||
|
||||
public fun RealMatrix.asMatrix(): CMMatrix = CMMatrix(this)
|
||||
|
||||
public class CMVector(public val origin: RealVector) : Point<Double> {
|
||||
public inline class CMVector(public val origin: RealVector) : Point<Double> {
|
||||
public override val size: Int get() = origin.dimension
|
||||
|
||||
public override operator fun get(index: Int): Double = origin.getEntry(index)
|
||||
@ -63,16 +70,17 @@ public class CMVector(public val origin: RealVector) : Point<Double> {
|
||||
public override operator fun iterator(): Iterator<Double> = origin.toArray().iterator()
|
||||
}
|
||||
|
||||
public fun Point<Double>.toCM(): CMVector = if (this is CMVector) this else {
|
||||
val array = DoubleArray(size) { this[it] }
|
||||
CMVector(ArrayRealVector(array))
|
||||
}
|
||||
|
||||
public fun RealVector.toPoint(): CMVector = CMVector(this)
|
||||
|
||||
public object CMMatrixContext : MatrixContext<Double, CMMatrix> {
|
||||
public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): CMMatrix {
|
||||
val array = Array(rows) { i -> DoubleArray(columns) { j -> initializer(i, j) } }
|
||||
public object CMLinearSpace : LinearSpace<Double, RealField> {
|
||||
override val elementAlgebra: RealField get() = RealField
|
||||
|
||||
public override fun buildMatrix(
|
||||
rows: Int,
|
||||
columns: Int,
|
||||
initializer: RealField.(i: Int, j: Int) -> Double,
|
||||
): CMMatrix {
|
||||
val array = Array(rows) { i -> DoubleArray(columns) { j -> RealField.initializer(i, j) } }
|
||||
return CMMatrix(Array2DRowRealMatrix(array))
|
||||
}
|
||||
|
||||
@ -82,33 +90,50 @@ public object CMMatrixContext : MatrixContext<Double, CMMatrix> {
|
||||
else -> {
|
||||
//TODO add feature analysis
|
||||
val array = Array(rowNum) { i -> DoubleArray(colNum) { j -> get(i, j) } }
|
||||
CMMatrix(Array2DRowRealMatrix(array))
|
||||
Array2DRowRealMatrix(array).wrap()
|
||||
}
|
||||
}
|
||||
|
||||
override fun scale(a: Matrix<Double>, value: Double): Matrix<Double> = a.toCM().times(value)
|
||||
public fun Point<Double>.toCM(): CMVector = if (this is CMVector) this else {
|
||||
val array = DoubleArray(size) { this[it] }
|
||||
ArrayRealVector(array).wrap()
|
||||
}
|
||||
|
||||
internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this)
|
||||
internal fun RealVector.wrap(): CMVector = CMVector(this)
|
||||
|
||||
override fun buildVector(size: Int, initializer: RealField.(Int) -> Double): Point<Double> =
|
||||
ArrayRealVector(DoubleArray(size) { RealField.initializer(it) }).wrap()
|
||||
|
||||
override fun Matrix<Double>.plus(other: Matrix<Double>): CMMatrix =
|
||||
toCM().origin.add(other.toCM().origin).wrap()
|
||||
|
||||
override fun Point<Double>.plus(other: Point<Double>): CMVector =
|
||||
toCM().origin.add(other.toCM().origin).wrap()
|
||||
|
||||
override fun Point<Double>.minus(other: Point<Double>): CMVector =
|
||||
toCM().origin.subtract(other.toCM().origin).wrap()
|
||||
|
||||
public override fun Matrix<Double>.dot(other: Matrix<Double>): CMMatrix =
|
||||
CMMatrix(toCM().origin.multiply(other.toCM().origin))
|
||||
toCM().origin.multiply(other.toCM().origin).wrap()
|
||||
|
||||
public override fun Matrix<Double>.dot(vector: Point<Double>): CMVector =
|
||||
CMVector(toCM().origin.preMultiply(vector.toCM().origin))
|
||||
toCM().origin.preMultiply(vector.toCM().origin).wrap()
|
||||
|
||||
public override operator fun Matrix<Double>.unaryMinus(): CMMatrix =
|
||||
produce(rowNum, colNum) { i, j -> -get(i, j) }
|
||||
|
||||
public override fun add(a: Matrix<Double>, b: Matrix<Double>): CMMatrix =
|
||||
CMMatrix(a.toCM().origin.multiply(b.toCM().origin))
|
||||
|
||||
public override operator fun Matrix<Double>.minus(b: Matrix<Double>): CMMatrix =
|
||||
CMMatrix(toCM().origin.subtract(b.toCM().origin))
|
||||
|
||||
// public override fun multiply(a: Matrix<Double>, k: Number): CMMatrix =
|
||||
// CMMatrix(a.toCM().origin.scalarMultiply(k.toDouble()))
|
||||
public override operator fun Matrix<Double>.minus(other: Matrix<Double>): CMMatrix =
|
||||
toCM().origin.subtract(other.toCM().origin).wrap()
|
||||
|
||||
public override operator fun Matrix<Double>.times(value: Double): CMMatrix =
|
||||
produce(rowNum, colNum) { i, j -> get(i, j) * value }
|
||||
toCM().origin.scalarMultiply(value).wrap()
|
||||
|
||||
override fun Double.times(m: Matrix<Double>): CMMatrix =
|
||||
m * this
|
||||
|
||||
override fun Point<Double>.times(value: Double): CMVector =
|
||||
toCM().origin.mapMultiply(value).wrap()
|
||||
|
||||
override fun Double.times(v: Point<Double>): CMVector =
|
||||
v * this
|
||||
}
|
||||
|
||||
public operator fun CMMatrix.plus(other: CMMatrix): CMMatrix =
|
||||
|
@ -12,7 +12,7 @@ public enum class CMDecomposition {
|
||||
CHOLESKY
|
||||
}
|
||||
|
||||
public fun CMMatrixContext.solver(
|
||||
public fun CMLinearSpace.solver(
|
||||
a: Matrix<Double>,
|
||||
decomposition: CMDecomposition = CMDecomposition.LUP
|
||||
): DecompositionSolver = when (decomposition) {
|
||||
@ -23,19 +23,19 @@ public fun CMMatrixContext.solver(
|
||||
CMDecomposition.CHOLESKY -> CholeskyDecomposition(a.toCM().origin).solver
|
||||
}
|
||||
|
||||
public fun CMMatrixContext.solve(
|
||||
public fun CMLinearSpace.solve(
|
||||
a: Matrix<Double>,
|
||||
b: Matrix<Double>,
|
||||
decomposition: CMDecomposition = CMDecomposition.LUP
|
||||
): CMMatrix = solver(a, decomposition).solve(b.toCM().origin).asMatrix()
|
||||
): CMMatrix = solver(a, decomposition).solve(b.toCM().origin).wrap()
|
||||
|
||||
public fun CMMatrixContext.solve(
|
||||
public fun CMLinearSpace.solve(
|
||||
a: Matrix<Double>,
|
||||
b: Point<Double>,
|
||||
decomposition: CMDecomposition = CMDecomposition.LUP
|
||||
): CMVector = solver(a, decomposition).solve(b.toCM().origin).toPoint()
|
||||
|
||||
public fun CMMatrixContext.inverse(
|
||||
public fun CMLinearSpace.inverse(
|
||||
a: Matrix<Double>,
|
||||
decomposition: CMDecomposition = CMDecomposition.LUP
|
||||
): CMMatrix = solver(a, decomposition).inverse.asMatrix()
|
||||
): CMMatrix = solver(a, decomposition).inverse.wrap()
|
||||
|
@ -432,106 +432,23 @@ public final class space/kscience/kmath/expressions/SymbolIndexerKt {
|
||||
public static final fun withSymbols ([Lspace/kscience/kmath/expressions/Symbol;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/BufferMatrix : space/kscience/kmath/nd/Structure2D {
|
||||
public fun <init> (IILspace/kscience/kmath/structures/Buffer;)V
|
||||
public fun elements ()Lkotlin/sequences/Sequence;
|
||||
public fun equals (Ljava/lang/Object;)Z
|
||||
public fun get (II)Ljava/lang/Object;
|
||||
public fun get ([I)Ljava/lang/Object;
|
||||
public final fun getBuffer ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getColNum ()I
|
||||
public fun getColumns ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getDimension ()I
|
||||
public fun getRowNum ()I
|
||||
public fun getRows ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getShape ()[I
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/BufferMatrixContext : space/kscience/kmath/linear/GenericMatrixContext {
|
||||
public static final field Companion Lspace/kscience/kmath/linear/BufferMatrixContext$Companion;
|
||||
public final class space/kscience/kmath/linear/BufferLinearSpace : space/kscience/kmath/linear/LinearSpace {
|
||||
public fun <init> (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;)V
|
||||
public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun add (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun add (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
|
||||
public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object;
|
||||
public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
|
||||
public fun div (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun buildMatrix (IILkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun buildVector (ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getElementContext ()Lspace/kscience/kmath/operations/Ring;
|
||||
public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public final fun one (II)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun point (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun produce (IILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun produce (IILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object;
|
||||
public fun scale (Lspace/kscience/kmath/nd/Structure2D;D)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun times (Ljava/lang/Number;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
|
||||
public fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
|
||||
public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun unaryPlus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/BufferMatrixContext$Companion {
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/BufferVectorSpace : space/kscience/kmath/linear/VectorSpace {
|
||||
public fun <init> (ILspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;)V
|
||||
public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun add (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
|
||||
public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object;
|
||||
public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
|
||||
public fun div (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getAlgebra ()Lspace/kscience/kmath/operations/Group;
|
||||
public final fun getBufferFactory ()Lkotlin/jvm/functions/Function2;
|
||||
public fun getSize ()I
|
||||
public synthetic fun getZero ()Ljava/lang/Object;
|
||||
public fun getZero ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Ring;
|
||||
public fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object;
|
||||
public fun scale (Lspace/kscience/kmath/structures/Buffer;D)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun times (Ljava/lang/Number;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
|
||||
public fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun times (Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun unaryMinus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
|
||||
public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun unaryPlus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/CholeskyDecompositionFeature : space/kscience/kmath/linear/MatrixFeature {
|
||||
@ -549,37 +466,6 @@ public abstract interface class space/kscience/kmath/linear/DiagonalFeature : sp
|
||||
public final class space/kscience/kmath/linear/DiagonalFeature$Companion : space/kscience/kmath/linear/DiagonalFeature {
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/GenericMatrixContext : space/kscience/kmath/linear/MatrixContext {
|
||||
public abstract fun add (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun getElementContext ()Lspace/kscience/kmath/operations/Ring;
|
||||
public abstract fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/GenericMatrixContext$DefaultImpls {
|
||||
public static fun add (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun binaryOperation (Lspace/kscience/kmath/linear/GenericMatrixContext;Ljava/lang/String;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun binaryOperationFunction (Lspace/kscience/kmath/linear/GenericMatrixContext;Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
|
||||
public static fun bindSymbol (Lspace/kscience/kmath/linear/GenericMatrixContext;Ljava/lang/String;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun div (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun dot (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun dot (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun minus (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun plus (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun point (Lspace/kscience/kmath/linear/GenericMatrixContext;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun times (Lspace/kscience/kmath/linear/GenericMatrixContext;Ljava/lang/Number;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun times (Lspace/kscience/kmath/linear/GenericMatrixContext;Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun times (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun times (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun unaryMinus (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun unaryOperation (Lspace/kscience/kmath/linear/GenericMatrixContext;Ljava/lang/String;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun unaryOperationFunction (Lspace/kscience/kmath/linear/GenericMatrixContext;Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
|
||||
public static fun unaryPlus (Lspace/kscience/kmath/linear/GenericMatrixContext;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/InverseMatrixFeature : space/kscience/kmath/linear/MatrixFeature {
|
||||
public abstract fun getInverse ()Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
@ -588,11 +474,6 @@ public final class space/kscience/kmath/linear/LFeature : space/kscience/kmath/l
|
||||
public static final field INSTANCE Lspace/kscience/kmath/linear/LFeature;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/LinearAlgebraKt {
|
||||
public static final fun asMatrix (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/linear/VirtualMatrix;
|
||||
public static final fun asPoint (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/structures/Buffer;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/LinearSolver {
|
||||
public abstract fun inverse (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun solve (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
@ -603,9 +484,58 @@ public final class space/kscience/kmath/linear/LinearSolver$DefaultImpls {
|
||||
public static fun solve (Lspace/kscience/kmath/linear/LinearSolver;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/LinearSolverKt {
|
||||
public static final fun asMatrix (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/linear/VirtualMatrix;
|
||||
public static final fun asVector (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/structures/Buffer;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/LinearSpace {
|
||||
public static final field Companion Lspace/kscience/kmath/linear/LinearSpace$Companion;
|
||||
public abstract fun buildMatrix (IILkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun buildVector (ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun getElementAlgebra ()Lspace/kscience/kmath/operations/Ring;
|
||||
public abstract fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun times (Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun unaryMinus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/LinearSpace$Companion {
|
||||
public final fun buffered (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/linear/LinearSpace;
|
||||
public static synthetic fun buffered$default (Lspace/kscience/kmath/linear/LinearSpace$Companion;Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lspace/kscience/kmath/linear/LinearSpace;
|
||||
public final fun getReal ()Lspace/kscience/kmath/linear/LinearSpace;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/LinearSpace$DefaultImpls {
|
||||
public static fun dot (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun dot (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun minus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun minus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun plus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun plus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun times (Lspace/kscience/kmath/linear/LinearSpace;Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun times (Lspace/kscience/kmath/linear/LinearSpace;Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun times (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun times (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun unaryMinus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun unaryMinus (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/LinearSpaceKt {
|
||||
public static final fun invoke (Lspace/kscience/kmath/linear/LinearSpace;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/LupDecomposition : space/kscience/kmath/linear/DeterminantFeature, space/kscience/kmath/linear/LupDecompositionFeature {
|
||||
public fun <init> (Lspace/kscience/kmath/linear/MatrixContext;Lspace/kscience/kmath/operations/Field;Lspace/kscience/kmath/nd/Structure2D;[IZ)V
|
||||
public final fun getContext ()Lspace/kscience/kmath/linear/MatrixContext;
|
||||
public fun <init> (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/operations/Field;Lspace/kscience/kmath/nd/Structure2D;[IZ)V
|
||||
public final fun getContext ()Lspace/kscience/kmath/linear/LinearSpace;
|
||||
public fun getDeterminant ()Ljava/lang/Object;
|
||||
public final fun getElementContext ()Lspace/kscience/kmath/operations/Field;
|
||||
public fun getL ()Lspace/kscience/kmath/nd/Structure2D;
|
||||
@ -622,57 +552,27 @@ public abstract interface class space/kscience/kmath/linear/LupDecompositionFeat
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/LupDecompositionKt {
|
||||
public static final fun abs (Lspace/kscience/kmath/linear/GenericMatrixContext;Ljava/lang/Comparable;)Ljava/lang/Comparable;
|
||||
public static final fun inverseWithLup (Lspace/kscience/kmath/linear/RealMatrixContext;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun lup (Lspace/kscience/kmath/linear/MatrixContext;Lkotlin/jvm/functions/Function2;Lspace/kscience/kmath/operations/Field;Lspace/kscience/kmath/nd/Structure2D;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/linear/LupDecomposition;
|
||||
public static final fun lup (Lspace/kscience/kmath/linear/MatrixContext;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/LupDecomposition;
|
||||
public static final fun abs (Lspace/kscience/kmath/linear/LinearSpace;Ljava/lang/Comparable;)Ljava/lang/Comparable;
|
||||
public static final fun inverseWithLup (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun lup (Lspace/kscience/kmath/linear/LinearSpace;Lkotlin/jvm/functions/Function2;Lspace/kscience/kmath/nd/Structure2D;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/linear/LupDecomposition;
|
||||
public static final fun lup (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/LupDecomposition;
|
||||
public static final fun solveWithLup (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun solveWithLup (Lspace/kscience/kmath/linear/LupDecomposition;Lkotlin/jvm/functions/Function2;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun solveWithLup (Lspace/kscience/kmath/linear/RealMatrixContext;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/MatrixBuilder {
|
||||
public fun <init> (II)V
|
||||
public fun <init> (Lspace/kscience/kmath/linear/LinearSpace;II)V
|
||||
public final fun getColumns ()I
|
||||
public final fun getLinearSpace ()Lspace/kscience/kmath/linear/LinearSpace;
|
||||
public final fun getRows ()I
|
||||
public final fun invoke ([Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/MatrixBuilderKt {
|
||||
public static final fun build (Lspace/kscience/kmath/nd/Structure2D$Companion;II)Lspace/kscience/kmath/linear/MatrixBuilder;
|
||||
public static final fun column (Lspace/kscience/kmath/nd/Structure2D$Companion;[Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun row (Lspace/kscience/kmath/nd/Structure2D$Companion;[Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/MatrixContext : space/kscience/kmath/operations/GroupOperations, space/kscience/kmath/operations/ScaleOperations {
|
||||
public static final field Companion Lspace/kscience/kmath/linear/MatrixContext$Companion;
|
||||
public abstract fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
|
||||
public abstract fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun point (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun produce (IILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/MatrixContext$Companion {
|
||||
public final fun buffered (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/linear/GenericMatrixContext;
|
||||
public static synthetic fun buffered$default (Lspace/kscience/kmath/linear/MatrixContext$Companion;Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lspace/kscience/kmath/linear/GenericMatrixContext;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/MatrixContext$DefaultImpls {
|
||||
public static fun binaryOperation (Lspace/kscience/kmath/linear/MatrixContext;Ljava/lang/String;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun binaryOperationFunction (Lspace/kscience/kmath/linear/MatrixContext;Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
|
||||
public static fun bindSymbol (Lspace/kscience/kmath/linear/MatrixContext;Ljava/lang/String;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun div (Lspace/kscience/kmath/linear/MatrixContext;Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun minus (Lspace/kscience/kmath/linear/MatrixContext;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun plus (Lspace/kscience/kmath/linear/MatrixContext;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun point (Lspace/kscience/kmath/linear/MatrixContext;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun times (Lspace/kscience/kmath/linear/MatrixContext;Ljava/lang/Number;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun times (Lspace/kscience/kmath/linear/MatrixContext;Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun times (Lspace/kscience/kmath/linear/MatrixContext;Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun unaryOperation (Lspace/kscience/kmath/linear/MatrixContext;Ljava/lang/String;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static fun unaryOperationFunction (Lspace/kscience/kmath/linear/MatrixContext;Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
|
||||
public static fun unaryPlus (Lspace/kscience/kmath/linear/MatrixContext;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun column (Lspace/kscience/kmath/linear/LinearSpace;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun column (Lspace/kscience/kmath/linear/LinearSpace;[Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun row (Lspace/kscience/kmath/linear/LinearSpace;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun row (Lspace/kscience/kmath/linear/LinearSpace;[Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/MatrixFeature {
|
||||
@ -688,12 +588,12 @@ public final class space/kscience/kmath/linear/MatrixWrapper : space/kscience/km
|
||||
public fun get (II)Ljava/lang/Object;
|
||||
public fun get ([I)Ljava/lang/Object;
|
||||
public fun getColNum ()I
|
||||
public fun getColumns ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getColumns ()Ljava/util/List;
|
||||
public fun getDimension ()I
|
||||
public final fun getFeatures ()Ljava/util/Set;
|
||||
public final fun getOrigin ()Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun getRowNum ()I
|
||||
public fun getRows ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getRows ()Ljava/util/List;
|
||||
public fun getShape ()[I
|
||||
public fun hashCode ()I
|
||||
public fun toString ()Ljava/lang/String;
|
||||
@ -701,12 +601,11 @@ public final class space/kscience/kmath/linear/MatrixWrapper : space/kscience/km
|
||||
|
||||
public final class space/kscience/kmath/linear/MatrixWrapperKt {
|
||||
public static final fun getOrigin (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun one (Lspace/kscience/kmath/linear/GenericMatrixContext;II)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun one (Lspace/kscience/kmath/linear/LinearSpace;II)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun plus (Lspace/kscience/kmath/nd/Structure2D;Ljava/util/Collection;)Lspace/kscience/kmath/linear/MatrixWrapper;
|
||||
public static final fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/linear/MatrixFeature;)Lspace/kscience/kmath/linear/MatrixWrapper;
|
||||
public static final fun square (Lspace/kscience/kmath/nd/Structure2D$Companion;[Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun transpose (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun zero (Lspace/kscience/kmath/linear/GenericMatrixContext;II)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public static final fun zero (Lspace/kscience/kmath/linear/LinearSpace;II)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/OrthogonalFeature : space/kscience/kmath/linear/MatrixFeature {
|
||||
@ -718,52 +617,6 @@ public abstract interface class space/kscience/kmath/linear/QRDecompositionFeatu
|
||||
public abstract fun getR ()Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/RealMatrixContext : space/kscience/kmath/linear/MatrixContext, space/kscience/kmath/operations/ScaleOperations {
|
||||
public static final field INSTANCE Lspace/kscience/kmath/linear/RealMatrixContext;
|
||||
public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun add (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun binaryOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
|
||||
public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object;
|
||||
public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
|
||||
public fun div (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public final fun one (II)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun point (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun produce (IILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun produce (IILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object;
|
||||
public fun scale (Lspace/kscience/kmath/nd/Structure2D;D)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public fun times (DLspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun times (Ljava/lang/Number;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
|
||||
public synthetic fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun times (Lspace/kscience/kmath/nd/Structure2D;D)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public final fun toBufferMatrix (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun unaryOperation (Ljava/lang/String;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
|
||||
public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object;
|
||||
public fun unaryPlus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/RealMatrixContextKt {
|
||||
public static final fun getReal (Lspace/kscience/kmath/linear/MatrixContext$Companion;)Lspace/kscience/kmath/linear/RealMatrixContext;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/SingularValueDecompositionFeature : space/kscience/kmath/linear/MatrixFeature {
|
||||
public abstract fun getS ()Lspace/kscience/kmath/nd/Structure2D;
|
||||
public abstract fun getSingularValues ()Lspace/kscience/kmath/structures/Buffer;
|
||||
@ -784,41 +637,6 @@ public final class space/kscience/kmath/linear/UnitFeature : space/kscience/kmat
|
||||
public static final field INSTANCE Lspace/kscience/kmath/linear/UnitFeature;
|
||||
}
|
||||
|
||||
public abstract interface class space/kscience/kmath/linear/VectorSpace : space/kscience/kmath/operations/Group, space/kscience/kmath/operations/ScaleOperations {
|
||||
public static final field Companion Lspace/kscience/kmath/linear/VectorSpace$Companion;
|
||||
public abstract fun add (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun getAlgebra ()Lspace/kscience/kmath/operations/Group;
|
||||
public abstract fun getSize ()I
|
||||
public abstract fun getZero ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun produce (Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun scale (Lspace/kscience/kmath/structures/Buffer;D)Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun unaryMinus (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/VectorSpace$Companion {
|
||||
public final fun buffered (ILspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/linear/BufferVectorSpace;
|
||||
public static synthetic fun buffered$default (Lspace/kscience/kmath/linear/VectorSpace$Companion;ILspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lspace/kscience/kmath/linear/BufferVectorSpace;
|
||||
public final fun real (I)Lspace/kscience/kmath/linear/BufferVectorSpace;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/VectorSpace$DefaultImpls {
|
||||
public static fun add (Lspace/kscience/kmath/linear/VectorSpace;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun binaryOperation (Lspace/kscience/kmath/linear/VectorSpace;Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun binaryOperationFunction (Lspace/kscience/kmath/linear/VectorSpace;Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
|
||||
public static fun bindSymbol (Lspace/kscience/kmath/linear/VectorSpace;Ljava/lang/String;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun div (Lspace/kscience/kmath/linear/VectorSpace;Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun getZero (Lspace/kscience/kmath/linear/VectorSpace;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun minus (Lspace/kscience/kmath/linear/VectorSpace;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun plus (Lspace/kscience/kmath/linear/VectorSpace;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun scale (Lspace/kscience/kmath/linear/VectorSpace;Lspace/kscience/kmath/structures/Buffer;D)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun times (Lspace/kscience/kmath/linear/VectorSpace;Ljava/lang/Number;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun times (Lspace/kscience/kmath/linear/VectorSpace;Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun unaryMinus (Lspace/kscience/kmath/linear/VectorSpace;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun unaryOperation (Lspace/kscience/kmath/linear/VectorSpace;Ljava/lang/String;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun unaryOperationFunction (Lspace/kscience/kmath/linear/VectorSpace;Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
|
||||
public static fun unaryPlus (Lspace/kscience/kmath/linear/VectorSpace;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/linear/VirtualMatrix : space/kscience/kmath/nd/Structure2D {
|
||||
public fun <init> (IILkotlin/jvm/functions/Function2;)V
|
||||
public fun elements ()Lkotlin/sequences/Sequence;
|
||||
@ -826,11 +644,11 @@ public final class space/kscience/kmath/linear/VirtualMatrix : space/kscience/km
|
||||
public fun get (II)Ljava/lang/Object;
|
||||
public fun get ([I)Ljava/lang/Object;
|
||||
public fun getColNum ()I
|
||||
public fun getColumns ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getColumns ()Ljava/util/List;
|
||||
public fun getDimension ()I
|
||||
public final fun getGenerator ()Lkotlin/jvm/functions/Function2;
|
||||
public fun getRowNum ()I
|
||||
public fun getRows ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public fun getRows ()Ljava/util/List;
|
||||
public fun getShape ()[I
|
||||
public fun hashCode ()I
|
||||
}
|
||||
@ -882,11 +700,11 @@ public final class space/kscience/kmath/nd/BufferNDAlgebra$DefaultImpls {
|
||||
|
||||
public final class space/kscience/kmath/nd/BufferNDAlgebraKt {
|
||||
public static final fun field (Lspace/kscience/kmath/nd/NDAlgebra$Companion;Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedNDField;
|
||||
public static final fun group (Lspace/kscience/kmath/nd/NDAlgebra$Companion;Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedNDGroup;
|
||||
public static final fun ndField (Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function2;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ndGroup (Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ndRing (Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ndSpace (Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object;
|
||||
public static final fun ring (Lspace/kscience/kmath/nd/NDAlgebra$Companion;Lspace/kscience/kmath/operations/Ring;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedNDRing;
|
||||
public static final fun space (Lspace/kscience/kmath/nd/NDAlgebra$Companion;Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function2;[I)Lspace/kscience/kmath/nd/BufferedNDGroup;
|
||||
}
|
||||
|
||||
public class space/kscience/kmath/nd/BufferedNDField : space/kscience/kmath/nd/BufferedNDRing, space/kscience/kmath/nd/NDField {
|
||||
@ -1147,10 +965,10 @@ public abstract interface class space/kscience/kmath/nd/NDStructure {
|
||||
public final class space/kscience/kmath/nd/NDStructure$Companion {
|
||||
public final fun auto (Lkotlin/reflect/KClass;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public final fun auto (Lkotlin/reflect/KClass;[ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public final fun build (Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public final fun build ([ILkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public static synthetic fun build$default (Lspace/kscience/kmath/nd/NDStructure$Companion;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public static synthetic fun build$default (Lspace/kscience/kmath/nd/NDStructure$Companion;[ILkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public final fun buffered (Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public final fun buffered ([ILkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public static synthetic fun buffered$default (Lspace/kscience/kmath/nd/NDStructure$Companion;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public static synthetic fun buffered$default (Lspace/kscience/kmath/nd/NDStructure$Companion;[ILkotlin/jvm/functions/Function2;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/NDBuffer;
|
||||
public final fun contentEquals (Lspace/kscience/kmath/nd/NDStructure;Lspace/kscience/kmath/nd/NDStructure;)Z
|
||||
}
|
||||
|
||||
@ -1307,22 +1125,21 @@ public abstract interface class space/kscience/kmath/nd/Structure2D : space/ksci
|
||||
public abstract fun get (II)Ljava/lang/Object;
|
||||
public abstract fun get ([I)Ljava/lang/Object;
|
||||
public abstract fun getColNum ()I
|
||||
public abstract fun getColumns ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun getColumns ()Ljava/util/List;
|
||||
public abstract fun getRowNum ()I
|
||||
public abstract fun getRows ()Lspace/kscience/kmath/structures/Buffer;
|
||||
public abstract fun getRows ()Ljava/util/List;
|
||||
public abstract fun getShape ()[I
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/nd/Structure2D$Companion {
|
||||
public final fun real (IILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/linear/BufferMatrix;
|
||||
}
|
||||
|
||||
public final class space/kscience/kmath/nd/Structure2D$DefaultImpls {
|
||||
public static fun elements (Lspace/kscience/kmath/nd/Structure2D;)Lkotlin/sequences/Sequence;
|
||||
public static fun get (Lspace/kscience/kmath/nd/Structure2D;[I)Ljava/lang/Object;
|
||||
public static fun getColumns (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun getColumns (Lspace/kscience/kmath/nd/Structure2D;)Ljava/util/List;
|
||||
public static fun getDimension (Lspace/kscience/kmath/nd/Structure2D;)I
|
||||
public static fun getRows (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/structures/Buffer;
|
||||
public static fun getRows (Lspace/kscience/kmath/nd/Structure2D;)Ljava/util/List;
|
||||
public static fun getShape (Lspace/kscience/kmath/nd/Structure2D;)[I
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,83 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.nd.*
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.VirtualBuffer
|
||||
import space.kscience.kmath.structures.indices
|
||||
|
||||
|
||||
public class BufferLinearSpace<T : Any, A : Ring<T>>(
|
||||
override val elementAlgebra: A,
|
||||
private val bufferFactory: BufferFactory<T>,
|
||||
) : LinearSpace<T, A> {
|
||||
|
||||
private fun ndRing(
|
||||
rows: Int,
|
||||
cols: Int,
|
||||
): BufferedNDRing<T, A> = NDAlgebra.ring(elementAlgebra, bufferFactory, rows, cols)
|
||||
|
||||
override fun buildMatrix(rows: Int, columns: Int, initializer: A.(i: Int, j: Int) -> T): Matrix<T> =
|
||||
ndRing(rows, columns).produce { (i, j) -> elementAlgebra.initializer(i, j) }.as2D()
|
||||
|
||||
override fun buildVector(size: Int, initializer: A.(Int) -> T): Point<T> =
|
||||
bufferFactory(size) { elementAlgebra.initializer(it) }
|
||||
|
||||
override fun Matrix<T>.unaryMinus(): Matrix<T> = ndRing(rowNum, colNum).run {
|
||||
unwrap().map { -it }.as2D()
|
||||
}
|
||||
|
||||
override fun Matrix<T>.plus(other: Matrix<T>): Matrix<T> = ndRing(rowNum, colNum).run {
|
||||
require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" }
|
||||
unwrap().plus(other.unwrap()).as2D()
|
||||
}
|
||||
|
||||
override fun Matrix<T>.minus(other: Matrix<T>): Matrix<T> = ndRing(rowNum, colNum).run {
|
||||
require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" }
|
||||
unwrap().minus(other.unwrap()).as2D()
|
||||
}
|
||||
|
||||
private fun Buffer<T>.linearize() = if (this is VirtualBuffer) {
|
||||
buildVector(size) { get(it) }
|
||||
} else {
|
||||
this
|
||||
}
|
||||
|
||||
override fun Matrix<T>.dot(other: Matrix<T>): Matrix<T> {
|
||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||
return elementAlgebra {
|
||||
val rows = this@dot.rows.map{it.linearize()}
|
||||
val columns = other.columns.map { it.linearize() }
|
||||
buildMatrix(rowNum, other.colNum) { i, j ->
|
||||
val r = rows[i]
|
||||
val c = columns[j]
|
||||
var res = zero
|
||||
for (l in r.indices) {
|
||||
res += r[l] * c[l]
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun Matrix<T>.dot(vector: Point<T>): Point<T> {
|
||||
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
||||
return elementAlgebra {
|
||||
val rows = this@dot.rows.map { it.linearize() }
|
||||
buildVector(rowNum) { i ->
|
||||
val r = rows[i]
|
||||
var res = zero
|
||||
for (j in r.indices) {
|
||||
res += r[j] * vector[j]
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun Matrix<T>.times(value: T): Matrix<T> = ndRing(rowNum, colNum).run {
|
||||
unwrap().map { it * value }.as2D()
|
||||
}
|
||||
}
|
@ -1,144 +0,0 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.nd.NDStructure
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.asSequence
|
||||
|
||||
/**
|
||||
* Alias for [Structure2D] with more familiar name.
|
||||
*
|
||||
* @param T the type of items.
|
||||
*/
|
||||
public typealias Matrix<T> = Structure2D<T>
|
||||
|
||||
/**
|
||||
* Basic implementation of Matrix space based on [NDStructure]
|
||||
*/
|
||||
public class BufferMatrixContext<T : Any, A>(
|
||||
public override val elementContext: A,
|
||||
private val bufferFactory: BufferFactory<T>,
|
||||
) : GenericMatrixContext<T, A, BufferMatrix<T>> where A : Ring<T>, A : ScaleOperations<T> {
|
||||
|
||||
public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): BufferMatrix<T> {
|
||||
val buffer = bufferFactory(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
|
||||
return BufferMatrix(rows, columns, buffer)
|
||||
}
|
||||
|
||||
override fun scale(a: Matrix<T>, value: Double): Matrix<T> = elementContext {
|
||||
produce(a.rowNum, a.colNum) { i, j ->
|
||||
a[i, j] * value
|
||||
}
|
||||
}
|
||||
|
||||
public override fun point(size: Int, initializer: (Int) -> T): Point<T> = bufferFactory(size, initializer)
|
||||
|
||||
private fun Matrix<T>.toBufferMatrix(): BufferMatrix<T> = if (this is BufferMatrix) this else {
|
||||
produce(rowNum, colNum) { i, j -> get(i, j) }
|
||||
}
|
||||
|
||||
public fun one(rows: Int, columns: Int): Matrix<Double> = VirtualMatrix(rows, columns) { i, j ->
|
||||
if (i == j) 1.0 else 0.0
|
||||
} + DiagonalFeature
|
||||
|
||||
public override infix fun Matrix<T>.dot(other: Matrix<T>): BufferMatrix<T> {
|
||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||
val bufferMatrix = toBufferMatrix()
|
||||
val otherBufferMatrix = other.toBufferMatrix()
|
||||
return elementContext {
|
||||
produce(rowNum, other.colNum) { i, j ->
|
||||
var res = one
|
||||
for (l in 0 until colNum) {
|
||||
res += bufferMatrix[i, l] * otherBufferMatrix[l, j]
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override infix fun Matrix<T>.dot(vector: Point<T>): Point<T> {
|
||||
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
||||
val bufferMatrix = toBufferMatrix()
|
||||
return elementContext {
|
||||
bufferFactory(rowNum) { i ->
|
||||
var res = one
|
||||
for (j in 0 until colNum) {
|
||||
res += bufferMatrix[i, j] * vector[j]
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun add(a: Matrix<T>, b: Matrix<T>): BufferMatrix<T> {
|
||||
require(a.rowNum == b.rowNum) { "Row number mismatch in matrix addition. Left side: ${a.rowNum}, right side: ${b.rowNum}" }
|
||||
require(a.colNum == b.colNum) { "Column number mismatch in matrix addition. Left side: ${a.colNum}, right side: ${b.colNum}" }
|
||||
val aBufferMatrix = a.toBufferMatrix()
|
||||
val bBufferMatrix = b.toBufferMatrix()
|
||||
return elementContext {
|
||||
produce(a.rowNum, a.colNum) { i, j ->
|
||||
aBufferMatrix[i, j] + bBufferMatrix[i, j]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// override fun multiply(a: Matrix<T>, k: Number): BufferMatrix<T> {
|
||||
// val aBufferMatrix = a.toBufferMatrix()
|
||||
// return elementContext {
|
||||
// produce(a.rowNum, a.colNum) { i, j -> aBufferMatrix[i, j] * k.toDouble() }
|
||||
// }
|
||||
// }
|
||||
|
||||
public companion object
|
||||
}
|
||||
|
||||
public class BufferMatrix<T : Any>(
|
||||
public override val rowNum: Int,
|
||||
public override val colNum: Int,
|
||||
public val buffer: Buffer<T>,
|
||||
) : Matrix<T> {
|
||||
|
||||
init {
|
||||
require(buffer.size == rowNum * colNum) { "Dimension mismatch for matrix structure" }
|
||||
}
|
||||
|
||||
override val shape: IntArray get() = intArrayOf(rowNum, colNum)
|
||||
|
||||
public override operator fun get(index: IntArray): T = get(index[0], index[1])
|
||||
public override operator fun get(i: Int, j: Int): T = buffer[i * colNum + j]
|
||||
|
||||
public override fun elements(): Sequence<Pair<IntArray, T>> = sequence {
|
||||
for (i in 0 until rowNum) for (j in 0 until colNum) yield(intArrayOf(i, j) to get(i, j))
|
||||
}
|
||||
|
||||
public override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
|
||||
return when (other) {
|
||||
is NDStructure<*> -> NDStructure.contentEquals(this, other)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = rowNum
|
||||
result = 31 * result + colNum
|
||||
result = 31 * result + buffer.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
public override fun toString(): String {
|
||||
return if (rowNum <= 5 && colNum <= 5)
|
||||
"Matrix(rowsNum = $rowNum, colNum = $colNum)\n" +
|
||||
rows.asSequence().joinToString(prefix = "(", postfix = ")", separator = "\n ") { buffer ->
|
||||
buffer.asSequence().joinToString(separator = "\t") { it.toString() }
|
||||
}
|
||||
else "Matrix(rowsNum = $rowNum, colNum = $colNum)"
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,25 +1,22 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.VirtualBuffer
|
||||
|
||||
public typealias Point<T> = Buffer<T>
|
||||
import space.kscience.kmath.nd.as1D
|
||||
|
||||
/**
|
||||
* A group of methods to resolve equation A dot X = B, where A and B are matrices or vectors
|
||||
*/
|
||||
public interface LinearSolver<T : Any> {
|
||||
public fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T>
|
||||
public fun solve(a: Matrix<T>, b: Point<T>): Point<T> = solve(a, b.asMatrix()).asPoint()
|
||||
public fun solve(a: Matrix<T>, b: Point<T>): Point<T> = solve(a, b.asMatrix()).asVector()
|
||||
public fun inverse(a: Matrix<T>): Matrix<T>
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert matrix to vector if it is possible
|
||||
*/
|
||||
public fun <T : Any> Matrix<T>.asPoint(): Point<T> =
|
||||
public fun <T : Any> Matrix<T>.asVector(): Point<T> =
|
||||
if (this.colNum == 1)
|
||||
VirtualBuffer(rowNum) { get(it, 0) }
|
||||
as1D()
|
||||
else
|
||||
error("Can't convert matrix with more than one column to vector")
|
||||
|
@ -0,0 +1,204 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.nd.*
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Alias for [Structure2D] with more familiar name.
|
||||
*
|
||||
* @param T the type of items.
|
||||
*/
|
||||
public typealias Matrix<T> = Structure2D<T>
|
||||
|
||||
/**
|
||||
* Alias or using [Buffer] as a point/vector in a many-dimensional space.
|
||||
*/
|
||||
public typealias Point<T> = Buffer<T>
|
||||
|
||||
/**
|
||||
* Basic operations on matrices and vectors. Operates on [Matrix].
|
||||
*
|
||||
* @param T the type of items in the matrices.
|
||||
* @param M the type of operated matrices.
|
||||
*/
|
||||
public interface LinearSpace<T : Any, out A : Ring<T>> {
|
||||
public val elementAlgebra: A
|
||||
|
||||
/**
|
||||
* Produces a matrix with this context and given dimensions.
|
||||
*/
|
||||
public fun buildMatrix(rows: Int, columns: Int, initializer: A.(i: Int, j: Int) -> T): Matrix<T>
|
||||
|
||||
/**
|
||||
* Produces a point compatible with matrix space (and possibly optimized for it).
|
||||
*/
|
||||
public fun buildVector(size: Int, initializer: A.(Int) -> T): Point<T>
|
||||
|
||||
public operator fun Matrix<T>.unaryMinus(): Matrix<T> = buildMatrix(rowNum, colNum) { i, j ->
|
||||
-get(i, j)
|
||||
}
|
||||
|
||||
public operator fun Point<T>.unaryMinus(): Point<T> = buildVector(size) {
|
||||
-get(it)
|
||||
}
|
||||
|
||||
/**
|
||||
* Matrix sum
|
||||
*/
|
||||
public operator fun Matrix<T>.plus(other: Matrix<T>): Matrix<T> = buildMatrix(rowNum, colNum) { i, j ->
|
||||
get(i, j) + other[i, j]
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Vector sum
|
||||
*/
|
||||
public operator fun Point<T>.plus(other: Point<T>): Point<T> = buildVector(size) {
|
||||
get(it) + other[it]
|
||||
}
|
||||
|
||||
/**
|
||||
* Matrix subtraction
|
||||
*/
|
||||
public operator fun Matrix<T>.minus(other: Matrix<T>): Matrix<T> = buildMatrix(rowNum, colNum) { i, j ->
|
||||
get(i, j) - other[i, j]
|
||||
}
|
||||
|
||||
/**
|
||||
* Vector subtraction
|
||||
*/
|
||||
public operator fun Point<T>.minus(other: Point<T>): Point<T> = buildVector(size) {
|
||||
get(it) - other[it]
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes the dot product of this matrix and another one.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param other the multiplier.
|
||||
* @return the dot product.
|
||||
*/
|
||||
public infix fun Matrix<T>.dot(other: Matrix<T>): Matrix<T> {
|
||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||
return elementAlgebra {
|
||||
buildMatrix(rowNum, other.colNum) { i, j ->
|
||||
var res = zero
|
||||
for (l in 0 until colNum) {
|
||||
res += this@dot[i, l] * other[l, j]
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the dot product of this matrix and a vector.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param vector the multiplier.
|
||||
* @return the dot product.
|
||||
*/
|
||||
public infix fun Matrix<T>.dot(vector: Point<T>): Point<T> {
|
||||
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
||||
return elementAlgebra {
|
||||
buildVector(rowNum) { i ->
|
||||
var res = one
|
||||
for (j in 0 until colNum) {
|
||||
res += this@dot[i, j] * vector[j]
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Multiplies a matrix by its element.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param value the multiplier.
|
||||
* @receiver the product.
|
||||
*/
|
||||
public operator fun Matrix<T>.times(value: T): Matrix<T> =
|
||||
buildMatrix(rowNum, colNum) { i, j -> get(i, j) * value }
|
||||
|
||||
/**
|
||||
* Multiplies an element by a matrix of it.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param m the multiplier.
|
||||
* @receiver the product.
|
||||
*/
|
||||
public operator fun T.times(m: Matrix<T>): Matrix<T> = m * this
|
||||
|
||||
/**
|
||||
* Multiplies a vector by its element.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param value the multiplier.
|
||||
* @receiver the product.
|
||||
*/
|
||||
public operator fun Point<T>.times(value: T): Point<T> =
|
||||
buildVector(size) { i -> get(i) * value }
|
||||
|
||||
/**
|
||||
* Multiplies an element by a vector of it.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param v the multiplier.
|
||||
* @receiver the product.
|
||||
*/
|
||||
public operator fun T.times(v: Point<T>): Point<T> = v * this
|
||||
|
||||
/**
|
||||
* Gets a feature from the matrix. This function may return some additional features to
|
||||
* [space.kscience.kmath.nd.NDStructure.getFeature].
|
||||
*
|
||||
* @param F the type of feature.
|
||||
* @param m the matrix.
|
||||
* @param type the [KClass] instance of [F].
|
||||
* @return a feature object or `null` if it isn't present.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun <F : Any> getFeature(m: Matrix<T>, type: KClass<F>): F? = m.getFeature(type)
|
||||
|
||||
public companion object {
|
||||
|
||||
/**
|
||||
* A structured matrix with custom buffer
|
||||
*/
|
||||
public fun <T : Any, A : Ring<T>> buffered(
|
||||
algebra: A,
|
||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
||||
): LinearSpace<T, A> = BufferLinearSpace(algebra,bufferFactory)
|
||||
|
||||
public val real: LinearSpace<Double, RealField> = buffered(RealField, Buffer.Companion::real)
|
||||
|
||||
/**
|
||||
* Automatic buffered matrix, unboxed if it is possible
|
||||
*/
|
||||
public inline fun <reified T : Any, A : Ring<T>> auto(ring: A): LinearSpace<T, A> =
|
||||
buffered(ring, Buffer.Companion::auto)
|
||||
}
|
||||
}
|
||||
|
||||
public operator fun <LS : LinearSpace<*, *>, R> LS.invoke(block: LS.() -> R): R = run(block)
|
||||
|
||||
/**
|
||||
* Gets a feature from the matrix. This function may return some additional features to
|
||||
* [space.kscience.kmath.nd.NDStructure.getFeature].
|
||||
*
|
||||
* @param T the type of items in the matrices.
|
||||
* @param M the type of operated matrices.
|
||||
* @param F the type of feature.
|
||||
* @receiver the [LinearSpace] of [T].
|
||||
* @param m the matrix.
|
||||
* @return a feature object or `null` if it isn't present.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public inline fun <T : Any, reified F : Any> LinearSpace<T, *>.getFeature(m: Matrix<T>): F? = getFeature(m, F::class)
|
||||
|
@ -12,7 +12,7 @@ import space.kscience.kmath.structures.MutableBufferFactory
|
||||
* Common implementation of [LupDecompositionFeature].
|
||||
*/
|
||||
public class LupDecomposition<T : Any>(
|
||||
public val context: MatrixContext<T, Matrix<T>>,
|
||||
public val context: LinearSpace<T, *>,
|
||||
public val elementContext: Field<T>,
|
||||
public val lu: Matrix<T>,
|
||||
public val pivot: IntArray,
|
||||
@ -62,15 +62,14 @@ public class LupDecomposition<T : Any>(
|
||||
}
|
||||
|
||||
@PublishedApi
|
||||
internal fun <T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F, *>.abs(value: T): T =
|
||||
if (value > elementContext.zero) value else elementContext { -value }
|
||||
internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T =
|
||||
if (value > elementAlgebra.zero) value else elementAlgebra { -value }
|
||||
|
||||
/**
|
||||
* Create a lup decomposition of generic matrix.
|
||||
*/
|
||||
public fun <T : Comparable<T>> MatrixContext<T, Matrix<T>>.lup(
|
||||
public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup(
|
||||
factory: MutableBufferFactory<T>,
|
||||
elementContext: Field<T>,
|
||||
matrix: Matrix<T>,
|
||||
checkSingular: (T) -> Boolean,
|
||||
): LupDecomposition<T> {
|
||||
@ -80,7 +79,7 @@ public fun <T : Comparable<T>> MatrixContext<T, Matrix<T>>.lup(
|
||||
|
||||
//TODO just waits for KEEP-176
|
||||
BufferAccessor2D(matrix.rowNum, matrix.colNum, factory).run {
|
||||
elementContext {
|
||||
elementAlgebra {
|
||||
val lu = create(matrix)
|
||||
|
||||
// Initialize permutation array and parity
|
||||
@ -142,18 +141,18 @@ public fun <T : Comparable<T>> MatrixContext<T, Matrix<T>>.lup(
|
||||
for (row in col + 1 until m) lu[row, col] /= luDiag
|
||||
}
|
||||
|
||||
return LupDecomposition(this@lup, elementContext, lu.collect(), pivot, even)
|
||||
return LupDecomposition(this@lup, elementAlgebra, lu.collect(), pivot, even)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F, Matrix<T>>.lup(
|
||||
public inline fun <reified T : Comparable<T>> LinearSpace<T, Field<T>>.lup(
|
||||
matrix: Matrix<T>,
|
||||
noinline checkSingular: (T) -> Boolean,
|
||||
): LupDecomposition<T> = lup(MutableBuffer.Companion::auto, elementContext, matrix, checkSingular)
|
||||
): LupDecomposition<T> = lup(MutableBuffer.Companion::auto, matrix, checkSingular)
|
||||
|
||||
public fun MatrixContext<Double, Matrix<Double>>.lup(matrix: Matrix<Double>): LupDecomposition<Double> =
|
||||
lup(Buffer.Companion::real, RealField, matrix) { it < 1e-11 }
|
||||
public fun LinearSpace<Double, RealField>.lup(matrix: Matrix<Double>): LupDecomposition<Double> =
|
||||
lup(Buffer.Companion::real, matrix) { it < 1e-11 }
|
||||
|
||||
public fun <T : Any> LupDecomposition<T>.solveWithLup(
|
||||
factory: MutableBufferFactory<T>,
|
||||
@ -198,7 +197,7 @@ public fun <T : Any> LupDecomposition<T>.solveWithLup(
|
||||
}
|
||||
}
|
||||
|
||||
return context.produce(pivot.size, matrix.colNum) { i, j -> bp[i, j] }
|
||||
return context.buildMatrix(pivot.size, matrix.colNum) { i, j -> bp[i, j] }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,18 +209,18 @@ public inline fun <reified T : Any> LupDecomposition<T>.solveWithLup(matrix: Mat
|
||||
* Solves a system of linear equations *ax = b** using LUP decomposition.
|
||||
*/
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F, Matrix<T>>.solveWithLup(
|
||||
public inline fun <reified T : Comparable<T>> LinearSpace<T, Field<T>>.solveWithLup(
|
||||
a: Matrix<T>,
|
||||
b: Matrix<T>,
|
||||
noinline bufferFactory: MutableBufferFactory<T> = MutableBuffer.Companion::auto,
|
||||
noinline checkSingular: (T) -> Boolean,
|
||||
): Matrix<T> {
|
||||
// Use existing decomposition if it is provided by matrix
|
||||
val decomposition = a.getFeature() ?: lup(bufferFactory, elementContext, a, checkSingular)
|
||||
val decomposition = a.getFeature() ?: lup(bufferFactory, a, checkSingular)
|
||||
return decomposition.solveWithLup(bufferFactory, b)
|
||||
}
|
||||
|
||||
public inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F, Matrix<T>>.inverseWithLup(
|
||||
public inline fun <reified T : Comparable<T>> LinearSpace<T, Field<T>>.inverseWithLup(
|
||||
matrix: Matrix<T>,
|
||||
noinline bufferFactory: MutableBufferFactory<T> = MutableBuffer.Companion::auto,
|
||||
noinline checkSingular: (T) -> Boolean,
|
||||
@ -229,15 +228,15 @@ public inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext
|
||||
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public fun RealMatrixContext.solveWithLup(a: Matrix<Double>, b: Matrix<Double>): Matrix<Double> {
|
||||
public fun LinearSpace<Double, RealField>.solveWithLup(a: Matrix<Double>, b: Matrix<Double>): Matrix<Double> {
|
||||
// Use existing decomposition if it is provided by matrix
|
||||
val bufferFactory: MutableBufferFactory<Double> = MutableBuffer.Companion::real
|
||||
val decomposition: LupDecomposition<Double> = a.getFeature() ?: lup(bufferFactory, RealField, a) { it < 1e-11 }
|
||||
val decomposition: LupDecomposition<Double> = a.getFeature() ?: lup(bufferFactory, a) { it < 1e-11 }
|
||||
return decomposition.solveWithLup(bufferFactory, b)
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverses a square matrix using LUP decomposition. Non square matrix will throw a error.
|
||||
*/
|
||||
public fun RealMatrixContext.inverseWithLup(matrix: Matrix<Double>): Matrix<Double> =
|
||||
public fun LinearSpace<Double, RealField>.inverseWithLup(matrix: Matrix<Double>): Matrix<Double> =
|
||||
solveWithLup(matrix, one(matrix.rowNum, matrix.colNum))
|
@ -1,46 +1,43 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.Ring
|
||||
|
||||
public class MatrixBuilder(public val rows: Int, public val columns: Int) {
|
||||
public operator fun <T : Any> invoke(vararg elements: T): Matrix<T> {
|
||||
public class MatrixBuilder<T : Any, A : Ring<T>>(
|
||||
public val linearSpace: LinearSpace<T, A>,
|
||||
public val rows: Int,
|
||||
public val columns: Int,
|
||||
) {
|
||||
public operator fun invoke(vararg elements: T): Matrix<T> {
|
||||
require(rows * columns == elements.size) { "The number of elements ${elements.size} is not equal $rows * $columns" }
|
||||
val buffer = elements.asBuffer()
|
||||
return BufferMatrix(rows, columns, buffer)
|
||||
return linearSpace.buildMatrix(rows, columns) { i, j -> elements[i * columns + j] }
|
||||
}
|
||||
|
||||
//TODO add specific matrix builder functions like diagonal, etc
|
||||
}
|
||||
|
||||
public fun Structure2D.Companion.build(rows: Int, columns: Int): MatrixBuilder = MatrixBuilder(rows, columns)
|
||||
/**
|
||||
* Create a matrix builder with given number of rows and columns
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun <T : Any, A : Ring<T>> LinearSpace<T, A>.matrix(rows: Int, columns: Int): MatrixBuilder<T, A> =
|
||||
MatrixBuilder(this, rows, columns)
|
||||
|
||||
public fun <T : Any> Structure2D.Companion.row(vararg values: T): Matrix<T> {
|
||||
val buffer = values.asBuffer()
|
||||
return BufferMatrix(1, values.size, buffer)
|
||||
@UnstableKMathAPI
|
||||
public fun <T : Any> LinearSpace<T, Ring<T>>.vector(vararg elements: T): Point<T> {
|
||||
return buildVector(elements.size) { elements[it] }
|
||||
}
|
||||
|
||||
public inline fun <reified T : Any> Structure2D.Companion.row(
|
||||
public inline fun <T : Any> LinearSpace<T, Ring<T>>.row(
|
||||
size: Int,
|
||||
factory: BufferFactory<T> = Buffer.Companion::auto,
|
||||
noinline builder: (Int) -> T,
|
||||
): Matrix<T> {
|
||||
val buffer = factory(size, builder)
|
||||
return BufferMatrix(1, size, buffer)
|
||||
}
|
||||
crossinline builder: (Int) -> T,
|
||||
): Matrix<T> = buildMatrix(1, size) { _, j -> builder(j) }
|
||||
|
||||
public fun <T : Any> Structure2D.Companion.column(vararg values: T): Matrix<T> {
|
||||
val buffer = values.asBuffer()
|
||||
return BufferMatrix(values.size, 1, buffer)
|
||||
}
|
||||
public fun <T : Any> LinearSpace<T, Ring<T>>.row(vararg values: T): Matrix<T> = row(values.size, values::get)
|
||||
|
||||
public inline fun <reified T : Any> Structure2D.Companion.column(
|
||||
public inline fun <T : Any> LinearSpace<T, Ring<T>>.column(
|
||||
size: Int,
|
||||
factory: BufferFactory<T> = Buffer.Companion::auto,
|
||||
noinline builder: (Int) -> T,
|
||||
): Matrix<T> {
|
||||
val buffer = factory(size, builder)
|
||||
return BufferMatrix(size, 1, buffer)
|
||||
}
|
||||
crossinline builder: (Int) -> T,
|
||||
): Matrix<T> = buildMatrix(size, 1) { i, _ -> builder(i) }
|
||||
|
||||
public fun <T : Any> LinearSpace<T, Ring<T>>.column(vararg values: T): Matrix<T> = column(values.size, values::get)
|
@ -1,173 +0,0 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.*
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
import space.kscience.kmath.structures.asSequence
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* Basic operations on matrices. Operates on [Matrix].
|
||||
*
|
||||
* @param T the type of items in the matrices.
|
||||
* @param M the type of operated matrices.
|
||||
*/
|
||||
public interface MatrixContext<T : Any, out M : Matrix<T>> : GroupOperations<Matrix<T>>, ScaleOperations<Matrix<T>> {
|
||||
/**
|
||||
* Produces a matrix with this context and given dimensions.
|
||||
*/
|
||||
public fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): M
|
||||
|
||||
/**
|
||||
* Produces a point compatible with matrix space (and possibly optimized for it).
|
||||
*/
|
||||
public fun point(size: Int, initializer: (Int) -> T): Point<T> = Buffer.boxing(size, initializer)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
public override fun binaryOperationFunction(operation: String): (left: Matrix<T>, right: Matrix<T>) -> M =
|
||||
when (operation) {
|
||||
"dot" -> { left, right -> left dot right }
|
||||
else -> super<GroupOperations>.binaryOperationFunction(operation) as (Matrix<T>, Matrix<T>) -> M
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the dot product of this matrix and another one.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param other the multiplier.
|
||||
* @return the dot product.
|
||||
*/
|
||||
public infix fun Matrix<T>.dot(other: Matrix<T>): M
|
||||
|
||||
/**
|
||||
* Computes the dot product of this matrix and a vector.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param vector the multiplier.
|
||||
* @return the dot product.
|
||||
*/
|
||||
public infix fun Matrix<T>.dot(vector: Point<T>): Point<T>
|
||||
|
||||
/**
|
||||
* Multiplies a matrix by its element.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param value the multiplier.
|
||||
* @receiver the product.
|
||||
*/
|
||||
public operator fun Matrix<T>.times(value: T): M
|
||||
|
||||
/**
|
||||
* Multiplies an element by a matrix of it.
|
||||
*
|
||||
* @receiver the multiplicand.
|
||||
* @param m the multiplier.
|
||||
* @receiver the product.
|
||||
*/
|
||||
public operator fun T.times(m: Matrix<T>): M = m * this
|
||||
|
||||
/**
|
||||
* Gets a feature from the matrix. This function may return some additional features to
|
||||
* [kscience.kmath.nd.NDStructure.getFeature].
|
||||
*
|
||||
* @param F the type of feature.
|
||||
* @param m the matrix.
|
||||
* @param type the [KClass] instance of [F].
|
||||
* @return a feature object or `null` if it isn't present.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun <F : Any> getFeature(m: Matrix<T>, type: KClass<F>): F? = m.getFeature(type)
|
||||
|
||||
public companion object {
|
||||
|
||||
/**
|
||||
* A structured matrix with custom buffer
|
||||
*/
|
||||
public fun <T : Any, A> buffered(
|
||||
ring: A,
|
||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
||||
): GenericMatrixContext<T, A, BufferMatrix<T>> where A : Ring<T>, A: ScaleOperations<T> = BufferMatrixContext(ring, bufferFactory)
|
||||
|
||||
/**
|
||||
* Automatic buffered matrix, unboxed if it is possible
|
||||
*/
|
||||
public inline fun <reified T : Any, A> auto(ring: A): GenericMatrixContext<T, A, BufferMatrix<T>> where A : Ring<T>, A: ScaleOperations<T> =
|
||||
buffered(ring, Buffer.Companion::auto)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a feature from the matrix. This function may return some additional features to
|
||||
* [kscience.kmath.nd.NDStructure.getFeature].
|
||||
*
|
||||
* @param T the type of items in the matrices.
|
||||
* @param M the type of operated matrices.
|
||||
* @param F the type of feature.
|
||||
* @receiver the [MatrixContext] of [T].
|
||||
* @param m the matrix.
|
||||
* @return a feature object or `null` if it isn't present.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public inline fun <T : Any, reified F : Any> MatrixContext<T, *>.getFeature(m: Matrix<T>): F? =
|
||||
getFeature(m, F::class)
|
||||
|
||||
/**
|
||||
* Partial implementation of [MatrixContext] for matrices of [Ring].
|
||||
*
|
||||
* @param T the type of items in the matrices.
|
||||
* @param A the type of ring of matrix elements.
|
||||
* @param M the type of operated matrices.
|
||||
*/
|
||||
public interface GenericMatrixContext<T : Any, A, out M : Matrix<T>> : MatrixContext<T, M> where A : Ring<T>, A : ScaleOperations<T>{
|
||||
/**
|
||||
* The ring over matrix elements.
|
||||
*/
|
||||
public val elementContext: A
|
||||
|
||||
public override infix fun Matrix<T>.dot(other: Matrix<T>): M {
|
||||
//TODO add typed error
|
||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||
|
||||
return produce(rowNum, other.colNum) { i, j ->
|
||||
val row = rows[i]
|
||||
val column = other.columns[j]
|
||||
elementContext { sum(row.asSequence().zip(column.asSequence(), ::multiply)) }
|
||||
}
|
||||
}
|
||||
|
||||
public override infix fun Matrix<T>.dot(vector: Point<T>): Point<T> {
|
||||
//TODO add typed error
|
||||
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
||||
|
||||
return point(rowNum) { i ->
|
||||
val row = rows[i]
|
||||
elementContext { sum(row.asSequence().zip(vector.asSequence(), ::multiply)) }
|
||||
}
|
||||
}
|
||||
|
||||
public override operator fun Matrix<T>.unaryMinus(): M =
|
||||
produce(rowNum, colNum) { i, j -> elementContext { -get(i, j) } }
|
||||
|
||||
public override fun add(a: Matrix<T>, b: Matrix<T>): M {
|
||||
require(a.rowNum == b.rowNum && a.colNum == b.colNum) {
|
||||
"Matrix operation dimension mismatch. [${a.rowNum},${a.colNum}] + [${b.rowNum},${b.colNum}]"
|
||||
}
|
||||
|
||||
return produce(a.rowNum, a.colNum) { i, j -> elementContext { a[i, j] + b[i, j] } }
|
||||
}
|
||||
|
||||
public override operator fun Matrix<T>.minus(b: Matrix<T>): M {
|
||||
require(rowNum == b.rowNum && colNum == b.colNum) {
|
||||
"Matrix operation dimension mismatch. [$rowNum,$colNum] - [${b.rowNum},${b.colNum}]"
|
||||
}
|
||||
|
||||
return produce(rowNum, colNum) { i, j -> elementContext { get(i, j) + b[i, j] } }
|
||||
}
|
||||
//
|
||||
// public override fun multiply(a: Matrix<T>, k: Number): M =
|
||||
// produce(a.rowNum, a.colNum) { i, j -> elementContext { a[i, j] * k } }
|
||||
|
||||
public override operator fun Matrix<T>.times(value: T): M =
|
||||
produce(rowNum, colNum) { i, j -> elementContext { get(i, j) * value } }
|
||||
}
|
@ -1,14 +1,9 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.nd.getFeature
|
||||
import space.kscience.kmath.operations.Ring
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.safeCast
|
||||
|
||||
/**
|
||||
* A [Matrix] that holds [MatrixFeature] objects.
|
||||
@ -24,7 +19,8 @@ public class MatrixWrapper<T : Any> internal constructor(
|
||||
* Get the first feature matching given class. Does not guarantee that matrix has only one feature matching the criteria
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
override fun <T : Any> getFeature(type: KClass<T>): T? = type.safeCast(features.find { type.isInstance(it) })
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <T : Any> getFeature(type: KClass<T>): T? = features.singleOrNull { type.isInstance(it) } as? T
|
||||
?: origin.getFeature(type)
|
||||
|
||||
override fun equals(other: Any?): Boolean = origin == other
|
||||
@ -61,35 +57,25 @@ public operator fun <T : Any> Matrix<T>.plus(newFeatures: Collection<MatrixFeatu
|
||||
MatrixWrapper(this, newFeatures.toSet())
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a square matrix from given elements.
|
||||
*/
|
||||
public fun <T : Any> Structure2D.Companion.square(vararg elements: T): Matrix<T> {
|
||||
val size: Int = sqrt(elements.size.toDouble()).toInt()
|
||||
require(size * size == elements.size) { "The number of elements ${elements.size} is not a full square" }
|
||||
val buffer = elements.asBuffer()
|
||||
return BufferMatrix(size, size, buffer)
|
||||
}
|
||||
|
||||
/**
|
||||
* Diagonal matrix of ones. The matrix is virtual no actual matrix is created
|
||||
*/
|
||||
public fun <T : Any, A> GenericMatrixContext<T, A, *>.one(
|
||||
public fun <T : Any> LinearSpace<T, Ring<T>>.one(
|
||||
rows: Int,
|
||||
columns: Int,
|
||||
): Matrix<T> where A : Ring<T>, A : ScaleOperations<T> = VirtualMatrix(rows, columns) { i, j ->
|
||||
if (i == j) elementContext.one else elementContext.zero
|
||||
): Matrix<T> = VirtualMatrix(rows, columns) { i, j ->
|
||||
if (i == j) elementAlgebra.one else elementAlgebra.zero
|
||||
} + UnitFeature
|
||||
|
||||
|
||||
/**
|
||||
* A virtual matrix of zeroes
|
||||
*/
|
||||
public fun <T : Any, A> GenericMatrixContext<T, A, *>.zero(
|
||||
public fun <T : Any> LinearSpace<T, Ring<T>>.zero(
|
||||
rows: Int,
|
||||
columns: Int,
|
||||
): Matrix<T> where A : Ring<T>, A : ScaleOperations<T> = VirtualMatrix(rows, columns) { _, _ ->
|
||||
elementContext.zero
|
||||
): Matrix<T> = VirtualMatrix(rows, columns) { _, _ ->
|
||||
elementAlgebra.zero
|
||||
} + ZeroFeature
|
||||
|
||||
public class TransposedFeature<T : Any>(public val original: Matrix<T>) : MatrixFeature
|
||||
|
@ -1,85 +0,0 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.structures.RealBuffer
|
||||
|
||||
public object RealMatrixContext : MatrixContext<Double, BufferMatrix<Double>>, ScaleOperations<Matrix<Double>> {
|
||||
|
||||
public override fun produce(
|
||||
rows: Int,
|
||||
columns: Int,
|
||||
initializer: (i: Int, j: Int) -> Double,
|
||||
): BufferMatrix<Double> {
|
||||
val buffer = RealBuffer(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
|
||||
return BufferMatrix(rows, columns, buffer)
|
||||
}
|
||||
|
||||
public fun Matrix<Double>.toBufferMatrix(): BufferMatrix<Double> = if (this is BufferMatrix) this else {
|
||||
produce(rowNum, colNum) { i, j -> get(i, j) }
|
||||
}
|
||||
|
||||
public fun one(rows: Int, columns: Int): Matrix<Double> = VirtualMatrix(rows, columns) { i, j ->
|
||||
if (i == j) 1.0 else 0.0
|
||||
} + DiagonalFeature
|
||||
|
||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = produce(rowNum, colNum) { i, j -> -get(i, j) }
|
||||
|
||||
public override infix fun Matrix<Double>.dot(other: Matrix<Double>): BufferMatrix<Double> {
|
||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||
val bufferMatrix = toBufferMatrix()
|
||||
val otherBufferMatrix = other.toBufferMatrix()
|
||||
return produce(rowNum, other.colNum) { i, j ->
|
||||
var res = 0.0
|
||||
for (l in 0 until colNum) {
|
||||
res += bufferMatrix[i, l] * otherBufferMatrix[l, j]
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
public override infix fun Matrix<Double>.dot(vector: Point<Double>): Point<Double> {
|
||||
require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
|
||||
val bufferMatrix = toBufferMatrix()
|
||||
return RealBuffer(rowNum) { i ->
|
||||
var res = 0.0
|
||||
for (j in 0 until colNum) {
|
||||
res += bufferMatrix[i, j] * vector[j]
|
||||
}
|
||||
res
|
||||
}
|
||||
}
|
||||
|
||||
override fun add(a: Matrix<Double>, b: Matrix<Double>): BufferMatrix<Double> {
|
||||
require(a.rowNum == b.rowNum) { "Row number mismatch in matrix addition. Left side: ${a.rowNum}, right side: ${b.rowNum}" }
|
||||
require(a.colNum == b.colNum) { "Column number mismatch in matrix addition. Left side: ${a.colNum}, right side: ${b.colNum}" }
|
||||
val aBufferMatrix = a.toBufferMatrix()
|
||||
val bBufferMatrix = b.toBufferMatrix()
|
||||
return produce(a.rowNum, a.colNum) { i, j ->
|
||||
aBufferMatrix[i, j] + bBufferMatrix[i, j]
|
||||
}
|
||||
}
|
||||
|
||||
override fun scale(a: Matrix<Double>, value: Double): BufferMatrix<Double> {
|
||||
val bufferMatrix = a.toBufferMatrix()
|
||||
return produce(a.rowNum, a.colNum) { i, j -> bufferMatrix[i, j] * value }
|
||||
}
|
||||
|
||||
override fun Matrix<Double>.times(value: Double): BufferMatrix<Double> = scale(this, value)
|
||||
|
||||
//
|
||||
// override fun multiply(a: Matrix<Double>, k: Number): BufferMatrix<Double> {
|
||||
// val aBufferMatrix = a.toBufferMatrix()
|
||||
// return produce(a.rowNum, a.colNum) { i, j -> aBufferMatrix[i, j] * k.toDouble() }
|
||||
// }
|
||||
//
|
||||
// override fun divide(a: Matrix<Double>, k: Number): BufferMatrix<Double> {
|
||||
// val aBufferMatrix = a.toBufferMatrix()
|
||||
// return produce(a.rowNum, a.colNum) { i, j -> aBufferMatrix[i, j] / k.toDouble() }
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Partially optimized real-valued matrix
|
||||
*/
|
||||
public val MatrixContext.Companion.real: RealMatrixContext get() = RealMatrixContext
|
@ -1,72 +0,0 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.operations.Group
|
||||
import space.kscience.kmath.operations.RealField
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.BufferFactory
|
||||
|
||||
/**
|
||||
* A linear space for vectors.
|
||||
* Could be used on any point-like structure
|
||||
*/
|
||||
public interface VectorSpace<T : Any, A> : Group<Point<T>>, ScaleOperations<Point<T>>
|
||||
where A : Group<T>, A : ScaleOperations<T> {
|
||||
public val size: Int
|
||||
public val algebra: A
|
||||
override val zero: Point<T> get() = produce { algebra.zero }
|
||||
|
||||
public fun produce(initializer: A.(Int) -> T): Point<T>
|
||||
|
||||
override fun add(a: Point<T>, b: Point<T>): Point<T> = produce { algebra { a[it] + b[it] } }
|
||||
|
||||
override fun scale(a: Point<T>, value: Double): Point<T> = produce { algebra.scale(a[it], value) }
|
||||
|
||||
override fun Point<T>.unaryMinus(): Point<T> = produce { -get(it) }
|
||||
|
||||
//TODO add basis
|
||||
|
||||
public companion object {
|
||||
private val realSpaceCache: MutableMap<Int, BufferVectorSpace<Double, RealField>> = hashMapOf()
|
||||
|
||||
/**
|
||||
* Non-boxing double vector space
|
||||
*/
|
||||
public fun real(size: Int): BufferVectorSpace<Double, RealField> = realSpaceCache.getOrPut(size) {
|
||||
BufferVectorSpace(
|
||||
size,
|
||||
RealField,
|
||||
Buffer.Companion::auto
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A structured vector space with custom buffer
|
||||
*/
|
||||
public fun <T : Any, A> buffered(
|
||||
size: Int,
|
||||
space: A,
|
||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
||||
): BufferVectorSpace<T, A> where A : Group<T>, A : ScaleOperations<T> =
|
||||
BufferVectorSpace(size, space, bufferFactory)
|
||||
|
||||
/**
|
||||
* Automatic buffered vector, unboxed if it is possible
|
||||
*/
|
||||
public inline fun <reified T : Any, A> auto(
|
||||
size: Int,
|
||||
space: A,
|
||||
): VectorSpace<T, A> where A : Group<T>, A : ScaleOperations<T> =
|
||||
buffered(size, space, Buffer.Companion::auto)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class BufferVectorSpace<T : Any, A>(
|
||||
override val size: Int,
|
||||
override val algebra: A,
|
||||
public val bufferFactory: BufferFactory<T>,
|
||||
) : VectorSpace<T, A> where A : Group<T>, A : ScaleOperations<T> {
|
||||
override fun produce(initializer: A.(Int) -> T): Buffer<T> = bufferFactory(size) { algebra.initializer(it) }
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.nd.NDStructure
|
||||
|
||||
/**
|
||||
* The matrix where each element is evaluated each time when is being accessed.
|
||||
*
|
||||
@ -17,12 +19,8 @@ public class VirtualMatrix<T : Any>(
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is Matrix<*>) return false
|
||||
|
||||
if (rowNum != other.rowNum) return false
|
||||
if (colNum != other.colNum) return false
|
||||
|
||||
return elements().all { (index, value) -> value == other[index] }
|
||||
if (other !is NDStructure<*>) return false
|
||||
return NDStructure.contentEquals(this, other)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
@ -31,6 +29,4 @@ public class VirtualMatrix<T : Any>(
|
||||
result = 31 * result + generator.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -79,20 +79,20 @@ public open class BufferedNDField<T, R : Field<T>>(
|
||||
override fun scale(a: NDStructure<T>, value: Double): NDStructure<T> = a.map { it * value }
|
||||
}
|
||||
|
||||
// space factories
|
||||
public fun <T, A : Group<T>> NDAlgebra.Companion.space(
|
||||
// group factories
|
||||
public fun <T, A : Group<T>> NDAlgebra.Companion.group(
|
||||
space: A,
|
||||
bufferFactory: BufferFactory<T>,
|
||||
vararg shape: Int,
|
||||
): BufferedNDGroup<T, A> = BufferedNDGroup(shape, space, bufferFactory)
|
||||
|
||||
public inline fun <T, A : Group<T>, R> A.ndSpace(
|
||||
public inline fun <T, A : Group<T>, R> A.ndGroup(
|
||||
noinline bufferFactory: BufferFactory<T>,
|
||||
vararg shape: Int,
|
||||
action: BufferedNDGroup<T, A>.() -> R,
|
||||
): R {
|
||||
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
|
||||
return NDAlgebra.space(this, bufferFactory, *shape).run(action)
|
||||
return NDAlgebra.group(this, bufferFactory, *shape).run(action)
|
||||
}
|
||||
|
||||
//ring factories
|
||||
|
@ -52,7 +52,7 @@ public interface NDStructure<T> {
|
||||
* optimize operations and performance. If the feature is not present, null is defined.
|
||||
*/
|
||||
@UnstableKMathAPI
|
||||
public fun <T : Any> getFeature(type: KClass<T>): T? = null
|
||||
public fun <F : Any> getFeature(type: KClass<F>): F? = null
|
||||
|
||||
public companion object {
|
||||
/**
|
||||
@ -74,7 +74,7 @@ public interface NDStructure<T> {
|
||||
*
|
||||
* Strides should be reused if possible.
|
||||
*/
|
||||
public fun <T> build(
|
||||
public fun <T> buffered(
|
||||
strides: Strides,
|
||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
||||
initializer: (IntArray) -> T,
|
||||
@ -94,11 +94,11 @@ public interface NDStructure<T> {
|
||||
crossinline initializer: (IntArray) -> T,
|
||||
): NDBuffer<T> = NDBuffer(strides, Buffer.auto(type, strides.linearSize) { i -> initializer(strides.index(i)) })
|
||||
|
||||
public fun <T> build(
|
||||
public fun <T> buffered(
|
||||
shape: IntArray,
|
||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
|
||||
initializer: (IntArray) -> T,
|
||||
): NDBuffer<T> = build(DefaultStrides(shape), bufferFactory, initializer)
|
||||
): NDBuffer<T> = buffered(DefaultStrides(shape), bufferFactory, initializer)
|
||||
|
||||
public inline fun <reified T : Any> auto(
|
||||
shape: IntArray,
|
||||
|
@ -45,10 +45,12 @@ private inline class Buffer1DWrapper<T>(val buffer: Buffer<T>) : Structure1D<T>
|
||||
/**
|
||||
* Represent a [NDStructure] as [Structure1D]. Throw error in case of dimension mismatch
|
||||
*/
|
||||
public fun <T> NDStructure<T>.as1D(): Structure1D<T> = if (shape.size == 1) {
|
||||
if (this is NDBuffer) Buffer1DWrapper(this.buffer) else Structure1DWrapper(this)
|
||||
} else
|
||||
error("Can't create 1d-structure from ${shape.size}d-structure")
|
||||
public fun <T> NDStructure<T>.as1D(): Structure1D<T> = this as? Structure1D<T> ?: if (shape.size == 1) {
|
||||
when (this) {
|
||||
is NDBuffer -> Buffer1DWrapper(this.buffer)
|
||||
else -> Structure1DWrapper(this)
|
||||
}
|
||||
} else error("Can't create 1d-structure from ${shape.size}d-structure")
|
||||
|
||||
/**
|
||||
* Represent this buffer as 1D structure
|
||||
|
@ -1,9 +1,9 @@
|
||||
package space.kscience.kmath.nd
|
||||
|
||||
import space.kscience.kmath.linear.BufferMatrix
|
||||
import space.kscience.kmath.linear.RealMatrixContext
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.VirtualBuffer
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
/**
|
||||
* A structure that is guaranteed to be two-dimensional.
|
||||
@ -26,14 +26,14 @@ public interface Structure2D<T> : NDStructure<T> {
|
||||
/**
|
||||
* The buffer of rows of this structure. It gets elements from the structure dynamically.
|
||||
*/
|
||||
public val rows: Buffer<Buffer<T>>
|
||||
get() = VirtualBuffer(rowNum) { i -> VirtualBuffer(colNum) { j -> get(i, j) } }
|
||||
public val rows: List<Buffer<T>>
|
||||
get() = List(rowNum) { i -> VirtualBuffer(colNum) { j -> get(i, j) } }
|
||||
|
||||
/**
|
||||
* The buffer of columns of this structure. It gets elements from the structure dynamically.
|
||||
*/
|
||||
public val columns: Buffer<Buffer<T>>
|
||||
get() = VirtualBuffer(colNum) { j -> VirtualBuffer(rowNum) { i -> get(i, j) } }
|
||||
public val columns: List<Buffer<T>>
|
||||
get() = List(colNum) { j -> VirtualBuffer(rowNum) { i -> get(i, j) } }
|
||||
|
||||
/**
|
||||
* Retrieves an element from the structure by two indices.
|
||||
@ -54,21 +54,13 @@ public interface Structure2D<T> : NDStructure<T> {
|
||||
for (j in 0 until colNum) yield(intArrayOf(i, j) to get(i, j))
|
||||
}
|
||||
|
||||
public companion object {
|
||||
public inline fun real(
|
||||
rows: Int,
|
||||
columns: Int,
|
||||
crossinline init: (i: Int, j: Int) -> Double,
|
||||
): BufferMatrix<Double> = RealMatrixContext.produce(rows,columns) { i, j ->
|
||||
init(i, j)
|
||||
}
|
||||
}
|
||||
public companion object
|
||||
}
|
||||
|
||||
/**
|
||||
* A 2D wrapper for nd-structure
|
||||
*/
|
||||
private inline class Structure2DWrapper<T>(val structure: NDStructure<T>) : Structure2D<T> {
|
||||
private class Structure2DWrapper<T>(val structure: NDStructure<T>) : Structure2D<T> {
|
||||
override val shape: IntArray get() = structure.shape
|
||||
|
||||
override val rowNum: Int get() = shape[0]
|
||||
@ -76,20 +68,22 @@ private inline class Structure2DWrapper<T>(val structure: NDStructure<T>) : Stru
|
||||
|
||||
override operator fun get(i: Int, j: Int): T = structure[i, j]
|
||||
|
||||
@UnstableKMathAPI
|
||||
override fun <F : Any> getFeature(type: KClass<F>): F? = structure.getFeature(type)
|
||||
|
||||
override fun elements(): Sequence<Pair<IntArray, T>> = structure.elements()
|
||||
|
||||
override fun equals(other: Any?): Boolean = structure == other
|
||||
|
||||
override fun hashCode(): Int = structure.hashCode()
|
||||
}
|
||||
|
||||
/**
|
||||
* Represent a [NDStructure] as [Structure1D]. Throw error in case of dimension mismatch
|
||||
*/
|
||||
public fun <T> NDStructure<T>.as2D(): Structure2D<T> = if (shape.size == 2)
|
||||
Structure2DWrapper(this)
|
||||
else
|
||||
error("Can't create 2d-structure from ${shape.size}d-structure")
|
||||
public fun <T> NDStructure<T>.as2D(): Structure2D<T> = this as? Structure2D<T> ?: when (shape.size) {
|
||||
2 -> Structure2DWrapper(this)
|
||||
else -> error("Can't create 2d-structure from ${shape.size}d-structure")
|
||||
}
|
||||
|
||||
/**
|
||||
* Alias for [Structure2D] with more familiar name.
|
||||
*
|
||||
* @param T the type of items in the matrix.
|
||||
*/
|
||||
public typealias Matrix<T> = Structure2D<T>
|
||||
internal fun <T> Structure2D<T>.unwrap(): NDStructure<T> = if (this is Structure2DWrapper) structure else this
|
@ -13,10 +13,10 @@ internal class BufferAccessor2D<T : Any>(
|
||||
public val colNum: Int,
|
||||
val factory: MutableBufferFactory<T>,
|
||||
) {
|
||||
public operator fun Buffer<T>.get(i: Int, j: Int): T = get(i + colNum * j)
|
||||
public operator fun Buffer<T>.get(i: Int, j: Int): T = get(i*colNum + j)
|
||||
|
||||
public operator fun MutableBuffer<T>.set(i: Int, j: Int, value: T) {
|
||||
set(i + colNum * j, value)
|
||||
set(i*colNum + j, value)
|
||||
}
|
||||
|
||||
public inline fun create(crossinline init: (i: Int, j: Int) -> T): MutableBuffer<T> =
|
||||
@ -25,7 +25,7 @@ internal class BufferAccessor2D<T : Any>(
|
||||
public fun create(mat: Structure2D<T>): MutableBuffer<T> = create { i, j -> mat[i, j] }
|
||||
|
||||
//TODO optimize wrapper
|
||||
public fun MutableBuffer<T>.collect(): Structure2D<T> = NDStructure.build(
|
||||
public fun MutableBuffer<T>.collect(): Structure2D<T> = NDStructure.buffered(
|
||||
DefaultStrides(intArrayOf(rowNum, colNum)),
|
||||
factory
|
||||
) { (i, j) ->
|
||||
|
@ -0,0 +1,7 @@
|
||||
package space.kscience.kmath.structures
|
||||
|
||||
|
||||
public inline fun <T : Any, reified R : Any> Buffer<T>.map(
|
||||
bufferFactory: BufferFactory<R> = Buffer.Companion::auto,
|
||||
crossinline block: (T) -> R,
|
||||
): Buffer<R> = bufferFactory(size) { block(get(it)) }
|
@ -1,23 +1,24 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.nd.NDStructure
|
||||
import space.kscience.kmath.nd.as2D
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@UnstableKMathAPI
|
||||
@Suppress("UNUSED_VARIABLE")
|
||||
class MatrixTest {
|
||||
@Test
|
||||
fun testTranspose() {
|
||||
val matrix = MatrixContext.real.one(3, 3)
|
||||
val matrix = LinearSpace.real.one(3, 3)
|
||||
val transposed = matrix.transpose()
|
||||
assertEquals(matrix, transposed)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testBuilder() {
|
||||
val matrix = Matrix.build(2, 3)(
|
||||
val matrix = LinearSpace.real.matrix(2, 3)(
|
||||
1.0, 0.0, 0.0,
|
||||
0.0, 1.0, 2.0
|
||||
)
|
||||
@ -39,7 +40,7 @@ class MatrixTest {
|
||||
infix fun Matrix<Double>.pow(power: Int): Matrix<Double> {
|
||||
var res = this
|
||||
repeat(power - 1) {
|
||||
res = RealMatrixContext.invoke { res dot this@pow }
|
||||
res = LinearSpace.real.run { res dot this@pow }
|
||||
}
|
||||
return res
|
||||
}
|
||||
@ -52,7 +53,7 @@ class MatrixTest {
|
||||
val firstMatrix = NDStructure.auto(2, 3) { (i, j) -> (i + j).toDouble() }.as2D()
|
||||
val secondMatrix = NDStructure.auto(3, 2) { (i, j) -> (i + j).toDouble() }.as2D()
|
||||
|
||||
MatrixContext.real.run {
|
||||
LinearSpace.real.run {
|
||||
// val firstMatrix = produce(2, 3) { i, j -> (i + j).toDouble() }
|
||||
// val secondMatrix = produce(3, 2) { i, j -> (i + j).toDouble() }
|
||||
val result = firstMatrix dot secondMatrix
|
||||
|
@ -1,29 +1,31 @@
|
||||
package space.kscience.kmath.linear
|
||||
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@UnstableKMathAPI
|
||||
class RealLUSolverTest {
|
||||
|
||||
@Test
|
||||
fun testInvertOne() {
|
||||
val matrix = MatrixContext.real.one(2, 2)
|
||||
val inverted = MatrixContext.real.inverseWithLup(matrix)
|
||||
val matrix = LinearSpace.real.one(2, 2)
|
||||
val inverted = LinearSpace.real.inverseWithLup(matrix)
|
||||
assertEquals(matrix, inverted)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDecomposition() {
|
||||
val matrix = Matrix.square(
|
||||
3.0, 1.0,
|
||||
1.0, 3.0
|
||||
)
|
||||
LinearSpace.real.run {
|
||||
val matrix = matrix(2,2)(
|
||||
3.0, 1.0,
|
||||
2.0, 3.0
|
||||
)
|
||||
|
||||
MatrixContext.real.run {
|
||||
val lup = lup(matrix)
|
||||
|
||||
//Check determinant
|
||||
assertEquals(8.0, lup.determinant)
|
||||
assertEquals(7.0, lup.determinant)
|
||||
|
||||
assertEquals(lup.p dot matrix, lup.l dot lup.u)
|
||||
}
|
||||
@ -31,14 +33,14 @@ class RealLUSolverTest {
|
||||
|
||||
@Test
|
||||
fun testInvert() {
|
||||
val matrix = Matrix.square(
|
||||
val matrix = LinearSpace.real.matrix(2,2)(
|
||||
3.0, 1.0,
|
||||
1.0, 3.0
|
||||
)
|
||||
|
||||
val inverted = MatrixContext.real.inverseWithLup(matrix)
|
||||
val inverted = LinearSpace.real.inverseWithLup(matrix)
|
||||
|
||||
val expected = Matrix.square(
|
||||
val expected = LinearSpace.real.matrix(2,2)(
|
||||
0.375, -0.125,
|
||||
-0.125, 0.375
|
||||
)
|
||||
|
@ -1,5 +1,6 @@
|
||||
package space.kscience.kmath.structures
|
||||
|
||||
import space.kscience.kmath.linear.LinearSpace
|
||||
import space.kscience.kmath.nd.*
|
||||
import space.kscience.kmath.operations.Norm
|
||||
import space.kscience.kmath.operations.invoke
|
||||
@ -33,7 +34,9 @@ class NumberNDFieldTest {
|
||||
@Test
|
||||
fun testGeneration() {
|
||||
|
||||
val array = Structure2D.real(3, 3) { i, j -> (i * 10 + j).toDouble() }
|
||||
val array = LinearSpace.real.buildMatrix(3, 3) { i, j ->
|
||||
(i * 10 + j).toDouble()
|
||||
}
|
||||
|
||||
for (i in 0..2) {
|
||||
for (j in 0..2) {
|
||||
|
@ -2,7 +2,8 @@ package space.kscience.kmath.dimensions
|
||||
|
||||
import space.kscience.kmath.linear.*
|
||||
import space.kscience.kmath.nd.Structure2D
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.operations.RealField
|
||||
import space.kscience.kmath.operations.Ring
|
||||
|
||||
/**
|
||||
* A matrix with compile-time controlled dimension
|
||||
@ -77,7 +78,7 @@ public inline class DPointWrapper<T, D : Dimension>(public val point: Point<T>)
|
||||
/**
|
||||
* Basic operations on dimension-safe matrices. Operates on [Matrix]
|
||||
*/
|
||||
public inline class DMatrixContext<T : Any>(public val context: MatrixContext<T, Matrix<T>>) {
|
||||
public inline class DMatrixContext<T : Any, out A : Ring<T>>(public val context: LinearSpace<T, A>) {
|
||||
public inline fun <reified R : Dimension, reified C : Dimension> Matrix<T>.coerce(): DMatrix<T, R, C> {
|
||||
require(rowNum == Dimension.dim<R>().toInt()) {
|
||||
"Row number mismatch: expected ${Dimension.dim<R>()} but found $rowNum"
|
||||
@ -93,17 +94,19 @@ public inline class DMatrixContext<T : Any>(public val context: MatrixContext<T,
|
||||
/**
|
||||
* Produce a matrix with this context and given dimensions
|
||||
*/
|
||||
public inline fun <reified R : Dimension, reified C : Dimension> produce(noinline initializer: (i: Int, j: Int) -> T): DMatrix<T, R, C> {
|
||||
public inline fun <reified R : Dimension, reified C : Dimension> produce(
|
||||
noinline initializer: A.(i: Int, j: Int) -> T
|
||||
): DMatrix<T, R, C> {
|
||||
val rows = Dimension.dim<R>()
|
||||
val cols = Dimension.dim<C>()
|
||||
return context.produce(rows.toInt(), cols.toInt(), initializer).coerce<R, C>()
|
||||
return context.buildMatrix(rows.toInt(), cols.toInt(), initializer).coerce<R, C>()
|
||||
}
|
||||
|
||||
public inline fun <reified D : Dimension> point(noinline initializer: (Int) -> T): DPoint<T, D> {
|
||||
public inline fun <reified D : Dimension> point(noinline initializer: A.(Int) -> T): DPoint<T, D> {
|
||||
val size = Dimension.dim<D>()
|
||||
|
||||
return DPoint.coerceUnsafe(
|
||||
context.point(
|
||||
context.buildVector(
|
||||
size.toInt(),
|
||||
initializer
|
||||
)
|
||||
@ -112,31 +115,31 @@ public inline class DMatrixContext<T : Any>(public val context: MatrixContext<T,
|
||||
|
||||
public inline infix fun <reified R1 : Dimension, reified C1 : Dimension, reified C2 : Dimension> DMatrix<T, R1, C1>.dot(
|
||||
other: DMatrix<T, C1, C2>,
|
||||
): DMatrix<T, R1, C2> = context { this@dot dot other }.coerce()
|
||||
): DMatrix<T, R1, C2> = context.run { this@dot dot other }.coerce()
|
||||
|
||||
public inline infix fun <reified R : Dimension, reified C : Dimension> DMatrix<T, R, C>.dot(vector: DPoint<T, C>): DPoint<T, R> =
|
||||
DPoint.coerceUnsafe(context { this@dot dot vector })
|
||||
DPoint.coerceUnsafe(context.run { this@dot dot vector })
|
||||
|
||||
public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, R, C>.times(value: T): DMatrix<T, R, C> =
|
||||
context { this@times.times(value) }.coerce()
|
||||
context.run { this@times.times(value) }.coerce()
|
||||
|
||||
public inline operator fun <reified R : Dimension, reified C : Dimension> T.times(m: DMatrix<T, R, C>): DMatrix<T, R, C> =
|
||||
m * this
|
||||
|
||||
public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.plus(other: DMatrix<T, C, R>): DMatrix<T, C, R> =
|
||||
context { this@plus + other }.coerce()
|
||||
context.run { this@plus + other }.coerce()
|
||||
|
||||
public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.minus(other: DMatrix<T, C, R>): DMatrix<T, C, R> =
|
||||
context { this@minus + other }.coerce()
|
||||
context.run { this@minus + other }.coerce()
|
||||
|
||||
public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.unaryMinus(): DMatrix<T, C, R> =
|
||||
context { this@unaryMinus.unaryMinus() }.coerce()
|
||||
context.run { this@unaryMinus.unaryMinus() }.coerce()
|
||||
|
||||
public inline fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.transpose(): DMatrix<T, R, C> =
|
||||
context { (this@transpose as Matrix<T>).transpose() }.coerce()
|
||||
context.run { (this@transpose as Matrix<T>).transpose() }.coerce()
|
||||
|
||||
public companion object {
|
||||
public val real: DMatrixContext<Double> = DMatrixContext(MatrixContext.real)
|
||||
public val real: DMatrixContext<Double, RealField> = DMatrixContext(LinearSpace.real)
|
||||
}
|
||||
}
|
||||
|
||||
@ -144,11 +147,11 @@ public inline class DMatrixContext<T : Any>(public val context: MatrixContext<T,
|
||||
/**
|
||||
* A square unit matrix
|
||||
*/
|
||||
public inline fun <reified D : Dimension> DMatrixContext<Double>.one(): DMatrix<Double, D, D> = produce { i, j ->
|
||||
public inline fun <reified D : Dimension> DMatrixContext<Double, RealField>.one(): DMatrix<Double, D, D> = produce { i, j ->
|
||||
if (i == j) 1.0 else 0.0
|
||||
}
|
||||
|
||||
public inline fun <reified R : Dimension, reified C : Dimension> DMatrixContext<Double>.zero(): DMatrix<Double, R, C> =
|
||||
public inline fun <reified R : Dimension, reified C : Dimension> DMatrixContext<Double, RealField>.zero(): DMatrix<Double, R, C> =
|
||||
produce { _, _ ->
|
||||
0.0
|
||||
}
|
@ -0,0 +1,113 @@
|
||||
package space.kscience.kmath.ejml
|
||||
|
||||
import org.ejml.simple.SimpleMatrix
|
||||
import space.kscience.kmath.linear.*
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.nd.getFeature
|
||||
import space.kscience.kmath.operations.RealField
|
||||
|
||||
/**
|
||||
* Represents context of basic operations operating with [EjmlMatrix].
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
public object EjmlLinearSpace : LinearSpace<Double, RealField> {
|
||||
|
||||
override val elementAlgebra: RealField get() = RealField
|
||||
|
||||
/**
|
||||
* Converts this matrix to EJML one.
|
||||
*/
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public fun Matrix<Double>.toEjml(): EjmlMatrix = when (val matrix = origin) {
|
||||
is EjmlMatrix -> matrix
|
||||
else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this vector to EJML one.
|
||||
*/
|
||||
public fun Point<Double>.toEjml(): EjmlVector = when (this) {
|
||||
is EjmlVector -> this
|
||||
else -> EjmlVector(SimpleMatrix(size, 1).also {
|
||||
(0 until it.numRows()).forEach { row -> it[row, 0] = get(row) }
|
||||
})
|
||||
}
|
||||
|
||||
override fun buildMatrix(rows: Int, columns: Int, initializer: RealField.(i: Int, j: Int) -> Double): EjmlMatrix =
|
||||
EjmlMatrix(SimpleMatrix(rows, columns).also {
|
||||
(0 until rows).forEach { row ->
|
||||
(0 until columns).forEach { col -> it[row, col] = RealField.initializer(row, col) }
|
||||
}
|
||||
})
|
||||
|
||||
override fun buildVector(size: Int, initializer: RealField.(Int) -> Double): Point<Double> =
|
||||
EjmlVector(SimpleMatrix(size, 1).also {
|
||||
(0 until it.numRows()).forEach { row -> it[row, 0] = RealField.initializer(row) }
|
||||
})
|
||||
|
||||
private fun SimpleMatrix.wrapMatrix() = EjmlMatrix(this)
|
||||
private fun SimpleMatrix.wrapVector() = EjmlVector(this)
|
||||
|
||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * (-1.0)
|
||||
|
||||
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlMatrix =
|
||||
EjmlMatrix(toEjml().origin.mult(other.toEjml().origin))
|
||||
|
||||
public override fun Matrix<Double>.dot(vector: Point<Double>): EjmlVector =
|
||||
EjmlVector(toEjml().origin.mult(vector.toEjml().origin))
|
||||
|
||||
public override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlMatrix =
|
||||
(toEjml().origin - other.toEjml().origin).wrapMatrix()
|
||||
|
||||
public override operator fun Matrix<Double>.times(value: Double): EjmlMatrix =
|
||||
toEjml().origin.scale(value).wrapMatrix()
|
||||
|
||||
override fun Point<Double>.unaryMinus(): EjmlVector =
|
||||
toEjml().origin.negative().wrapVector()
|
||||
|
||||
override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlMatrix =
|
||||
(toEjml().origin + other.toEjml().origin).wrapMatrix()
|
||||
|
||||
override fun Point<Double>.plus(other: Point<Double>): EjmlVector =
|
||||
(toEjml().origin + other.toEjml().origin).wrapVector()
|
||||
|
||||
override fun Point<Double>.minus(other: Point<Double>): EjmlVector =
|
||||
(toEjml().origin - other.toEjml().origin).wrapVector()
|
||||
|
||||
override fun Double.times(m: Matrix<Double>): EjmlMatrix =
|
||||
m.toEjml().origin.scale(this).wrapMatrix()
|
||||
|
||||
override fun Point<Double>.times(value: Double): EjmlVector =
|
||||
toEjml().origin.scale(value).wrapVector()
|
||||
|
||||
override fun Double.times(v: Point<Double>): EjmlVector =
|
||||
v.toEjml().origin.scale(this).wrapVector()
|
||||
}
|
||||
|
||||
/**
|
||||
* Solves for X in the following equation: x = a^-1*b, where 'a' is base matrix and 'b' is an n by p matrix.
|
||||
*
|
||||
* @param a the base matrix.
|
||||
* @param b n by p matrix.
|
||||
* @return the solution for 'x' that is n by p.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
public fun EjmlLinearSpace.solve(a: Matrix<Double>, b: Matrix<Double>): EjmlMatrix =
|
||||
EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin))
|
||||
|
||||
/**
|
||||
* Solves for X in the following equation: x = a^(-1)*b, where 'a' is base matrix and 'b' is an n by p matrix.
|
||||
*
|
||||
* @param a the base matrix.
|
||||
* @param b n by p vector.
|
||||
* @return the solution for 'x' that is n by p.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
public fun EjmlLinearSpace.solve(a: Matrix<Double>, b: Point<Double>): EjmlVector =
|
||||
EjmlVector(a.toEjml().origin.solve(b.toEjml().origin))
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public fun EjmlMatrix.inverted(): EjmlMatrix = getFeature<InverseMatrixFeature<Double>>()!!.inverse as EjmlMatrix
|
||||
|
||||
public fun EjmlLinearSpace.inverse(matrix: Matrix<Double>): Matrix<Double> = matrix.toEjml().inverted()
|
@ -85,7 +85,7 @@ public class EjmlMatrix(public val origin: SimpleMatrix) : Matrix<Double> {
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is Matrix<*>) return false
|
||||
if (other !is NDStructure<*>) return false
|
||||
return NDStructure.contentEquals(this, other)
|
||||
}
|
||||
|
||||
|
@ -1,92 +0,0 @@
|
||||
package space.kscience.kmath.ejml
|
||||
|
||||
import org.ejml.simple.SimpleMatrix
|
||||
import space.kscience.kmath.linear.*
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.nd.getFeature
|
||||
import space.kscience.kmath.operations.ScaleOperations
|
||||
|
||||
/**
|
||||
* Represents context of basic operations operating with [EjmlMatrix].
|
||||
*
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
public object EjmlMatrixContext : MatrixContext<Double, EjmlMatrix>, ScaleOperations<Matrix<Double>> {
|
||||
|
||||
/**
|
||||
* Converts this matrix to EJML one.
|
||||
*/
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public fun Matrix<Double>.toEjml(): EjmlMatrix = when (val matrix = origin) {
|
||||
is EjmlMatrix -> matrix
|
||||
else -> produce(rowNum, colNum) { i, j -> get(i, j) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this vector to EJML one.
|
||||
*/
|
||||
public fun Point<Double>.toEjml(): EjmlVector =
|
||||
if (this is EjmlVector) this else EjmlVector(SimpleMatrix(size, 1).also {
|
||||
(0 until it.numRows()).forEach { row -> it[row, 0] = get(row) }
|
||||
})
|
||||
|
||||
override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): EjmlMatrix =
|
||||
EjmlMatrix(SimpleMatrix(rows, columns).also {
|
||||
(0 until rows).forEach { row ->
|
||||
(0 until columns).forEach { col -> it[row, col] = initializer(row, col) }
|
||||
}
|
||||
})
|
||||
|
||||
override fun point(size: Int, initializer: (Int) -> Double): Point<Double> =
|
||||
EjmlVector(SimpleMatrix(size, 1).also {
|
||||
(0 until it.numRows()).forEach { row -> it[row, 0] = initializer(row) }
|
||||
})
|
||||
|
||||
|
||||
override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this*(-1)
|
||||
|
||||
public override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlMatrix =
|
||||
EjmlMatrix(toEjml().origin.mult(other.toEjml().origin))
|
||||
|
||||
public override fun Matrix<Double>.dot(vector: Point<Double>): EjmlVector =
|
||||
EjmlVector(toEjml().origin.mult(vector.toEjml().origin))
|
||||
|
||||
public override fun add(a: Matrix<Double>, b: Matrix<Double>): EjmlMatrix =
|
||||
EjmlMatrix(a.toEjml().origin + b.toEjml().origin)
|
||||
|
||||
public override operator fun Matrix<Double>.minus(b: Matrix<Double>): EjmlMatrix =
|
||||
EjmlMatrix(toEjml().origin - b.toEjml().origin)
|
||||
|
||||
public override fun scale(a: Matrix<Double>, value: Double): EjmlMatrix =
|
||||
produce(a.rowNum, a.colNum) { i, j -> a[i, j] * value }
|
||||
|
||||
public override operator fun Matrix<Double>.times(value: Double): EjmlMatrix =
|
||||
EjmlMatrix(toEjml().origin.scale(value))
|
||||
}
|
||||
|
||||
/**
|
||||
* Solves for X in the following equation: x = a^-1*b, where 'a' is base matrix and 'b' is an n by p matrix.
|
||||
*
|
||||
* @param a the base matrix.
|
||||
* @param b n by p matrix.
|
||||
* @return the solution for 'x' that is n by p.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
public fun EjmlMatrixContext.solve(a: Matrix<Double>, b: Matrix<Double>): EjmlMatrix =
|
||||
EjmlMatrix(a.toEjml().origin.solve(b.toEjml().origin))
|
||||
|
||||
/**
|
||||
* Solves for X in the following equation: x = a^(-1)*b, where 'a' is base matrix and 'b' is an n by p matrix.
|
||||
*
|
||||
* @param a the base matrix.
|
||||
* @param b n by p vector.
|
||||
* @return the solution for 'x' that is n by p.
|
||||
* @author Iaroslav Postovalov
|
||||
*/
|
||||
public fun EjmlMatrixContext.solve(a: Matrix<Double>, b: Point<Double>): EjmlVector =
|
||||
EjmlVector(a.toEjml().origin.solve(b.toEjml().origin))
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public fun EjmlMatrix.inverted(): EjmlMatrix = getFeature<InverseMatrixFeature<Double>>()!!.inverse as EjmlMatrix
|
||||
|
||||
public fun EjmlMatrixContext.inverse(matrix: Matrix<Double>): Matrix<Double> = matrix.toEjml().inverted()
|
@ -2,6 +2,7 @@ package space.kscience.kmath.real
|
||||
|
||||
import space.kscience.kmath.linear.*
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.operations.RealField
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.RealBuffer
|
||||
import space.kscience.kmath.structures.asIterable
|
||||
@ -21,15 +22,19 @@ import kotlin.math.pow
|
||||
|
||||
public typealias RealMatrix = Matrix<Double>
|
||||
|
||||
public fun realMatrix(rowNum: Int, colNum: Int, initializer: (i: Int, j: Int) -> Double): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum, initializer)
|
||||
public fun realMatrix(rowNum: Int, colNum: Int, initializer: RealField.(i: Int, j: Int) -> Double): RealMatrix =
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum, initializer)
|
||||
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
public fun realMatrix(rowNum: Int, colNum: Int): MatrixBuilder<Double, RealField> =
|
||||
LinearSpace.real.matrix(rowNum, colNum)
|
||||
|
||||
public fun Array<DoubleArray>.toMatrix(): RealMatrix {
|
||||
return MatrixContext.real.produce(size, this[0].size) { row, col -> this[row][col] }
|
||||
return LinearSpace.real.buildMatrix(size, this[0].size) { row, col -> this@toMatrix[row][col] }
|
||||
}
|
||||
|
||||
public fun Sequence<DoubleArray>.toMatrix(): RealMatrix = toList().let {
|
||||
MatrixContext.real.produce(it.size, it[0].size) { row, col -> it[row][col] }
|
||||
LinearSpace.real.buildMatrix(it.size, it[0].size) { row, col -> it[row][col] }
|
||||
}
|
||||
|
||||
public fun RealMatrix.repeatStackVertical(n: Int): RealMatrix =
|
||||
@ -42,38 +47,38 @@ public fun RealMatrix.repeatStackVertical(n: Int): RealMatrix =
|
||||
*/
|
||||
|
||||
public operator fun RealMatrix.times(double: Double): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum) { row, col ->
|
||||
this[row, col] * double
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum) { row, col ->
|
||||
get(row, col) * double
|
||||
}
|
||||
|
||||
public operator fun RealMatrix.plus(double: Double): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum) { row, col ->
|
||||
this[row, col] + double
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum) { row, col ->
|
||||
get(row, col) + double
|
||||
}
|
||||
|
||||
public operator fun RealMatrix.minus(double: Double): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum) { row, col ->
|
||||
this[row, col] - double
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum) { row, col ->
|
||||
get(row, col) - double
|
||||
}
|
||||
|
||||
public operator fun RealMatrix.div(double: Double): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum) { row, col ->
|
||||
this[row, col] / double
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum) { row, col ->
|
||||
get(row, col) / double
|
||||
}
|
||||
|
||||
public operator fun Double.times(matrix: RealMatrix): RealMatrix =
|
||||
MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
|
||||
this * matrix[row, col]
|
||||
LinearSpace.real.buildMatrix(matrix.rowNum, matrix.colNum) { row, col ->
|
||||
this@times * matrix[row, col]
|
||||
}
|
||||
|
||||
public operator fun Double.plus(matrix: RealMatrix): RealMatrix =
|
||||
MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
|
||||
this + matrix[row, col]
|
||||
LinearSpace.real.buildMatrix(matrix.rowNum, matrix.colNum) { row, col ->
|
||||
this@plus + matrix[row, col]
|
||||
}
|
||||
|
||||
public operator fun Double.minus(matrix: RealMatrix): RealMatrix =
|
||||
MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
|
||||
this - matrix[row, col]
|
||||
LinearSpace.real.buildMatrix(matrix.rowNum, matrix.colNum) { row, col ->
|
||||
this@minus - matrix[row, col]
|
||||
}
|
||||
|
||||
// TODO: does this operation make sense? Should it be 'this/matrix[row, col]'?
|
||||
@ -87,29 +92,29 @@ public operator fun Double.minus(matrix: RealMatrix): RealMatrix =
|
||||
|
||||
@UnstableKMathAPI
|
||||
public operator fun RealMatrix.times(other: RealMatrix): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] * other[row, col] }
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum) { row, col -> this@times[row, col] * other[row, col] }
|
||||
|
||||
public operator fun RealMatrix.plus(other: RealMatrix): RealMatrix =
|
||||
MatrixContext.real.add(this, other)
|
||||
LinearSpace.real.run { this@plus + other }
|
||||
|
||||
public operator fun RealMatrix.minus(other: RealMatrix): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] - other[row, col] }
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum) { row, col -> this@minus[row, col] - other[row, col] }
|
||||
|
||||
/*
|
||||
* Operations on columns
|
||||
*/
|
||||
|
||||
public inline fun RealMatrix.appendColumn(crossinline mapper: (Buffer<Double>) -> Double): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum + 1) { row, col ->
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum + 1) { row, col ->
|
||||
if (col < colNum)
|
||||
this[row, col]
|
||||
get(row, col)
|
||||
else
|
||||
mapper(rows[row])
|
||||
}
|
||||
|
||||
public fun RealMatrix.extractColumns(columnRange: IntRange): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, columnRange.count()) { row, col ->
|
||||
this[row, columnRange.first + col]
|
||||
LinearSpace.real.buildMatrix(rowNum, columnRange.count()) { row, col ->
|
||||
this@extractColumns[row, columnRange.first + col]
|
||||
}
|
||||
|
||||
public fun RealMatrix.extractColumn(columnIndex: Int): RealMatrix =
|
||||
@ -141,14 +146,14 @@ public fun RealMatrix.max(): Double? = elements().map { (_, value) -> value }.ma
|
||||
public fun RealMatrix.average(): Double = elements().map { (_, value) -> value }.average()
|
||||
|
||||
public inline fun RealMatrix.map(crossinline transform: (Double) -> Double): RealMatrix =
|
||||
MatrixContext.real.produce(rowNum, colNum) { i, j ->
|
||||
LinearSpace.real.buildMatrix(rowNum, colNum) { i, j ->
|
||||
transform(get(i, j))
|
||||
}
|
||||
|
||||
/**
|
||||
* Inverse a square real matrix using LUP decomposition
|
||||
*/
|
||||
public fun RealMatrix.inverseWithLup(): RealMatrix = MatrixContext.real.inverseWithLup(this)
|
||||
public fun RealMatrix.inverseWithLup(): RealMatrix = LinearSpace.real.inverseWithLup(this)
|
||||
|
||||
//extended operations
|
||||
|
||||
|
@ -5,6 +5,7 @@ import space.kscience.kmath.operations.Norm
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.asBuffer
|
||||
import space.kscience.kmath.structures.asIterable
|
||||
import space.kscience.kmath.structures.indices
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sqrt
|
||||
|
||||
@ -30,7 +31,7 @@ public inline fun RealVector.mapIndexed(transform: (index: Int, value: Double) -
|
||||
Buffer.real(size) { transform(it, get(it)) }
|
||||
|
||||
public operator fun RealVector.plus(other: RealVector): RealVector {
|
||||
require(size == other.size){"Vector size $size expected but ${other.size} found"}
|
||||
require(size == other.size) { "Vector size $size expected but ${other.size} found" }
|
||||
return mapIndexed { index, value -> value + other[index] }
|
||||
}
|
||||
|
||||
@ -41,7 +42,7 @@ public operator fun Number.plus(vector: RealVector): RealVector = vector + this
|
||||
public operator fun RealVector.unaryMinus(): Buffer<Double> = map { -it }
|
||||
|
||||
public operator fun RealVector.minus(other: RealVector): RealVector {
|
||||
require(size == other.size){"Vector size $size expected but ${other.size} found"}
|
||||
require(size == other.size) { "Vector size $size expected but ${other.size} found" }
|
||||
return mapIndexed { index, value -> value - other[index] }
|
||||
}
|
||||
|
||||
@ -50,7 +51,7 @@ public operator fun RealVector.minus(number: Number): RealVector = map { it - nu
|
||||
public operator fun Number.minus(vector: RealVector): RealVector = vector.map { toDouble() - it }
|
||||
|
||||
public operator fun RealVector.times(other: RealVector): RealVector {
|
||||
require(size == other.size){"Vector size $size expected but ${other.size} found"}
|
||||
require(size == other.size) { "Vector size $size expected but ${other.size} found" }
|
||||
return mapIndexed { index, value -> value * other[index] }
|
||||
}
|
||||
|
||||
@ -59,7 +60,7 @@ public operator fun RealVector.times(number: Number): RealVector = map { it * nu
|
||||
public operator fun Number.times(vector: RealVector): RealVector = vector * this
|
||||
|
||||
public operator fun RealVector.div(other: RealVector): RealVector {
|
||||
require(size == other.size){"Vector size $size expected but ${other.size} found"}
|
||||
require(size == other.size) { "Vector size $size expected but ${other.size} found" }
|
||||
return mapIndexed { index, value -> value / other[index] }
|
||||
}
|
||||
|
||||
@ -88,3 +89,13 @@ public fun tan(vector: RealVector): RealVector = vector.map { kotlin.math.tan(it
|
||||
public fun ln(vector: RealVector): RealVector = vector.map { kotlin.math.ln(it) }
|
||||
|
||||
public fun log10(vector: RealVector): RealVector = vector.map { kotlin.math.log10(it) }
|
||||
|
||||
// reductions methods
|
||||
|
||||
public fun RealVector.sum(): Double {
|
||||
var res = 0.0
|
||||
for (i in indices) {
|
||||
res += get(i)
|
||||
}
|
||||
return res
|
||||
}
|
@ -1,31 +1,12 @@
|
||||
package space.kscience.kmath.real
|
||||
|
||||
import space.kscience.kmath.linear.BufferMatrix
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import space.kscience.kmath.structures.RealBuffer
|
||||
import space.kscience.kmath.linear.LinearSpace
|
||||
import space.kscience.kmath.linear.Matrix
|
||||
|
||||
|
||||
/**
|
||||
* Optimized dot product for real matrices
|
||||
*/
|
||||
public infix fun BufferMatrix<Double>.dot(other: BufferMatrix<Double>): BufferMatrix<Double> {
|
||||
require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
|
||||
val resultArray = DoubleArray(this.rowNum * other.colNum)
|
||||
|
||||
//convert to array to insure there is no memory indirection
|
||||
fun Buffer<Double>.unsafeArray() = if (this is RealBuffer)
|
||||
this.array
|
||||
else
|
||||
DoubleArray(size) { get(it) }
|
||||
|
||||
val a = this.buffer.unsafeArray()
|
||||
val b = other.buffer.unsafeArray()
|
||||
|
||||
for (i in (0 until rowNum))
|
||||
for (j in (0 until other.colNum))
|
||||
for (k in (0 until colNum))
|
||||
resultArray[i * other.colNum + j] += a[i * colNum + k] * b[k * other.colNum + j]
|
||||
|
||||
val buffer = RealBuffer(resultArray)
|
||||
return BufferMatrix(rowNum, other.colNum, buffer)
|
||||
public infix fun Matrix<Double>.dot(other: Matrix<Double>): Matrix<Double> = LinearSpace.real.run{
|
||||
this@dot dot other
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package kaceince.kmath.real
|
||||
|
||||
import space.kscience.kmath.linear.Matrix
|
||||
import space.kscience.kmath.linear.build
|
||||
import space.kscience.kmath.linear.LinearSpace
|
||||
import space.kscience.kmath.linear.matrix
|
||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||
import space.kscience.kmath.real.*
|
||||
import space.kscience.kmath.structures.contentEquals
|
||||
@ -9,6 +9,7 @@ import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
@UnstableKMathAPI
|
||||
internal class RealMatrixTest {
|
||||
@Test
|
||||
fun testSum() {
|
||||
@ -30,11 +31,11 @@ internal class RealMatrixTest {
|
||||
|
||||
@Test
|
||||
fun testRepeatStackVertical() {
|
||||
val matrix1 = Matrix.build(2, 3)(
|
||||
val matrix1 = realMatrix(2, 3)(
|
||||
1.0, 0.0, 0.0,
|
||||
0.0, 1.0, 2.0
|
||||
)
|
||||
val matrix2 = Matrix.build(6, 3)(
|
||||
val matrix2 = realMatrix(6, 3)(
|
||||
1.0, 0.0, 0.0,
|
||||
0.0, 1.0, 2.0,
|
||||
1.0, 0.0, 0.0,
|
||||
@ -47,12 +48,12 @@ internal class RealMatrixTest {
|
||||
|
||||
@Test
|
||||
fun testMatrixAndDouble() {
|
||||
val matrix1 = Matrix.build(2, 3)(
|
||||
val matrix1 = realMatrix(2, 3)(
|
||||
1.0, 0.0, 3.0,
|
||||
4.0, 6.0, 2.0
|
||||
)
|
||||
val matrix2 = (matrix1 * 2.5 + 1.0 - 2.0) / 2.0
|
||||
val expectedResult = Matrix.build(2, 3)(
|
||||
val expectedResult = LinearSpace.real.matrix(2, 3)(
|
||||
0.75, -0.5, 3.25,
|
||||
4.5, 7.0, 2.0
|
||||
)
|
||||
@ -61,13 +62,13 @@ internal class RealMatrixTest {
|
||||
|
||||
@Test
|
||||
fun testDoubleAndMatrix() {
|
||||
val matrix1 = Matrix.build(2, 3)(
|
||||
val matrix1 = realMatrix(2, 3)(
|
||||
1.0, 0.0, 3.0,
|
||||
4.0, 6.0, 2.0
|
||||
)
|
||||
val matrix2 = 20.0 - (10.0 + (5.0 * matrix1))
|
||||
//val matrix2 = 10.0 + (5.0 * matrix1)
|
||||
val expectedResult = Matrix.build(2, 3)(
|
||||
val expectedResult = realMatrix(2, 3)(
|
||||
5.0, 10.0, -5.0,
|
||||
-10.0, -20.0, 0.0
|
||||
)
|
||||
@ -76,15 +77,15 @@ internal class RealMatrixTest {
|
||||
|
||||
@Test
|
||||
fun testSquareAndPower() {
|
||||
val matrix1 = Matrix.build(2, 3)(
|
||||
val matrix1 = realMatrix(2, 3)(
|
||||
-1.0, 0.0, 3.0,
|
||||
4.0, -6.0, -2.0
|
||||
)
|
||||
val matrix2 = Matrix.build(2, 3)(
|
||||
val matrix2 = realMatrix(2, 3)(
|
||||
1.0, 0.0, 9.0,
|
||||
16.0, 36.0, 4.0
|
||||
)
|
||||
val matrix3 = Matrix.build(2, 3)(
|
||||
val matrix3 = realMatrix(2, 3)(
|
||||
-1.0, 0.0, 27.0,
|
||||
64.0, -216.0, -8.0
|
||||
)
|
||||
@ -95,16 +96,16 @@ internal class RealMatrixTest {
|
||||
@OptIn(UnstableKMathAPI::class)
|
||||
@Test
|
||||
fun testTwoMatrixOperations() {
|
||||
val matrix1 = Matrix.build(2, 3)(
|
||||
val matrix1 = realMatrix(2, 3)(
|
||||
-1.0, 0.0, 3.0,
|
||||
4.0, -6.0, 7.0
|
||||
)
|
||||
val matrix2 = Matrix.build(2, 3)(
|
||||
val matrix2 = realMatrix(2, 3)(
|
||||
1.0, 0.0, 3.0,
|
||||
4.0, 6.0, -2.0
|
||||
)
|
||||
val result = matrix1 * matrix2 + matrix1 - matrix2
|
||||
val expectedResult = Matrix.build(2, 3)(
|
||||
val expectedResult = realMatrix(2, 3)(
|
||||
-3.0, 0.0, 9.0,
|
||||
16.0, -48.0, -5.0
|
||||
)
|
||||
@ -113,16 +114,16 @@ internal class RealMatrixTest {
|
||||
|
||||
@Test
|
||||
fun testColumnOperations() {
|
||||
val matrix1 = Matrix.build(2, 4)(
|
||||
val matrix1 = realMatrix(2, 4)(
|
||||
-1.0, 0.0, 3.0, 15.0,
|
||||
4.0, -6.0, 7.0, -11.0
|
||||
)
|
||||
val matrix2 = Matrix.build(2, 5)(
|
||||
val matrix2 = realMatrix(2, 5)(
|
||||
-1.0, 0.0, 3.0, 15.0, -1.0,
|
||||
4.0, -6.0, 7.0, -11.0, 4.0
|
||||
)
|
||||
val col1 = Matrix.build(2, 1)(0.0, -6.0)
|
||||
val cols1to2 = Matrix.build(2, 2)(
|
||||
val col1 = realMatrix(2, 1)(0.0, -6.0)
|
||||
val cols1to2 = realMatrix(2, 2)(
|
||||
0.0, 3.0,
|
||||
-6.0, 7.0
|
||||
)
|
||||
@ -147,7 +148,7 @@ internal class RealMatrixTest {
|
||||
|
||||
@Test
|
||||
fun testAllElementOperations() {
|
||||
val matrix1 = Matrix.build(2, 4)(
|
||||
val matrix1 = LinearSpace.real.matrix(2, 4)(
|
||||
-1.0, 0.0, 3.0, 15.0,
|
||||
4.0, -6.0, 7.0, -11.0
|
||||
)
|
||||
|
@ -1,10 +1,8 @@
|
||||
package kaceince.kmath.real
|
||||
|
||||
import space.kscience.kmath.linear.MatrixContext
|
||||
import space.kscience.kmath.linear.LinearSpace
|
||||
import space.kscience.kmath.linear.asMatrix
|
||||
import space.kscience.kmath.linear.real
|
||||
import space.kscience.kmath.linear.transpose
|
||||
import space.kscience.kmath.operations.invoke
|
||||
import space.kscience.kmath.real.plus
|
||||
import space.kscience.kmath.structures.Buffer
|
||||
import kotlin.test.Test
|
||||
@ -32,7 +30,7 @@ internal class RealVectorTest {
|
||||
val vector2 = Buffer.real(5) { 5 - it.toDouble() }
|
||||
val matrix1 = vector1.asMatrix()
|
||||
val matrix2 = vector2.asMatrix().transpose()
|
||||
val product = MatrixContext.real { matrix1 dot matrix2 }
|
||||
val product = LinearSpace.real.run { matrix1 dot matrix2 }
|
||||
assertEquals(5.0, product[1, 0])
|
||||
assertEquals(6.0, product[2, 2])
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user