forked from kscience/kmath
Shapeless ND and Buffer algebras
This commit is contained in:
parent
688382eed6
commit
4513b06e87
@ -1,6 +0,0 @@
|
|||||||
<component name="CopyrightManager">
|
|
||||||
<copyright>
|
|
||||||
<option name="notice" value="Copyright 2018-2021 KMath contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file." />
|
|
||||||
<option name="myName" value="kmath" />
|
|
||||||
</copyright>
|
|
||||||
</component>
|
|
@ -1,21 +0,0 @@
|
|||||||
<component name="CopyrightManager">
|
|
||||||
<settings default="kmath">
|
|
||||||
<module2copyright>
|
|
||||||
<element module="Apply copyright" copyright="kmath" />
|
|
||||||
</module2copyright>
|
|
||||||
<LanguageOptions name="Groovy">
|
|
||||||
<option name="fileTypeOverride" value="1" />
|
|
||||||
</LanguageOptions>
|
|
||||||
<LanguageOptions name="HTML">
|
|
||||||
<option name="fileTypeOverride" value="1" />
|
|
||||||
<option name="prefixLines" value="false" />
|
|
||||||
</LanguageOptions>
|
|
||||||
<LanguageOptions name="Properties">
|
|
||||||
<option name="fileTypeOverride" value="1" />
|
|
||||||
</LanguageOptions>
|
|
||||||
<LanguageOptions name="XML">
|
|
||||||
<option name="fileTypeOverride" value="1" />
|
|
||||||
<option name="prefixLines" value="false" />
|
|
||||||
</LanguageOptions>
|
|
||||||
</settings>
|
|
||||||
</component>
|
|
@ -1,4 +0,0 @@
|
|||||||
<component name="DependencyValidationManager">
|
|
||||||
<scope name="Apply copyright"
|
|
||||||
pattern="!file[*]:*//testData//*&&!file[*]:testData//*&&!file[*]:*.gradle.kts&&!file[*]:*.gradle&&!file[group:kotlin-ultimate]:*/&&!file[kotlin.libraries]:stdlib/api//*"/>
|
|
||||||
</component>
|
|
@ -203,7 +203,9 @@ public interface RingND<T, out A : Ring<T>> : Ring<StructureND<T>>, RingOpsND<T,
|
|||||||
* @param T the type of the element contained in ND structure.
|
* @param T the type of the element contained in ND structure.
|
||||||
* @param A the type field over structure elements.
|
* @param A the type field over structure elements.
|
||||||
*/
|
*/
|
||||||
public interface FieldOpsND<T, out A : Field<T>> : FieldOps<StructureND<T>>, RingOpsND<T, A>,
|
public interface FieldOpsND<T, out A : Field<T>> :
|
||||||
|
FieldOps<StructureND<T>>,
|
||||||
|
RingOpsND<T, A>,
|
||||||
ScaleOperations<StructureND<T>> {
|
ScaleOperations<StructureND<T>> {
|
||||||
/**
|
/**
|
||||||
* Element-wise division.
|
* Element-wise division.
|
||||||
|
@ -150,7 +150,7 @@ public interface ScaleOperations<T> : Algebra<T> {
|
|||||||
* TODO to be removed and replaced by extensions after multiple receivers are there
|
* TODO to be removed and replaced by extensions after multiple receivers are there
|
||||||
*/
|
*/
|
||||||
@UnstableKMathAPI
|
@UnstableKMathAPI
|
||||||
public interface NumbersAddOps<T> : Ring<T>, NumericAlgebra<T> {
|
public interface NumbersAddOps<T> : RingOps<T>, NumericAlgebra<T> {
|
||||||
/**
|
/**
|
||||||
* Addition of element and scalar.
|
* Addition of element and scalar.
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018-2021 KMath contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package space.kscience.kmath.viktor
|
||||||
|
|
||||||
|
import org.jetbrains.bio.viktor.F64Array
|
||||||
|
import space.kscience.kmath.misc.UnstableKMathAPI
|
||||||
|
import space.kscience.kmath.nd.*
|
||||||
|
import space.kscience.kmath.operations.DoubleField
|
||||||
|
import space.kscience.kmath.operations.ExtendedFieldOps
|
||||||
|
import space.kscience.kmath.operations.NumbersAddOps
|
||||||
|
|
||||||
|
@OptIn(UnstableKMathAPI::class)
|
||||||
|
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||||
|
public open class ViktorFieldOpsND :
|
||||||
|
FieldOpsND<Double, DoubleField>,
|
||||||
|
ExtendedFieldOps<StructureND<Double>> {
|
||||||
|
|
||||||
|
public val StructureND<Double>.f64Buffer: F64Array
|
||||||
|
get() = when (this) {
|
||||||
|
is ViktorStructureND -> this.f64Buffer
|
||||||
|
else -> produce(shape) { this@f64Buffer[it] }.f64Buffer
|
||||||
|
}
|
||||||
|
|
||||||
|
override val elementAlgebra: DoubleField get() = DoubleField
|
||||||
|
|
||||||
|
override fun produce(shape: IntArray, initializer: DoubleField.(IntArray) -> Double): ViktorStructureND =
|
||||||
|
F64Array(*shape).apply {
|
||||||
|
DefaultStrides(shape).indices().forEach { index ->
|
||||||
|
set(value = DoubleField.initializer(index), indices = index)
|
||||||
|
}
|
||||||
|
}.asStructure()
|
||||||
|
|
||||||
|
override fun StructureND<Double>.unaryMinus(): StructureND<Double> = -1 * this
|
||||||
|
|
||||||
|
override fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): ViktorStructureND =
|
||||||
|
F64Array(*shape).apply {
|
||||||
|
DefaultStrides(shape).indices().forEach { index ->
|
||||||
|
set(value = DoubleField.transform(this@map[index]), indices = index)
|
||||||
|
}
|
||||||
|
}.asStructure()
|
||||||
|
|
||||||
|
override fun StructureND<Double>.mapIndexed(
|
||||||
|
transform: DoubleField.(index: IntArray, Double) -> Double,
|
||||||
|
): ViktorStructureND = F64Array(*shape).apply {
|
||||||
|
DefaultStrides(shape).indices().forEach { index ->
|
||||||
|
set(value = DoubleField.transform(index, this@mapIndexed[index]), indices = index)
|
||||||
|
}
|
||||||
|
}.asStructure()
|
||||||
|
|
||||||
|
override fun zip(
|
||||||
|
left: StructureND<Double>,
|
||||||
|
right: StructureND<Double>,
|
||||||
|
transform: DoubleField.(Double, Double) -> Double,
|
||||||
|
): ViktorStructureND {
|
||||||
|
require(left.shape.contentEquals(right.shape))
|
||||||
|
return F64Array(*left.shape).apply {
|
||||||
|
DefaultStrides(left.shape).indices().forEach { index ->
|
||||||
|
set(value = DoubleField.transform(left[index], right[index]), indices = index)
|
||||||
|
}
|
||||||
|
}.asStructure()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun add(left: StructureND<Double>, right: StructureND<Double>): ViktorStructureND =
|
||||||
|
(left.f64Buffer + right.f64Buffer).asStructure()
|
||||||
|
|
||||||
|
override fun scale(a: StructureND<Double>, value: Double): ViktorStructureND =
|
||||||
|
(a.f64Buffer * value).asStructure()
|
||||||
|
|
||||||
|
override fun StructureND<Double>.plus(other: StructureND<Double>): ViktorStructureND =
|
||||||
|
(f64Buffer + other.f64Buffer).asStructure()
|
||||||
|
|
||||||
|
override fun StructureND<Double>.minus(other: StructureND<Double>): ViktorStructureND =
|
||||||
|
(f64Buffer - other.f64Buffer).asStructure()
|
||||||
|
|
||||||
|
override fun StructureND<Double>.times(k: Number): ViktorStructureND =
|
||||||
|
(f64Buffer * k.toDouble()).asStructure()
|
||||||
|
|
||||||
|
override fun StructureND<Double>.plus(arg: Double): ViktorStructureND =
|
||||||
|
(f64Buffer.plus(arg)).asStructure()
|
||||||
|
|
||||||
|
override fun sin(arg: StructureND<Double>): ViktorStructureND = arg.map { sin(it) }
|
||||||
|
override fun cos(arg: StructureND<Double>): ViktorStructureND = arg.map { cos(it) }
|
||||||
|
override fun tan(arg: StructureND<Double>): ViktorStructureND = arg.map { tan(it) }
|
||||||
|
override fun asin(arg: StructureND<Double>): ViktorStructureND = arg.map { asin(it) }
|
||||||
|
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()
|
||||||
|
|
||||||
|
override fun sinh(arg: StructureND<Double>): ViktorStructureND = arg.map { sinh(it) }
|
||||||
|
|
||||||
|
override fun cosh(arg: StructureND<Double>): ViktorStructureND = arg.map { cosh(it) }
|
||||||
|
|
||||||
|
override fun asinh(arg: StructureND<Double>): ViktorStructureND = arg.map { asinh(it) }
|
||||||
|
|
||||||
|
override fun acosh(arg: StructureND<Double>): ViktorStructureND = arg.map { acosh(it) }
|
||||||
|
|
||||||
|
override fun atanh(arg: StructureND<Double>): ViktorStructureND = arg.map { atanh(it) }
|
||||||
|
|
||||||
|
public companion object : ViktorFieldOpsND()
|
||||||
|
}
|
||||||
|
|
||||||
|
public val DoubleField.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND
|
||||||
|
|
||||||
|
public open class ViktorFieldND(
|
||||||
|
override val shape: Shape
|
||||||
|
) : ViktorFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>> {
|
||||||
|
override val zero: ViktorStructureND by lazy { F64Array.full(init = 0.0, shape = shape).asStructure() }
|
||||||
|
override val one: ViktorStructureND by lazy { F64Array.full(init = 1.0, shape = shape).asStructure() }
|
||||||
|
|
||||||
|
override fun number(value: Number): ViktorStructureND =
|
||||||
|
F64Array.full(init = value.toDouble(), shape = shape).asStructure()
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun DoubleField.viktorAlgebra(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)
|
||||||
|
|
||||||
|
public fun ViktorFieldND(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)
|
@ -7,12 +7,8 @@ package space.kscience.kmath.viktor
|
|||||||
|
|
||||||
import org.jetbrains.bio.viktor.F64Array
|
import org.jetbrains.bio.viktor.F64Array
|
||||||
import space.kscience.kmath.misc.PerformancePitfall
|
import space.kscience.kmath.misc.PerformancePitfall
|
||||||
import space.kscience.kmath.misc.UnstableKMathAPI
|
import space.kscience.kmath.nd.DefaultStrides
|
||||||
import space.kscience.kmath.nd.*
|
import space.kscience.kmath.nd.MutableStructureND
|
||||||
import space.kscience.kmath.operations.DoubleField
|
|
||||||
import space.kscience.kmath.operations.ExtendedField
|
|
||||||
import space.kscience.kmath.operations.NumbersAddOps
|
|
||||||
import space.kscience.kmath.operations.ScaleOperations
|
|
||||||
|
|
||||||
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
||||||
public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructureND<Double> {
|
public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructureND<Double> {
|
||||||
@ -31,96 +27,4 @@ public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructur
|
|||||||
|
|
||||||
public fun F64Array.asStructure(): ViktorStructureND = ViktorStructureND(this)
|
public fun F64Array.asStructure(): ViktorStructureND = ViktorStructureND(this)
|
||||||
|
|
||||||
@OptIn(UnstableKMathAPI::class)
|
|
||||||
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
|
|
||||||
public class ViktorFieldND(override val shape: IntArray) : FieldND<Double, DoubleField>,
|
|
||||||
NumbersAddOps<StructureND<Double>>, ExtendedField<StructureND<Double>>,
|
|
||||||
ScaleOperations<StructureND<Double>> {
|
|
||||||
|
|
||||||
public val StructureND<Double>.f64Buffer: F64Array
|
|
||||||
get() = when {
|
|
||||||
!shape.contentEquals(this@ViktorFieldND.shape) -> throw ShapeMismatchException(
|
|
||||||
this@ViktorFieldND.shape,
|
|
||||||
shape
|
|
||||||
)
|
|
||||||
this is ViktorStructureND && this.f64Buffer.shape.contentEquals(this@ViktorFieldND.shape) -> this.f64Buffer
|
|
||||||
else -> produce(shape) { this@f64Buffer[it] }.f64Buffer
|
|
||||||
}
|
|
||||||
|
|
||||||
override val zero: ViktorStructureND by lazy { F64Array.full(init = 0.0, shape = shape).asStructure() }
|
|
||||||
override val one: ViktorStructureND by lazy { F64Array.full(init = 1.0, shape = shape).asStructure() }
|
|
||||||
|
|
||||||
private val strides: Strides = DefaultStrides(shape)
|
|
||||||
|
|
||||||
override val elementAlgebra: DoubleField get() = DoubleField
|
|
||||||
|
|
||||||
override fun produce(shape: IntArray, initializer: DoubleField.(IntArray) -> Double): ViktorStructureND =
|
|
||||||
F64Array(*shape).apply {
|
|
||||||
this@ViktorFieldND.strides.indices().forEach { index ->
|
|
||||||
set(value = DoubleField.initializer(index), indices = index)
|
|
||||||
}
|
|
||||||
}.asStructure()
|
|
||||||
|
|
||||||
override fun StructureND<Double>.unaryMinus(): StructureND<Double> = -1 * this
|
|
||||||
|
|
||||||
override fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): ViktorStructureND =
|
|
||||||
F64Array(*this@ViktorFieldND.shape).apply {
|
|
||||||
this@ViktorFieldND.strides.indices().forEach { index ->
|
|
||||||
set(value = DoubleField.transform(this@map[index]), indices = index)
|
|
||||||
}
|
|
||||||
}.asStructure()
|
|
||||||
|
|
||||||
override fun StructureND<Double>.mapIndexed(
|
|
||||||
transform: DoubleField.(index: IntArray, Double) -> Double,
|
|
||||||
): ViktorStructureND = F64Array(*this@ViktorFieldND.shape).apply {
|
|
||||||
this@ViktorFieldND.strides.indices().forEach { index ->
|
|
||||||
set(value = DoubleField.transform(index, this@mapIndexed[index]), indices = index)
|
|
||||||
}
|
|
||||||
}.asStructure()
|
|
||||||
|
|
||||||
override fun zip(
|
|
||||||
left: StructureND<Double>,
|
|
||||||
right: StructureND<Double>,
|
|
||||||
transform: DoubleField.(Double, Double) -> Double,
|
|
||||||
): ViktorStructureND = F64Array(*shape).apply {
|
|
||||||
this@ViktorFieldND.strides.indices().forEach { index ->
|
|
||||||
set(value = DoubleField.transform(left[index], right[index]), indices = index)
|
|
||||||
}
|
|
||||||
}.asStructure()
|
|
||||||
|
|
||||||
override fun add(left: StructureND<Double>, right: StructureND<Double>): ViktorStructureND =
|
|
||||||
(left.f64Buffer + right.f64Buffer).asStructure()
|
|
||||||
|
|
||||||
override fun scale(a: StructureND<Double>, value: Double): ViktorStructureND =
|
|
||||||
(a.f64Buffer * value).asStructure()
|
|
||||||
|
|
||||||
override inline fun StructureND<Double>.plus(other: StructureND<Double>): ViktorStructureND =
|
|
||||||
(f64Buffer + other.f64Buffer).asStructure()
|
|
||||||
|
|
||||||
override inline fun StructureND<Double>.minus(other: StructureND<Double>): ViktorStructureND =
|
|
||||||
(f64Buffer - other.f64Buffer).asStructure()
|
|
||||||
|
|
||||||
override inline fun StructureND<Double>.times(k: Number): ViktorStructureND =
|
|
||||||
(f64Buffer * k.toDouble()).asStructure()
|
|
||||||
|
|
||||||
override inline fun StructureND<Double>.plus(arg: Double): ViktorStructureND =
|
|
||||||
(f64Buffer.plus(arg)).asStructure()
|
|
||||||
|
|
||||||
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) }
|
|
||||||
override fun cos(arg: StructureND<Double>): ViktorStructureND = arg.map { cos(it) }
|
|
||||||
override fun tan(arg: StructureND<Double>): ViktorStructureND = arg.map { tan(it) }
|
|
||||||
override fun asin(arg: StructureND<Double>): ViktorStructureND = arg.map { asin(it) }
|
|
||||||
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 fun ViktorFieldND(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)
|
|
||||||
|
Loading…
Reference in New Issue
Block a user