From badb7b1365897d930789f818a863b70b221f994f Mon Sep 17 00:00:00 2001 From: Commander Tvis Date: Fri, 3 Jul 2020 17:14:50 +0700 Subject: [PATCH] Update implementation of Complex Division and Exponentiation --- .../scientifik/kmath/operations/Complex.kt | 17 +++++------- .../{ComplexTest.kt => ComplexFieldTest.kt} | 27 ++++++++++++++++--- 2 files changed, 30 insertions(+), 14 deletions(-) rename kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/{ComplexTest.kt => ComplexFieldTest.kt} (62%) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt index 0d0593d1b..3dd6f5157 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt @@ -41,8 +41,8 @@ private val PI_DIV_2 = Complex(PI / 2, 0) * A field for complex numbers. */ object ComplexField : ExtendedField { - override val zero: Complex = Complex(0, 0) - override val one: Complex = Complex(1, 0) + override val zero: Complex = 0.0.toComplex() + override val one: Complex = 1.0.toComplex() /** * The imaginary unit constant. @@ -90,24 +90,21 @@ object ComplexField : ExtendedField { return i * (e1 - e2) / (e1 + e2) } - override fun asin(arg: Complex): Complex = -i * ln(sqrt(one - arg pow 2) + i * arg) - override fun acos(arg: Complex): Complex = PI_DIV_2 + i * ln(sqrt(one - arg pow 2) + i * arg) + override fun asin(arg: Complex): Complex = -i * ln(sqrt(1 - (arg pow 2)) + i * arg) + override fun acos(arg: Complex): Complex = PI_DIV_2 + i * ln(sqrt(1 - (arg pow 2)) + i * arg) override fun atan(arg: Complex): Complex { val iArg = i * arg - return i * (ln(one - iArg) - ln(one + iArg)) / 2 + return i * (ln(1 - iArg) - ln(1 + iArg)) / 2 } override fun sinh(arg: Complex): Complex = (exp(arg) - exp(-arg)) / 2 override fun cosh(arg: Complex): Complex = (exp(arg) + exp(-arg)) / 2 override fun tanh(arg: Complex): Complex = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg)) - override fun asinh(arg: Complex): Complex = ln(sqrt(arg pow 2) + arg) + override fun asinh(arg: Complex): Complex = ln(sqrt((arg pow 2) + 1) + arg) override fun acosh(arg: Complex): Complex = ln(arg + sqrt((arg - 1) * (arg + 1))) override fun atanh(arg: Complex): Complex = (ln(arg + 1) - ln(1 - arg)) / 2 - - override fun power(arg: Complex, pow: Number): Complex = - arg.r.pow(pow.toDouble()) * (cos(pow.toDouble() * arg.theta) + i * sin(pow.toDouble() * arg.theta)) - + override fun power(arg: Complex, pow: Number): Complex = exp(ln(arg) * pow) override fun exp(arg: Complex): Complex = exp(arg.re) * (cos(arg.im) + i * sin(arg.im)) override fun ln(arg: Complex): Complex = ln(arg.r) + i * atan2(arg.im, arg.re) diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexTest.kt b/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexFieldTest.kt similarity index 62% rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexTest.kt rename to kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexFieldTest.kt index ad85fa9aa..2986efd5f 100644 --- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexTest.kt +++ b/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexFieldTest.kt @@ -37,13 +37,32 @@ internal class ComplexFieldTest { @Test fun testSine() { - assertEquals(Complex(1.2246467991473532E-16, 0), ComplexField { sin(PI.toComplex()) }) - assertEquals(Complex(0, 11.548739357257748), ComplexField { sin(i * PI.toComplex()) }) - assertEquals(Complex(0, 1.1752011936438014), ComplexField { sin(i) }) + assertEquals(ComplexField { i * sinh(one) }, ComplexField { sin(i) }) + assertEquals(ComplexField { i * sinh(PI.toComplex()) }, ComplexField { sin(i * PI.toComplex()) }) } @Test - fun testArcsine() { + fun testInverseSine() { assertEquals(Complex(0, -0.0), ComplexField { asin(zero) }) + + assertEquals(ComplexField { i * asinh(one) }.let { it.im.toInt() to it.re.toInt() }, + ComplexField { asin(i) }.let { it.im.toInt() to it.re.toInt() }) + } + + @Test + fun testInverseHyperbolicSine() { + assertEquals( + ComplexField { i * PI.toComplex() / 2 }.let { it.im.toInt() to it.re.toInt() }, + ComplexField { asinh(i) }.let { it.im.toInt() to it.re.toInt() }) + } + + @Test + fun testPower() { + assertEquals(ComplexField.zero, ComplexField { zero pow 2 }) + assertEquals(ComplexField.zero, ComplexField { zero pow 2 }) + + assertEquals( + ComplexField { i * 8 }.let { it.im.toInt() to it.re.toInt() }, + ComplexField { Complex(2, 2) pow 2 }.let { it.im.toInt() to it.re.toInt() }) } }