Add pi and e constants, some unrelated changes

This commit is contained in:
Iaroslav Postovalov 2021-03-31 21:51:54 +07:00
parent f7e792faff
commit cf91da1a98
No known key found for this signature in database
GPG Key ID: 46E15E4A31B3BCD7
25 changed files with 225 additions and 140 deletions

View File

@ -1,6 +1,5 @@
package space.kscience.kmath.structures
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.ExtendedField
@ -9,12 +8,10 @@ import java.util.*
import java.util.stream.IntStream
/**
* A demonstration implementation of NDField over Real using Java [DoubleStream] for parallel execution
* A demonstration implementation of NDField over Real using Java [java.util.stream.DoubleStream] for parallel
* execution.
*/
@OptIn(UnstableKMathAPI::class)
class StreamDoubleFieldND(
override val shape: IntArray,
) : FieldND<Double, DoubleField>,
class StreamDoubleFieldND(override val shape: IntArray) : FieldND<Double, DoubleField>,
NumbersAddOperations<StructureND<Double>>,
ExtendedField<StructureND<Double>> {
@ -38,7 +35,6 @@ class StreamDoubleFieldND(
else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) }
}
override fun produce(initializer: DoubleField.(IntArray) -> Double): BufferND<Double> {
val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset ->
val index = strides.index(offset)
@ -104,4 +100,4 @@ class StreamDoubleFieldND(
override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) }
}
fun AlgebraND.Companion.realWithStream(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(shape)
fun AlgebraND.Companion.realWithStream(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(shape)

View File

@ -49,9 +49,10 @@ public object MstGroup : Group<MST>, NumericAlgebra<MST>, ScaleOperations<MST> {
/**
* [Ring] over [MST] nodes.
*/
@Suppress("OVERRIDE_BY_INLINE")
@OptIn(UnstableKMathAPI::class)
public object MstRing : Ring<MST>, NumbersAddOperations<MST>, ScaleOperations<MST> {
public override val zero: MST.Numeric get() = MstGroup.zero
public override inline val zero: MST.Numeric get() = MstGroup.zero
public override val one: MST.Numeric = number(1.0)
public override fun number(value: Number): MST.Numeric = MstGroup.number(value)
@ -78,11 +79,11 @@ public object MstRing : Ring<MST>, NumbersAddOperations<MST>, ScaleOperations<MS
/**
* [Field] over [MST] nodes.
*/
@Suppress("OVERRIDE_BY_INLINE")
@OptIn(UnstableKMathAPI::class)
public object MstField : Field<MST>, NumbersAddOperations<MST>, ScaleOperations<MST> {
public override val zero: MST.Numeric get() = MstRing.zero
public override val one: MST.Numeric get() = MstRing.one
public override inline val zero: MST.Numeric get() = MstRing.zero
public override inline val one: MST.Numeric get() = MstRing.one
public override fun bindSymbolOrNull(value: String): MST.Symbolic = MstAlgebra.bindSymbolOrNull(value)
public override fun number(value: Number): MST.Numeric = MstRing.number(value)
@ -109,9 +110,10 @@ public object MstField : Field<MST>, NumbersAddOperations<MST>, ScaleOperations<
/**
* [ExtendedField] over [MST] nodes.
*/
@Suppress("OVERRIDE_BY_INLINE")
public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> {
public override val zero: MST.Numeric get() = MstField.zero
public override val one: MST.Numeric get() = MstField.one
public override inline val zero: MST.Numeric get() = MstField.zero
public override inline val one: MST.Numeric get() = MstField.one
public override fun bindSymbolOrNull(value: String): MST.Symbolic = MstAlgebra.bindSymbolOrNull(value)
public override fun number(value: Number): MST.Numeric = MstRing.number(value)

View File

@ -34,6 +34,7 @@ public object LatexSyntaxRenderer : SyntaxRenderer {
is SpecialSymbolSyntax -> when (node.kind) {
SpecialSymbolSyntax.Kind.INFINITY -> append("\\infty")
SpecialSymbolSyntax.Kind.SMALL_PI -> append("\\pi")
}
is OperandSyntax -> {

View File

@ -48,6 +48,7 @@ public object MathMLSyntaxRenderer : SyntaxRenderer {
is SpecialSymbolSyntax -> when (node.kind) {
SpecialSymbolSyntax.Kind.INFINITY -> tag("mo") { append("&infin;") }
SpecialSymbolSyntax.Kind.SMALL_PI -> tag("mo") { append("&pi;") }
}
is OperandSyntax -> if (node.parentheses) {

View File

@ -85,9 +85,10 @@ public open class FeaturedMathRendererWithPostProcess(
BinaryOperator.Default,
UnaryOperator.Default,
// Pretty printing for numerics
// Pretty printing for some objects
PrettyPrintFloats.Default,
PrettyPrintIntegers.Default,
PrettyPrintPi.Default,
// Printing terminal nodes as string
PrintNumeric,
@ -96,7 +97,7 @@ public open class FeaturedMathRendererWithPostProcess(
listOf(
SimplifyParentheses.Default,
BetterMultiplication,
)
),
)
}
}

View File

@ -101,6 +101,11 @@ public data class SpecialSymbolSyntax(public var kind: Kind) : TerminalSyntax()
* The infinity (&infin;) symbol.
*/
INFINITY,
/**
* The Pi (&pi;) symbol.
*/
SMALL_PI;
}
}

View File

@ -118,6 +118,25 @@ public class PrettyPrintIntegers(public val types: Set<KClass<out Number>>) : Re
}
}
/**
* Special printing for symbols meaning Pi.
*
* @property symbols The allowed symbols.
*/
public class PrettyPrintPi(public val symbols: Set<String>) : RenderFeature {
public override fun render(renderer: FeaturedMathRenderer, node: MST): MathSyntax? {
if (node !is MST.Symbolic || node.value !in symbols) return null
return SpecialSymbolSyntax(kind = SpecialSymbolSyntax.Kind.SMALL_PI)
}
public companion object {
/**
* The default instance containing `pi`.
*/
public val Default: PrettyPrintPi = PrettyPrintPi(setOf("pi"))
}
}
/**
* Abstract printing of unary operations which discards [MST] if their operation is not in [operations] or its type is
* not [MST.Unary].

View File

@ -45,6 +45,11 @@ internal class TestFeatures {
testLatex(Numeric(-42), "-42")
}
@Test
fun prettyPrintPi() {
testLatex("pi", "\\pi")
}
@Test
fun binaryPlus() = testLatex("2+2", "2+2")

View File

@ -16,7 +16,10 @@ internal class TestLatex {
fun operatorName() = testLatex("sin(1)", "\\operatorname{sin}\\,\\left(1\\right)")
@Test
fun specialSymbol() = testLatex(MST.Numeric(Double.POSITIVE_INFINITY), "\\infty")
fun specialSymbol() {
testLatex(MST.Numeric(Double.POSITIVE_INFINITY), "\\infty")
testLatex("pi", "\\pi")
}
@Test
fun operand() {

View File

@ -19,7 +19,10 @@ internal class TestMathML {
)
@Test
fun specialSymbol() = testMathML(MST.Numeric(Double.POSITIVE_INFINITY), "<mo>&infin;</mo>")
fun specialSymbol() {
testMathML(MST.Numeric(Double.POSITIVE_INFINITY), "<mo>&infin;</mo>")
testMathML("pi", "<mo>&pi;</mo>")
}
@Test
fun operand() {

View File

@ -24,7 +24,7 @@ public class DerivativeStructureField(
public override val zero: DerivativeStructure by lazy { DerivativeStructure(numberOfVariables, order) }
public override val one: DerivativeStructure by lazy { DerivativeStructure(numberOfVariables, order, 1.0) }
override fun number(value: Number): DerivativeStructure = const(value.toDouble())
public override fun number(value: Number): DerivativeStructure = const(value.toDouble())
/**
* A class that implements both [DerivativeStructure] and a [Symbol]
@ -35,10 +35,10 @@ public class DerivativeStructureField(
symbol: Symbol,
value: Double,
) : DerivativeStructure(size, order, index, value), Symbol {
override val identity: String = symbol.identity
override fun toString(): String = identity
override fun equals(other: Any?): Boolean = this.identity == (other as? Symbol)?.identity
override fun hashCode(): Int = identity.hashCode()
public override val identity: String = symbol.identity
public override fun toString(): String = identity
public override fun equals(other: Any?): Boolean = this.identity == (other as? Symbol)?.identity
public override fun hashCode(): Int = identity.hashCode()
}
/**
@ -48,10 +48,10 @@ public class DerivativeStructureField(
key.identity to DerivativeStructureSymbol(numberOfVariables, index, key, value)
}.toMap()
override fun const(value: Double): DerivativeStructure = DerivativeStructure(numberOfVariables, order, value)
public override fun const(value: Double): DerivativeStructure = DerivativeStructure(numberOfVariables, order, value)
override fun bindSymbolOrNull(value: String): DerivativeStructureSymbol? = variables[value]
override fun bindSymbol(value: String): DerivativeStructureSymbol = variables.getValue(value)
public override fun bindSymbolOrNull(value: String): DerivativeStructureSymbol? = variables[value]
public override fun bindSymbol(value: String): DerivativeStructureSymbol = variables.getValue(value)
public fun bindSymbolOrNull(symbol: Symbol): DerivativeStructureSymbol? = variables[symbol.identity]
public fun bindSymbol(symbol: Symbol): DerivativeStructureSymbol = variables.getValue(symbol.identity)
@ -64,7 +64,7 @@ public class DerivativeStructureField(
public fun DerivativeStructure.derivative(vararg symbols: Symbol): Double = derivative(symbols.toList())
override fun DerivativeStructure.unaryMinus(): DerivativeStructure = negate()
public override fun DerivativeStructure.unaryMinus(): DerivativeStructure = negate()
public override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b)

View File

@ -121,8 +121,8 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, Num
/**
* Adds complex number to real one.
*
* @receiver the addend.
* @param c the augend.
* @receiver the augend.
* @param c the addend.
* @return the sum.
*/
public operator fun Double.plus(c: Complex): Complex = add(this.toComplex(), c)
@ -139,8 +139,8 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, Num
/**
* Adds real number to complex one.
*
* @receiver the addend.
* @param d the augend.
* @receiver the augend.
* @param d the addend.
* @return the sum.
*/
public operator fun Complex.plus(d: Double): Complex = d + this

View File

@ -22,10 +22,10 @@ public class ComplexFieldND(
NumbersAddOperations<StructureND<Complex>>,
ExtendedField<StructureND<Complex>> {
override val zero: BufferND<Complex> by lazy { produce { zero } }
override val one: BufferND<Complex> by lazy { produce { one } }
public override val zero: BufferND<Complex> by lazy { produce { zero } }
public override val one: BufferND<Complex> by lazy { produce { one } }
override fun number(value: Number): BufferND<Complex> {
public override fun number(value: Number): BufferND<Complex> {
val d = value.toComplex() // minimize conversions
return produce { d }
}
@ -76,25 +76,25 @@ public class ComplexFieldND(
// return BufferedNDFieldElement(this, buffer)
// }
override fun power(arg: StructureND<Complex>, pow: Number): BufferND<Complex> = arg.map { power(it, pow) }
public override fun power(arg: StructureND<Complex>, pow: Number): BufferND<Complex> = arg.map { power(it, pow) }
override fun exp(arg: StructureND<Complex>): BufferND<Complex> = arg.map { exp(it) }
public override fun exp(arg: StructureND<Complex>): BufferND<Complex> = arg.map { exp(it) }
override fun ln(arg: StructureND<Complex>): BufferND<Complex> = arg.map { ln(it) }
public override fun ln(arg: StructureND<Complex>): BufferND<Complex> = arg.map { ln(it) }
override fun sin(arg: StructureND<Complex>): BufferND<Complex> = arg.map { sin(it) }
override fun cos(arg: StructureND<Complex>): BufferND<Complex> = arg.map { cos(it) }
override fun tan(arg: StructureND<Complex>): BufferND<Complex> = arg.map { tan(it) }
override fun asin(arg: StructureND<Complex>): BufferND<Complex> = arg.map { asin(it) }
override fun acos(arg: StructureND<Complex>): BufferND<Complex> = arg.map { acos(it) }
override fun atan(arg: StructureND<Complex>): BufferND<Complex> = arg.map { atan(it) }
public override fun sin(arg: StructureND<Complex>): BufferND<Complex> = arg.map { sin(it) }
public override fun cos(arg: StructureND<Complex>): BufferND<Complex> = arg.map { cos(it) }
public override fun tan(arg: StructureND<Complex>): BufferND<Complex> = arg.map { tan(it) }
public override fun asin(arg: StructureND<Complex>): BufferND<Complex> = arg.map { asin(it) }
public override fun acos(arg: StructureND<Complex>): BufferND<Complex> = arg.map { acos(it) }
public override fun atan(arg: StructureND<Complex>): BufferND<Complex> = arg.map { atan(it) }
override fun sinh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { sinh(it) }
override fun cosh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { cosh(it) }
override fun tanh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { tanh(it) }
override fun asinh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { asinh(it) }
override fun acosh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { acosh(it) }
override fun atanh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { atanh(it) }
public override fun sinh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { sinh(it) }
public override fun cosh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { cosh(it) }
public override fun tanh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { tanh(it) }
public override fun asinh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { asinh(it) }
public override fun acosh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { acosh(it) }
public override fun atanh(arg: StructureND<Complex>): BufferND<Complex> = arg.map { atanh(it) }
}

View File

@ -121,6 +121,8 @@ public class space/kscience/kmath/expressions/FunctionalExpressionExtendedField
public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object;
public fun atanh (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression;
public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object;
public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Expression;
public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object;
public fun cos (Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression;
public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object;
@ -152,6 +154,8 @@ public class space/kscience/kmath/expressions/FunctionalExpressionExtendedField
public class space/kscience/kmath/expressions/FunctionalExpressionField : space/kscience/kmath/expressions/FunctionalExpressionRing, space/kscience/kmath/operations/Field, space/kscience/kmath/operations/ScaleOperations {
public fun <init> (Lspace/kscience/kmath/operations/Field;)V
public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object;
public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Expression;
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public final fun div (Ljava/lang/Object;Lspace/kscience/kmath/expressions/Expression;)Lspace/kscience/kmath/expressions/Expression;
@ -235,6 +239,8 @@ public final class space/kscience/kmath/expressions/SimpleAutoDiffExtendedField
public fun atan (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue;
public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object;
public fun atanh (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue;
public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object;
public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/expressions/AutoDiffValue;
public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object;
public fun cos (Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue;
public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object;
@ -708,6 +714,8 @@ public final class space/kscience/kmath/nd/BufferND : space/kscience/kmath/nd/St
public class space/kscience/kmath/nd/BufferedFieldND : space/kscience/kmath/nd/BufferedRingND, space/kscience/kmath/nd/FieldND {
public fun <init> ([ILspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function2;)V
public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object;
public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/nd/StructureND;
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND;
@ -821,6 +829,8 @@ public final class space/kscience/kmath/nd/DoubleFieldND : space/kscience/kmath/
public fun atan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND;
public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object;
public fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND;
public synthetic fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object;
public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/nd/StructureND;
public fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/BufferND;
public synthetic fun combine (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND;
public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object;
@ -997,6 +1007,8 @@ public final class space/kscience/kmath/nd/ShapeMismatchException : java/lang/Ru
public final class space/kscience/kmath/nd/ShortRingND : space/kscience/kmath/nd/BufferedRingND, space/kscience/kmath/operations/NumbersAddOperations {
public fun <init> ([I)V
public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object;
public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/nd/StructureND;
public synthetic fun getOne ()Ljava/lang/Object;
public fun getOne ()Lspace/kscience/kmath/nd/BufferND;
public synthetic fun getZero ()Ljava/lang/Object;
@ -1447,6 +1459,7 @@ public abstract interface class space/kscience/kmath/operations/ExtendedField :
public abstract fun acosh (Ljava/lang/Object;)Ljava/lang/Object;
public abstract fun asinh (Ljava/lang/Object;)Ljava/lang/Object;
public abstract fun atanh (Ljava/lang/Object;)Ljava/lang/Object;
public abstract fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object;
public abstract fun cosh (Ljava/lang/Object;)Ljava/lang/Object;
public abstract fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public abstract fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
@ -1914,6 +1927,7 @@ public final class space/kscience/kmath/operations/NumbersAddOperations$DefaultI
}
public abstract interface class space/kscience/kmath/operations/NumericAlgebra : space/kscience/kmath/operations/Algebra {
public abstract fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object;
public abstract fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public abstract fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public abstract fun number (Ljava/lang/Number;)Ljava/lang/Object;
@ -1934,6 +1948,11 @@ public final class space/kscience/kmath/operations/NumericAlgebra$DefaultImpls {
public static fun unaryOperationFunction (Lspace/kscience/kmath/operations/NumericAlgebra;Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
}
public final class space/kscience/kmath/operations/NumericAlgebraKt {
public static final fun getE (Lspace/kscience/kmath/operations/NumericAlgebra;)Ljava/lang/Object;
public static final fun getPi (Lspace/kscience/kmath/operations/NumericAlgebra;)Ljava/lang/Object;
}
public final class space/kscience/kmath/operations/OptionalOperationsKt {
}

View File

@ -19,8 +19,10 @@ public abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(
/**
* Builds an Expression to access a variable.
*/
override fun bindSymbolOrNull(value: String): Expression<T>? = Expression { arguments ->
arguments[StringSymbol(value)] ?: error("Argument not found: $value")
public override fun bindSymbolOrNull(value: String): Expression<T>? = Expression { arguments ->
algebra.bindSymbolOrNull(value)
?: arguments[StringSymbol(value)]
?: error("Symbol '$value' is not supported in $this")
}
/**
@ -49,7 +51,7 @@ public open class FunctionalExpressionGroup<T, A : Group<T>>(
) : FunctionalExpressionAlgebra<T, A>(algebra), Group<Expression<T>> {
public override val zero: Expression<T> get() = const(algebra.zero)
override fun Expression<T>.unaryMinus(): Expression<T> =
public override fun Expression<T>.unaryMinus(): Expression<T> =
unaryOperation(GroupOperations.MINUS_OPERATION, this)
/**
@ -117,16 +119,21 @@ public open class FunctionalExpressionField<T, A : Field<T>>(
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
super<FunctionalExpressionRing>.binaryOperationFunction(operation)
override fun scale(a: Expression<T>, value: Double): Expression<T> = algebra {
public override fun scale(a: Expression<T>, value: Double): Expression<T> = algebra {
Expression { args -> a(args) * value }
}
public override fun bindSymbolOrNull(value: String): Expression<T>? =
super<FunctionalExpressionRing>.bindSymbolOrNull(value)
}
public open class FunctionalExpressionExtendedField<T, A : ExtendedField<T>>(
algebra: A,
) : FunctionalExpressionField<T, A>(algebra), ExtendedField<Expression<T>> {
public override fun number(value: Number): Expression<T> = const(algebra.number(value))
override fun number(value: Number): Expression<T> = const(algebra.number(value))
public override fun sqrt(arg: Expression<T>): Expression<T> =
unaryOperationFunction(PowerOperations.SQRT_OPERATION)(arg)
public override fun sin(arg: Expression<T>): Expression<T> =
unaryOperationFunction(TrigonometricOperations.SIN_OPERATION)(arg)
@ -157,6 +164,8 @@ public open class FunctionalExpressionExtendedField<T, A : ExtendedField<T>>(
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
super<FunctionalExpressionField>.binaryOperationFunction(operation)
public override fun bindSymbol(value: String): Expression<T> = super<FunctionalExpressionField>.bindSymbol(value)
}
public inline fun <T, A : Group<T>> A.expressionInSpace(block: FunctionalExpressionGroup<T, A>.() -> Expression<T>): Expression<T> =

View File

@ -337,9 +337,11 @@ public class SimpleAutoDiffExtendedField<T : Any, F : ExtendedField<T>>(
) : ExtendedField<AutoDiffValue<T>>, ScaleOperations<AutoDiffValue<T>>,
SimpleAutoDiffField<T, F>(context, bindings) {
override fun number(value: Number): AutoDiffValue<T> = const { number(value) }
override fun bindSymbol(value: String): AutoDiffValue<T> = super<SimpleAutoDiffField>.bindSymbol(value)
override fun scale(a: AutoDiffValue<T>, value: Double): AutoDiffValue<T> = a * number(value)
public override fun number(value: Number): AutoDiffValue<T> = const { number(value) }
public override fun scale(a: AutoDiffValue<T>, value: Double): AutoDiffValue<T> = a * number(value)
// x ^ 2
public fun sqr(x: AutoDiffValue<T>): AutoDiffValue<T> =

View File

@ -120,8 +120,8 @@ public interface GroupND<T, S : Group<T>> : Group<StructureND<T>>, AlgebraND<T,
/**
* Element-wise addition.
*
* @param a the addend.
* @param b the augend.
* @param a the augend.
* @param b the addend.
* @return the sum.
*/
public override fun add(a: StructureND<T>, b: StructureND<T>): StructureND<T> =
@ -141,8 +141,8 @@ public interface GroupND<T, S : Group<T>> : Group<StructureND<T>>, AlgebraND<T,
/**
* Adds an ND structure to an element of it.
*
* @receiver the addend.
* @param arg the augend.
* @receiver the augend.
* @param arg the addend.
* @return the sum.
*/
public operator fun StructureND<T>.plus(arg: T): StructureND<T> = this.map { value -> add(arg, value) }
@ -159,8 +159,8 @@ public interface GroupND<T, S : Group<T>> : Group<StructureND<T>>, AlgebraND<T,
/**
* Adds an element to ND structure of it.
*
* @receiver the addend.
* @param arg the augend.
* @receiver the augend.
* @param arg the addend.
* @return the sum.
*/
public operator fun T.plus(arg: StructureND<T>): StructureND<T> = arg.map { value -> add(this@plus, value) }

View File

@ -17,15 +17,15 @@ public class DoubleFieldND(
ScaleOperations<StructureND<Double>>,
ExtendedField<StructureND<Double>> {
override val zero: BufferND<Double> by lazy { produce { zero } }
override val one: BufferND<Double> by lazy { produce { one } }
public override val zero: BufferND<Double> by lazy { produce { zero } }
public override val one: BufferND<Double> by lazy { produce { one } }
override fun number(value: Number): BufferND<Double> {
public override fun number(value: Number): BufferND<Double> {
val d = value.toDouble() // minimize conversions
return produce { d }
}
override val StructureND<Double>.buffer: DoubleBuffer
public override val StructureND<Double>.buffer: DoubleBuffer
get() = when {
!shape.contentEquals(this@DoubleFieldND.shape) -> throw ShapeMismatchException(
this@DoubleFieldND.shape,
@ -36,7 +36,7 @@ public class DoubleFieldND(
}
@Suppress("OVERRIDE_BY_INLINE")
override inline fun StructureND<Double>.map(
public override inline fun StructureND<Double>.map(
transform: DoubleField.(Double) -> Double,
): BufferND<Double> {
val buffer = DoubleBuffer(strides.linearSize) { offset -> DoubleField.transform(buffer.array[offset]) }
@ -44,7 +44,7 @@ public class DoubleFieldND(
}
@Suppress("OVERRIDE_BY_INLINE")
override inline fun produce(initializer: DoubleField.(IntArray) -> Double): BufferND<Double> {
public override inline fun produce(initializer: DoubleField.(IntArray) -> Double): BufferND<Double> {
val array = DoubleArray(strides.linearSize) { offset ->
val index = strides.index(offset)
DoubleField.initializer(index)
@ -53,7 +53,7 @@ public class DoubleFieldND(
}
@Suppress("OVERRIDE_BY_INLINE")
override inline fun StructureND<Double>.mapIndexed(
public override inline fun StructureND<Double>.mapIndexed(
transform: DoubleField.(index: IntArray, Double) -> Double,
): BufferND<Double> = BufferND(
strides,
@ -65,7 +65,7 @@ public class DoubleFieldND(
})
@Suppress("OVERRIDE_BY_INLINE")
override inline fun combine(
public override inline fun combine(
a: StructureND<Double>,
b: StructureND<Double>,
transform: DoubleField.(Double, Double) -> Double,
@ -76,27 +76,26 @@ public class DoubleFieldND(
return BufferND(strides, buffer)
}
override fun scale(a: StructureND<Double>, value: Double): StructureND<Double> = a.map { it * value }
public override fun scale(a: StructureND<Double>, value: Double): StructureND<Double> = a.map { it * value }
override fun power(arg: StructureND<Double>, pow: Number): BufferND<Double> = arg.map { power(it, pow) }
public override fun power(arg: StructureND<Double>, pow: Number): BufferND<Double> = arg.map { power(it, pow) }
override fun exp(arg: StructureND<Double>): BufferND<Double> = arg.map { exp(it) }
public override fun exp(arg: StructureND<Double>): BufferND<Double> = arg.map { exp(it) }
public override fun ln(arg: StructureND<Double>): BufferND<Double> = arg.map { ln(it) }
override fun ln(arg: StructureND<Double>): BufferND<Double> = arg.map { ln(it) }
public override fun sin(arg: StructureND<Double>): BufferND<Double> = arg.map { sin(it) }
public override fun cos(arg: StructureND<Double>): BufferND<Double> = arg.map { cos(it) }
public override fun tan(arg: StructureND<Double>): BufferND<Double> = arg.map { tan(it) }
public override fun asin(arg: StructureND<Double>): BufferND<Double> = arg.map { asin(it) }
public override fun acos(arg: StructureND<Double>): BufferND<Double> = arg.map { acos(it) }
public override fun atan(arg: StructureND<Double>): BufferND<Double> = arg.map { atan(it) }
override fun sin(arg: StructureND<Double>): BufferND<Double> = arg.map { sin(it) }
override fun cos(arg: StructureND<Double>): BufferND<Double> = arg.map { cos(it) }
override fun tan(arg: StructureND<Double>): BufferND<Double> = arg.map { tan(it) }
override fun asin(arg: StructureND<Double>): BufferND<Double> = arg.map { asin(it) }
override fun acos(arg: StructureND<Double>): BufferND<Double> = arg.map { acos(it) }
override fun atan(arg: StructureND<Double>): BufferND<Double> = arg.map { atan(it) }
override fun sinh(arg: StructureND<Double>): BufferND<Double> = arg.map { sinh(it) }
override fun cosh(arg: StructureND<Double>): BufferND<Double> = arg.map { cosh(it) }
override fun tanh(arg: StructureND<Double>): BufferND<Double> = arg.map { tanh(it) }
override fun asinh(arg: StructureND<Double>): BufferND<Double> = arg.map { asinh(it) }
override fun acosh(arg: StructureND<Double>): BufferND<Double> = arg.map { acosh(it) }
override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) }
public override fun sinh(arg: StructureND<Double>): BufferND<Double> = arg.map { sinh(it) }
public override fun cosh(arg: StructureND<Double>): BufferND<Double> = arg.map { cosh(it) }
public override fun tanh(arg: StructureND<Double>): BufferND<Double> = arg.map { tanh(it) }
public override fun asinh(arg: StructureND<Double>): BufferND<Double> = arg.map { asinh(it) }
public override fun acosh(arg: StructureND<Double>): BufferND<Double> = arg.map { acosh(it) }
public override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) }
}
public fun AlgebraND.Companion.real(vararg shape: Int): DoubleFieldND = DoubleFieldND(shape)

View File

@ -119,8 +119,8 @@ public interface GroupOperations<T> : Algebra<T> {
/**
* Addition of two elements.
*
* @param a the addend.
* @param b the augend.
* @param a the augend.
* @param b the addend.
* @return the sum.
*/
public fun add(a: T, b: T): T
@ -146,8 +146,8 @@ public interface GroupOperations<T> : Algebra<T> {
/**
* Addition of two elements.
*
* @receiver the addend.
* @param b the augend.
* @receiver the augend.
* @param b the addend.
* @return the sum.
*/
public operator fun T.plus(b: T): T = add(this, b)
@ -293,5 +293,5 @@ public interface FieldOperations<T> : RingOperations<T> {
* @param T the type of element of this field.
*/
public interface Field<T> : Ring<T>, FieldOperations<T>, ScaleOperations<T>, NumericAlgebra<T> {
override fun number(value: Number): T = scale(one, value.toDouble())
}
public override fun number(value: Number): T = scale(one, value.toDouble())
}

View File

@ -46,7 +46,8 @@ public operator fun <T : AlgebraElement<T, S>, S : NumbersAddOperations<T>> T.mi
/**
* Adds element to this one.
*
* @param b the augend.
* @receiver the augend.
* @param b the addend.
* @return the sum.
*/
public operator fun <T : AlgebraElement<T, S>, S : Group<T>> T.plus(b: T): T =
@ -58,11 +59,11 @@ public operator fun <T : AlgebraElement<T, S>, S : Group<T>> T.plus(b: T): T =
//public operator fun <T : AlgebraElement<T, S>, S : Space<T>> Number.times(element: T): T =
// element.times(this)
/**
* Multiplies this element by another one.
*
* @param b the multiplicand.
* @receiver the multiplicand.
* @param b the multiplier.
* @return the product.
*/
public operator fun <T : AlgebraElement<T, R>, R : Ring<T>> T.times(b: T): T =

View File

@ -1,6 +1,8 @@
package space.kscience.kmath.operations
import space.kscience.kmath.misc.UnstableKMathAPI
import kotlin.math.E
import kotlin.math.PI
/**
* An algebraic structure where elements can have numeric representation.
@ -79,8 +81,26 @@ public interface NumericAlgebra<T> : Algebra<T> {
*/
public fun rightSideNumberOperation(operation: String, left: T, right: Number): T =
rightSideNumberOperationFunction(operation)(left, right)
public override fun bindSymbolOrNull(value: String): T? = when (value) {
"pi" -> number(PI)
"e" -> number(E)
else -> super.bindSymbolOrNull(value)
}
}
/**
* The &pi; mathematical constant.
*/
public val <T> NumericAlgebra<T>.pi: T
get() = bindSymbolOrNull("pi") ?: number(PI)
/**
* The *e* mathematical constant.
*/
public val <T> NumericAlgebra<T>.e: T
get() = number(E)
/**
* Scale by scalar operations
*/
@ -131,16 +151,16 @@ public interface NumbersAddOperations<T> : Group<T>, NumericAlgebra<T> {
/**
* Addition of element and scalar.
*
* @receiver the addend.
* @param b the augend.
* @receiver the augend.
* @param b the addend.
*/
public operator fun T.plus(b: Number): T = this + number(b)
/**
* Addition of scalar and element.
*
* @receiver the addend.
* @param b the augend.
* @receiver the augend.
* @param b the addend.
*/
public operator fun Number.plus(b: T): T = b + this

View File

@ -44,6 +44,12 @@ public interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T>, Numeri
public override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one)))
public override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2.0
public override fun bindSymbol(value: String): T = when (value) {
"pi" -> pi
"e" -> e
else -> super<ExtendedFieldOperations>.bindSymbol(value)
}
public override fun rightSideNumberOperationFunction(operation: String): (left: T, right: Number) -> T =
when (operation) {
PowerOperations.POW_OPERATION -> ::power
@ -56,10 +62,10 @@ public interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T>, Numeri
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> {
public override val zero: Double = 0.0
public override val one: Double = 1.0
public override inline val zero: Double get() = 0.0
public override inline val one: Double get() = 1.0
override fun number(value: Number): Double = value.toDouble()
public override fun number(value: Number): Double = value.toDouble()
public override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double =
when (operation) {
@ -68,13 +74,11 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp
}
public override inline fun add(a: Double, b: Double): Double = a + b
// public override inline fun multiply(a: Double, k: Number): Double = a * k.toDouble()
// override fun divide(a: Double, k: Number): Double = a / k.toDouble()
public override inline fun multiply(a: Double, b: Double): Double = a * b
public override inline fun divide(a: Double, b: Double): Double = a / b
override fun scale(a: Double, value: Double): Double = a * value
public override fun scale(a: Double, value: Double): Double = a * value
public override inline fun sin(arg: Double): Double = kotlin.math.sin(arg)
public override inline fun cos(arg: Double): Double = kotlin.math.cos(arg)
@ -108,10 +112,10 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
public override val zero: Float = 0.0f
public override val one: Float = 1.0f
public override inline val zero: Float get() = 0.0f
public override inline val one: Float get() = 1.0f
override fun number(value: Number): Float = value.toFloat()
public override fun number(value: Number): Float = value.toFloat()
public override fun binaryOperationFunction(operation: String): (left: Float, right: Float) -> Float =
when (operation) {
@ -120,7 +124,7 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
}
public override inline fun add(a: Float, b: Float): Float = a + b
override fun scale(a: Float, value: Double): Float = a * value.toFloat()
public override fun scale(a: Float, value: Double): Float = a * value.toFloat()
public override inline fun multiply(a: Float, b: Float): Float = a * b
@ -158,13 +162,13 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> {
public override val zero: Int
public override inline val zero: Int
get() = 0
public override val one: Int
public override inline val one: Int
get() = 1
override fun number(value: Number): Int = value.toInt()
public override fun number(value: Number): Int = value.toInt()
public override inline fun add(a: Int, b: Int): Int = a + b
public override inline fun multiply(a: Int, b: Int): Int = a * b
public override inline fun norm(arg: Int): Int = abs(arg)
@ -180,13 +184,13 @@ public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> {
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> {
public override val zero: Short
public override inline val zero: Short
get() = 0
public override val one: Short
public override inline val one: Short
get() = 1
override fun number(value: Number): Short = value.toShort()
public override fun number(value: Number): Short = value.toShort()
public override inline fun add(a: Short, b: Short): Short = (a + b).toShort()
public override inline fun multiply(a: Short, b: Short): Short = (a * b).toShort()
public override fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort()
@ -202,13 +206,13 @@ public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short>
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> {
public override val zero: Byte
public override inline val zero: Byte
get() = 0
public override val one: Byte
public override inline val one: Byte
get() = 1
override fun number(value: Number): Byte = value.toByte()
public override fun number(value: Number): Byte = value.toByte()
public override inline fun add(a: Byte, b: Byte): Byte = (a + b).toByte()
public override inline fun multiply(a: Byte, b: Byte): Byte = (a * b).toByte()
public override fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte()
@ -224,13 +228,13 @@ public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> {
*/
@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public object LongRing : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> {
public override val zero: Long
public override inline val zero: Long
get() = 0L
public override val one: Long
public override inline val one: Long
get() = 1L
override fun number(value: Number): Long = value.toLong()
public override fun number(value: Number): Long = value.toLong()
public override inline fun add(a: Long, b: Long): Long = a + b
public override inline fun multiply(a: Long, b: Long): Long = a * b
public override fun norm(arg: Long): Long = abs(arg)

View File

@ -3,7 +3,6 @@ package space.kscience.kmath.stat
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.runBlocking
import space.kscience.kmath.streaming.chunked
import kotlin.test.Test

View File

@ -126,7 +126,7 @@ public final class space/kscience/kmath/viktor/ViktorFieldND : space/kscience/km
public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object;
public fun sqrt (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND;
public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object;
public fun tan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND;
public fun tan-8UOKELU (Lspace/kscience/kmath/nd/StructureND;)Lorg/jetbrains/bio/viktor/F64Array;
public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object;
public fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND;
public fun times (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND;

View File

@ -41,7 +41,6 @@ public class ViktorFieldND(public override val shape: IntArray) : FieldND<Double
}
public override val zero: ViktorStructureND by lazy { F64Array.full(init = 0.0, shape = shape).asStructure() }
public override val one: ViktorStructureND by lazy { F64Array.full(init = 1.0, shape = shape).asStructure() }
private val strides: Strides = DefaultStrides(shape)
@ -55,7 +54,7 @@ public class ViktorFieldND(public override val shape: IntArray) : FieldND<Double
}
}.asStructure()
override fun StructureND<Double>.unaryMinus(): StructureND<Double> = -1 * this
public override fun StructureND<Double>.unaryMinus(): StructureND<Double> = -1 * this
public override fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): ViktorStructureND =
F64Array(*this@ViktorFieldND.shape).apply {
@ -100,24 +99,21 @@ public class ViktorFieldND(public override val shape: IntArray) : FieldND<Double
public override inline fun StructureND<Double>.plus(arg: Double): ViktorStructureND =
(f64Buffer.plus(arg)).asStructure()
override fun number(value: Number): ViktorStructureND =
public override fun number(value: Number): ViktorStructureND =
F64Array.full(init = value.toDouble(), shape = shape).asStructure()
override fun sin(arg: StructureND<Double>): ViktorStructureND = arg.map { sin(it) }
public override fun sin(arg: StructureND<Double>): ViktorStructureND = arg.map { sin(it) }
public override fun cos(arg: StructureND<Double>): ViktorStructureND = arg.map { cos(it) }
public override fun tan(arg: StructureND<Double>): ViktorStructureND = arg.map { tan(it) }
public override fun asin(arg: StructureND<Double>): ViktorStructureND = arg.map { asin(it) }
public override fun acos(arg: StructureND<Double>): ViktorStructureND = arg.map { acos(it) }
public override fun atan(arg: StructureND<Double>): ViktorStructureND = arg.map { atan(it) }
override fun cos(arg: StructureND<Double>): ViktorStructureND = arg.map { cos(it) }
public override fun power(arg: StructureND<Double>, pow: Number): ViktorStructureND = arg.map { it.pow(pow) }
override fun asin(arg: StructureND<Double>): ViktorStructureND = arg.map { asin(it) }
public override fun exp(arg: StructureND<Double>): ViktorStructureND = arg.f64Buffer.exp().asStructure()
override fun acos(arg: StructureND<Double>): ViktorStructureND = arg.map { acos(it) }
override fun atan(arg: StructureND<Double>): ViktorStructureND = arg.map { atan(it) }
override fun power(arg: StructureND<Double>, pow: Number): ViktorStructureND = arg.map { it.pow(pow) }
override fun exp(arg: StructureND<Double>): ViktorStructureND = arg.f64Buffer.exp().asStructure()
override fun ln(arg: StructureND<Double>): ViktorStructureND = arg.f64Buffer.log().asStructure()
public override fun ln(arg: StructureND<Double>): ViktorStructureND = arg.f64Buffer.log().asStructure()
}
public fun ViktorNDField(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)
public fun ViktorNDField(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)