Feature: Polynomials and rational functions #469

Merged
lounres merged 132 commits from feature/polynomials into dev 2022-07-28 18:04:06 +03:00
10 changed files with 1714 additions and 99 deletions
Showing only changes of commit b5a94923b5 - Show all commits

View File

@ -100,14 +100,17 @@ public open class ListPolynomialSpace<C, A : Ring<C>>(
* The operation is equivalent to sum of [other] copies of [this].
*/
public override operator fun ListPolynomial<C>.times(other: Int): ListPolynomial<C> =
if (other == 0) zero
else ListPolynomial(
coefficients
.toMutableList()
.apply {
for (deg in indices) this[deg] = this[deg] * other
}
)
when (other) {
0 -> zero
1 -> this
else -> ListPolynomial(
coefficients
.toMutableList()
.apply {
for (deg in indices) this[deg] = this[deg] * other
}
)
}
/**
* Returns sum of the integer represented as a polynomial and the polynomial.
@ -133,34 +136,39 @@ public open class ListPolynomialSpace<C, A : Ring<C>>(
* The operation is equivalent to subtraction [this] copies of unit polynomial from [other].
*/
public override operator fun Int.minus(other: ListPolynomial<C>): ListPolynomial<C> =
if (this == 0) other
else
ListPolynomial(
other.coefficients
.toMutableList()
.apply {
forEachIndexed { index, c -> if (index != 0) this[index] = -c }
ListPolynomial(
other.coefficients
.toMutableList()
.apply {
if (this@minus == 0) {
indices.forEach { this[it] = -this[it] }
} else {
(1..lastIndex).forEach { this[it] = -this[it] }
val result = this@minus - getOrElse(0) { constantZero }
if(size == 0) add(result)
if (size == 0) add(result)
else this[0] = result
}
)
}
)
/**
* Returns product of the integer represented as a polynomial and the polynomial.
*
* The operation is equivalent to sum of [this] copies of [other].
*/
public override operator fun Int.times(other: ListPolynomial<C>): ListPolynomial<C> =
if (this == 0) zero
else ListPolynomial(
other.coefficients
.toMutableList()
.apply {
for (deg in indices) this[deg] = this@times * this[deg]
}
)
when (this) {
0 -> zero
1 -> other
else -> ListPolynomial(
other.coefficients
.toMutableList()
.apply {
for (deg in indices) this[deg] = this@times * this[deg]
}
)
}
/**
* Converts the integer [value] to polynomial.
@ -192,7 +200,7 @@ public open class ListPolynomialSpace<C, A : Ring<C>>(
else ListPolynomial(
toMutableList()
.apply {
forEachIndexed { index, c -> if (index != 0) this[index] = -c }
(1 .. lastIndex).forEach { this[it] = -this[it] }
val result = if (size == 0) this@minus else this@minus - get(0)

View File

@ -98,14 +98,17 @@ public class NumberedPolynomialSpace<C, A : Ring<C>>(
* The operation is equivalent to sum of [other] copies of [this].
*/
public override operator fun NumberedPolynomial<C>.times(other: Int): NumberedPolynomial<C> =
if (other == 0) zero
else NumberedPolynomialAsIs(
coefficients
.toMutableMap()
.apply {
for (degs in keys) this[degs] = this[degs]!! * other
}
)
when (other) {
0 -> zero
1 -> this
else -> NumberedPolynomialAsIs(
coefficients
.toMutableMap()
.apply {
for (degs in keys) this[degs] = this[degs]!! * other
}
)
}
/**
* Returns sum of the integer represented as a polynomial and the polynomial.
@ -130,16 +133,20 @@ public class NumberedPolynomialSpace<C, A : Ring<C>>(
* The operation is equivalent to subtraction [this] copies of unit polynomial from [other].
*/
public override operator fun Int.minus(other: NumberedPolynomial<C>): NumberedPolynomial<C> =
if (this == 0) other
else
NumberedPolynomialAsIs(
other.coefficients
.toMutableMap()
.apply {
NumberedPolynomialAsIs(
other.coefficients
.toMutableMap()
.apply {
if (this@minus == 0) {
forEach { (key, value) -> this[key] = -value }
} else {
forEach { (key, value) -> if (key.isNotEmpty()) this[key] = -value }
val degs = emptyList<UInt>()
this[degs] = this@minus - getOrElse(degs) { constantZero }
}
}
)
/**
* Returns product of the integer represented as a polynomial and the polynomial.
@ -147,14 +154,17 @@ public class NumberedPolynomialSpace<C, A : Ring<C>>(
* The operation is equivalent to sum of [this] copies of [other].
*/
public override operator fun Int.times(other: NumberedPolynomial<C>): NumberedPolynomial<C> =
if (this == 0) zero
else NumberedPolynomialAsIs(
other.coefficients
.toMutableMap()
.apply {
for (degs in keys) this[degs] = this@times * this[degs]!!
}
)
when (this) {
0 -> zero
1 -> other
else -> NumberedPolynomialAsIs(
other.coefficients
.toMutableMap()
.apply {
for (degs in keys) this[degs] = this@times * this[degs]!!
}
)
}
/**
* Converts the integer [value] to polynomial.
@ -185,7 +195,7 @@ public class NumberedPolynomialSpace<C, A : Ring<C>>(
else NumberedPolynomialAsIs(
toMutableMap()
.apply {
forEach { (degs, c) -> if(degs.isNotEmpty()) this[degs] = -c }
forEach { (degs, c) -> if (degs.isNotEmpty()) this[degs] = -c }
val degs = emptyList<UInt>()
@ -266,7 +276,7 @@ public class NumberedPolynomialSpace<C, A : Ring<C>>(
override operator fun NumberedPolynomial<C>.plus(other: NumberedPolynomial<C>): NumberedPolynomial<C> =
NumberedPolynomialAsIs(
buildMap(coefficients.size + other.coefficients.size) {
other.coefficients.mapValuesTo(this) { it.value }
coefficients.mapValuesTo(this) { it.value }
other.coefficients.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! + value else value }
}
)
@ -276,7 +286,7 @@ public class NumberedPolynomialSpace<C, A : Ring<C>>(
override operator fun NumberedPolynomial<C>.minus(other: NumberedPolynomial<C>): NumberedPolynomial<C> =
NumberedPolynomialAsIs(
buildMap(coefficients.size + other.coefficients.size) {
other.coefficients.mapValuesTo(this) { it.value }
coefficients.mapValuesTo(this) { it.value }
other.coefficients.mapValuesTo(this) { (key, value) -> if (key in this) this[key]!! - value else -value }
}
)

View File

@ -119,11 +119,13 @@ public class NumberedRationalFunctionSpace<C, A: Ring<C>> (
* Substitutes provided polynomial [argument] into [this] polynomial.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("substitutePolynomial")
public inline fun NumberedPolynomial<C>.substitute(argument: Map<Int, NumberedPolynomial<C>>): NumberedPolynomial<C> = substitute(ring, argument)
/**
* Substitutes provided rational function [argument] into [this] polynomial.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("substituteRationalFunction")
public inline fun NumberedPolynomial<C>.substitute(argument: Map<Int, NumberedRationalFunction<C>>): NumberedRationalFunction<C> = substitute(ring, argument)
/**
* Substitutes provided constant [argument] into [this] rational function.
@ -134,11 +136,13 @@ public class NumberedRationalFunctionSpace<C, A: Ring<C>> (
* Substitutes provided polynomial [argument] into [this] rational function.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("substitutePolynomial")
public inline fun NumberedRationalFunction<C>.substitute(argument: Map<Int, NumberedPolynomial<C>>): NumberedRationalFunction<C> = substitute(ring, argument)
/**
* Substitutes provided rational function [argument] into [this] rational function.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("substituteRationalFunction")
public inline fun NumberedRationalFunction<C>.substitute(argument: Map<Int, NumberedRationalFunction<C>>): NumberedRationalFunction<C> = substitute(ring, argument)
/**
* Substitutes provided constant [argument] into [this] polynomial.
@ -149,11 +153,13 @@ public class NumberedRationalFunctionSpace<C, A: Ring<C>> (
* Substitutes provided polynomial [argument] into [this] polynomial.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("substitutePolynomial")
public inline fun NumberedPolynomial<C>.substitute(argument: Buffer<NumberedPolynomial<C>>): NumberedPolynomial<C> = substitute(ring, argument)
/**
* Substitutes provided rational function [argument] into [this] polynomial.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("substituteRationalFunction")
public inline fun NumberedPolynomial<C>.substitute(argument: Buffer<NumberedRationalFunction<C>>): NumberedRationalFunction<C> = substitute(ring, argument)
/**
* Substitutes provided constant [argument] into [this] rational function.
@ -164,11 +170,13 @@ public class NumberedRationalFunctionSpace<C, A: Ring<C>> (
* Substitutes provided polynomial [arguments] into [this] rational function.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("substitutePolynomial")
public inline fun NumberedRationalFunction<C>.substitute(arguments: Buffer<NumberedPolynomial<C>>): NumberedRationalFunction<C> = substitute(ring, arguments)
/**
* Substitutes provided rational function [arguments] into [this] rational function.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("substituteRationalFunction")
public inline fun NumberedRationalFunction<C>.substitute(arguments: Buffer<NumberedRationalFunction<C>>): NumberedRationalFunction<C> = substitute(ring, arguments)
/**
* Substitutes provided constant [arguments] into [this] polynomial.
@ -222,7 +230,7 @@ public class NumberedRationalFunctionSpace<C, A: Ring<C>> (
* Substitutes provided [arguments] into [this] polynomial.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("invokePolynomial")
@JvmName("invokeRationalFunction")
public inline operator fun NumberedPolynomial<C>.invoke(arguments: Buffer<NumberedRationalFunction<C>>): NumberedRationalFunction<C> = substitute(ring, arguments)
/**
* Substitutes provided [arguments] into [this] rational function.
@ -234,6 +242,6 @@ public class NumberedRationalFunctionSpace<C, A: Ring<C>> (
* Substitutes provided [arguments] into [this] rational function.
*/
@Suppress("NOTHING_TO_INLINE")
@JvmName("invokePolynomial")
@JvmName("invokeRationalFunction")
public inline operator fun NumberedRationalFunction<C>.invoke(arguments: Buffer<NumberedRationalFunction<C>>): NumberedRationalFunction<C> = substitute(ring, arguments)
}

View File

@ -6,8 +6,27 @@
package space.kscience.kmath.functions
/**
* Marks operations that are going to be optimized reimplementations by reducing number of boxings but currently is
* under development and is not stable (or even ready to use).
*/
@RequiresOptIn(
message = "It's copy of operation with optimized boxing. It's currently unstable.",
level = RequiresOptIn.Level.ERROR
)
internal annotation class UnstablePolynomialBoxingOptimization
internal annotation class UnstablePolynomialBoxingOptimization
/**
* Marks declarations that give access to internal entities of polynomials delicate structure. Thus, it allows to
* optimize performance a bit by skipping standard steps, but such skips may cause critical errors if something is
* implemented badly. Make sure you fully read and understand documentation and don't break internal contracts.
*/
@RequiresOptIn(
message = "This declaration gives access to delicate internal structure of polynomials. " +
"It allows to optimize performance by skipping unnecessary arguments check. " +
"But at the same time makes it easy to make a mistake " +
"that will cause wrong computation result or even runtime error. " +
"Make sure you fully read and understand documentation.",
level = RequiresOptIn.Level.WARNING
)
internal annotation class DelicatePolynomialAPI

View File

@ -37,6 +37,38 @@ internal inline fun <C> NumberedPolynomialAsIs(pairs: Collection<Pair<List<UInt>
@PublishedApi
internal inline fun <C> NumberedPolynomialAsIs(vararg pairs: Pair<List<UInt>, C>) : NumberedPolynomial<C> = NumberedPolynomial<C>(pairs.toMap())
/**
* Constructs [NumberedPolynomial] with provided coefficients map [coefs]. The map is used as is.
*
* **Be sure you read description of [NumberedPolynomial.coefficients]. Otherwise, you may make a mistake that will
* cause wrong computation result or even runtime error.**
*/
@Suppress("FunctionName", "NOTHING_TO_INLINE")
@DelicatePolynomialAPI
public inline fun <C> NumberedPolynomialWithoutCheck(coefs: Map<List<UInt>, C>) : NumberedPolynomial<C> = NumberedPolynomial<C>(coefs)
/**
* Constructs [NumberedPolynomial] with provided collection of [pairs] of pairs "term's signature &mdash; term's coefficient".
* The collections will be transformed to map with [toMap] and then will be used as is.
*
* **Be sure you read description of [NumberedPolynomial.coefficients]. Otherwise, you may make a mistake that will
* cause wrong computation result or even runtime error.**
*/
@Suppress("FunctionName", "NOTHING_TO_INLINE")
@DelicatePolynomialAPI
public inline fun <C> NumberedPolynomialWithoutCheck(pairs: Collection<Pair<List<UInt>, C>>) : NumberedPolynomial<C> = NumberedPolynomial<C>(pairs.toMap())
/**
* Constructs [NumberedPolynomial] with provided array of [pairs] of pairs "term's signature &mdash; term's coefficient".
* The array will be transformed to map with [toMap] and then will be used as is.
*
* **Be sure you read description of [NumberedPolynomial.coefficients]. Otherwise, you may make a mistake that will
* cause wrong computation result or even runtime error.**
*/
@Suppress("FunctionName", "NOTHING_TO_INLINE")
@DelicatePolynomialAPI
public inline fun <C> NumberedPolynomialWithoutCheck(vararg pairs: Pair<List<UInt>, C>) : NumberedPolynomial<C> = NumberedPolynomial<C>(pairs.toMap())
/**
* Constructs [NumberedPolynomial] with provided coefficients map [coefs].
*
@ -245,11 +277,12 @@ public class NumberedPolynomialTermSignatureBuilder {
* Declaring another power of the same variable will increase its degree by received degree.
*/
public infix fun Int.inPowerOf(deg: UInt) {
if (this > signature.lastIndex) {
signature.addAll(List(this - signature.lastIndex - 1) { 0u })
val index = this - 1
if (index > signature.lastIndex) {
signature.addAll(List(index - signature.lastIndex - 1) { 0u })
signature.add(deg)
} else {
signature[this] += deg
signature[index] += deg
}
}
/**
@ -334,22 +367,26 @@ public class NumberedPolynomialBuilder<C>(
// Waiting for context receivers :( FIXME: Replace with context receivers when they will be available
/**
* Creates [NumberedPolynomial] with lambda [block] in context of [this] ring of constants.
*
* For example, polynomial `5 x_1^2 x_3^3 - 6 x_2` can be described as
* ```
* Int.algebra {
* val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial {
* 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 +
* (-6) { 2 inPowerOf 1u } // (-6) x_2^1
* }
* }
* ```
*/
@UnstableKMathAPI
@Suppress("FunctionName")
public inline fun <C, A: Ring<C>> A.NumberedPolynomial(initialCapacity: Int = 0, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder(::add, initialCapacity).apply(block).build()
///**
// * Creates [NumberedPolynomial] with lambda [block] in context of [this] ring of constants.
// *
// * For example, polynomial `5 x_1^2 x_3^3 - 6 x_2` can be described as
// * ```
// * Int.algebra {
// * val numberedPolynomial : NumberedPolynomial<Int> = NumberedPolynomial {
// * 5 { 1 inPowerOf 2u; 3 inPowerOf 3u } // 5 x_1^2 x_3^3 +
// * (-6) { 2 inPowerOf 1u } // (-6) x_2^1
// * }
// * }
// * ```
// */
// FIXME: For now this fabric does not let next two fabrics work. (See KT-52803.) Possible feature solutions:
// 1. `LowPriorityInOverloadResolution` becomes public. Then it should be applied to this function.
// 2. Union types are implemented. Then all three functions should be rewritten
// as one with single union type as a (context) receiver.
//@UnstableKMathAPI
//@Suppress("FunctionName")
//public inline fun <C, A: Ring<C>> A.NumberedPolynomial(initialCapacity: Int = 0, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder(::add, initialCapacity).apply(block).build()
/**
* Creates [NumberedPolynomial] with lambda [block] in context of [this] ring of [NumberedPolynomial]s.
*
@ -365,7 +402,7 @@ public inline fun <C, A: Ring<C>> A.NumberedPolynomial(initialCapacity: Int = 0,
*/
@UnstableKMathAPI
@Suppress("FunctionName")
public inline fun <C, A: Ring<C>> NumberedPolynomialSpace<C, A>.NumberedPolynomial(initialCapacity: Int, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build()
public inline fun <C, A: Ring<C>> NumberedPolynomialSpace<C, A>.NumberedPolynomial(initialCapacity: Int = 0, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build()
/**
* Creates [NumberedPolynomial] with lambda [block] in context of [this] field of [NumberedRationalFunction]s.
*
@ -381,7 +418,7 @@ public inline fun <C, A: Ring<C>> NumberedPolynomialSpace<C, A>.NumberedPolynomi
*/
@UnstableKMathAPI
@Suppress("FunctionName")
public inline fun <C, A: Ring<C>> NumberedRationalFunctionSpace<C, A>.NumberedPolynomial(initialCapacity: Int, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build()
public inline fun <C, A: Ring<C>> NumberedRationalFunctionSpace<C, A>.NumberedPolynomial(initialCapacity: Int = 0, block: NumberedPolynomialBuilder<C>.() -> Unit) : NumberedPolynomial<C> = NumberedPolynomialBuilder({ left: C, right: C -> left + right }, initialCapacity).apply(block).build()
// Waiting for context receivers :( FIXME: Replace with context receivers when they will be available

View File

@ -86,7 +86,7 @@ public fun <C> NumberedPolynomial<C>.substitute(ring: Ring<C>, args: Map<Int, C>
/**
* Substitutes provided arguments [args] into [this] polynomial.
*/ // TODO: To optimize boxing
*/ // TODO: To optimize boxing
@JvmName("substitutePolynomial")
public fun <C> NumberedPolynomial<C>.substitute(ring: Ring<C>, args: Map<Int, NumberedPolynomial<C>>) : NumberedPolynomial<C> =
ring.numberedPolynomialSpace {

View File

@ -3,6 +3,8 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
@file:Suppress("LocalVariableName")
package space.kscience.kmath.functions
import space.kscience.kmath.test.misc.*
@ -28,25 +30,32 @@ class ListPolynomialTest {
ListPolynomial(Rational(-2)) + 2,
"test 3"
)
assertEquals(
ListPolynomial(),
ListPolynomial<Rational>() + 0,
val polynomial_4 = ListPolynomial<Rational>()
assertSame(
polynomial_4,
polynomial_4 + 0,
"test 4"
)
val polynomial_5 = ListPolynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7))
assertSame(
polynomial_5,
polynomial_5 + 0,
"test 5"
)
assertEquals(
ListPolynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)) + 1,
"test 5"
"test 6"
)
assertEquals(
ListPolynomial(Rational(-1)),
ListPolynomial(Rational(-2)) + 1,
"test 6"
"test 7"
)
assertEquals(
ListPolynomial(Rational(2)),
ListPolynomial<Rational>() + 2,
"test 7"
"test 8"
)
}
}
@ -68,25 +77,32 @@ class ListPolynomialTest {
ListPolynomial(Rational(2)) - 2,
"test 3"
)
assertEquals(
ListPolynomial(),
ListPolynomial<Rational>() - 0,
val polynomial_4 = ListPolynomial<Rational>()
assertSame(
polynomial_4,
polynomial_4 - 0,
"test 4"
)
val polynomial_5 = ListPolynomial(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7))
assertEquals(
polynomial_5,
polynomial_5 - 0,
"test 5"
)
assertEquals(
ListPolynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
ListPolynomial(Rational(2), Rational(0), Rational(0), Rational(0)) - 1,
"test 5"
"test 6"
)
assertEquals(
ListPolynomial(Rational(1)),
ListPolynomial(Rational(2)) - 1,
"test 6"
"test 7"
)
assertEquals(
ListPolynomial(Rational(-2)),
ListPolynomial<Rational>() - 2,
"test 7"
"test 8"
)
}
}
@ -103,6 +119,17 @@ class ListPolynomialTest {
ListPolynomial(7, 0, 49, 21, 14) * 15,
"test 2"
)
val polynomial = ListPolynomial(22, 26, 13, 15, 26)
assertSame(
zero,
polynomial * 0,
"test 3"
)
assertSame(
polynomial,
polynomial * 1,
"test 4"
)
}
}
@Test
@ -123,25 +150,32 @@ class ListPolynomialTest {
2 + ListPolynomial(Rational(-2)),
"test 3"
)
assertEquals(
ListPolynomial(),
0 + ListPolynomial(),
val polynomial_4 = ListPolynomial<Rational>()
assertSame(
polynomial_4,
0 + polynomial_4,
"test 4"
)
val polynomial_5 = ListPolynomial<Rational>(Rational(-22, 9), Rational(-8, 9), Rational(-8, 7))
assertSame(
polynomial_5,
0 + polynomial_5,
"test 5"
)
assertEquals(
ListPolynomial(Rational(-1), Rational(0), Rational(0), Rational(0)),
1 + ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
"test 5"
"test 6"
)
assertEquals(
ListPolynomial(Rational(-1)),
1 + ListPolynomial(Rational(-2)),
"test 6"
"test 7"
)
assertEquals(
ListPolynomial(Rational(2)),
2 + ListPolynomial(),
"test 7"
"test 8"
)
}
}
@ -163,25 +197,30 @@ class ListPolynomialTest {
-2 - ListPolynomial(Rational(-2)),
"test 3"
)
assertEquals(
ListPolynomial(Rational(-32, 9), Rational(-8, -9), Rational(8, 7)),
0 - ListPolynomial(Rational(32, 9), Rational(-8, 9), Rational(-8, 7)),
"test 4"
)
assertEquals(
ListPolynomial(),
0 - ListPolynomial(),
"test 4"
"test 5"
)
assertEquals(
ListPolynomial(Rational(1), Rational(0), Rational(0), Rational(0)),
-1 - ListPolynomial(Rational(-2), Rational(0), Rational(0), Rational(0)),
"test 5"
"test 6"
)
assertEquals(
ListPolynomial(Rational(1)),
-1 - ListPolynomial(Rational(-2)),
"test 6"
"test 7"
)
assertEquals(
ListPolynomial(Rational(-2)),
-2 - ListPolynomial(),
"test 7"
"test 8"
)
}
}
@ -198,6 +237,17 @@ class ListPolynomialTest {
15 * ListPolynomial(7, 0, 49, 21, 14),
"test 2"
)
val polynomial = ListPolynomial(22, 26, 13, 15, 26)
assertSame(
zero,
0 * polynomial,
"test 3"
)
assertSame(
polynomial,
1 * polynomial,
"test 4"
)
}
}
@Test

View File

@ -0,0 +1,111 @@
/*
* Copyright 2018-2021 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.functions
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
class NumberedConstructorsTest {
@Test
@UnstableKMathAPI
fun testBuilder() {
assertEquals(
NumberedPolynomialAsIs(
listOf(2u, 0u, 3u) to 5,
listOf(0u, 1u) to -6,
),
Int.algebra.numberedPolynomialSpace {
NumberedPolynomial {
5 { 1 inPowerOf 2u; 3 inPowerOf 3u }
(-6) { 2 inPowerOf 1u }
}
},
"test 1"
)
assertEquals(
NumberedPolynomialAsIs(
listOf<UInt>() to -1,
),
Int.algebra.numberedPolynomialSpace {
NumberedPolynomial {
5 { }
(-6) { }
}
},
"test 2"
)
assertEquals(
NumberedPolynomialAsIs(
listOf(2u) to -1,
),
Int.algebra.numberedPolynomialSpace {
NumberedPolynomial {
5 { 1 inPowerOf 1u; 1 inPowerOf 1u }
(-6) { 1 inPowerOf 2u }
}
},
"test 3"
)
}
@Test
@UnstableKMathAPI
fun testFabric() {
assertEquals(
NumberedPolynomialAsIs(
listOf(2u, 0u, 3u) to 5,
listOf(0u, 1u) to -6,
),
Int.algebra {
NumberedPolynomial(
listOf(2u, 0u, 3u) to 5,
listOf(0u, 1u) to -6,
)
},
"test 1"
)
assertEquals(
NumberedPolynomialAsIs(
listOf(2u, 0u, 3u) to 5,
listOf(0u, 1u) to -6,
),
Int.algebra {
NumberedPolynomial(
listOf(2u, 0u, 3u, 0u) to 5,
listOf(0u, 1u, 0u, 0u) to -6,
)
},
"test 2"
)
assertEquals(
NumberedPolynomialAsIs(
listOf<UInt>() to -1,
),
Int.algebra {
NumberedPolynomial(
listOf(0u) to 5,
listOf(0u, 0u) to -6,
)
},
"test 3"
)
assertEquals(
NumberedPolynomialAsIs(
listOf<UInt>() to 0,
),
Int.algebra {
NumberedPolynomial(
listOf(0u) to 5,
listOf(0u, 0u) to -5,
)
},
"test 4"
)
}
}

View File

@ -7,6 +7,7 @@ package space.kscience.kmath.test.misc
import space.kscience.kmath.functions.ListPolynomial
import space.kscience.kmath.functions.ListPolynomialSpace
import space.kscience.kmath.functions.PolynomialSpaceOverRing
import space.kscience.kmath.operations.Ring
@ -135,4 +136,7 @@ class IntModuloRing : Ring<IntModulo> {
fun ListPolynomialSpace<IntModulo, IntModuloRing>.ListPolynomial(vararg coefs: Int): ListPolynomial<IntModulo> =
ListPolynomial(coefs.map { IntModulo(it, ring.modulus) })
fun IntModuloRing.ListPolynomial(vararg coefs: Int): ListPolynomial<IntModulo> =
ListPolynomial(coefs.map { IntModulo(it, modulus) })
ListPolynomial(coefs.map { IntModulo(it, modulus) })
fun IntModuloRing.m(arg: Int) = IntModulo(arg, modulus)
fun PolynomialSpaceOverRing<IntModulo, *, IntModuloRing>.m(arg: Int) = IntModulo(arg, ring.modulus)