All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.space.kscience.kmath.nd.RealNDField.kt Maven / Gradle / Ivy

package space.kscience.kmath.nd

import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.ExtendedField
import space.kscience.kmath.operations.RealField
import space.kscience.kmath.operations.RingWithNumbers
import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.RealBuffer
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract

@OptIn(UnstableKMathAPI::class)
public class RealNDField(
    shape: IntArray,
) : BufferedNDField(shape, RealField, Buffer.Companion::real),
    RingWithNumbers>,
    ExtendedField> {

    override val zero: NDBuffer by lazy { produce { zero } }
    override val one: NDBuffer by lazy { produce { one } }

    override fun number(value: Number): NDBuffer {
        val d = value.toDouble() // minimize conversions
        return produce { d }
    }

    override val NDStructure.buffer: RealBuffer
        get() = when {
            !shape.contentEquals([email protected]) -> throw ShapeMismatchException(
                [email protected],
                shape
            )
            this is NDBuffer && this.strides == [email protected] -> this.buffer as RealBuffer
            else -> RealBuffer(strides.linearSize) { offset -> get(strides.index(offset)) }
        }

    @Suppress("OVERRIDE_BY_INLINE")
    override inline fun NDStructure.map(
        transform: RealField.(Double) -> Double,
    ): NDBuffer {
        val buffer = RealBuffer(strides.linearSize) { offset -> RealField.transform(buffer.array[offset]) }
        return NDBuffer(strides, buffer)
    }

    @Suppress("OVERRIDE_BY_INLINE")
    override inline fun produce(initializer: RealField.(IntArray) -> Double): NDBuffer {
        val array = DoubleArray(strides.linearSize) { offset ->
            val index = strides.index(offset)
            RealField.initializer(index)
        }
        return NDBuffer(strides, RealBuffer(array))
    }

    @Suppress("OVERRIDE_BY_INLINE")
    override inline fun NDStructure.mapIndexed(
        transform: RealField.(index: IntArray, Double) -> Double,
    ): NDBuffer = NDBuffer(
        strides,
        buffer = RealBuffer(strides.linearSize) { offset ->
            RealField.transform(
                strides.index(offset),
                buffer.array[offset]
            )
        })

    @Suppress("OVERRIDE_BY_INLINE")
    override inline fun combine(
        a: NDStructure,
        b: NDStructure,
        transform: RealField.(Double, Double) -> Double,
    ): NDBuffer {
        val buffer = RealBuffer(strides.linearSize) { offset ->
            RealField.transform(a.buffer.array[offset], b.buffer.array[offset])
        }
        return NDBuffer(strides, buffer)
    }

    override fun power(arg: NDStructure, pow: Number): NDBuffer = arg.map { power(it, pow) }

    override fun exp(arg: NDStructure): NDBuffer = arg.map { exp(it) }

    override fun ln(arg: NDStructure): NDBuffer = arg.map { ln(it) }

    override fun sin(arg: NDStructure): NDBuffer = arg.map { sin(it) }
    override fun cos(arg: NDStructure): NDBuffer = arg.map { cos(it) }
    override fun tan(arg: NDStructure): NDBuffer = arg.map { tan(it) }
    override fun asin(arg: NDStructure): NDBuffer = arg.map { asin(it) }
    override fun acos(arg: NDStructure): NDBuffer = arg.map { acos(it) }
    override fun atan(arg: NDStructure): NDBuffer = arg.map { atan(it) }

    override fun sinh(arg: NDStructure): NDBuffer = arg.map { sinh(it) }
    override fun cosh(arg: NDStructure): NDBuffer = arg.map { cosh(it) }
    override fun tanh(arg: NDStructure): NDBuffer = arg.map { tanh(it) }
    override fun asinh(arg: NDStructure): NDBuffer = arg.map { asinh(it) }
    override fun acosh(arg: NDStructure): NDBuffer = arg.map { acosh(it) }
    override fun atanh(arg: NDStructure): NDBuffer = arg.map { atanh(it) }
}

public fun NDAlgebra.Companion.real(vararg shape: Int): RealNDField = RealNDField(shape)

/**
 * Produce a context for n-dimensional operations inside this real field
 */
public inline fun  RealField.nd(vararg shape: Int, action: RealNDField.() -> R): R {
    contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
    return RealNDField(shape).run(action)
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy