v0.2.0 #206
@ -59,7 +59,7 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
|
||||
public override fun divide(a: Complex, b: Complex): Complex = when {
|
||||
b.re.isNaN() || b.im.isNaN() -> Complex(Double.NaN, Double.NaN)
|
||||
|
||||
(if (b.im < 0) -b.im else +b.im) < (if (b.re < 0) -b.re else +b.re) -> {
|
||||
abs(b.im) < abs(b.re) -> {
|
||||
val wr = b.im / b.re
|
||||
val wd = b.re + wr * b.im
|
||||
|
||||
@ -91,8 +91,8 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
|
||||
return i * (e1 - e2) / (e1 + e2)
|
||||
}
|
||||
|
||||
public override fun asin(arg: Complex): Complex = -i * ln(sqrt(1 - (arg * arg)) + i * arg)
|
||||
public override fun acos(arg: Complex): Complex = PI_DIV_2 + i * ln(sqrt(1 - (arg * arg)) + i * arg)
|
||||
public override fun asin(arg: Complex): Complex = -i * ln(sqrt(one - (arg * arg)) + i * arg)
|
||||
public override fun acos(arg: Complex): Complex = PI_DIV_2 + i * ln(sqrt(one - (arg * arg)) + i * arg)
|
||||
|
||||
public override fun atan(arg: Complex): Complex {
|
||||
val iArg = i * arg
|
||||
@ -125,6 +125,7 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
|
||||
public data class Complex(val re: Double, val im: Double) : FieldElement<Complex, Complex, ComplexField>,
|
||||
Comparable<Complex> {
|
||||
public constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble())
|
||||
public constructor(re: Number) : this(re.toDouble(), 0.0)
|
||||
|
||||
public override val context: ComplexField
|
||||
get() = ComplexField
|
||||
@ -155,7 +156,7 @@ public data class Complex(val re: Double, val im: Double) : FieldElement<Complex
|
||||
* @receiver the real part.
|
||||
* @return the new complex number.
|
||||
*/
|
||||
public fun Number.toComplex(): Complex = Complex(this, 0)
|
||||
public fun Number.toComplex(): Complex = Complex(this)
|
||||
|
||||
/**
|
||||
* Creates a new buffer of complex numbers with the specified [size], where each element is calculated by calling the
|
||||
|
@ -85,20 +85,23 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Quaternion>,
|
||||
return exp(pow * ln(arg))
|
||||
}
|
||||
|
||||
private fun pwr(x: Quaternion, a: Int): Quaternion {
|
||||
if (a < 0) return -(pwr(x, -a))
|
||||
if (a == 0) return one
|
||||
if (a == 1) return x
|
||||
if (a == 2) return pwr2(x)
|
||||
if (a == 3) return pwr3(x)
|
||||
if (a == 4) return pwr4(x)
|
||||
val x4 = pwr4(x)
|
||||
var y = x4
|
||||
repeat((1 until a / 4).count()) { y *= x4 }
|
||||
if (a % 4 == 3) y *= pwr3(x)
|
||||
if (a % 4 == 2) y *= pwr2(x)
|
||||
if (a % 4 == 1) y *= x
|
||||
return y
|
||||
private fun pwr(x: Quaternion, a: Int): Quaternion = when {
|
||||
a < 0 -> -(pwr(x, -a))
|
||||
a == 0 -> one
|
||||
a == 1 -> x
|
||||
a == 2 -> pwr2(x)
|
||||
a == 3 -> pwr3(x)
|
||||
a == 4 -> pwr4(x)
|
||||
|
||||
else -> {
|
||||
val x4 = pwr4(x)
|
||||
var y = x4
|
||||
repeat((1 until a / 4).count()) { y *= x4 }
|
||||
if (a % 4 == 3) y *= pwr3(x)
|
||||
if (a % 4 == 2) y *= pwr2(x)
|
||||
if (a % 4 == 1) y *= x
|
||||
y
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun pwr2(x: Quaternion): Quaternion {
|
||||
@ -204,7 +207,11 @@ public data class Quaternion(val w: Double, val x: Double, val y: Double, val z:
|
||||
z.toDouble()
|
||||
)
|
||||
|
||||
public constructor(w: Number, x: Number, y: Number) : this(w.toDouble(), x.toDouble(), y.toDouble(), 0.0)
|
||||
public constructor(w: Number, x: Number) : this(w.toDouble(), x.toDouble(), 0.0, 0.0)
|
||||
public constructor(w: Number) : this(w.toDouble(), 0.0, 0.0, 0.0)
|
||||
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)
|
||||
|
||||
public override val context: QuaternionField
|
||||
get() = QuaternionField
|
||||
@ -241,7 +248,7 @@ public data class Quaternion(val w: Double, val x: Double, val y: Double, val z:
|
||||
* @receiver the real part.
|
||||
* @return a new quaternion.
|
||||
*/
|
||||
public fun Number.toQuaternion(): Quaternion = Quaternion(this, 0, 0, 0)
|
||||
public fun Number.toQuaternion(): Quaternion = Quaternion(this)
|
||||
|
||||
/**
|
||||
* Creates a quaternion with `w`-component equal to `re`-component of given complex and `x`-component equal to
|
||||
@ -250,7 +257,7 @@ public fun Number.toQuaternion(): Quaternion = Quaternion(this, 0, 0, 0)
|
||||
* @receiver the complex number.
|
||||
* @return a new quaternion.
|
||||
*/
|
||||
public fun Complex.toQuaternion(): Quaternion = Quaternion(re, im, 0, 0)
|
||||
public fun Complex.toQuaternion(): Quaternion = Quaternion(this)
|
||||
|
||||
/**
|
||||
* Creates a new buffer of quaternions with the specified [size], where each element is calculated by calling the
|
||||
|
@ -1,39 +1,30 @@
|
||||
package kscience.kmath.operations
|
||||
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
internal class ComplexTest {
|
||||
@Test
|
||||
fun conjugate() {
|
||||
assertEquals(
|
||||
Complex(0, -42), (ComplexField.i * 42).conjugate
|
||||
)
|
||||
}
|
||||
fun conjugate() = assertEquals(Complex(0, -42), (ComplexField.i * 42).conjugate)
|
||||
|
||||
@Test
|
||||
fun reciprocal() {
|
||||
assertTrue { (Complex(0.5, -0.0) - 2.toComplex().reciprocal).r < 1e-10}
|
||||
}
|
||||
fun reciprocal() = assertTrue((Complex(0.5, -0.0) - 2.toComplex().reciprocal).r < 1e-10)
|
||||
|
||||
@Test
|
||||
fun r() {
|
||||
assertEquals(kotlin.math.sqrt(2.0), (ComplexField.i + 1.0.toComplex()).r)
|
||||
}
|
||||
fun r() = assertEquals(sqrt(2.0), (ComplexField.i + 1.0.toComplex()).r)
|
||||
|
||||
@Test
|
||||
fun theta() {
|
||||
assertEquals(0.0, 1.toComplex().theta)
|
||||
}
|
||||
fun theta() = assertEquals(0.0, 1.toComplex().theta)
|
||||
|
||||
@Test
|
||||
fun toComplex() {
|
||||
assertEquals(Complex(42, 0), 42.toComplex())
|
||||
assertEquals(Complex(42.0, 0), 42.0.toComplex())
|
||||
assertEquals(Complex(42f, 0), 42f.toComplex())
|
||||
assertEquals(Complex(42.0, 0), 42.0.toComplex())
|
||||
assertEquals(Complex(42.toByte(), 0), 42.toByte().toComplex())
|
||||
assertEquals(Complex(42.toShort(), 0), 42.toShort().toComplex())
|
||||
assertEquals(Complex(42), 42.toComplex())
|
||||
assertEquals(Complex(42.0), 42.0.toComplex())
|
||||
assertEquals(Complex(42f), 42f.toComplex())
|
||||
assertEquals(Complex(42.0), 42.0.toComplex())
|
||||
assertEquals(Complex(42.toByte()), 42.toByte().toComplex())
|
||||
assertEquals(Complex(42.toShort()), 42.toShort().toComplex())
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,50 @@
|
||||
package kscience.kmath.operations
|
||||
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
internal class QuaternionFieldTest {
|
||||
@Test
|
||||
fun testAddition() {
|
||||
assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(16, 16) + Quaternion(26, 26) })
|
||||
assertEquals(Quaternion(42, 16), QuaternionField { Quaternion(16, 16) + 26 })
|
||||
assertEquals(Quaternion(42, 16), QuaternionField { 26 + Quaternion(16, 16) })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSubtraction() {
|
||||
assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(86, 55) - Quaternion(44, 13) })
|
||||
assertEquals(Quaternion(42, 56), QuaternionField { Quaternion(86, 56) - 44 })
|
||||
assertTrue(Quaternion(42, 56) - QuaternionField { 86 - Quaternion(44, -56) } < 1e-10.toQuaternion())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testMultiplication() {
|
||||
assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(4.2, 0) * Quaternion(10, 10) })
|
||||
assertEquals(Quaternion(42, 21), QuaternionField { Quaternion(4.2, 2.1) * 10 })
|
||||
assertEquals(Quaternion(42, 21), QuaternionField { 10 * Quaternion(4.2, 2.1) })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testDivision() {
|
||||
assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(0, 168) / Quaternion(2, 2) })
|
||||
assertEquals(Quaternion(42, 56), QuaternionField { Quaternion(86, 56) - 44 })
|
||||
assertTrue(Quaternion(42, 56) - QuaternionField { 86 - Quaternion(44, -56) } < 1e-10.toQuaternion())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPower() {
|
||||
assertEquals(QuaternionField.zero, QuaternionField { zero pow 2 })
|
||||
assertEquals(QuaternionField.zero, QuaternionField { zero pow 2 })
|
||||
|
||||
assertEquals(
|
||||
QuaternionField { i * 8 }.let { it.x.toInt() to it.w.toInt() },
|
||||
QuaternionField { Quaternion(2, 2) pow 2 }.let { it.x.toInt() to it.w.toInt() })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNorm() {
|
||||
assertEquals(2.toQuaternion(), QuaternionField { norm(2 * i) })
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user