Implement hyperbolic functions for various Algebras #118
@ -84,9 +84,9 @@ object MstExtendedField : ExtendedField<MST> {
|
||||
|
||||
override fun sin(arg: MST): MST = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg)
|
||||
override fun cos(arg: MST): MST = unaryOperation(TrigonometricOperations.COS_OPERATION, arg)
|
||||
override fun asin(arg: MST): MST = unaryOperation(InverseTrigonometricOperations.ASIN_OPERATION, arg)
|
||||
override fun acos(arg: MST): MST = unaryOperation(InverseTrigonometricOperations.ACOS_OPERATION, arg)
|
||||
override fun atan(arg: MST): MST = unaryOperation(InverseTrigonometricOperations.ATAN_OPERATION, arg)
|
||||
override fun asin(arg: MST): MST = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg)
|
||||
override fun acos(arg: MST): MST = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg)
|
||||
override fun atan(arg: MST): MST = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg)
|
||||
override fun add(a: MST, b: MST): MST = MstField.add(a, b)
|
||||
override fun multiply(a: MST, k: Number): MST = MstField.multiply(a, k)
|
||||
override fun multiply(a: MST, b: MST): MST = MstField.multiply(a, b)
|
||||
|
@ -139,15 +139,9 @@ open class FunctionalExpressionExtendedField<T, A>(algebra: A) :
|
||||
ExtendedField<Expression<T>> where A : ExtendedField<T>, A : NumericAlgebra<T> {
|
||||
override fun sin(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg)
|
||||
override fun cos(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.COS_OPERATION, arg)
|
||||
|
||||
override fun asin(arg: Expression<T>): Expression<T> =
|
||||
unaryOperation(InverseTrigonometricOperations.ASIN_OPERATION, arg)
|
||||
|
||||
override fun acos(arg: Expression<T>): Expression<T> =
|
||||
unaryOperation(InverseTrigonometricOperations.ACOS_OPERATION, arg)
|
||||
|
||||
override fun atan(arg: Expression<T>): Expression<T> =
|
||||
unaryOperation(InverseTrigonometricOperations.ATAN_OPERATION, arg)
|
||||
override fun asin(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg)
|
||||
override fun acos(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg)
|
||||
override fun atan(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg)
|
||||
|
||||
override fun power(arg: Expression<T>, pow: Number): Expression<T> =
|
||||
binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow))
|
||||
|
@ -99,13 +99,6 @@ object ComplexField : ExtendedField<Complex> {
|
||||
return i * (ln(1 - iArg) - ln(1 + iArg)) / 2
|
||||
}
|
||||
|
||||
override fun sinh(arg: Complex): Complex = (exp(arg) - exp(-arg)) / 2
|
||||
override fun cosh(arg: Complex): Complex = (exp(arg) + exp(-arg)) / 2
|
||||
override fun tanh(arg: Complex): Complex = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg))
|
||||
override fun asinh(arg: Complex): Complex = ln(sqrt(arg * arg + 1) + arg)
|
||||
override fun acosh(arg: Complex): Complex = ln(arg + sqrt((arg - 1) * (arg + 1)))
|
||||
override fun atanh(arg: Complex): Complex = (ln(arg + 1) - ln(1 - arg)) / 2
|
||||
|
||||
override fun power(arg: Complex, pow: Number): Complex = if (arg.im == 0.0)
|
||||
arg.re.pow(pow.toDouble()).toComplex()
|
||||
else
|
||||
@ -199,7 +192,7 @@ data class Complex(val re: Double, val im: Double) : FieldElement<Complex, Compl
|
||||
* @receiver the real part.
|
||||
* @return the new complex number.
|
||||
*/
|
||||
fun Number.toComplex() = Complex(this, 0.0)
|
||||
fun Number.toComplex(): Complex = Complex(this, 0.0)
|
||||
|
||||
inline fun Buffer.Companion.complex(size: Int, crossinline init: (Int) -> Complex): Buffer<Complex> {
|
||||
return MemoryBuffer.create(Complex, size, init)
|
||||
|
@ -7,8 +7,9 @@ import kotlin.math.pow as kpow
|
||||
* Advanced Number-like semifield that implements basic operations.
|
||||
*/
|
||||
interface ExtendedFieldOperations<T> :
|
||||
FieldOperations<T>,
|
||||
TrigonometricOperations<T>,
|
||||
HyperbolicTrigonometricOperations<T>,
|
||||
HyperbolicOperations<T>,
|
||||
PowerOperations<T>,
|
||||
ExponentialOperations<T> {
|
||||
|
||||
@ -22,16 +23,16 @@ interface ExtendedFieldOperations<T> :
|
||||
TrigonometricOperations.ACOS_OPERATION -> acos(arg)
|
||||
TrigonometricOperations.ASIN_OPERATION -> asin(arg)
|
||||
TrigonometricOperations.ATAN_OPERATION -> atan(arg)
|
||||
HyperbolicTrigonometricOperations.COSH_OPERATION -> cosh(arg)
|
||||
HyperbolicTrigonometricOperations.SINH_OPERATION -> sinh(arg)
|
||||
HyperbolicTrigonometricOperations.TANH_OPERATION -> tanh(arg)
|
||||
HyperbolicTrigonometricOperations.ACOSH_OPERATION -> acosh(arg)
|
||||
HyperbolicTrigonometricOperations.ASINH_OPERATION -> asinh(arg)
|
||||
HyperbolicTrigonometricOperations.ATANH_OPERATION -> atanh(arg)
|
||||
HyperbolicOperations.COSH_OPERATION -> cosh(arg)
|
||||
HyperbolicOperations.SINH_OPERATION -> sinh(arg)
|
||||
HyperbolicOperations.TANH_OPERATION -> tanh(arg)
|
||||
HyperbolicOperations.ACOSH_OPERATION -> acosh(arg)
|
||||
HyperbolicOperations.ASINH_OPERATION -> asinh(arg)
|
||||
HyperbolicOperations.ATANH_OPERATION -> atanh(arg)
|
||||
PowerOperations.SQRT_OPERATION -> sqrt(arg)
|
||||
ExponentialOperations.EXP_OPERATION -> exp(arg)
|
||||
ExponentialOperations.LN_OPERATION -> ln(arg)
|
||||
else -> super<HyperbolicTrigonometricOperations>.unaryOperation(operation, arg)
|
||||
else -> super.unaryOperation(operation, arg)
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +41,13 @@ interface ExtendedFieldOperations<T> :
|
||||
* Advanced Number-like field that implements basic operations.
|
||||
*/
|
||||
interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T> {
|
||||
override fun sinh(arg: T): T = (exp(arg) - exp(-arg)) / 2
|
||||
override fun cosh(arg: T): T = (exp(arg) + exp(-arg)) / 2
|
||||
override fun tanh(arg: T): T = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg))
|
||||
override fun asinh(arg: T): T = ln(sqrt(arg * arg + one) + arg)
|
||||
override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one)))
|
||||
override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2
|
||||
|
||||
override fun rightSideNumberOperation(operation: String, left: T, right: Number): T = when (operation) {
|
||||
PowerOperations.POW_OPERATION -> power(left, right)
|
||||
else -> super.rightSideNumberOperation(operation, left, right)
|
||||
@ -155,7 +163,7 @@ object FloatField : ExtendedField<Float>, Norm<Float, Float> {
|
||||
}
|
||||
|
||||
/**
|
||||
* A field for [Int] without boxing. Does not produce corresponding field element
|
||||
* A field for [Int] without boxing. Does not produce corresponding ring element.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||
object IntRing : Ring<Int>, Norm<Int, Int> {
|
||||
@ -179,7 +187,7 @@ object IntRing : Ring<Int>, Norm<Int, Int> {
|
||||
}
|
||||
|
||||
/**
|
||||
* A field for [Short] without boxing. Does not produce appropriate field element
|
||||
* A field for [Short] without boxing. Does not produce appropriate ring element.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||
object ShortRing : Ring<Short>, Norm<Short, Short> {
|
||||
@ -203,7 +211,7 @@ object ShortRing : Ring<Short>, Norm<Short, Short> {
|
||||
}
|
||||
|
||||
/**
|
||||
* A field for [Byte] values
|
||||
* A field for [Byte] without boxing. Does not produce appropriate ring element.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||
object ByteRing : Ring<Byte>, Norm<Byte, Byte> {
|
||||
@ -227,7 +235,7 @@ object ByteRing : Ring<Byte>, Norm<Byte, Byte> {
|
||||
}
|
||||
|
||||
/**
|
||||
* A field for [Long] values
|
||||
* A field for [Double] without boxing. Does not produce appropriate ring element.
|
||||
*/
|
||||
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||
object LongRing : Ring<Long>, Norm<Long, Long> {
|
||||
|
@ -6,7 +6,7 @@ package scientifik.kmath.operations
|
||||
* The operations are not exposed to class directly to avoid method bloat but instead are declared in the field.
|
||||
* It also allows to override behavior for optional operations.
|
||||
*/
|
||||
interface TrigonometricOperations<T> : FieldOperations<T> {
|
||||
interface TrigonometricOperations<T> : Algebra<T> {
|
||||
/**
|
||||
* Computes the sine of [arg].
|
||||
*/
|
||||
@ -62,6 +62,7 @@ interface TrigonometricOperations<T> : FieldOperations<T> {
|
||||
* The identifier of inverse cosine.
|
||||
*/
|
||||
const val ACOS_OPERATION = "acos"
|
||||
|
||||
/**
|
||||
* The identifier of inverse tangent.
|
||||
*/
|
||||
@ -106,7 +107,7 @@ fun <T : MathElement<out TrigonometricOperations<T>>> atan(arg: T): T = arg.cont
|
||||
* The operations are not exposed to class directly to avoid method bloat but instead are declared in the field. It
|
||||
* also allows to override behavior for optional operations.
|
||||
*/
|
||||
interface HyperbolicTrigonometricOperations<T> : FieldOperations<T> {
|
||||
interface HyperbolicOperations<T> : Algebra<T> {
|
||||
/**
|
||||
* Computes the hyperbolic sine of [arg].
|
||||
*/
|
||||
@ -138,21 +139,67 @@ interface HyperbolicTrigonometricOperations<T> : FieldOperations<T> {
|
||||
fun atanh(arg: T): T
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* The identifier of hyperbolic sine.
|
||||
*/
|
||||
const val SINH_OPERATION = "sinh"
|
||||
|
||||
/**
|
||||
* The identifier of hyperbolic cosine.
|
||||
*/
|
||||
const val COSH_OPERATION = "cosh"
|
||||
|
||||
/**
|
||||
* The identifier of hyperbolic tangent.
|
||||
*/
|
||||
const val TANH_OPERATION = "tanh"
|
||||
|
||||
/**
|
||||
* The identifier of inverse hyperbolic sine.
|
||||
*/
|
||||
const val ASINH_OPERATION = "asinh"
|
||||
|
||||
/**
|
||||
* The identifier of inverse hyperbolic cosine.
|
||||
*/
|
||||
const val ACOSH_OPERATION = "acosh"
|
||||
|
||||
/**
|
||||
* The identifier of inverse hyperbolic tangent.
|
||||
*/
|
||||
const val ATANH_OPERATION = "atanh"
|
||||
}
|
||||
}
|
||||
|
||||
fun <T : MathElement<out HyperbolicTrigonometricOperations<T>>> sinh(arg: T): T = arg.context.sinh(arg)
|
||||
fun <T : MathElement<out HyperbolicTrigonometricOperations<T>>> cosh(arg: T): T = arg.context.cosh(arg)
|
||||
fun <T : MathElement<out HyperbolicTrigonometricOperations<T>>> tanh(arg: T): T = arg.context.tanh(arg)
|
||||
fun <T : MathElement<out HyperbolicTrigonometricOperations<T>>> asinh(arg: T): T = arg.context.asinh(arg)
|
||||
fun <T : MathElement<out HyperbolicTrigonometricOperations<T>>> acosh(arg: T): T = arg.context.acosh(arg)
|
||||
fun <T : MathElement<out HyperbolicTrigonometricOperations<T>>> atanh(arg: T): T = arg.context.atanh(arg)
|
||||
/**
|
||||
* Computes the hyperbolic sine of [arg].
|
||||
*/
|
||||
fun <T : MathElement<out HyperbolicOperations<T>>> sinh(arg: T): T = arg.context.sinh(arg)
|
||||
|
||||
/**
|
||||
* Computes the hyperbolic cosine of [arg].
|
||||
*/
|
||||
fun <T : MathElement<out HyperbolicOperations<T>>> cosh(arg: T): T = arg.context.cosh(arg)
|
||||
|
||||
/**
|
||||
* Computes the hyperbolic tangent of [arg].
|
||||
*/
|
||||
fun <T : MathElement<out HyperbolicOperations<T>>> tanh(arg: T): T = arg.context.tanh(arg)
|
||||
|
||||
/**
|
||||
* Computes the inverse hyperbolic sine of [arg].
|
||||
*/
|
||||
fun <T : MathElement<out HyperbolicOperations<T>>> asinh(arg: T): T = arg.context.asinh(arg)
|
||||
|
||||
/**
|
||||
* Computes the inverse hyperbolic cosine of [arg].
|
||||
*/
|
||||
fun <T : MathElement<out HyperbolicOperations<T>>> acosh(arg: T): T = arg.context.acosh(arg)
|
||||
|
||||
/**
|
||||
* Computes the inverse hyperbolic tangent of [arg].
|
||||
*/
|
||||
fun <T : MathElement<out HyperbolicOperations<T>>> atanh(arg: T): T = arg.context.atanh(arg)
|
||||
|
||||
/**
|
||||
* A context extension to include power operations based on exponentiation.
|
||||
|
Loading…
Reference in New Issue
Block a user