diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/labeledConstructors.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/labeledConstructors.kt index 12688a865..e81a9388e 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/labeledConstructors.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/labeledConstructors.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.functions import space.kscience.kmath.expressions.Symbol +import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Ring @@ -103,6 +104,61 @@ public fun > LabeledRationalFunctionSpace.LabeledPolynomial( public fun C.asLabeledPolynomial() : LabeledPolynomial = LabeledPolynomial(mapOf(emptyMap() to this)) +@DslMarker +@UnstableKMathAPI +internal annotation class LabeledPolynomialConstructorDSL + +@UnstableKMathAPI +@LabeledPolynomialConstructorDSL +public class LabeledPolynomialTermSignatureBuilder { + private val signature: MutableMap = LinkedHashMap() + public fun build(): Map = signature + public infix fun Symbol.inPowerOf(deg: UInt) { + signature[this] = deg + } + @Suppress("NOTHING_TO_INLINE") + public inline infix fun Symbol.pow(deg: UInt): Unit = this inPowerOf deg + @Suppress("NOTHING_TO_INLINE") + public inline infix fun Symbol.`in`(deg: UInt): Unit = this inPowerOf deg + @Suppress("NOTHING_TO_INLINE") + public inline infix fun Symbol.of(deg: UInt): Unit = this inPowerOf deg +} + +@UnstableKMathAPI +public class LabeledPolynomialBuilder(private val zero: C, private val add: (C, C) -> C, capacity: Int = 0) { + private val coefficients: MutableMap, C> = LinkedHashMap(capacity) + public fun build(): LabeledPolynomial = LabeledPolynomial(coefficients) + public operator fun C.invoke(block: LabeledPolynomialTermSignatureBuilder.() -> Unit) { + val signature = LabeledPolynomialTermSignatureBuilder().apply(block).build() + coefficients[signature] = add(coefficients.getOrElse(signature) { zero }, this@invoke) + } + @Suppress("NOTHING_TO_INLINE") + public inline infix fun C.with(noinline block: LabeledPolynomialTermSignatureBuilder.() -> Unit): Unit = this.invoke(block) + @Suppress("NOTHING_TO_INLINE") + public inline infix fun (LabeledPolynomialTermSignatureBuilder.() -> Unit).with(coef: C): Unit = coef.invoke(this) + @Suppress("NOTHING_TO_INLINE") + public infix fun sig(block: LabeledPolynomialTermSignatureBuilder.() -> Unit): LabeledPolynomialTermSignatureBuilder.() -> Unit = block +} + +// Waiting for context receivers :( FIXME: Replace with context receivers when they will be available + +@UnstableKMathAPI +@LabeledPolynomialConstructorDSL +@Suppress("FunctionName") +public inline fun > A.LabeledPolynomial(block: LabeledPolynomialBuilder.() -> Unit) : LabeledPolynomial = LabeledPolynomialBuilder(zero, ::add).apply(block).build() +@UnstableKMathAPI +@LabeledPolynomialConstructorDSL +@Suppress("FunctionName") +public inline fun > A.LabeledPolynomial(capacity: Int, block: LabeledPolynomialBuilder.() -> Unit) : LabeledPolynomial = LabeledPolynomialBuilder(zero, ::add, capacity).apply(block).build() +@UnstableKMathAPI +@LabeledPolynomialConstructorDSL +@Suppress("FunctionName") +public inline fun > LabeledPolynomialSpace.LabeledPolynomial(block: LabeledPolynomialBuilder.() -> Unit) : LabeledPolynomial = LabeledPolynomialBuilder(constantZero, { left: C, right: C -> left + right}).apply(block).build() +@UnstableKMathAPI +@LabeledPolynomialConstructorDSL +@Suppress("FunctionName") +public inline fun > LabeledPolynomialSpace.LabeledPolynomial(capacity: Int, block: LabeledPolynomialBuilder.() -> Unit) : LabeledPolynomial = LabeledPolynomialBuilder(constantZero, { left: C, right: C -> left + right}, capacity).apply(block).build() + // Waiting for context receivers :( FIXME: Replace with context receivers when they will be available @Suppress("FunctionName") diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/numberedConstructors.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/numberedConstructors.kt index e4b79b0b2..dca8a0cff 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/numberedConstructors.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/numberedConstructors.kt @@ -5,8 +5,8 @@ package space.kscience.kmath.functions +import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.operations.Ring -import space.kscience.kmath.operations.invoke /** @@ -97,8 +97,10 @@ public fun > NumberedRationalFunctionSpace.NumberedPolynomia public fun C.asNumberedPolynomial() : NumberedPolynomial = NumberedPolynomial(mapOf(emptyList() to this)) @DslMarker +@UnstableKMathAPI internal annotation class NumberedPolynomialConstructorDSL +@UnstableKMathAPI @NumberedPolynomialConstructorDSL public class NumberedPolynomialTermSignatureBuilder { private val signature: MutableList = ArrayList() @@ -111,43 +113,48 @@ public class NumberedPolynomialTermSignatureBuilder { signature[this] = deg } } - public infix fun Int.pow(deg: UInt): Unit = this inPowerOf deg - public infix fun Int.of(deg: UInt): Unit = this inPowerOf deg + @Suppress("NOTHING_TO_INLINE") + public inline infix fun Int.pow(deg: UInt): Unit = this inPowerOf deg + @Suppress("NOTHING_TO_INLINE") + public inline infix fun Int.`in`(deg: UInt): Unit = this inPowerOf deg + @Suppress("NOTHING_TO_INLINE") + public inline infix fun Int.of(deg: UInt): Unit = this inPowerOf deg } -@NumberedPolynomialConstructorDSL -public class NumberedPolynomialBuilderOverRing internal constructor(internal val context: Ring, capacity: Int = 0) { +@UnstableKMathAPI +public class NumberedPolynomialBuilder(private val zero: C, private val add: (C, C) -> C, capacity: Int = 0) { private val coefficients: MutableMap, C> = LinkedHashMap(capacity) public fun build(): NumberedPolynomial = NumberedPolynomial(coefficients) public operator fun C.invoke(block: NumberedPolynomialTermSignatureBuilder.() -> Unit) { val signature = NumberedPolynomialTermSignatureBuilder().apply(block).build() - coefficients[signature] = context { coefficients.getOrElse(signature) { zero } + this@invoke } + coefficients[signature] = add(coefficients.getOrElse(signature) { zero }, this@invoke) } - public infix fun C.with(block: NumberedPolynomialTermSignatureBuilder.() -> Unit): Unit = this.invoke(block) + @Suppress("NOTHING_TO_INLINE") + public inline infix fun C.with(noinline block: NumberedPolynomialTermSignatureBuilder.() -> Unit): Unit = this.invoke(block) + @Suppress("NOTHING_TO_INLINE") + public inline infix fun (NumberedPolynomialTermSignatureBuilder.() -> Unit).with(coef: C): Unit = coef.invoke(this) + @Suppress("NOTHING_TO_INLINE") + public infix fun sig(block: NumberedPolynomialTermSignatureBuilder.() -> Unit): NumberedPolynomialTermSignatureBuilder.() -> Unit = block } -@NumberedPolynomialConstructorDSL -public class NumberedPolynomialBuilderOverPolynomialSpace internal constructor(internal val context: NumberedPolynomialSpace, capacity: Int = 0) { - private val coefficients: MutableMap, C> = LinkedHashMap(capacity) - public fun build(): NumberedPolynomial = NumberedPolynomial(coefficients) - public operator fun C.invoke(block: NumberedPolynomialTermSignatureBuilder.() -> Unit) { - val signature = NumberedPolynomialTermSignatureBuilder().apply(block).build() - coefficients[signature] = context { coefficients.getOrElse(signature) { constantZero } + this@invoke } - } -} +// Waiting for context receivers :( FIXME: Replace with context receivers when they will be available +@UnstableKMathAPI @NumberedPolynomialConstructorDSL @Suppress("FunctionName") -public fun > A.NumberedPolynomial(block: NumberedPolynomialBuilderOverRing.() -> Unit) : NumberedPolynomial = NumberedPolynomialBuilderOverRing(this).apply(block).build() +public inline fun > A.NumberedPolynomial(block: NumberedPolynomialBuilder.() -> Unit) : NumberedPolynomial = NumberedPolynomialBuilder(zero, ::add).apply(block).build() +@UnstableKMathAPI @NumberedPolynomialConstructorDSL @Suppress("FunctionName") -public fun > A.NumberedPolynomial(capacity: Int, block: NumberedPolynomialBuilderOverRing.() -> Unit) : NumberedPolynomial = NumberedPolynomialBuilderOverRing(this, capacity).apply(block).build() +public inline fun > A.NumberedPolynomial(capacity: Int, block: NumberedPolynomialBuilder.() -> Unit) : NumberedPolynomial = NumberedPolynomialBuilder(zero, ::add, capacity).apply(block).build() +@UnstableKMathAPI @NumberedPolynomialConstructorDSL @Suppress("FunctionName") -public fun > NumberedPolynomialSpace.NumberedPolynomial(block: NumberedPolynomialBuilderOverPolynomialSpace.() -> Unit) : NumberedPolynomial = NumberedPolynomialBuilderOverPolynomialSpace(this).apply(block).build() +public inline fun > NumberedPolynomialSpace.NumberedPolynomial(block: NumberedPolynomialBuilder.() -> Unit) : NumberedPolynomial = NumberedPolynomialBuilder(constantZero, { left: C, right: C -> left + right}).apply(block).build() +@UnstableKMathAPI @NumberedPolynomialConstructorDSL @Suppress("FunctionName") -public fun > NumberedPolynomialSpace.NumberedPolynomial(capacity: Int, block: NumberedPolynomialBuilderOverPolynomialSpace.() -> Unit) : NumberedPolynomial = NumberedPolynomialBuilderOverPolynomialSpace(this, capacity).apply(block).build() +public inline fun > NumberedPolynomialSpace.NumberedPolynomial(capacity: Int, block: NumberedPolynomialBuilder.() -> Unit) : NumberedPolynomial = NumberedPolynomialBuilder(constantZero, { left: C, right: C -> left + right}, capacity).apply(block).build() // Waiting for context receivers :( FIXME: Replace with context receivers when they will be available