diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt index b242c8b0f..8aa4b0954 100644 --- a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt @@ -57,26 +57,24 @@ public object ComplexField : ExtendedField, Norm { Complex(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re) public override fun divide(a: Complex, b: Complex): Complex = when { - b.re.isNaN() || b.im.isNaN() -> Complex(Double.NaN, Double.NaN) - abs(b.im) < abs(b.re) -> { val wr = b.im / b.re val wd = b.re + wr * b.im if (wd.isNaN() || wd == 0.0) - Complex(Double.NaN, Double.NaN) + throw ArithmeticException("Division by zero or infinity") else Complex((a.re + a.im * wr) / wd, (a.im - a.re * wr) / wd) } - b.im == 0.0 -> Complex(Double.NaN, Double.NaN) + b.im == 0.0 -> throw ArithmeticException("Division by zero") else -> { val wr = b.re / b.im val wd = b.im + wr * b.re if (wd.isNaN() || wd == 0.0) - Complex(Double.NaN, Double.NaN) + throw ArithmeticException("Division by zero or infinity") else Complex((a.re * wr + a.im) / wd, (a.im * wr - a.re) / wd) } @@ -130,6 +128,11 @@ public data class Complex(val re: Double, val im: Double) : FieldElement, Norm, /** * The `i` quaternion unit. */ - public val i: Quaternion by lazy { Quaternion(0, 1, 0, 0) } + public val i: Quaternion by lazy { Quaternion(0, 1) } /** * The `j` quaternion unit. */ - public val j: Quaternion by lazy { Quaternion(0, 0, 1, 0) } + public val j: Quaternion by lazy { Quaternion(0, 0, 1) } /** * The `k` quaternion unit. @@ -104,41 +104,23 @@ public object QuaternionField : Field, Norm, } } - private inline fun pwr2(x: Quaternion): Quaternion { + private fun pwr2(x: Quaternion): Quaternion { val aa = 2 * x.w - - return Quaternion( - x.w * x.w - (x.x * x.x + x.y * x.y + x.z * x.z), - aa * x.x, - aa * x.y, - aa * x.z - ) + return Quaternion(x.w * x.w - (x.x * x.x + x.y * x.y + x.z * x.z), aa * x.x, aa * x.y, aa * x.z) } - private inline fun pwr3(x: Quaternion): Quaternion { + private fun pwr3(x: Quaternion): Quaternion { val a2 = x.w * x.w val n1 = x.x * x.x + x.y * x.y + x.z * x.z val n2 = 3.0 * a2 - n1 - - return Quaternion( - x.w * (a2 - 3 * n1), - x.x * n2, - x.y * n2, - x.z * n2 - ) + return Quaternion(x.w * (a2 - 3 * n1), x.x * n2, x.y * n2, x.z * n2) } - private inline fun pwr4(x: Quaternion): Quaternion { + private fun pwr4(x: Quaternion): Quaternion { val a2 = x.w * x.w val n1 = x.x * x.x + x.y * x.y + x.z * x.z val n2 = 4 * x.w * (a2 - n1) - - return Quaternion( - a2 * a2 - 6 * a2 * n1 + n1 * n1, - x.x * n2, - x.y * n2, - x.z * n2 - ) + return Quaternion(a2 * a2 - 6 * a2 * n1 + n1 * n1, x.x * n2, x.y * n2, x.z * n2) } public override fun exp(arg: Quaternion): Quaternion { @@ -213,6 +195,13 @@ public data class Quaternion(val w: Double, val x: Double, val y: Double, val z: public constructor(wx: Complex, yz: Complex) : this(wx.re, wx.im, yz.re, yz.im) public constructor(wx: Complex) : this(wx.re, wx.im, 0, 0) + init { + require(!w.isNaN()) { "w-component of quaternion is not-a-number" } + require(!x.isNaN()) { "x-component of quaternion is not-a-number" } + require(!y.isNaN()) { "x-component of quaternion is not-a-number" } + require(!z.isNaN()) { "x-component of quaternion is not-a-number" } + } + public override val context: QuaternionField get() = QuaternionField diff --git a/kmath-stat/build.gradle.kts b/kmath-stat/build.gradle.kts index 186aff944..849c05e53 100644 --- a/kmath-stat/build.gradle.kts +++ b/kmath-stat/build.gradle.kts @@ -3,6 +3,13 @@ plugins { } kotlin.sourceSets { + all { + languageSettings.apply { + useExperimentalAnnotation("kotlinx.coroutines.FlowPreview") + useExperimentalAnnotation("kotlinx.coroutines.ExperimentalCoroutinesApi") + } + } + commonMain { dependencies { api(project(":kmath-coroutines"))