Merge to update docs and contributions #504

Merged
altavir merged 199 commits from dev into master 2022-10-03 20:58:00 +03:00
27 changed files with 200 additions and 73 deletions
Showing only changes of commit 569e01fce1 - Show all commits

View File

@ -11,7 +11,7 @@ allprojects {
} }
group = "space.kscience" group = "space.kscience"
version = "0.3.1" version = "0.3.1-dev-1"
} }
subprojects { subprojects {

View File

@ -1,8 +1,8 @@
plugins { plugins {
kotlin("jvm") version "1.7.0-RC" kotlin("jvm") version "1.7.0"
`kotlin-dsl` `kotlin-dsl`
`version-catalog` `version-catalog`
alias(miptNpmLibs.plugins.kotlin.plugin.serialization) alias(npmlibs.plugins.kotlin.plugin.serialization)
} }
java.targetCompatibility = JavaVersion.VERSION_11 java.targetCompatibility = JavaVersion.VERSION_11
@ -14,17 +14,18 @@ repositories {
gradlePluginPortal() gradlePluginPortal()
} }
val toolsVersion: String by extra val toolsVersion = npmlibs.versions.tools.get()
val kotlinVersion = miptNpmLibs.versions.kotlin.asProvider().get() val kotlinVersion = npmlibs.versions.kotlin.asProvider().get()
val benchmarksVersion = miptNpmLibs.versions.kotlinx.benchmark.get() val benchmarksVersion = npmlibs.versions.kotlinx.benchmark.get()
dependencies { dependencies {
api("ru.mipt.npm:gradle-tools:$toolsVersion") api("ru.mipt.npm:gradle-tools:$toolsVersion")
api(npmlibs.atomicfu.gradle)
//plugins form benchmarks //plugins form benchmarks
api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:$benchmarksVersion") api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:$benchmarksVersion")
api("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion") api("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
//to be used inside build-script only //to be used inside build-script only
implementation(miptNpmLibs.kotlinx.serialization.json) implementation(npmlibs.kotlinx.serialization.json)
} }
kotlin.sourceSets.all { kotlin.sourceSets.all {

View File

@ -1,7 +0,0 @@
#
# 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/LICENSE.txt file.
#
kotlin.code.style=official
toolsVersion=0.11.5-kotlin-1.7.0-RC

View File

@ -6,7 +6,17 @@
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
dependencyResolutionManagement { dependencyResolutionManagement {
val toolsVersion: String by extra val projectProperties = java.util.Properties()
file("../gradle.properties").inputStream().use {
projectProperties.load(it)
}
projectProperties.forEach { key, value ->
extra.set(key.toString(), value)
}
val toolsVersion: String = projectProperties["toolsVersion"].toString()
repositories { repositories {
mavenLocal() mavenLocal()
@ -16,7 +26,7 @@ dependencyResolutionManagement {
} }
versionCatalogs { versionCatalogs {
create("miptNpmLibs") { create("npmlibs") {
from("ru.mipt.npm:version-catalog:$toolsVersion") from("ru.mipt.npm:version-catalog:$toolsVersion")
} }
} }

View File

@ -319,7 +319,9 @@ public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra},
} }
else -> null else -> null
}?.let(type::cast) }?.let{
type.cast(it)
}
} }
/** /**

View File

@ -6,7 +6,10 @@ kotlin.code.style=official
kotlin.jupyter.add.scanner=false kotlin.jupyter.add.scanner=false
kotlin.mpp.stability.nowarn=true kotlin.mpp.stability.nowarn=true
kotlin.native.ignoreDisabledTargets=true kotlin.native.ignoreDisabledTargets=true
#kotlin.incremental.js.ir=true //kotlin.incremental.js.ir=true
org.gradle.configureondemand=true org.gradle.configureondemand=true
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.jvmargs=-Xmx4096m
toolsVersion=0.11.6-kotlin-1.7.0

View File

@ -57,7 +57,7 @@ tasks.dokkaHtml {
if (System.getProperty("space.kscience.kmath.ast.dump.generated.classes") == "1") if (System.getProperty("space.kscience.kmath.ast.dump.generated.classes") == "1")
tasks.jvmTest { tasks.jvmTest {
jvmArgs = (jvmArgs ?: emptyList()) + listOf("-Dspace.kscience.kmath.ast.dump.generated.classes=1") jvmArgs("-Dspace.kscience.kmath.ast.dump.generated.classes=1")
} }
readme { readme {

View File

@ -1,8 +1,6 @@
plugins { plugins {
kotlin("multiplatform") id("ru.mipt.npm.gradle.mpp")
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 {

View File

@ -10,25 +10,6 @@ import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.* import space.kscience.kmath.operations.*
import kotlin.reflect.KClass import kotlin.reflect.KClass
/**
* An exception is thrown when the expected and actual shape of NDArray differ.
*
* @property expected the expected shape.
* @property actual the actual shape.
*/
public class ShapeMismatchException(public val expected: IntArray, public val actual: IntArray) :
RuntimeException("Shape ${actual.contentToString()} doesn't fit in expected shape ${expected.contentToString()}.")
public typealias Shape = IntArray
public fun Shape(shapeFirst: Int, vararg shapeRest: Int): Shape = intArrayOf(shapeFirst, *shapeRest)
public interface WithShape {
public val shape: Shape
public val indices: ShapeIndexer get() = DefaultStrides(shape)
}
/** /**
* The base interface for all ND-algebra implementations. * The base interface for all ND-algebra implementations.
* *

View File

@ -47,7 +47,7 @@ public interface BufferAlgebraND<T, out A : Algebra<T>> : AlgebraND<T, A> {
zipInline(left.toBufferND(), right.toBufferND(), transform) zipInline(left.toBufferND(), right.toBufferND(), transform)
public companion object { public companion object {
public val defaultIndexerBuilder: (IntArray) -> ShapeIndexer = DefaultStrides.Companion::invoke public val defaultIndexerBuilder: (IntArray) -> ShapeIndexer = ::Strides
} }
} }

View File

@ -0,0 +1,35 @@
/*
* 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/LICENSE.txt file.
*/
package space.kscience.kmath.nd
/**
* An exception is thrown when the expected and actual shape of NDArray differ.
*
* @property expected the expected shape.
* @property actual the actual shape.
*/
public class ShapeMismatchException(public val expected: IntArray, public val actual: IntArray) :
RuntimeException("Shape ${actual.contentToString()} doesn't fit in expected shape ${expected.contentToString()}.")
public class IndexOutOfShapeException(public val shape: Shape, public val index: IntArray) :
RuntimeException("Index ${index.contentToString()} is out of shape ${shape.contentToString()}")
public typealias Shape = IntArray
public fun Shape(shapeFirst: Int, vararg shapeRest: Int): Shape = intArrayOf(shapeFirst, *shapeRest)
public interface WithShape {
public val shape: Shape
public val indices: ShapeIndexer get() = DefaultStrides(shape)
}
internal fun requireIndexInShape(index: IntArray, shape: Shape) {
if (index.size != shape.size) throw IndexOutOfShapeException(index, shape)
shape.forEachIndexed { axis, axisShape ->
if (index[axis] !in 0 until axisShape) throw IndexOutOfShapeException(index, shape)
}
}

View File

@ -10,7 +10,7 @@ import kotlin.native.concurrent.ThreadLocal
/** /**
* A converter from linear index to multivariate index * A converter from linear index to multivariate index
*/ */
public interface ShapeIndexer: Iterable<IntArray>{ public interface ShapeIndexer : Iterable<IntArray> {
public val shape: Shape public val shape: Shape
/** /**
@ -44,7 +44,7 @@ public interface ShapeIndexer: Iterable<IntArray>{
/** /**
* Linear transformation of indexes * Linear transformation of indexes
*/ */
public abstract class Strides: ShapeIndexer { public abstract class Strides : ShapeIndexer {
/** /**
* Array strides * Array strides
*/ */
@ -66,7 +66,7 @@ public abstract class Strides: ShapeIndexer {
/** /**
* Simple implementation of [Strides]. * Simple implementation of [Strides].
*/ */
public class DefaultStrides private constructor(override val shape: IntArray) : Strides() { public class DefaultStrides(override val shape: IntArray) : Strides() {
override val linearSize: Int get() = strides[shape.size] override val linearSize: Int get() = strides[shape.size]
/** /**
@ -112,10 +112,16 @@ public class DefaultStrides private constructor(override val shape: IntArray) :
/** /**
* Cached builder for default strides * Cached builder for default strides
*/ */
@Deprecated("Replace by Strides(shape)")
public operator fun invoke(shape: IntArray): Strides = public operator fun invoke(shape: IntArray): Strides =
defaultStridesCache.getOrPut(shape) { DefaultStrides(shape) } defaultStridesCache.getOrPut(shape) { DefaultStrides(shape) }
} }
} }
@ThreadLocal @ThreadLocal
private val defaultStridesCache = HashMap<IntArray, Strides>() private val defaultStridesCache = HashMap<IntArray, Strides>()
/**
* Cached builder for default strides
*/
public fun Strides(shape: IntArray): Strides = defaultStridesCache.getOrPut(shape) { DefaultStrides(shape) }

View File

@ -101,8 +101,8 @@ public interface StructureND<out T> : Featured<StructureFeature>, WithShape {
val bufferRepr: String = when (structure.shape.size) { val bufferRepr: String = when (structure.shape.size) {
1 -> (0 until structure.shape[0]).map { structure[it] } 1 -> (0 until structure.shape[0]).map { structure[it] }
.joinToString(prefix = "[", postfix = "]", separator = ", ") .joinToString(prefix = "[", postfix = "]", separator = ", ")
2 -> (0 until structure.shape[0]).joinToString(prefix = "[", postfix = "]", separator = ", ") { i -> 2 -> (0 until structure.shape[0]).joinToString(prefix = "[\n", postfix = "\n]", separator = ",\n") { i ->
(0 until structure.shape[1]).joinToString(prefix = "[", postfix = "]", separator = ", ") { j -> (0 until structure.shape[1]).joinToString(prefix = " [", postfix = "]", separator = ", ") { j ->
structure[i, j].toString() structure[i, j].toString()
} }
} }

View File

@ -5,12 +5,26 @@
package space.kscience.kmath.nd package space.kscience.kmath.nd
import space.kscience.kmath.misc.UnstableKMathAPI
public open class VirtualStructureND<T>( public open class VirtualStructureND<T>(
override val shape: Shape, override val shape: Shape,
public val producer: (IntArray) -> T, public val producer: (IntArray) -> T,
) : StructureND<T> { ) : StructureND<T> {
override fun get(index: IntArray): T { override fun get(index: IntArray): T {
require(check that index is in the shape boundaries) requireIndexInShape(index, shape)
return producer(index) return producer(index)
} }
} }
@UnstableKMathAPI
public class VirtualDoubleStructureND(
shape: Shape,
producer: (IntArray) -> Double,
) : VirtualStructureND<Double>(shape, producer)
@UnstableKMathAPI
public class VirtualIntStructureND(
shape: Shape,
producer: (IntArray) -> Int,
) : VirtualStructureND<Int>(shape, producer)

View File

@ -0,0 +1,32 @@
/*
* 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/LICENSE.txt file.
*/
package space.kscience.kmath.nd
public fun <T> StructureND<T>.roll(axis: Int, step: Int = 1): StructureND<T> {
require(axis in shape.indices) { "Axis $axis is outside of shape dimensions: [0, ${shape.size})" }
return VirtualStructureND(shape) { index ->
val newIndex: IntArray = IntArray(index.size) { indexAxis ->
if (indexAxis == axis) {
(index[indexAxis] + step).mod(shape[indexAxis])
} else {
index[indexAxis]
}
}
get(newIndex)
}
}
public fun <T> StructureND<T>.roll(pair: Pair<Int, Int>, vararg others: Pair<Int, Int>): StructureND<T> {
val axisMap: Map<Int, Int> = mapOf(pair, *others)
require(axisMap.keys.all { it in shape.indices }) { "Some of axes ${axisMap.keys} is outside of shape dimensions: [0, ${shape.size})" }
return VirtualStructureND(shape) { index ->
val newIndex: IntArray = IntArray(index.size) { indexAxis ->
val offset = axisMap[indexAxis] ?: 0
(index[indexAxis] + offset).mod(shape[indexAxis])
}
get(newIndex)
}
}

View File

@ -0,0 +1,28 @@
/*
* 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/LICENSE.txt file.
*/
package space.kscience.kmath.nd
import space.kscience.kmath.operations.DoubleField
import kotlin.test.Test
import kotlin.test.assertEquals
class NdOperationsTest {
@Test
fun roll() {
val structure = DoubleField.ndAlgebra.structureND(5, 5) { index ->
index.sumOf { it.toDouble() }
}
println(StructureND.toString(structure))
val rolled = structure.roll(0,-1)
println(StructureND.toString(rolled))
assertEquals(4.0, rolled[0, 0])
}
}

View File

@ -271,7 +271,9 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix
} }
else -> null else -> null
}?.let(type::cast) }?.let{
type.cast(it)
}
} }
/** /**
@ -505,7 +507,9 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM
} }
else -> null else -> null
}?.let(type::cast) }?.let{
type.cast(it)
}
} }
/** /**
@ -734,7 +738,9 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix
} }
else -> null else -> null
}?.let(type::cast) }?.let{
type.cast(it)
}
} }
/** /**
@ -963,7 +969,9 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSp
} }
else -> null else -> null
}?.let(type::cast) }?.let{
type.cast(it)
}
} }
/** /**

View File

@ -3,6 +3,8 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
@file:OptIn(PerformancePitfall::class)
package space.kscience.kmath.ejml package space.kscience.kmath.ejml
import org.ejml.data.DMatrixRMaj import org.ejml.data.DMatrixRMaj
@ -18,11 +20,11 @@ import kotlin.random.Random
import kotlin.random.asJavaRandom import kotlin.random.asJavaRandom
import kotlin.test.* import kotlin.test.*
@OptIn(PerformancePitfall::class) internal fun <T : Any> assertMatrixEquals(expected: StructureND<T>, actual: StructureND<T>) {
fun <T : Any> assertMatrixEquals(expected: StructureND<T>, actual: StructureND<T>) {
assertTrue { StructureND.contentEquals(expected, actual) } assertTrue { StructureND.contentEquals(expected, actual) }
} }
@OptIn(UnstableKMathAPI::class)
internal class EjmlMatrixTest { internal class EjmlMatrixTest {
private val random = Random(0) private val random = Random(0)

View File

@ -1,17 +1,15 @@
plugins { plugins {
kotlin("multiplatform") id("ru.mipt.npm.gradle.mpp")
id("ru.mipt.npm.gradle.common")
id("ru.mipt.npm.gradle.native") id("ru.mipt.npm.gradle.native")
} }
kscience { //apply(plugin = "kotlinx-atomicfu")
useAtomic()
}
kotlin.sourceSets { kotlin.sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api(project(":kmath-core")) api(project(":kmath-core"))
api(npmlibs.atomicfu)
} }
} }
commonTest { commonTest {

View File

@ -6,12 +6,14 @@
package space.kscience.kmath.histogram package space.kscience.kmath.histogram
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.real.step import space.kscience.kmath.real.step
import kotlin.random.Random import kotlin.random.Random
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
@OptIn(UnstableKMathAPI::class)
class TreeHistogramTest { class TreeHistogramTest {
@Test @Test

View File

@ -1,6 +1,5 @@
plugins { plugins {
kotlin("multiplatform") id("ru.mipt.npm.gradle.mpp")
id("ru.mipt.npm.gradle.common")
id("ru.mipt.npm.gradle.native") id("ru.mipt.npm.gradle.native")
} }

View File

@ -3,10 +3,6 @@ plugins {
id("ru.mipt.npm.gradle.native") id("ru.mipt.npm.gradle.native")
} }
kscience {
useAtomic()
}
kotlin.sourceSets { kotlin.sourceSets {
all { all {
languageSettings.optIn("space.kscience.kmath.misc.UnstableKMathAPI") languageSettings.optIn("space.kscience.kmath.misc.UnstableKMathAPI")
@ -15,6 +11,7 @@ kotlin.sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api(project(":kmath-coroutines")) api(project(":kmath-coroutines"))
api(npmlibs.atomicfu)
} }
} }
} }

View File

@ -3,14 +3,11 @@ plugins {
id("ru.mipt.npm.gradle.native") id("ru.mipt.npm.gradle.native")
} }
kscience {
useAtomic()
}
kotlin.sourceSets { kotlin.sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api(project(":kmath-coroutines")) api(project(":kmath-coroutines"))
implementation(npmlibs.atomicfu)
} }
} }

View File

@ -8,6 +8,7 @@ package space.kscience.kmath.stat
import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.first
import space.kscience.kmath.chains.Chain import space.kscience.kmath.chains.Chain
import space.kscience.kmath.chains.combine import space.kscience.kmath.chains.combine
import space.kscience.kmath.misc.UnstableKMathAPI
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 space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.DoubleBuffer
@ -30,6 +31,7 @@ public fun interface Sampler<out T : Any> {
/** /**
* Sample a bunch of values * Sample a bunch of values
*/ */
@OptIn(UnstableKMathAPI::class)
public fun <T : Any> Sampler<T>.sampleBuffer( public fun <T : Any> Sampler<T>.sampleBuffer(
generator: RandomGenerator, generator: RandomGenerator,
size: Int, size: Int,

View File

@ -66,7 +66,7 @@ class MCScopeTest {
} }
@OptIn(ObsoleteCoroutinesApi::class) @OptIn(DelicateCoroutinesApi::class)
fun compareResult(test: ATest) { fun compareResult(test: ATest) {
val res1 = runBlocking(Dispatchers.Default) { test() } val res1 = runBlocking(Dispatchers.Default) { test() }
val res2 = runBlocking(newSingleThreadContext("test")) { test() } val res2 = runBlocking(newSingleThreadContext("test")) { test() }

View File

@ -117,6 +117,7 @@ public open class ViktorFieldOpsND :
public val DoubleField.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND public val DoubleField.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND
@OptIn(UnstableKMathAPI::class)
public open class ViktorFieldND( public open class ViktorFieldND(
override val shape: Shape, override val shape: Shape,
) : ViktorFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>> { ) : ViktorFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>> {

View File

@ -1,6 +1,24 @@
rootProject.name = "kmath" rootProject.name = "kmath"
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
dependencyResolutionManagement {
val toolsVersion: String by extra
repositories {
mavenLocal()
maven("https://repo.kotlin.link")
mavenCentral()
gradlePluginPortal()
}
versionCatalogs {
create("npmlibs") {
from("ru.mipt.npm:version-catalog:$toolsVersion")
}
}
}
include( include(
":kmath-memory", ":kmath-memory",
":kmath-complex", ":kmath-complex",
@ -27,4 +45,4 @@ include(
":kmath-jafama", ":kmath-jafama",
":examples", ":examples",
":benchmarks", ":benchmarks",
) )