Draft implementation of RemainderDivision algebra #119

Closed
CommanderTvis wants to merge 10 commits from rem-and-div into dev
3 changed files with 51 additions and 12 deletions

View File

@ -1,6 +1,5 @@
package scientifik.kmath.operations package scientifik.kmath.operations
import scientifik.kmath.operations.RealField.pow
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.pow as kpow import kotlin.math.pow as kpow
@ -177,7 +176,7 @@ object FloatField : ExtendedField<Float>, Norm<Float, Float> {
* A field for [Int] without boxing. Does not produce corresponding ring element. * A field for [Int] without boxing. Does not produce corresponding ring element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
object IntRing : Ring<Int>, Norm<Int, Int> { object IntRing : Ring<Int>, Norm<Int, Int>, RemainderDivisionOperations<Int> {
override val zero: Int override val zero: Int
get() = 0 get() = 0
@ -195,13 +194,16 @@ object IntRing : Ring<Int>, Norm<Int, Int> {
override inline fun Int.plus(b: Int): Int = this + b override inline fun Int.plus(b: Int): Int = this + b
override inline fun Int.minus(b: Int): Int = this - b override inline fun Int.minus(b: Int): Int = this - b
override inline fun Int.times(b: Int): Int = this * b override inline fun Int.times(b: Int): Int = this * b
override fun Int.rem(arg: Int): Int = this % arg
override fun Int.div(arg: Int): Int = this / arg
} }
/** /**
* A field for [Short] without boxing. Does not produce appropriate ring element. * A field for [Short] without boxing. Does not produce appropriate ring element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
object ShortRing : Ring<Short>, Norm<Short, Short> { object ShortRing : Ring<Short>, Norm<Short, Short>, RemainderDivisionOperations<Short> {
override val zero: Short override val zero: Short
get() = 0 get() = 0
@ -219,13 +221,16 @@ object ShortRing : Ring<Short>, Norm<Short, Short> {
override inline fun Short.plus(b: Short): Short = (this + b).toShort() override inline fun Short.plus(b: Short): Short = (this + b).toShort()
override inline fun Short.minus(b: Short): Short = (this - b).toShort() override inline fun Short.minus(b: Short): Short = (this - b).toShort()
override inline fun Short.times(b: Short): Short = (this * b).toShort() override inline fun Short.times(b: Short): Short = (this * b).toShort()
override fun Short.rem(arg: Short): Short = (this % arg).toShort()
override fun Short.div(arg: Short): Short = (this / arg).toShort()
} }
/** /**
* A field for [Byte] without boxing. Does not produce appropriate ring element. * A field for [Byte] without boxing. Does not produce appropriate ring element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
object ByteRing : Ring<Byte>, Norm<Byte, Byte> { object ByteRing : Ring<Byte>, Norm<Byte, Byte>, RemainderDivisionOperations<Byte> {
override val zero: Byte override val zero: Byte
get() = 0 get() = 0
@ -243,20 +248,23 @@ object ByteRing : Ring<Byte>, Norm<Byte, Byte> {
override inline fun Byte.plus(b: Byte): Byte = (this + b).toByte() override inline fun Byte.plus(b: Byte): Byte = (this + b).toByte()
override inline fun Byte.minus(b: Byte): Byte = (this - b).toByte() override inline fun Byte.minus(b: Byte): Byte = (this - b).toByte()
override inline fun Byte.times(b: Byte): Byte = (this * b).toByte() override inline fun Byte.times(b: Byte): Byte = (this * b).toByte()
override fun Byte.rem(arg: Byte): Byte = (this % arg).toByte()
override fun Byte.div(arg: Byte): Byte = (this / arg).toByte()
} }
/** /**
* A field for [Double] without boxing. Does not produce appropriate ring element. * A field for [Double] without boxing. Does not produce appropriate ring element.
*/ */
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
object LongRing : Ring<Long>, Norm<Long, Long> { object LongRing : Ring<Long>, Norm<Long, Long>, RemainderDivisionOperations<Long> {
override val zero: Long override val zero: Long
get() = 0 get() = 0
override val one: Long override val one: Long
get() = 1 get() = 1
override inline fun add(a: Long, b: Long): Long = a + b override inline fun add(a: Long, b: Long): Long = (a + b)
override inline fun multiply(a: Long, k: Number): Long = a * k.toLong() override inline fun multiply(a: Long, k: Number): Long = a * k.toLong()
override inline fun multiply(a: Long, b: Long): Long = a * b override inline fun multiply(a: Long, b: Long): Long = a * b
@ -267,4 +275,7 @@ object LongRing : Ring<Long>, Norm<Long, Long> {
override inline fun Long.plus(b: Long): Long = (this + b) override inline fun Long.plus(b: Long): Long = (this + b)
override inline fun Long.minus(b: Long): Long = (this - b) override inline fun Long.minus(b: Long): Long = (this - b)
override inline fun Long.times(b: Long): Long = (this * b) override inline fun Long.times(b: Long): Long = (this * b)
override fun Long.rem(arg: Long): Long = this % arg
override fun Long.div(arg: Long): Long = this / arg
} }

View File

@ -307,3 +307,29 @@ interface Norm<in T : Any, out R> {
* Computes the norm of [arg] (i.e. absolute value or vector length). * Computes the norm of [arg] (i.e. absolute value or vector length).
*/ */
fun <T : MathElement<out Norm<T, R>>, R> norm(arg: T): R = arg.context.norm(arg) fun <T : MathElement<out Norm<T, R>>, R> norm(arg: T): R = arg.context.norm(arg)
interface RemainderDivisionOperations<T> : RingOperations<T> {
/**
* Calculates the remainder of dividing this value by [arg].
*/
operator fun T.rem(arg: T): T
/**
* Performs the floored division of this value by [arg].
*/
operator fun T.div(arg: T): T
override fun binaryOperation(operation: String, left: T, right: T): T = when (operation) {
REM_OPERATION -> left % right
DIV_OPERATION -> left / right
else -> super.binaryOperation(operation, left, right)
}
companion object {
const val REM_OPERATION = "rem"
const val DIV_OPERATION = "div"
}
}
infix fun <T : MathElement<out RemainderDivisionOperations<T>>> T.rem(arg: T): T = arg.context { this@rem rem arg }
infix fun <T : MathElement<out RemainderDivisionOperations<T>>> T.div(arg: T): T = arg.context { this@div div arg }

View File

@ -7,20 +7,22 @@ import java.math.MathContext
/** /**
* A field over [BigInteger]. * A field over [BigInteger].
*/ */
object JBigIntegerField : Field<BigInteger> { object JBigIntegerField : Ring<BigInteger>, RemainderDivisionOperations<BigInteger> {
override val zero: BigInteger override val zero: BigInteger
get() = BigInteger.ZERO get() = BigInteger.ZERO
override val one: BigInteger override val one: BigInteger
get() = BigInteger.ONE get() = BigInteger.ONE
override fun number(value: Number): BigInteger = BigInteger.valueOf(value.toLong()) override fun number(value: Number): BigInteger = value.toLong().toBigInteger()
override fun divide(a: BigInteger, b: BigInteger): BigInteger = a.div(b)
override fun add(a: BigInteger, b: BigInteger): BigInteger = a.add(b) override fun add(a: BigInteger, b: BigInteger): BigInteger = a.add(b)
override fun BigInteger.minus(b: BigInteger): BigInteger = this.subtract(b) override fun BigInteger.minus(b: BigInteger): BigInteger = subtract(b)
override fun multiply(a: BigInteger, k: Number): BigInteger = a.multiply(k.toInt().toBigInteger()) override fun multiply(a: BigInteger, k: Number): BigInteger = a.multiply(k.toLong().toBigInteger())
override fun multiply(a: BigInteger, b: BigInteger): BigInteger = a.multiply(b) override fun multiply(a: BigInteger, b: BigInteger): BigInteger = a.multiply(b)
override fun BigInteger.unaryMinus(): BigInteger = negate() override fun BigInteger.unaryMinus(): BigInteger = negate()
override fun BigInteger.div(arg: BigInteger): BigInteger = divide(arg)
override fun BigInteger.div(k: Number): BigInteger = this / k.toLong().toBigInteger()
override fun BigInteger.rem(arg: BigInteger): BigInteger = remainder(arg)
} }
/** /**
@ -39,7 +41,7 @@ abstract class JBigDecimalFieldBase internal constructor(val mathContext: MathCo
override fun add(a: BigDecimal, b: BigDecimal): BigDecimal = a.add(b) override fun add(a: BigDecimal, b: BigDecimal): BigDecimal = a.add(b)
override fun BigDecimal.minus(b: BigDecimal): BigDecimal = subtract(b) override fun BigDecimal.minus(b: BigDecimal): BigDecimal = subtract(b)
override fun number(value: Number): BigDecimal = BigDecimal.valueOf(value.toDouble()) override fun number(value: Number): BigDecimal = value.toDouble().toBigDecimal(mathContext)
override fun multiply(a: BigDecimal, k: Number): BigDecimal = override fun multiply(a: BigDecimal, k: Number): BigDecimal =
a.multiply(k.toDouble().toBigDecimal(mathContext), mathContext) a.multiply(k.toDouble().toBigDecimal(mathContext), mathContext)