Fixed GitHub #524 (Complex power of real-valued number

This commit is contained in:
Alexander Nozik 2024-02-07 21:18:47 +03:00
parent a84f1e1500
commit 8a754ace19
3 changed files with 27 additions and 12 deletions

View File

@ -19,6 +19,7 @@
### Fixed ### Fixed
- Median statistics - Median statistics
- Complex power of negative real numbers
### Security ### Security

View File

@ -129,13 +129,25 @@ public object ComplexField :
} }
override fun power(arg: Complex, pow: Number): Complex = if (arg.im == 0.0) { override fun power(arg: Complex, pow: Number): Complex = if (arg.im == 0.0) {
arg.re.pow(pow.toDouble()).toComplex() val powDouble = pow.toDouble()
when {
arg.re > 0 -> arg.re.pow(powDouble).toComplex()
arg.re < 0 -> i * (-arg.re).pow(powDouble)
else -> if (powDouble == 0.0) {
one
} else {
zero
}
}
} else { } else {
exp(pow * ln(arg)) exp(pow * ln(arg))
} }
public fun power(arg: Complex, pow: Complex): Complex = exp(pow * ln(arg)) public fun power(arg: Complex, pow: Complex): Complex = exp(pow * ln(arg))
public fun Complex.pow(power: Complex): Complex = power(this, power)
override fun exp(arg: Complex): Complex = exp(arg.re) * (cos(arg.im) + i * sin(arg.im)) override fun exp(arg: Complex): Complex = exp(arg.re) * (cos(arg.im) + i * sin(arg.im))
@ -189,6 +201,7 @@ public object ComplexField :
override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg) override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg)
} }
/** /**
* Represents `double`-based complex number. * Represents `double`-based complex number.
* *

View File

@ -58,24 +58,25 @@ internal class ComplexFieldTest {
} }
@Test @Test
fun testInverseHyperbolicSine() { fun testInverseHyperbolicSine() = ComplexField {
assertEquals( assertEquals(i * PI.toComplex() / 2, asinh(i))
ComplexField { i * PI.toComplex() / 2 },
ComplexField { asinh(i) })
} }
@Test @Test
fun testPower() { fun testPower() = ComplexField {
assertEquals(ComplexField.zero, ComplexField { zero pow 2 }) assertEquals(zero, zero pow 2)
assertEquals(ComplexField.zero, ComplexField { zero pow 2 }) assertEquals(zero, zero pow 2)
assertEquals( assertEquals(
ComplexField { i * 8 }.let { it.im.toInt() to it.re.toInt() }, (i * 8).let { it.im.toInt() to it.re.toInt() },
ComplexField { Complex(2, 2) pow 2 }.let { it.im.toInt() to it.re.toInt() }) (Complex(2, 2) pow 2).let { it.im.toInt() to it.re.toInt() })
assertEquals(2.0, power(Complex(-4.0, 0.0), 0.5 + 0 * i).im, 0.01)
assertEquals(2.0, power(Complex(-4.0, 0.0), 0.5).im, 0.01)
} }
@Test @Test
fun testNorm() { fun testNorm() = ComplexField {
assertEquals(2.toComplex(), ComplexField { norm(2 * i) }) assertEquals(2.toComplex(), norm(2 * i))
} }
} }