Refactor ND builders to suit new discoverability pattern

This commit is contained in:
Alexander Nozik 2021-09-19 20:48:36 +03:00
parent 6dc9e8847a
commit 49ec5d1554
23 changed files with 1130 additions and 75 deletions

View File

@ -46,8 +46,8 @@ internal class NDFieldBenchmark {
private companion object { private companion object {
private const val dim = 1000 private const val dim = 1000
private const val n = 100 private const val n = 100
private val autoField = AlgebraND.auto(DoubleField, dim, dim) private val autoField = DoubleField.autoNd(dim, dim)
private val specializedField = AlgebraND.real(dim, dim) private val specializedField = DoubleField.nd(dim, dim)
private val genericField = AlgebraND.field(DoubleField, Buffer.Companion::boxing, dim, dim) private val genericField = DoubleField.nd(Buffer.Companion::boxing, dim, dim)
} }
} }

View File

@ -10,10 +10,9 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import org.jetbrains.bio.viktor.F64Array import org.jetbrains.bio.viktor.F64Array
import space.kscience.kmath.nd.AlgebraND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.auto import space.kscience.kmath.nd.autoNd
import space.kscience.kmath.nd.real import space.kscience.kmath.nd.nd
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.viktor.ViktorNDField import space.kscience.kmath.viktor.ViktorNDField
@ -59,8 +58,8 @@ internal class ViktorBenchmark {
private const val n = 100 private const val n = 100
// automatically build context most suited for given type. // automatically build context most suited for given type.
private val autoField = AlgebraND.auto(DoubleField, dim, dim) private val autoField = DoubleField.autoNd(dim, dim)
private val realField = AlgebraND.real(dim, dim) private val realField = DoubleField.nd(dim, dim)
private val viktorField = ViktorNDField(dim, dim) private val viktorField = ViktorNDField(dim, dim)
} }
} }

View File

@ -10,9 +10,8 @@ import kotlinx.benchmark.Blackhole
import kotlinx.benchmark.Scope import kotlinx.benchmark.Scope
import kotlinx.benchmark.State import kotlinx.benchmark.State
import org.jetbrains.bio.viktor.F64Array import org.jetbrains.bio.viktor.F64Array
import space.kscience.kmath.nd.AlgebraND import space.kscience.kmath.nd.autoNd
import space.kscience.kmath.nd.auto import space.kscience.kmath.nd.nd
import space.kscience.kmath.nd.real
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.viktor.ViktorFieldND import space.kscience.kmath.viktor.ViktorFieldND
@ -51,8 +50,8 @@ internal class ViktorLogBenchmark {
private const val n = 100 private const val n = 100
// automatically build context most suited for given type. // automatically build context most suited for given type.
private val autoField = AlgebraND.auto(DoubleField, dim, dim) private val autoField = DoubleField.autoNd(dim, dim)
private val realNdField = AlgebraND.real(dim, dim) private val realNdField = DoubleField.nd(dim, dim)
private val viktorField = ViktorFieldND(intArrayOf(dim, dim)) private val viktorField = ViktorFieldND(intArrayOf(dim, dim))
} }
} }

1020
docs/diagrams/core.puml Normal file

File diff suppressed because it is too large Load Diff

View File

@ -9,12 +9,12 @@ import space.kscience.kmath.integration.gaussIntegrator
import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.integrate
import space.kscience.kmath.integration.value import space.kscience.kmath.integration.value
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.nd import space.kscience.kmath.nd.withNd
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
fun main(): Unit = DoubleField { fun main(): Unit = DoubleField {
nd(2, 2) { withNd(2, 2) {
//Produce a diagonal StructureND //Produce a diagonal StructureND
fun diagonal(v: Double) = produce { (i, j) -> fun diagonal(v: Double) = produce { (i, j) ->

View File

@ -6,18 +6,20 @@
package space.kscience.kmath.operations package space.kscience.kmath.operations
import space.kscience.kmath.complex.Complex import space.kscience.kmath.complex.Complex
import space.kscience.kmath.complex.complex import space.kscience.kmath.complex.ComplexField
import space.kscience.kmath.nd.AlgebraND import space.kscience.kmath.complex.withNd
import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.autoNd
fun main() { fun main() {
// 2d element // 2d element
val element = AlgebraND.complex(2, 2).produce { (i, j) -> val element = ComplexField.autoNd(2, 2).produce { (i, j) ->
Complex(i.toDouble() - j.toDouble(), i.toDouble() + j.toDouble()) Complex(i - j, i + j)
} }
println(element) println(element)
// 1d element operation // 1d element operation
val result = with(AlgebraND.complex(8)) { val result: StructureND<Complex> = ComplexField.withNd(8) {
val a = produce { (it) -> i * it - it.toDouble() } val a = produce { (it) -> i * it - it.toDouble() }
val b = 3 val b = 3
val c = Complex(1.0, 1.0) val c = Complex(1.0, 1.0)

View File

@ -9,10 +9,10 @@ package space.kscience.kmath.structures
import space.kscience.kmath.complex.* import space.kscience.kmath.complex.*
import space.kscience.kmath.linear.transpose import space.kscience.kmath.linear.transpose
import space.kscience.kmath.nd.AlgebraND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.as2D import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.real import space.kscience.kmath.nd.nd
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis
@ -20,8 +20,8 @@ fun main() {
val dim = 1000 val dim = 1000
val n = 1000 val n = 1000
val realField = AlgebraND.real(dim, dim) val realField = DoubleField.nd(dim, dim)
val complexField: ComplexFieldND = AlgebraND.complex(dim, dim) val complexField: ComplexFieldND = ComplexField.nd(dim, dim)
val realTime = measureTimeMillis { val realTime = measureTimeMillis {
realField { realField {
@ -49,7 +49,7 @@ fun main() {
fun complexExample() { fun complexExample() {
//Create a context for 2-d structure with complex values //Create a context for 2-d structure with complex values
ComplexField { ComplexField {
nd(4, 8) { withNd(4, 8) {
//a constant real-valued structure //a constant real-valued structure
val x = one * 2.5 val x = one * 2.5
operator fun Number.plus(other: Complex) = Complex(this.toDouble() + other.re, other.im) operator fun Number.plus(other: Complex) = Complex(this.toDouble() + other.re, other.im)

View File

@ -8,7 +8,9 @@ package space.kscience.kmath.structures
import kotlinx.coroutines.DelicateCoroutinesApi import kotlinx.coroutines.DelicateCoroutinesApi
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import org.nd4j.linalg.factory.Nd4j import org.nd4j.linalg.factory.Nd4j
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.autoNd
import space.kscience.kmath.nd.nd
import space.kscience.kmath.nd4j.Nd4jArrayField import space.kscience.kmath.nd4j.Nd4jArrayField
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
@ -31,17 +33,17 @@ fun main() {
val n = 1000 val n = 1000
// automatically build context most suited for given type. // automatically build context most suited for given type.
val autoField = AlgebraND.auto(DoubleField, dim, dim) val autoField = DoubleField.autoNd(dim, dim)
// specialized nd-field for Double. It works as generic Double field as well. // specialized nd-field for Double. It works as generic Double field as well.
val realField = AlgebraND.real(dim, dim) val realField = DoubleField.nd(dim, dim)
//A generic boxing field. It should be used for objects, not primitives. //A generic boxing field. It should be used for objects, not primitives.
val boxingField = AlgebraND.field(DoubleField, Buffer.Companion::boxing, dim, dim) val boxingField = DoubleField.nd(Buffer.Companion::boxing, dim, dim)
// Nd4j specialized field. // Nd4j specialized field.
val nd4jField = Nd4jArrayField.real(dim, dim) val nd4jField = Nd4jArrayField.real(dim, dim)
//viktor field //viktor field
val viktorField = ViktorNDField(dim, dim) val viktorField = ViktorNDField(dim, dim)
//parallel processing based on Java Streams //parallel processing based on Java Streams
val parallelField = AlgebraND.realWithStream(dim, dim) val parallelField = DoubleField.ndStreaming(dim, dim)
measureAndPrint("Boxing addition") { measureAndPrint("Boxing addition") {
boxingField { boxingField {

View File

@ -105,4 +105,4 @@ class StreamDoubleFieldND(override val shape: IntArray) : FieldND<Double, Double
override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) } override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) }
} }
fun AlgebraND.Companion.realWithStream(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(shape) fun DoubleField.ndStreaming(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(shape)

View File

@ -7,6 +7,8 @@ kotlin.code.style=official
kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.mpp.stability.nowarn=true kotlin.mpp.stability.nowarn=true
kotlin.native.enableDependencyPropagation=false kotlin.native.enableDependencyPropagation=false
kotlin.jupyter.add.scanner=false
org.gradle.configureondemand=true org.gradle.configureondemand=true
org.gradle.jvmargs=-XX:MaxMetaspaceSize=2G org.gradle.jvmargs=-XX:MaxMetaspaceSize=2G
org.gradle.parallel=true org.gradle.parallel=true

View File

@ -6,7 +6,6 @@
package space.kscience.kmath.complex package space.kscience.kmath.complex
import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.AlgebraND
import space.kscience.kmath.nd.BufferND import space.kscience.kmath.nd.BufferND
import space.kscience.kmath.nd.BufferedFieldND import space.kscience.kmath.nd.BufferedFieldND
import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.StructureND
@ -113,12 +112,12 @@ public inline fun BufferedFieldND<Complex, ComplexField>.produceInline(initializ
} }
public fun AlgebraND.Companion.complex(vararg shape: Int): ComplexFieldND = ComplexFieldND(shape) public fun ComplexField.nd(vararg shape: Int): ComplexFieldND = ComplexFieldND(shape)
/** /**
* Produce a context for n-dimensional operations inside this real field * Produce a context for n-dimensional operations inside this real field
*/ */
public inline fun <R> ComplexField.nd(vararg shape: Int, action: ComplexFieldND.() -> R): R { public inline fun <R> ComplexField.withNd(vararg shape: Int, action: ComplexFieldND.() -> R): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return ComplexFieldND(shape).action() return ComplexFieldND(shape).action()
} }

View File

@ -2,6 +2,7 @@ plugins {
kotlin("multiplatform") kotlin("multiplatform")
id("ru.mipt.npm.gradle.common") id("ru.mipt.npm.gradle.common")
id("ru.mipt.npm.gradle.native") id("ru.mipt.npm.gradle.native")
// id("com.xcporter.metaview") version "0.0.5"
} }
kotlin.sourceSets { kotlin.sourceSets {
@ -12,6 +13,12 @@ kotlin.sourceSets {
} }
} }
//generateUml {
// classTree {
//
// }
//}
readme { readme {
description = "Core classes, algebra definitions, basic linear algebra" description = "Core classes, algebra definitions, basic linear algebra"
maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT

View File

@ -6,7 +6,10 @@
package space.kscience.kmath.linear package space.kscience.kmath.linear
import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.BufferedRingND
import space.kscience.kmath.nd.as2D
import space.kscience.kmath.nd.nd
import space.kscience.kmath.nd.unwrap
import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.Ring
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Buffer
@ -23,7 +26,7 @@ public class BufferedLinearSpace<T : Any, out A : Ring<T>>(
private fun ndRing( private fun ndRing(
rows: Int, rows: Int,
cols: Int, cols: Int,
): BufferedRingND<T, A> = AlgebraND.ring(elementAlgebra, bufferFactory, rows, cols) ): BufferedRingND<T, A> = elementAlgebra.nd(bufferFactory, rows, cols)
override fun buildMatrix(rows: Int, columns: Int, initializer: A.(i: Int, j: Int) -> T): Matrix<T> = override fun buildMatrix(rows: Int, columns: Int, initializer: A.(i: Int, j: Int) -> T): Matrix<T> =
ndRing(rows, columns).produce { (i, j) -> elementAlgebra.initializer(i, j) }.as2D() ndRing(rows, columns).produce { (i, j) -> elementAlgebra.initializer(i, j) }.as2D()

View File

@ -5,11 +5,13 @@
package space.kscience.kmath.nd package space.kscience.kmath.nd
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.* import space.kscience.kmath.operations.*
import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Buffer
import space.kscience.kmath.structures.BufferFactory import space.kscience.kmath.structures.BufferFactory
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.jvm.JvmName
public interface BufferAlgebraND<T, out A : Algebra<T>> : AlgebraND<T, A> { public interface BufferAlgebraND<T, out A : Algebra<T>> : AlgebraND<T, A> {
public val strides: Strides public val strides: Strides
@ -85,58 +87,61 @@ public open class BufferedFieldND<T, out R : Field<T>>(
} }
// group factories // group factories
public fun <T, A : Ring<T>> AlgebraND.Companion.group( public fun <T, A : Group<T>> A.nd(
space: A,
bufferFactory: BufferFactory<T>, bufferFactory: BufferFactory<T>,
vararg shape: Int, vararg shape: Int,
): BufferedGroupND<T, A> = BufferedGroupND(shape, space, bufferFactory) ): BufferedGroupND<T, A> = BufferedGroupND(shape, this, bufferFactory)
public inline fun <T, A : Ring<T>, R> A.ndGroup( @JvmName("withNdGroup")
public inline fun <T, A : Group<T>, R> A.withNd(
noinline bufferFactory: BufferFactory<T>, noinline bufferFactory: BufferFactory<T>,
vararg shape: Int, vararg shape: Int,
action: BufferedGroupND<T, A>.() -> R, action: BufferedGroupND<T, A>.() -> R,
): R { ): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return AlgebraND.group(this, bufferFactory, *shape).run(action) return nd(bufferFactory, *shape).run(action)
} }
//ring factories //ring factories
public fun <T, A : Ring<T>> AlgebraND.Companion.ring( public fun <T, A : Ring<T>> A.nd(
ring: A,
bufferFactory: BufferFactory<T>, bufferFactory: BufferFactory<T>,
vararg shape: Int, vararg shape: Int,
): BufferedRingND<T, A> = BufferedRingND(shape, ring, bufferFactory) ): BufferedRingND<T, A> = BufferedRingND(shape, this, bufferFactory)
public inline fun <T, A : Ring<T>, R> A.ndRing( @JvmName("withNdRing")
public inline fun <T, A : Ring<T>, R> A.withNd(
noinline bufferFactory: BufferFactory<T>, noinline bufferFactory: BufferFactory<T>,
vararg shape: Int, vararg shape: Int,
action: BufferedRingND<T, A>.() -> R, action: BufferedRingND<T, A>.() -> R,
): R { ): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return AlgebraND.ring(this, bufferFactory, *shape).run(action) return nd(bufferFactory, *shape).run(action)
} }
//field factories //field factories
public fun <T, A : Field<T>> AlgebraND.Companion.field( public fun <T, A : Field<T>> A.nd(
field: A,
bufferFactory: BufferFactory<T>, bufferFactory: BufferFactory<T>,
vararg shape: Int, vararg shape: Int,
): BufferedFieldND<T, A> = BufferedFieldND(shape, field, bufferFactory) ): BufferedFieldND<T, A> = BufferedFieldND(shape, this, bufferFactory)
/**
* Create a [FieldND] for this [Field] inferring proper buffer factory from the type
*/
@UnstableKMathAPI
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public inline fun <reified T : Any, A : Field<T>> AlgebraND.Companion.auto( public inline fun <reified T : Any, A : Field<T>> A.autoNd(
field: A,
vararg shape: Int, vararg shape: Int,
): FieldND<T, A> = when (field) { ): FieldND<T, A> = when (this) {
DoubleField -> DoubleFieldND(shape) as FieldND<T, A> DoubleField -> DoubleFieldND(shape) as FieldND<T, A>
else -> BufferedFieldND(shape, field, Buffer.Companion::auto) else -> BufferedFieldND(shape, this, Buffer.Companion::auto)
} }
public inline fun <T, A : Field<T>, R> A.ndField( @JvmName("withNdField")
public inline fun <T, A : Field<T>, R> A.withNd(
noinline bufferFactory: BufferFactory<T>, noinline bufferFactory: BufferFactory<T>,
vararg shape: Int, vararg shape: Int,
action: BufferedFieldND<T, A>.() -> R, action: BufferedFieldND<T, A>.() -> R,
): R { ): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return AlgebraND.field(this, bufferFactory, *shape).run(action) return nd(bufferFactory, *shape).run(action)
} }

View File

@ -103,12 +103,12 @@ public class DoubleFieldND(
override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) } override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) }
} }
public fun AlgebraND.Companion.real(vararg shape: Int): DoubleFieldND = DoubleFieldND(shape) public fun DoubleField.nd(vararg shape: Int): DoubleFieldND = DoubleFieldND(shape)
/** /**
* Produce a context for n-dimensional operations inside this real field * Produce a context for n-dimensional operations inside this real field
*/ */
public inline fun <R> DoubleField.nd(vararg shape: Int, action: DoubleFieldND.() -> R): R { public inline fun <R> DoubleField.withNd(vararg shape: Int, action: DoubleFieldND.() -> R): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return DoubleFieldND(shape).run(action) return DoubleFieldND(shape).run(action)
} }

View File

@ -34,7 +34,7 @@ public class ShortRingND(
public inline fun BufferedRingND<Short, ShortRing>.produceInline(crossinline initializer: ShortRing.(Int) -> Short): BufferND<Short> = public inline fun BufferedRingND<Short, ShortRing>.produceInline(crossinline initializer: ShortRing.(Int) -> Short): BufferND<Short> =
BufferND(strides, ShortBuffer(ShortArray(strides.linearSize) { offset -> ShortRing.initializer(offset) })) BufferND(strides, ShortBuffer(ShortArray(strides.linearSize) { offset -> ShortRing.initializer(offset) }))
public inline fun <R> ShortRing.nd(vararg shape: Int, action: ShortRingND.() -> R): R { public inline fun <R> ShortRing.withNd(vararg shape: Int, action: ShortRingND.() -> R): R {
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
return ShortRingND(shape).run(action) return ShortRingND(shape).run(action)
} }

View File

@ -6,7 +6,6 @@
package space.kscience.kmath.operations package space.kscience.kmath.operations
import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.AlgebraND
import space.kscience.kmath.nd.BufferedRingND import space.kscience.kmath.nd.BufferedRingND
import space.kscience.kmath.operations.BigInt.Companion.BASE import space.kscience.kmath.operations.BigInt.Companion.BASE
import space.kscience.kmath.operations.BigInt.Companion.BASE_SIZE import space.kscience.kmath.operations.BigInt.Companion.BASE_SIZE
@ -533,5 +532,5 @@ public inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigIn
public inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): MutableBuffer<BigInt> = public inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): MutableBuffer<BigInt> =
boxing(size, initializer) boxing(size, initializer)
public fun AlgebraND.Companion.bigInt(vararg shape: Int): BufferedRingND<BigInt, BigIntField> = public fun BigIntField.nd(vararg shape: Int): BufferedRingND<BigInt, BigIntField> =
BufferedRingND(shape, BigIntField, Buffer.Companion::bigInt) BufferedRingND(shape, BigIntField, Buffer.Companion::bigInt)

View File

@ -5,9 +5,9 @@
package space.kscience.kmath.structures package space.kscience.kmath.structures
import space.kscience.kmath.nd.AlgebraND
import space.kscience.kmath.nd.get import space.kscience.kmath.nd.get
import space.kscience.kmath.nd.real import space.kscience.kmath.nd.nd
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import space.kscience.kmath.testutils.FieldVerifier import space.kscience.kmath.testutils.FieldVerifier
import kotlin.test.Test import kotlin.test.Test
@ -16,12 +16,12 @@ import kotlin.test.assertEquals
internal class NDFieldTest { internal class NDFieldTest {
@Test @Test
fun verify() { fun verify() {
(AlgebraND.real(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) } (DoubleField.nd(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) }
} }
@Test @Test
fun testStrides() { fun testStrides() {
val ndArray = AlgebraND.real(10, 10).produce { (it[0] + it[1]).toDouble() } val ndArray = DoubleField.nd(10, 10).produce { (it[0] + it[1]).toDouble() }
assertEquals(ndArray[5, 5], 10.0) assertEquals(ndArray[5, 5], 10.0)
} }
} }

View File

@ -7,7 +7,11 @@ package space.kscience.kmath.structures
import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.LinearSpace
import space.kscience.kmath.misc.PerformancePitfall import space.kscience.kmath.misc.PerformancePitfall
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.nd.combine
import space.kscience.kmath.nd.get
import space.kscience.kmath.nd.nd
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.Norm import space.kscience.kmath.operations.Norm
import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.invoke
import kotlin.math.abs import kotlin.math.abs
@ -17,7 +21,7 @@ import kotlin.test.assertEquals
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
class NumberNDFieldTest { class NumberNDFieldTest {
val algebra = AlgebraND.real(3, 3) val algebra = DoubleField.nd(3, 3)
val array1 = algebra.produce { (i, j) -> (i + j).toDouble() } val array1 = algebra.produce { (i, j) -> (i + j).toDouble() }
val array2 = algebra.produce { (i, j) -> (i - j).toDouble() } val array2 = algebra.produce { (i, j) -> (i - j).toDouble() }
@ -83,7 +87,7 @@ class NumberNDFieldTest {
@Test @Test
fun testInternalContext() { fun testInternalContext() {
algebra { algebra {
(AlgebraND.real(*array1.shape)) { with(L2Norm) { 1 + norm(array1) + exp(array2) } } (DoubleField.nd(*array1.shape)) { with(L2Norm) { 1 + norm(array1) + exp(array2) } }
} }
} }
} }

View File

@ -9,6 +9,7 @@ import space.kscience.kmath.domains.Domain
import space.kscience.kmath.domains.HyperSquareDomain import space.kscience.kmath.domains.HyperSquareDomain
import space.kscience.kmath.misc.UnstableKMathAPI import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.structures.* import space.kscience.kmath.structures.*
import kotlin.math.floor import kotlin.math.floor
@ -28,7 +29,7 @@ public class DoubleHistogramSpace(
public val dimension: Int get() = lower.size public val dimension: Int get() = lower.size
private val shape = IntArray(binNums.size) { binNums[it] + 2 } private val shape = IntArray(binNums.size) { binNums[it] + 2 }
override val histogramValueSpace: DoubleFieldND = AlgebraND.real(*shape) override val histogramValueSpace: DoubleFieldND = DoubleField.nd(*shape)
override val strides: Strides get() = histogramValueSpace.strides override val strides: Strides get() = histogramValueSpace.strides
private val binSize = DoubleBuffer(dimension) { (upper[it] - lower[it]) / binNums[it] } private val binSize = DoubleBuffer(dimension) { (upper[it] - lower[it]) / binNums[it] }

View File

@ -11,7 +11,6 @@ import kotlinx.html.stream.createHTML
import kotlinx.html.unsafe import kotlinx.html.unsafe
import org.jetbrains.kotlinx.jupyter.api.DisplayResult import org.jetbrains.kotlinx.jupyter.api.DisplayResult
import org.jetbrains.kotlinx.jupyter.api.HTML import org.jetbrains.kotlinx.jupyter.api.HTML
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
import space.kscience.kmath.ast.rendering.FeaturedMathRendererWithPostProcess import space.kscience.kmath.ast.rendering.FeaturedMathRendererWithPostProcess
import space.kscience.kmath.ast.rendering.MathMLSyntaxRenderer import space.kscience.kmath.ast.rendering.MathMLSyntaxRenderer

View File

@ -16,6 +16,14 @@ import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.kmath.structures.DoubleL2Norm import space.kscience.kmath.structures.DoubleL2Norm
public class QowRuns(public val runs: Int) : OptimizationFeature {
init {
require(runs >= 1) { "Number of runs must be more than zero" }
}
override fun toString(): String = "QowRuns(runs=$runs)"
}
/** /**
* An optimizer based onf Fyodor Tkachev's quasi-optimal weights method. * An optimizer based onf Fyodor Tkachev's quasi-optimal weights method.
@ -56,7 +64,7 @@ public object QowOptimizer : Optimizer<Double, XYFit> {
val prior: DifferentiableExpression<Double>? get() = problem.getFeature<OptimizationPrior<Double>>() val prior: DifferentiableExpression<Double>? get() = problem.getFeature<OptimizationPrior<Double>>()
override fun toString(): String = parameters.toString() override fun toString(): String = parameters.toString()
} }
/** /**
@ -242,9 +250,15 @@ public object QowOptimizer : Optimizer<Double, XYFit> {
} }
override suspend fun optimize(problem: XYFit): XYFit { override suspend fun optimize(problem: XYFit): XYFit {
val qowSteps = 2 val qowRuns = problem.getFeature<QowRuns>()?.runs ?: 2
val initialWeight = QoWeight(problem, problem.startPoint)
val res = initialWeight.newtonianRun()
var qow = QoWeight(problem, problem.startPoint)
var res = qow.newtonianRun()
repeat(qowRuns - 1) {
qow = QoWeight(problem, res.parameters)
res = qow.newtonianRun()
}
return res.problem.withFeature(OptimizationResult(res.parameters)) return res.problem.withFeature(OptimizationResult(res.parameters))
} }
} }

View File

@ -5,11 +5,11 @@ pluginManagement {
gradlePluginPortal() gradlePluginPortal()
} }
val kotlinVersion = "1.5.21" val kotlinVersion = "1.5.30"
plugins { plugins {
id("org.jetbrains.kotlinx.benchmark") version "0.3.1" id("org.jetbrains.kotlinx.benchmark") version "0.3.1"
id("ru.mipt.npm.gradle.project") version "0.10.2" id("ru.mipt.npm.gradle.project") version "0.10.3"
kotlin("multiplatform") version kotlinVersion kotlin("multiplatform") version kotlinVersion
kotlin("plugin.allopen") version kotlinVersion kotlin("plugin.allopen") version kotlinVersion
} }