diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt index b47c7cae8..23deae24b 100644 --- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt +++ b/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt @@ -84,9 +84,9 @@ object MstExtendedField : ExtendedField { 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) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt index dd5fb572a..9fe8aaf93 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -139,15 +139,9 @@ open class FunctionalExpressionExtendedField(algebra: A) : ExtendedField> where A : ExtendedField, A : NumericAlgebra { override fun sin(arg: Expression): Expression = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg) override fun cos(arg: Expression): Expression = unaryOperation(TrigonometricOperations.COS_OPERATION, arg) - - override fun asin(arg: Expression): Expression = - unaryOperation(InverseTrigonometricOperations.ASIN_OPERATION, arg) - - override fun acos(arg: Expression): Expression = - unaryOperation(InverseTrigonometricOperations.ACOS_OPERATION, arg) - - override fun atan(arg: Expression): Expression = - unaryOperation(InverseTrigonometricOperations.ATAN_OPERATION, arg) + override fun asin(arg: Expression): Expression = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg) + override fun acos(arg: Expression): Expression = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg) + override fun atan(arg: Expression): Expression = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg) override fun power(arg: Expression, pow: Number): Expression = binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow)) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt index aea0c59ec..f1535e212 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt @@ -99,13 +99,6 @@ object ComplexField : ExtendedField { 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): Buffer { return MemoryBuffer.create(Complex, size, init) diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt index 8b397208b..98cf912ac 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt @@ -7,8 +7,9 @@ import kotlin.math.pow as kpow * Advanced Number-like semifield that implements basic operations. */ interface ExtendedFieldOperations : + FieldOperations, TrigonometricOperations, - HyperbolicTrigonometricOperations, + HyperbolicOperations, PowerOperations, ExponentialOperations { @@ -22,16 +23,16 @@ interface ExtendedFieldOperations : 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.unaryOperation(operation, arg) + else -> super.unaryOperation(operation, arg) } } @@ -40,6 +41,13 @@ interface ExtendedFieldOperations : * Advanced Number-like field that implements basic operations. */ interface ExtendedField : ExtendedFieldOperations, Field { + 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, Norm { } /** - * 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, Norm { @@ -179,7 +187,7 @@ object IntRing : Ring, Norm { } /** - * 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, Norm { @@ -203,7 +211,7 @@ object ShortRing : Ring, Norm { } /** - * 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, Norm { @@ -227,7 +235,7 @@ object ByteRing : Ring, Norm { } /** - * 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, Norm { diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt index 165d34dc4..e19acea3d 100644 --- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt +++ b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt @@ -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 : FieldOperations { +interface TrigonometricOperations : Algebra { /** * Computes the sine of [arg]. */ @@ -62,6 +62,7 @@ interface TrigonometricOperations : FieldOperations { * The identifier of inverse cosine. */ const val ACOS_OPERATION = "acos" + /** * The identifier of inverse tangent. */ @@ -106,7 +107,7 @@ fun >> 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 : FieldOperations { +interface HyperbolicOperations : Algebra { /** * Computes the hyperbolic sine of [arg]. */ @@ -138,21 +139,67 @@ interface HyperbolicTrigonometricOperations : FieldOperations { 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 >> sinh(arg: T): T = arg.context.sinh(arg) -fun >> cosh(arg: T): T = arg.context.cosh(arg) -fun >> tanh(arg: T): T = arg.context.tanh(arg) -fun >> asinh(arg: T): T = arg.context.asinh(arg) -fun >> acosh(arg: T): T = arg.context.acosh(arg) -fun >> atanh(arg: T): T = arg.context.atanh(arg) +/** + * Computes the hyperbolic sine of [arg]. + */ +fun >> sinh(arg: T): T = arg.context.sinh(arg) + +/** + * Computes the hyperbolic cosine of [arg]. + */ +fun >> cosh(arg: T): T = arg.context.cosh(arg) + +/** + * Computes the hyperbolic tangent of [arg]. + */ +fun >> tanh(arg: T): T = arg.context.tanh(arg) + +/** + * Computes the inverse hyperbolic sine of [arg]. + */ +fun >> asinh(arg: T): T = arg.context.asinh(arg) + +/** + * Computes the inverse hyperbolic cosine of [arg]. + */ +fun >> acosh(arg: T): T = arg.context.acosh(arg) + +/** + * Computes the inverse hyperbolic tangent of [arg]. + */ +fun >> atanh(arg: T): T = arg.context.atanh(arg) /** * A context extension to include power operations based on exponentiation.