[orx-math] Add complex number implementation and associated test cases
This commit is contained in:
442
orx-math/src/commonMain/kotlin/complex/Complex.kt
Normal file
442
orx-math/src/commonMain/kotlin/complex/Complex.kt
Normal file
@@ -0,0 +1,442 @@
|
||||
package org.openrndr.extra.math.complex
|
||||
|
||||
import kotlin.jvm.JvmRecord
|
||||
import kotlin.math.atan2
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.cosh
|
||||
import kotlin.math.exp
|
||||
import kotlin.math.ln
|
||||
import kotlin.math.pow
|
||||
import kotlin.math.sin
|
||||
import kotlin.math.sinh
|
||||
|
||||
/**
|
||||
* Represents a complex number with a real and imaginary part.
|
||||
*
|
||||
* Provides functionality to perform common mathematical operations
|
||||
* with complex numbers, such as addition, subtraction, multiplication,
|
||||
* division, and more. Includes utility functions for magnitude,
|
||||
* argument, and conversions between polar and rectangular forms.
|
||||
*
|
||||
* @property real The real part of the complex number.
|
||||
* @property imaginary The imaginary part of the complex number.
|
||||
*/
|
||||
@JvmRecord
|
||||
data class Complex(val real: Double, val imaginary: Double) {
|
||||
operator fun plus(other: Complex): Complex {
|
||||
return Complex(real + other.real, imaginary + other.imaginary)
|
||||
}
|
||||
|
||||
operator fun times(other: Complex): Complex {
|
||||
return Complex(real * other.real - imaginary * other.imaginary, real * other.imaginary + imaginary * other.real)
|
||||
}
|
||||
|
||||
operator fun unaryMinus(): Complex {
|
||||
return Complex(-real, -imaginary)
|
||||
}
|
||||
|
||||
operator fun div(other: Complex): Complex {
|
||||
val c = other.real * other.real + other.imaginary * other.imaginary
|
||||
return Complex(
|
||||
(real * other.real + imaginary * other.imaginary) / c,
|
||||
(imaginary * other.real - real * other.imaginary) / c
|
||||
)
|
||||
}
|
||||
|
||||
operator fun div(other: Double): Complex {
|
||||
return Complex(real / other, imaginary / other)
|
||||
}
|
||||
|
||||
operator fun minus(other: Complex): Complex {
|
||||
return Complex(real - other.real, imaginary - other.imaginary)
|
||||
}
|
||||
|
||||
operator fun times(other: Double): Complex {
|
||||
return Complex(real * other, imaginary * other)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the magnitude (or absolute value) of the complex number.
|
||||
* The magnitude is computed as the square root of the sum of the squares
|
||||
* of the real and imaginary parts.
|
||||
*
|
||||
* @return The magnitude of the complex number.
|
||||
*/
|
||||
fun magnitude(): Double {
|
||||
return kotlin.math.sqrt(real * real + imaginary * imaginary)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the squared magnitude (or squared absolute value) of the complex number.
|
||||
* The squared magnitude is determined as the sum of the squares of the real and imaginary parts.
|
||||
*
|
||||
* @return The squared magnitude of the complex number.
|
||||
*/
|
||||
fun sqrMagnitude(): Double {
|
||||
return real * real + imaginary * imaginary
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the conjugate of the complex number.
|
||||
* The conjugate of a complex number is formed by changing the sign of its imaginary part.
|
||||
*
|
||||
* @return A new instance of [Complex] representing the conjugate of the current complex number.
|
||||
*/
|
||||
fun conjugate(): Complex {
|
||||
return Complex(real, -imaginary)
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes the complex number to a unit magnitude.
|
||||
* The normalized complex number retains the same direction in the complex plane
|
||||
* but has a magnitude of 1.
|
||||
*
|
||||
* @return A new instance of [Complex] representing the normalized complex number.
|
||||
*/
|
||||
fun normalize(): Complex {
|
||||
val m = magnitude()
|
||||
return Complex(real / m, imaginary / m)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the principal square root of the complex number.
|
||||
* The square root is calculated based on the polar representation of the complex number.
|
||||
*
|
||||
* @return A new instance of [Complex] representing the square root of the current complex number.
|
||||
*/
|
||||
fun sqrt(): Complex {
|
||||
val r = kotlin.math.sqrt(kotlin.math.sqrt(real * real + imaginary * imaginary))
|
||||
val t = atan2(imaginary, real) / 2.0
|
||||
return Complex(r * cos(t), r * sin(t))
|
||||
}
|
||||
|
||||
/**
|
||||
* Raises the current complex number to the power of the given exponent.
|
||||
* The operation is performed in polar form, where the magnitude is raised
|
||||
* to the exponent and the argument is multiplied by the exponent.
|
||||
*
|
||||
* @param exponent The exponent to which the complex number is raised.
|
||||
* @return A new instance of [Complex] representing the result of the operation.
|
||||
*/
|
||||
fun pow(exponent: Double): Complex {
|
||||
val m = magnitude().pow(exponent)
|
||||
val phi = argument() * exponent
|
||||
|
||||
return Complex(m * cos(phi), m * sin(phi))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the argument (or angle) of the complex number in polar coordinates.
|
||||
* The argument is the angle formed by the positive real axis and the line representing the complex number
|
||||
* in the complex plane, measured in radians.
|
||||
*
|
||||
* @return The argument of the complex number in radians.
|
||||
*/
|
||||
fun argument(): Double {
|
||||
return atan2(imaginary, real)
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromRadians(radians: Double): Complex {
|
||||
return Complex(cos(radians), sin(radians))
|
||||
}
|
||||
|
||||
fun fromPolar(magnitude: Double, argument: Double): Complex {
|
||||
return Complex(magnitude * cos(argument), magnitude * sin(argument))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Divides a double-precision floating-point number by a complex number and returns the result.
|
||||
*
|
||||
* The division is performed using the formula for dividing a real number by a complex number.
|
||||
*
|
||||
* @param other The complex number to divide by.
|
||||
* @return A new instance of [Complex] representing the result of the division.
|
||||
*/
|
||||
operator fun Double.div(other: Complex): Complex {
|
||||
val c = other.real * other.real + other.imaginary * other.imaginary
|
||||
return Complex((this * other.real) / c, (-this * other.imaginary) / c)
|
||||
}
|
||||
|
||||
/**
|
||||
* Raises a real number to the power of a complex number.
|
||||
*
|
||||
* @param exponent The complex exponent to which the real number will be raised.
|
||||
* @return A [Complex] number representing the result of raising this real number
|
||||
* to the power of the given complex exponent.
|
||||
*/
|
||||
fun Double.pow(exponent: Complex): Complex {
|
||||
val be = this.pow(exponent.real)
|
||||
val phase = exponent.imaginary * ln(this)
|
||||
return Complex(be * cos(phase), be * sin(phase))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cosine of a complex number.
|
||||
* The cosine of a complex number is calculated using the formula:
|
||||
* cos(a + bi) = cos(a)cosh(b) - i*sin(a)sinh(b),
|
||||
* where a and b are the real and imaginary parts of the complex number, respectively.
|
||||
*
|
||||
* @param complex The complex number for which the cosine is to be calculated.
|
||||
* @return A new instance of [Complex] representing the cosine of the given complex number.
|
||||
*/
|
||||
fun cos(complex: Complex): Complex {
|
||||
return Complex(cos(complex.real) * cosh(complex.imaginary), -sin(complex.real) * sinh(complex.imaginary))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the sine of a given complex number using the formula:
|
||||
* sin(z) = sin(a) * cosh(b) - i * cos(a) * sinh(b),
|
||||
* where z = a + bi is the complex number, a is the real part, and b is the imaginary part.
|
||||
*
|
||||
* @param complex The complex number for which the sine is computed.
|
||||
* @return A new instance of [Complex] representing the sine of the given complex number.
|
||||
*/
|
||||
fun sin(complex: Complex): Complex {
|
||||
return Complex(sin(complex.real) * cosh(complex.imaginary), -cos(complex.real) * sinh(complex.imaginary))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the tangent of a given complex number.
|
||||
* The tangent of a complex number is calculated as the quotient of its sine and cosine.
|
||||
*
|
||||
* @param complex The complex number for which the tangent is to be calculated.
|
||||
* @return A new instance of [Complex] representing the tangent of the given complex number.
|
||||
*/
|
||||
fun tan(complex: Complex): Complex {
|
||||
return sin(complex) / cos(complex)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the cotangent of a complex number.
|
||||
* The cotangent is calculated using the formula cot(z) = cos(z) / sin(z),
|
||||
* where z is the complex number.
|
||||
*
|
||||
* @param complex The complex number for which the cotangent is calculated.
|
||||
* @return A new instance of [Complex] representing the cotangent of the given complex number.
|
||||
*/
|
||||
fun cot(complex: Complex): Complex {
|
||||
return cos(complex) / sin(complex)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the natural logarithm of a complex number.
|
||||
* The natural logarithm is calculated using the formula:
|
||||
* ln(z) = ln(|z|) + i * arg(z)
|
||||
* where |z| is the magnitude and arg(z) is the argument of the complex number.
|
||||
*
|
||||
* @param complex The complex number for which the natural logarithm is calculated.
|
||||
* @return A new instance of [Complex] representing the natural logarithm of the given complex number.
|
||||
*/
|
||||
fun ln(complex: Complex): Complex {
|
||||
return Complex(ln(complex.magnitude()), complex.argument())
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the exponential of a complex number.
|
||||
* The exponential is calculated using the formula:
|
||||
* exp(a + bi) = e^a * (cos(b) + i*sin(b))
|
||||
* where a and b are the real and imaginary parts of the complex number, respectively.
|
||||
*
|
||||
* @param complex The complex number for which the exponential is calculated.
|
||||
* @return A new instance of [Complex] representing the exponential of the given complex number.
|
||||
*/
|
||||
fun exp(complex: Complex): Complex {
|
||||
val expReal = exp(complex.real)
|
||||
return Complex(expReal * cos(complex.imaginary), expReal * sin(complex.imaginary))
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the logarithm of a complex number with a specified base.
|
||||
* The logarithm with base b is calculated using the formula:
|
||||
* log_b(z) = ln(z) / ln(b)
|
||||
* where z is the complex number and b is the base.
|
||||
*
|
||||
* @param x The complex number for which the logarithm is calculated.
|
||||
* @param base The base of the logarithm (must be positive and not equal to 1).
|
||||
* @return A new instance of [Complex] representing the logarithm of the given complex number with the specified base.
|
||||
*/
|
||||
fun log(x: Complex, base: Double): Complex {
|
||||
require(base > 0 && base != 1.0) { "Logarithm base must be positive and not equal to 1" }
|
||||
return ln(x) / ln(base)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the logarithm of a complex number with a specified complex base.
|
||||
* The logarithm with base b is calculated using the formula:
|
||||
* log_b(z) = ln(z) / ln(b)
|
||||
* where z is the complex number and b is the complex base.
|
||||
*
|
||||
* @param x The complex number for which the logarithm is calculated.
|
||||
* @param base The complex base of the logarithm.
|
||||
* @return A new instance of [Complex] representing the logarithm of the given complex number with the specified complex base.
|
||||
*/
|
||||
fun log(x: Complex, base: Complex): Complex {
|
||||
require(base != Complex(1.0, 0.0)) { "Logarithm base must not be equal to 1" }
|
||||
require(base.magnitude() > 0) { "Logarithm base must have non-zero magnitude" }
|
||||
return ln(x) / ln(base)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the arc cosine (inverse cosine) of a complex number.
|
||||
* The arc cosine is calculated using the formula:
|
||||
* acos(z) = -i * ln(z + i * sqrt(1 - z²))
|
||||
* where z is the complex number.
|
||||
*
|
||||
* @param complex The complex number for which the arc cosine is calculated.
|
||||
* @return A new instance of [Complex] representing the arc cosine of the given complex number.
|
||||
*/
|
||||
fun acos(complex: Complex): Complex {
|
||||
val z2 = complex * complex
|
||||
val oneMinusZ2 = Complex(1.0, 0.0) - z2
|
||||
val sqrt = oneMinusZ2.sqrt()
|
||||
val sum = complex + Complex(0.0, 1.0) * sqrt
|
||||
// The negative sign is applied to the entire result
|
||||
return Complex(0.0, 1.0) * ln(sum) * Complex(-1.0, 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the arc sine (inverse sine) of a complex number.
|
||||
* The arc sine is calculated using the formula:
|
||||
* asin(z) = -i * ln(i * z + sqrt(1 - z²))
|
||||
* where z is the complex number.
|
||||
*
|
||||
* @param complex The complex number for which the arc sine is calculated.
|
||||
* @return A new instance of [Complex] representing the arc sine of the given complex number.
|
||||
*/
|
||||
fun asin(complex: Complex): Complex {
|
||||
val z2 = complex * complex
|
||||
val oneMinusZ2 = Complex(1.0, 0.0) - z2
|
||||
val sqrt = oneMinusZ2.sqrt()
|
||||
val sum = Complex(0.0, 1.0) * complex + sqrt
|
||||
return Complex(0.0, -1.0) * ln(sum)
|
||||
}
|
||||
|
||||
/**
|
||||
* Raises a real number to the power of the given exponent and returns the result as a complex number.
|
||||
*
|
||||
* This function internally converts the real number to a complex number with an imaginary part of 0,
|
||||
* and then performs the power operation.
|
||||
*
|
||||
* @param exponent The exponent to which the number is raised.
|
||||
* @return A [Complex] instance representing the result of raising the number to the given power.
|
||||
*/
|
||||
fun Double.cpow(exponent: Double): Complex = Complex(this, 0.0).pow(exponent)
|
||||
|
||||
/**
|
||||
* Computes the arc tangent (inverse tangent) of a complex number.
|
||||
* The arc tangent is calculated using the formula:
|
||||
* atan(z) = (i/2) * ln((i+z)/(i-z))
|
||||
* where z is the complex number.
|
||||
*
|
||||
* @param complex The complex number for which the arc tangent is calculated.
|
||||
* @return A new instance of [Complex] representing the arc tangent of the given complex number.
|
||||
*/
|
||||
fun atan(complex: Complex): Complex {
|
||||
val i = Complex(0.0, 1.0)
|
||||
val numerator = i + complex
|
||||
val denominator = i - complex
|
||||
val fraction = numerator / denominator
|
||||
return i * ln(fraction) * Complex(0.5, 0.0)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the hyperbolic cosine of a complex number.
|
||||
* The hyperbolic cosine is calculated using the formula:
|
||||
* cosh(a + bi) = cosh(a)cos(b) + i·sinh(a)sin(b),
|
||||
* where a and b are the real and imaginary parts of the complex number, respectively.
|
||||
*
|
||||
* @param complex The complex number for which the hyperbolic cosine is calculated.
|
||||
* @return A new instance of [Complex] representing the hyperbolic cosine of the given complex number.
|
||||
*/
|
||||
fun cosh(complex: Complex): Complex =
|
||||
Complex(cosh(complex.real) * cos(complex.imaginary), sinh(complex.real) * sin(complex.imaginary))
|
||||
|
||||
/**
|
||||
* Computes the hyperbolic sine of a complex number.
|
||||
* The hyperbolic sine is calculated using the formula:
|
||||
* sinh(a + bi) = sinh(a)cos(b) + i·cosh(a)sin(b),
|
||||
* where a and b are the real and imaginary parts of the complex number, respectively.
|
||||
*
|
||||
* @param complex The complex number for which the hyperbolic sine is calculated.
|
||||
* @return A new instance of [Complex] representing the hyperbolic sine of the given complex number.
|
||||
*/
|
||||
fun sinh(complex: Complex): Complex =
|
||||
Complex(sinh(complex.real) * cos(complex.imaginary), cosh(complex.real) * sin(complex.imaginary))
|
||||
|
||||
/**
|
||||
* Computes the inverse hyperbolic cosine of a complex number.
|
||||
* The inverse hyperbolic cosine is calculated using the formula:
|
||||
* acosh(z) = ln(z + sqrt(z² - 1))
|
||||
* where z is the complex number.
|
||||
*
|
||||
* @param complex The complex number for which the inverse hyperbolic cosine is calculated.
|
||||
* @return A new instance of [Complex] representing the inverse hyperbolic cosine of the given complex number.
|
||||
*/
|
||||
fun acosh(complex: Complex): Complex {
|
||||
val z2 = complex * complex
|
||||
val z2Minus1 = z2 - Complex(1.0, 0.0)
|
||||
val sqrt = z2Minus1.sqrt()
|
||||
val sum = complex + sqrt
|
||||
return ln(sum)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the inverse hyperbolic sine of a complex number.
|
||||
* The inverse hyperbolic sine is calculated using the formula:
|
||||
* asinh(z) = ln(z + sqrt(z² + 1))
|
||||
* where z is the complex number.
|
||||
*
|
||||
* @param complex The complex number for which the inverse hyperbolic sine is calculated.
|
||||
* @return A new instance of [Complex] representing the inverse hyperbolic sine of the given complex number.
|
||||
*/
|
||||
fun asinh(complex: Complex): Complex {
|
||||
val z2 = complex * complex
|
||||
val z2Plus1 = z2 + Complex(1.0, 0.0)
|
||||
val sqrt = z2Plus1.sqrt()
|
||||
val sum = complex + sqrt
|
||||
return ln(sum)
|
||||
}
|
||||
|
||||
/**
|
||||
* Computes the hyperbolic tangent of a complex number.
|
||||
* The hyperbolic tangent is calculated using the formula:
|
||||
* tanh(z) = sinh(z) / cosh(z)
|
||||
* where z is the complex number.
|
||||
*
|
||||
* @param complex The complex number for which the hyperbolic tangent is calculated.
|
||||
* @return A new instance of [Complex] representing the hyperbolic tangent of the given complex number.
|
||||
*/
|
||||
fun tanh(complex: Complex): Complex = sinh(complex) / cosh(complex)
|
||||
|
||||
/**
|
||||
* Computes the inverse hyperbolic tangent of a complex number.
|
||||
* The inverse hyperbolic tangent is calculated using the formula:
|
||||
* atanh(z) = (1/2) * ln((1+z)/(1-z))
|
||||
* where z is the complex number.
|
||||
*
|
||||
* Special cases:
|
||||
* - For z = i (imaginary unit), atanh(i) = i*π/2
|
||||
* - For z = -i (negative imaginary unit), atanh(-i) = -i*π/2
|
||||
*
|
||||
* @param complex The complex number for which the inverse hyperbolic tangent is calculated.
|
||||
* @return A new instance of [Complex] representing the inverse hyperbolic tangent of the given complex number.
|
||||
*/
|
||||
fun atanh(complex: Complex): Complex {
|
||||
// Special cases for imaginary unit values
|
||||
if (complex.real == 0.0 && complex.imaginary == 1.0) {
|
||||
return Complex(0.0, kotlin.math.PI / 2)
|
||||
}
|
||||
if (complex.real == 0.0 && complex.imaginary == -1.0) {
|
||||
return Complex(0.0, -kotlin.math.PI / 2)
|
||||
}
|
||||
|
||||
val one = Complex(1.0, 0.0)
|
||||
val numerator = one + complex
|
||||
val denominator = one - complex
|
||||
val fraction = numerator / denominator
|
||||
return ln(fraction) * Complex(0.5, 0.0)
|
||||
}
|
||||
|
||||
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