Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
fuookami.ospf.kotlin.utils.math.Rational.kt Maven / Gradle / Ivy
package fuookami.ospf.kotlin.utils.math
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlinx.serialization.json.*
import fuookami.ospf.kotlin.utils.concept.*
import fuookami.ospf.kotlin.utils.math.ordinary.*
import fuookami.ospf.kotlin.utils.operator.*
abstract class RationalSerializer(
name: String,
val ctor: (I, I) -> Self,
) : KSerializer where Self : Rational, I : Integer, I : NumberField {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor(name) {
element("num")
element("den")
}
abstract val valueSerializer: KSerializer
override fun serialize(encoder: Encoder, value: Self) {
require(encoder is JsonEncoder)
encoder.encodeJsonElement(
buildJsonObject {
put("num", encoder.json.encodeToJsonElement(valueSerializer, value.num))
put("den", encoder.json.encodeToJsonElement(valueSerializer, value.den))
}
)
}
@OptIn(ExperimentalSerializationApi::class)
override fun deserialize(decoder: Decoder): Self {
require(decoder is JsonDecoder)
val element = decoder.decodeJsonElement()
require(element is JsonObject)
require(descriptor.elementNames.all { it in element })
return ctor(
decoder.json.decodeFromJsonElement(valueSerializer, element["num"]!!),
decoder.json.decodeFromJsonElement(valueSerializer, element["den"]!!),
)
}
}
abstract class Rational protected constructor(
private val ctor: (I, I) -> Self,
private val integerConstants: RealNumberConstants
) : RationalNumber where Self : Rational, I : Integer, I : NumberField {
abstract val num: I
abstract val den: I
override fun copy() = ctor(num, den)
override fun toString() = "($num / $den)"
abstract fun toString(radix: Int): String;
override fun partialOrd(rhs: Self) = orderOf((num * rhs.den).compareTo(den * rhs.num))
override fun partialEq(rhs: Self) = num.eq(rhs.num) && den.eq(rhs.den)
override fun unaryMinus() = ctor(-num, den)
override fun reciprocal() = ctor(den, num)
override fun abs() = ctor(num.abs(), den)
override fun inc() = ctor(num + den, den)
override fun dec() = ctor(num - den, den)
override fun rem(rhs: Self): Self {
val k = this intDiv rhs;
return this - k * rhs;
}
override fun intDiv(rhs: Self): Self {
val divisor = this / rhs;
return ctor(divisor.num / divisor.den, integerConstants.one);
}
override fun log(base: FloatingNumber<*>) = toFltX().log(base)
override fun lg() = log(FltX.ten)
override fun ln() = log(FltX.e)
override fun pow(index: FloatingNumber<*>) = toFltX().pow(index)
override fun pow(index: Int) = pow(copy(), index, constants)
override fun sqr() = pow(2)
override fun cub() = pow(3)
override fun sqrt() = pow(FltX.one / FltX.two)
override fun cbrt() = pow(FltX.one / FltX.three)
override fun exp() = toFltX().exp()
override fun toInt8() = (num / den).toInt8()
override fun toInt16() = (num / den).toInt16()
override fun toInt32() = (num / den).toInt32()
override fun toInt64() = (num / den).toInt64()
override fun toIntX() = (num / den).toIntX()
override fun toUInt8() = (num / den).toUInt8()
override fun toUInt16() = (num / den).toUInt16()
override fun toUInt32() = (num / den).toUInt32()
override fun toUInt64() = (num / den).toUInt64()
override fun toUIntX() = (num / den).toUIntX()
override fun toRtn8() = Rtn8(num.toInt8(), den.toInt8())
override fun toRtn16() = Rtn16(num.toInt16(), den.toInt16())
override fun toRtn32() = Rtn32(num.toInt32(), den.toInt32())
override fun toRtn64() = Rtn64(num.toInt64(), den.toInt64())
override fun toRtnX() = RtnX(num.toIntX(), den.toIntX())
override fun toURtn8() = URtn8(num.toUInt8(), den.toUInt8())
override fun toURtn16() = URtn16(num.toUInt16(), den.toUInt16())
override fun toURtn32() = URtn32(num.toUInt32(), den.toUInt32())
override fun toURtn64() = URtn64(num.toUInt64(), den.toUInt64())
override fun toURtnX() = URtnX(num.toUIntX(), den.toUIntX())
override fun toFlt32() = num.toFlt32() / den.toFlt32()
override fun toFlt64() = num.toFlt64() / den.toFlt64()
override fun toFltX() = num.toFltX() / den.toFltX()
}
abstract class RationalConstants protected constructor(
private val ctor: (I, I) -> Self,
private val constants: RealNumberConstants
) : RealNumberConstants where Self : Rational, I : Integer, I : NumberField {
override val zero: Self get() = ctor(constants.zero, constants.one)
override val one: Self get() = ctor(constants.one, constants.one)
override val two: Self get() = ctor(constants.two, constants.one)
override val three: Self get() = ctor(constants.three, constants.one)
override val ten: Self get() = ctor(constants.ten, constants.one)
override val minimum: Self get() = ctor(constants.minimum, constants.one)
override val maximum: Self get() = ctor(constants.maximum, constants.one)
override val nan: Self get() = ctor(constants.zero, constants.zero)
override val infinity: Self get() = ctor(constants.one, constants.zero)
override val negativeInfinity: Self get() = ctor(-constants.one, constants.zero)
}
data object Rtn8Serializer : RationalSerializer("Rtn8", Rtn8::invoke) {
override val valueSerializer = Int8Serializer
}
@Serializable(with = Rtn8Serializer::class)
data class Rtn8 internal constructor(
override val num: Int8,
override val den: Int8
) : Rational(Rtn8::invoke, Int8), Copyable {
companion object : RationalConstants(Rtn8::invoke, Int8) {
operator fun invoke(num: Int8, den: Int8): Rtn8 {
val divisor = gcd(num, den)
val negative = (num < Int8.zero) xor (den < Int8.zero);
return if (negative) {
Rtn8(-num.abs() / divisor, den.abs() / divisor)
} else {
Rtn8(num.abs() / divisor, den.abs() / divisor)
}
}
}
override val constants: RealNumberConstants get() = Companion
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: Rtn8) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: Rtn8) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: Rtn8) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: Rtn8) = invoke(num * rhs.den, rhs.num * den)
}
data object Rtn16Serializer : RationalSerializer("Rtn16", Rtn16::invoke) {
override val valueSerializer = Int16Serializer
}
@Serializable(with = Rtn16Serializer::class)
data class Rtn16 internal constructor(
override val num: Int16,
override val den: Int16
) : Rational(Rtn16::invoke, Int16), Copyable {
companion object : RationalConstants(Rtn16::invoke, Int16) {
operator fun invoke(num: Int16, den: Int16): Rtn16 {
val divisor = gcd(num, den)
return Rtn16(num / divisor, den / divisor)
}
}
override val constants: RealNumberConstants get() = Rtn16
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: Rtn16) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: Rtn16) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: Rtn16) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: Rtn16) = invoke(num * rhs.den, rhs.num * den)
}
data object Rtn32Serializer : RationalSerializer("Rtn32", Rtn32::invoke) {
override val valueSerializer = Int32Serializer
}
@Serializable(with = Rtn32Serializer::class)
data class Rtn32 internal constructor(
override val num: Int32,
override val den: Int32
) : Rational(Rtn32::invoke, Int32), Copyable {
companion object : RationalConstants(Rtn32::invoke, Int32) {
operator fun invoke(num: Int32, den: Int32): Rtn32 {
val divisor = gcd(num, den)
return Rtn32(num / divisor, den / divisor)
}
}
override val constants: RealNumberConstants get() = Rtn32
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: Rtn32) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: Rtn32) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: Rtn32) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: Rtn32) = invoke(num * rhs.den, rhs.num * den)
}
data object Rtn64Serializer : RationalSerializer("Rtn64", Rtn64::invoke) {
override val valueSerializer = Int64Serializer
}
@Serializable(with = Rtn64Serializer::class)
data class Rtn64 internal constructor(
override val num: Int64,
override val den: Int64
) : Rational(Rtn64::invoke, Int64), Copyable {
companion object : RationalConstants(Rtn64::invoke, Int64) {
operator fun invoke(num: Int64, den: Int64): Rtn64 {
val divisor = gcd(num, den)
return Rtn64(num / divisor, den / divisor)
}
}
override val constants: RealNumberConstants get() = Rtn64
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: Rtn64) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: Rtn64) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: Rtn64) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: Rtn64) = invoke(num * rhs.den, rhs.num * den)
}
data object RtnXSerializer : RationalSerializer("RtnX", RtnX::invoke) {
override val valueSerializer = IntXSerializer
}
@Serializable(with = RtnXSerializer::class)
data class RtnX internal constructor(
override val num: IntX,
override val den: IntX
) : Rational(RtnX::invoke, IntX), Copyable {
companion object : RationalConstants(RtnX::invoke, IntX) {
operator fun invoke(num: IntX, den: IntX): RtnX {
val divisor = gcd(num, den)
return RtnX(num / divisor, den / divisor)
}
}
override val constants: RealNumberConstants get() = RtnX
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: RtnX) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: RtnX) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: RtnX) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: RtnX) = invoke(num * rhs.den, rhs.num * den)
}
object URtn8Serializer : RationalSerializer("URtn8", URtn8::invoke) {
override val valueSerializer = UInt8Serializer
}
@Serializable(with = URtn8Serializer::class)
data class URtn8 internal constructor(
override val num: UInt8,
override val den: UInt8
) : Rational(URtn8::invoke, UInt8), Copyable {
companion object : RationalConstants(URtn8::invoke, UInt8) {
operator fun invoke(num: UInt8, den: UInt8): URtn8 {
val divisor = gcd(num, den)
return URtn8(num / divisor, den / divisor)
}
}
override val constants: RealNumberConstants get() = URtn8
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: URtn8) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: URtn8) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: URtn8) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: URtn8) = invoke(num * rhs.den, rhs.num * den)
}
object URtn16Serializer : RationalSerializer("URtn16", URtn16::invoke) {
override val valueSerializer = UInt16Serializer
}
@Serializable(with = URtn16Serializer::class)
data class URtn16 internal constructor(
override val num: UInt16,
override val den: UInt16
) : Rational(URtn16::invoke, UInt16), Copyable {
companion object : RationalConstants(URtn16::invoke, UInt16) {
operator fun invoke(num: UInt16, den: UInt16): URtn16 {
val divisor = gcd(num, den)
return URtn16(num / divisor, den / divisor)
}
}
override val constants: RealNumberConstants get() = URtn16
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: URtn16) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: URtn16) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: URtn16) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: URtn16) = invoke(num * rhs.den, rhs.num * den)
}
object URtn32Serializer : RationalSerializer("URtn32", URtn32::invoke) {
override val valueSerializer = UInt32Serializer
}
@Serializable(with = URtn32Serializer::class)
data class URtn32 internal constructor(
override val num: UInt32,
override val den: UInt32
) : Rational(URtn32::invoke, UInt32), Copyable {
companion object : RationalConstants(URtn32::invoke, UInt32) {
operator fun invoke(num: UInt32, den: UInt32): URtn32 {
val divisor = gcd(num, den)
return URtn32(num / divisor, den / divisor)
}
}
override val constants: RealNumberConstants get() = URtn32
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: URtn32) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: URtn32) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: URtn32) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: URtn32) = invoke(num * rhs.den, rhs.num * den)
}
object URtn64Serializer : RationalSerializer("URtn64", URtn64::invoke) {
override val valueSerializer = UInt64Serializer
}
@Serializable(with = URtn64Serializer::class)
data class URtn64 internal constructor(
override val num: UInt64,
override val den: UInt64
) : Rational(URtn64::invoke, UInt64), Copyable {
companion object : RationalConstants(URtn64::invoke, UInt64) {
operator fun invoke(num: UInt64, den: UInt64): URtn64 {
val divisor = gcd(num, den)
return URtn64(num / divisor, den / divisor)
}
operator fun invoke(num: Int, den: Int): URtn64 {
return this(UInt64(num), UInt64(den))
}
}
override val constants: RealNumberConstants get() = URtn64
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: URtn64) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: URtn64) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: URtn64) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: URtn64) = invoke(num * rhs.den, rhs.num * den)
}
object URtnXSerializer : RationalSerializer("URtnX", URtnX::invoke) {
override val valueSerializer = UIntXSerializer
}
@Serializable(with = URtnXSerializer::class)
data class URtnX internal constructor(
override val num: UIntX,
override val den: UIntX
) : Rational(URtnX::invoke, UIntX), Copyable {
companion object : RationalConstants(URtnX::invoke, UIntX) {
operator fun invoke(num: UIntX, den: UIntX): URtnX {
val divisor = gcd(num, den)
return URtnX(num / divisor, den / divisor)
}
}
override val constants: RealNumberConstants get() = URtnX
override fun toString(radix: Int) = "(${num.toString(radix)} / ${den.toString(radix)})"
override fun plus(rhs: URtnX) = invoke(num * rhs.den + rhs.num * den, den * rhs.den)
override fun minus(rhs: URtnX) = invoke(num * rhs.den - rhs.num * den, den * rhs.den)
override fun times(rhs: URtnX) = invoke(num * rhs.num, den * rhs.den)
override fun div(rhs: URtnX) = invoke(num * rhs.den, rhs.num * den)
}