Feature: Polynomials and rational functions #469
@ -6,9 +6,16 @@ plugins {
|
|||||||
|
|
||||||
description = "Functions, integration and interpolation"
|
description = "Functions, integration and interpolation"
|
||||||
|
|
||||||
kotlin.sourceSets.commonMain {
|
kotlin.sourceSets {
|
||||||
dependencies {
|
commonMain {
|
||||||
api(project(":kmath-core"))
|
dependencies {
|
||||||
|
api(project(":kmath-core"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commonTest {
|
||||||
|
dependencies {
|
||||||
|
api(projects.testUtilsFunctions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,10 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
import space.kscience.kmath.test.misc.*
|
import space.kscience.kmath.functions.testUtils.IntModuloRing
|
||||||
|
import space.kscience.kmath.functions.testUtils.ListPolynomial
|
||||||
|
import space.kscience.kmath.functions.testUtils.Rational
|
||||||
|
import space.kscience.kmath.functions.testUtils.RationalField
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +6,9 @@
|
|||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.test.misc.Rational
|
import space.kscience.kmath.functions.testUtils.Rational
|
||||||
import space.kscience.kmath.test.misc.RationalField
|
import space.kscience.kmath.functions.testUtils.RationalField
|
||||||
import space.kscience.kmath.test.misc.assertFailsWithTypeAndMessage
|
import space.kscience.kmath.functions.testUtils.assertFailsWithTypeAndMessage
|
||||||
import kotlin.test.Ignore
|
import kotlin.test.Ignore
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
@ -64,7 +64,7 @@ class ListPolynomialUtilTest {
|
|||||||
)
|
)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Rational(25057, 21000),
|
Rational(25057, 21000),
|
||||||
ListPolynomial(Rational(5,8), Rational(8, 3), Rational(4, 7), Rational(3, 2))
|
ListPolynomial(Rational(5, 8), Rational(8, 3), Rational(4, 7), Rational(3, 2))
|
||||||
.substitute(RationalField, Rational(1, 5)),
|
.substitute(RationalField, Rational(1, 5)),
|
||||||
"test 2"
|
"test 2"
|
||||||
)
|
)
|
||||||
@ -76,13 +76,13 @@ class ListPolynomialUtilTest {
|
|||||||
)
|
)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Rational(4961, 4200),
|
Rational(4961, 4200),
|
||||||
ListPolynomial(Rational(5,8), Rational(8, 3), Rational(4, 7), Rational(0))
|
ListPolynomial(Rational(5, 8), Rational(8, 3), Rational(4, 7), Rational(0))
|
||||||
.substitute(RationalField, Rational(1, 5)),
|
.substitute(RationalField, Rational(1, 5)),
|
||||||
"test 4"
|
"test 4"
|
||||||
)
|
)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
Rational(3511, 3000),
|
Rational(3511, 3000),
|
||||||
ListPolynomial(Rational(5,8), Rational(8, 3), Rational(0), Rational(3, 2))
|
ListPolynomial(Rational(5, 8), Rational(8, 3), Rational(0), Rational(3, 2))
|
||||||
.substitute(RationalField, Rational(1, 5)),
|
.substitute(RationalField, Rational(1, 5)),
|
||||||
"test 5"
|
"test 5"
|
||||||
)
|
)
|
||||||
@ -233,7 +233,7 @@ class ListPolynomialUtilTest {
|
|||||||
ListPolynomial(
|
ListPolynomial(
|
||||||
Rational(-13, 9),
|
Rational(-13, 9),
|
||||||
Rational(5, 3),
|
Rational(5, 3),
|
||||||
Rational(-5, 4) ,
|
Rational(-5, 4),
|
||||||
Rational(0),
|
Rational(0),
|
||||||
Rational(0),
|
Rational(0),
|
||||||
Rational(0),
|
Rational(0),
|
||||||
|
30
kmath-polynomialX/build.gradle.kts
Normal file
30
kmath-polynomialX/build.gradle.kts
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
|
id("ru.mipt.npm.gradle.common")
|
||||||
|
id("ru.mipt.npm.gradle.native")
|
||||||
|
}
|
||||||
|
|
||||||
|
description = "Polynomial extra utilities and rational functions"
|
||||||
|
|
||||||
|
kotlin.sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api(projects.kmathCore)
|
||||||
|
api(projects.kmathFunctions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
commonTest {
|
||||||
|
dependencies {
|
||||||
|
api(projects.testUtilsFunctions)
|
||||||
|
api(projects.testUtilsPolynomialX)
|
||||||
|
api(kotlin("test"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readme {
|
||||||
|
maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE
|
||||||
|
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
|
||||||
|
|
||||||
|
// feature("TODO") { "TODO" }
|
||||||
|
}
|
@ -0,0 +1,146 @@
|
|||||||
|
/*
|
||||||
|
* 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.operations.*
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: All of this should be moved to algebraic structures' place for utilities
|
||||||
|
// FIXME: Move receiver to context receiver
|
||||||
|
/**
|
||||||
|
* Returns product of [arg] and integer [multiplier].
|
||||||
|
*
|
||||||
|
* @param arg the multiplicand.
|
||||||
|
* @param multiplier the integer multiplier.
|
||||||
|
* @return product of the multiplicand [arg] and the multiplier [multiplier].
|
||||||
|
* @author Gleb Minaev
|
||||||
|
*/
|
||||||
|
internal fun <C> Group<C>.multiplyByDoubling(arg: C, multiplier: Int): C =
|
||||||
|
if (multiplier >= 0) multiplyByDoubling(arg, multiplier.toUInt())
|
||||||
|
else multiplyByDoubling(-arg, (-multiplier).toUInt())
|
||||||
|
|
||||||
|
// FIXME: Move receiver to context receiver
|
||||||
|
/**
|
||||||
|
* Adds product of [arg] and [multiplier] to [base].
|
||||||
|
*
|
||||||
|
* @param base the augend.
|
||||||
|
* @param arg the multiplicand.
|
||||||
|
* @param multiplier the integer multiplier.
|
||||||
|
* @return sum of the augend [base] and product of the multiplicand [arg] and the multiplier [multiplier].
|
||||||
|
* @author Gleb Minaev
|
||||||
|
*/
|
||||||
|
internal fun <C> GroupOps<C>.addMultipliedByDoubling(base: C, arg: C, multiplier: Int): C =
|
||||||
|
if (multiplier >= 0) addMultipliedByDoubling(base, arg, multiplier.toUInt())
|
||||||
|
else addMultipliedByDoubling(base, -arg, (-multiplier).toUInt())
|
||||||
|
|
||||||
|
// FIXME: Move receiver to context receiver
|
||||||
|
/**
|
||||||
|
* Returns product of [arg] and integer [multiplier].
|
||||||
|
*
|
||||||
|
* This is implementation of variation of [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring)
|
||||||
|
*
|
||||||
|
* @param arg the multiplicand.
|
||||||
|
* @param multiplier the integer multiplier.
|
||||||
|
* @return product of the multiplicand [arg] and the multiplier [multiplier].
|
||||||
|
* @author Gleb Minaev
|
||||||
|
*/
|
||||||
|
internal tailrec fun <C> Group<C>.multiplyByDoubling(arg: C, multiplier: UInt): C =
|
||||||
|
when {
|
||||||
|
multiplier == 0u -> zero
|
||||||
|
multiplier == 1u -> arg
|
||||||
|
multiplier and 1u == 0u -> multiplyByDoubling(arg + arg, multiplier shr 1)
|
||||||
|
multiplier and 1u == 1u -> addMultipliedByDoubling(arg, arg + arg, multiplier shr 1)
|
||||||
|
else -> error("Error in multiplication group instant by unsigned integer: got reminder by division by 2 different from 0 and 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Move receiver to context receiver
|
||||||
|
/**
|
||||||
|
* Adds product of [arg] and [multiplier] to [base].
|
||||||
|
*
|
||||||
|
* This is implementation of variation of [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring)
|
||||||
|
*
|
||||||
|
* @param base the augend.
|
||||||
|
* @param arg the multiplicand.
|
||||||
|
* @param multiplier the integer multiplier.
|
||||||
|
* @return sum of the augend [base] and product of the multiplicand [arg] and the multiplier [multiplier].
|
||||||
|
* @author Gleb Minaev
|
||||||
|
*/
|
||||||
|
internal tailrec fun <C> GroupOps<C>.addMultipliedByDoubling(base: C, arg: C, multiplier: UInt): C =
|
||||||
|
when {
|
||||||
|
multiplier == 0u -> base
|
||||||
|
multiplier == 1u -> base + arg
|
||||||
|
multiplier and 1u == 0u -> addMultipliedByDoubling(base, arg + arg, multiplier shr 1)
|
||||||
|
multiplier and 1u == 1u -> addMultipliedByDoubling(base + arg, arg + arg, multiplier shr 1)
|
||||||
|
else -> error("Error in multiplication group instant by unsigned integer: got reminder by division by 2 different from 0 and 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Move receiver to context receiver
|
||||||
|
/**
|
||||||
|
* Raises [arg] to the integer power [exponent].
|
||||||
|
*
|
||||||
|
* @param arg the base of the power.
|
||||||
|
* @param exponent the exponent of the power.
|
||||||
|
* @return [arg] raised to the power [exponent].
|
||||||
|
* @author Gleb Minaev
|
||||||
|
*/
|
||||||
|
internal fun <C> Field<C>.exponentiateBySquaring(arg: C, exponent: Int): C =
|
||||||
|
if (exponent >= 0) exponentiateBySquaring(arg, exponent.toUInt())
|
||||||
|
else exponentiateBySquaring(one / arg, (-exponent).toUInt())
|
||||||
|
|
||||||
|
// FIXME: Move receiver to context receiver
|
||||||
|
/**
|
||||||
|
* Multiplies [base] and [arg] raised to the integer power [exponent].
|
||||||
|
*
|
||||||
|
* @param base the multiplicand.
|
||||||
|
* @param arg the base of the power.
|
||||||
|
* @param exponent the exponent of the power.
|
||||||
|
* @return product of [base] and [arg] raised to the power [exponent].
|
||||||
|
* @author Gleb Minaev
|
||||||
|
*/
|
||||||
|
internal fun <C> Field<C>.multiplyExponentiatedBySquaring(base: C, arg: C, exponent: Int): C =
|
||||||
|
if (exponent >= 0) multiplyExponentiatedBySquaring(base, arg, exponent.toUInt())
|
||||||
|
else multiplyExponentiatedBySquaring(base, one / arg, (-exponent).toUInt())
|
||||||
|
|
||||||
|
// FIXME: Move receiver to context receiver
|
||||||
|
/**
|
||||||
|
* Raises [arg] to the integer power [exponent].
|
||||||
|
*
|
||||||
|
* This is implementation of variation of [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring)
|
||||||
|
*
|
||||||
|
* @param arg the base of the power.
|
||||||
|
* @param exponent the exponent of the power.
|
||||||
|
* @return [arg] raised to the power [exponent].
|
||||||
|
* @author Gleb Minaev
|
||||||
|
*/
|
||||||
|
internal tailrec fun <C> Ring<C>.exponentiateBySquaring(arg: C, exponent: UInt): C =
|
||||||
|
when {
|
||||||
|
exponent == 0u -> zero
|
||||||
|
exponent == 1u -> arg
|
||||||
|
exponent and 1u == 0u -> exponentiateBySquaring(arg * arg, exponent shr 1)
|
||||||
|
exponent and 1u == 1u -> multiplyExponentiatedBySquaring(arg, arg * arg, exponent shr 1)
|
||||||
|
else -> error("Error in multiplication group instant by unsigned integer: got reminder by division by 2 different from 0 and 1")
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Move receiver to context receiver
|
||||||
|
/**
|
||||||
|
* Multiplies [base] and [arg] raised to the integer power [exponent].
|
||||||
|
*
|
||||||
|
* This is implementation of variation of [exponentiation by squaring](https://en.wikipedia.org/wiki/Exponentiation_by_squaring)
|
||||||
|
*
|
||||||
|
* @param base the multiplicand.
|
||||||
|
* @param arg the base of the power.
|
||||||
|
* @param exponent the exponent of the power.
|
||||||
|
* @return product of [base] and [arg] raised to the power [exponent].
|
||||||
|
* @author Gleb Minaev
|
||||||
|
*/
|
||||||
|
internal tailrec fun <C> RingOps<C>.multiplyExponentiatedBySquaring(base: C, arg: C, exponent: UInt): C =
|
||||||
|
when {
|
||||||
|
exponent == 0u -> base
|
||||||
|
exponent == 1u -> base * arg
|
||||||
|
exponent and 1u == 0u -> multiplyExponentiatedBySquaring(base, arg * arg, exponent shr 1)
|
||||||
|
exponent and 1u == 1u -> multiplyExponentiatedBySquaring(base * arg, arg * arg, exponent shr 1)
|
||||||
|
else -> error("Error in multiplication group instant by unsigned integer: got reminder by division by 2 different from 0 and 1")
|
||||||
|
}
|
@ -6,19 +6,17 @@
|
|||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
import space.kscience.kmath.expressions.Symbol
|
import space.kscience.kmath.expressions.Symbol
|
||||||
import space.kscience.kmath.expressions.symbol
|
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.algebra
|
import space.kscience.kmath.operations.algebra
|
||||||
import space.kscience.kmath.operations.invoke
|
import space.kscience.kmath.operations.invoke
|
||||||
|
import space.kscience.kmath.functions.testUtils.t
|
||||||
|
import space.kscience.kmath.functions.testUtils.x
|
||||||
|
import space.kscience.kmath.functions.testUtils.y
|
||||||
|
import space.kscience.kmath.functions.testUtils.z
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class LabeledConstructorsTest {
|
class LabeledConstructorsTest {
|
||||||
val x by symbol
|
|
||||||
val y by symbol
|
|
||||||
val z by symbol
|
|
||||||
val t by symbol
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
fun testDSL1() {
|
fun testDSL1() {
|
@ -8,25 +8,22 @@
|
|||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
import space.kscience.kmath.expressions.Symbol
|
import space.kscience.kmath.expressions.Symbol
|
||||||
import space.kscience.kmath.expressions.symbol
|
import space.kscience.kmath.functions.testUtils.IntModuloRing
|
||||||
import space.kscience.kmath.test.misc.IntModuloRing
|
import space.kscience.kmath.functions.testUtils.Rational
|
||||||
import space.kscience.kmath.test.misc.Rational
|
import space.kscience.kmath.functions.testUtils.RationalField
|
||||||
import space.kscience.kmath.test.misc.RationalField
|
import space.kscience.kmath.functions.testUtils.o
|
||||||
import space.kscience.kmath.test.misc.m
|
import space.kscience.kmath.functions.testUtils.m
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
import space.kscience.kmath.functions.testUtils.x
|
||||||
|
import space.kscience.kmath.functions.testUtils.y
|
||||||
|
import space.kscience.kmath.functions.testUtils.z
|
||||||
|
import space.kscience.kmath.functions.testUtils.t
|
||||||
|
import space.kscience.kmath.functions.testUtils.s
|
||||||
|
import space.kscience.kmath.functions.testUtils.iota
|
||||||
|
|
||||||
|
|
||||||
// TODO: Тесты на конвертацию.
|
// TODO: Тесты на конвертацию.
|
||||||
class LabeledPolynomialTest {
|
class LabeledPolynomialTest {
|
||||||
val x by symbol
|
|
||||||
val y by symbol
|
|
||||||
val z by symbol
|
|
||||||
val t by symbol
|
|
||||||
val s by symbol
|
|
||||||
val iota by symbol
|
|
||||||
|
|
||||||
val o = Rational(0)
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun test_Variable_Int_plus() {
|
fun test_Variable_Int_plus() {
|
||||||
RationalField.labeledPolynomialSpace {
|
RationalField.labeledPolynomialSpace {
|
@ -6,20 +6,18 @@
|
|||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
import space.kscience.kmath.expressions.Symbol
|
import space.kscience.kmath.expressions.Symbol
|
||||||
import space.kscience.kmath.expressions.symbol
|
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.test.misc.Rational
|
import space.kscience.kmath.functions.testUtils.Rational
|
||||||
import space.kscience.kmath.test.misc.RationalField
|
import space.kscience.kmath.functions.testUtils.RationalField
|
||||||
import space.kscience.kmath.test.misc.assertEquals
|
|
||||||
import kotlin.test.Ignore
|
import kotlin.test.Ignore
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
import space.kscience.kmath.functions.testUtils.x
|
||||||
|
import space.kscience.kmath.functions.testUtils.y
|
||||||
|
import space.kscience.kmath.functions.testUtils.iota
|
||||||
|
import space.kscience.kmath.functions.testUtils.assertEquals
|
||||||
|
|
||||||
class LabeledPolynomialUtilTest {
|
class LabeledPolynomialUtilTest {
|
||||||
val x by symbol
|
|
||||||
val y by symbol
|
|
||||||
val iota by symbol
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun test_Polynomial_substitute_Double() {
|
fun test_Polynomial_substitute_Double() {
|
||||||
assertEquals(
|
assertEquals(
|
@ -7,10 +7,11 @@
|
|||||||
|
|
||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
import space.kscience.kmath.test.misc.IntModuloRing
|
import space.kscience.kmath.functions.testUtils.IntModuloRing
|
||||||
import space.kscience.kmath.test.misc.Rational
|
import space.kscience.kmath.functions.testUtils.Rational
|
||||||
import space.kscience.kmath.test.misc.RationalField
|
import space.kscience.kmath.functions.testUtils.RationalField
|
||||||
import space.kscience.kmath.test.misc.m
|
import space.kscience.kmath.functions.testUtils.m
|
||||||
|
import space.kscience.kmath.functions.testUtils.o
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertSame
|
import kotlin.test.assertSame
|
||||||
@ -18,8 +19,6 @@ import kotlin.test.fail
|
|||||||
|
|
||||||
|
|
||||||
class NumberedPolynomialTest {
|
class NumberedPolynomialTest {
|
||||||
val o = Rational(0)
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun test_Polynomial_Int_plus() {
|
fun test_Polynomial_Int_plus() {
|
||||||
RationalField.numberedPolynomialSpace {
|
RationalField.numberedPolynomialSpace {
|
@ -6,19 +6,16 @@
|
|||||||
package space.kscience.kmath.functions
|
package space.kscience.kmath.functions
|
||||||
|
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.structures.Buffer
|
import space.kscience.kmath.functions.testUtils.Rational
|
||||||
import space.kscience.kmath.structures.asBuffer
|
import space.kscience.kmath.functions.testUtils.RationalField
|
||||||
import space.kscience.kmath.test.misc.Rational
|
import space.kscience.kmath.functions.testUtils.assertFailsWithTypeAndMessage
|
||||||
import space.kscience.kmath.test.misc.RationalField
|
|
||||||
import space.kscience.kmath.test.misc.assertEquals
|
|
||||||
import space.kscience.kmath.test.misc.assertFailsWithTypeAndMessage
|
|
||||||
import kotlin.test.Ignore
|
import kotlin.test.Ignore
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
import space.kscience.kmath.functions.testUtils.bufferOf
|
||||||
|
import space.kscience.kmath.functions.testUtils.assertEquals
|
||||||
|
|
||||||
|
|
||||||
fun <T> bufferOf(vararg elements: T): Buffer<T> = elements.asBuffer()
|
|
||||||
|
|
||||||
class NumberedPolynomialUtilTest {
|
class NumberedPolynomialUtilTest {
|
||||||
@Test
|
@Test
|
||||||
fun test_Polynomial_substitute_Double_Map() {
|
fun test_Polynomial_substitute_Double_Map() {
|
@ -26,6 +26,9 @@ include(
|
|||||||
":kmath-core",
|
":kmath-core",
|
||||||
":kmath-coroutines",
|
":kmath-coroutines",
|
||||||
":kmath-functions",
|
":kmath-functions",
|
||||||
|
":test-utils-functions",
|
||||||
|
":kmath-polynomialX",
|
||||||
|
":test-utils-polynomialX",
|
||||||
":kmath-histograms",
|
":kmath-histograms",
|
||||||
":kmath-commons",
|
":kmath-commons",
|
||||||
":kmath-viktor",
|
":kmath-viktor",
|
||||||
|
14
test-utils-functions/build.gradle.kts
Normal file
14
test-utils-functions/build.gradle.kts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
plugins {
|
||||||
|
id("ru.mipt.npm.gradle.mpp")
|
||||||
|
id("ru.mipt.npm.gradle.native")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api(projects.kmathCore)
|
||||||
|
api(projects.kmathFunctions)
|
||||||
|
api(kotlin("test"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,40 +5,37 @@
|
|||||||
|
|
||||||
@file:Suppress("NOTHING_TO_INLINE", "KotlinRedundantDiagnosticSuppress")
|
@file:Suppress("NOTHING_TO_INLINE", "KotlinRedundantDiagnosticSuppress")
|
||||||
|
|
||||||
package space.kscience.kmath.test.misc
|
package space.kscience.kmath.functions.testUtils
|
||||||
|
|
||||||
import space.kscience.kmath.functions.ListPolynomial
|
|
||||||
import space.kscience.kmath.functions.ListPolynomialSpace
|
|
||||||
import space.kscience.kmath.functions.PolynomialSpaceOverRing
|
|
||||||
import space.kscience.kmath.operations.Ring
|
import space.kscience.kmath.operations.Ring
|
||||||
|
|
||||||
|
|
||||||
class IntModulo {
|
public class IntModulo {
|
||||||
val residue: Int
|
public val residue: Int
|
||||||
val modulus: Int
|
public val modulus: Int
|
||||||
|
|
||||||
@PublishedApi
|
@PublishedApi
|
||||||
internal constructor(residue: Int, modulus: Int, toCheckInput: Boolean = true) {
|
internal constructor(residue: Int, modulus: Int, toCheckInput: Boolean = true) {
|
||||||
if (toCheckInput) {
|
if (toCheckInput) {
|
||||||
require(modulus != 0) { "modulus can not be zero" }
|
require(modulus != 0) { "modulus can not be zero" }
|
||||||
this.modulus = if (modulus < 0) -modulus else modulus
|
this.modulus = if (modulus < 0) -modulus else modulus
|
||||||
this.residue = residue.mod(modulus)
|
this.residue = residue.mod(this.modulus)
|
||||||
} else {
|
} else {
|
||||||
this.residue = residue
|
this.residue = residue
|
||||||
this.modulus = modulus
|
this.modulus = modulus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(residue: Int, modulus: Int) : this(residue, modulus, true)
|
public constructor(residue: Int, modulus: Int) : this(residue, modulus, true)
|
||||||
|
|
||||||
operator fun unaryPlus(): IntModulo = this
|
public operator fun unaryPlus(): IntModulo = this
|
||||||
operator fun unaryMinus(): IntModulo =
|
public operator fun unaryMinus(): IntModulo =
|
||||||
IntModulo(
|
IntModulo(
|
||||||
if (residue == 0) 0 else modulus - residue,
|
if (residue == 0) 0 else modulus - residue,
|
||||||
modulus,
|
modulus,
|
||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun plus(other: IntModulo): IntModulo {
|
public operator fun plus(other: IntModulo): IntModulo {
|
||||||
require(modulus == other.modulus) { "can not add two residue different modulo" }
|
require(modulus == other.modulus) { "can not add two residue different modulo" }
|
||||||
return IntModulo(
|
return IntModulo(
|
||||||
(residue + other.residue) % modulus,
|
(residue + other.residue) % modulus,
|
||||||
@ -46,13 +43,13 @@ class IntModulo {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun plus(other: Int): IntModulo =
|
public operator fun plus(other: Int): IntModulo =
|
||||||
IntModulo(
|
IntModulo(
|
||||||
(residue + other) % modulus,
|
(residue + other) % modulus,
|
||||||
modulus,
|
modulus,
|
||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun minus(other: IntModulo): IntModulo {
|
public operator fun minus(other: IntModulo): IntModulo {
|
||||||
require(modulus == other.modulus) { "can not subtract two residue different modulo" }
|
require(modulus == other.modulus) { "can not subtract two residue different modulo" }
|
||||||
return IntModulo(
|
return IntModulo(
|
||||||
(residue - other.residue) % modulus,
|
(residue - other.residue) % modulus,
|
||||||
@ -60,13 +57,13 @@ class IntModulo {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun minus(other: Int): IntModulo =
|
public operator fun minus(other: Int): IntModulo =
|
||||||
IntModulo(
|
IntModulo(
|
||||||
(residue - other) % modulus,
|
(residue - other) % modulus,
|
||||||
modulus,
|
modulus,
|
||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun times(other: IntModulo): IntModulo {
|
public operator fun times(other: IntModulo): IntModulo {
|
||||||
require(modulus == other.modulus) { "can not multiply two residue different modulo" }
|
require(modulus == other.modulus) { "can not multiply two residue different modulo" }
|
||||||
return IntModulo(
|
return IntModulo(
|
||||||
(residue * other.residue) % modulus,
|
(residue * other.residue) % modulus,
|
||||||
@ -74,13 +71,13 @@ class IntModulo {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun times(other: Int): IntModulo =
|
public operator fun times(other: Int): IntModulo =
|
||||||
IntModulo(
|
IntModulo(
|
||||||
(residue * other) % modulus,
|
(residue * other) % modulus,
|
||||||
modulus,
|
modulus,
|
||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun div(other: IntModulo): IntModulo {
|
public operator fun div(other: IntModulo): IntModulo {
|
||||||
require(modulus == other.modulus) { "can not divide two residue different modulo" }
|
require(modulus == other.modulus) { "can not divide two residue different modulo" }
|
||||||
val (reciprocalCandidate, gcdOfOtherResidueAndModulus) = bezoutIdentityWithGCD(other.residue, modulus)
|
val (reciprocalCandidate, gcdOfOtherResidueAndModulus) = bezoutIdentityWithGCD(other.residue, modulus)
|
||||||
require(gcdOfOtherResidueAndModulus == 1) { "can not divide to residue that has non-trivial GCD with modulo" }
|
require(gcdOfOtherResidueAndModulus == 1) { "can not divide to residue that has non-trivial GCD with modulo" }
|
||||||
@ -90,7 +87,7 @@ class IntModulo {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun div(other: Int): IntModulo {
|
public operator fun div(other: Int): IntModulo {
|
||||||
val (reciprocalCandidate, gcdOfOtherResidueAndModulus) = bezoutIdentityWithGCD(other, modulus)
|
val (reciprocalCandidate, gcdOfOtherResidueAndModulus) = bezoutIdentityWithGCD(other, modulus)
|
||||||
require(gcdOfOtherResidueAndModulus == 1) { "can not divide to residue that has non-trivial GCD with modulo" }
|
require(gcdOfOtherResidueAndModulus == 1) { "can not divide to residue that has non-trivial GCD with modulo" }
|
||||||
return IntModulo(
|
return IntModulo(
|
||||||
@ -111,11 +108,11 @@ class IntModulo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
||||||
class IntModuloRing : Ring<IntModulo> {
|
public class IntModuloRing : Ring<IntModulo> {
|
||||||
|
|
||||||
val modulus: Int
|
public val modulus: Int
|
||||||
|
|
||||||
constructor(modulus: Int) {
|
public constructor(modulus: Int) {
|
||||||
require(modulus != 0) { "modulus can not be zero" }
|
require(modulus != 0) { "modulus can not be zero" }
|
||||||
this.modulus = if (modulus < 0) -modulus else modulus
|
this.modulus = if (modulus < 0) -modulus else modulus
|
||||||
}
|
}
|
||||||
@ -123,7 +120,7 @@ class IntModuloRing : Ring<IntModulo> {
|
|||||||
override inline val zero: IntModulo get() = IntModulo(0, modulus, toCheckInput = false)
|
override inline val zero: IntModulo get() = IntModulo(0, modulus, toCheckInput = false)
|
||||||
override inline val one: IntModulo get() = IntModulo(1, modulus, toCheckInput = false)
|
override inline val one: IntModulo get() = IntModulo(1, modulus, toCheckInput = false)
|
||||||
|
|
||||||
fun number(arg: Int) = IntModulo(arg, modulus, toCheckInput = false)
|
public fun number(arg: Int): IntModulo = IntModulo(arg, modulus, toCheckInput = false)
|
||||||
|
|
||||||
override inline fun add(left: IntModulo, right: IntModulo): IntModulo = left + right
|
override inline fun add(left: IntModulo, right: IntModulo): IntModulo = left + right
|
||||||
override inline fun multiply(left: IntModulo, right: IntModulo): IntModulo = left * right
|
override inline fun multiply(left: IntModulo, right: IntModulo): IntModulo = left * right
|
||||||
@ -132,13 +129,5 @@ class IntModuloRing : Ring<IntModulo> {
|
|||||||
override inline fun IntModulo.plus(arg: IntModulo): IntModulo = this + arg
|
override inline fun IntModulo.plus(arg: IntModulo): IntModulo = this + arg
|
||||||
override inline fun IntModulo.minus(arg: IntModulo): IntModulo = this - arg
|
override inline fun IntModulo.minus(arg: IntModulo): IntModulo = this - arg
|
||||||
override inline fun IntModulo.times(arg: IntModulo): IntModulo = this * arg
|
override inline fun IntModulo.times(arg: IntModulo): IntModulo = this * arg
|
||||||
inline fun IntModulo.div(arg: IntModulo): IntModulo = this / arg
|
public inline fun IntModulo.div(arg: IntModulo): IntModulo = this / arg
|
||||||
}
|
}
|
||||||
|
|
||||||
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) })
|
|
||||||
|
|
||||||
fun IntModuloRing.m(arg: Int) = IntModulo(arg, modulus)
|
|
||||||
fun PolynomialSpaceOverRing<IntModulo, *, IntModuloRing>.m(arg: Int) = IntModulo(arg, ring.modulus)
|
|
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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.testUtils
|
||||||
|
|
||||||
|
import space.kscience.kmath.functions.ListPolynomial
|
||||||
|
import space.kscience.kmath.functions.ListPolynomialSpace
|
||||||
|
import space.kscience.kmath.functions.PolynomialSpaceOverRing
|
||||||
|
|
||||||
|
|
||||||
|
public fun ListPolynomialSpace<IntModulo, IntModuloRing>.ListPolynomial(vararg coefs: Int): ListPolynomial<IntModulo> =
|
||||||
|
ListPolynomial(coefs.map { IntModulo(it, ring.modulus) })
|
||||||
|
public fun IntModuloRing.ListPolynomial(vararg coefs: Int): ListPolynomial<IntModulo> =
|
||||||
|
ListPolynomial(coefs.map { IntModulo(it, modulus) })
|
||||||
|
|
||||||
|
public fun IntModuloRing.m(arg: Int): IntModulo = IntModulo(arg, modulus)
|
||||||
|
public fun PolynomialSpaceOverRing<IntModulo, *, IntModuloRing>.m(arg: Int): IntModulo = IntModulo(arg, ring.modulus)
|
@ -5,21 +5,21 @@
|
|||||||
|
|
||||||
@file:Suppress("NOTHING_TO_INLINE", "KotlinRedundantDiagnosticSuppress")
|
@file:Suppress("NOTHING_TO_INLINE", "KotlinRedundantDiagnosticSuppress")
|
||||||
|
|
||||||
package space.kscience.kmath.test.misc
|
package space.kscience.kmath.functions.testUtils
|
||||||
|
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
import space.kscience.kmath.operations.Field
|
import space.kscience.kmath.operations.Field
|
||||||
import space.kscience.kmath.operations.NumbersAddOps
|
import space.kscience.kmath.operations.NumbersAddOps
|
||||||
|
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
class Rational {
|
public class Rational {
|
||||||
companion object {
|
public companion object {
|
||||||
val ZERO: Rational = Rational(0L)
|
public val ZERO: Rational = Rational(0L)
|
||||||
val ONE: Rational = Rational(1L)
|
public val ONE: Rational = Rational(1L)
|
||||||
}
|
}
|
||||||
|
|
||||||
val numerator: Long
|
public val numerator: Long
|
||||||
val denominator: Long
|
public val denominator: Long
|
||||||
|
|
||||||
internal constructor(numerator: Long, denominator: Long, toCheckInput: Boolean = true) {
|
internal constructor(numerator: Long, denominator: Long, toCheckInput: Boolean = true) {
|
||||||
if (toCheckInput) {
|
if (toCheckInput) {
|
||||||
@ -35,16 +35,16 @@ class Rational {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(numerator: Int, denominator: Int) : this(numerator.toLong(), denominator.toLong(), true)
|
public constructor(numerator: Int, denominator: Int) : this(numerator.toLong(), denominator.toLong(), true)
|
||||||
constructor(numerator: Int, denominator: Long) : this(numerator.toLong(), denominator, true)
|
public constructor(numerator: Int, denominator: Long) : this(numerator.toLong(), denominator, true)
|
||||||
constructor(numerator: Long, denominator: Int) : this(numerator, denominator.toLong(), true)
|
public constructor(numerator: Long, denominator: Int) : this(numerator, denominator.toLong(), true)
|
||||||
constructor(numerator: Long, denominator: Long) : this(numerator, denominator, true)
|
public constructor(numerator: Long, denominator: Long) : this(numerator, denominator, true)
|
||||||
constructor(numerator: Int) : this(numerator.toLong(), 1L, false)
|
public constructor(numerator: Int) : this(numerator.toLong(), 1L, false)
|
||||||
constructor(numerator: Long) : this(numerator, 1L, false)
|
public constructor(numerator: Long) : this(numerator, 1L, false)
|
||||||
|
|
||||||
operator fun unaryPlus(): Rational = this
|
public operator fun unaryPlus(): Rational = this
|
||||||
operator fun unaryMinus(): Rational = Rational(-this.numerator, this.denominator)
|
public operator fun unaryMinus(): Rational = Rational(-this.numerator, this.denominator)
|
||||||
operator fun plus(other: Rational): Rational {
|
public operator fun plus(other: Rational): Rational {
|
||||||
val denominatorsGcd = gcd(denominator, other.denominator)
|
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||||
val dividedThisDenominator = denominator / denominatorsGcd
|
val dividedThisDenominator = denominator / denominatorsGcd
|
||||||
val dividedOtherDenominator = other.denominator / denominatorsGcd
|
val dividedOtherDenominator = other.denominator / denominatorsGcd
|
||||||
@ -56,19 +56,19 @@ class Rational {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun plus(other: Int): Rational =
|
public operator fun plus(other: Int): Rational =
|
||||||
Rational(
|
Rational(
|
||||||
numerator + denominator * other.toLong(),
|
numerator + denominator * other.toLong(),
|
||||||
denominator,
|
denominator,
|
||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun plus(other: Long): Rational =
|
public operator fun plus(other: Long): Rational =
|
||||||
Rational(
|
Rational(
|
||||||
numerator + denominator * other,
|
numerator + denominator * other,
|
||||||
denominator,
|
denominator,
|
||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun minus(other: Rational): Rational {
|
public operator fun minus(other: Rational): Rational {
|
||||||
val denominatorsGcd = gcd(denominator, other.denominator)
|
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||||
val dividedThisDenominator = denominator / denominatorsGcd
|
val dividedThisDenominator = denominator / denominatorsGcd
|
||||||
val dividedOtherDenominator = other.denominator / denominatorsGcd
|
val dividedOtherDenominator = other.denominator / denominatorsGcd
|
||||||
@ -80,19 +80,19 @@ class Rational {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun minus(other: Int): Rational =
|
public operator fun minus(other: Int): Rational =
|
||||||
Rational(
|
Rational(
|
||||||
numerator - denominator * other.toLong(),
|
numerator - denominator * other.toLong(),
|
||||||
denominator,
|
denominator,
|
||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun minus(other: Long): Rational =
|
public operator fun minus(other: Long): Rational =
|
||||||
Rational(
|
Rational(
|
||||||
numerator - denominator * other,
|
numerator - denominator * other,
|
||||||
denominator,
|
denominator,
|
||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
operator fun times(other: Rational): Rational {
|
public operator fun times(other: Rational): Rational {
|
||||||
val thisDenominatorAndOtherNumeratorGcd = gcd(denominator, other.numerator)
|
val thisDenominatorAndOtherNumeratorGcd = gcd(denominator, other.numerator)
|
||||||
val otherDenominatorAndThisNumeratorGcd = gcd(other.denominator, numerator)
|
val otherDenominatorAndThisNumeratorGcd = gcd(other.denominator, numerator)
|
||||||
return Rational(
|
return Rational(
|
||||||
@ -101,7 +101,7 @@ class Rational {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun times(other: Int): Rational {
|
public operator fun times(other: Int): Rational {
|
||||||
val other = other.toLong()
|
val other = other.toLong()
|
||||||
val denominatorAndOtherGcd = gcd(denominator, other)
|
val denominatorAndOtherGcd = gcd(denominator, other)
|
||||||
return Rational(
|
return Rational(
|
||||||
@ -110,7 +110,7 @@ class Rational {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun times(other: Long): Rational {
|
public operator fun times(other: Long): Rational {
|
||||||
val denominatorAndOtherGcd = gcd(denominator, other)
|
val denominatorAndOtherGcd = gcd(denominator, other)
|
||||||
return Rational(
|
return Rational(
|
||||||
numerator * (other / denominatorAndOtherGcd),
|
numerator * (other / denominatorAndOtherGcd),
|
||||||
@ -118,7 +118,7 @@ class Rational {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun div(other: Rational): Rational {
|
public operator fun div(other: Rational): Rational {
|
||||||
val denominatorsGcd = gcd(denominator, other.denominator)
|
val denominatorsGcd = gcd(denominator, other.denominator)
|
||||||
val numeratorsGcd = gcd(numerator, other.numerator)
|
val numeratorsGcd = gcd(numerator, other.numerator)
|
||||||
return Rational(
|
return Rational(
|
||||||
@ -126,7 +126,7 @@ class Rational {
|
|||||||
(denominator / denominatorsGcd) * (other.numerator / numeratorsGcd)
|
(denominator / denominatorsGcd) * (other.numerator / numeratorsGcd)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun div(other: Int): Rational {
|
public operator fun div(other: Int): Rational {
|
||||||
val other = other.toLong()
|
val other = other.toLong()
|
||||||
val numeratorAndOtherGcd = gcd(numerator, other)
|
val numeratorAndOtherGcd = gcd(numerator, other)
|
||||||
return Rational(
|
return Rational(
|
||||||
@ -135,7 +135,7 @@ class Rational {
|
|||||||
toCheckInput = false
|
toCheckInput = false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
operator fun div(other: Long): Rational {
|
public operator fun div(other: Long): Rational {
|
||||||
val numeratorAndOtherGcd = gcd(numerator, other)
|
val numeratorAndOtherGcd = gcd(numerator, other)
|
||||||
return Rational(
|
return Rational(
|
||||||
numerator / numeratorAndOtherGcd,
|
numerator / numeratorAndOtherGcd,
|
||||||
@ -158,7 +158,7 @@ class Rational {
|
|||||||
|
|
||||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE")
|
||||||
@OptIn(UnstableKMathAPI::class)
|
@OptIn(UnstableKMathAPI::class)
|
||||||
object RationalField : Field<Rational>, NumbersAddOps<Rational> {
|
public object RationalField : Field<Rational>, NumbersAddOps<Rational> {
|
||||||
override inline val zero: Rational get() = Rational.ZERO
|
override inline val zero: Rational get() = Rational.ZERO
|
||||||
override inline val one: Rational get() = Rational.ONE
|
override inline val one: Rational get() = Rational.ONE
|
||||||
|
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* 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.testUtils
|
||||||
|
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
|
|
||||||
|
public inline fun <reified T : Throwable> assertFailsWithTypeAndMessage(
|
||||||
|
expectedMessage: String? = null,
|
||||||
|
assertionMessage: String? = null,
|
||||||
|
block: () -> Unit
|
||||||
|
) {
|
||||||
|
assertEquals(
|
||||||
|
expectedMessage,
|
||||||
|
assertFailsWith(T::class, assertionMessage, block).message,
|
||||||
|
assertionMessage
|
||||||
|
)
|
||||||
|
}
|
@ -3,16 +3,16 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.test.misc
|
package space.kscience.kmath.functions.testUtils
|
||||||
|
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
|
||||||
data class BezoutIdentityWithGCD<T>(val first: T, val second: T, val gcd: T)
|
internal data class BezoutIdentityWithGCD<T>(val first: T, val second: T, val gcd: T)
|
||||||
|
|
||||||
tailrec fun gcd(a: Long, b: Long): Long = if (a == 0L) abs(b) else gcd(b % a, a)
|
internal tailrec fun gcd(a: Long, b: Long): Long = if (a == 0L) abs(b) else gcd(b % a, a)
|
||||||
|
|
||||||
fun bezoutIdentityWithGCD(a: Int, b: Int): BezoutIdentityWithGCD<Int> =
|
internal fun bezoutIdentityWithGCD(a: Int, b: Int): BezoutIdentityWithGCD<Int> =
|
||||||
when {
|
when {
|
||||||
a < 0 && b < 0 -> with(bezoutIdentityWithGCDInternalLogic(-a, -b, 1, 0, 0, 1)) { BezoutIdentityWithGCD(-first, -second, gcd) }
|
a < 0 && b < 0 -> with(bezoutIdentityWithGCDInternalLogic(-a, -b, 1, 0, 0, 1)) { BezoutIdentityWithGCD(-first, -second, gcd) }
|
||||||
a < 0 -> with(bezoutIdentityWithGCDInternalLogic(-a, b, 1, 0, 0, 1)) { BezoutIdentityWithGCD(-first, second, gcd) }
|
a < 0 -> with(bezoutIdentityWithGCDInternalLogic(-a, b, 1, 0, 0, 1)) { BezoutIdentityWithGCD(-first, second, gcd) }
|
16
test-utils-polynomialX/build.gradle.kts
Normal file
16
test-utils-polynomialX/build.gradle.kts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
plugins {
|
||||||
|
id("ru.mipt.npm.gradle.mpp")
|
||||||
|
id("ru.mipt.npm.gradle.native")
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin.sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api(projects.kmathCore)
|
||||||
|
api(projects.kmathFunctions)
|
||||||
|
api(projects.testUtilsFunctions)
|
||||||
|
api(projects.kmathPolynomialX)
|
||||||
|
api(kotlin("test"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
/*
|
||||||
|
* 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.testUtils
|
||||||
|
|
||||||
|
import space.kscience.kmath.structures.Buffer
|
||||||
|
import space.kscience.kmath.structures.asBuffer
|
||||||
|
|
||||||
|
|
||||||
|
public fun <T> bufferOf(vararg elements: T): Buffer<T> = elements.asBuffer()
|
@ -3,7 +3,7 @@
|
|||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* 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.test.misc
|
package space.kscience.kmath.functions.testUtils
|
||||||
|
|
||||||
import space.kscience.kmath.functions.LabeledPolynomial
|
import space.kscience.kmath.functions.LabeledPolynomial
|
||||||
import space.kscience.kmath.functions.LabeledRationalFunction
|
import space.kscience.kmath.functions.LabeledRationalFunction
|
||||||
@ -13,36 +13,45 @@ import kotlin.test.assertEquals
|
|||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
|
||||||
|
|
||||||
fun <T> assertContentEquals(expected: Map<T, Double>, actual: Map<T, Double>, absoluteTolerance: Double, message: String? = null) {
|
public fun <T> assertContentEquals(
|
||||||
|
expected: Map<T, Double>,
|
||||||
|
actual: Map<T, Double>,
|
||||||
|
absoluteTolerance: Double,
|
||||||
|
message: String? = null
|
||||||
|
) {
|
||||||
assertEquals(expected.keys, actual.keys, message)
|
assertEquals(expected.keys, actual.keys, message)
|
||||||
for ((key, expectedValue) in expected) assertEquals(expectedValue, actual[key]!!, absoluteTolerance, message)
|
for ((key, expectedValue) in expected) assertEquals(expectedValue, actual[key]!!, absoluteTolerance, message)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertEquals(
|
public fun assertEquals(
|
||||||
expected: NumberedPolynomial<Double>,
|
expected: NumberedPolynomial<Double>,
|
||||||
actual: NumberedPolynomial<Double>,
|
actual: NumberedPolynomial<Double>,
|
||||||
absoluteTolerance: Double,
|
absoluteTolerance: Double,
|
||||||
message: String? = null
|
message: String? = null
|
||||||
) = assertContentEquals(
|
) {
|
||||||
expected.coefficients,
|
assertContentEquals(
|
||||||
actual.coefficients,
|
expected.coefficients,
|
||||||
absoluteTolerance,
|
actual.coefficients,
|
||||||
message
|
absoluteTolerance,
|
||||||
)
|
message
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun assertEquals(
|
public fun assertEquals(
|
||||||
expected: LabeledPolynomial<Double>,
|
expected: LabeledPolynomial<Double>,
|
||||||
actual: LabeledPolynomial<Double>,
|
actual: LabeledPolynomial<Double>,
|
||||||
absoluteTolerance: Double,
|
absoluteTolerance: Double,
|
||||||
message: String? = null
|
message: String? = null
|
||||||
) = assertContentEquals(
|
) {
|
||||||
expected.coefficients,
|
assertContentEquals(
|
||||||
actual.coefficients,
|
expected.coefficients,
|
||||||
absoluteTolerance,
|
actual.coefficients,
|
||||||
message
|
absoluteTolerance,
|
||||||
)
|
message
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fun assertEquals(
|
public fun assertEquals(
|
||||||
expected: NumberedRationalFunction<Double>,
|
expected: NumberedRationalFunction<Double>,
|
||||||
actual: NumberedRationalFunction<Double>,
|
actual: NumberedRationalFunction<Double>,
|
||||||
absoluteTolerance: Double,
|
absoluteTolerance: Double,
|
||||||
@ -62,7 +71,7 @@ fun assertEquals(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun assertEquals(
|
public fun assertEquals(
|
||||||
expected: LabeledRationalFunction<Double>,
|
expected: LabeledRationalFunction<Double>,
|
||||||
actual: LabeledRationalFunction<Double>,
|
actual: LabeledRationalFunction<Double>,
|
||||||
absoluteTolerance: Double,
|
absoluteTolerance: Double,
|
||||||
@ -82,13 +91,15 @@ fun assertEquals(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun <reified T : Throwable> assertFailsWithTypeAndMessage(
|
// FIXME: Don't understand why but the same function from test-utils-functions module can not be used
|
||||||
|
public inline fun <reified T : Throwable> assertFailsWithTypeAndMessage(
|
||||||
expectedMessage: String? = null,
|
expectedMessage: String? = null,
|
||||||
assertionMessage: String? = null,
|
assertionMessage: String? = null,
|
||||||
block: () -> Unit
|
block: () -> Unit
|
||||||
) =
|
) {
|
||||||
assertEquals(
|
assertEquals(
|
||||||
expectedMessage,
|
expectedMessage,
|
||||||
assertFailsWith(T::class, assertionMessage, block).message,
|
assertFailsWith(T::class, assertionMessage, block).message,
|
||||||
assertionMessage
|
assertionMessage
|
||||||
)
|
)
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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.testUtils
|
||||||
|
|
||||||
|
import space.kscience.kmath.expressions.Symbol
|
||||||
|
import space.kscience.kmath.expressions.symbol
|
||||||
|
|
||||||
|
|
||||||
|
public val o: Rational = Rational(0)
|
||||||
|
|
||||||
|
public val x: Symbol by symbol
|
||||||
|
public val y: Symbol by symbol
|
||||||
|
public val z: Symbol by symbol
|
||||||
|
public val t: Symbol by symbol
|
||||||
|
public val s: Symbol by symbol
|
||||||
|
public val iota: Symbol by symbol
|
Loading…
Reference in New Issue
Block a user