[WIP] Features to Attributes refactoring
This commit is contained in:
parent
6da51b7794
commit
4abe25c188
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
- Features replaced with Attributes.
|
- Features replaced with Attributes.
|
||||||
|
- Transposed refactored.
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package space.kscience.attributes
|
package space.kscience.attributes
|
||||||
|
|
||||||
|
import kotlin.jvm.JvmInline
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import kotlin.reflect.KType
|
import kotlin.reflect.KType
|
||||||
import kotlin.reflect.typeOf
|
import kotlin.reflect.typeOf
|
||||||
@ -14,7 +15,8 @@ import kotlin.reflect.typeOf
|
|||||||
*
|
*
|
||||||
* @param kType raw [KType]
|
* @param kType raw [KType]
|
||||||
*/
|
*/
|
||||||
public class SafeType<T> @PublishedApi internal constructor(public val kType: KType)
|
@JvmInline
|
||||||
|
public value class SafeType<T> @PublishedApi internal constructor(public val kType: KType)
|
||||||
|
|
||||||
public inline fun <reified T> safeTypeOf(): SafeType<T> = SafeType(typeOf<T>())
|
public inline fun <reified T> safeTypeOf(): SafeType<T> = SafeType(typeOf<T>())
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ private fun DMatrixContext<Double, *>.simple() {
|
|||||||
val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() }
|
val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() }
|
||||||
|
|
||||||
//Dimension-safe addition
|
//Dimension-safe addition
|
||||||
m1.transpose() + m2
|
m1.transposed() + m2
|
||||||
}
|
}
|
||||||
|
|
||||||
private object D5 : Dimension {
|
private object D5 : Dimension {
|
||||||
|
@ -125,7 +125,7 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> {
|
|||||||
|
|
||||||
val logger = problem.getFeature<OptimizationLog>()
|
val logger = problem.getFeature<OptimizationLog>()
|
||||||
|
|
||||||
for (feature in problem.features) {
|
for (feature in problem.attributes) {
|
||||||
when (feature) {
|
when (feature) {
|
||||||
is CMOptimizerData -> feature.data.forEach { dataBuilder ->
|
is CMOptimizerData -> feature.data.forEach { dataBuilder ->
|
||||||
addOptimizationData(dataBuilder())
|
addOptimizationData(dataBuilder())
|
||||||
|
@ -174,9 +174,8 @@ public interface LinearSpace<T, out A : Ring<T>> : MatrixOperations<T> {
|
|||||||
/**
|
/**
|
||||||
* Get an attribute value for the structure in this scope. Structure features take precedence other context features.
|
* Get an attribute value for the structure in this scope. Structure features take precedence other context features.
|
||||||
*
|
*
|
||||||
* @param A the type of feature.
|
|
||||||
* @param structure the structure.
|
* @param structure the structure.
|
||||||
* @param attribute to be computed
|
* @param attribute to be computed.
|
||||||
* @return a feature object or `null` if it isn't present.
|
* @return a feature object or `null` if it isn't present.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
@ -21,12 +21,11 @@ import space.kscience.kmath.structures.*
|
|||||||
* @param T the type of matrices' items.
|
* @param T the type of matrices' items.
|
||||||
* @param l The lower triangular matrix in this decomposition. It may have [LowerTriangular].
|
* @param l The lower triangular matrix in this decomposition. It may have [LowerTriangular].
|
||||||
* @param u The upper triangular matrix in this decomposition. It may have [UpperTriangular].
|
* @param u The upper triangular matrix in this decomposition. It may have [UpperTriangular].
|
||||||
* @param p he permutation matrix in this decomposition. May have [Determinant] attribute
|
|
||||||
*/
|
*/
|
||||||
public data class LupDecomposition<T>(
|
public data class LupDecomposition<T>(
|
||||||
public val l: Matrix<T>,
|
public val l: Matrix<T>,
|
||||||
public val u: Matrix<T>,
|
public val u: Matrix<T>,
|
||||||
public val p: Matrix<T>,
|
public val pivot: IntBuffer,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -180,12 +179,12 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup(
|
|||||||
val u = VirtualMatrix(rowNum, colNum) { i, j ->
|
val u = VirtualMatrix(rowNum, colNum) { i, j ->
|
||||||
if (j >= i) lu[i, j] else zero
|
if (j >= i) lu[i, j] else zero
|
||||||
}.withAttribute(UpperTriangular)
|
}.withAttribute(UpperTriangular)
|
||||||
|
//
|
||||||
|
// val p = VirtualMatrix(rowNum, colNum) { i, j ->
|
||||||
|
// if (j == pivot[i]) one else zero
|
||||||
|
// }.withAttribute(Determinant, if (even) one else -one)
|
||||||
|
|
||||||
val p = VirtualMatrix(rowNum, colNum) { i, j ->
|
return LupDecomposition(l, u, pivot.asBuffer())
|
||||||
if (j == pivot[i]) one else zero
|
|
||||||
}.withAttribute(Determinant, if (even) one else -one)
|
|
||||||
|
|
||||||
return LupDecomposition(l, u, p)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +208,7 @@ internal fun <T : Any, A : Field<T>> LinearSpace<T, A>.solve(
|
|||||||
|
|
||||||
for (row in 0 until rowNum) {
|
for (row in 0 until rowNum) {
|
||||||
val bpRow = bp.row(row)
|
val bpRow = bp.row(row)
|
||||||
val pRow = pivot[row]
|
val pRow = lup.pivot[row]
|
||||||
for (col in 0 until matrix.colNum) bpRow[col] = matrix[pRow, col]
|
for (col in 0 until matrix.colNum) bpRow[col] = matrix[pRow, col]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@ package space.kscience.kmath.linear
|
|||||||
import space.kscience.attributes.*
|
import space.kscience.attributes.*
|
||||||
import space.kscience.kmath.UnstableKMathAPI
|
import space.kscience.kmath.UnstableKMathAPI
|
||||||
import space.kscience.kmath.nd.StructureAttribute
|
import space.kscience.kmath.nd.StructureAttribute
|
||||||
import kotlin.reflect.KType
|
|
||||||
import kotlin.reflect.typeOf
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A marker interface representing some properties of matrices or additional transformations of them. Features are used
|
* A marker interface representing some properties of matrices or additional transformations of them. Features are used
|
||||||
@ -53,11 +51,9 @@ public val <T> MatrixOperations<T>.Inverted: Inverted<T> get() = Inverted(safeTy
|
|||||||
*
|
*
|
||||||
* @param T the type of matrices' items.
|
* @param T the type of matrices' items.
|
||||||
*/
|
*/
|
||||||
public class Determinant<T>(type: SafeType<T>) :
|
public class Determinant<T> : MatrixAttribute<T>
|
||||||
PolymorphicAttribute<T>(type),
|
|
||||||
MatrixAttribute<T>
|
|
||||||
|
|
||||||
public inline val <reified T> MatrixOperations<T>.Determinant: Determinant<T> get() = Determinant(safeTypeOf())
|
public val <T> MatrixOperations<T>.Determinant: Determinant<T> get() = Determinant()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Matrices with this feature are lower triangular ones.
|
* Matrices with this feature are lower triangular ones.
|
||||||
@ -174,4 +170,5 @@ public class SingularValueDecompositionAttribute<T>(type: SafeType<SingularValue
|
|||||||
public val <T> MatrixOperations<T>.SVD: SingularValueDecompositionAttribute<T>
|
public val <T> MatrixOperations<T>.SVD: SingularValueDecompositionAttribute<T>
|
||||||
get() = SingularValueDecompositionAttribute(safeTypeOf())
|
get() = SingularValueDecompositionAttribute(safeTypeOf())
|
||||||
|
|
||||||
|
|
||||||
//TODO add sparse matrix feature
|
//TODO add sparse matrix feature
|
||||||
|
@ -82,13 +82,3 @@ public fun <T : Any> LinearSpace<T, Ring<T>>.zero(
|
|||||||
): MatrixWrapper<T> = VirtualMatrix(rows, columns) { _, _ ->
|
): MatrixWrapper<T> = VirtualMatrix(rows, columns) { _, _ ->
|
||||||
elementAlgebra.zero
|
elementAlgebra.zero
|
||||||
}.withAttribute(IsZero)
|
}.withAttribute(IsZero)
|
||||||
|
|
||||||
public class TransposedAttribute<out T : Any>(public val original: Matrix<T>) : MatrixAttribute
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A`
|
|
||||||
*/
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
|
||||||
public fun <T : Any> Matrix<T>.transpose(): Matrix<T> = getFeature(TransposedAttribute::class)?.original as? Matrix<T>
|
|
||||||
?: VirtualMatrix(colNum, rowNum) { i, j -> get(j, i) }.withAttribute(TransposedAttribute(this))
|
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2023 KMath contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package space.kscience.kmath.linear
|
||||||
|
|
||||||
|
import space.kscience.attributes.Attributes
|
||||||
|
|
||||||
|
|
||||||
|
public class TransposedMatrix<T>(public val origin: Matrix<T>) : Matrix<T> {
|
||||||
|
override val rowNum: Int get() = origin.colNum
|
||||||
|
override val colNum: Int get() = origin.rowNum
|
||||||
|
|
||||||
|
override fun get(i: Int, j: Int): T = origin[j, i]
|
||||||
|
|
||||||
|
override val attributes: Attributes get() = Attributes.EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A`
|
||||||
|
*/
|
||||||
|
public val <T> Matrix<T>.transposed: Matrix<T>
|
||||||
|
get() = (this as? TransposedMatrix<T>)?.origin ?: TransposedMatrix(this)
|
@ -29,5 +29,4 @@ public class VirtualMatrix<out T : Any>(
|
|||||||
public fun <T : Any> MatrixBuilder<T, *>.virtual(
|
public fun <T : Any> MatrixBuilder<T, *>.virtual(
|
||||||
attributes: Attributes = Attributes.EMPTY,
|
attributes: Attributes = Attributes.EMPTY,
|
||||||
generator: (i: Int, j: Int) -> T,
|
generator: (i: Int, j: Int) -> T,
|
||||||
): VirtualMatrix<T> =
|
): VirtualMatrix<T> = VirtualMatrix(rows, columns, attributes, generator)
|
||||||
VirtualMatrix(rows, columns, attributes, generator)
|
|
||||||
|
@ -71,31 +71,19 @@ public interface AlgebraND<T, out C : Algebra<T>> : Algebra<StructureND<T>> {
|
|||||||
structure.map { value -> this@invoke(value) }
|
structure.map { value -> this@invoke(value) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a feature of the structure in this scope. Structure features take precedence other context features.
|
* Get an attribute value for the structure in this scope. Structure features take precedence other context features.
|
||||||
*
|
*
|
||||||
* @param F the type of feature.
|
|
||||||
* @param structure the structure.
|
* @param structure the structure.
|
||||||
* @param type the [KClass] instance of [F].
|
* @param attribute to be computed.
|
||||||
* @return a feature object or `null` if it isn't present.
|
* @return a feature object or `null` if it isn't present.
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public fun <F : StructureAttribute> getFeature(structure: StructureND<T>, type: KClass<out F>): F? =
|
public fun <T, A : StructureAttribute<T>> attributeFor(structure: StructureND<*>, attribute: A): T? =
|
||||||
structure.getFeature(type)
|
structure.attributes[attribute]
|
||||||
|
|
||||||
public companion object
|
public companion object
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a feature of the structure in this scope. Structure features take precedence other context features.
|
|
||||||
*
|
|
||||||
* @param T the type of items in the matrices.
|
|
||||||
* @param F the type of feature.
|
|
||||||
* @return a feature object or `null` if it isn't present.
|
|
||||||
*/
|
|
||||||
@UnstableKMathAPI
|
|
||||||
public inline fun <T : Any, reified F : StructureAttribute> AlgebraND<T, *>.getFeature(structure: StructureND<T>): F? =
|
|
||||||
getFeature(structure, F::class)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Space of [StructureND].
|
* Space of [StructureND].
|
||||||
*
|
*
|
||||||
|
@ -36,8 +36,8 @@ public open class BufferND<out T>(
|
|||||||
*/
|
*/
|
||||||
public inline fun <reified T> BufferND(
|
public inline fun <reified T> BufferND(
|
||||||
shape: ShapeND,
|
shape: ShapeND,
|
||||||
bufferFactory: BufferFactory<T> = BufferFactory.auto(),
|
bufferFactory: BufferFactory<T> = BufferFactory.auto<T>(),
|
||||||
initializer: (IntArray) -> T,
|
crossinline initializer: (IntArray) -> T,
|
||||||
): BufferND<T> {
|
): BufferND<T> {
|
||||||
val strides = Strides(shape)
|
val strides = Strides(shape)
|
||||||
return BufferND(strides, bufferFactory(strides.linearSize) { initializer(strides.index(it)) })
|
return BufferND(strides, bufferFactory(strides.linearSize) { initializer(strides.index(it)) })
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.nd
|
package space.kscience.kmath.nd
|
||||||
|
|
||||||
|
import space.kscience.attributes.Attributes
|
||||||
import space.kscience.kmath.PerformancePitfall
|
import space.kscience.kmath.PerformancePitfall
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.MutableBuffer
|
import space.kscience.kmath.structures.MutableBuffer
|
||||||
@ -110,7 +111,8 @@ private value class Structure2DWrapper<out T>(val structure: StructureND<T>) : S
|
|||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
override operator fun get(i: Int, j: Int): T = structure[i, j]
|
override operator fun get(i: Int, j: Int): T = structure[i, j]
|
||||||
|
|
||||||
override fun <F : StructureAttribute> getFeature(type: KClass<out F>): F? = structure.getFeature(type)
|
override val attributes: Attributes
|
||||||
|
get() = structure.attributes
|
||||||
|
|
||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
override fun elements(): Sequence<Pair<IntArray, T>> = structure.elements()
|
override fun elements(): Sequence<Pair<IntArray, T>> = structure.elements()
|
||||||
|
@ -7,13 +7,13 @@ package space.kscience.kmath.nd
|
|||||||
|
|
||||||
import space.kscience.attributes.Attribute
|
import space.kscience.attributes.Attribute
|
||||||
import space.kscience.attributes.AttributeContainer
|
import space.kscience.attributes.AttributeContainer
|
||||||
|
import space.kscience.attributes.Attributes
|
||||||
import space.kscience.attributes.SafeType
|
import space.kscience.attributes.SafeType
|
||||||
import space.kscience.kmath.PerformancePitfall
|
import space.kscience.kmath.PerformancePitfall
|
||||||
import space.kscience.kmath.linear.LinearSpace
|
import space.kscience.kmath.linear.LinearSpace
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.structures.Buffer
|
||||||
import space.kscience.kmath.structures.BufferFactory
|
|
||||||
import kotlin.jvm.JvmName
|
import kotlin.jvm.JvmName
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
@ -57,6 +57,8 @@ public interface StructureND<out T> : AttributeContainer, WithShape {
|
|||||||
@PerformancePitfall
|
@PerformancePitfall
|
||||||
public fun elements(): Sequence<Pair<IntArray, T>> = indices.asSequence().map { it to get(it) }
|
public fun elements(): Sequence<Pair<IntArray, T>> = indices.asSequence().map { it to get(it) }
|
||||||
|
|
||||||
|
override val attributes: Attributes get() = Attributes.EMPTY
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
/**
|
/**
|
||||||
* Indicates whether some [StructureND] is equal to another one.
|
* Indicates whether some [StructureND] is equal to another one.
|
||||||
|
@ -20,8 +20,6 @@ public interface WithSize {
|
|||||||
public interface BufferAlgebra<T, out A : Algebra<T>> : Algebra<Buffer<T>> {
|
public interface BufferAlgebra<T, out A : Algebra<T>> : Algebra<Buffer<T>> {
|
||||||
public val elementAlgebra: A
|
public val elementAlgebra: A
|
||||||
|
|
||||||
public val elementType: KType
|
|
||||||
|
|
||||||
public val elementBufferFactory: MutableBufferFactory<T> get() = elementAlgebra.bufferFactory
|
public val elementBufferFactory: MutableBufferFactory<T> get() = elementAlgebra.bufferFactory
|
||||||
|
|
||||||
public fun buffer(size: Int, vararg elements: T): Buffer<T> {
|
public fun buffer(size: Int, vararg elements: T): Buffer<T> {
|
||||||
|
@ -21,7 +21,7 @@ public fun interface BufferFactory<T> {
|
|||||||
public operator fun invoke(size: Int, builder: (Int) -> T): Buffer<T>
|
public operator fun invoke(size: Int, builder: (Int) -> T): Buffer<T>
|
||||||
|
|
||||||
public companion object{
|
public companion object{
|
||||||
public inline fun <reified T : Any> auto(): BufferFactory<T> =
|
public inline fun <reified T> auto(): BufferFactory<T> =
|
||||||
BufferFactory(Buffer.Companion::auto)
|
BufferFactory(Buffer.Companion::auto)
|
||||||
|
|
||||||
public fun <T> boxing(): BufferFactory<T> =
|
public fun <T> boxing(): BufferFactory<T> =
|
||||||
|
@ -146,8 +146,8 @@ public value class DMatrixContext<T : Any, out A : Ring<T>>(public val context:
|
|||||||
public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.unaryMinus(): DMatrix<T, C, R> =
|
public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.unaryMinus(): DMatrix<T, C, R> =
|
||||||
context.run { 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> =
|
public inline fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.transposed(): DMatrix<T, R, C> =
|
||||||
context.run { (this@transpose as Matrix<T>).transpose() }.coerce()
|
context.run { (this@transposed as Matrix<T>).transposed }.coerce()
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public val real: DMatrixContext<Double, DoubleField> = DMatrixContext(Double.algebra.linearSpace)
|
public val real: DMatrixContext<Double, DoubleField> = DMatrixContext(Double.algebra.linearSpace)
|
||||||
|
@ -30,7 +30,7 @@ internal class DMatrixContextTest {
|
|||||||
val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() }
|
val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() }
|
||||||
|
|
||||||
//Dimension-safe addition
|
//Dimension-safe addition
|
||||||
m1.transpose() + m2
|
m1.transposed() + m2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ kscience{
|
|||||||
|
|
||||||
wasm()
|
wasm()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(projects.kmathCore)
|
api(projects.kmathCore)
|
||||||
}
|
}
|
||||||
|
@ -68,9 +68,6 @@ public open class PolynomialSpace<C, A>(
|
|||||||
public val ring: A,
|
public val ring: A,
|
||||||
) : Ring<Polynomial<C>>, ScaleOperations<Polynomial<C>> where A : Ring<C>, A : ScaleOperations<C> {
|
) : Ring<Polynomial<C>>, ScaleOperations<Polynomial<C>> where A : Ring<C>, A : ScaleOperations<C> {
|
||||||
|
|
||||||
@UnstableKMathAPI
|
|
||||||
override val elementType: KType get() = typeOf<Polynomial<C>>()
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instance of zero constant (zero of the underlying ring).
|
* Instance of zero constant (zero of the underlying ring).
|
||||||
*/
|
*/
|
||||||
|
@ -5,21 +5,21 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.optimization
|
package space.kscience.kmath.optimization
|
||||||
|
|
||||||
|
import space.kscience.attributes.*
|
||||||
import space.kscience.kmath.expressions.DifferentiableExpression
|
import space.kscience.kmath.expressions.DifferentiableExpression
|
||||||
import space.kscience.kmath.expressions.Symbol
|
import space.kscience.kmath.expressions.Symbol
|
||||||
import space.kscience.kmath.misc.FeatureSet
|
|
||||||
|
|
||||||
public class OptimizationValue<T>(public val value: T) : OptimizationFeature {
|
public class OptimizationValue<T>(public val value: T) : OptimizationFeature {
|
||||||
override fun toString(): String = "Value($value)"
|
override fun toString(): String = "Value($value)"
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum class FunctionOptimizationTarget : OptimizationFeature {
|
public enum class FunctionOptimizationTarget {
|
||||||
MAXIMIZE,
|
MAXIMIZE,
|
||||||
MINIMIZE
|
MINIMIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
public class FunctionOptimization<T>(
|
public class FunctionOptimization<T>(
|
||||||
override val features: FeatureSet<OptimizationFeature>,
|
override val attributes: Attributes,
|
||||||
public val expression: DifferentiableExpression<T>,
|
public val expression: DifferentiableExpression<T>,
|
||||||
) : OptimizationProblem<T> {
|
) : OptimizationProblem<T> {
|
||||||
|
|
||||||
@ -30,25 +30,36 @@ public class FunctionOptimization<T>(
|
|||||||
|
|
||||||
other as FunctionOptimization<*>
|
other as FunctionOptimization<*>
|
||||||
|
|
||||||
if (features != other.features) return false
|
if (attributes != other.attributes) return false
|
||||||
if (expression != other.expression) return false
|
if (expression != other.expression) return false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
var result = features.hashCode()
|
var result = attributes.hashCode()
|
||||||
result = 31 * result + expression.hashCode()
|
result = 31 * result + expression.hashCode()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String = "FunctionOptimization(features=$features)"
|
override fun toString(): String = "FunctionOptimization(features=$attributes)"
|
||||||
|
|
||||||
|
public companion object
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class OptimizationPrior<T>(type: SafeType<T>):
|
||||||
|
PolymorphicAttribute<DifferentiableExpression<T>>(safeTypeOf()),
|
||||||
|
Attribute<DifferentiableExpression<T>>
|
||||||
|
|
||||||
|
public val <T> FunctionOptimization.Companion.Optimization get() =
|
||||||
|
|
||||||
|
|
||||||
public fun <T> FunctionOptimization<T>.withFeatures(
|
public fun <T> FunctionOptimization<T>.withFeatures(
|
||||||
vararg newFeature: OptimizationFeature,
|
vararg newFeature: OptimizationFeature,
|
||||||
): FunctionOptimization<T> = FunctionOptimization(
|
): FunctionOptimization<T> = FunctionOptimization(
|
||||||
features.with(*newFeature),
|
attributes.with(*newFeature),
|
||||||
expression,
|
expression,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -5,21 +5,16 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.optimization
|
package space.kscience.kmath.optimization
|
||||||
|
|
||||||
|
import space.kscience.attributes.*
|
||||||
import space.kscience.kmath.expressions.DifferentiableExpression
|
import space.kscience.kmath.expressions.DifferentiableExpression
|
||||||
import space.kscience.kmath.expressions.NamedMatrix
|
import space.kscience.kmath.expressions.NamedMatrix
|
||||||
import space.kscience.kmath.expressions.Symbol
|
import space.kscience.kmath.expressions.Symbol
|
||||||
import space.kscience.kmath.misc.*
|
import space.kscience.kmath.misc.*
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
public interface OptimizationFeature : Feature<OptimizationFeature> {
|
public interface OptimizationAttribute<T>: Attribute<T>
|
||||||
// enforce toString override
|
|
||||||
override fun toString(): String
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface OptimizationProblem<T> : Featured<OptimizationFeature> {
|
public interface OptimizationProblem<T> : AttributeContainer
|
||||||
public val features: FeatureSet<OptimizationFeature>
|
|
||||||
override fun <F : OptimizationFeature> getFeature(type: KClass<out F>): F? = features.getFeature(type)
|
|
||||||
}
|
|
||||||
|
|
||||||
public inline fun <reified F : OptimizationFeature> OptimizationProblem<*>.getFeature(): F? = getFeature(F::class)
|
public inline fun <reified F : OptimizationFeature> OptimizationProblem<*>.getFeature(): F? = getFeature(F::class)
|
||||||
|
|
||||||
@ -27,11 +22,6 @@ public open class OptimizationStartPoint<T>(public val point: Map<Symbol, T>) :
|
|||||||
override fun toString(): String = "StartPoint($point)"
|
override fun toString(): String = "StartPoint($point)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public interface OptimizationPrior<T> : OptimizationFeature, DifferentiableExpression<T> {
|
|
||||||
override val key: FeatureKey<OptimizationFeature> get() = OptimizationPrior::class
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Covariance matrix for
|
* Covariance matrix for
|
||||||
*/
|
*/
|
||||||
|
@ -79,7 +79,7 @@ public interface PointWeight : OptimizationFeature {
|
|||||||
public class XYFit(
|
public class XYFit(
|
||||||
public val data: XYColumnarData<Double, Double, Double>,
|
public val data: XYColumnarData<Double, Double, Double>,
|
||||||
public val model: DifferentiableExpression<Double>,
|
public val model: DifferentiableExpression<Double>,
|
||||||
override val features: FeatureSet<OptimizationFeature>,
|
override val attributes: FeatureSet<OptimizationFeature>,
|
||||||
internal val pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
internal val pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY,
|
||||||
internal val pointWeight: PointWeight = PointWeight.byYSigma,
|
internal val pointWeight: PointWeight = PointWeight.byYSigma,
|
||||||
public val xSymbol: Symbol = Symbol.x,
|
public val xSymbol: Symbol = Symbol.x,
|
||||||
@ -90,7 +90,7 @@ public class XYFit(
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun XYFit.withFeature(vararg features: OptimizationFeature): XYFit {
|
public fun XYFit.withFeature(vararg features: OptimizationFeature): XYFit {
|
||||||
return XYFit(data, model, this.features.with(*features), pointToCurveDistance, pointWeight)
|
return XYFit(data, model, this.attributes.with(*features), pointToCurveDistance, pointWeight)
|
||||||
}
|
}
|
||||||
|
|
||||||
public suspend fun XYColumnarData<Double, Double, Double>.fitWith(
|
public suspend fun XYColumnarData<Double, Double, Double>.fitWith(
|
||||||
|
@ -53,9 +53,9 @@ internal fun XYFit.logLikelihood(): DifferentiableExpression<Double> = object :
|
|||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public suspend fun Optimizer<Double, FunctionOptimization<Double>>.maximumLogLikelihood(problem: XYFit): XYFit {
|
public suspend fun Optimizer<Double, FunctionOptimization<Double>>.maximumLogLikelihood(problem: XYFit): XYFit {
|
||||||
val functionOptimization = FunctionOptimization(problem.features, problem.logLikelihood())
|
val functionOptimization = FunctionOptimization(problem.attributes, problem.logLikelihood())
|
||||||
val result = optimize(functionOptimization.withFeatures(FunctionOptimizationTarget.MAXIMIZE))
|
val result = optimize(functionOptimization.withFeatures(FunctionOptimizationTarget.MAXIMIZE))
|
||||||
return XYFit(problem.data, problem.model, result.features)
|
return XYFit(problem.data, problem.model, result.attributes)
|
||||||
}
|
}
|
||||||
|
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
|
Loading…
Reference in New Issue
Block a user