Add field test, minor refactor
This commit is contained in:
parent
828e40c452
commit
202ea3582c
@ -59,7 +59,7 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
|
|||||||
public override fun divide(a: Complex, b: Complex): Complex = when {
|
public override fun divide(a: Complex, b: Complex): Complex = when {
|
||||||
b.re.isNaN() || b.im.isNaN() -> Complex(Double.NaN, Double.NaN)
|
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 wr = b.im / b.re
|
||||||
val wd = b.re + wr * b.im
|
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)
|
return i * (e1 - e2) / (e1 + e2)
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun asin(arg: Complex): Complex = -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(1 - (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 {
|
public override fun atan(arg: Complex): Complex {
|
||||||
val iArg = i * arg
|
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>,
|
public data class Complex(val re: Double, val im: Double) : FieldElement<Complex, Complex, ComplexField>,
|
||||||
Comparable<Complex> {
|
Comparable<Complex> {
|
||||||
public constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble())
|
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
|
public override val context: ComplexField
|
||||||
get() = ComplexField
|
get() = ComplexField
|
||||||
@ -155,7 +156,7 @@ public data class Complex(val re: Double, val im: Double) : FieldElement<Complex
|
|||||||
* @receiver the real part.
|
* @receiver the real part.
|
||||||
* @return the new complex number.
|
* @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
|
* 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))
|
return exp(pow * ln(arg))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun pwr(x: Quaternion, a: Int): Quaternion {
|
private fun pwr(x: Quaternion, a: Int): Quaternion = when {
|
||||||
if (a < 0) return -(pwr(x, -a))
|
a < 0 -> -(pwr(x, -a))
|
||||||
if (a == 0) return one
|
a == 0 -> one
|
||||||
if (a == 1) return x
|
a == 1 -> x
|
||||||
if (a == 2) return pwr2(x)
|
a == 2 -> pwr2(x)
|
||||||
if (a == 3) return pwr3(x)
|
a == 3 -> pwr3(x)
|
||||||
if (a == 4) return pwr4(x)
|
a == 4 -> pwr4(x)
|
||||||
|
|
||||||
|
else -> {
|
||||||
val x4 = pwr4(x)
|
val x4 = pwr4(x)
|
||||||
var y = x4
|
var y = x4
|
||||||
repeat((1 until a / 4).count()) { y *= x4 }
|
repeat((1 until a / 4).count()) { y *= x4 }
|
||||||
if (a % 4 == 3) y *= pwr3(x)
|
if (a % 4 == 3) y *= pwr3(x)
|
||||||
if (a % 4 == 2) y *= pwr2(x)
|
if (a % 4 == 2) y *= pwr2(x)
|
||||||
if (a % 4 == 1) y *= x
|
if (a % 4 == 1) y *= x
|
||||||
return y
|
y
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inline fun pwr2(x: Quaternion): Quaternion {
|
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()
|
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, 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
|
public override val context: QuaternionField
|
||||||
get() = 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.
|
* @receiver the real part.
|
||||||
* @return a new quaternion.
|
* @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
|
* 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.
|
* @receiver the complex number.
|
||||||
* @return a new quaternion.
|
* @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
|
* 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
|
package kscience.kmath.operations
|
||||||
|
|
||||||
|
import kotlin.math.sqrt
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
internal class ComplexTest {
|
internal class ComplexTest {
|
||||||
@Test
|
@Test
|
||||||
fun conjugate() {
|
fun conjugate() = assertEquals(Complex(0, -42), (ComplexField.i * 42).conjugate)
|
||||||
assertEquals(
|
|
||||||
Complex(0, -42), (ComplexField.i * 42).conjugate
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun reciprocal() {
|
fun reciprocal() = assertTrue((Complex(0.5, -0.0) - 2.toComplex().reciprocal).r < 1e-10)
|
||||||
assertTrue { (Complex(0.5, -0.0) - 2.toComplex().reciprocal).r < 1e-10}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun r() {
|
fun r() = assertEquals(sqrt(2.0), (ComplexField.i + 1.0.toComplex()).r)
|
||||||
assertEquals(kotlin.math.sqrt(2.0), (ComplexField.i + 1.0.toComplex()).r)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun theta() {
|
fun theta() = assertEquals(0.0, 1.toComplex().theta)
|
||||||
assertEquals(0.0, 1.toComplex().theta)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun toComplex() {
|
fun toComplex() {
|
||||||
assertEquals(Complex(42, 0), 42.toComplex())
|
assertEquals(Complex(42), 42.toComplex())
|
||||||
assertEquals(Complex(42.0, 0), 42.0.toComplex())
|
assertEquals(Complex(42.0), 42.0.toComplex())
|
||||||
assertEquals(Complex(42f, 0), 42f.toComplex())
|
assertEquals(Complex(42f), 42f.toComplex())
|
||||||
assertEquals(Complex(42.0, 0), 42.0.toComplex())
|
assertEquals(Complex(42.0), 42.0.toComplex())
|
||||||
assertEquals(Complex(42.toByte(), 0), 42.toByte().toComplex())
|
assertEquals(Complex(42.toByte()), 42.toByte().toComplex())
|
||||||
assertEquals(Complex(42.toShort(), 0), 42.toShort().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