[orx-math] Add complex number implementation and associated test cases
This commit is contained in:
59
orx-math/src/commonTest/kotlin/complex/ComplexAcoshTest.kt
Normal file
59
orx-math/src/commonTest/kotlin/complex/ComplexAcoshTest.kt
Normal file
@@ -0,0 +1,59 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ComplexAcoshTest {
|
||||
|
||||
@Test
|
||||
fun testAcoshOfOne() {
|
||||
val z = Complex(1.0, 0.0)
|
||||
val result = acosh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAcoshOfZero() {
|
||||
val z = Complex(0.0, 0.0)
|
||||
val result = acosh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(PI/2, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAcoshOfMinusOne() {
|
||||
val z = Complex(-1.0, 0.0)
|
||||
val result = acosh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(PI, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAcoshOfTwo() {
|
||||
val z = Complex(2.0, 0.0)
|
||||
val result = acosh(z)
|
||||
assertEquals(ln(2.0 + sqrt(3.0)), result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAcoshOfImaginaryUnit() {
|
||||
val z = Complex(0.0, 1.0)
|
||||
val result = acosh(z)
|
||||
assertEquals(0.8813735870195429, result.real, 1e-10)
|
||||
assertEquals(PI/2, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAcoshOfComplexNumber() {
|
||||
val z = Complex(1.0, 1.0)
|
||||
val result = acosh(z)
|
||||
// Expected values calculated using external reference
|
||||
assertEquals(1.061275061, result.real, 1e-8)
|
||||
assertEquals(0.904556894, result.imaginary, 1e-8)
|
||||
}
|
||||
}
|
||||
49
orx-math/src/commonTest/kotlin/complex/ComplexAsinTest.kt
Normal file
49
orx-math/src/commonTest/kotlin/complex/ComplexAsinTest.kt
Normal file
@@ -0,0 +1,49 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ComplexAsinTest {
|
||||
|
||||
@Test
|
||||
fun testAsinOfZero() {
|
||||
val z = Complex(0.0, 0.0)
|
||||
val result = asin(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinOfOne() {
|
||||
val z = Complex(1.0, 0.0)
|
||||
val result = asin(z)
|
||||
assertEquals(PI/2, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinOfMinusOne() {
|
||||
val z = Complex(-1.0, 0.0)
|
||||
val result = asin(z)
|
||||
assertEquals(-PI/2, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinOfImaginaryUnit() {
|
||||
val z = Complex(0.0, 1.0)
|
||||
val result = asin(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(0.881373587, result.imaginary, 1e-8) // approximately ln(1 + sqrt(2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinOfComplexNumber() {
|
||||
val z = Complex(1.0, 1.0)
|
||||
val result = asin(z)
|
||||
// Expected values calculated using external reference
|
||||
assertEquals(0.666239432, result.real, 1e-8)
|
||||
assertEquals(1.061275061, result.imaginary, 1e-8)
|
||||
}
|
||||
}
|
||||
61
orx-math/src/commonTest/kotlin/complex/ComplexAsinhTest.kt
Normal file
61
orx-math/src/commonTest/kotlin/complex/ComplexAsinhTest.kt
Normal file
@@ -0,0 +1,61 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.sqrt
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ComplexAsinhTest {
|
||||
|
||||
@Test
|
||||
fun testAsinhOfZero() {
|
||||
val z = Complex(0.0, 0.0)
|
||||
val result = asinh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinhOfOne() {
|
||||
val z = Complex(1.0, 0.0)
|
||||
val result = asinh(z)
|
||||
// Expected value is ln(1 + sqrt(2))
|
||||
assertEquals(ln(1.0 + sqrt(2.0)), result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinhOfMinusOne() {
|
||||
val z = Complex(-1.0, 0.0)
|
||||
val result = asinh(z)
|
||||
// Expected value is -ln(1 + sqrt(2))
|
||||
assertEquals(-ln(1.0 + sqrt(2.0)), result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinhOfImaginaryUnit() {
|
||||
val z = Complex(0.0, 1.0)
|
||||
val result = asinh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(PI/2, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinhOfNegativeImaginaryUnit() {
|
||||
val z = Complex(0.0, -1.0)
|
||||
val result = asinh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(-PI/2, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAsinhOfComplexNumber() {
|
||||
val z = Complex(1.0, 1.0)
|
||||
val result = asinh(z)
|
||||
// Expected values calculated using external reference
|
||||
assertEquals(1.061275061, result.real, 1e-8)
|
||||
assertEquals(0.666239432, result.imaginary, 1e-8)
|
||||
}
|
||||
}
|
||||
74
orx-math/src/commonTest/kotlin/complex/ComplexAtanhTest.kt
Normal file
74
orx-math/src/commonTest/kotlin/complex/ComplexAtanhTest.kt
Normal file
@@ -0,0 +1,74 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ComplexAtanhTest {
|
||||
|
||||
@Test
|
||||
fun testAtanhOfZero() {
|
||||
val z = Complex(0.0, 0.0)
|
||||
val result = atanh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtanhOfHalf() {
|
||||
val z = Complex(0.5, 0.0)
|
||||
val result = atanh(z)
|
||||
// atanh(0.5) = 0.5493061443340548
|
||||
assertEquals(0.5493061443340548, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtanhOfImaginaryUnit() {
|
||||
val z = Complex(0.0, 1.0)
|
||||
val result = atanh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
// atanh(i) = i*π/2
|
||||
assertEquals(PI/2, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtanhOfNegativeImaginaryUnit() {
|
||||
val z = Complex(0.0, -1.0)
|
||||
val result = atanh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
// atanh(-i) = -i*π/2
|
||||
assertEquals(-PI/2, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtanhOfComplexNumber() {
|
||||
val z = Complex(0.5, 0.5)
|
||||
val result = atanh(z)
|
||||
|
||||
// Calculate expected values using the formula: atanh(z) = 0.5 * ln((1+z)/(1-z))
|
||||
val one = Complex(1.0, 0.0)
|
||||
val numerator = one + z
|
||||
val denominator = one - z
|
||||
val fraction = numerator / denominator
|
||||
val expected = ln(fraction) * Complex(0.5, 0.0)
|
||||
|
||||
assertEquals(expected.real, result.real, 1e-10)
|
||||
assertEquals(expected.imaginary, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testAtanhIdentity() {
|
||||
// Test the identity: tanh(atanh(z)) = z for |z| < 1
|
||||
val z = Complex(0.3, 0.4)
|
||||
|
||||
// Calculate atanh(z)
|
||||
val atanhZ = atanh(z)
|
||||
|
||||
// Calculate tanh(atanh(z))
|
||||
val result = tanh(atanhZ)
|
||||
|
||||
assertEquals(z.real, result.real, 1e-10)
|
||||
assertEquals(z.imaginary, result.imaginary, 1e-10)
|
||||
}
|
||||
}
|
||||
51
orx-math/src/commonTest/kotlin/complex/ComplexCoshTest.kt
Normal file
51
orx-math/src/commonTest/kotlin/complex/ComplexCoshTest.kt
Normal file
@@ -0,0 +1,51 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ComplexCoshTest {
|
||||
|
||||
@Test
|
||||
fun testCoshOfZero() {
|
||||
val z = Complex(0.0, 0.0)
|
||||
val result = cosh(z)
|
||||
assertEquals(1.0, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCoshOfOne() {
|
||||
val z = Complex(1.0, 0.0)
|
||||
val result = cosh(z)
|
||||
assertEquals(kotlin.math.cosh(1.0), result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCoshOfImaginaryUnit() {
|
||||
val z = Complex(0.0, 1.0)
|
||||
val result = cosh(z)
|
||||
assertEquals(kotlin.math.cos(1.0), result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCoshOfImaginaryPi() {
|
||||
val z = Complex(0.0, PI)
|
||||
val result = cosh(z)
|
||||
assertEquals(kotlin.math.cos(PI), result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCoshOfComplexNumber() {
|
||||
val z = Complex(1.0, 1.0)
|
||||
val result = cosh(z)
|
||||
// Expected values calculated using the formula: cosh(1+i) = cosh(1)cos(1) + i·sinh(1)sin(1)
|
||||
val expectedReal = kotlin.math.cosh(1.0) * kotlin.math.cos(1.0)
|
||||
val expectedImaginary = kotlin.math.sinh(1.0) * kotlin.math.sin(1.0)
|
||||
assertEquals(expectedReal, result.real, 1e-10)
|
||||
assertEquals(expectedImaginary, result.imaginary, 1e-10)
|
||||
}
|
||||
}
|
||||
95
orx-math/src/commonTest/kotlin/complex/ComplexLogTest.kt
Normal file
95
orx-math/src/commonTest/kotlin/complex/ComplexLogTest.kt
Normal file
@@ -0,0 +1,95 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.ln
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class ComplexLogTest {
|
||||
// Small epsilon for floating-point comparisons
|
||||
private val e = 1E-6
|
||||
|
||||
/**
|
||||
* Tests the logarithm function with arbitrary base for complex numbers.
|
||||
*
|
||||
* This test verifies that the logarithm of specific complex numbers
|
||||
* with different bases produces results that match the expected values
|
||||
* within an acceptable error tolerance.
|
||||
*/
|
||||
@Test
|
||||
fun testLog() {
|
||||
// Test case 1: log_10(10) should be 1
|
||||
val z1 = Complex(10.0, 0.0)
|
||||
val result1 = log(z1, 10.0)
|
||||
assertTrue(result1.real in 1.0 - e..1.0 + e)
|
||||
assertTrue(result1.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 2: log_2(8) should be 3
|
||||
val z2 = Complex(8.0, 0.0)
|
||||
val result2 = log(z2, 2.0)
|
||||
assertTrue(result2.real in 3.0 - e..3.0 + e)
|
||||
assertTrue(result2.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 3: log_e(e) should be 1
|
||||
val z3 = Complex(kotlin.math.E, 0.0)
|
||||
val result3 = log(z3, kotlin.math.E)
|
||||
assertTrue(result3.real in 1.0 - e..1.0 + e)
|
||||
assertTrue(result3.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 4: log_10(i) should be ln(i)/ln(10)
|
||||
val z4 = Complex(0.0, 1.0)
|
||||
val result4 = log(z4, 10.0)
|
||||
// ln(i) = ln(e^(i*π/2)) = i*π/2
|
||||
val expectedReal4 = 0.0
|
||||
val expectedImag4 = kotlin.math.PI / (2 * ln(10.0))
|
||||
assertTrue(result4.real in expectedReal4 - e..expectedReal4 + e)
|
||||
assertTrue(result4.imaginary in expectedImag4 - e..expectedImag4 + e)
|
||||
|
||||
// Test case 5: log_2(-1) should be ln(-1)/ln(2) = i*π/ln(2)
|
||||
val z5 = Complex(-1.0, 0.0)
|
||||
val result5 = log(z5, 2.0)
|
||||
val expectedReal5 = 0.0
|
||||
val expectedImag5 = kotlin.math.PI / ln(2.0)
|
||||
assertTrue(result5.real in expectedReal5 - e..expectedReal5 + e)
|
||||
assertTrue(result5.imaginary in expectedImag5 - e..expectedImag5 + e)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the logarithm function with complex base for complex numbers.
|
||||
*
|
||||
* This test verifies that the logarithm of specific complex numbers
|
||||
* with different complex bases produces results that match the expected values
|
||||
* within an acceptable error tolerance.
|
||||
*/
|
||||
@Test
|
||||
fun testLogWithComplexBase() {
|
||||
// Test case 1: log_i(i) should be 1
|
||||
val z1 = Complex(0.0, 1.0)
|
||||
val base1 = Complex(0.0, 1.0)
|
||||
val result1 = log(z1, base1)
|
||||
assertTrue(result1.real in 1.0 - e..1.0 + e)
|
||||
assertTrue(result1.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 2: log_(2+3i)(4+5i)
|
||||
val z2 = Complex(4.0, 5.0)
|
||||
val base2 = Complex(2.0, 3.0)
|
||||
val result2 = log(z2, base2)
|
||||
// Expected result is ln(4+5i) / ln(2+3i)
|
||||
val expectedResult2 = ln(z2) / ln(base2)
|
||||
assertTrue(result2.real in expectedResult2.real - e..expectedResult2.real + e)
|
||||
assertTrue(result2.imaginary in expectedResult2.imaginary - e..expectedResult2.imaginary + e)
|
||||
|
||||
// Test case 3: log_(1+0i)(e+0i) should be 1
|
||||
val z3 = Complex(kotlin.math.E, 0.0)
|
||||
val base3 = Complex(kotlin.math.E, 0.0)
|
||||
val result3 = log(z3, base3)
|
||||
assertTrue(result3.real in 1.0 - e..1.0 + e)
|
||||
assertTrue(result3.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 4: log_(2+0i)(8+0i) should be 3
|
||||
val z4 = Complex(8.0, 0.0)
|
||||
val base4 = Complex(2.0, 0.0)
|
||||
val result4 = log(z4, base4)
|
||||
assertTrue(result4.real in 3.0 - e..3.0 + e)
|
||||
assertTrue(result4.imaginary in 0.0 - e..0.0 + e)
|
||||
}
|
||||
}
|
||||
51
orx-math/src/commonTest/kotlin/complex/ComplexSinhTest.kt
Normal file
51
orx-math/src/commonTest/kotlin/complex/ComplexSinhTest.kt
Normal file
@@ -0,0 +1,51 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ComplexSinhTest {
|
||||
|
||||
@Test
|
||||
fun testSinhOfZero() {
|
||||
val z = Complex(0.0, 0.0)
|
||||
val result = sinh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSinhOfOne() {
|
||||
val z = Complex(1.0, 0.0)
|
||||
val result = sinh(z)
|
||||
assertEquals(kotlin.math.sinh(1.0), result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSinhOfImaginaryUnit() {
|
||||
val z = Complex(0.0, 1.0)
|
||||
val result = sinh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(kotlin.math.sin(1.0), result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSinhOfImaginaryPi() {
|
||||
val z = Complex(0.0, PI)
|
||||
val result = sinh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(kotlin.math.sin(PI), result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSinhOfComplexNumber() {
|
||||
val z = Complex(1.0, 1.0)
|
||||
val result = sinh(z)
|
||||
// Expected values calculated using the formula: sinh(1+i) = sinh(1)cos(1) + i·cosh(1)sin(1)
|
||||
val expectedReal = kotlin.math.sinh(1.0) * kotlin.math.cos(1.0)
|
||||
val expectedImaginary = kotlin.math.cosh(1.0) * kotlin.math.sin(1.0)
|
||||
assertEquals(expectedReal, result.real, 1e-10)
|
||||
assertEquals(expectedImaginary, result.imaginary, 1e-10)
|
||||
}
|
||||
}
|
||||
71
orx-math/src/commonTest/kotlin/complex/ComplexTanhTest.kt
Normal file
71
orx-math/src/commonTest/kotlin/complex/ComplexTanhTest.kt
Normal file
@@ -0,0 +1,71 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ComplexTanhTest {
|
||||
|
||||
@Test
|
||||
fun testTanhOfZero() {
|
||||
val z = Complex(0.0, 0.0)
|
||||
val result = tanh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTanhOfOne() {
|
||||
val z = Complex(1.0, 0.0)
|
||||
val result = tanh(z)
|
||||
assertEquals(kotlin.math.tanh(1.0), result.real, 1e-10)
|
||||
assertEquals(0.0, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTanhOfImaginaryUnit() {
|
||||
val z = Complex(0.0, 1.0)
|
||||
val result = tanh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(kotlin.math.tan(1.0), result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTanhOfImaginaryPi() {
|
||||
val z = Complex(0.0, PI)
|
||||
val result = tanh(z)
|
||||
assertEquals(0.0, result.real, 1e-10)
|
||||
assertEquals(kotlin.math.tan(PI), result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTanhOfComplexNumber() {
|
||||
val z = Complex(1.0, 1.0)
|
||||
val result = tanh(z)
|
||||
|
||||
// Calculate expected values using the formula: tanh(z) = sinh(z) / cosh(z)
|
||||
val sinhZ = sinh(z)
|
||||
val coshZ = cosh(z)
|
||||
val expected = sinhZ / coshZ
|
||||
|
||||
assertEquals(expected.real, result.real, 1e-10)
|
||||
assertEquals(expected.imaginary, result.imaginary, 1e-10)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testTanhIdentity() {
|
||||
// Test the identity: tanh(z) = sinh(z) / cosh(z)
|
||||
val z = Complex(2.0, 3.0)
|
||||
|
||||
// Calculate using our tanh implementation
|
||||
val result = tanh(z)
|
||||
|
||||
// Calculate using the identity
|
||||
val sinhZ = sinh(z)
|
||||
val coshZ = cosh(z)
|
||||
val expected = sinhZ / coshZ
|
||||
|
||||
assertEquals(expected.real, result.real, 1e-10)
|
||||
assertEquals(expected.imaginary, result.imaginary, 1e-10)
|
||||
}
|
||||
}
|
||||
97
orx-math/src/commonTest/kotlin/complex/TestComplex.kt
Normal file
97
orx-math/src/commonTest/kotlin/complex/TestComplex.kt
Normal file
@@ -0,0 +1,97 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.exp
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class TestComplex {
|
||||
// Small epsilon for floating-point comparisons
|
||||
private val e = 1E-6
|
||||
|
||||
/**
|
||||
* Tests the arc cosine function for complex numbers.
|
||||
*
|
||||
* This test verifies that the arc cosine of specific complex numbers
|
||||
* produces results that match the expected values within an acceptable
|
||||
* error tolerance.
|
||||
*/
|
||||
@Test
|
||||
fun testAcos() {
|
||||
// Test case 1: acos(1) should be 0
|
||||
val z1 = Complex(1.0, 0.0)
|
||||
val result1 = acos(z1)
|
||||
assertTrue(result1.real in 0.0 - e..0.0 + e)
|
||||
assertTrue(result1.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 2: acos(-1) should be PI
|
||||
val z2 = Complex(-1.0, 0.0)
|
||||
val result2 = acos(z2)
|
||||
assertTrue(result2.real in PI - e..PI + e)
|
||||
assertTrue(result2.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 3: acos(0) should be PI/2
|
||||
val z3 = Complex(0.0, 0.0)
|
||||
val result3 = acos(z3)
|
||||
assertTrue(result3.real in PI/2 - e..PI/2 + e)
|
||||
assertTrue(result3.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 4: acos(i) should be PI/2 - i*ln(1 + sqrt(2))
|
||||
val z4 = Complex(0.0, 1.0)
|
||||
val result4 = acos(z4)
|
||||
val expectedImag4 = -kotlin.math.ln(1.0 + kotlin.math.sqrt(2.0))
|
||||
assertTrue(result4.real in PI/2 - e..PI/2 + e)
|
||||
assertTrue(result4.imaginary in expectedImag4 - e..expectedImag4 + e)
|
||||
|
||||
// Test case 5: acos(2) should be 0 + i*acosh(2)
|
||||
// For real x > 1, acos(x) = 0 + i*acosh(x) where acosh(x) = ln(x + sqrt(x^2 - 1))
|
||||
val z5 = Complex(2.0, 0.0)
|
||||
val result5 = acos(z5)
|
||||
val expectedImag5 = kotlin.math.ln(2.0 + kotlin.math.sqrt(3.0))
|
||||
assertTrue(result5.real in 0.0 - e..0.0 + e)
|
||||
assertTrue(result5.imaginary in expectedImag5 - e..expectedImag5 + e)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the exponential function for complex numbers.
|
||||
*
|
||||
* This test verifies that the exponential of specific complex numbers
|
||||
* produces results that match the expected values within an acceptable
|
||||
* error tolerance.
|
||||
*/
|
||||
@Test
|
||||
fun testExp() {
|
||||
// Test case 1: exp(0) should be 1
|
||||
val z1 = Complex(0.0, 0.0)
|
||||
val result1 = exp(z1)
|
||||
assertTrue(result1.real in 1.0 - e..1.0 + e)
|
||||
assertTrue(result1.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 2: exp(1) should be e
|
||||
val z2 = Complex(1.0, 0.0)
|
||||
val result2 = exp(z2)
|
||||
val expectedReal2 = exp(1.0)
|
||||
assertTrue(result2.real in expectedReal2 - e..expectedReal2 + e)
|
||||
assertTrue(result2.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 3: exp(i*PI) should be -1
|
||||
val z3 = Complex(0.0, PI)
|
||||
val result3 = exp(z3)
|
||||
assertTrue(result3.real in -1.0 - e..-1.0 + e)
|
||||
assertTrue(result3.imaginary in 0.0 - e..0.0 + e)
|
||||
|
||||
// Test case 4: exp(i*PI/2) should be i
|
||||
val z4 = Complex(0.0, PI/2)
|
||||
val result4 = exp(z4)
|
||||
assertTrue(result4.real in 0.0 - e..0.0 + e)
|
||||
assertTrue(result4.imaginary in 1.0 - e..1.0 + e)
|
||||
|
||||
// Test case 5: exp(1+i) = e^1 * (cos(1) + i*sin(1))
|
||||
val z5 = Complex(1.0, 1.0)
|
||||
val result5 = exp(z5)
|
||||
val expectedReal5 = exp(1.0) * kotlin.math.cos(1.0)
|
||||
val expectedImag5 = exp(1.0) * kotlin.math.sin(1.0)
|
||||
assertTrue(result5.real in expectedReal5 - e..expectedReal5 + e)
|
||||
assertTrue(result5.imaginary in expectedImag5 - e..expectedImag5 + e)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user