kmath/doc/operations.md

2.0 KiB

Spaces and fields

An obvious first choice of mathematical objects to implement in a context-oriented style are algebraic elements like spaces, rings and fields. Those are located in the scientifik.kmath.operations.Algebra.kt file. Alongside common contexts, the file includes definitions for algebra elements like FieldElement. A FieldElement object stores a reference to the Field which contains additive and multiplicative operations, meaning it has one fixed context attached and does not require explicit external context. So those MathElements can be operated without context:

val c1 = Complex(1.0, 2.0)
val c2 = ComplexField.i
val c3 = c1 + c2

ComplexField also features special operations to mix complex and real numbers, for example:

val c1 = Complex(1.0, 2.0)
val c2 = ComplexField.run{ c1 - 1.0} // Returns: [re:0.0, im: 2.0]
val c3 = ComplexField.run{ c1 - i*2.0}

Note: In theory it is possible to add behaviors directly to the context, but currently kotlin syntax does not support that. Watch KT-10468 and KEEP-176 for updates.

Nested fields

Contexts allow one to build more complex structures. For example, it is possible to create a Matrix from complex elements like so:

val element = NDElement.complex(shape = intArrayOf(2,2)){ index: IntArray ->
    Complex(index[0].toDouble() - index[1].toDouble(), index[0].toDouble() + index[1].toDouble())
}

The element in this example is a member of the Field of 2-d structures, each element of which is a member of its own ComplexField. The important thing is one does not need to create a special n-d class to hold complex numbers and implement operations on it, one just needs to provide a field for its elements.

Note: Fields themselves do not solve the problem of JVM boxing, but it is possible to solve with special contexts like BufferSpec. This feature is in development phase.