From 875e32679bc53f7e27814b6d067594f38de53ba6 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 12 Apr 2023 11:39:28 +0300 Subject: [PATCH 001/103] [WIP] geometry refactor --- CHANGELOG.md | 1 + build.gradle.kts | 8 ++--- .../space/kscience/kmath/geometry/Circle2D.kt | 6 ++-- .../kmath/geometry/Euclidean2DSpace.kt | 7 +++-- .../kmath/geometry/Euclidean3DSpace.kt | 6 ++-- .../kscience/kmath/geometry/GeometrySpace.kt | 23 ++++++++------ .../space/kscience/kmath/geometry/Line.kt | 14 ++++----- .../kscience/kmath/geometry/projections.kt | 4 +-- .../{floatPrecision.kt => vectorPrecision.kt} | 31 ++++++------------- .../kscience/kmath/geometry/testUtils.kt | 6 ++-- .../kscience/kmath/geometry/lineExtensions.kt | 7 +++-- 11 files changed, 56 insertions(+), 57 deletions(-) rename kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/{floatPrecision.kt => vectorPrecision.kt} (51%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 998e6daae..073eaaba2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ - Algebra now has an obligatory `bufferFactory` (#477). ### Changed +- Removed marker `Vector` type for geometry - Geometry uses type-safe angles - Tensor operations switched to prefix notation - Row-wise and column-wise ND shapes in the core diff --git a/build.gradle.kts b/build.gradle.kts index ec67eaa54..e061d007c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ allprojects { } group = "space.kscience" - version = "0.3.1-dev-RC" + version = "0.3.2-dev-" } subprojects { @@ -66,10 +66,10 @@ ksciencePublish { } github("kmath", "SciProgCentre") space( - if (isInDevelopment) { - "https://maven.pkg.jetbrains.space/spc/p/sci/dev" - } else { + if (findProperty("production") == "true" || !isInDevelopment) { "https://maven.pkg.jetbrains.space/spc/p/sci/maven" + } else { + "https://maven.pkg.jetbrains.space/spc/p/sci/dev" } ) sonatype() diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt index d37ed45c0..1a4cb6734 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt @@ -6,8 +6,10 @@ package space.kscience.kmath.geometry import kotlinx.serialization.Serializable -import space.kscience.kmath.geometry.Euclidean2DSpace.distanceTo -import kotlin.math.* +import kotlin.math.PI + +interface Circle<T> + /** * A circle in 2D space diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt index 3df8dba7b..012b5b73a 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt @@ -17,7 +17,7 @@ import space.kscience.kmath.operations.ScaleOperations import kotlin.math.pow import kotlin.math.sqrt -public interface Vector2D<T> : Point<T>, Vector { +public interface Vector2D<T> : Point<T> { public val x: T public val y: T override val size: Int get() = 2 @@ -47,7 +47,8 @@ public val Vector2D<Double>.r: Double get() = Euclidean2DSpace.norm(this) /** * 2D Euclidean space */ -public object Euclidean2DSpace : GeometrySpace<DoubleVector2D>, +public object Euclidean2DSpace : + GeometrySpace<DoubleVector2D, Double>, ScaleOperations<DoubleVector2D>, Norm<DoubleVector2D, Double> { @@ -87,4 +88,6 @@ public object Euclidean2DSpace : GeometrySpace<DoubleVector2D>, public val xAxis: DoubleVector2D = vector(1.0, 0.0) public val yAxis: DoubleVector2D = vector(0.0, 1.0) + + override val defaultPrecision: Double = 1e-6 } diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt index 3059cefe6..ce19d20a5 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt @@ -18,7 +18,7 @@ import space.kscience.kmath.structures.Buffer import kotlin.math.pow import kotlin.math.sqrt -public interface Vector3D<T> : Point<T>, Vector { +public interface Vector3D<T> : Point<T> { public val x: T public val y: T public val z: T @@ -55,7 +55,7 @@ public typealias Float64Vector3D = Vector3D<Double> public val DoubleVector3D.r: Double get() = Euclidean3DSpace.norm(this) -public object Euclidean3DSpace : GeometrySpace<DoubleVector3D>, ScaleOperations<DoubleVector3D>, +public object Euclidean3DSpace : GeometrySpace<DoubleVector3D, Double>, ScaleOperations<DoubleVector3D>, Norm<DoubleVector3D, Double> { @Serializable @@ -146,4 +146,6 @@ public object Euclidean3DSpace : GeometrySpace<DoubleVector3D>, ScaleOperations< public val xAxis: DoubleVector3D = vector(1.0, 0.0, 0.0) public val yAxis: DoubleVector3D = vector(0.0, 1.0, 0.0) public val zAxis: DoubleVector3D = vector(0.0, 0.0, 1.0) + + override val defaultPrecision: Double = 1e-6 } diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt index d6d7e5725..77c3b3a92 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt @@ -9,23 +9,26 @@ import space.kscience.kmath.operations.Group import space.kscience.kmath.operations.Norm import space.kscience.kmath.operations.ScaleOperations -public interface Vector - -public interface GeometrySpace<V : Vector> : Group<V>, ScaleOperations<V>, Norm<V, Double> { +/** + * A geometry vector space + * @param V the type of vector object + * @param D the type of distance + */ +public interface GeometrySpace<V : Any, D: Comparable<D>> : Group<V>, ScaleOperations<V>, Norm<V, D> { /** * L2 distance */ - public fun V.distanceTo(other: V): Double + public fun V.distanceTo(other: V): D /** * Scalar product */ public infix fun V.dot(other: V): Double - public companion object{ - /** - * Default precision for geometry objects comparison - */ - internal const val DEFAULT_PRECISION = 1e-6 - } + /** + * Default precision for geometry objects comparison + */ + public val defaultPrecision: D + + public companion object } \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt index a7f6ae35d..ed970b944 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt @@ -12,16 +12,16 @@ import kotlinx.serialization.Serializable * A line formed by [start] vector of start and a [direction] vector. Direction vector is not necessarily normalized, * but its length does not affect line properties */ -public interface Line<out V : Vector> { +public interface Line<out V : Any> { public val start: V public val direction: V } @Serializable @SerialName("Line") -private data class LineImpl<out V : Vector>(override val start: V, override val direction: V): Line<V> +private data class LineImpl<out V : Any>(override val start: V, override val direction: V) : Line<V> -public fun <V : Vector> Line(base: V, direction: V): Line<V> = LineImpl(base, direction) +public fun <V : Any> Line(base: V, direction: V): Line<V> = LineImpl(base, direction) public typealias Line2D = Line<DoubleVector2D> public typealias Line3D = Line<DoubleVector3D> @@ -29,7 +29,7 @@ public typealias Line3D = Line<DoubleVector3D> /** * A directed line segment between [begin] and [end] */ -public interface LineSegment<out V : Vector> { +public interface LineSegment<out V : Any> { public val begin: V public val end: V } @@ -39,11 +39,11 @@ public interface LineSegment<out V : Vector> { */ @Serializable @SerialName("LineSegment") -private data class LineSegmentImpl<out V : Vector>(override val begin: V, override val end: V) : LineSegment<V> +private data class LineSegmentImpl<out V : Any>(override val begin: V, override val end: V) : LineSegment<V> -public fun <V : Vector> LineSegment(begin: V, end: V): LineSegment<V> = LineSegmentImpl(begin, end) +public fun <V : Any> LineSegment(begin: V, end: V): LineSegment<V> = LineSegmentImpl(begin, end) -public fun <V : Vector> LineSegment<V>.line(algebra: GeometrySpace<V>): Line<V> = with(algebra) { +public fun <V : Any> LineSegment<V>.line(algebra: GeometrySpace<V, *>): Line<V> = with(algebra) { Line(begin, end - begin) } diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/projections.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/projections.kt index c5c3487a1..a983e6837 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/projections.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/projections.kt @@ -12,7 +12,7 @@ package space.kscience.kmath.geometry * @param vector to project * @param line line to which vector should be projected */ -public fun <V : Vector> GeometrySpace<V>.projectToLine(vector: V, line: Line<V>): V = with(line) { +public fun <V : Any> GeometrySpace<V, *>.projectToLine(vector: V, line: Line<V>): V = with(line) { start + (direction dot (vector - start)) / (direction dot direction) * direction } @@ -23,5 +23,5 @@ public fun <V : Vector> GeometrySpace<V>.projectToLine(vector: V, line: Line<V>) * @param normal normal (perpendicular) vector to a hyper-plane to which vector should be projected * @param base point belonging to a hyper-plane to which vector should be projected */ -public fun <V : Vector> GeometrySpace<V>.projectAlong(vector: V, normal: V, base: V): V = +public fun <V : Any> GeometrySpace<V, *>.projectAlong(vector: V, normal: V, base: V): V = vector + normal * ((base - vector) dot normal) / (normal dot normal) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt similarity index 51% rename from kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt rename to kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt index ea46ab90f..0c6816186 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt @@ -5,27 +5,14 @@ package space.kscience.kmath.geometry -import space.kscience.kmath.geometry.GeometrySpace.Companion.DEFAULT_PRECISION - -/** - * Float equality within given [precision] - */ -public fun Double.equalsFloat(other: Double, precision: Double = DEFAULT_PRECISION): Boolean = - kotlin.math.abs(this - other) < precision - -/** - * Float equality within given [precision] - */ -public fun Double.equalsFloat(other: Float, precision: Double = DEFAULT_PRECISION): Boolean = - kotlin.math.abs(this - other) < precision /** * Vector equality within given [precision] (using [GeometrySpace.norm] provided by the space */ -public fun <V : Vector> V.equalsVector( - space: GeometrySpace<V>, +public fun <V : Any, D : Comparable<D>> V.equalsVector( + space: GeometrySpace<V, D>, other: V, - precision: Double = DEFAULT_PRECISION, + precision: D = space.defaultPrecision, ): Boolean = with(space) { norm(this@equalsVector - other) < precision } @@ -35,22 +22,22 @@ public fun <V : Vector> V.equalsVector( */ public fun Float64Vector2D.equalsVector( other: Float64Vector2D, - precision: Double = DEFAULT_PRECISION, + precision: Double = Euclidean3DSpace.defaultPrecision, ): Boolean = equalsVector(Euclidean2DSpace, other, precision) /** - * Vector equality using Euclidian L2 norm and given [precision] + * Vector equality using Euclidean L2 norm and given [precision] */ public fun Float64Vector3D.equalsVector( other: Float64Vector3D, - precision: Double = DEFAULT_PRECISION, + precision: Double = Euclidean3DSpace.defaultPrecision, ): Boolean = equalsVector(Euclidean3DSpace, other, precision) /** * Line equality using [GeometrySpace.norm] provided by the [space] and given [precision] */ -public fun <V : Vector> LineSegment<V>.equalsLine( - space: GeometrySpace<V>, +public fun <V : Any, D : Comparable<D>> LineSegment<V>.equalsLine( + space: GeometrySpace<V, D>, other: LineSegment<V>, - precision: Double = DEFAULT_PRECISION, + precision: D = space.defaultPrecision, ): Boolean = begin.equalsVector(space, other.begin, precision) && end.equalsVector(space, other.end, precision) \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt index c62af3cd3..6796b291f 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -36,13 +36,13 @@ fun assertVectorEquals(expected: DoubleVector3D, actual: DoubleVector3D, absolut assertEquals(expected.z, actual.z, absoluteTolerance) } -fun <V : Vector> GeometrySpace<V>.isCollinear(a: V, b: V, absoluteTolerance: Double = 1e-6): Boolean { +fun <V : Any, D: Comparable<D>> GeometrySpace<V, D>.isCollinear(a: V, b: V, absoluteTolerance: D = defaultPrecision): Boolean { val aDist = a.distanceTo(zero) val bDist = b.distanceTo(zero) - return abs(aDist) < absoluteTolerance || abs(bDist) < absoluteTolerance || abs(abs((a dot b) / (aDist * bDist)) - 1) < absoluteTolerance + return aDist < absoluteTolerance || bDist < absoluteTolerance || abs(abs((a dot b) / (aDist * bDist)) - 1) < absoluteTolerance } -fun <V : Vector> GeometrySpace<V>.isOrthogonal(a: V, b: V, absoluteTolerance: Double = 1e-6): Boolean = +fun <V : Any> GeometrySpace<V,*>.isOrthogonal(a: V, b: V, absoluteTolerance: Double = 1e-6): Boolean = abs(a dot b) < absoluteTolerance fun Double.equalFloat(other: Double, maxFloatDelta: Double = 0.000001): diff --git a/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt b/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt index 5fcd2b23e..cf204f080 100644 --- a/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt +++ b/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt @@ -6,15 +6,16 @@ import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Line import space.kscience.kmath.geometry.LineSegment -import space.kscience.kmath.geometry.Vector import space.kscience.kmath.operations.Group /** * Get a line, containing this [LineSegment] */ -context(Group<V>) public val <V : Vector> LineSegment<V>.line: Line<V> get() = Line(begin, end - begin) +context(Group<V>) +public val <V : Any> LineSegment<V>.line: Line<V> get() = Line(begin, end - begin) /** * Get a length of a line segment */ -context(GeometrySpace<V>) public val <V : Vector> LineSegment<V>.length: Double get() = norm(end - begin) \ No newline at end of file +context(GeometrySpace<V>) +public val <V : Any> LineSegment<V>.length: Double get() = norm(end - begin) \ No newline at end of file From cdfddb75514a0a9f0f1118bce0b0f8c20438e026 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 21 Apr 2023 12:41:46 +0300 Subject: [PATCH 002/103] Explicit mutability for StructureND builders --- CHANGELOG.md | 1 + buildSrc/build.gradle.kts | 11 ++-- examples/build.gradle.kts | 2 +- .../kmath/operations/mixedNDOperations.kt | 7 +-- .../space/kscience/kmath/series/analyzeDif.kt | 5 +- .../kscience/kmath/series/seriesBuilder.kt | 50 +++++++++++++++++++ .../kmath/structures/StreamDoubleFieldND.kt | 9 ++++ .../kscience/kmath/structures/mutableNd.kt | 26 ++++++++++ gradle/wrapper/gradle-wrapper.properties | 2 +- kmath-core/build.gradle.kts | 4 +- .../space/kscience/kmath/nd/AlgebraND.kt | 10 +++- .../kscience/kmath/nd/BufferAlgebraND.kt | 13 ++++- .../space/kscience/kmath/nd/DoubleFieldND.kt | 4 +- .../space/kscience/kmath/nd/StructureND.kt | 1 + .../kscience/kmath/nd/algebraNDExtentions.kt | 6 +++ .../kmath/operations/BufferAlgebra.kt | 9 ++-- .../kmath/multik/MultikTensorAlgebra.kt | 6 +-- .../kscience/kmath/nd4j/Nd4jArrayAlgebra.kt | 2 +- .../kscience/kmath/nd4j/Nd4jTensorAlgebra.kt | 10 ++-- .../tensorflow/DoubleTensorFlowAlgebra.kt | 5 +- kmath-tensors/build.gradle.kts | 4 +- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 2 +- .../kmath/tensors/core/IntTensorAlgebra.kt | 2 +- .../kmath/tensors/core/TestDoubleTensor.kt | 4 +- .../kscience/kmath/viktor/ViktorFieldOpsND.kt | 7 ++- 25 files changed, 159 insertions(+), 43 deletions(-) create mode 100644 examples/src/main/kotlin/space/kscience/kmath/series/seriesBuilder.kt create mode 100644 examples/src/main/kotlin/space/kscience/kmath/structures/mutableNd.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 073eaaba2..3ce57d5ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased ### Added +- Explicit `mutableStructureND` builders for mutable stucures ### Changed diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index afa36ed1e..734f60091 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -3,8 +3,6 @@ plugins { `version-catalog` } -java.targetCompatibility = JavaVersion.VERSION_11 - repositories { mavenLocal() maven("https://repo.kotlin.link") @@ -26,6 +24,11 @@ dependencies { implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.+") } -kotlin.sourceSets.all { - languageSettings.optIn("kotlin.OptIn") +kotlin{ + jvmToolchain{ + languageVersion.set(JavaLanguageVersion.of(11)) + } + sourceSets.all { + languageSettings.optIn("kotlin.OptIn") + } } diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 50708eaa9..4047dfc5e 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -52,7 +52,7 @@ dependencies { implementation("org.slf4j:slf4j-simple:1.7.32") // plotting - implementation("space.kscience:plotlykt-server:0.5.0") + implementation("space.kscience:plotlykt-server:0.5.3-dev-1") } kotlin { diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt index 4a5d783e1..6cbcd9943 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt @@ -8,14 +8,15 @@ package space.kscience.kmath.operations import space.kscience.kmath.commons.linear.CMLinearSpace import space.kscience.kmath.linear.matrix import space.kscience.kmath.nd.DoubleBufferND -import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.Structure2D +import space.kscience.kmath.nd.mutableStructureND import space.kscience.kmath.nd.ndAlgebra -import space.kscience.kmath.viktor.ViktorStructureND import space.kscience.kmath.viktor.viktorAlgebra +import kotlin.collections.component1 +import kotlin.collections.component2 fun main() { - val viktorStructure: ViktorStructureND = DoubleField.viktorAlgebra.structureND(ShapeND(2, 2)) { (i, j) -> + val viktorStructure = DoubleField.viktorAlgebra.mutableStructureND(2, 2) { (i, j) -> if (i == j) 2.0 else 0.0 } diff --git a/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt b/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt index 0e10f1a9a..e49adc82e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt @@ -13,7 +13,10 @@ import space.kscience.kmath.structures.slice import space.kscience.plotly.* import kotlin.math.PI -fun main() = with(Double.algebra.bufferAlgebra.seriesAlgebra()) { +fun Double.Companion.seriesAlgebra() = Double.algebra.bufferAlgebra.seriesAlgebra() + + +fun main() = with(Double.seriesAlgebra()) { fun Plot.plotSeries(name: String, buffer: Buffer<Double>) { diff --git a/examples/src/main/kotlin/space/kscience/kmath/series/seriesBuilder.kt b/examples/src/main/kotlin/space/kscience/kmath/series/seriesBuilder.kt new file mode 100644 index 000000000..f8a8f1d0b --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/series/seriesBuilder.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018-2023 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.series + + +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.asBuffer +import space.kscience.kmath.structures.toDoubleArray +import space.kscience.plotly.* +import space.kscience.plotly.models.Scatter +import space.kscience.plotly.models.ScatterMode +import kotlin.random.Random + +fun main(): Unit = with(Double.seriesAlgebra()) { + + val random = Random(1234) + + val arrayOfRandoms = DoubleArray(20) { random.nextDouble() } + + val series1: DoubleBuffer = arrayOfRandoms.asBuffer() + val series2: Series<Double> = series1.moveBy(3) + + val res = series2 - series1 + + println(res.size) + + println(res) + + fun Plot.series(name: String, buffer: Buffer<Double>, block: Scatter.() -> Unit = {}) { + scatter { + this.name = name + x.numbers = buffer.offsetIndices + y.doubles = buffer.toDoubleArray() + block() + } + } + + Plotly.plot { + series("series1", series1) + series("series2", series2) + series("dif", res){ + mode = ScatterMode.lines + line.color("magenta") + } + }.makeFile(resourceLocation = ResourceLocation.REMOTE) +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt index 2ce2c21a6..9877c41ad 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt @@ -52,6 +52,15 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF return BufferND(strides, array.asBuffer()) } + override fun mutableStructureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): MutableBufferND<Double> { + val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> + val index = strides.index(offset) + DoubleField.initializer(index) + }.toArray() + + return MutableBufferND(strides, array.asBuffer()) + } + @OptIn(PerformancePitfall::class) override fun StructureND<Double>.map( transform: DoubleField.(Double) -> Double, diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/mutableNd.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/mutableNd.kt new file mode 100644 index 000000000..0b0a4cac1 --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/mutableNd.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2018-2023 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.structures + +import space.kscience.kmath.PerformancePitfall +import space.kscience.kmath.nd.* +import space.kscience.kmath.operations.algebra + +@OptIn(PerformancePitfall::class) +fun main(): Unit = with(Double.algebra.ndAlgebra) { + val structure: MutableStructure2D<Double> = mutableStructureND(ShapeND(2, 2)) { (i, j) -> + i.toDouble() + j.toDouble() + }.as2D() + + structure[0, 1] = -2.0 + + val structure2 = mutableStructureND(2, 2) { (i, j) -> i.toDouble() + j.toDouble() }.as2D() + + structure2[0, 1] = 2.0 + + + println(structure + structure2) +} \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 070cb702f..59bc51a20 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index 08411be59..600b0b8ce 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -37,8 +37,8 @@ kotlin.sourceSets { filter { it.name.contains("test", true) } .map(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::languageSettings) .forEach { - it.optIn("space.kscience.kmath.misc.PerformancePitfall") - it.optIn("space.kscience.kmath.misc.UnstableKMathAPI") + it.optIn("space.kscience.kmath.PerformancePitfall") + it.optIn("space.kscience.kmath.UnstableKMathAPI") } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt index 91e26cc1b..f6626432d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt @@ -16,16 +16,22 @@ import kotlin.reflect.KClass * @param T the type of ND-structure element. * @param C the type of the element context. */ -public interface AlgebraND<T, out C : Algebra<T>>: Algebra<StructureND<T>> { +public interface AlgebraND<T, out C : Algebra<T>> : Algebra<StructureND<T>> { /** * The algebra over elements of ND structure. */ public val elementAlgebra: C + /** + * Produces a new [MutableStructureND] using given initializer function. + */ + public fun mutableStructureND(shape: ShapeND, initializer: C.(IntArray) -> T): MutableStructureND<T> + /** * Produces a new [StructureND] using given initializer function. */ - public fun structureND(shape: ShapeND, initializer: C.(IntArray) -> T): StructureND<T> + public fun structureND(shape: ShapeND, initializer: C.(IntArray) -> T): StructureND<T> = + mutableStructureND(shape, initializer) /** * Maps elements from one structure to another one by applying [transform] to them. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt index 74c63e6e2..78bc83826 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt @@ -16,9 +16,10 @@ public interface BufferAlgebraND<T, out A : Algebra<T>> : AlgebraND<T, A> { public val bufferAlgebra: BufferAlgebra<T, A> override val elementAlgebra: A get() = bufferAlgebra.elementAlgebra - override fun structureND(shape: ShapeND, initializer: A.(IntArray) -> T): BufferND<T> { + //TODO change AlgebraND contract to include this + override fun mutableStructureND(shape: ShapeND, initializer: A.(IntArray) -> T): MutableBufferND<T> { val indexer = indexerBuilder(shape) - return BufferND( + return MutableBufferND( indexer, bufferAlgebra.buffer(indexer.linearSize) { offset -> elementAlgebra.initializer(indexer.index(offset)) @@ -26,6 +27,9 @@ public interface BufferAlgebraND<T, out A : Algebra<T>> : AlgebraND<T, A> { ) } + override fun structureND(shape: ShapeND, initializer: A.(IntArray) -> T): BufferND<T> = + mutableStructureND(shape, initializer) + @OptIn(PerformancePitfall::class) public fun StructureND<T>.toBufferND(): BufferND<T> = when (this) { is BufferND -> this @@ -133,6 +137,11 @@ public fun <T, A : Algebra<T>> BufferAlgebraND<T, A>.structureND( initializer: A.(IntArray) -> T, ): BufferND<T> = structureND(ShapeND(shape), initializer) +public fun <T, A : Algebra<T>> BufferAlgebraND<T, A>.mutableStructureND( + vararg shape: Int, + initializer: A.(IntArray) -> T, +): MutableBufferND<T> = mutableStructureND(ShapeND(shape), initializer) + public fun <T, EA : Algebra<T>, A> A.structureND( initializer: EA.(IntArray) -> T, ): BufferND<T> where A : BufferAlgebraND<T, EA>, A : WithShape = structureND(shape, initializer) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt index 265d1eec8..15048efa2 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt @@ -74,7 +74,7 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D transform: DoubleField.(Double, Double) -> Double, ): BufferND<Double> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> DoubleField.transform(l, r) } - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): DoubleBufferND { + override fun mutableStructureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): DoubleBufferND { val indexer = indexerBuilder(shape) return DoubleBufferND( indexer, @@ -225,7 +225,7 @@ public class DoubleFieldND(override val shape: ShapeND) : override fun number(value: Number): DoubleBufferND { val d = value.toDouble() // minimize conversions - return structureND(shape) { d } + return mutableStructureND(shape) { d } } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index e643186ba..f0a258389 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -244,6 +244,7 @@ public interface MutableStructureND<T> : StructureND<T> { * Set value at specified indices */ @PerformancePitfall +@Deprecated("") public operator fun <T> MutableStructureND<T>.set(vararg index: Int, value: T) { set(index, value) } \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt index f0d4bd7f5..506f82da4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt @@ -17,6 +17,12 @@ public fun <T, A : Algebra<T>> AlgebraND<T, A>.structureND( initializer: A.(IntArray) -> T ): StructureND<T> = structureND(ShapeND(shapeFirst, *shapeRest), initializer) +public fun <T, A : Algebra<T>> AlgebraND<T, A>.mutableStructureND( + shapeFirst: Int, + vararg shapeRest: Int, + initializer: A.(IntArray) -> T +): MutableStructureND<T> = mutableStructureND(ShapeND(shapeFirst, *shapeRest), initializer) + public fun <T, A : Group<T>> AlgebraND<T, A>.zero(shape: ShapeND): StructureND<T> = structureND(shape) { zero } @JvmName("zeroVarArg") diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index af0bc4d9b..26a4b0a53 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -6,7 +6,8 @@ package space.kscience.kmath.operations import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.BufferFactory +import space.kscience.kmath.structures.MutableBuffer +import space.kscience.kmath.structures.MutableBufferFactory public interface WithSize { public val size: Int @@ -17,7 +18,7 @@ public interface WithSize { */ public interface BufferAlgebra<T, out A : Algebra<T>> : Algebra<Buffer<T>> { public val elementAlgebra: A - public val elementBufferFactory: BufferFactory<T> get() = elementAlgebra.bufferFactory + public val elementBufferFactory: MutableBufferFactory<T> get() = elementAlgebra.bufferFactory public fun buffer(size: Int, vararg elements: T): Buffer<T> { require(elements.size == size) { "Expected $size elements but found ${elements.size}" } @@ -73,11 +74,11 @@ private inline fun <T, A : Algebra<T>> BufferAlgebra<T, A>.zipInline( return elementBufferFactory(l.size) { elementAlgebra.block(l[it], r[it]) } } -public fun <T> BufferAlgebra<T, *>.buffer(size: Int, initializer: (Int) -> T): Buffer<T> { +public fun <T> BufferAlgebra<T, *>.buffer(size: Int, initializer: (Int) -> T): MutableBuffer<T> { return elementBufferFactory(size, initializer) } -public fun <T, A> A.buffer(initializer: (Int) -> T): Buffer<T> where A : BufferAlgebra<T, *>, A : WithSize { +public fun <T, A> A.buffer(initializer: (Int) -> T): MutableBuffer<T> where A : BufferAlgebra<T, *>, A : WithSize { return elementBufferFactory(size, initializer) } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt index c3a82b167..c5bbebfd8 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt @@ -33,7 +33,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( protected val multikStat: Statistics = multikEngine.getStatistics() @OptIn(UnsafeKMathAPI::class) - override fun structureND(shape: ShapeND, initializer: A.(IntArray) -> T): MultikTensor<T> { + override fun mutableStructureND(shape: ShapeND, initializer: A.(IntArray) -> T): MultikTensor<T> { val strides = ColumnStrides(shape) val memoryView = initMemoryView<T>(strides.linearSize, type) strides.asSequence().forEachIndexed { linearIndex, tensorIndex -> @@ -49,7 +49,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( for (el in array) data[count++] = elementAlgebra.transform(el) NDArray(data, shape = shape.asArray(), dim = array.dim).wrap() } else { - structureND(shape) { index -> + mutableStructureND(shape) { index -> transform(get(index)) } } @@ -70,7 +70,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( } NDArray(data, shape = array.shape, dim = array.dim).wrap() } else { - structureND(shape) { index -> + mutableStructureND(shape) { index -> transform(index, get(index)) } } diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt index 0eb147b6f..eab6672a1 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt @@ -34,7 +34,7 @@ public sealed interface Nd4jArrayAlgebra<T, out C : Algebra<T>> : AlgebraND<T, C public val StructureND<T>.ndArray: INDArray @OptIn(PerformancePitfall::class) - override fun structureND(shape: ShapeND, initializer: C.(IntArray) -> T): Nd4jArrayStructure<T> { + override fun mutableStructureND(shape: ShapeND, initializer: C.(IntArray) -> T): Nd4jArrayStructure<T> { @OptIn(UnsafeKMathAPI::class) val struct: Nd4jArrayStructure<T> = Nd4j.create(*shape.asArray())!!.wrap() struct.indicesIterator().forEach { struct[it] = elementAlgebra.initializer(it) } diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt index 5905739f8..44401ec53 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt @@ -37,20 +37,20 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe */ public val StructureND<T>.ndArray: INDArray - override fun structureND(shape: ShapeND, initializer: A.(IntArray) -> T): Nd4jArrayStructure<T> + override fun mutableStructureND(shape: ShapeND, initializer: A.(IntArray) -> T): Nd4jArrayStructure<T> @OptIn(PerformancePitfall::class) override fun StructureND<T>.map(transform: A.(T) -> T): Nd4jArrayStructure<T> = - structureND(shape) { index -> elementAlgebra.transform(get(index)) } + mutableStructureND(shape) { index -> elementAlgebra.transform(get(index)) } @OptIn(PerformancePitfall::class) override fun StructureND<T>.mapIndexed(transform: A.(index: IntArray, T) -> T): Nd4jArrayStructure<T> = - structureND(shape) { index -> elementAlgebra.transform(index, get(index)) } + mutableStructureND(shape) { index -> elementAlgebra.transform(index, get(index)) } @OptIn(PerformancePitfall::class) override fun zip(left: StructureND<T>, right: StructureND<T>, transform: A.(T, T) -> T): Nd4jArrayStructure<T> { require(left.shape.contentEquals(right.shape)) - return structureND(left.shape) { index -> elementAlgebra.transform(left[index], right[index]) } + return mutableStructureND(left.shape) { index -> elementAlgebra.transform(left[index], right[index]) } } override fun T.plus(arg: StructureND<T>): Nd4jArrayStructure<T> = arg.ndArray.add(this).wrap() @@ -178,7 +178,7 @@ public object DoubleNd4jTensorAlgebra : Nd4jTensorAlgebra<Double, DoubleField> { override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure() @OptIn(UnsafeKMathAPI::class) - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): Nd4jArrayStructure<Double> { + override fun mutableStructureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): Nd4jArrayStructure<Double> { val array: INDArray = Nd4j.zeros(*shape.asArray()) val indices = ColumnStrides(shape) indices.asSequence().forEach { index -> diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt index 41c7c0b68..dceb0cb53 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt @@ -14,6 +14,7 @@ import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.nd.ColumnStrides +import space.kscience.kmath.nd.MutableStructureND import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.StructureND import space.kscience.kmath.operations.DoubleField @@ -36,10 +37,10 @@ public class DoubleTensorFlowAlgebra internal constructor( override val elementAlgebra: DoubleField get() = DoubleField - override fun structureND( + override fun mutableStructureND( shape: ShapeND, initializer: DoubleField.(IntArray) -> Double, - ): StructureND<Double> { + ): MutableStructureND<Double> { val res = TFloat64.tensorOf(org.tensorflow.ndarray.Shape.of(*shape.toLongArray())) { array -> ColumnStrides(shape).forEach { index -> array.setDouble(elementAlgebra.initializer(index), *index.toLongArray()) diff --git a/kmath-tensors/build.gradle.kts b/kmath-tensors/build.gradle.kts index d27faeeef..7a556ddb6 100644 --- a/kmath-tensors/build.gradle.kts +++ b/kmath-tensors/build.gradle.kts @@ -15,12 +15,12 @@ kscience{ kotlin.sourceSets { all { - languageSettings.optIn("space.kscience.kmath.misc.UnstableKMathAPI") + languageSettings.optIn("space.kscience.kmath.UnstableKMathAPI") } filter { it.name.contains("test", true) } .map(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::languageSettings) - .forEach { it.optIn("space.kscience.kmath.misc.PerformancePitfall") } + .forEach { it.optIn("space.kscience.kmath.PerformancePitfall") } commonMain { dependencies { diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 70a3ef7e2..7a076b8b2 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -127,7 +127,7 @@ public open class DoubleTensorAlgebra : * @param initializer mapping tensor indices to values. * @return tensor with the [shape] shape and data generated by the [initializer]. */ - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): DoubleTensor = fromArray( + override fun mutableStructureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): DoubleTensor = fromArray( shape, RowStrides(shape).asSequence().map { DoubleField.initializer(it) }.toMutableList().toDoubleArray() ) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt index d1cdc68d4..c20b1cd7d 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt @@ -118,7 +118,7 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> { * @param initializer mapping tensor indices to values. * @return tensor with the [shape] shape and data generated by the [initializer]. */ - override fun structureND(shape: ShapeND, initializer: IntRing.(IntArray) -> Int): IntTensor = fromArray( + override fun mutableStructureND(shape: ShapeND, initializer: IntRing.(IntArray) -> Int): IntTensor = fromArray( shape, RowStrides(shape).asSequence().map { IntRing.initializer(it) }.toMutableList().toIntArray() ) diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt index 811fc1117..1f3079bd0 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt @@ -92,7 +92,7 @@ internal class TestDoubleTensor { @Test fun test2D() = with(DoubleTensorAlgebra) { - val tensor: DoubleTensor = structureND(ShapeND(3, 3)) { (i, j) -> (i - j).toDouble() } + val tensor: DoubleTensor = mutableStructureND(ShapeND(3, 3)) { (i, j) -> (i - j).toDouble() } //println(tensor.toPrettyString()) val tensor2d = tensor.asDoubleTensor2D() assertBufferEquals(DoubleBuffer(1.0, 0.0, -1.0), tensor2d.rows[1]) @@ -101,7 +101,7 @@ internal class TestDoubleTensor { @Test fun testMatrixIteration() = with(DoubleTensorAlgebra) { - val tensor = structureND(ShapeND(3, 3, 3, 3)) { index -> index.sum().toDouble() } + val tensor = mutableStructureND(ShapeND(3, 3, 3, 3)) { index -> index.sum().toDouble() } tensor.forEachMatrix { index, matrix -> println(index.joinToString { it.toString() }) println(matrix) diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt index 8c7d6d199..ed705d2cd 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt @@ -17,8 +17,7 @@ import space.kscience.kmath.operations.ExtendedFieldOps import space.kscience.kmath.operations.NumbersAddOps import space.kscience.kmath.operations.PowerOperations -@OptIn(UnstableKMathAPI::class, PerformancePitfall::class) -@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") +@OptIn(PerformancePitfall::class) public open class ViktorFieldOpsND : FieldOpsND<Double, DoubleField>, ExtendedFieldOps<StructureND<Double>>, @@ -27,13 +26,13 @@ public open class ViktorFieldOpsND : public val StructureND<Double>.f64Buffer: F64Array get() = when (this) { is ViktorStructureND -> this.f64Buffer - else -> structureND(shape) { this@f64Buffer[it] }.f64Buffer + else -> mutableStructureND(shape) { this@f64Buffer[it] }.f64Buffer } override val elementAlgebra: DoubleField get() = DoubleField @OptIn(UnsafeKMathAPI::class) - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): ViktorStructureND = + override fun mutableStructureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): ViktorStructureND = F64Array(*shape.asArray()).apply { ColumnStrides(shape).asSequence().forEach { index -> set(value = DoubleField.initializer(index), indices = index) From f09371a3f9d90e52c1826f1bf2a09d935987cb08 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sat, 22 Apr 2023 09:13:06 +0300 Subject: [PATCH 003/103] Explicit mutability for StructureND builders --- kmath-ast/build.gradle.kts | 2 +- .../src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt | 2 ++ .../kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt | 2 ++ .../kotlin/space/kscience/kmath/geometry/Circle2D.kt | 2 +- .../kotlin/space/kscience/kmath/geometry/testUtils.kt | 2 +- .../space/kscience/kmath/geometry/lineExtensions.kt | 8 +++++--- 6 files changed, 12 insertions(+), 6 deletions(-) diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index c60977862..7cdb745f0 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -46,7 +46,7 @@ kotlin { sourceSets { filter { it.name.contains("test", true) } .map(org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet::languageSettings) - .forEach { it.optIn("space.kscience.kmath.misc.UnstableKMathAPI") } + .forEach { it.optIn("space.kscience.kmath.UnstableKMathAPI") } } } diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt index c6b241e5c..f48f74ccd 100644 --- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt +++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.ast +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.Symbol @@ -17,6 +18,7 @@ import space.kscience.kmath.estree.compileToExpression as estreeCompileToExpress import space.kscience.kmath.wasm.compile as wasmCompile import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression +@OptIn(UnstableKMathAPI::class) private object WasmCompilerTestContext : CompilerTestContext { override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = wasmCompileToExpression(algebra) override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = wasmCompile(algebra, arguments) diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt index 0a85d5f24..132f9f1bd 100644 --- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt +++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.wasm +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.MstRing import space.kscience.kmath.expressions.invoke @@ -15,6 +16,7 @@ import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals +@OptIn(UnstableKMathAPI::class) internal class TestWasmSpecific { @Test fun int() { diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt index 1a4cb6734..202dab0c2 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.geometry import kotlinx.serialization.Serializable import kotlin.math.PI -interface Circle<T> +public interface Circle<T> /** diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt index 6796b291f..4c3bcc85e 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -36,7 +36,7 @@ fun assertVectorEquals(expected: DoubleVector3D, actual: DoubleVector3D, absolut assertEquals(expected.z, actual.z, absoluteTolerance) } -fun <V : Any, D: Comparable<D>> GeometrySpace<V, D>.isCollinear(a: V, b: V, absoluteTolerance: D = defaultPrecision): Boolean { +fun <V : Any> GeometrySpace<V, Double>.isCollinear(a: V, b: V, absoluteTolerance: Double = defaultPrecision): Boolean { val aDist = a.distanceTo(zero) val bDist = b.distanceTo(zero) return aDist < absoluteTolerance || bDist < absoluteTolerance || abs(abs((a dot b) / (aDist * bDist)) - 1) < absoluteTolerance diff --git a/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt b/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt index cf204f080..bec7e9799 100644 --- a/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt +++ b/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt @@ -12,10 +12,12 @@ import space.kscience.kmath.operations.Group * Get a line, containing this [LineSegment] */ context(Group<V>) -public val <V : Any> LineSegment<V>.line: Line<V> get() = Line(begin, end - begin) +public val <V : Any> LineSegment<V>.line: Line<V> + get() = Line(begin, end - begin) /** * Get a length of a line segment */ -context(GeometrySpace<V>) -public val <V : Any> LineSegment<V>.length: Double get() = norm(end - begin) \ No newline at end of file +context(GeometrySpace<V, D>) +public val <V : Any, D : Comparable<D>> LineSegment<V>.length: D + get() = norm(end - begin) \ No newline at end of file From 10f84bd630ae6654fb03898e1fd2d50300976db7 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 3 May 2023 21:14:29 +0300 Subject: [PATCH 004/103] added function solve --- .../kmath/tensors/api/LinearOpsTensorAlgebra.kt | 14 ++++++++++++++ .../kmath/tensors/core/DoubleTensorAlgebra.kt | 6 ++++++ 2 files changed, 20 insertions(+) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt index faff2eb80..60865ecba 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt @@ -5,8 +5,15 @@ package space.kscience.kmath.tensors.api +import space.kscience.kmath.nd.MutableStructure2D import space.kscience.kmath.nd.StructureND +import space.kscience.kmath.nd.as2D import space.kscience.kmath.operations.Field +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.map +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.transposed +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra /** * Common linear algebra operations. Operates on [Tensor]. @@ -103,4 +110,11 @@ public interface LinearOpsTensorAlgebra<T, A : Field<T>> : TensorPartialDivision */ public fun symEig(structureND: StructureND<T>): Pair<StructureND<T>, StructureND<T>> + /** Returns the solution to the equation Ax = B for the square matrix A as `input1` and + * for the square matrix B as `input2`. + * + * @receiver the `input1` and the `input2`. + * @return the square matrix x which is the solution of the equation. + */ + public fun solve(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 70a3ef7e2..1571eb7f1 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -711,6 +711,12 @@ public open class DoubleTensorAlgebra : override fun symEig(structureND: StructureND<Double>): Pair<DoubleTensor, DoubleTensor> = symEigJacobi(structureND = structureND, maxIteration = 50, epsilon = 1e-15) + override fun solve(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { + val aSvd = DoubleTensorAlgebra.svd(a) + val s = BroadcastDoubleTensorAlgebra.diagonalEmbedding(aSvd.second.map {1.0 / it}) + val aInverse = aSvd.third.dot(s).dot(aSvd.first.transposed()) + return aInverse.dot(b).as2D() + } } public val Double.Companion.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra From 19c1af18743b899e566c254a121cd4a961d0ca59 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 3 May 2023 21:25:30 +0300 Subject: [PATCH 005/103] added helper functions for levenberg-marquardt algorithm --- .../kmath/tensors/core/internal/linUtils.kt | 228 ++++++++++++++++++ 1 file changed, 228 insertions(+) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index cf3697e76..c559803ec 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -12,7 +12,14 @@ import space.kscience.kmath.structures.IntBuffer import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.structures.indices import space.kscience.kmath.tensors.core.* +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.minus +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.times +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.transposed +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus import kotlin.math.abs +import kotlin.math.max import kotlin.math.min import kotlin.math.sqrt @@ -308,3 +315,224 @@ internal fun DoubleTensorAlgebra.svdHelper( matrixV.source[i] = vBuffer[i] } } + +data class LMSettings ( + var iteration:Int, + var func_calls: Int, + var example_number:Int +) + +/* matrix -> column of all elemnets */ +fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D<Double> { + val shape = intArrayOf(tensor.shape.component1() * tensor.shape.component2(), 1) + var buffer = DoubleArray(tensor.shape.component1() * tensor.shape.component2()) + for (i in 0 until tensor.shape.component1()) { + for (j in 0 until tensor.shape.component2()) { + buffer[i * tensor.shape.component2() + j] = tensor[i, j] + } + } + var column = BroadcastDoubleTensorAlgebra.fromArray(ShapeND(shape), buffer).as2D() + return column +} + +/* column length */ +fun length(column: MutableStructure2D<Double>) : Int { + return column.shape.component1() +} + +fun MutableStructure2D<Double>.abs() { + for (i in 0 until this.shape.component1()) { + for (j in 0 until this.shape.component2()) { + this[i, j] = abs(this[i, j]) + } + } +} + +fun abs(input: MutableStructure2D<Double>): MutableStructure2D<Double> { + val tensor = BroadcastDoubleTensorAlgebra.ones( + ShapeND( + intArrayOf( + input.shape.component1(), + input.shape.component2() + ) + ) + ).as2D() + for (i in 0 until tensor.shape.component1()) { + for (j in 0 until tensor.shape.component2()) { + tensor[i, j] = abs(input[i, j]) + } + } + return tensor +} + +fun diag(input: MutableStructure2D<Double>): MutableStructure2D<Double> { + val tensor = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(input.shape.component1(), 1))).as2D() + for (i in 0 until tensor.shape.component1()) { + tensor[i, 0] = input[i, i] + } + return tensor +} + +fun make_matrx_with_diagonal(column: MutableStructure2D<Double>): MutableStructure2D<Double> { + val size = column.shape.component1() + val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(size, size))).as2D() + for (i in 0 until size) { + tensor[i, i] = column[i, 0] + } + return tensor +} + +fun lm_eye(size: Int): MutableStructure2D<Double> { + val column = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(size, 1))).as2D() + return make_matrx_with_diagonal(column) +} + +fun largest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { + val a_sizeX = a.shape.component1() + val a_sizeY = a.shape.component2() + val b_sizeX = b.shape.component1() + val b_sizeY = b.shape.component2() + val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(a_sizeX, b_sizeX), max(a_sizeY, b_sizeY)))).as2D() + for (i in 0 until tensor.shape.component1()) { + for (j in 0 until tensor.shape.component2()) { + if (i < a_sizeX && i < b_sizeX && j < a_sizeY && j < b_sizeY) { + tensor[i, j] = max(a[i, j], b[i, j]) + } + else if (i < a_sizeX && j < a_sizeY) { + tensor[i, j] = a[i, j] + } + else { + tensor[i, j] = b[i, j] + } + } + } + return tensor +} + +fun smallest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { + val a_sizeX = a.shape.component1() + val a_sizeY = a.shape.component2() + val b_sizeX = b.shape.component1() + val b_sizeY = b.shape.component2() + val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(a_sizeX, b_sizeX), max(a_sizeY, b_sizeY)))).as2D() + for (i in 0 until tensor.shape.component1()) { + for (j in 0 until tensor.shape.component2()) { + if (i < a_sizeX && i < b_sizeX && j < a_sizeY && j < b_sizeY) { + tensor[i, j] = min(a[i, j], b[i, j]) + } + else if (i < a_sizeX && j < a_sizeY) { + tensor[i, j] = a[i, j] + } + else { + tensor[i, j] = b[i, j] + } + } + } + return tensor +} + +fun get_zero_indices(column: MutableStructure2D<Double>, epsilon: Double = 0.000001): MutableStructure2D<Double>? { + var idx = emptyArray<Double>() + for (i in 0 until column.shape.component1()) { + if (abs(column[i, 0]) > epsilon) { + idx += (i + 1.0) + } + } + if (idx.size > 0) { + return BroadcastDoubleTensorAlgebra.fromArray(ShapeND(intArrayOf(idx.size, 1)), idx.toDoubleArray()).as2D() + } + return null +} + +fun feval(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings) + : MutableStructure2D<Double> +{ + return func(t, p, settings) +} + +fun lm_matx(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, + dX2: Int, J_input: MutableStructure2D<Double>, p: MutableStructure2D<Double>, + y_dat: MutableStructure2D<Double>, weight: MutableStructure2D<Double>, dp:MutableStructure2D<Double>, settings:LMSettings) : Array<MutableStructure2D<Double>> +{ + // default: dp = 0.001 + + val Npnt = length(y_dat) // number of data points + val Npar = length(p) // number of parameters + + val y_hat = feval(func, t, p, settings) // evaluate model using parameters 'p' + settings.func_calls += 1 + + var J = J_input + + if (settings.iteration % (2 * Npar) == 0 || dX2 > 0) { + J = lm_FD_J(func, t, p, y_hat, dp, settings).as2D() // finite difference + } + else { + J = lm_Broyden_J(p_old, y_old, J, p, y_hat).as2D() // rank-1 update + } + + val delta_y = y_dat.minus(y_hat) + + val Chi_sq = delta_y.transposed().dot( delta_y.times(weight) ).as2D() + val JtWJ = J.transposed().dot ( J.times( weight.dot(BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(1, Npar)))) ) ).as2D() + val JtWdy = J.transposed().dot( weight.times(delta_y) ).as2D() + + return arrayOf(JtWJ,JtWdy,Chi_sq,y_hat,J) +} + +fun lm_Broyden_J(p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, J_input: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, y: MutableStructure2D<Double>): MutableStructure2D<Double> { + var J = J_input.copyToTensor() + + val h = p.minus(p_old) + val increase = y.minus(y_old).minus( J.dot(h) ).dot(h.transposed()).div( (h.transposed().dot(h)).as2D()[0, 0] ) + J = J.plus(increase) + + return J.as2D() +} + +fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, settings: LMSettings) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y: MutableStructure2D<Double>, + dp: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + // default: dp = 0.001 * ones(1,n) + + val m = length(y) // number of data points + val n = length(p) // number of parameters + + val ps = p.copyToTensor().as2D() + val J = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, n))).as2D() // initialize Jacobian to Zero + val del = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(n, 1))).as2D() + + for (j in 0 until n) { + + del[j, 0] = dp[j, 0] * (1 + abs(p[j, 0])) // parameter perturbation + p[j, 0] = ps[j, 0] + del[j, 0] // perturb parameter p(j) + + val epsilon = 0.0000001 + if (kotlin.math.abs(del[j, 0]) > epsilon) { + val y1 = feval(func, t, p, settings) + settings.func_calls += 1 + + if (dp[j, 0] < 0) { // backwards difference + for (i in 0 until J.shape.component1()) { + J[i, j] = (y1.as2D().minus(y).as2D())[i, 0] / del[j, 0] + } + } + else { + // Do tests for it + println("Potential mistake") + p[j, 0] = ps[j, 0] - del[j, 0] // central difference, additional func call + for (i in 0 until J.shape.component1()) { + J[i, j] = (y1.as2D().minus(feval(func, t, p, settings)).as2D())[i, 0] / (2 * del[j, 0]) + } + settings.func_calls += 1 + } + } + + p[j, 0] = ps[j, 0] // restore p(j) + } + + return J.as2D() +} From 89a5522144b2052278c252f833ec678628918b06 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Thu, 4 May 2023 00:44:18 +0300 Subject: [PATCH 006/103] added new svd algorithm (Golub Kahan) and used by default for svd --- .../space/kscience/kmath/ejml/_generated.kt | 2 +- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 2 +- .../kmath/tensors/core/internal/linUtils.kt | 301 +++++++++++++++++- .../kscience/kmath/tensors/core/tensorOps.kt | 30 ++ 4 files changed, 329 insertions(+), 6 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index c56583fa8..8ad7f7293 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,9 +19,9 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.FloatField diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 1571eb7f1..5325fe19e 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -706,7 +706,7 @@ public open class DoubleTensorAlgebra : override fun svd( structureND: StructureND<Double>, ): Triple<StructureND<Double>, StructureND<Double>, StructureND<Double>> = - svd(structureND = structureND, epsilon = 1e-10) + svdGolubKahan(structureND = structureND, epsilon = 1e-10) override fun symEig(structureND: StructureND<Double>): Pair<DoubleTensor, DoubleTensor> = symEigJacobi(structureND = structureND, maxIteration = 50, epsilon = 1e-15) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index c559803ec..6e5456c62 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -7,10 +7,7 @@ package space.kscience.kmath.tensors.core.internal import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.DoubleBuffer -import space.kscience.kmath.structures.IntBuffer -import space.kscience.kmath.structures.asBuffer -import space.kscience.kmath.structures.indices +import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.core.* import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot @@ -316,6 +313,302 @@ internal fun DoubleTensorAlgebra.svdHelper( } } +private fun pythag(a: Double, b: Double): Double { + val at: Double = abs(a) + val bt: Double = abs(b) + val ct: Double + val result: Double + if (at > bt) { + ct = bt / at + result = at * sqrt(1.0 + ct * ct) + } else if (bt > 0.0) { + ct = at / bt + result = bt * sqrt(1.0 + ct * ct) + } else result = 0.0 + return result +} + +private fun SIGN(a: Double, b: Double): Double { + if (b >= 0.0) + return abs(a) + else + return -abs(a) +} + +internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2D<Double>, w: BufferedTensor<Double>, + v: MutableStructure2D<Double>, iterations: Int, epsilon: Double) { + val shape = this.shape + val m = shape.component1() + val n = shape.component2() + var f = 0.0 + val rv1 = DoubleArray(n) + var s = 0.0 + var scale = 0.0 + var anorm = 0.0 + var g = 0.0 + var l = 0 + + val wStart = 0 + val wBuffer = w.source + + for (i in 0 until n) { + /* left-hand reduction */ + l = i + 1 + rv1[i] = scale * g + g = 0.0 + s = 0.0 + scale = 0.0 + if (i < m) { + for (k in i until m) { + scale += abs(this[k, i]); + } + if (abs(scale) > epsilon) { + for (k in i until m) { + this[k, i] = (this[k, i] / scale) + s += this[k, i] * this[k, i] + } + f = this[i, i] + if (f >= 0) { + g = (-1) * abs(sqrt(s)) + } else { + g = abs(sqrt(s)) + } + val h = f * g - s + this[i, i] = f - g + if (i != n - 1) { + for (j in l until n) { + s = 0.0 + for (k in i until m) { + s += this[k, i] * this[k, j] + } + f = s / h + for (k in i until m) { + this[k, j] += f * this[k, i] + } + } + } + for (k in i until m) { + this[k, i] = this[k, i] * scale + } + } + } + + wBuffer[wStart + i] = scale * g + /* right-hand reduction */ + g = 0.0 + s = 0.0 + scale = 0.0 + if (i < m && i != n - 1) { + for (k in l until n) { + scale += abs(this[i, k]) + } + if (abs(scale) > epsilon) { + for (k in l until n) { + this[i, k] = this[i, k] / scale + s += this[i, k] * this[i, k] + } + f = this[i, l] + if (f >= 0) { + g = (-1) * abs(sqrt(s)) + } else { + g = abs(sqrt(s)) + } + val h = f * g - s + this[i, l] = f - g + for (k in l until n) { + rv1[k] = this[i, k] / h + } + if (i != m - 1) { + for (j in l until m) { + s = 0.0 + for (k in l until n) { + s += this[j, k] * this[i, k] + } + for (k in l until n) { + this[j, k] += s * rv1[k] + } + } + } + for (k in l until n) { + this[i, k] = this[i, k] * scale + } + } + } + anorm = max(anorm, (abs(wBuffer[wStart + i]) + abs(rv1[i]))); + } + + for (i in n - 1 downTo 0) { + if (i < n - 1) { + if (abs(g) > epsilon) { + for (j in l until n) { + v[j, i] = (this[i, j] / this[i, l]) / g + } + for (j in l until n) { + s = 0.0 + for (k in l until n) + s += this[i, k] * v[k, j] + for (k in l until n) + v[k, j] += s * v[k, i] + } + } + for (j in l until n) { + v[i, j] = 0.0 + v[j, i] = 0.0 + } + } + v[i, i] = 1.0 + g = rv1[i] + l = i + } + + for (i in min(n, m) - 1 downTo 0) { + l = i + 1 + g = wBuffer[wStart + i] + for (j in l until n) { + this[i, j] = 0.0 + } + if (abs(g) > epsilon) { + g = 1.0 / g + for (j in l until n) { + s = 0.0 + for (k in l until m) { + s += this[k, i] * this[k, j] + } + f = (s / this[i, i]) * g + for (k in i until m) { + this[k, j] += f * this[k, i] + } + } + for (j in i until m) { + this[j, i] *= g + } + } else { + for (j in i until m) { + this[j, i] = 0.0 + } + } + this[i, i] += 1.0 + } + + var flag = 0 + var nm = 0 + var c = 0.0 + var h = 0.0 + var y = 0.0 + var z = 0.0 + var x = 0.0 + for (k in n - 1 downTo 0) { + for (its in 1 until iterations) { + flag = 1 + for (newl in k downTo 0) { + nm = newl - 1 + if (abs(rv1[newl]) + anorm == anorm) { + flag = 0 + l = newl + break + } + if (abs(wBuffer[wStart + nm]) + anorm == anorm) { + l = newl + break + } + } + + if (flag != 0) { + c = 0.0 + s = 1.0 + for (i in l until k + 1) { + f = s * rv1[i] + rv1[i] = c * rv1[i] + if (abs(f) + anorm == anorm) { + break + } + g = wBuffer[wStart + i] + h = pythag(f, g) + wBuffer[wStart + i] = h + h = 1.0 / h + c = g * h + s = (-f) * h + for (j in 0 until m) { + y = this[j, nm] + z = this[j, i] + this[j, nm] = y * c + z * s + this[j, i] = z * c - y * s + } + } + } + + z = wBuffer[wStart + k] + if (l == k) { + if (z < 0.0) { + wBuffer[wStart + k] = -z + for (j in 0 until n) + v[j, k] = -v[j, k] + } + break + } + + x = wBuffer[wStart + l] + nm = k - 1 + y = wBuffer[wStart + nm] + g = rv1[nm] + h = rv1[k] + f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y) + g = pythag(f, 1.0) + f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x + c = 1.0 + s = 1.0 + + var i = 0 + for (j in l until nm + 1) { + i = j + 1 + g = rv1[i] + y = wBuffer[wStart + i] + h = s * g + g = c * g + z = pythag(f, h) + rv1[j] = z + c = f / z + s = h / z + f = x * c + g * s + g = g * c - x * s + h = y * s + y *= c + + for (jj in 0 until n) { + x = v[jj, j]; + z = v[jj, i]; + v[jj, j] = x * c + z * s; + v[jj, i] = z * c - x * s; + } + z = pythag(f, h) + wBuffer[wStart + j] = z + if (abs(z) > epsilon) { + z = 1.0 / z + c = f * z + s = h * z + } + f = c * g + s * y + x = c * y - s * g + for (jj in 0 until m) { + y = this[jj, j] + z = this[jj, i] + this[jj, j] = y * c + z * s + this[jj, i] = z * c - y * s + } + } + rv1[l] = 0.0 + rv1[k] = f + wBuffer[wStart + k] = x + } + } + + for (i in 0 until n) { + for (j in 0 until m) { + u[j, i] = this[j, i] + } + } +} + data class LMSettings ( var iteration:Int, var func_calls: Int, diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt index e5dc55f68..88ffb0bfe 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt @@ -212,6 +212,36 @@ public fun DoubleTensorAlgebra.svd( return Triple(uTensor.transposed(), sTensor, vTensor.transposed()) } +public fun DoubleTensorAlgebra.svdGolubKahan( + structureND: StructureND<Double>, + iterations: Int = 30, epsilon: Double = 1e-10 +): Triple<DoubleTensor, DoubleTensor, DoubleTensor> { + val size = structureND.dimension + val commonShape = structureND.shape.slice(0 until size - 2) + val (n, m) = structureND.shape.slice(size - 2 until size) + val uTensor = zeros(commonShape + intArrayOf(n, m)) + val sTensor = zeros(commonShape + intArrayOf(m)) + val vTensor = zeros(commonShape + intArrayOf(m, m)) + + val matrices = structureND.asDoubleTensor().matrices + val uTensors = uTensor.matrices + val sTensorVectors = sTensor.vectors + val vTensors = vTensor.matrices + + for (index in matrices.indices) { + val matrix = matrices[index] + val matrixSize = matrix.shape.linearSize + val curMatrix = DoubleTensor( + matrix.shape, + matrix.source.view(0, matrixSize).copy() + ) + curMatrix.as2D().svdGolubKahanHelper(uTensors[index].as2D(), sTensorVectors[index], vTensors[index].as2D(), + iterations, epsilon) + } + + return Triple(uTensor, sTensor, vTensor) +} + /** * Returns eigenvalues and eigenvectors of a real symmetric matrix input or a batch of real symmetric matrices, * represented by a pair `eigenvalues to eigenvectors`. From b526f9a476c3df4d65b945130beebba9f578e76d Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Thu, 4 May 2023 20:05:32 +0300 Subject: [PATCH 007/103] added Levenberg-Marquardt algorithm + test --- .../tensors/api/LinearOpsTensorAlgebra.kt | 8 + .../kmath/tensors/core/DoubleTensorAlgebra.kt | 369 +++++++++++++++++- .../tensors/core/TestDoubleTensorAlgebra.kt | 85 +++- 3 files changed, 455 insertions(+), 7 deletions(-) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt index 60865ecba..5cf0081fb 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt @@ -14,6 +14,8 @@ import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.map import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.transposed import space.kscience.kmath.tensors.core.DoubleTensorAlgebra +import space.kscience.kmath.tensors.core.internal.LMSettings +import kotlin.reflect.KFunction3 /** * Common linear algebra operations. Operates on [Tensor]. @@ -117,4 +119,10 @@ public interface LinearOpsTensorAlgebra<T, A : Field<T>> : TensorPartialDivision * @return the square matrix x which is the solution of the equation. */ public fun solve(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> + + public fun lm( + func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, + p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, + weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, + c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): Double } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 5325fe19e..e7e22afa9 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -9,6 +9,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall +import space.kscience.kmath.linear.transpose import space.kscience.kmath.nd.* import space.kscience.kmath.operations.DoubleBufferOps import space.kscience.kmath.operations.DoubleField @@ -17,10 +18,8 @@ import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.core.internal.* -import kotlin.math.abs -import kotlin.math.ceil -import kotlin.math.floor -import kotlin.math.sqrt +import kotlin.math.* +import kotlin.reflect.KFunction3 /** * Implementation of basic operations over double tensors and basic algebra operations on them. @@ -717,6 +716,368 @@ public open class DoubleTensorAlgebra : val aInverse = aSvd.third.dot(s).dot(aSvd.first.transposed()) return aInverse.dot(b).as2D() } + + override fun lm( + func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, + p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, + weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, + c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): Double { + + var result_chi_sq = 0.0 + + val tensor_parameter = 0 + val eps:Double = 2.2204e-16 + + var settings = LMSettings(0, 0, example_number) + settings.func_calls = 0 // running count of function evaluations + + var p = p_input + val y_dat = y_dat_input + val t = t_input + + val Npar = length(p) // number of parameters + val Npnt = length(y_dat) // number of data points + var p_old = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters + var y_old = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) + var X2 = 1e-3 / eps // a really big initial Chi-sq value + var X2_old = 1e-3 / eps // a really big initial Chi-sq value + var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix + val DoF = Npnt - Npar + 1 // statistical degrees of freedom + + var corr_p = 0 + var sigma_p = 0 + var sigma_y = 0 + var R_sq = 0 + var cvg_hist = 0 + + if (length(t) != length(y_dat)) { + println("lm.m error: the length of t must equal the length of y_dat") + val length_t = length(t) + val length_y_dat = length(y_dat) + X2 = 0.0 + + corr_p = 0 + sigma_p = 0 + sigma_y = 0 + R_sq = 0 + cvg_hist = 0 + +// if (tensor_parameter != 0) { // Зачем эта проверка? +// return +// } + } + + var weight = weight_input + if (nargin < 5) { + weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf((y_dat.transpose().dot(y_dat)).as1D()[0])).as2D() + } + + var dp = dp_input + if (nargin < 6) { + dp = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.001)).as2D() + } + + var p_min = p_min_input + if (nargin < 7) { + p_min = p + p_min.abs() + p_min = p_min.div(-100.0).as2D() + } + + var p_max = p_max_input + if (nargin < 8) { + p_max = p + p_max.abs() + p_max = p_max.div(100.0).as2D() + } + + var c = c_input + if (nargin < 9) { + c = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(1.0)).as2D() + } + + var opts = opts_input + if (nargin < 10) { + opts = doubleArrayOf(3.0, 10.0 * Npar, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) + } + + val prnt = opts[0] // >1 intermediate results; >2 plots + val MaxIter = opts[1].toInt() // maximum number of iterations + val epsilon_1 = opts[2] // convergence tolerance for gradient + val epsilon_2 = opts[3] // convergence tolerance for parameters + val epsilon_3 = opts[4] // convergence tolerance for Chi-square + val epsilon_4 = opts[5] // determines acceptance of a L-M step + val lambda_0 = opts[6] // initial value of damping paramter, lambda + val lambda_UP_fac = opts[7] // factor for increasing lambda + val lambda_DN_fac = opts[8] // factor for decreasing lambda + val Update_Type = opts[9].toInt() // 1: Levenberg-Marquardt lambda update + // 2: Quadratic update + // 3: Nielsen's lambda update equations + + val plotcmd = "figure(102); plot(t(:,1),y_init,''-k'',t(:,1),y_hat,''-b'',t(:,1),y_dat,''o'',''color'',[0,0.6,0],''MarkerSize'',4); title(sprintf(''\\chi^2_\\nu = %f'',X2/DoF)); drawnow" + + p_min = make_column(p_min) + p_max = make_column(p_max) + + if (length(make_column(dp)) == 1) { + dp = ones(ShapeND(intArrayOf(Npar, 1))).div(1 / dp[0, 0]).as2D() + } + + val idx = get_zero_indices(dp) // indices of the parameters to be fit + val Nfit = idx?.shape?.component1() // number of parameters to fit + var stop = false // termination flag + val y_init = feval(func, t, p, settings) // residual error using p_try + + if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector + weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / kotlin.math.abs(weight[0, 0])).as2D() // !!! need to check + println("using uniform weights for error analysis") + } + else { + weight = make_column(weight) + weight.abs() + } + + // initialize Jacobian with finite difference calculation + var lm_matx_ans = lm_matx(func, t, p_old, y_old,1, J, p, y_dat, weight, dp, settings) + var JtWJ = lm_matx_ans[0] + var JtWdy = lm_matx_ans[1] + X2 = lm_matx_ans[2][0, 0] + var y_hat = lm_matx_ans[3] + J = lm_matx_ans[4] + + if ( abs(JtWdy).max()!! < epsilon_1 ) { + println(" *** Your Initial Guess is Extremely Close to Optimal ***\n") + println(" *** epsilon_1 = %e\n$epsilon_1") + stop = true + } + + var lambda = 1.0 + var nu = 1 + when (Update_Type) { + 1 -> lambda = lambda_0 // Marquardt: init'l lambda + else -> { // Quadratic and Nielsen + lambda = lambda_0 * (diag(JtWJ)).max()!! + nu = 2 + } + } + + X2_old = X2 // previous value of X2 + var cvg_hst = ones(ShapeND(intArrayOf(MaxIter, Npar + 3))) // initialize convergence history + + var h = JtWJ.copyToTensor() + var dX2 = X2 + while (!stop && settings.iteration <= MaxIter) { //--- Start Main Loop + settings.iteration += 1 + + // incremental change in parameters + h = when (Update_Type) { + 1 -> { // Marquardt + val solve = solve(JtWJ.plus(make_matrx_with_diagonal(diag(JtWJ)).div(1 / lambda)).as2D(), JtWdy) + solve.asDoubleTensor() + } + + else -> { // Quadratic and Nielsen + val solve = solve(JtWJ.plus(lm_eye(Npar).div(1 / lambda)).as2D(), JtWdy) + solve.asDoubleTensor() + } + } + + // big = max(abs(h./p)) > 2; % this is a big step + + // --- Are parameters [p+h] much better than [p] ? + + var p_try = (p + h).as2D() // update the [idx] elements + p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try.as2D()), p_max) // apply constraints + + var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try + + // TODO + //if ~all(isfinite(delta_y)) // floating point error; break + // stop = 1; + // break + //end + + settings.func_calls += 1 + + val tmp = delta_y.times(weight) + var X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria + + val alpha = 1.0 + if (Update_Type == 2) { // Quadratic + // One step of quadratic line update in the h direction for minimum X2 + +// TODO +// val alpha = JtWdy.transpose().dot(h) / ((X2_try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h))) +// alpha = JtWdy'*h / ( (X2_try - X2)/2 + 2*JtWdy'*h ) ; +// h = alpha * h; +// +// p_try = p + h(idx); % update only [idx] elements +// p_try = min(max(p_min,p_try),p_max); % apply constraints +// +// delta_y = y_dat - feval(func,t,p_try,c); % residual error using p_try +// func_calls = func_calls + 1; +// тX2_try = delta_y' * ( delta_y .* weight ); % Chi-squared error criteria + } + + val rho = when (Update_Type) { // Nielsen + 1 -> { + val tmp = h.transposed().dot(make_matrx_with_diagonal(diag(JtWJ)).div(1 / lambda).dot(h).plus(JtWdy)) + X2.minus(X2_try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] + } + else -> { + val tmp = h.transposed().dot(h.div(1 / lambda).plus(JtWdy)) + X2.minus(X2_try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] + } + } + + println() + println("rho = " + rho) + + if (rho > epsilon_4) { // it IS significantly better + val dX2 = X2.minus(X2_old) + X2_old = X2 + p_old = p.copyToTensor().as2D() + y_old = y_hat.copyToTensor().as2D() + p = make_column(p_try) // accept p_try + + lm_matx_ans = lm_matx(func, t, p_old, y_old, dX2.toInt(), J, p, y_dat, weight, dp, settings) + // decrease lambda ==> Gauss-Newton method + + JtWJ = lm_matx_ans[0] + JtWdy = lm_matx_ans[1] + X2 = lm_matx_ans[2][0, 0] + y_hat = lm_matx_ans[3] + J = lm_matx_ans[4] + + lambda = when (Update_Type) { + 1 -> { // Levenberg + max(lambda / lambda_DN_fac, 1e-7); + } + 2 -> { // Quadratic + max( lambda / (1 + alpha) , 1e-7 ); + } + else -> { // Nielsen + nu = 2 + lambda * max( 1.0 / 3, 1 - (2 * rho - 1).pow(3) ) + } + } + + // if (prnt > 2) { + // eval(plotcmd) + // } + } + else { // it IS NOT better + X2 = X2_old // do not accept p_try + if (settings.iteration % (2 * Npar) == 0 ) { // rank-1 update of Jacobian + lm_matx_ans = lm_matx(func, t, p_old, y_old,-1, J, p, y_dat, weight, dp, settings) + JtWJ = lm_matx_ans[0] + JtWdy = lm_matx_ans[1] + dX2 = lm_matx_ans[2][0, 0] + y_hat = lm_matx_ans[3] + J = lm_matx_ans[4] + } + + // increase lambda ==> gradient descent method + lambda = when (Update_Type) { + 1 -> { // Levenberg + min(lambda * lambda_UP_fac, 1e7) + } + 2 -> { // Quadratic + lambda + abs(((X2_try.as2D()[0, 0] - X2) / 2) / alpha) + } + else -> { // Nielsen + nu *= 2 + lambda * (nu / 2) + } + } + } + + if (prnt > 1) { + val chi_sq = X2 / DoF + println("Iteration $settings.iteration, func_calls $settings.func_calls | chi_sq=$chi_sq | lambda=$lambda") + print("param: ") + for (pn in 0 until Npar) { + print(p[pn, 0].toString() + " ") + } + print("\ndp/p: ") + for (pn in 0 until Npar) { + print((h.as2D()[pn, 0] / p[pn, 0]).toString() + " ") + } + result_chi_sq = chi_sq + } + + // update convergence history ... save _reduced_ Chi-square + // cvg_hst(iteration,:) = [ func_calls p' X2/DoF lambda ]; + + if (abs(JtWdy).max()!! < epsilon_1 && settings.iteration > 2) { + println(" **** Convergence in r.h.s. (\"JtWdy\") ****") + println(" **** epsilon_1 = $epsilon_1") + stop = true + } + if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon_2 && settings.iteration > 2) { + println(" **** Convergence in Parameters ****") + println(" **** epsilon_2 = $epsilon_2") + stop = true + } + if (X2 / DoF < epsilon_3 && settings.iteration > 2) { + println(" **** Convergence in reduced Chi-square **** ") + println(" **** epsilon_3 = $epsilon_3") + stop = true + } + if (settings.iteration == MaxIter) { + println(" !! Maximum Number of Iterations Reached Without Convergence !!") + stop = true + } + } // --- End of Main Loop + + // --- convergence achieved, find covariance and confidence intervals + + // ---- Error Analysis ---- + +// if (weight.shape.component1() == 1 || weight.variance() == 0.0) { +// weight = DoF / (delta_y.transpose().dot(delta_y)) * ones(intArrayOf(Npt, 1)) +// } + +// if (nargout > 1) { +// val redX2 = X2 / DoF +// } +// +// lm_matx_ans = lm_matx(func, t, p_old, y_old, -1, J, p, y_dat, weight, dp) +// JtWJ = lm_matx_ans[0] +// JtWdy = lm_matx_ans[1] +// X2 = lm_matx_ans[2][0, 0] +// y_hat = lm_matx_ans[3] +// J = lm_matx_ans[4] +// +// if (nargout > 2) { // standard error of parameters +// covar_p = inv(JtWJ); +// siif nagma_p = sqrt(diag(covar_p)); +// } +// +// if (nargout > 3) { // standard error of the fit +// /// sigma_y = sqrt(diag(J * covar_p * J')); // slower version of below +// sigma_y = zeros(Npnt,1); +// for i=1:Npnt +// sigma_y(i) = J(i,:) * covar_p * J(i,:)'; +// end +// sigma_y = sqrt(sigma_y); +// } +// +// if (nargout > 4) { // parameter correlation matrix +// corr_p = covar_p ./ [sigma_p*sigma_p']; +// } +// +// if (nargout > 5) { // coefficient of multiple determination +// R_sq = corr([y_dat y_hat]); +// R_sq = R_sq(1,2).^2; +// } +// +// if (nargout > 6) { // convergence history +// cvg_hst = cvg_hst(1:iteration,:); +// } + + return result_chi_sq + } } public val Double.Companion.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt index cae01bed8..2c3b3a231 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt @@ -6,11 +6,11 @@ package space.kscience.kmath.tensors.core -import space.kscience.kmath.nd.ShapeND -import space.kscience.kmath.nd.contentEquals -import space.kscience.kmath.nd.get +import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke +import space.kscience.kmath.tensors.core.internal.LMSettings import space.kscience.kmath.testutils.assertBufferEquals +import kotlin.math.roundToInt import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -207,4 +207,83 @@ internal class TestDoubleTensorAlgebra { assertTrue { ShapeND(5, 5) contentEquals res.shape } assertEquals(2.0, res[4, 4]) } + + @Test + fun testLM() = DoubleTensorAlgebra { + fun lm_func(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + val m = t.shape.component1() + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) + + if (settings.example_number == 1) { + y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( + DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) + ) + } + else if (settings.example_number == 2) { + val mt = t.max() + y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + + (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + + (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + + (t.times(1.0 / mt)).pow(4).times(p[3, 0]) + } + else if (settings.example_number == 3) { + y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) + .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) + } + + return y_hat.as2D() + } + + val lm_matx_y_dat = doubleArrayOf( + 19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807, + 14.7620, 15.1128, 16.0973, 15.1934, 15.8636, 15.4763, 15.6860, 15.1895, 15.3495, 16.6054, + 16.2247, 15.9854, 16.1421, 17.0960, 16.7769, 17.1997, 17.2767, 17.5882, 17.5378, 16.7894, + 17.7648, 18.2512, 18.1581, 16.7037, 17.8475, 17.9081, 18.3067, 17.9632, 18.2817, 19.1427, + 18.8130, 18.5658, 18.0056, 18.4607, 18.5918, 18.2544, 18.3731, 18.7511, 19.3181, 17.3066, + 17.9632, 19.0513, 18.7528, 18.2928, 18.5967, 17.8567, 17.7859, 18.4016, 18.9423, 18.4959, + 17.8000, 18.4251, 17.7829, 17.4645, 17.5221, 17.3517, 17.4637, 17.7563, 16.8471, 17.4558, + 17.7447, 17.1487, 17.3183, 16.8312, 17.7551, 17.0942, 15.6093, 16.4163, 15.3755, 16.6725, + 16.2332, 16.2316, 16.2236, 16.5361, 15.3721, 15.3347, 15.5815, 15.6319, 14.4538, 14.6044, + 14.7665, 13.3718, 15.0587, 13.8320, 14.7873, 13.6824, 14.2579, 14.2154, 13.5818, 13.8157 + ) + + var example_number = 1 + val p_init = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(5.0, 2.0, 0.2, 10.0) + ).as2D() + + var t = ones(ShapeND(intArrayOf(100, 1))).as2D() + for (i in 0 until 100) { + t[i, 0] = t[i, 0] * (i + 1) + } + + val y_dat = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(100, 1)), lm_matx_y_dat + ).as2D() + + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 4.0 } + ).as2D() + + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + + val p_min = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(-50.0, -20.0, -2.0, -100.0) + ).as2D() + + val p_max = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0) + ).as2D() + + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + + val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) + + val chi_sq = lm(::lm_func, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts, 10, example_number) + assertEquals(0.9131, (chi_sq * 10000).roundToInt() / 10000.0) + } } From 64e563340a04b1f8f1ccb3e0c78921ef479aeb7c Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Sun, 7 May 2023 17:26:59 +0300 Subject: [PATCH 008/103] fixed error for chi_sq and added more complete output for lm --- .../tensors/api/LinearOpsTensorAlgebra.kt | 11 +++++- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 38 ++++++++----------- .../tensors/core/TestDoubleTensorAlgebra.kt | 9 ++++- 3 files changed, 32 insertions(+), 26 deletions(-) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt index 5cf0081fb..3c74263ec 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt @@ -120,9 +120,18 @@ public interface LinearOpsTensorAlgebra<T, A : Field<T>> : TensorPartialDivision */ public fun solve(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> + data class LMResultInfo ( + var iterations:Int, + var func_calls: Int, + var example_number: Int, + var result_chi_sq: Double, + var result_lambda: Double, + var result_parameters: MutableStructure2D<Double> + ) + public fun lm( func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, - c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): Double + c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LMResultInfo } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index e7e22afa9..21a034676 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -721,9 +721,9 @@ public open class DoubleTensorAlgebra : func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, - c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): Double { + c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LinearOpsTensorAlgebra.LMResultInfo { - var result_chi_sq = 0.0 + var resultInfo = LinearOpsTensorAlgebra.LMResultInfo(0, 0, example_number, 0.0, 0.0, p_input) val tensor_parameter = 0 val eps:Double = 2.2204e-16 @@ -742,7 +742,7 @@ public open class DoubleTensorAlgebra : var X2 = 1e-3 / eps // a really big initial Chi-sq value var X2_old = 1e-3 / eps // a really big initial Chi-sq value var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix - val DoF = Npnt - Npar + 1 // statistical degrees of freedom + val DoF = Npnt - Npar // statistical degrees of freedom var corr_p = 0 var sigma_p = 0 @@ -811,10 +811,8 @@ public open class DoubleTensorAlgebra : val lambda_UP_fac = opts[7] // factor for increasing lambda val lambda_DN_fac = opts[8] // factor for decreasing lambda val Update_Type = opts[9].toInt() // 1: Levenberg-Marquardt lambda update - // 2: Quadratic update - // 3: Nielsen's lambda update equations - - val plotcmd = "figure(102); plot(t(:,1),y_init,''-k'',t(:,1),y_hat,''-b'',t(:,1),y_dat,''o'',''color'',[0,0.6,0],''MarkerSize'',4); title(sprintf(''\\chi^2_\\nu = %f'',X2/DoF)); drawnow" + // 2: Quadratic update + // 3: Nielsen's lambda update equations p_min = make_column(p_min) p_max = make_column(p_max) @@ -829,7 +827,7 @@ public open class DoubleTensorAlgebra : val y_init = feval(func, t, p, settings) // residual error using p_try if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector - weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / kotlin.math.abs(weight[0, 0])).as2D() // !!! need to check + weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / abs(weight[0, 0])).as2D() // !!! need to check println("using uniform weights for error analysis") } else { @@ -864,7 +862,7 @@ public open class DoubleTensorAlgebra : X2_old = X2 // previous value of X2 var cvg_hst = ones(ShapeND(intArrayOf(MaxIter, Npar + 3))) // initialize convergence history - var h = JtWJ.copyToTensor() + var h: DoubleTensor var dX2 = X2 while (!stop && settings.iteration <= MaxIter) { //--- Start Main Loop settings.iteration += 1 @@ -882,10 +880,6 @@ public open class DoubleTensorAlgebra : } } - // big = max(abs(h./p)) > 2; % this is a big step - - // --- Are parameters [p+h] much better than [p] ? - var p_try = (p + h).as2D() // update the [idx] elements p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try.as2D()), p_max) // apply constraints @@ -961,10 +955,6 @@ public open class DoubleTensorAlgebra : lambda * max( 1.0 / 3, 1 - (2 * rho - 1).pow(3) ) } } - - // if (prnt > 2) { - // eval(plotcmd) - // } } else { // it IS NOT better X2 = X2_old // do not accept p_try @@ -994,7 +984,7 @@ public open class DoubleTensorAlgebra : if (prnt > 1) { val chi_sq = X2 / DoF - println("Iteration $settings.iteration, func_calls $settings.func_calls | chi_sq=$chi_sq | lambda=$lambda") + println("Iteration $settings | chi_sq=$chi_sq | lambda=$lambda") print("param: ") for (pn in 0 until Npar) { print(p[pn, 0].toString() + " ") @@ -1003,7 +993,11 @@ public open class DoubleTensorAlgebra : for (pn in 0 until Npar) { print((h.as2D()[pn, 0] / p[pn, 0]).toString() + " ") } - result_chi_sq = chi_sq + resultInfo.iterations = settings.iteration + resultInfo.func_calls = settings.func_calls + resultInfo.result_chi_sq = chi_sq + resultInfo.result_lambda = lambda + resultInfo.result_parameters = p } // update convergence history ... save _reduced_ Chi-square @@ -1076,11 +1070,9 @@ public open class DoubleTensorAlgebra : // cvg_hst = cvg_hst(1:iteration,:); // } - return result_chi_sq + return resultInfo } } public val Double.Companion.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra -public val DoubleField.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra - - +public val DoubleField.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra \ No newline at end of file diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt index 2c3b3a231..e5c35f8fd 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt @@ -11,6 +11,7 @@ import space.kscience.kmath.operations.invoke import space.kscience.kmath.tensors.core.internal.LMSettings import space.kscience.kmath.testutils.assertBufferEquals import kotlin.math.roundToInt +import kotlin.math.roundToLong import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -283,7 +284,11 @@ internal class TestDoubleTensorAlgebra { val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) - val chi_sq = lm(::lm_func, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts, 10, example_number) - assertEquals(0.9131, (chi_sq * 10000).roundToInt() / 10000.0) + val result = lm(::lm_func, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts, 10, example_number) + assertEquals(13, result.iterations) + assertEquals(31, result.func_calls) + assertEquals(1, result.example_number) + assertEquals(0.9131368192633, (result.result_chi_sq * 1e13).roundToLong() / 1e13) + assertEquals(3.7790980 * 1e-7, (result.result_lambda * 1e13).roundToLong() / 1e13) } } From cfe8e9bfee19974d083bfd653a25ed1e8f301dd9 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Sun, 7 May 2023 21:34:20 +0300 Subject: [PATCH 009/103] done TODOs, deleted prints and added type of convergence to output of lm --- .../tensors/api/LinearOpsTensorAlgebra.kt | 13 ++- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 95 ++++++++++--------- .../tensors/core/TestDoubleTensorAlgebra.kt | 2 + 3 files changed, 62 insertions(+), 48 deletions(-) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt index 3c74263ec..7964656f1 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt @@ -120,13 +120,22 @@ public interface LinearOpsTensorAlgebra<T, A : Field<T>> : TensorPartialDivision */ public fun solve(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> - data class LMResultInfo ( + public enum class TypeOfConvergence{ + inRHS_JtWdy, + inParameters, + inReducedChi_square, + noConvergence + } + + public data class LMResultInfo ( var iterations:Int, var func_calls: Int, var example_number: Int, var result_chi_sq: Double, var result_lambda: Double, - var result_parameters: MutableStructure2D<Double> + var result_parameters: MutableStructure2D<Double>, + var typeOfConvergence: TypeOfConvergence, + var epsilon: Double ) public fun lm( diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 21a034676..43f097564 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -723,9 +723,9 @@ public open class DoubleTensorAlgebra : weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LinearOpsTensorAlgebra.LMResultInfo { - var resultInfo = LinearOpsTensorAlgebra.LMResultInfo(0, 0, example_number, 0.0, 0.0, p_input) + var resultInfo = LinearOpsTensorAlgebra.LMResultInfo(0, 0, example_number, 0.0, + 0.0, p_input, LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence, 0.0) - val tensor_parameter = 0 val eps:Double = 2.2204e-16 var settings = LMSettings(0, 0, example_number) @@ -751,7 +751,7 @@ public open class DoubleTensorAlgebra : var cvg_hist = 0 if (length(t) != length(y_dat)) { - println("lm.m error: the length of t must equal the length of y_dat") + // println("lm.m error: the length of t must equal the length of y_dat") val length_t = length(t) val length_y_dat = length(y_dat) X2 = 0.0 @@ -761,10 +761,6 @@ public open class DoubleTensorAlgebra : sigma_y = 0 R_sq = 0 cvg_hist = 0 - -// if (tensor_parameter != 0) { // Зачем эта проверка? -// return -// } } var weight = weight_input @@ -827,8 +823,8 @@ public open class DoubleTensorAlgebra : val y_init = feval(func, t, p, settings) // residual error using p_try if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector - weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / abs(weight[0, 0])).as2D() // !!! need to check - println("using uniform weights for error analysis") + weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / abs(weight[0, 0])).as2D() + // println("using uniform weights for error analysis") } else { weight = make_column(weight) @@ -844,8 +840,8 @@ public open class DoubleTensorAlgebra : J = lm_matx_ans[4] if ( abs(JtWdy).max()!! < epsilon_1 ) { - println(" *** Your Initial Guess is Extremely Close to Optimal ***\n") - println(" *** epsilon_1 = %e\n$epsilon_1") +// println(" *** Your Initial Guess is Extremely Close to Optimal ***\n") +// println(" *** epsilon_1 = %e\n$epsilon_1") stop = true } @@ -885,11 +881,14 @@ public open class DoubleTensorAlgebra : var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try - // TODO - //if ~all(isfinite(delta_y)) // floating point error; break - // stop = 1; - // break - //end + for (i in 0 until delta_y.shape.component1()) { // floating point error; break + for (j in 0 until delta_y.shape.component2()) { + if (delta_y[i, j] == Double.POSITIVE_INFINITY || delta_y[i, j] == Double.NEGATIVE_INFINITY) { + stop = true + break + } + } + } settings.func_calls += 1 @@ -900,17 +899,16 @@ public open class DoubleTensorAlgebra : if (Update_Type == 2) { // Quadratic // One step of quadratic line update in the h direction for minimum X2 -// TODO -// val alpha = JtWdy.transpose().dot(h) / ((X2_try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h))) -// alpha = JtWdy'*h / ( (X2_try - X2)/2 + 2*JtWdy'*h ) ; -// h = alpha * h; -// -// p_try = p + h(idx); % update only [idx] elements -// p_try = min(max(p_min,p_try),p_max); % apply constraints -// -// delta_y = y_dat - feval(func,t,p_try,c); % residual error using p_try -// func_calls = func_calls + 1; -// тX2_try = delta_y' * ( delta_y .* weight ); % Chi-squared error criteria + val alpha = JtWdy.transpose().dot(h) / ( (X2_try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h)) ) + h = h.dot(alpha) + p_try = p.plus(h).as2D() // update only [idx] elements + p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try), p_max) // apply constraints + + var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try + settings.func_calls += 1 + + val tmp = delta_y.times(weight) + X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria } val rho = when (Update_Type) { // Nielsen @@ -924,9 +922,6 @@ public open class DoubleTensorAlgebra : } } - println() - println("rho = " + rho) - if (rho > epsilon_4) { // it IS significantly better val dX2 = X2.minus(X2_old) X2_old = X2 @@ -984,15 +979,15 @@ public open class DoubleTensorAlgebra : if (prnt > 1) { val chi_sq = X2 / DoF - println("Iteration $settings | chi_sq=$chi_sq | lambda=$lambda") - print("param: ") - for (pn in 0 until Npar) { - print(p[pn, 0].toString() + " ") - } - print("\ndp/p: ") - for (pn in 0 until Npar) { - print((h.as2D()[pn, 0] / p[pn, 0]).toString() + " ") - } +// println("Iteration $settings | chi_sq=$chi_sq | lambda=$lambda") +// print("param: ") +// for (pn in 0 until Npar) { +// print(p[pn, 0].toString() + " ") +// } +// print("\ndp/p: ") +// for (pn in 0 until Npar) { +// print((h.as2D()[pn, 0] / p[pn, 0]).toString() + " ") +// } resultInfo.iterations = settings.iteration resultInfo.func_calls = settings.func_calls resultInfo.result_chi_sq = chi_sq @@ -1004,22 +999,30 @@ public open class DoubleTensorAlgebra : // cvg_hst(iteration,:) = [ func_calls p' X2/DoF lambda ]; if (abs(JtWdy).max()!! < epsilon_1 && settings.iteration > 2) { - println(" **** Convergence in r.h.s. (\"JtWdy\") ****") - println(" **** epsilon_1 = $epsilon_1") +// println(" **** Convergence in r.h.s. (\"JtWdy\") ****") +// println(" **** epsilon_1 = $epsilon_1") + resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inRHS_JtWdy + resultInfo.epsilon = epsilon_1 stop = true } if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon_2 && settings.iteration > 2) { - println(" **** Convergence in Parameters ****") - println(" **** epsilon_2 = $epsilon_2") +// println(" **** Convergence in Parameters ****") +// println(" **** epsilon_2 = $epsilon_2") + resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inParameters + resultInfo.epsilon = epsilon_2 stop = true } if (X2 / DoF < epsilon_3 && settings.iteration > 2) { - println(" **** Convergence in reduced Chi-square **** ") - println(" **** epsilon_3 = $epsilon_3") +// println(" **** Convergence in reduced Chi-square **** ") +// println(" **** epsilon_3 = $epsilon_3") + resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inReducedChi_square + resultInfo.epsilon = epsilon_3 stop = true } if (settings.iteration == MaxIter) { - println(" !! Maximum Number of Iterations Reached Without Convergence !!") +// println(" !! Maximum Number of Iterations Reached Without Convergence !!") + resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence + resultInfo.epsilon = 0.0 stop = true } } // --- End of Main Loop diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt index e5c35f8fd..85b81524b 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt @@ -8,6 +8,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke +import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra import space.kscience.kmath.tensors.core.internal.LMSettings import space.kscience.kmath.testutils.assertBufferEquals import kotlin.math.roundToInt @@ -290,5 +291,6 @@ internal class TestDoubleTensorAlgebra { assertEquals(1, result.example_number) assertEquals(0.9131368192633, (result.result_chi_sq * 1e13).roundToLong() / 1e13) assertEquals(3.7790980 * 1e-7, (result.result_lambda * 1e13).roundToLong() / 1e13) + assertEquals(result.typeOfConvergence, LinearOpsTensorAlgebra.TypeOfConvergence.inParameters) } } From 1316e6548ed71ff2ebd4fe3afeb910349af22310 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 9 May 2023 19:01:37 +0300 Subject: [PATCH 010/103] Remove vector type from polygon --- docs/templates/README-TEMPLATE.md | 13 +++++-------- .../kotlin/space/kscience/kmath/geometry/Polygon.kt | 4 ++-- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/docs/templates/README-TEMPLATE.md b/docs/templates/README-TEMPLATE.md index d7d5a806d..8988a887e 100644 --- a/docs/templates/README-TEMPLATE.md +++ b/docs/templates/README-TEMPLATE.md @@ -59,22 +59,21 @@ ${modules} KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the [common source sets](/kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features are delegated to platform-specific implementations even if they could be provided in the common module for performance -reasons. Currently, the Kotlin/JVM is the primary platform, however Kotlin/Native and Kotlin/JS contributions and +reasons. Currently, Kotlin/JVM is the primary platform, however, Kotlin/Native and Kotlin/JS contributions and feedback are also welcome. ## Performance -Calculation performance is one of major goals of KMath in the future, but in some cases it is impossible to achieve both +Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to achieve both performance and flexibility. -We expect to focus on creating convenient universal API first and then work on increasing performance for specific +We expect to focus on creating a convenient universal API first and then work on increasing performance for specific cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy. ## Requirements -KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend to use GraalVM-CE 11 for -execution to get better performance. +KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE 11/17 for execution to get better performance. ### Repositories @@ -94,11 +93,9 @@ dependencies { } ``` -Gradle `6.0+` is required for multiplatform artifacts. - ## Contributing The project requires a lot of additional work. The most important thing we need is a feedback about what features are required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues marked with -[waiting for a hero](https://github.com/mipt-npm/kmath/labels/waiting%20for%20a%20hero) label. \ No newline at end of file +[good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label. \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt index 20f4a031e..0d82f865c 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt @@ -9,6 +9,6 @@ package space.kscience.kmath.geometry /** * A closed polygon in 2D space */ -public interface Polygon<T> { - public val points: List<Vector2D<T>> +public interface Polygon<V: Any> { + public val points: List<V> } \ No newline at end of file From 3e9d28be315447754ee5d9de2a3f1af10f1dc5c0 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 26 May 2023 11:38:50 +0300 Subject: [PATCH 011/103] Update build tools --- build.gradle.kts | 2 +- gradle.properties | 2 +- kmath-complex/build.gradle.kts | 18 +----------------- kmath-core/build.gradle.kts | 17 +---------------- .../kscience/kmath/streaming/BufferFlow.kt | 2 ++ kmath-functions/build.gradle.kts | 18 ++---------------- kmath-memory/build.gradle.kts | 17 +---------------- 7 files changed, 9 insertions(+), 67 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index fb2f7d8c7..aed79909c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -72,7 +72,7 @@ ksciencePublish { "https://maven.pkg.jetbrains.space/spc/p/sci/maven" } ) - sonatype() + sonatype("https://oss.sonatype.org") } apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI") diff --git a/gradle.properties b/gradle.properties index e33106c0c..fee75d428 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ kotlin.native.ignoreDisabledTargets=true org.gradle.configureondemand=true org.gradle.jvmargs=-Xmx4096m -toolsVersion=0.14.6-kotlin-1.8.20 +toolsVersion=0.14.8-kotlin-1.8.20 org.gradle.parallel=true diff --git a/kmath-complex/build.gradle.kts b/kmath-complex/build.gradle.kts index 0611e9aae..2f8c320cf 100644 --- a/kmath-complex/build.gradle.kts +++ b/kmath-complex/build.gradle.kts @@ -7,23 +7,7 @@ kscience { js() native() - wasm{ - browser { - testTask { - useKarma { - this.webpackConfig.experiments.add("topLevelAwait") - useChromeHeadless() - useConfigDirectory(project.projectDir.resolve("karma.config.d").resolve("wasm")) - } - } - } - } - - wasmTest{ - dependencies { - implementation(kotlin("test")) - } - } + wasm() dependencies { api(projects.kmathCore) diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index 8c622e8b0..2088e0159 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -6,22 +6,7 @@ kscience{ jvm() js() native() - wasm{ - browser { - testTask { - useKarma { - webpackConfig.experiments.add("topLevelAwait") - useChromeHeadless() - } - } - } - } - - wasmTest{ - dependencies { - implementation(kotlin("test")) - } - } + wasm() dependencies { api(projects.kmathMemory) diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt index ccd329064..2cc8b8393 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.streaming +import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow @@ -25,6 +26,7 @@ public fun <T> Buffer<T>.asFlow(): Flow<T> = iterator().asFlow() /** * Flat map a [Flow] of [Buffer] into continuous [Flow] of elements */ +@OptIn(ExperimentalCoroutinesApi::class) public fun <T> Flow<Buffer<T>>.spread(): Flow<T> = flatMapConcat { it.asFlow() } /** diff --git a/kmath-functions/build.gradle.kts b/kmath-functions/build.gradle.kts index acabd1eb9..4ec52f5ee 100644 --- a/kmath-functions/build.gradle.kts +++ b/kmath-functions/build.gradle.kts @@ -7,23 +7,9 @@ kscience{ js() native() - wasm{ - browser { - testTask { - useKarma { - this.webpackConfig.experiments.add("topLevelAwait") - useChromeHeadless() - useConfigDirectory(project.projectDir.resolve("karma.config.d").resolve("wasm")) - } - } - } - } + wasm() + - wasmTest{ - dependencies { - implementation(kotlin("test")) - } - } dependencies { api(projects.kmathCore) diff --git a/kmath-memory/build.gradle.kts b/kmath-memory/build.gradle.kts index 8c1e63cb7..fe422f751 100644 --- a/kmath-memory/build.gradle.kts +++ b/kmath-memory/build.gradle.kts @@ -6,22 +6,7 @@ kscience { jvm() js() native() - wasm{ - browser { - testTask { - useKarma { - webpackConfig.experiments.add("topLevelAwait") - useChromeHeadless() - } - } - } - } - - wasmTest{ - dependencies { - implementation(kotlin("test")) - } - } + wasm() } readme { From 65c696254408c960f3b83ce1f909b1cf69f9f526 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 26 May 2023 16:46:18 +0300 Subject: [PATCH 012/103] Update build tools --- build.gradle.kts | 2 +- gradle.properties | 6 +++--- .../space/kscience/kmath/ast/rendering/TestFeatures.kt | 2 +- .../kscience/kmath/internal/binaryen/index.binaryen.kt | 1 - kmath-complex/build.gradle.kts | 1 - kmath-memory/build.gradle.kts | 5 +++++ .../kotlin/space/kscience/kmath/memory/NativeMemory.kt | 4 ++++ 7 files changed, 14 insertions(+), 7 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index aed79909c..7dbe87445 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ allprojects { } group = "space.kscience" - version = "0.3.1" + version = "0.3.2-dev-1" } subprojects { diff --git a/gradle.properties b/gradle.properties index fee75d428..76f51c4af 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,8 +9,8 @@ kotlin.native.ignoreDisabledTargets=true org.gradle.configureondemand=true org.gradle.jvmargs=-Xmx4096m -toolsVersion=0.14.8-kotlin-1.8.20 - - org.gradle.parallel=true org.gradle.workers.max=4 + +toolsVersion=0.14.8-kotlin-1.9.0-Beta +#kscience.wasm.disabled=true \ No newline at end of file diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt index 7b5ec5765..bb6d39204 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt @@ -17,7 +17,7 @@ internal class TestFeatures { fun printNumeric() { val num = object : Number() { override fun toByte(): Byte = throw UnsupportedOperationException() - override fun toChar(): Char = throw UnsupportedOperationException() +// override fun toChar(): Char = throw UnsupportedOperationException() override fun toDouble(): Double = throw UnsupportedOperationException() override fun toFloat(): Float = throw UnsupportedOperationException() override fun toInt(): Int = throw UnsupportedOperationException() diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt index d907a12c9..f2e1aae83 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt @@ -8,7 +8,6 @@ "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "PropertyName", "ClassName", ) diff --git a/kmath-complex/build.gradle.kts b/kmath-complex/build.gradle.kts index 2f8c320cf..3e8b3b75e 100644 --- a/kmath-complex/build.gradle.kts +++ b/kmath-complex/build.gradle.kts @@ -6,7 +6,6 @@ kscience { jvm() js() native() - wasm() dependencies { diff --git a/kmath-memory/build.gradle.kts b/kmath-memory/build.gradle.kts index fe422f751..63811d784 100644 --- a/kmath-memory/build.gradle.kts +++ b/kmath-memory/build.gradle.kts @@ -1,3 +1,5 @@ +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension + plugins { id("space.kscience.gradle.mpp") } @@ -15,3 +17,6 @@ readme { An API and basic implementation for arranging objects in a continuous memory block. """.trimIndent() } + +rootProject.the<NodeJsRootExtension>().versions.webpack.version = "5.76.2" +rootProject.the<NodeJsRootExtension>().nodeVersion = "20.2.0" diff --git a/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt b/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt index 32bc8d6a5..0ae3c7ebc 100644 --- a/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt +++ b/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.memory +import kotlin.experimental.ExperimentalNativeApi + @PublishedApi internal class NativeMemory( val array: ByteArray, @@ -26,6 +28,7 @@ internal class NativeMemory( return NativeMemory(copy) } + @OptIn(ExperimentalNativeApi::class) private val reader: MemoryReader = object : MemoryReader { override val memory: Memory get() = this@NativeMemory @@ -48,6 +51,7 @@ internal class NativeMemory( override fun reader(): MemoryReader = reader + @OptIn(ExperimentalNativeApi::class) private val writer: MemoryWriter = object : MemoryWriter { override val memory: Memory get() = this@NativeMemory From a18fa01100e5f2689ef0842a9190f08e28f0dd5a Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Fri, 26 May 2023 21:53:50 +0300 Subject: [PATCH 013/103] added parameter check in tests --- .../kmath/tensors/core/TestDoubleTensorAlgebra.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt index 85b81524b..5aea9b879 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt @@ -292,5 +292,17 @@ internal class TestDoubleTensorAlgebra { assertEquals(0.9131368192633, (result.result_chi_sq * 1e13).roundToLong() / 1e13) assertEquals(3.7790980 * 1e-7, (result.result_lambda * 1e13).roundToLong() / 1e13) assertEquals(result.typeOfConvergence, LinearOpsTensorAlgebra.TypeOfConvergence.inParameters) + val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(20.527230909086, 9.833627103230, 0.997571256572, 50.174445822506) + ).as2D() + result.result_parameters = result.result_parameters.map { x -> (x * 1e12).toLong() / 1e12}.as2D() + val receivedParameters = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(result.result_parameters[0, 0], result.result_parameters[1, 0], + result.result_parameters[2, 0], result.result_parameters[3, 0]) + ).as2D() + assertEquals(expectedParameters[0, 0], receivedParameters[0, 0]) + assertEquals(expectedParameters[1, 0], receivedParameters[1, 0]) + assertEquals(expectedParameters[2, 0], receivedParameters[2, 0]) + assertEquals(expectedParameters[3, 0], receivedParameters[3, 0]) } } From ce169461055a1372baed6baae80e662320150b60 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Sat, 27 May 2023 01:16:43 +0300 Subject: [PATCH 014/103] added streaming version of LM --- .../StreamingLm/functionsToOptimize.kt | 109 ++++++++++++++++++ .../tensors/StreamingLm/streamingLmMain.kt | 75 ++++++++++++ 2 files changed, 184 insertions(+) create mode 100644 examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/functionsToOptimize.kt create mode 100644 examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/functionsToOptimize.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/functionsToOptimize.kt new file mode 100644 index 000000000..1d0ce7deb --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/functionsToOptimize.kt @@ -0,0 +1,109 @@ +/* + * Copyright 2018-2023 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.tensors.StreamingLm + +import space.kscience.kmath.nd.MutableStructure2D +import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.nd.as2D +import space.kscience.kmath.nd.component1 +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times +import space.kscience.kmath.tensors.core.internal.LMSettings + +public data class StartDataLm ( + var lm_matx_y_dat: MutableStructure2D<Double>, + var example_number: Int, + var p_init: MutableStructure2D<Double>, + var t: MutableStructure2D<Double>, + var y_dat: MutableStructure2D<Double>, + var weight: MutableStructure2D<Double>, + var dp: MutableStructure2D<Double>, + var p_min: MutableStructure2D<Double>, + var p_max: MutableStructure2D<Double>, + var consts: MutableStructure2D<Double>, + var opts: DoubleArray +) + +fun func1ForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + val m = t.shape.component1() + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + + if (settings.example_number == 1) { + y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( + DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) + ) + } + else if (settings.example_number == 2) { + val mt = t.max() + y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + + (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + + (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + + (t.times(1.0 / mt)).pow(4).times(p[3, 0]) + } + else if (settings.example_number == 3) { + y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) + .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) + } + + return y_hat.as2D() +} + +fun getStartDataForFunc1(): StartDataLm { + val lm_matx_y_dat = doubleArrayOf( + 19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807, + 14.7620, 15.1128, 16.0973, 15.1934, 15.8636, 15.4763, 15.6860, 15.1895, 15.3495, 16.6054, + 16.2247, 15.9854, 16.1421, 17.0960, 16.7769, 17.1997, 17.2767, 17.5882, 17.5378, 16.7894, + 17.7648, 18.2512, 18.1581, 16.7037, 17.8475, 17.9081, 18.3067, 17.9632, 18.2817, 19.1427, + 18.8130, 18.5658, 18.0056, 18.4607, 18.5918, 18.2544, 18.3731, 18.7511, 19.3181, 17.3066, + 17.9632, 19.0513, 18.7528, 18.2928, 18.5967, 17.8567, 17.7859, 18.4016, 18.9423, 18.4959, + 17.8000, 18.4251, 17.7829, 17.4645, 17.5221, 17.3517, 17.4637, 17.7563, 16.8471, 17.4558, + 17.7447, 17.1487, 17.3183, 16.8312, 17.7551, 17.0942, 15.6093, 16.4163, 15.3755, 16.6725, + 16.2332, 16.2316, 16.2236, 16.5361, 15.3721, 15.3347, 15.5815, 15.6319, 14.4538, 14.6044, + 14.7665, 13.3718, 15.0587, 13.8320, 14.7873, 13.6824, 14.2579, 14.2154, 13.5818, 13.8157 + ) + + var example_number = 1 + val p_init = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(5.0, 2.0, 0.2, 10.0) + ).as2D() + + var t = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(100, 1))).as2D() + for (i in 0 until 100) { + t[i, 0] = t[i, 0] * (i + 1) + } + + val y_dat = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(100, 1)), lm_matx_y_dat + ).as2D() + + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 4.0 } + ).as2D() + + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + + val p_min = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(-50.0, -20.0, -2.0, -100.0) + ).as2D() + + val p_max = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0) + ).as2D() + + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + + val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) + + return StartDataLm(y_dat, example_number, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts) +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt new file mode 100644 index 000000000..e33cfac80 --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2018-2023 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.tensors.StreamingLm + +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.* +import space.kscience.kmath.nd.* +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra +import space.kscience.kmath.tensors.core.internal.LMSettings +import kotlin.math.roundToInt +import kotlin.random.Random +import kotlin.reflect.KFunction3 + +fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, + startData: StartDataLm, launchFrequencyInMs: Long): Flow<MutableStructure2D<Double>> = flow{ + + var example_number = startData.example_number + var p_init = startData.p_init + var t = startData.t + val y_dat = startData.y_dat + val weight = startData.weight + val dp = startData.dp + val p_min = startData.p_min + val p_max = startData.p_max + val consts = startData.consts + val opts = startData.opts + + while (true) { + val result = DoubleTensorAlgebra.lm( + lm_func, + p_init, + t, + y_dat, + weight, + dp, + p_min, + p_max, + consts, + opts, + 10, + example_number + ) + emit(result.result_parameters) + delay(launchFrequencyInMs) + p_init = generateNewParameters(p_init, 0.1) + } +} + +fun generateNewParameters(p: MutableStructure2D<Double>, delta: Double): MutableStructure2D<Double>{ + val n = p.shape.component1() + val p_new = zeros(ShapeND(intArrayOf(n, 1))).as2D() + for (i in 0 until n) { + val randomEps = Random.nextDouble(delta + delta) - delta + p_new[i, 0] = p[i, 0] + randomEps + } + return p_new +} + +suspend fun main(){ + val startData = getStartDataForFunc1() + // Создание потока: + val numberFlow = streamLm(::func1ForLm, startData, 1000) + // Запуск потока + numberFlow.collect { parameters -> + for (i in 0 until parameters.shape.component1()) { + val x = (parameters[i, 0] * 10000).roundToInt() / 10000.0 + print("$x ") + if (i == parameters.shape.component1() - 1) println() + } + } +} \ No newline at end of file From e738fbc86d27597dcc9521756837026910b46648 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Sat, 27 May 2023 01:24:37 +0300 Subject: [PATCH 015/103] typo fixed --- .../kscience/kmath/tensors/StreamingLm/streamingLmMain.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt index e33cfac80..06105fb9f 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt @@ -63,9 +63,9 @@ fun generateNewParameters(p: MutableStructure2D<Double>, delta: Double): Mutable suspend fun main(){ val startData = getStartDataForFunc1() // Создание потока: - val numberFlow = streamLm(::func1ForLm, startData, 1000) + val lmFlow = streamLm(::func1ForLm, startData, 1000) // Запуск потока - numberFlow.collect { parameters -> + lmFlow.collect { parameters -> for (i in 0 until parameters.shape.component1()) { val x = (parameters[i, 0] * 10000).roundToInt() / 10000.0 print("$x ") From 20c20a30e8b7f670f7586efffbb8cf63a4e9e917 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Sat, 27 May 2023 16:07:13 +0300 Subject: [PATCH 016/103] y_dat added generation --- .../kmath/tensors/StreamingLm/streamingLmMain.kt | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt index 06105fb9f..0fa934955 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt @@ -21,7 +21,7 @@ fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D< var example_number = startData.example_number var p_init = startData.p_init var t = startData.t - val y_dat = startData.y_dat + var y_dat = startData.y_dat val weight = startData.weight val dp = startData.dp val p_min = startData.p_min @@ -46,18 +46,19 @@ fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D< ) emit(result.result_parameters) delay(launchFrequencyInMs) - p_init = generateNewParameters(p_init, 0.1) + p_init = result.result_parameters + y_dat = generateNewYDat(y_dat, 0.1) } } -fun generateNewParameters(p: MutableStructure2D<Double>, delta: Double): MutableStructure2D<Double>{ - val n = p.shape.component1() - val p_new = zeros(ShapeND(intArrayOf(n, 1))).as2D() +fun generateNewYDat(y_dat: MutableStructure2D<Double>, delta: Double): MutableStructure2D<Double>{ + val n = y_dat.shape.component1() + val y_dat_new = zeros(ShapeND(intArrayOf(n, 1))).as2D() for (i in 0 until n) { val randomEps = Random.nextDouble(delta + delta) - delta - p_new[i, 0] = p[i, 0] + randomEps + y_dat_new[i, 0] = y_dat[i, 0] + randomEps } - return p_new + return y_dat_new } suspend fun main(){ From 33cb317ceee1256f3d271dd6723b8d55c57b814f Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Sun, 28 May 2023 23:07:01 +0300 Subject: [PATCH 017/103] added examples and tests --- .../StaticLm/staticDifficultTest.kt | 92 ++++++ .../StaticLm/staticEasyTest.kt | 56 ++++ .../StaticLm/staticMiddleTest.kt | 91 ++++++ .../StreamingLm/streamLm.kt} | 26 +- .../StreamingLm/streamingLmTest.kt | 25 ++ .../functionsToOptimize.kt | 39 ++- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 6 +- .../kmath/tensors/core/TestLmAlgorithm.kt | 267 ++++++++++++++++++ 8 files changed, 579 insertions(+), 23 deletions(-) create mode 100644 examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt create mode 100644 examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt create mode 100644 examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt rename examples/src/main/kotlin/space/kscience/kmath/tensors/{StreamingLm/streamingLmMain.kt => LevenbergMarquardt/StreamingLm/streamLm.kt} (72%) create mode 100644 examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt rename examples/src/main/kotlin/space/kscience/kmath/tensors/{StreamingLm => LevenbergMarquardt}/functionsToOptimize.kt (77%) create mode 100644 kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt new file mode 100644 index 000000000..621943aea --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt @@ -0,0 +1,92 @@ +/* + * Copyright 2018-2023 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.tensors.LevenbergMarquardt.StaticLm + +import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.nd.as2D +import space.kscience.kmath.nd.component1 +import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra +import space.kscience.kmath.tensors.core.internal.LMSettings +import kotlin.math.roundToInt + +fun main() { + val NData = 200 + var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() + for (i in 0 until NData) { + t_example[i, 0] = t_example[i, 0] * (i + 1) - 104 + } + + val Nparams = 15 + var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_example[i, 0] = p_example[i, 0] + i - 25 + } + + val settings = LMSettings(0, 0, 1) + + var y_hat = funcDifficultForLm(t_example, p_example, settings) + + var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_init[i, 0] = (p_example[i, 0] + 0.9) + } + + var t = t_example + val y_dat = y_hat + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 / Nparams * 1.0 - 0.085 } + ).as2D() + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / -50.0) + val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / 50.0) + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + val opts = doubleArrayOf(3.0, 10000.0, 1e-2, 0.015, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) +// val opts = doubleArrayOf(3.0, 10000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-3, 11.0, 9.0, 1.0) + + val result = DoubleTensorAlgebra.lm( + ::funcDifficultForLm, + p_init.as2D(), + t, + y_dat, + weight, + dp, + p_min.as2D(), + p_max.as2D(), + consts, + opts, + 10, + 1 + ) + + println("Parameters:") + for (i in 0 until result.result_parameters.shape.component1()) { + val x = (result.result_parameters[i, 0] * 10000).roundToInt() / 10000.0 + print("$x ") + } + println() + + println("Y true and y received:") + var y_hat_after = funcDifficultForLm(t_example, result.result_parameters, settings) + for (i in 0 until y_hat.shape.component1()) { + val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0 + val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 + println("$x $y") + } + + println("Сhi_sq:") + println(result.result_chi_sq) + println("Number of iterations:") + println(result.iterations) +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt new file mode 100644 index 000000000..bae5a674f --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt @@ -0,0 +1,56 @@ +/* + * Copyright 2018-2023 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.tensors.LevenbergMarquardt.StaticLm + +import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.nd.as2D +import space.kscience.kmath.nd.component1 +import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm +import space.kscience.kmath.tensors.LevenbergMarquardt.funcEasyForLm +import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncEasy +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra +import space.kscience.kmath.tensors.core.internal.LMSettings +import kotlin.math.roundToInt + +fun main() { + val startedData = getStartDataForFuncEasy() + + val result = DoubleTensorAlgebra.lm( + ::funcEasyForLm, + DoubleTensorAlgebra.ones(ShapeND(intArrayOf(4, 1))).as2D(), + startedData.t, + startedData.y_dat, + startedData.weight, + startedData.dp, + startedData.p_min, + startedData.p_max, + startedData.consts, + startedData.opts, + 10, + startedData.example_number + ) + + println("Parameters:") + for (i in 0 until result.result_parameters.shape.component1()) { + val x = (result.result_parameters[i, 0] * 10000).roundToInt() / 10000.0 + print("$x ") + } + println() + + println("Y true and y received:") + var y_hat_after = funcDifficultForLm(startedData.t, result.result_parameters, LMSettings(0, 0, startedData.example_number)) + for (i in 0 until startedData.y_dat.shape.component1()) { + val x = (startedData.y_dat[i, 0] * 10000).roundToInt() / 10000.0 + val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 + println("$x $y") + } + + println("Сhi_sq:") + println(result.result_chi_sq) + println("Number of iterations:") + println(result.iterations) +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt new file mode 100644 index 000000000..a39572858 --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt @@ -0,0 +1,91 @@ +/* + * Copyright 2018-2023 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.tensors.LevenbergMarquardt.StaticLm + +import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.nd.as2D +import space.kscience.kmath.nd.component1 +import space.kscience.kmath.tensors.LevenbergMarquardt.funcMiddleForLm +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra +import space.kscience.kmath.tensors.core.internal.LMSettings +import kotlin.math.roundToInt +fun main() { + val NData = 100 + var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() + for (i in 0 until NData) { + t_example[i, 0] = t_example[i, 0] * (i + 1) + } + + val Nparams = 20 + var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_example[i, 0] = p_example[i, 0] + i - 25 + } + + val settings = LMSettings(0, 0, 1) + + var y_hat = funcMiddleForLm(t_example, p_example, settings) + + var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_init[i, 0] = (p_example[i, 0] + 0.9) + } +// val p_init = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) +// val p_init = p_example + var t = t_example + val y_dat = y_hat + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 } + ).as2D() + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / -50.0) + val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / 50.0) + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + val opts = doubleArrayOf(3.0, 10000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) + + val result = DoubleTensorAlgebra.lm( + ::funcMiddleForLm, + p_init.as2D(), + t, + y_dat, + weight, + dp, + p_min.as2D(), + p_max.as2D(), + consts, + opts, + 10, + 1 + ) + + println("Parameters:") + for (i in 0 until result.result_parameters.shape.component1()) { + val x = (result.result_parameters[i, 0] * 10000).roundToInt() / 10000.0 + print("$x ") + } + println() + + println("Y true and y received:") + var y_hat_after = funcMiddleForLm(t_example, result.result_parameters, settings) + for (i in 0 until y_hat.shape.component1()) { + val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0 + val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 + println("$x $y") + } + + println("Сhi_sq:") + println(result.result_chi_sq) + println("Number of iterations:") + println(result.iterations) +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt similarity index 72% rename from examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt rename to examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index 0fa934955..5a1037618 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/streamingLmMain.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -3,20 +3,20 @@ * 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.tensors.StreamingLm +package space.kscience.kmath.tensors.LevenbergMarquardt.StreamingLm import kotlinx.coroutines.delay import kotlinx.coroutines.flow.* import space.kscience.kmath.nd.* +import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.internal.LMSettings -import kotlin.math.roundToInt import kotlin.random.Random import kotlin.reflect.KFunction3 fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, - startData: StartDataLm, launchFrequencyInMs: Long): Flow<MutableStructure2D<Double>> = flow{ + startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int): Flow<MutableStructure2D<Double>> = flow{ var example_number = startData.example_number var p_init = startData.p_init @@ -29,7 +29,10 @@ fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D< val consts = startData.consts val opts = startData.opts - while (true) { + var steps = numberOfLaunches + val isEndless = (steps <= 0) + + while (isEndless || steps > 0) { val result = DoubleTensorAlgebra.lm( lm_func, p_init, @@ -48,6 +51,7 @@ fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D< delay(launchFrequencyInMs) p_init = result.result_parameters y_dat = generateNewYDat(y_dat, 0.1) + if (!isEndless) steps -= 1 } } @@ -59,18 +63,4 @@ fun generateNewYDat(y_dat: MutableStructure2D<Double>, delta: Double): MutableSt y_dat_new[i, 0] = y_dat[i, 0] + randomEps } return y_dat_new -} - -suspend fun main(){ - val startData = getStartDataForFunc1() - // Создание потока: - val lmFlow = streamLm(::func1ForLm, startData, 1000) - // Запуск потока - lmFlow.collect { parameters -> - for (i in 0 until parameters.shape.component1()) { - val x = (parameters[i, 0] * 10000).roundToInt() / 10000.0 - print("$x ") - if (i == parameters.shape.component1() - 1) println() - } - } } \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt new file mode 100644 index 000000000..f81b048e5 --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2018-2023 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.tensors.LevenbergMarquardt.StreamingLm + +import space.kscience.kmath.nd.* +import space.kscience.kmath.tensors.LevenbergMarquardt.funcEasyForLm +import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncEasy +import kotlin.math.roundToInt + +suspend fun main(){ + val startData = getStartDataForFuncEasy() + // Создание потока: + val lmFlow = streamLm(::funcEasyForLm, startData, 1000, 10) + // Запуск потока + lmFlow.collect { parameters -> + for (i in 0 until parameters.shape.component1()) { + val x = (parameters[i, 0] * 10000).roundToInt() / 10000.0 + print("$x ") + if (i == parameters.shape.component1() - 1) println() + } + } +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/functionsToOptimize.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt similarity index 77% rename from examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/functionsToOptimize.kt rename to examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt index 1d0ce7deb..191dc5c67 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/StreamingLm/functionsToOptimize.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt @@ -3,7 +3,7 @@ * 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.tensors.StreamingLm +package space.kscience.kmath.tensors.LevenbergMarquardt import space.kscience.kmath.nd.MutableStructure2D import space.kscience.kmath.nd.ShapeND @@ -15,6 +15,7 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times +import space.kscience.kmath.tensors.core.asDoubleTensor import space.kscience.kmath.tensors.core.internal.LMSettings public data class StartDataLm ( @@ -31,7 +32,39 @@ public data class StartDataLm ( var opts: DoubleArray ) -fun func1ForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { +fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + val m = t.shape.component1() + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + + val mt = t.max() + for(i in 0 until p.shape.component1()){ + y_hat = y_hat.plus( (t.times(1.0 / mt)).times(p[i, 0]) ) + } + + for(i in 0 until 4){ + y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, settings).asDoubleTensor() + } + + return y_hat.as2D() +} + +fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + val m = t.shape.component1() + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + + val mt = t.max() + for(i in 0 until p.shape.component1()){ + y_hat += (t.times(1.0 / mt)).times(p[i, 0]) + } + + for(i in 0 until 5){ + y_hat = funcEasyForLm(y_hat.as2D(), p, settings).asDoubleTensor() + } + + return y_hat.as2D() +} + +fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { val m = t.shape.component1() var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) @@ -55,7 +88,7 @@ fun func1ForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, set return y_hat.as2D() } -fun getStartDataForFunc1(): StartDataLm { +fun getStartDataForFuncEasy(): StartDataLm { val lm_matx_y_dat = doubleArrayOf( 19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807, 14.7620, 15.1128, 16.0973, 15.1934, 15.8636, 15.4763, 15.6860, 15.1895, 15.3495, 16.6054, diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 43f097564..2b8bf84c0 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -765,12 +765,12 @@ public open class DoubleTensorAlgebra : var weight = weight_input if (nargin < 5) { - weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf((y_dat.transpose().dot(y_dat)).as1D()[0])).as2D() + fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(1.0)).as2D() } var dp = dp_input if (nargin < 6) { - dp = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.001)).as2D() + dp = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(-0.001)).as2D() } var p_min = p_min_input @@ -1023,6 +1023,8 @@ public open class DoubleTensorAlgebra : // println(" !! Maximum Number of Iterations Reached Without Convergence !!") resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence resultInfo.epsilon = 0.0 + print("noConvergence, MaxIter = ") + println(MaxIter) stop = true } } // --- End of Main Loop diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt new file mode 100644 index 000000000..29accbbfa --- /dev/null +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -0,0 +1,267 @@ +/* + * Copyright 2018-2023 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.tensors.core + +import space.kscience.kmath.nd.MutableStructure2D +import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.nd.as2D +import space.kscience.kmath.nd.component1 +import space.kscience.kmath.operations.invoke +import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times +import space.kscience.kmath.tensors.core.internal.LMSettings +import kotlin.math.roundToLong +import kotlin.test.Test +import kotlin.test.assertEquals + +class TestLmAlgorithm { + companion object { + fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + val m = t.shape.component1() + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) + + if (settings.example_number == 1) { + y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( + DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) + ) + } + else if (settings.example_number == 2) { + val mt = t.max() + y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + + (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + + (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + + (t.times(1.0 / mt)).pow(4).times(p[3, 0]) + } + else if (settings.example_number == 3) { + y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) + .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) + } + + return y_hat.as2D() + } + + fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + val m = t.shape.component1() + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + + val mt = t.max() + for(i in 0 until p.shape.component1()){ + y_hat += (t.times(1.0 / mt)).times(p[i, 0]) + } + + for(i in 0 until 5){ + y_hat = funcEasyForLm(y_hat.as2D(), p, settings).asDoubleTensor() + } + + return y_hat.as2D() + } + + fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + val m = t.shape.component1() + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + + val mt = t.max() + for(i in 0 until p.shape.component1()){ + y_hat = y_hat.plus( (t.times(1.0 / mt)).times(p[i, 0]) ) + } + + for(i in 0 until 4){ + y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, settings).asDoubleTensor() + } + + return y_hat.as2D() + } + + } + @Test + fun testLMEasy() = DoubleTensorAlgebra { + val lm_matx_y_dat = doubleArrayOf( + 19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807, + 14.7620, 15.1128, 16.0973, 15.1934, 15.8636, 15.4763, 15.6860, 15.1895, 15.3495, 16.6054, + 16.2247, 15.9854, 16.1421, 17.0960, 16.7769, 17.1997, 17.2767, 17.5882, 17.5378, 16.7894, + 17.7648, 18.2512, 18.1581, 16.7037, 17.8475, 17.9081, 18.3067, 17.9632, 18.2817, 19.1427, + 18.8130, 18.5658, 18.0056, 18.4607, 18.5918, 18.2544, 18.3731, 18.7511, 19.3181, 17.3066, + 17.9632, 19.0513, 18.7528, 18.2928, 18.5967, 17.8567, 17.7859, 18.4016, 18.9423, 18.4959, + 17.8000, 18.4251, 17.7829, 17.4645, 17.5221, 17.3517, 17.4637, 17.7563, 16.8471, 17.4558, + 17.7447, 17.1487, 17.3183, 16.8312, 17.7551, 17.0942, 15.6093, 16.4163, 15.3755, 16.6725, + 16.2332, 16.2316, 16.2236, 16.5361, 15.3721, 15.3347, 15.5815, 15.6319, 14.4538, 14.6044, + 14.7665, 13.3718, 15.0587, 13.8320, 14.7873, 13.6824, 14.2579, 14.2154, 13.5818, 13.8157 + ) + + var example_number = 1 + val p_init = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(5.0, 2.0, 0.2, 10.0) + ).as2D() + + var t = ones(ShapeND(intArrayOf(100, 1))).as2D() + for (i in 0 until 100) { + t[i, 0] = t[i, 0] * (i + 1) + } + + val y_dat = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(100, 1)), lm_matx_y_dat + ).as2D() + + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 4.0 } + ).as2D() + + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + + val p_min = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(-50.0, -20.0, -2.0, -100.0) + ).as2D() + + val p_max = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0) + ).as2D() + + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + + val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) + + val result = lm(::funcEasyForLm, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts, 10, example_number) + assertEquals(13, result.iterations) + assertEquals(31, result.func_calls) + assertEquals(1, result.example_number) + assertEquals(0.9131368192633, (result.result_chi_sq * 1e13).roundToLong() / 1e13) + assertEquals(3.7790980 * 1e-7, (result.result_lambda * 1e13).roundToLong() / 1e13) + assertEquals(result.typeOfConvergence, LinearOpsTensorAlgebra.TypeOfConvergence.inParameters) + val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(20.527230909086, 9.833627103230, 0.997571256572, 50.174445822506) + ).as2D() + result.result_parameters = result.result_parameters.map { x -> (x * 1e12).toLong() / 1e12}.as2D() + val receivedParameters = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(4, 1)), doubleArrayOf(result.result_parameters[0, 0], result.result_parameters[1, 0], + result.result_parameters[2, 0], result.result_parameters[3, 0]) + ).as2D() + assertEquals(expectedParameters[0, 0], receivedParameters[0, 0]) + assertEquals(expectedParameters[1, 0], receivedParameters[1, 0]) + assertEquals(expectedParameters[2, 0], receivedParameters[2, 0]) + assertEquals(expectedParameters[3, 0], receivedParameters[3, 0]) + } + + @Test + fun TestLMMiddle() = DoubleTensorAlgebra { + val NData = 100 + var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() + for (i in 0 until NData) { + t_example[i, 0] = t_example[i, 0] * (i + 1) + } + + val Nparams = 20 + var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_example[i, 0] = p_example[i, 0] + i - 25 + } + + val settings = LMSettings(0, 0, 1) + + var y_hat = funcMiddleForLm(t_example, p_example, settings) + + var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_init[i, 0] = (p_example[i, 0] + 0.9) + } + + var t = t_example + val y_dat = y_hat + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 } + ).as2D() + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / -50.0) + val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / 50.0) + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) + + val result = DoubleTensorAlgebra.lm( + ::funcMiddleForLm, + p_init.as2D(), + t, + y_dat, + weight, + dp, + p_min.as2D(), + p_max.as2D(), + consts, + opts, + 10, + 1 + ) + } + + @Test + fun TestLMDifficult() = DoubleTensorAlgebra { + val NData = 200 + var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() + for (i in 0 until NData) { + t_example[i, 0] = t_example[i, 0] * (i + 1) - 104 + } + + val Nparams = 15 + var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_example[i, 0] = p_example[i, 0] + i - 25 + } + + val settings = LMSettings(0, 0, 1) + + var y_hat = funcDifficultForLm(t_example, p_example, settings) + + var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_init[i, 0] = (p_example[i, 0] + 0.9) + } + + var t = t_example + val y_dat = y_hat + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 / Nparams * 1.0 - 0.085 } + ).as2D() + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / -50.0) + val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / 50.0) + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + val opts = doubleArrayOf(3.0, 7000.0, 1e-2, 1e-1, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) + + val result = DoubleTensorAlgebra.lm( + ::funcDifficultForLm, + p_init.as2D(), + t, + y_dat, + weight, + dp, + p_min.as2D(), + p_max.as2D(), + consts, + opts, + 10, + 1 + ) + +// assertEquals(1.15, (result.result_chi_sq * 1e2).roundToLong() / 1e2) + } +} \ No newline at end of file From 1afb0d0a4c3f88a03e04358e636745937aeab32d Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Mon, 29 May 2023 15:13:13 +0300 Subject: [PATCH 018/103] fixed time for js tests for lm --- kmath-tensors/build.gradle.kts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/kmath-tensors/build.gradle.kts b/kmath-tensors/build.gradle.kts index d27faeeef..fdd841bc3 100644 --- a/kmath-tensors/build.gradle.kts +++ b/kmath-tensors/build.gradle.kts @@ -4,7 +4,13 @@ plugins { kscience{ jvm() - js() + js { + browser { + testTask { + useMocha().timeout = "100000" + } + } + } native() dependencies { From 47600dff23a63e6d11341e509a698288114cb057 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Tue, 6 Jun 2023 00:39:19 +0300 Subject: [PATCH 019/103] tests changed --- .../StaticLm/staticDifficultTest.kt | 4 +- .../StaticLm/staticMiddleTest.kt | 5 +- .../StreamingLm/streamingLmTest.kt | 15 +++- .../LevenbergMarquardt/functionsToOptimize.kt | 87 +++++++++++++++++++ kmath-tensors/build.gradle.kts | 2 +- .../kmath/tensors/core/TestLmAlgorithm.kt | 4 +- 6 files changed, 105 insertions(+), 12 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt index 621943aea..0a502afa8 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt @@ -52,8 +52,8 @@ fun main() { val consts = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) ).as2D() - val opts = doubleArrayOf(3.0, 10000.0, 1e-2, 0.015, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) -// val opts = doubleArrayOf(3.0, 10000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-3, 11.0, 9.0, 1.0) + val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-2, 11.0, 9.0, 1.0) +// val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-3, 11.0, 9.0, 1.0) val result = DoubleTensorAlgebra.lm( ::funcDifficultForLm, diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt index a39572858..02917caf2 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt @@ -12,6 +12,7 @@ import space.kscience.kmath.tensors.LevenbergMarquardt.funcMiddleForLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.DoubleTensorAlgebra +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times import space.kscience.kmath.tensors.core.internal.LMSettings import kotlin.math.roundToInt fun main() { @@ -52,7 +53,7 @@ fun main() { val consts = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) ).as2D() - val opts = doubleArrayOf(3.0, 10000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) + val opts = doubleArrayOf(3.0, 10000.0, 1e-3, 1e-3, 1e-3, 1e-3, 1e-15, 11.0, 9.0, 1.0) val result = DoubleTensorAlgebra.lm( ::funcMiddleForLm, @@ -76,7 +77,7 @@ fun main() { } println() - println("Y true and y received:") + var y_hat_after = funcMiddleForLm(t_example, result.result_parameters, settings) for (i in 0 until y_hat.shape.component1()) { val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0 diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt index f81b048e5..c9dd5029e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt @@ -6,20 +6,27 @@ package space.kscience.kmath.tensors.LevenbergMarquardt.StreamingLm import space.kscience.kmath.nd.* -import space.kscience.kmath.tensors.LevenbergMarquardt.funcEasyForLm -import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncEasy +import space.kscience.kmath.tensors.LevenbergMarquardt.* import kotlin.math.roundToInt suspend fun main(){ - val startData = getStartDataForFuncEasy() + val startData = getStartDataForFuncDifficult() // Создание потока: - val lmFlow = streamLm(::funcEasyForLm, startData, 1000, 10) + val lmFlow = streamLm(::funcDifficultForLm, startData, 0, 100) + var initialTime = System.currentTimeMillis() + var lastTime: Long + val launches = mutableListOf<Long>() // Запуск потока lmFlow.collect { parameters -> + lastTime = System.currentTimeMillis() + launches.add(lastTime - initialTime) + initialTime = lastTime for (i in 0 until parameters.shape.component1()) { val x = (parameters[i, 0] * 10000).roundToInt() / 10000.0 print("$x ") if (i == parameters.shape.component1() - 1) println() } } + + println("Average without first is: ${launches.subList(1, launches.size - 1).average()}") } \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt index 191dc5c67..5b194ab6b 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt @@ -10,6 +10,7 @@ import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.as2D import space.kscience.kmath.nd.component1 import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus @@ -17,6 +18,7 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times import space.kscience.kmath.tensors.core.asDoubleTensor import space.kscience.kmath.tensors.core.internal.LMSettings +import kotlin.math.roundToInt public data class StartDataLm ( var lm_matx_y_dat: MutableStructure2D<Double>, @@ -88,6 +90,91 @@ fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, return y_hat.as2D() } +fun getStartDataForFuncDifficult(): StartDataLm { + val NData = 200 + var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() + for (i in 0 until NData) { + t_example[i, 0] = t_example[i, 0] * (i + 1) - 104 + } + + val Nparams = 15 + var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_example[i, 0] = p_example[i, 0] + i - 25 + } + + val settings = LMSettings(0, 0, 1) + + var y_hat = funcDifficultForLm(t_example, p_example, settings) + + var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_init[i, 0] = (p_example[i, 0] + 0.9) + } + + var t = t_example + val y_dat = y_hat + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 / Nparams * 1.0 - 0.085 } + ).as2D() + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / -50.0) + val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / 50.0) + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + val opts = doubleArrayOf(3.0, 10000.0, 1e-2, 1e-3, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) + + return StartDataLm(y_dat, 1, p_init, t, y_dat, weight, dp, p_min.as2D(), p_max.as2D(), consts, opts) +} + +fun getStartDataForFuncMiddle(): StartDataLm { + val NData = 100 + var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() + for (i in 0 until NData) { + t_example[i, 0] = t_example[i, 0] * (i + 1) + } + + val Nparams = 20 + var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_example[i, 0] = p_example[i, 0] + i - 25 + } + + val settings = LMSettings(0, 0, 1) + + var y_hat = funcMiddleForLm(t_example, p_example, settings) + + var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + p_init[i, 0] = (p_example[i, 0] + 10.0) + } + var t = t_example + val y_dat = y_hat + val weight = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 } + ).as2D() + val dp = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } + ).as2D() + var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / -50.0) + val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + p_min = p_min.div(1.0 / 50.0) + val consts = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) + ).as2D() + val opts = doubleArrayOf(3.0, 10000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) + + var example_number = 1 + + return StartDataLm(y_dat, example_number, p_init, t, y_dat, weight, dp, p_min.as2D(), p_max.as2D(), consts, opts) +} + fun getStartDataForFuncEasy(): StartDataLm { val lm_matx_y_dat = doubleArrayOf( 19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807, diff --git a/kmath-tensors/build.gradle.kts b/kmath-tensors/build.gradle.kts index fdd841bc3..5e82835a7 100644 --- a/kmath-tensors/build.gradle.kts +++ b/kmath-tensors/build.gradle.kts @@ -7,7 +7,7 @@ kscience{ js { browser { testTask { - useMocha().timeout = "100000" + useMocha().timeout = "0" } } } diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index 29accbbfa..f554a742c 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -245,7 +245,7 @@ class TestLmAlgorithm { val consts = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) ).as2D() - val opts = doubleArrayOf(3.0, 7000.0, 1e-2, 1e-1, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) + val opts = doubleArrayOf(3.0, 7000.0, 1e-2, 1e-3, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) val result = DoubleTensorAlgebra.lm( ::funcDifficultForLm, @@ -261,7 +261,5 @@ class TestLmAlgorithm { 10, 1 ) - -// assertEquals(1.15, (result.result_chi_sq * 1e2).roundToLong() / 1e2) } } \ No newline at end of file From 8d81d2d8d5a39d0309dbd2c4b70b516092f5bfea Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Tue, 6 Jun 2023 01:41:08 +0300 Subject: [PATCH 020/103] move lm-algorithm from DoubleTensorAlgebra as extension --- .../tensors/api/LinearOpsTensorAlgebra.kt | 14 - .../kmath/tensors/core/DoubleTensorAlgebra.kt | 363 ------------ .../core/LevenbergMarquardtAlgorithm.kt | 553 ++++++++++++++++++ .../kmath/tensors/core/internal/linUtils.kt | 229 +------- .../tensors/core/TestDoubleTensorAlgebra.kt | 100 ---- .../kmath/tensors/core/TestLmAlgorithm.kt | 1 - 6 files changed, 554 insertions(+), 706 deletions(-) create mode 100644 kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt index 7964656f1..6b3859316 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt @@ -7,15 +7,7 @@ package space.kscience.kmath.tensors.api import space.kscience.kmath.nd.MutableStructure2D import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.nd.as2D import space.kscience.kmath.operations.Field -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.map -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.transposed -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.internal.LMSettings -import kotlin.reflect.KFunction3 /** * Common linear algebra operations. Operates on [Tensor]. @@ -137,10 +129,4 @@ public interface LinearOpsTensorAlgebra<T, A : Field<T>> : TensorPartialDivision var typeOfConvergence: TypeOfConvergence, var epsilon: Double ) - - public fun lm( - func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, - p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, - weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, - c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LMResultInfo } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 2b8bf84c0..c8cf56888 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -9,7 +9,6 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall -import space.kscience.kmath.linear.transpose import space.kscience.kmath.nd.* import space.kscience.kmath.operations.DoubleBufferOps import space.kscience.kmath.operations.DoubleField @@ -19,7 +18,6 @@ import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.core.internal.* import kotlin.math.* -import kotlin.reflect.KFunction3 /** * Implementation of basic operations over double tensors and basic algebra operations on them. @@ -716,367 +714,6 @@ public open class DoubleTensorAlgebra : val aInverse = aSvd.third.dot(s).dot(aSvd.first.transposed()) return aInverse.dot(b).as2D() } - - override fun lm( - func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, - p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, - weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, - c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LinearOpsTensorAlgebra.LMResultInfo { - - var resultInfo = LinearOpsTensorAlgebra.LMResultInfo(0, 0, example_number, 0.0, - 0.0, p_input, LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence, 0.0) - - val eps:Double = 2.2204e-16 - - var settings = LMSettings(0, 0, example_number) - settings.func_calls = 0 // running count of function evaluations - - var p = p_input - val y_dat = y_dat_input - val t = t_input - - val Npar = length(p) // number of parameters - val Npnt = length(y_dat) // number of data points - var p_old = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters - var y_old = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) - var X2 = 1e-3 / eps // a really big initial Chi-sq value - var X2_old = 1e-3 / eps // a really big initial Chi-sq value - var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix - val DoF = Npnt - Npar // statistical degrees of freedom - - var corr_p = 0 - var sigma_p = 0 - var sigma_y = 0 - var R_sq = 0 - var cvg_hist = 0 - - if (length(t) != length(y_dat)) { - // println("lm.m error: the length of t must equal the length of y_dat") - val length_t = length(t) - val length_y_dat = length(y_dat) - X2 = 0.0 - - corr_p = 0 - sigma_p = 0 - sigma_y = 0 - R_sq = 0 - cvg_hist = 0 - } - - var weight = weight_input - if (nargin < 5) { - fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(1.0)).as2D() - } - - var dp = dp_input - if (nargin < 6) { - dp = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(-0.001)).as2D() - } - - var p_min = p_min_input - if (nargin < 7) { - p_min = p - p_min.abs() - p_min = p_min.div(-100.0).as2D() - } - - var p_max = p_max_input - if (nargin < 8) { - p_max = p - p_max.abs() - p_max = p_max.div(100.0).as2D() - } - - var c = c_input - if (nargin < 9) { - c = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(1.0)).as2D() - } - - var opts = opts_input - if (nargin < 10) { - opts = doubleArrayOf(3.0, 10.0 * Npar, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) - } - - val prnt = opts[0] // >1 intermediate results; >2 plots - val MaxIter = opts[1].toInt() // maximum number of iterations - val epsilon_1 = opts[2] // convergence tolerance for gradient - val epsilon_2 = opts[3] // convergence tolerance for parameters - val epsilon_3 = opts[4] // convergence tolerance for Chi-square - val epsilon_4 = opts[5] // determines acceptance of a L-M step - val lambda_0 = opts[6] // initial value of damping paramter, lambda - val lambda_UP_fac = opts[7] // factor for increasing lambda - val lambda_DN_fac = opts[8] // factor for decreasing lambda - val Update_Type = opts[9].toInt() // 1: Levenberg-Marquardt lambda update - // 2: Quadratic update - // 3: Nielsen's lambda update equations - - p_min = make_column(p_min) - p_max = make_column(p_max) - - if (length(make_column(dp)) == 1) { - dp = ones(ShapeND(intArrayOf(Npar, 1))).div(1 / dp[0, 0]).as2D() - } - - val idx = get_zero_indices(dp) // indices of the parameters to be fit - val Nfit = idx?.shape?.component1() // number of parameters to fit - var stop = false // termination flag - val y_init = feval(func, t, p, settings) // residual error using p_try - - if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector - weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / abs(weight[0, 0])).as2D() - // println("using uniform weights for error analysis") - } - else { - weight = make_column(weight) - weight.abs() - } - - // initialize Jacobian with finite difference calculation - var lm_matx_ans = lm_matx(func, t, p_old, y_old,1, J, p, y_dat, weight, dp, settings) - var JtWJ = lm_matx_ans[0] - var JtWdy = lm_matx_ans[1] - X2 = lm_matx_ans[2][0, 0] - var y_hat = lm_matx_ans[3] - J = lm_matx_ans[4] - - if ( abs(JtWdy).max()!! < epsilon_1 ) { -// println(" *** Your Initial Guess is Extremely Close to Optimal ***\n") -// println(" *** epsilon_1 = %e\n$epsilon_1") - stop = true - } - - var lambda = 1.0 - var nu = 1 - when (Update_Type) { - 1 -> lambda = lambda_0 // Marquardt: init'l lambda - else -> { // Quadratic and Nielsen - lambda = lambda_0 * (diag(JtWJ)).max()!! - nu = 2 - } - } - - X2_old = X2 // previous value of X2 - var cvg_hst = ones(ShapeND(intArrayOf(MaxIter, Npar + 3))) // initialize convergence history - - var h: DoubleTensor - var dX2 = X2 - while (!stop && settings.iteration <= MaxIter) { //--- Start Main Loop - settings.iteration += 1 - - // incremental change in parameters - h = when (Update_Type) { - 1 -> { // Marquardt - val solve = solve(JtWJ.plus(make_matrx_with_diagonal(diag(JtWJ)).div(1 / lambda)).as2D(), JtWdy) - solve.asDoubleTensor() - } - - else -> { // Quadratic and Nielsen - val solve = solve(JtWJ.plus(lm_eye(Npar).div(1 / lambda)).as2D(), JtWdy) - solve.asDoubleTensor() - } - } - - var p_try = (p + h).as2D() // update the [idx] elements - p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try.as2D()), p_max) // apply constraints - - var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try - - for (i in 0 until delta_y.shape.component1()) { // floating point error; break - for (j in 0 until delta_y.shape.component2()) { - if (delta_y[i, j] == Double.POSITIVE_INFINITY || delta_y[i, j] == Double.NEGATIVE_INFINITY) { - stop = true - break - } - } - } - - settings.func_calls += 1 - - val tmp = delta_y.times(weight) - var X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria - - val alpha = 1.0 - if (Update_Type == 2) { // Quadratic - // One step of quadratic line update in the h direction for minimum X2 - - val alpha = JtWdy.transpose().dot(h) / ( (X2_try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h)) ) - h = h.dot(alpha) - p_try = p.plus(h).as2D() // update only [idx] elements - p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try), p_max) // apply constraints - - var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try - settings.func_calls += 1 - - val tmp = delta_y.times(weight) - X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria - } - - val rho = when (Update_Type) { // Nielsen - 1 -> { - val tmp = h.transposed().dot(make_matrx_with_diagonal(diag(JtWJ)).div(1 / lambda).dot(h).plus(JtWdy)) - X2.minus(X2_try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] - } - else -> { - val tmp = h.transposed().dot(h.div(1 / lambda).plus(JtWdy)) - X2.minus(X2_try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] - } - } - - if (rho > epsilon_4) { // it IS significantly better - val dX2 = X2.minus(X2_old) - X2_old = X2 - p_old = p.copyToTensor().as2D() - y_old = y_hat.copyToTensor().as2D() - p = make_column(p_try) // accept p_try - - lm_matx_ans = lm_matx(func, t, p_old, y_old, dX2.toInt(), J, p, y_dat, weight, dp, settings) - // decrease lambda ==> Gauss-Newton method - - JtWJ = lm_matx_ans[0] - JtWdy = lm_matx_ans[1] - X2 = lm_matx_ans[2][0, 0] - y_hat = lm_matx_ans[3] - J = lm_matx_ans[4] - - lambda = when (Update_Type) { - 1 -> { // Levenberg - max(lambda / lambda_DN_fac, 1e-7); - } - 2 -> { // Quadratic - max( lambda / (1 + alpha) , 1e-7 ); - } - else -> { // Nielsen - nu = 2 - lambda * max( 1.0 / 3, 1 - (2 * rho - 1).pow(3) ) - } - } - } - else { // it IS NOT better - X2 = X2_old // do not accept p_try - if (settings.iteration % (2 * Npar) == 0 ) { // rank-1 update of Jacobian - lm_matx_ans = lm_matx(func, t, p_old, y_old,-1, J, p, y_dat, weight, dp, settings) - JtWJ = lm_matx_ans[0] - JtWdy = lm_matx_ans[1] - dX2 = lm_matx_ans[2][0, 0] - y_hat = lm_matx_ans[3] - J = lm_matx_ans[4] - } - - // increase lambda ==> gradient descent method - lambda = when (Update_Type) { - 1 -> { // Levenberg - min(lambda * lambda_UP_fac, 1e7) - } - 2 -> { // Quadratic - lambda + abs(((X2_try.as2D()[0, 0] - X2) / 2) / alpha) - } - else -> { // Nielsen - nu *= 2 - lambda * (nu / 2) - } - } - } - - if (prnt > 1) { - val chi_sq = X2 / DoF -// println("Iteration $settings | chi_sq=$chi_sq | lambda=$lambda") -// print("param: ") -// for (pn in 0 until Npar) { -// print(p[pn, 0].toString() + " ") -// } -// print("\ndp/p: ") -// for (pn in 0 until Npar) { -// print((h.as2D()[pn, 0] / p[pn, 0]).toString() + " ") -// } - resultInfo.iterations = settings.iteration - resultInfo.func_calls = settings.func_calls - resultInfo.result_chi_sq = chi_sq - resultInfo.result_lambda = lambda - resultInfo.result_parameters = p - } - - // update convergence history ... save _reduced_ Chi-square - // cvg_hst(iteration,:) = [ func_calls p' X2/DoF lambda ]; - - if (abs(JtWdy).max()!! < epsilon_1 && settings.iteration > 2) { -// println(" **** Convergence in r.h.s. (\"JtWdy\") ****") -// println(" **** epsilon_1 = $epsilon_1") - resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inRHS_JtWdy - resultInfo.epsilon = epsilon_1 - stop = true - } - if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon_2 && settings.iteration > 2) { -// println(" **** Convergence in Parameters ****") -// println(" **** epsilon_2 = $epsilon_2") - resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inParameters - resultInfo.epsilon = epsilon_2 - stop = true - } - if (X2 / DoF < epsilon_3 && settings.iteration > 2) { -// println(" **** Convergence in reduced Chi-square **** ") -// println(" **** epsilon_3 = $epsilon_3") - resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inReducedChi_square - resultInfo.epsilon = epsilon_3 - stop = true - } - if (settings.iteration == MaxIter) { -// println(" !! Maximum Number of Iterations Reached Without Convergence !!") - resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence - resultInfo.epsilon = 0.0 - print("noConvergence, MaxIter = ") - println(MaxIter) - stop = true - } - } // --- End of Main Loop - - // --- convergence achieved, find covariance and confidence intervals - - // ---- Error Analysis ---- - -// if (weight.shape.component1() == 1 || weight.variance() == 0.0) { -// weight = DoF / (delta_y.transpose().dot(delta_y)) * ones(intArrayOf(Npt, 1)) -// } - -// if (nargout > 1) { -// val redX2 = X2 / DoF -// } -// -// lm_matx_ans = lm_matx(func, t, p_old, y_old, -1, J, p, y_dat, weight, dp) -// JtWJ = lm_matx_ans[0] -// JtWdy = lm_matx_ans[1] -// X2 = lm_matx_ans[2][0, 0] -// y_hat = lm_matx_ans[3] -// J = lm_matx_ans[4] -// -// if (nargout > 2) { // standard error of parameters -// covar_p = inv(JtWJ); -// siif nagma_p = sqrt(diag(covar_p)); -// } -// -// if (nargout > 3) { // standard error of the fit -// /// sigma_y = sqrt(diag(J * covar_p * J')); // slower version of below -// sigma_y = zeros(Npnt,1); -// for i=1:Npnt -// sigma_y(i) = J(i,:) * covar_p * J(i,:)'; -// end -// sigma_y = sqrt(sigma_y); -// } -// -// if (nargout > 4) { // parameter correlation matrix -// corr_p = covar_p ./ [sigma_p*sigma_p']; -// } -// -// if (nargout > 5) { // coefficient of multiple determination -// R_sq = corr([y_dat y_hat]); -// R_sq = R_sq(1,2).^2; -// } -// -// if (nargout > 6) { // convergence history -// cvg_hst = cvg_hst(1:iteration,:); -// } - - return resultInfo - } } public val Double.Companion.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt new file mode 100644 index 000000000..f4b50626a --- /dev/null +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -0,0 +1,553 @@ +/* + * Copyright 2018-2023 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.tensors.core + +import space.kscience.kmath.linear.transpose +import space.kscience.kmath.nd.* +import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.minus +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.times +import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.transposed +import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus +import kotlin.math.max +import kotlin.math.min +import kotlin.math.pow +import kotlin.reflect.KFunction3 + +public fun DoubleTensorAlgebra.lm( + func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, + p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, + weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, + c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LinearOpsTensorAlgebra.LMResultInfo { + + val resultInfo = LinearOpsTensorAlgebra.LMResultInfo(0, 0, example_number, 0.0, + 0.0, p_input, LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence, 0.0) + + val eps:Double = 2.2204e-16 + + val settings = LMSettings(0, 0, example_number) + settings.func_calls = 0 // running count of function evaluations + + var p = p_input + val y_dat = y_dat_input + val t = t_input + + val Npar = length(p) // number of parameters + val Npnt = length(y_dat) // number of data points + var p_old = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters + var y_old = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) + var X2 = 1e-3 / eps // a really big initial Chi-sq value + var X2_old = 1e-3 / eps // a really big initial Chi-sq value + var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix + val DoF = Npnt - Npar // statistical degrees of freedom + + var corr_p = 0 + var sigma_p = 0 + var sigma_y = 0 + var R_sq = 0 + var cvg_hist = 0 + + if (length(t) != length(y_dat)) { + // println("lm.m error: the length of t must equal the length of y_dat") + val length_t = length(t) + val length_y_dat = length(y_dat) + X2 = 0.0 + + corr_p = 0 + sigma_p = 0 + sigma_y = 0 + R_sq = 0 + cvg_hist = 0 + } + + var weight = weight_input + if (nargin < 5) { + weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf((y_dat.transpose().dot(y_dat)).as1D()[0])).as2D() + } + + var dp = dp_input + if (nargin < 6) { + dp = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.001)).as2D() + } + + var p_min = p_min_input + if (nargin < 7) { + p_min = p + p_min.abs() + p_min = p_min.div(-100.0).as2D() + } + + var p_max = p_max_input + if (nargin < 8) { + p_max = p + p_max.abs() + p_max = p_max.div(100.0).as2D() + } + + var c = c_input + if (nargin < 9) { + c = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(1.0)).as2D() + } + + var opts = opts_input + if (nargin < 10) { + opts = doubleArrayOf(3.0, 10.0 * Npar, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) + } + + val prnt = opts[0] // >1 intermediate results; >2 plots + val MaxIter = opts[1].toInt() // maximum number of iterations + val epsilon_1 = opts[2] // convergence tolerance for gradient + val epsilon_2 = opts[3] // convergence tolerance for parameters + val epsilon_3 = opts[4] // convergence tolerance for Chi-square + val epsilon_4 = opts[5] // determines acceptance of a L-M step + val lambda_0 = opts[6] // initial value of damping paramter, lambda + val lambda_UP_fac = opts[7] // factor for increasing lambda + val lambda_DN_fac = opts[8] // factor for decreasing lambda + val Update_Type = opts[9].toInt() // 1: Levenberg-Marquardt lambda update + // 2: Quadratic update + // 3: Nielsen's lambda update equations + + p_min = make_column(p_min) + p_max = make_column(p_max) + + if (length(make_column(dp)) == 1) { + dp = ones(ShapeND(intArrayOf(Npar, 1))).div(1 / dp[0, 0]).as2D() + } + + val idx = get_zero_indices(dp) // indices of the parameters to be fit + val Nfit = idx?.shape?.component1() // number of parameters to fit + var stop = false // termination flag + val y_init = feval(func, t, p, settings) // residual error using p_try + + if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector + weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / kotlin.math.abs(weight[0, 0])).as2D() + // println("using uniform weights for error analysis") + } + else { + weight = make_column(weight) + weight.abs() + } + + // initialize Jacobian with finite difference calculation + var lm_matx_ans = lm_matx(func, t, p_old, y_old,1, J, p, y_dat, weight, dp, settings) + var JtWJ = lm_matx_ans[0] + var JtWdy = lm_matx_ans[1] + X2 = lm_matx_ans[2][0, 0] + var y_hat = lm_matx_ans[3] + J = lm_matx_ans[4] + + if ( abs(JtWdy).max()!! < epsilon_1 ) { +// println(" *** Your Initial Guess is Extremely Close to Optimal ***\n") +// println(" *** epsilon_1 = %e\n$epsilon_1") + stop = true + } + + var lambda = 1.0 + var nu = 1 + when (Update_Type) { + 1 -> lambda = lambda_0 // Marquardt: init'l lambda + else -> { // Quadratic and Nielsen + lambda = lambda_0 * (diag(JtWJ)).max()!! + nu = 2 + } + } + + X2_old = X2 // previous value of X2 + var cvg_hst = ones(ShapeND(intArrayOf(MaxIter, Npar + 3))) // initialize convergence history + + var h: DoubleTensor + var dX2 = X2 + while (!stop && settings.iteration <= MaxIter) { //--- Start Main Loop + settings.iteration += 1 + + // incremental change in parameters + h = when (Update_Type) { + 1 -> { // Marquardt + val solve = solve(JtWJ.plus(make_matrx_with_diagonal(diag(JtWJ)).div(1 / lambda)).as2D(), JtWdy) + solve.asDoubleTensor() + } + + else -> { // Quadratic and Nielsen + val solve = solve(JtWJ.plus(lm_eye(Npar).div(1 / lambda)).as2D(), JtWdy) + solve.asDoubleTensor() + } + } + + var p_try = (p + h).as2D() // update the [idx] elements + p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try.as2D()), p_max) // apply constraints + + var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try + + for (i in 0 until delta_y.shape.component1()) { // floating point error; break + for (j in 0 until delta_y.shape.component2()) { + if (delta_y[i, j] == Double.POSITIVE_INFINITY || delta_y[i, j] == Double.NEGATIVE_INFINITY) { + stop = true + break + } + } + } + + settings.func_calls += 1 + + val tmp = delta_y.times(weight) + var X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria + + val alpha = 1.0 + if (Update_Type == 2) { // Quadratic + // One step of quadratic line update in the h direction for minimum X2 + + val alpha = JtWdy.transpose().dot(h) / ( (X2_try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h)) ) + h = h.dot(alpha) + p_try = p.plus(h).as2D() // update only [idx] elements + p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try), p_max) // apply constraints + + var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try + settings.func_calls += 1 + + val tmp = delta_y.times(weight) + X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria + } + + val rho = when (Update_Type) { // Nielsen + 1 -> { + val tmp = h.transposed().dot(make_matrx_with_diagonal(diag(JtWJ)).div(1 / lambda).dot(h).plus(JtWdy)) + X2.minus(X2_try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] + } + else -> { + val tmp = h.transposed().dot(h.div(1 / lambda).plus(JtWdy)) + X2.minus(X2_try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] + } + } + + if (rho > epsilon_4) { // it IS significantly better + val dX2 = X2.minus(X2_old) + X2_old = X2 + p_old = p.copyToTensor().as2D() + y_old = y_hat.copyToTensor().as2D() + p = make_column(p_try) // accept p_try + + lm_matx_ans = lm_matx(func, t, p_old, y_old, dX2.toInt(), J, p, y_dat, weight, dp, settings) + // decrease lambda ==> Gauss-Newton method + + JtWJ = lm_matx_ans[0] + JtWdy = lm_matx_ans[1] + X2 = lm_matx_ans[2][0, 0] + y_hat = lm_matx_ans[3] + J = lm_matx_ans[4] + + lambda = when (Update_Type) { + 1 -> { // Levenberg + max(lambda / lambda_DN_fac, 1e-7); + } + 2 -> { // Quadratic + max( lambda / (1 + alpha) , 1e-7 ); + } + else -> { // Nielsen + nu = 2 + lambda * max( 1.0 / 3, 1 - (2 * rho - 1).pow(3) ) + } + } + } + else { // it IS NOT better + X2 = X2_old // do not accept p_try + if (settings.iteration % (2 * Npar) == 0 ) { // rank-1 update of Jacobian + lm_matx_ans = lm_matx(func, t, p_old, y_old,-1, J, p, y_dat, weight, dp, settings) + JtWJ = lm_matx_ans[0] + JtWdy = lm_matx_ans[1] + dX2 = lm_matx_ans[2][0, 0] + y_hat = lm_matx_ans[3] + J = lm_matx_ans[4] + } + + // increase lambda ==> gradient descent method + lambda = when (Update_Type) { + 1 -> { // Levenberg + min(lambda * lambda_UP_fac, 1e7) + } + 2 -> { // Quadratic + lambda + kotlin.math.abs(((X2_try.as2D()[0, 0] - X2) / 2) / alpha) + } + else -> { // Nielsen + nu *= 2 + lambda * (nu / 2) + } + } + } + + if (prnt > 1) { + val chi_sq = X2 / DoF +// println("Iteration $settings | chi_sq=$chi_sq | lambda=$lambda") +// print("param: ") +// for (pn in 0 until Npar) { +// print(p[pn, 0].toString() + " ") +// } +// print("\ndp/p: ") +// for (pn in 0 until Npar) { +// print((h.as2D()[pn, 0] / p[pn, 0]).toString() + " ") +// } + resultInfo.iterations = settings.iteration + resultInfo.func_calls = settings.func_calls + resultInfo.result_chi_sq = chi_sq + resultInfo.result_lambda = lambda + resultInfo.result_parameters = p + } + + // update convergence history ... save _reduced_ Chi-square + // cvg_hst(iteration,:) = [ func_calls p' X2/DoF lambda ]; + + if (abs(JtWdy).max()!! < epsilon_1 && settings.iteration > 2) { +// println(" **** Convergence in r.h.s. (\"JtWdy\") ****") +// println(" **** epsilon_1 = $epsilon_1") + resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inRHS_JtWdy + resultInfo.epsilon = epsilon_1 + stop = true + } + if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon_2 && settings.iteration > 2) { +// println(" **** Convergence in Parameters ****") +// println(" **** epsilon_2 = $epsilon_2") + resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inParameters + resultInfo.epsilon = epsilon_2 + stop = true + } + if (X2 / DoF < epsilon_3 && settings.iteration > 2) { +// println(" **** Convergence in reduced Chi-square **** ") +// println(" **** epsilon_3 = $epsilon_3") + resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inReducedChi_square + resultInfo.epsilon = epsilon_3 + stop = true + } + if (settings.iteration == MaxIter) { +// println(" !! Maximum Number of Iterations Reached Without Convergence !!") + resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence + resultInfo.epsilon = 0.0 + stop = true + } + } // --- End of Main Loop + return resultInfo +} + +public data class LMSettings ( + var iteration:Int, + var func_calls: Int, + var example_number:Int +) + +/* matrix -> column of all elemnets */ +public fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D<Double> { + val shape = intArrayOf(tensor.shape.component1() * tensor.shape.component2(), 1) + val buffer = DoubleArray(tensor.shape.component1() * tensor.shape.component2()) + for (i in 0 until tensor.shape.component1()) { + for (j in 0 until tensor.shape.component2()) { + buffer[i * tensor.shape.component2() + j] = tensor[i, j] + } + } + val column = BroadcastDoubleTensorAlgebra.fromArray(ShapeND(shape), buffer).as2D() + return column +} + +/* column length */ +public fun length(column: MutableStructure2D<Double>) : Int { + return column.shape.component1() +} + +public fun MutableStructure2D<Double>.abs() { + for (i in 0 until this.shape.component1()) { + for (j in 0 until this.shape.component2()) { + this[i, j] = kotlin.math.abs(this[i, j]) + } + } +} + +public fun abs(input: MutableStructure2D<Double>): MutableStructure2D<Double> { + val tensor = BroadcastDoubleTensorAlgebra.ones( + ShapeND( + intArrayOf( + input.shape.component1(), + input.shape.component2() + ) + ) + ).as2D() + for (i in 0 until tensor.shape.component1()) { + for (j in 0 until tensor.shape.component2()) { + tensor[i, j] = kotlin.math.abs(input[i, j]) + } + } + return tensor +} + +public fun diag(input: MutableStructure2D<Double>): MutableStructure2D<Double> { + val tensor = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(input.shape.component1(), 1))).as2D() + for (i in 0 until tensor.shape.component1()) { + tensor[i, 0] = input[i, i] + } + return tensor +} + +public fun make_matrx_with_diagonal(column: MutableStructure2D<Double>): MutableStructure2D<Double> { + val size = column.shape.component1() + val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(size, size))).as2D() + for (i in 0 until size) { + tensor[i, i] = column[i, 0] + } + return tensor +} + +public fun lm_eye(size: Int): MutableStructure2D<Double> { + val column = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(size, 1))).as2D() + return make_matrx_with_diagonal(column) +} + +public fun largest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { + val a_sizeX = a.shape.component1() + val a_sizeY = a.shape.component2() + val b_sizeX = b.shape.component1() + val b_sizeY = b.shape.component2() + val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(a_sizeX, b_sizeX), max(a_sizeY, b_sizeY)))).as2D() + for (i in 0 until tensor.shape.component1()) { + for (j in 0 until tensor.shape.component2()) { + if (i < a_sizeX && i < b_sizeX && j < a_sizeY && j < b_sizeY) { + tensor[i, j] = max(a[i, j], b[i, j]) + } + else if (i < a_sizeX && j < a_sizeY) { + tensor[i, j] = a[i, j] + } + else { + tensor[i, j] = b[i, j] + } + } + } + return tensor +} + +public fun smallest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { + val a_sizeX = a.shape.component1() + val a_sizeY = a.shape.component2() + val b_sizeX = b.shape.component1() + val b_sizeY = b.shape.component2() + val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(a_sizeX, b_sizeX), max(a_sizeY, b_sizeY)))).as2D() + for (i in 0 until tensor.shape.component1()) { + for (j in 0 until tensor.shape.component2()) { + if (i < a_sizeX && i < b_sizeX && j < a_sizeY && j < b_sizeY) { + tensor[i, j] = min(a[i, j], b[i, j]) + } + else if (i < a_sizeX && j < a_sizeY) { + tensor[i, j] = a[i, j] + } + else { + tensor[i, j] = b[i, j] + } + } + } + return tensor +} + +public fun get_zero_indices(column: MutableStructure2D<Double>, epsilon: Double = 0.000001): MutableStructure2D<Double>? { + var idx = emptyArray<Double>() + for (i in 0 until column.shape.component1()) { + if (kotlin.math.abs(column[i, 0]) > epsilon) { + idx += (i + 1.0) + } + } + if (idx.size > 0) { + return BroadcastDoubleTensorAlgebra.fromArray(ShapeND(intArrayOf(idx.size, 1)), idx.toDoubleArray()).as2D() + } + return null +} + +public fun feval(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings) + : MutableStructure2D<Double> +{ + return func(t, p, settings) +} + +public fun lm_matx(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, + dX2: Int, J_input: MutableStructure2D<Double>, p: MutableStructure2D<Double>, + y_dat: MutableStructure2D<Double>, weight: MutableStructure2D<Double>, dp:MutableStructure2D<Double>, settings:LMSettings) : Array<MutableStructure2D<Double>> +{ + // default: dp = 0.001 + + val Npnt = length(y_dat) // number of data points + val Npar = length(p) // number of parameters + + val y_hat = feval(func, t, p, settings) // evaluate model using parameters 'p' + settings.func_calls += 1 + + var J = J_input + + if (settings.iteration % (2 * Npar) == 0 || dX2 > 0) { + J = lm_FD_J(func, t, p, y_hat, dp, settings).as2D() // finite difference + } + else { + J = lm_Broyden_J(p_old, y_old, J, p, y_hat).as2D() // rank-1 update + } + + val delta_y = y_dat.minus(y_hat) + + val Chi_sq = delta_y.transposed().dot( delta_y.times(weight) ).as2D() + val JtWJ = J.transposed().dot ( J.times( weight.dot(BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(1, Npar)))) ) ).as2D() + val JtWdy = J.transposed().dot( weight.times(delta_y) ).as2D() + + return arrayOf(JtWJ,JtWdy,Chi_sq,y_hat,J) +} + +public fun lm_Broyden_J(p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, J_input: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, y: MutableStructure2D<Double>): MutableStructure2D<Double> { + var J = J_input.copyToTensor() + + val h = p.minus(p_old) + val increase = y.minus(y_old).minus( J.dot(h) ).dot(h.transposed()).div( (h.transposed().dot(h)).as2D()[0, 0] ) + J = J.plus(increase) + + return J.as2D() +} + +public fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, settings: LMSettings) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y: MutableStructure2D<Double>, + dp: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + // default: dp = 0.001 * ones(1,n) + + val m = length(y) // number of data points + val n = length(p) // number of parameters + + val ps = p.copyToTensor().as2D() + val J = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, n))).as2D() // initialize Jacobian to Zero + val del = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(n, 1))).as2D() + + for (j in 0 until n) { + + del[j, 0] = dp[j, 0] * (1 + kotlin.math.abs(p[j, 0])) // parameter perturbation + p[j, 0] = ps[j, 0] + del[j, 0] // perturb parameter p(j) + + val epsilon = 0.0000001 + if (kotlin.math.abs(del[j, 0]) > epsilon) { + val y1 = feval(func, t, p, settings) + settings.func_calls += 1 + + if (dp[j, 0] < 0) { // backwards difference + for (i in 0 until J.shape.component1()) { + J[i, j] = (y1.as2D().minus(y).as2D())[i, 0] / del[j, 0] + } + } + else { + // Do tests for it + println("Potential mistake") + p[j, 0] = ps[j, 0] - del[j, 0] // central difference, additional func call + for (i in 0 until J.shape.component1()) { + J[i, j] = (y1.as2D().minus(feval(func, t, p, settings)).as2D())[i, 0] / (2 * del[j, 0]) + } + settings.func_calls += 1 + } + } + + p[j, 0] = ps[j, 0] // restore p(j) + } + + return J.as2D() +} diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index 6e5456c62..086c69e49 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -9,12 +9,6 @@ import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.core.* -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.minus -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.times -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.transposed -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus import kotlin.math.abs import kotlin.math.max import kotlin.math.min @@ -607,225 +601,4 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2 u[j, i] = this[j, i] } } -} - -data class LMSettings ( - var iteration:Int, - var func_calls: Int, - var example_number:Int -) - -/* matrix -> column of all elemnets */ -fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D<Double> { - val shape = intArrayOf(tensor.shape.component1() * tensor.shape.component2(), 1) - var buffer = DoubleArray(tensor.shape.component1() * tensor.shape.component2()) - for (i in 0 until tensor.shape.component1()) { - for (j in 0 until tensor.shape.component2()) { - buffer[i * tensor.shape.component2() + j] = tensor[i, j] - } - } - var column = BroadcastDoubleTensorAlgebra.fromArray(ShapeND(shape), buffer).as2D() - return column -} - -/* column length */ -fun length(column: MutableStructure2D<Double>) : Int { - return column.shape.component1() -} - -fun MutableStructure2D<Double>.abs() { - for (i in 0 until this.shape.component1()) { - for (j in 0 until this.shape.component2()) { - this[i, j] = abs(this[i, j]) - } - } -} - -fun abs(input: MutableStructure2D<Double>): MutableStructure2D<Double> { - val tensor = BroadcastDoubleTensorAlgebra.ones( - ShapeND( - intArrayOf( - input.shape.component1(), - input.shape.component2() - ) - ) - ).as2D() - for (i in 0 until tensor.shape.component1()) { - for (j in 0 until tensor.shape.component2()) { - tensor[i, j] = abs(input[i, j]) - } - } - return tensor -} - -fun diag(input: MutableStructure2D<Double>): MutableStructure2D<Double> { - val tensor = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(input.shape.component1(), 1))).as2D() - for (i in 0 until tensor.shape.component1()) { - tensor[i, 0] = input[i, i] - } - return tensor -} - -fun make_matrx_with_diagonal(column: MutableStructure2D<Double>): MutableStructure2D<Double> { - val size = column.shape.component1() - val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(size, size))).as2D() - for (i in 0 until size) { - tensor[i, i] = column[i, 0] - } - return tensor -} - -fun lm_eye(size: Int): MutableStructure2D<Double> { - val column = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(size, 1))).as2D() - return make_matrx_with_diagonal(column) -} - -fun largest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { - val a_sizeX = a.shape.component1() - val a_sizeY = a.shape.component2() - val b_sizeX = b.shape.component1() - val b_sizeY = b.shape.component2() - val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(a_sizeX, b_sizeX), max(a_sizeY, b_sizeY)))).as2D() - for (i in 0 until tensor.shape.component1()) { - for (j in 0 until tensor.shape.component2()) { - if (i < a_sizeX && i < b_sizeX && j < a_sizeY && j < b_sizeY) { - tensor[i, j] = max(a[i, j], b[i, j]) - } - else if (i < a_sizeX && j < a_sizeY) { - tensor[i, j] = a[i, j] - } - else { - tensor[i, j] = b[i, j] - } - } - } - return tensor -} - -fun smallest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { - val a_sizeX = a.shape.component1() - val a_sizeY = a.shape.component2() - val b_sizeX = b.shape.component1() - val b_sizeY = b.shape.component2() - val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(a_sizeX, b_sizeX), max(a_sizeY, b_sizeY)))).as2D() - for (i in 0 until tensor.shape.component1()) { - for (j in 0 until tensor.shape.component2()) { - if (i < a_sizeX && i < b_sizeX && j < a_sizeY && j < b_sizeY) { - tensor[i, j] = min(a[i, j], b[i, j]) - } - else if (i < a_sizeX && j < a_sizeY) { - tensor[i, j] = a[i, j] - } - else { - tensor[i, j] = b[i, j] - } - } - } - return tensor -} - -fun get_zero_indices(column: MutableStructure2D<Double>, epsilon: Double = 0.000001): MutableStructure2D<Double>? { - var idx = emptyArray<Double>() - for (i in 0 until column.shape.component1()) { - if (abs(column[i, 0]) > epsilon) { - idx += (i + 1.0) - } - } - if (idx.size > 0) { - return BroadcastDoubleTensorAlgebra.fromArray(ShapeND(intArrayOf(idx.size, 1)), idx.toDoubleArray()).as2D() - } - return null -} - -fun feval(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings) - : MutableStructure2D<Double> -{ - return func(t, p, settings) -} - -fun lm_matx(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, - dX2: Int, J_input: MutableStructure2D<Double>, p: MutableStructure2D<Double>, - y_dat: MutableStructure2D<Double>, weight: MutableStructure2D<Double>, dp:MutableStructure2D<Double>, settings:LMSettings) : Array<MutableStructure2D<Double>> -{ - // default: dp = 0.001 - - val Npnt = length(y_dat) // number of data points - val Npar = length(p) // number of parameters - - val y_hat = feval(func, t, p, settings) // evaluate model using parameters 'p' - settings.func_calls += 1 - - var J = J_input - - if (settings.iteration % (2 * Npar) == 0 || dX2 > 0) { - J = lm_FD_J(func, t, p, y_hat, dp, settings).as2D() // finite difference - } - else { - J = lm_Broyden_J(p_old, y_old, J, p, y_hat).as2D() // rank-1 update - } - - val delta_y = y_dat.minus(y_hat) - - val Chi_sq = delta_y.transposed().dot( delta_y.times(weight) ).as2D() - val JtWJ = J.transposed().dot ( J.times( weight.dot(BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(1, Npar)))) ) ).as2D() - val JtWdy = J.transposed().dot( weight.times(delta_y) ).as2D() - - return arrayOf(JtWJ,JtWdy,Chi_sq,y_hat,J) -} - -fun lm_Broyden_J(p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, J_input: MutableStructure2D<Double>, - p: MutableStructure2D<Double>, y: MutableStructure2D<Double>): MutableStructure2D<Double> { - var J = J_input.copyToTensor() - - val h = p.minus(p_old) - val increase = y.minus(y_old).minus( J.dot(h) ).dot(h.transposed()).div( (h.transposed().dot(h)).as2D()[0, 0] ) - J = J.plus(increase) - - return J.as2D() -} - -fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, settings: LMSettings) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y: MutableStructure2D<Double>, - dp: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { - // default: dp = 0.001 * ones(1,n) - - val m = length(y) // number of data points - val n = length(p) // number of parameters - - val ps = p.copyToTensor().as2D() - val J = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, n))).as2D() // initialize Jacobian to Zero - val del = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(n, 1))).as2D() - - for (j in 0 until n) { - - del[j, 0] = dp[j, 0] * (1 + abs(p[j, 0])) // parameter perturbation - p[j, 0] = ps[j, 0] + del[j, 0] // perturb parameter p(j) - - val epsilon = 0.0000001 - if (kotlin.math.abs(del[j, 0]) > epsilon) { - val y1 = feval(func, t, p, settings) - settings.func_calls += 1 - - if (dp[j, 0] < 0) { // backwards difference - for (i in 0 until J.shape.component1()) { - J[i, j] = (y1.as2D().minus(y).as2D())[i, 0] / del[j, 0] - } - } - else { - // Do tests for it - println("Potential mistake") - p[j, 0] = ps[j, 0] - del[j, 0] // central difference, additional func call - for (i in 0 until J.shape.component1()) { - J[i, j] = (y1.as2D().minus(feval(func, t, p, settings)).as2D())[i, 0] / (2 * del[j, 0]) - } - settings.func_calls += 1 - } - } - - p[j, 0] = ps[j, 0] // restore p(j) - } - - return J.as2D() -} +} \ No newline at end of file diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt index 5aea9b879..7222fc7a6 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt @@ -8,11 +8,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke -import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra -import space.kscience.kmath.tensors.core.internal.LMSettings import space.kscience.kmath.testutils.assertBufferEquals -import kotlin.math.roundToInt -import kotlin.math.roundToLong import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -209,100 +205,4 @@ internal class TestDoubleTensorAlgebra { assertTrue { ShapeND(5, 5) contentEquals res.shape } assertEquals(2.0, res[4, 4]) } - - @Test - fun testLM() = DoubleTensorAlgebra { - fun lm_func(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { - val m = t.shape.component1() - var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) - - if (settings.example_number == 1) { - y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( - DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) - ) - } - else if (settings.example_number == 2) { - val mt = t.max() - y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + - (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + - (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + - (t.times(1.0 / mt)).pow(4).times(p[3, 0]) - } - else if (settings.example_number == 3) { - y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) - .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) - } - - return y_hat.as2D() - } - - val lm_matx_y_dat = doubleArrayOf( - 19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807, - 14.7620, 15.1128, 16.0973, 15.1934, 15.8636, 15.4763, 15.6860, 15.1895, 15.3495, 16.6054, - 16.2247, 15.9854, 16.1421, 17.0960, 16.7769, 17.1997, 17.2767, 17.5882, 17.5378, 16.7894, - 17.7648, 18.2512, 18.1581, 16.7037, 17.8475, 17.9081, 18.3067, 17.9632, 18.2817, 19.1427, - 18.8130, 18.5658, 18.0056, 18.4607, 18.5918, 18.2544, 18.3731, 18.7511, 19.3181, 17.3066, - 17.9632, 19.0513, 18.7528, 18.2928, 18.5967, 17.8567, 17.7859, 18.4016, 18.9423, 18.4959, - 17.8000, 18.4251, 17.7829, 17.4645, 17.5221, 17.3517, 17.4637, 17.7563, 16.8471, 17.4558, - 17.7447, 17.1487, 17.3183, 16.8312, 17.7551, 17.0942, 15.6093, 16.4163, 15.3755, 16.6725, - 16.2332, 16.2316, 16.2236, 16.5361, 15.3721, 15.3347, 15.5815, 15.6319, 14.4538, 14.6044, - 14.7665, 13.3718, 15.0587, 13.8320, 14.7873, 13.6824, 14.2579, 14.2154, 13.5818, 13.8157 - ) - - var example_number = 1 - val p_init = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(4, 1)), doubleArrayOf(5.0, 2.0, 0.2, 10.0) - ).as2D() - - var t = ones(ShapeND(intArrayOf(100, 1))).as2D() - for (i in 0 until 100) { - t[i, 0] = t[i, 0] * (i + 1) - } - - val y_dat = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(100, 1)), lm_matx_y_dat - ).as2D() - - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 4.0 } - ).as2D() - - val dp = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } - ).as2D() - - val p_min = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(4, 1)), doubleArrayOf(-50.0, -20.0, -2.0, -100.0) - ).as2D() - - val p_max = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0) - ).as2D() - - val consts = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) - ).as2D() - - val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) - - val result = lm(::lm_func, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts, 10, example_number) - assertEquals(13, result.iterations) - assertEquals(31, result.func_calls) - assertEquals(1, result.example_number) - assertEquals(0.9131368192633, (result.result_chi_sq * 1e13).roundToLong() / 1e13) - assertEquals(3.7790980 * 1e-7, (result.result_lambda * 1e13).roundToLong() / 1e13) - assertEquals(result.typeOfConvergence, LinearOpsTensorAlgebra.TypeOfConvergence.inParameters) - val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(4, 1)), doubleArrayOf(20.527230909086, 9.833627103230, 0.997571256572, 50.174445822506) - ).as2D() - result.result_parameters = result.result_parameters.map { x -> (x * 1e12).toLong() / 1e12}.as2D() - val receivedParameters = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(4, 1)), doubleArrayOf(result.result_parameters[0, 0], result.result_parameters[1, 0], - result.result_parameters[2, 0], result.result_parameters[3, 0]) - ).as2D() - assertEquals(expectedParameters[0, 0], receivedParameters[0, 0]) - assertEquals(expectedParameters[1, 0], receivedParameters[1, 0]) - assertEquals(expectedParameters[2, 0], receivedParameters[2, 0]) - assertEquals(expectedParameters[3, 0], receivedParameters[3, 0]) - } } diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index f554a742c..db8bc9d20 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -15,7 +15,6 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times -import space.kscience.kmath.tensors.core.internal.LMSettings import kotlin.math.roundToLong import kotlin.test.Test import kotlin.test.assertEquals From c940645e2e2591314ce7149370ccad9a53b3832d Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 6 Jun 2023 17:43:38 +0300 Subject: [PATCH 021/103] fix simja version --- gradle.properties | 5 +++-- kmath-symja/build.gradle.kts | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 76f51c4af..0fdf1a058 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,5 +12,6 @@ org.gradle.jvmargs=-Xmx4096m org.gradle.parallel=true org.gradle.workers.max=4 -toolsVersion=0.14.8-kotlin-1.9.0-Beta -#kscience.wasm.disabled=true \ No newline at end of file +toolsVersion=0.14.9-kotlin-1.9.0-Beta +kotlin.experimental.tryK2=true +kscience.wasm.disabled=true \ No newline at end of file diff --git a/kmath-symja/build.gradle.kts b/kmath-symja/build.gradle.kts index 8741de2ae..a996f3bec 100644 --- a/kmath-symja/build.gradle.kts +++ b/kmath-symja/build.gradle.kts @@ -10,7 +10,7 @@ plugins { description = "Symja integration module" dependencies { - api("org.matheclipse:matheclipse-core:2.0.0-SNAPSHOT") { + api("org.matheclipse:matheclipse-core:2.0.0") { // Incorrect transitive dependencies exclude("org.apfloat", "apfloat") exclude("org.hipparchus", "hipparchus-clustering") From 963e14b00a273c55049f66dcb96a93e1c158d7c4 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Tue, 6 Jun 2023 20:07:42 +0300 Subject: [PATCH 022/103] move enums --- kmath-symja/build.gradle.kts | 2 +- .../tensors/api/LinearOpsTensorAlgebra.kt | 18 ----------- .../core/LevenbergMarquardtAlgorithm.kt | 32 +++++++++++++++---- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/kmath-symja/build.gradle.kts b/kmath-symja/build.gradle.kts index 8741de2ae..a996f3bec 100644 --- a/kmath-symja/build.gradle.kts +++ b/kmath-symja/build.gradle.kts @@ -10,7 +10,7 @@ plugins { description = "Symja integration module" dependencies { - api("org.matheclipse:matheclipse-core:2.0.0-SNAPSHOT") { + api("org.matheclipse:matheclipse-core:2.0.0") { // Incorrect transitive dependencies exclude("org.apfloat", "apfloat") exclude("org.hipparchus", "hipparchus-clustering") diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt index 6b3859316..f2c7f1821 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt @@ -111,22 +111,4 @@ public interface LinearOpsTensorAlgebra<T, A : Field<T>> : TensorPartialDivision * @return the square matrix x which is the solution of the equation. */ public fun solve(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> - - public enum class TypeOfConvergence{ - inRHS_JtWdy, - inParameters, - inReducedChi_square, - noConvergence - } - - public data class LMResultInfo ( - var iterations:Int, - var func_calls: Int, - var example_number: Int, - var result_chi_sq: Double, - var result_lambda: Double, - var result_parameters: MutableStructure2D<Double>, - var typeOfConvergence: TypeOfConvergence, - var epsilon: Double - ) } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index f4b50626a..4323a86a3 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -19,14 +19,32 @@ import kotlin.math.min import kotlin.math.pow import kotlin.reflect.KFunction3 +public enum class TypeOfConvergence{ + inRHS_JtWdy, + inParameters, + inReducedChi_square, + noConvergence +} + +public data class LMResultInfo ( + var iterations:Int, + var func_calls: Int, + var example_number: Int, + var result_chi_sq: Double, + var result_lambda: Double, + var result_parameters: MutableStructure2D<Double>, + var typeOfConvergence: TypeOfConvergence, + var epsilon: Double +) + public fun DoubleTensorAlgebra.lm( func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, - c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LinearOpsTensorAlgebra.LMResultInfo { + c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LMResultInfo { - val resultInfo = LinearOpsTensorAlgebra.LMResultInfo(0, 0, example_number, 0.0, - 0.0, p_input, LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence, 0.0) + val resultInfo = LMResultInfo(0, 0, example_number, 0.0, + 0.0, p_input, TypeOfConvergence.noConvergence, 0.0) val eps:Double = 2.2204e-16 @@ -303,27 +321,27 @@ public fun DoubleTensorAlgebra.lm( if (abs(JtWdy).max()!! < epsilon_1 && settings.iteration > 2) { // println(" **** Convergence in r.h.s. (\"JtWdy\") ****") // println(" **** epsilon_1 = $epsilon_1") - resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inRHS_JtWdy + resultInfo.typeOfConvergence = TypeOfConvergence.inRHS_JtWdy resultInfo.epsilon = epsilon_1 stop = true } if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon_2 && settings.iteration > 2) { // println(" **** Convergence in Parameters ****") // println(" **** epsilon_2 = $epsilon_2") - resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inParameters + resultInfo.typeOfConvergence = TypeOfConvergence.inParameters resultInfo.epsilon = epsilon_2 stop = true } if (X2 / DoF < epsilon_3 && settings.iteration > 2) { // println(" **** Convergence in reduced Chi-square **** ") // println(" **** epsilon_3 = $epsilon_3") - resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.inReducedChi_square + resultInfo.typeOfConvergence = TypeOfConvergence.inReducedChi_square resultInfo.epsilon = epsilon_3 stop = true } if (settings.iteration == MaxIter) { // println(" !! Maximum Number of Iterations Reached Without Convergence !!") - resultInfo.typeOfConvergence = LinearOpsTensorAlgebra.TypeOfConvergence.noConvergence + resultInfo.typeOfConvergence = TypeOfConvergence.noConvergence resultInfo.epsilon = 0.0 stop = true } From 29d392a8a05aa8bb27b342a53b5920607644217e Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Tue, 6 Jun 2023 20:31:15 +0300 Subject: [PATCH 023/103] fix problem with imports --- .../LevenbergMarquardt/StaticLm/staticDifficultTest.kt | 3 ++- .../tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt | 4 ++-- .../tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt | 3 ++- .../kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt | 3 ++- .../kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt | 3 +-- 5 files changed, 9 insertions(+), 7 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt index 0a502afa8..e996b7f7e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt @@ -12,7 +12,8 @@ import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.internal.LMSettings +import space.kscience.kmath.tensors.core.LMSettings +import space.kscience.kmath.tensors.core.lm import kotlin.math.roundToInt fun main() { diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt index bae5a674f..d9e5f350e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt @@ -11,9 +11,9 @@ import space.kscience.kmath.nd.component1 import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm import space.kscience.kmath.tensors.LevenbergMarquardt.funcEasyForLm import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncEasy -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.internal.LMSettings +import space.kscience.kmath.tensors.core.LMSettings +import space.kscience.kmath.tensors.core.lm import kotlin.math.roundToInt fun main() { diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt index 02917caf2..b5553a930 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt @@ -13,7 +13,8 @@ import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times -import space.kscience.kmath.tensors.core.internal.LMSettings +import space.kscience.kmath.tensors.core.LMSettings +import space.kscience.kmath.tensors.core.lm import kotlin.math.roundToInt fun main() { val NData = 100 diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index 5a1037618..46bda40c6 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -11,7 +11,8 @@ import space.kscience.kmath.nd.* import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.internal.LMSettings +import space.kscience.kmath.tensors.core.LMSettings +import space.kscience.kmath.tensors.core.lm import kotlin.random.Random import kotlin.reflect.KFunction3 diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt index 5b194ab6b..a22de71d8 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt @@ -16,9 +16,8 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times +import space.kscience.kmath.tensors.core.LMSettings import space.kscience.kmath.tensors.core.asDoubleTensor -import space.kscience.kmath.tensors.core.internal.LMSettings -import kotlin.math.roundToInt public data class StartDataLm ( var lm_matx_y_dat: MutableStructure2D<Double>, From 1ed40cd8ce5bd0f6d70da097b328267c2a49203c Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Tue, 6 Jun 2023 20:43:59 +0300 Subject: [PATCH 024/103] fix problem with imports --- .../space/kscience/kmath/tensors/core/TestLmAlgorithm.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index db8bc9d20..dae3006c9 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -10,7 +10,6 @@ import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.as2D import space.kscience.kmath.nd.component1 import space.kscience.kmath.operations.invoke -import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow @@ -135,7 +134,7 @@ class TestLmAlgorithm { assertEquals(1, result.example_number) assertEquals(0.9131368192633, (result.result_chi_sq * 1e13).roundToLong() / 1e13) assertEquals(3.7790980 * 1e-7, (result.result_lambda * 1e13).roundToLong() / 1e13) - assertEquals(result.typeOfConvergence, LinearOpsTensorAlgebra.TypeOfConvergence.inParameters) + assertEquals(result.typeOfConvergence, TypeOfConvergence.inParameters) val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(4, 1)), doubleArrayOf(20.527230909086, 9.833627103230, 0.997571256572, 50.174445822506) ).as2D() From 0c7f5697da6e8a52176ca5f90f780b37ed918f07 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 7 Jun 2023 00:50:27 +0300 Subject: [PATCH 025/103] add documentation for enum TypeOfConvergence --- .../core/LevenbergMarquardtAlgorithm.kt | 66 +++++++++---------- .../kmath/tensors/core/TestLmAlgorithm.kt | 2 +- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index 4323a86a3..deb7ee300 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -7,7 +7,6 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.linear.transpose import space.kscience.kmath.nd.* -import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.minus @@ -19,11 +18,26 @@ import kotlin.math.min import kotlin.math.pow import kotlin.reflect.KFunction3 +/** + * Type of convergence achieved as a result of executing the Levenberg-Marquardt algorithm + * + * InGradient: gradient convergence achieved + * (max(J^T W dy) < epsilon1 = opts[2], + * where J - Jacobi matrix (dy^/dp) for the current approximation y^, + * W - weight matrix from input, dy = (y - y^(p))) + * InParameters: convergence in parameters achieved + * (max(h_i / p_i) < epsilon2 = opts[3], + * where h_i - offset for parameter p_i on the current iteration) + * InReducedChiSquare: chi-squared convergence achieved + * (chi squared value divided by (m - n + 1) < epsilon2 = opts[4], + * where n - number of parameters, m - amount of points + * NoConvergence: the maximum number of iterations has been reached without reaching convergence + */ public enum class TypeOfConvergence{ - inRHS_JtWdy, - inParameters, - inReducedChi_square, - noConvergence + InGradient, + InParameters, + InReducedChiSquare, + NoConvergence } public data class LMResultInfo ( @@ -37,6 +51,12 @@ public data class LMResultInfo ( var epsilon: Double ) +public data class LMSettings ( + var iteration:Int, + var func_calls: Int, + var example_number:Int +) + public fun DoubleTensorAlgebra.lm( func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, @@ -44,7 +64,7 @@ public fun DoubleTensorAlgebra.lm( c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LMResultInfo { val resultInfo = LMResultInfo(0, 0, example_number, 0.0, - 0.0, p_input, TypeOfConvergence.noConvergence, 0.0) + 0.0, p_input, TypeOfConvergence.NoConvergence, 0.0) val eps:Double = 2.2204e-16 @@ -299,15 +319,6 @@ public fun DoubleTensorAlgebra.lm( if (prnt > 1) { val chi_sq = X2 / DoF -// println("Iteration $settings | chi_sq=$chi_sq | lambda=$lambda") -// print("param: ") -// for (pn in 0 until Npar) { -// print(p[pn, 0].toString() + " ") -// } -// print("\ndp/p: ") -// for (pn in 0 until Npar) { -// print((h.as2D()[pn, 0] / p[pn, 0]).toString() + " ") -// } resultInfo.iterations = settings.iteration resultInfo.func_calls = settings.func_calls resultInfo.result_chi_sq = chi_sq @@ -319,42 +330,29 @@ public fun DoubleTensorAlgebra.lm( // cvg_hst(iteration,:) = [ func_calls p' X2/DoF lambda ]; if (abs(JtWdy).max()!! < epsilon_1 && settings.iteration > 2) { -// println(" **** Convergence in r.h.s. (\"JtWdy\") ****") -// println(" **** epsilon_1 = $epsilon_1") - resultInfo.typeOfConvergence = TypeOfConvergence.inRHS_JtWdy + resultInfo.typeOfConvergence = TypeOfConvergence.InGradient resultInfo.epsilon = epsilon_1 stop = true } if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon_2 && settings.iteration > 2) { -// println(" **** Convergence in Parameters ****") -// println(" **** epsilon_2 = $epsilon_2") - resultInfo.typeOfConvergence = TypeOfConvergence.inParameters + resultInfo.typeOfConvergence = TypeOfConvergence.InParameters resultInfo.epsilon = epsilon_2 stop = true } if (X2 / DoF < epsilon_3 && settings.iteration > 2) { -// println(" **** Convergence in reduced Chi-square **** ") -// println(" **** epsilon_3 = $epsilon_3") - resultInfo.typeOfConvergence = TypeOfConvergence.inReducedChi_square + resultInfo.typeOfConvergence = TypeOfConvergence.InReducedChiSquare resultInfo.epsilon = epsilon_3 stop = true } if (settings.iteration == MaxIter) { -// println(" !! Maximum Number of Iterations Reached Without Convergence !!") - resultInfo.typeOfConvergence = TypeOfConvergence.noConvergence + resultInfo.typeOfConvergence = TypeOfConvergence.NoConvergence resultInfo.epsilon = 0.0 stop = true } - } // --- End of Main Loop + } return resultInfo } -public data class LMSettings ( - var iteration:Int, - var func_calls: Int, - var example_number:Int -) - /* matrix -> column of all elemnets */ public fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D<Double> { val shape = intArrayOf(tensor.shape.component1() * tensor.shape.component2(), 1) @@ -564,7 +562,7 @@ public fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double> } } - p[j, 0] = ps[j, 0] // restore p(j) + p[j, 0] = ps[j, 0] } return J.as2D() diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index dae3006c9..1112043fc 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -134,7 +134,7 @@ class TestLmAlgorithm { assertEquals(1, result.example_number) assertEquals(0.9131368192633, (result.result_chi_sq * 1e13).roundToLong() / 1e13) assertEquals(3.7790980 * 1e-7, (result.result_lambda * 1e13).roundToLong() / 1e13) - assertEquals(result.typeOfConvergence, TypeOfConvergence.inParameters) + assertEquals(result.typeOfConvergence, TypeOfConvergence.InParameters) val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(4, 1)), doubleArrayOf(20.527230909086, 9.833627103230, 0.997571256572, 50.174445822506) ).as2D() From cac5b513f30515e38b4f7706b7161905733781e3 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 7 Jun 2023 01:55:38 +0300 Subject: [PATCH 026/103] made class for settings private and removed settings as input from a custom function --- .../StaticLm/staticDifficultTest.kt | 13 +-- .../StaticLm/staticEasyTest.kt | 9 +- .../StaticLm/staticMiddleTest.kt | 19 ++-- .../StreamingLm/streamLm.kt | 7 +- .../LevenbergMarquardt/functionsToOptimize.kt | 60 +++++----- .../core/LevenbergMarquardtAlgorithm.kt | 107 +++++++++--------- .../kmath/tensors/core/TestLmAlgorithm.kt | 38 +++---- 7 files changed, 125 insertions(+), 128 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt index e996b7f7e..24cfa955a 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt @@ -12,7 +12,6 @@ import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.LMSettings import space.kscience.kmath.tensors.core.lm import kotlin.math.roundToInt @@ -29,9 +28,9 @@ fun main() { p_example[i, 0] = p_example[i, 0] + i - 25 } - val settings = LMSettings(0, 0, 1) + val exampleNumber = 1 - var y_hat = funcDifficultForLm(t_example, p_example, settings) + var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { @@ -72,14 +71,14 @@ fun main() { ) println("Parameters:") - for (i in 0 until result.result_parameters.shape.component1()) { - val x = (result.result_parameters[i, 0] * 10000).roundToInt() / 10000.0 + for (i in 0 until result.resultParameters.shape.component1()) { + val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0 print("$x ") } println() println("Y true and y received:") - var y_hat_after = funcDifficultForLm(t_example, result.result_parameters, settings) + var y_hat_after = funcDifficultForLm(t_example, result.resultParameters, exampleNumber) for (i in 0 until y_hat.shape.component1()) { val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0 val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 @@ -87,7 +86,7 @@ fun main() { } println("Сhi_sq:") - println(result.result_chi_sq) + println(result.resultChiSq) println("Number of iterations:") println(result.iterations) } \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt index d9e5f350e..c7b2b0def 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt @@ -12,7 +12,6 @@ import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm import space.kscience.kmath.tensors.LevenbergMarquardt.funcEasyForLm import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncEasy import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.LMSettings import space.kscience.kmath.tensors.core.lm import kotlin.math.roundToInt @@ -35,14 +34,14 @@ fun main() { ) println("Parameters:") - for (i in 0 until result.result_parameters.shape.component1()) { - val x = (result.result_parameters[i, 0] * 10000).roundToInt() / 10000.0 + for (i in 0 until result.resultParameters.shape.component1()) { + val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0 print("$x ") } println() println("Y true and y received:") - var y_hat_after = funcDifficultForLm(startedData.t, result.result_parameters, LMSettings(0, 0, startedData.example_number)) + var y_hat_after = funcDifficultForLm(startedData.t, result.resultParameters, startedData.example_number) for (i in 0 until startedData.y_dat.shape.component1()) { val x = (startedData.y_dat[i, 0] * 10000).roundToInt() / 10000.0 val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 @@ -50,7 +49,7 @@ fun main() { } println("Сhi_sq:") - println(result.result_chi_sq) + println(result.resultChiSq) println("Number of iterations:") println(result.iterations) } \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt index b5553a930..471143102 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt @@ -12,8 +12,6 @@ import space.kscience.kmath.tensors.LevenbergMarquardt.funcMiddleForLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times -import space.kscience.kmath.tensors.core.LMSettings import space.kscience.kmath.tensors.core.lm import kotlin.math.roundToInt fun main() { @@ -29,16 +27,15 @@ fun main() { p_example[i, 0] = p_example[i, 0] + i - 25 } - val settings = LMSettings(0, 0, 1) + val exampleNumber = 1 - var y_hat = funcMiddleForLm(t_example, p_example, settings) + var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { p_init[i, 0] = (p_example[i, 0] + 0.9) } -// val p_init = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) -// val p_init = p_example + var t = t_example val y_dat = y_hat val weight = BroadcastDoubleTensorAlgebra.fromArray( @@ -54,7 +51,7 @@ fun main() { val consts = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) ).as2D() - val opts = doubleArrayOf(3.0, 10000.0, 1e-3, 1e-3, 1e-3, 1e-3, 1e-15, 11.0, 9.0, 1.0) + val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) val result = DoubleTensorAlgebra.lm( ::funcMiddleForLm, @@ -72,14 +69,14 @@ fun main() { ) println("Parameters:") - for (i in 0 until result.result_parameters.shape.component1()) { - val x = (result.result_parameters[i, 0] * 10000).roundToInt() / 10000.0 + for (i in 0 until result.resultParameters.shape.component1()) { + val x = (result.resultParameters[i, 0] * 10000).roundToInt() / 10000.0 print("$x ") } println() - var y_hat_after = funcMiddleForLm(t_example, result.result_parameters, settings) + var y_hat_after = funcMiddleForLm(t_example, result.resultParameters, exampleNumber) for (i in 0 until y_hat.shape.component1()) { val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0 val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 @@ -87,7 +84,7 @@ fun main() { } println("Сhi_sq:") - println(result.result_chi_sq) + println(result.resultChiSq) println("Number of iterations:") println(result.iterations) } \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index 46bda40c6..f031d82bf 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -11,12 +11,11 @@ import space.kscience.kmath.nd.* import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.LMSettings import space.kscience.kmath.tensors.core.lm import kotlin.random.Random import kotlin.reflect.KFunction3 -fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, +fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, Int, MutableStructure2D<Double>>, startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int): Flow<MutableStructure2D<Double>> = flow{ var example_number = startData.example_number @@ -48,9 +47,9 @@ fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D< 10, example_number ) - emit(result.result_parameters) + emit(result.resultParameters) delay(launchFrequencyInMs) - p_init = result.result_parameters + p_init = result.resultParameters y_dat = generateNewYDat(y_dat, 0.1) if (!isEndless) steps -= 1 } diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt index a22de71d8..537b86da3 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt @@ -16,7 +16,6 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times -import space.kscience.kmath.tensors.core.LMSettings import space.kscience.kmath.tensors.core.asDoubleTensor public data class StartDataLm ( @@ -33,23 +32,31 @@ public data class StartDataLm ( var opts: DoubleArray ) -fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { +fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() - var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) - val mt = t.max() - for(i in 0 until p.shape.component1()){ - y_hat = y_hat.plus( (t.times(1.0 / mt)).times(p[i, 0]) ) + if (exampleNumber == 1) { + y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( + DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) + ) } - - for(i in 0 until 4){ - y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, settings).asDoubleTensor() + else if (exampleNumber == 2) { + val mt = t.max() + y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + + (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + + (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + + (t.times(1.0 / mt)).pow(4).times(p[3, 0]) + } + else if (exampleNumber == 3) { + y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) + .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) } return y_hat.as2D() } -fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { +fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) @@ -59,36 +66,29 @@ fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double> } for(i in 0 until 5){ - y_hat = funcEasyForLm(y_hat.as2D(), p, settings).asDoubleTensor() + y_hat = funcEasyForLm(y_hat.as2D(), p, exampleNumber).asDoubleTensor() } return y_hat.as2D() } -fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { +fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) - if (settings.example_number == 1) { - y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( - DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) - ) + val mt = t.max() + for(i in 0 until p.shape.component1()){ + y_hat = y_hat.plus( (t.times(1.0 / mt)).times(p[i, 0]) ) } - else if (settings.example_number == 2) { - val mt = t.max() - y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + - (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + - (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + - (t.times(1.0 / mt)).pow(4).times(p[3, 0]) - } - else if (settings.example_number == 3) { - y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) - .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) + + for(i in 0 until 4){ + y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, exampleNumber).asDoubleTensor() } return y_hat.as2D() } + fun getStartDataForFuncDifficult(): StartDataLm { val NData = 200 var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() @@ -102,9 +102,9 @@ fun getStartDataForFuncDifficult(): StartDataLm { p_example[i, 0] = p_example[i, 0] + i - 25 } - val settings = LMSettings(0, 0, 1) + val exampleNumber = 1 - var y_hat = funcDifficultForLm(t_example, p_example, settings) + var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { @@ -144,9 +144,9 @@ fun getStartDataForFuncMiddle(): StartDataLm { p_example[i, 0] = p_example[i, 0] + i - 25 } - val settings = LMSettings(0, 0, 1) + val exampleNumber = 1 - var y_hat = funcMiddleForLm(t_example, p_example, settings) + var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index deb7ee300..7fbf6ecd8 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -40,36 +40,39 @@ public enum class TypeOfConvergence{ NoConvergence } +/** + * Class for the data obtained as a result of the execution of the Levenberg-Marquardt algorithm + * + * iterations: number of completed iterations + * funcCalls: the number of evaluations of the input function during execution + * resultChiSq: chi squared value on final parameters + * resultLambda: final lambda parameter used to calculate the offset + * resultParameters: final parameters + * typeOfConvergence: type of convergence + */ public data class LMResultInfo ( var iterations:Int, - var func_calls: Int, - var example_number: Int, - var result_chi_sq: Double, - var result_lambda: Double, - var result_parameters: MutableStructure2D<Double>, + var funcCalls: Int, + var resultChiSq: Double, + var resultLambda: Double, + var resultParameters: MutableStructure2D<Double>, var typeOfConvergence: TypeOfConvergence, - var epsilon: Double -) - -public data class LMSettings ( - var iteration:Int, - var func_calls: Int, - var example_number:Int ) public fun DoubleTensorAlgebra.lm( - func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings, MutableStructure2D<Double>>, + func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, Int, MutableStructure2D<Double>>, p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LMResultInfo { - val resultInfo = LMResultInfo(0, 0, example_number, 0.0, - 0.0, p_input, TypeOfConvergence.NoConvergence, 0.0) + + val resultInfo = LMResultInfo(0, 0, 0.0, + 0.0, p_input, TypeOfConvergence.NoConvergence) val eps:Double = 2.2204e-16 val settings = LMSettings(0, 0, example_number) - settings.func_calls = 0 // running count of function evaluations + settings.funcCalls = 0 // running count of function evaluations var p = p_input val y_dat = y_dat_input @@ -160,7 +163,7 @@ public fun DoubleTensorAlgebra.lm( val idx = get_zero_indices(dp) // indices of the parameters to be fit val Nfit = idx?.shape?.component1() // number of parameters to fit var stop = false // termination flag - val y_init = feval(func, t, p, settings) // residual error using p_try + val y_init = feval(func, t, p, example_number) // residual error using p_try if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / kotlin.math.abs(weight[0, 0])).as2D() @@ -219,7 +222,7 @@ public fun DoubleTensorAlgebra.lm( var p_try = (p + h).as2D() // update the [idx] elements p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try.as2D()), p_max) // apply constraints - var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try + var delta_y = y_dat.minus(feval(func, t, p_try, example_number)) // residual error using p_try for (i in 0 until delta_y.shape.component1()) { // floating point error; break for (j in 0 until delta_y.shape.component2()) { @@ -230,7 +233,7 @@ public fun DoubleTensorAlgebra.lm( } } - settings.func_calls += 1 + settings.funcCalls += 1 val tmp = delta_y.times(weight) var X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria @@ -244,8 +247,8 @@ public fun DoubleTensorAlgebra.lm( p_try = p.plus(h).as2D() // update only [idx] elements p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try), p_max) // apply constraints - var delta_y = y_dat.minus(feval(func, t, p_try, settings)) // residual error using p_try - settings.func_calls += 1 + var delta_y = y_dat.minus(feval(func, t, p_try, example_number)) // residual error using p_try + settings.funcCalls += 1 val tmp = delta_y.times(weight) X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria @@ -320,10 +323,10 @@ public fun DoubleTensorAlgebra.lm( if (prnt > 1) { val chi_sq = X2 / DoF resultInfo.iterations = settings.iteration - resultInfo.func_calls = settings.func_calls - resultInfo.result_chi_sq = chi_sq - resultInfo.result_lambda = lambda - resultInfo.result_parameters = p + resultInfo.funcCalls = settings.funcCalls + resultInfo.resultChiSq = chi_sq + resultInfo.resultLambda = lambda + resultInfo.resultParameters = p } // update convergence history ... save _reduced_ Chi-square @@ -331,30 +334,32 @@ public fun DoubleTensorAlgebra.lm( if (abs(JtWdy).max()!! < epsilon_1 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InGradient - resultInfo.epsilon = epsilon_1 stop = true } if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon_2 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InParameters - resultInfo.epsilon = epsilon_2 stop = true } if (X2 / DoF < epsilon_3 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InReducedChiSquare - resultInfo.epsilon = epsilon_3 stop = true } if (settings.iteration == MaxIter) { resultInfo.typeOfConvergence = TypeOfConvergence.NoConvergence - resultInfo.epsilon = 0.0 stop = true } } return resultInfo } +private data class LMSettings ( + var iteration:Int, + var funcCalls: Int, + var exampleNumber:Int +) + /* matrix -> column of all elemnets */ -public fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D<Double> { +private fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D<Double> { val shape = intArrayOf(tensor.shape.component1() * tensor.shape.component2(), 1) val buffer = DoubleArray(tensor.shape.component1() * tensor.shape.component2()) for (i in 0 until tensor.shape.component1()) { @@ -367,11 +372,11 @@ public fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D< } /* column length */ -public fun length(column: MutableStructure2D<Double>) : Int { +private fun length(column: MutableStructure2D<Double>) : Int { return column.shape.component1() } -public fun MutableStructure2D<Double>.abs() { +private fun MutableStructure2D<Double>.abs() { for (i in 0 until this.shape.component1()) { for (j in 0 until this.shape.component2()) { this[i, j] = kotlin.math.abs(this[i, j]) @@ -379,7 +384,7 @@ public fun MutableStructure2D<Double>.abs() { } } -public fun abs(input: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun abs(input: MutableStructure2D<Double>): MutableStructure2D<Double> { val tensor = BroadcastDoubleTensorAlgebra.ones( ShapeND( intArrayOf( @@ -396,7 +401,7 @@ public fun abs(input: MutableStructure2D<Double>): MutableStructure2D<Double> { return tensor } -public fun diag(input: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun diag(input: MutableStructure2D<Double>): MutableStructure2D<Double> { val tensor = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(input.shape.component1(), 1))).as2D() for (i in 0 until tensor.shape.component1()) { tensor[i, 0] = input[i, i] @@ -404,7 +409,7 @@ public fun diag(input: MutableStructure2D<Double>): MutableStructure2D<Double> { return tensor } -public fun make_matrx_with_diagonal(column: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun make_matrx_with_diagonal(column: MutableStructure2D<Double>): MutableStructure2D<Double> { val size = column.shape.component1() val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(size, size))).as2D() for (i in 0 until size) { @@ -413,12 +418,12 @@ public fun make_matrx_with_diagonal(column: MutableStructure2D<Double>): Mutable return tensor } -public fun lm_eye(size: Int): MutableStructure2D<Double> { +private fun lm_eye(size: Int): MutableStructure2D<Double> { val column = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(size, 1))).as2D() return make_matrx_with_diagonal(column) } -public fun largest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun largest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { val a_sizeX = a.shape.component1() val a_sizeY = a.shape.component2() val b_sizeX = b.shape.component1() @@ -440,7 +445,7 @@ public fun largest_element_comparison(a: MutableStructure2D<Double>, b: MutableS return tensor } -public fun smallest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun smallest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { val a_sizeX = a.shape.component1() val a_sizeY = a.shape.component2() val b_sizeX = b.shape.component1() @@ -462,7 +467,7 @@ public fun smallest_element_comparison(a: MutableStructure2D<Double>, b: Mutable return tensor } -public fun get_zero_indices(column: MutableStructure2D<Double>, epsilon: Double = 0.000001): MutableStructure2D<Double>? { +private fun get_zero_indices(column: MutableStructure2D<Double>, epsilon: Double = 0.000001): MutableStructure2D<Double>? { var idx = emptyArray<Double>() for (i in 0 until column.shape.component1()) { if (kotlin.math.abs(column[i, 0]) > epsilon) { @@ -475,14 +480,14 @@ public fun get_zero_indices(column: MutableStructure2D<Double>, epsilon: Double return null } -public fun feval(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings) +private fun feval(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int) : MutableStructure2D<Double> { - return func(t, p, settings) + return func(t, p, exampleNumber) } -public fun lm_matx(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, LMSettings) -> MutableStructure2D<Double>, +private fun lm_matx(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, t: MutableStructure2D<Double>, p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, dX2: Int, J_input: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y_dat: MutableStructure2D<Double>, weight: MutableStructure2D<Double>, dp:MutableStructure2D<Double>, settings:LMSettings) : Array<MutableStructure2D<Double>> @@ -492,8 +497,8 @@ public fun lm_matx(func: (MutableStructure2D<Double>, MutableStructure2D<Double> val Npnt = length(y_dat) // number of data points val Npar = length(p) // number of parameters - val y_hat = feval(func, t, p, settings) // evaluate model using parameters 'p' - settings.func_calls += 1 + val y_hat = feval(func, t, p, settings.exampleNumber) // evaluate model using parameters 'p' + settings.funcCalls += 1 var J = J_input @@ -513,7 +518,7 @@ public fun lm_matx(func: (MutableStructure2D<Double>, MutableStructure2D<Double> return arrayOf(JtWJ,JtWdy,Chi_sq,y_hat,J) } -public fun lm_Broyden_J(p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, J_input: MutableStructure2D<Double>, +private fun lm_Broyden_J(p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, J_input: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y: MutableStructure2D<Double>): MutableStructure2D<Double> { var J = J_input.copyToTensor() @@ -524,7 +529,7 @@ public fun lm_Broyden_J(p_old: MutableStructure2D<Double>, y_old: MutableStructu return J.as2D() } -public fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, settings: LMSettings) -> MutableStructure2D<Double>, +private fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, exampleNumber: Int) -> MutableStructure2D<Double>, t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y: MutableStructure2D<Double>, dp: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { // default: dp = 0.001 * ones(1,n) @@ -543,8 +548,8 @@ public fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double> val epsilon = 0.0000001 if (kotlin.math.abs(del[j, 0]) > epsilon) { - val y1 = feval(func, t, p, settings) - settings.func_calls += 1 + val y1 = feval(func, t, p, settings.exampleNumber) + settings.funcCalls += 1 if (dp[j, 0] < 0) { // backwards difference for (i in 0 until J.shape.component1()) { @@ -556,9 +561,9 @@ public fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double> println("Potential mistake") p[j, 0] = ps[j, 0] - del[j, 0] // central difference, additional func call for (i in 0 until J.shape.component1()) { - J[i, j] = (y1.as2D().minus(feval(func, t, p, settings)).as2D())[i, 0] / (2 * del[j, 0]) + J[i, j] = (y1.as2D().minus(feval(func, t, p, settings.exampleNumber)).as2D())[i, 0] / (2 * del[j, 0]) } - settings.func_calls += 1 + settings.funcCalls += 1 } } diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index 1112043fc..c3e5fa16f 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -20,23 +20,23 @@ import kotlin.test.assertEquals class TestLmAlgorithm { companion object { - fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) - if (settings.example_number == 1) { + if (exampleNumber == 1) { y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) ) } - else if (settings.example_number == 2) { + else if (exampleNumber == 2) { val mt = t.max() y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + (t.times(1.0 / mt)).pow(4).times(p[3, 0]) } - else if (settings.example_number == 3) { + else if (exampleNumber == 3) { y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) } @@ -44,7 +44,7 @@ class TestLmAlgorithm { return y_hat.as2D() } - fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) @@ -54,13 +54,13 @@ class TestLmAlgorithm { } for(i in 0 until 5){ - y_hat = funcEasyForLm(y_hat.as2D(), p, settings).asDoubleTensor() + y_hat = funcEasyForLm(y_hat.as2D(), p, exampleNumber).asDoubleTensor() } return y_hat.as2D() } - fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { + fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) @@ -70,12 +70,11 @@ class TestLmAlgorithm { } for(i in 0 until 4){ - y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, settings).asDoubleTensor() + y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, exampleNumber).asDoubleTensor() } return y_hat.as2D() } - } @Test fun testLMEasy() = DoubleTensorAlgebra { @@ -130,18 +129,17 @@ class TestLmAlgorithm { val result = lm(::funcEasyForLm, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts, 10, example_number) assertEquals(13, result.iterations) - assertEquals(31, result.func_calls) - assertEquals(1, result.example_number) - assertEquals(0.9131368192633, (result.result_chi_sq * 1e13).roundToLong() / 1e13) - assertEquals(3.7790980 * 1e-7, (result.result_lambda * 1e13).roundToLong() / 1e13) + assertEquals(31, result.funcCalls) + assertEquals(0.9131368192633, (result.resultChiSq * 1e13).roundToLong() / 1e13) + assertEquals(3.7790980 * 1e-7, (result.resultLambda * 1e13).roundToLong() / 1e13) assertEquals(result.typeOfConvergence, TypeOfConvergence.InParameters) val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(4, 1)), doubleArrayOf(20.527230909086, 9.833627103230, 0.997571256572, 50.174445822506) ).as2D() - result.result_parameters = result.result_parameters.map { x -> (x * 1e12).toLong() / 1e12}.as2D() + result.resultParameters = result.resultParameters.map { x -> (x * 1e12).toLong() / 1e12}.as2D() val receivedParameters = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(4, 1)), doubleArrayOf(result.result_parameters[0, 0], result.result_parameters[1, 0], - result.result_parameters[2, 0], result.result_parameters[3, 0]) + ShapeND(intArrayOf(4, 1)), doubleArrayOf(result.resultParameters[0, 0], result.resultParameters[1, 0], + result.resultParameters[2, 0], result.resultParameters[3, 0]) ).as2D() assertEquals(expectedParameters[0, 0], receivedParameters[0, 0]) assertEquals(expectedParameters[1, 0], receivedParameters[1, 0]) @@ -163,9 +161,9 @@ class TestLmAlgorithm { p_example[i, 0] = p_example[i, 0] + i - 25 } - val settings = LMSettings(0, 0, 1) + val exampleNumber = 1 - var y_hat = funcMiddleForLm(t_example, p_example, settings) + var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { @@ -219,9 +217,9 @@ class TestLmAlgorithm { p_example[i, 0] = p_example[i, 0] + i - 25 } - val settings = LMSettings(0, 0, 1) + val exampleNumber = 1 - var y_hat = funcDifficultForLm(t_example, p_example, settings) + var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { From 162e37cb2fe8a3b27df82cbde91ff3442f4394de Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 7 Jun 2023 02:52:00 +0300 Subject: [PATCH 027/103] removed extra comments, unnecessary variables, renaming variables and secondary functions --- .../StaticLm/staticDifficultTest.kt | 4 - .../StaticLm/staticEasyTest.kt | 1 - .../StaticLm/staticMiddleTest.kt | 4 - .../StreamingLm/streamLm.kt | 2 - .../core/LevenbergMarquardtAlgorithm.kt | 363 ++++++++---------- .../kmath/tensors/core/TestLmAlgorithm.kt | 14 +- 6 files changed, 165 insertions(+), 223 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt index 24cfa955a..95a62e21e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt @@ -49,9 +49,6 @@ fun main() { p_min = p_min.div(1.0 / -50.0) val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) p_min = p_min.div(1.0 / 50.0) - val consts = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) - ).as2D() val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-2, 11.0, 9.0, 1.0) // val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-3, 11.0, 9.0, 1.0) @@ -64,7 +61,6 @@ fun main() { dp, p_min.as2D(), p_max.as2D(), - consts, opts, 10, 1 diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt index c7b2b0def..0b26838a0 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt @@ -27,7 +27,6 @@ fun main() { startedData.dp, startedData.p_min, startedData.p_max, - startedData.consts, startedData.opts, 10, startedData.example_number diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt index 471143102..b60ea1897 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt @@ -48,9 +48,6 @@ fun main() { p_min = p_min.div(1.0 / -50.0) val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) p_min = p_min.div(1.0 / 50.0) - val consts = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) - ).as2D() val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) val result = DoubleTensorAlgebra.lm( @@ -62,7 +59,6 @@ fun main() { dp, p_min.as2D(), p_max.as2D(), - consts, opts, 10, 1 diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index f031d82bf..99fb97923 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -26,7 +26,6 @@ fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D< val dp = startData.dp val p_min = startData.p_min val p_max = startData.p_max - val consts = startData.consts val opts = startData.opts var steps = numberOfLaunches @@ -42,7 +41,6 @@ fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D< dp, p_min, p_max, - consts, opts, 10, example_number diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index 7fbf6ecd8..af41a7a00 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -31,7 +31,7 @@ import kotlin.reflect.KFunction3 * InReducedChiSquare: chi-squared convergence achieved * (chi squared value divided by (m - n + 1) < epsilon2 = opts[4], * where n - number of parameters, m - amount of points - * NoConvergence: the maximum number of iterations has been reached without reaching convergence + * NoConvergence: the maximum number of iterations has been reached without reaching any convergence */ public enum class TypeOfConvergence{ InGradient, @@ -61,172 +61,141 @@ public data class LMResultInfo ( public fun DoubleTensorAlgebra.lm( func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, Int, MutableStructure2D<Double>>, - p_input: MutableStructure2D<Double>, t_input: MutableStructure2D<Double>, y_dat_input: MutableStructure2D<Double>, - weight_input: MutableStructure2D<Double>, dp_input: MutableStructure2D<Double>, p_min_input: MutableStructure2D<Double>, p_max_input: MutableStructure2D<Double>, - c_input: MutableStructure2D<Double>, opts_input: DoubleArray, nargin: Int, example_number: Int): LMResultInfo { + pInput: MutableStructure2D<Double>, tInput: MutableStructure2D<Double>, yDatInput: MutableStructure2D<Double>, + weightInput: MutableStructure2D<Double>, dpInput: MutableStructure2D<Double>, pMinInput: MutableStructure2D<Double>, + pMaxInput: MutableStructure2D<Double>, optsInput: DoubleArray, nargin: Int, exampleNumber: Int): LMResultInfo { val resultInfo = LMResultInfo(0, 0, 0.0, - 0.0, p_input, TypeOfConvergence.NoConvergence) + 0.0, pInput, TypeOfConvergence.NoConvergence) - val eps:Double = 2.2204e-16 + val eps = 2.2204e-16 - val settings = LMSettings(0, 0, example_number) + val settings = LMSettings(0, 0, exampleNumber) settings.funcCalls = 0 // running count of function evaluations - var p = p_input - val y_dat = y_dat_input - val t = t_input + var p = pInput + val t = tInput val Npar = length(p) // number of parameters - val Npnt = length(y_dat) // number of data points - var p_old = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters - var y_old = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) + val Npnt = length(yDatInput) // number of data points + var pOld = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters + var yOld = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) var X2 = 1e-3 / eps // a really big initial Chi-sq value - var X2_old = 1e-3 / eps // a really big initial Chi-sq value + var X2Old = 1e-3 / eps // a really big initial Chi-sq value var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix val DoF = Npnt - Npar // statistical degrees of freedom - var corr_p = 0 - var sigma_p = 0 - var sigma_y = 0 - var R_sq = 0 - var cvg_hist = 0 - - if (length(t) != length(y_dat)) { - // println("lm.m error: the length of t must equal the length of y_dat") - val length_t = length(t) - val length_y_dat = length(y_dat) - X2 = 0.0 - - corr_p = 0 - sigma_p = 0 - sigma_y = 0 - R_sq = 0 - cvg_hist = 0 - } - - var weight = weight_input + var weight = weightInput if (nargin < 5) { - weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf((y_dat.transpose().dot(y_dat)).as1D()[0])).as2D() + weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf((yDatInput.transpose().dot(yDatInput)).as1D()[0])).as2D() } - var dp = dp_input + var dp = dpInput if (nargin < 6) { dp = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.001)).as2D() } - var p_min = p_min_input + var pMin = pMinInput if (nargin < 7) { - p_min = p - p_min.abs() - p_min = p_min.div(-100.0).as2D() + pMin = p + pMin.abs() + pMin = pMin.div(-100.0).as2D() } - var p_max = p_max_input + var pMax = pMaxInput if (nargin < 8) { - p_max = p - p_max.abs() - p_max = p_max.div(100.0).as2D() + pMax = p + pMax.abs() + pMax = pMax.div(100.0).as2D() } - var c = c_input - if (nargin < 9) { - c = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(1.0)).as2D() - } - - var opts = opts_input + var opts = optsInput if (nargin < 10) { opts = doubleArrayOf(3.0, 10.0 * Npar, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) } val prnt = opts[0] // >1 intermediate results; >2 plots - val MaxIter = opts[1].toInt() // maximum number of iterations - val epsilon_1 = opts[2] // convergence tolerance for gradient - val epsilon_2 = opts[3] // convergence tolerance for parameters - val epsilon_3 = opts[4] // convergence tolerance for Chi-square - val epsilon_4 = opts[5] // determines acceptance of a L-M step - val lambda_0 = opts[6] // initial value of damping paramter, lambda - val lambda_UP_fac = opts[7] // factor for increasing lambda - val lambda_DN_fac = opts[8] // factor for decreasing lambda - val Update_Type = opts[9].toInt() // 1: Levenberg-Marquardt lambda update - // 2: Quadratic update - // 3: Nielsen's lambda update equations + val maxIterations = opts[1].toInt() // maximum number of iterations + val epsilon1 = opts[2] // convergence tolerance for gradient + val epsilon2 = opts[3] // convergence tolerance for parameters + val epsilon3 = opts[4] // convergence tolerance for Chi-square + val epsilon4 = opts[5] // determines acceptance of a L-M step + val lambda0 = opts[6] // initial value of damping paramter, lambda + val lambdaUpFac = opts[7] // factor for increasing lambda + val lambdaDnFac = opts[8] // factor for decreasing lambda + val updateType = opts[9].toInt() // 1: Levenberg-Marquardt lambda update + // 2: Quadratic update + // 3: Nielsen's lambda update equations - p_min = make_column(p_min) - p_max = make_column(p_max) + pMin = makeColumn(pMin) + pMax = makeColumn(pMax) - if (length(make_column(dp)) == 1) { + if (length(makeColumn(dp)) == 1) { dp = ones(ShapeND(intArrayOf(Npar, 1))).div(1 / dp[0, 0]).as2D() } - val idx = get_zero_indices(dp) // indices of the parameters to be fit - val Nfit = idx?.shape?.component1() // number of parameters to fit var stop = false // termination flag - val y_init = feval(func, t, p, example_number) // residual error using p_try if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / kotlin.math.abs(weight[0, 0])).as2D() - // println("using uniform weights for error analysis") } else { - weight = make_column(weight) + weight = makeColumn(weight) weight.abs() } // initialize Jacobian with finite difference calculation - var lm_matx_ans = lm_matx(func, t, p_old, y_old,1, J, p, y_dat, weight, dp, settings) - var JtWJ = lm_matx_ans[0] - var JtWdy = lm_matx_ans[1] - X2 = lm_matx_ans[2][0, 0] - var y_hat = lm_matx_ans[3] - J = lm_matx_ans[4] + var lmMatxAns = lmMatx(func, t, pOld, yOld, 1, J, p, yDatInput, weight, dp, settings) + var JtWJ = lmMatxAns[0] + var JtWdy = lmMatxAns[1] + X2 = lmMatxAns[2][0, 0] + var yHat = lmMatxAns[3] + J = lmMatxAns[4] - if ( abs(JtWdy).max()!! < epsilon_1 ) { -// println(" *** Your Initial Guess is Extremely Close to Optimal ***\n") -// println(" *** epsilon_1 = %e\n$epsilon_1") + if ( abs(JtWdy).max() < epsilon1 ) { stop = true } var lambda = 1.0 var nu = 1 - when (Update_Type) { - 1 -> lambda = lambda_0 // Marquardt: init'l lambda + when (updateType) { + 1 -> lambda = lambda0 // Marquardt: init'l lambda else -> { // Quadratic and Nielsen - lambda = lambda_0 * (diag(JtWJ)).max()!! + lambda = lambda0 * (makeColumnFromDiagonal(JtWJ)).max()!! nu = 2 } } - X2_old = X2 // previous value of X2 - var cvg_hst = ones(ShapeND(intArrayOf(MaxIter, Npar + 3))) // initialize convergence history + X2Old = X2 // previous value of X2 var h: DoubleTensor - var dX2 = X2 - while (!stop && settings.iteration <= MaxIter) { //--- Start Main Loop + + while (!stop && settings.iteration <= maxIterations) { //--- Start Main Loop settings.iteration += 1 // incremental change in parameters - h = when (Update_Type) { + h = when (updateType) { 1 -> { // Marquardt - val solve = solve(JtWJ.plus(make_matrx_with_diagonal(diag(JtWJ)).div(1 / lambda)).as2D(), JtWdy) + val solve = + solve(JtWJ.plus(makeMatrixWithDiagonal(makeColumnFromDiagonal(JtWJ)).div(1 / lambda)).as2D(), JtWdy) solve.asDoubleTensor() } else -> { // Quadratic and Nielsen - val solve = solve(JtWJ.plus(lm_eye(Npar).div(1 / lambda)).as2D(), JtWdy) + val solve = solve(JtWJ.plus(lmEye(Npar).div(1 / lambda)).as2D(), JtWdy) solve.asDoubleTensor() } } - var p_try = (p + h).as2D() // update the [idx] elements - p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try.as2D()), p_max) // apply constraints + var pTry = (p + h).as2D() // update the [idx] elements + pTry = smallestElementComparison(largestElementComparison(pMin, pTry.as2D()), pMax) // apply constraints - var delta_y = y_dat.minus(feval(func, t, p_try, example_number)) // residual error using p_try + var deltaY = yDatInput.minus(evaluateFunction(func, t, pTry, exampleNumber)) // residual error using p_try - for (i in 0 until delta_y.shape.component1()) { // floating point error; break - for (j in 0 until delta_y.shape.component2()) { - if (delta_y[i, j] == Double.POSITIVE_INFINITY || delta_y[i, j] == Double.NEGATIVE_INFINITY) { + for (i in 0 until deltaY.shape.component1()) { // floating point error; break + for (j in 0 until deltaY.shape.component2()) { + if (deltaY[i, j] == Double.POSITIVE_INFINITY || deltaY[i, j] == Double.NEGATIVE_INFINITY) { stop = true break } @@ -235,84 +204,87 @@ public fun DoubleTensorAlgebra.lm( settings.funcCalls += 1 - val tmp = delta_y.times(weight) - var X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria + val tmp = deltaY.times(weight) + var X2Try = deltaY.as2D().transpose().dot(tmp) // Chi-squared error criteria val alpha = 1.0 - if (Update_Type == 2) { // Quadratic + if (updateType == 2) { // Quadratic // One step of quadratic line update in the h direction for minimum X2 - val alpha = JtWdy.transpose().dot(h) / ( (X2_try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h)) ) + val alpha = JtWdy.transpose().dot(h) / ((X2Try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h))) h = h.dot(alpha) - p_try = p.plus(h).as2D() // update only [idx] elements - p_try = smallest_element_comparison(largest_element_comparison(p_min, p_try), p_max) // apply constraints + pTry = p.plus(h).as2D() // update only [idx] elements + pTry = smallestElementComparison(largestElementComparison(pMin, pTry), pMax) // apply constraints - var delta_y = y_dat.minus(feval(func, t, p_try, example_number)) // residual error using p_try + deltaY = yDatInput.minus(evaluateFunction(func, t, pTry, exampleNumber)) // residual error using p_try settings.funcCalls += 1 - val tmp = delta_y.times(weight) - X2_try = delta_y.as2D().transpose().dot(tmp) // Chi-squared error criteria + X2Try = deltaY.as2D().transpose().dot(deltaY.times(weight)) // Chi-squared error criteria } - val rho = when (Update_Type) { // Nielsen + val rho = when (updateType) { // Nielsen 1 -> { - val tmp = h.transposed().dot(make_matrx_with_diagonal(diag(JtWJ)).div(1 / lambda).dot(h).plus(JtWdy)) - X2.minus(X2_try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] + val tmp = h.transposed() + .dot(makeMatrixWithDiagonal(makeColumnFromDiagonal(JtWJ)).div(1 / lambda).dot(h).plus(JtWdy)) + X2.minus(X2Try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] } + else -> { val tmp = h.transposed().dot(h.div(1 / lambda).plus(JtWdy)) - X2.minus(X2_try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] + X2.minus(X2Try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] } } - if (rho > epsilon_4) { // it IS significantly better - val dX2 = X2.minus(X2_old) - X2_old = X2 - p_old = p.copyToTensor().as2D() - y_old = y_hat.copyToTensor().as2D() - p = make_column(p_try) // accept p_try + if (rho > epsilon4) { // it IS significantly better + val dX2 = X2.minus(X2Old) + X2Old = X2 + pOld = p.copyToTensor().as2D() + yOld = yHat.copyToTensor().as2D() + p = makeColumn(pTry) // accept p_try - lm_matx_ans = lm_matx(func, t, p_old, y_old, dX2.toInt(), J, p, y_dat, weight, dp, settings) + lmMatxAns = lmMatx(func, t, pOld, yOld, dX2.toInt(), J, p, yDatInput, weight, dp, settings) // decrease lambda ==> Gauss-Newton method - JtWJ = lm_matx_ans[0] - JtWdy = lm_matx_ans[1] - X2 = lm_matx_ans[2][0, 0] - y_hat = lm_matx_ans[3] - J = lm_matx_ans[4] + JtWJ = lmMatxAns[0] + JtWdy = lmMatxAns[1] + X2 = lmMatxAns[2][0, 0] + yHat = lmMatxAns[3] + J = lmMatxAns[4] - lambda = when (Update_Type) { + lambda = when (updateType) { 1 -> { // Levenberg - max(lambda / lambda_DN_fac, 1e-7); + max(lambda / lambdaDnFac, 1e-7); } + 2 -> { // Quadratic - max( lambda / (1 + alpha) , 1e-7 ); + max(lambda / (1 + alpha), 1e-7); } + else -> { // Nielsen nu = 2 - lambda * max( 1.0 / 3, 1 - (2 * rho - 1).pow(3) ) + lambda * max(1.0 / 3, 1 - (2 * rho - 1).pow(3)) } } - } - else { // it IS NOT better - X2 = X2_old // do not accept p_try - if (settings.iteration % (2 * Npar) == 0 ) { // rank-1 update of Jacobian - lm_matx_ans = lm_matx(func, t, p_old, y_old,-1, J, p, y_dat, weight, dp, settings) - JtWJ = lm_matx_ans[0] - JtWdy = lm_matx_ans[1] - dX2 = lm_matx_ans[2][0, 0] - y_hat = lm_matx_ans[3] - J = lm_matx_ans[4] + } else { // it IS NOT better + X2 = X2Old // do not accept p_try + if (settings.iteration % (2 * Npar) == 0) { // rank-1 update of Jacobian + lmMatxAns = lmMatx(func, t, pOld, yOld, -1, J, p, yDatInput, weight, dp, settings) + JtWJ = lmMatxAns[0] + JtWdy = lmMatxAns[1] + yHat = lmMatxAns[3] + J = lmMatxAns[4] } // increase lambda ==> gradient descent method - lambda = when (Update_Type) { + lambda = when (updateType) { 1 -> { // Levenberg - min(lambda * lambda_UP_fac, 1e7) + min(lambda * lambdaUpFac, 1e7) } + 2 -> { // Quadratic - lambda + kotlin.math.abs(((X2_try.as2D()[0, 0] - X2) / 2) / alpha) + lambda + kotlin.math.abs(((X2Try.as2D()[0, 0] - X2) / 2) / alpha) } + else -> { // Nielsen nu *= 2 lambda * (nu / 2) @@ -321,30 +293,27 @@ public fun DoubleTensorAlgebra.lm( } if (prnt > 1) { - val chi_sq = X2 / DoF + val chiSq = X2 / DoF resultInfo.iterations = settings.iteration resultInfo.funcCalls = settings.funcCalls - resultInfo.resultChiSq = chi_sq + resultInfo.resultChiSq = chiSq resultInfo.resultLambda = lambda resultInfo.resultParameters = p } - // update convergence history ... save _reduced_ Chi-square - // cvg_hst(iteration,:) = [ func_calls p' X2/DoF lambda ]; - - if (abs(JtWdy).max()!! < epsilon_1 && settings.iteration > 2) { + if (abs(JtWdy).max() < epsilon1 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InGradient stop = true } - if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon_2 && settings.iteration > 2) { + if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon2 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InParameters stop = true } - if (X2 / DoF < epsilon_3 && settings.iteration > 2) { + if (X2 / DoF < epsilon3 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InReducedChiSquare stop = true } - if (settings.iteration == MaxIter) { + if (settings.iteration == maxIterations) { resultInfo.typeOfConvergence = TypeOfConvergence.NoConvergence stop = true } @@ -358,8 +327,8 @@ private data class LMSettings ( var exampleNumber:Int ) -/* matrix -> column of all elemnets */ -private fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D<Double> { +/* matrix -> column of all elements */ +private fun makeColumn(tensor: MutableStructure2D<Double>): MutableStructure2D<Double> { val shape = intArrayOf(tensor.shape.component1() * tensor.shape.component2(), 1) val buffer = DoubleArray(tensor.shape.component1() * tensor.shape.component2()) for (i in 0 until tensor.shape.component1()) { @@ -367,8 +336,7 @@ private fun make_column(tensor: MutableStructure2D<Double>) : MutableStructure2D buffer[i * tensor.shape.component2() + j] = tensor[i, j] } } - val column = BroadcastDoubleTensorAlgebra.fromArray(ShapeND(shape), buffer).as2D() - return column + return BroadcastDoubleTensorAlgebra.fromArray(ShapeND(shape), buffer).as2D() } /* column length */ @@ -401,7 +369,7 @@ private fun abs(input: MutableStructure2D<Double>): MutableStructure2D<Double> { return tensor } -private fun diag(input: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun makeColumnFromDiagonal(input: MutableStructure2D<Double>): MutableStructure2D<Double> { val tensor = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(input.shape.component1(), 1))).as2D() for (i in 0 until tensor.shape.component1()) { tensor[i, 0] = input[i, i] @@ -409,7 +377,7 @@ private fun diag(input: MutableStructure2D<Double>): MutableStructure2D<Double> return tensor } -private fun make_matrx_with_diagonal(column: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun makeMatrixWithDiagonal(column: MutableStructure2D<Double>): MutableStructure2D<Double> { val size = column.shape.component1() val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(size, size))).as2D() for (i in 0 until size) { @@ -418,23 +386,23 @@ private fun make_matrx_with_diagonal(column: MutableStructure2D<Double>): Mutabl return tensor } -private fun lm_eye(size: Int): MutableStructure2D<Double> { +private fun lmEye(size: Int): MutableStructure2D<Double> { val column = BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(size, 1))).as2D() - return make_matrx_with_diagonal(column) + return makeMatrixWithDiagonal(column) } -private fun largest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { - val a_sizeX = a.shape.component1() - val a_sizeY = a.shape.component2() - val b_sizeX = b.shape.component1() - val b_sizeY = b.shape.component2() - val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(a_sizeX, b_sizeX), max(a_sizeY, b_sizeY)))).as2D() +private fun largestElementComparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { + val aSizeX = a.shape.component1() + val aSizeY = a.shape.component2() + val bSizeX = b.shape.component1() + val bSizeY = b.shape.component2() + val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(aSizeX, bSizeX), max(aSizeY, bSizeY)))).as2D() for (i in 0 until tensor.shape.component1()) { for (j in 0 until tensor.shape.component2()) { - if (i < a_sizeX && i < b_sizeX && j < a_sizeY && j < b_sizeY) { + if (i < aSizeX && i < bSizeX && j < aSizeY && j < bSizeY) { tensor[i, j] = max(a[i, j], b[i, j]) } - else if (i < a_sizeX && j < a_sizeY) { + else if (i < aSizeX && j < aSizeY) { tensor[i, j] = a[i, j] } else { @@ -445,18 +413,18 @@ private fun largest_element_comparison(a: MutableStructure2D<Double>, b: Mutable return tensor } -private fun smallest_element_comparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { - val a_sizeX = a.shape.component1() - val a_sizeY = a.shape.component2() - val b_sizeX = b.shape.component1() - val b_sizeY = b.shape.component2() - val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(a_sizeX, b_sizeX), max(a_sizeY, b_sizeY)))).as2D() +private fun smallestElementComparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { + val aSizeX = a.shape.component1() + val aSizeY = a.shape.component2() + val bSizeX = b.shape.component1() + val bSizeY = b.shape.component2() + val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(aSizeX, bSizeX), max(aSizeY, bSizeY)))).as2D() for (i in 0 until tensor.shape.component1()) { for (j in 0 until tensor.shape.component2()) { - if (i < a_sizeX && i < b_sizeX && j < a_sizeY && j < b_sizeY) { + if (i < aSizeX && i < bSizeX && j < aSizeY && j < bSizeY) { tensor[i, j] = min(a[i, j], b[i, j]) } - else if (i < a_sizeX && j < a_sizeY) { + else if (i < aSizeX && j < aSizeY) { tensor[i, j] = a[i, j] } else { @@ -467,71 +435,69 @@ private fun smallest_element_comparison(a: MutableStructure2D<Double>, b: Mutabl return tensor } -private fun get_zero_indices(column: MutableStructure2D<Double>, epsilon: Double = 0.000001): MutableStructure2D<Double>? { +private fun getZeroIndices(column: MutableStructure2D<Double>, epsilon: Double = 0.000001): MutableStructure2D<Double>? { var idx = emptyArray<Double>() for (i in 0 until column.shape.component1()) { if (kotlin.math.abs(column[i, 0]) > epsilon) { idx += (i + 1.0) } } - if (idx.size > 0) { + if (idx.isNotEmpty()) { return BroadcastDoubleTensorAlgebra.fromArray(ShapeND(intArrayOf(idx.size, 1)), idx.toDoubleArray()).as2D() } return null } -private fun feval(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int) +private fun evaluateFunction(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int) : MutableStructure2D<Double> { return func(t, p, exampleNumber) } -private fun lm_matx(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, - dX2: Int, J_input: MutableStructure2D<Double>, p: MutableStructure2D<Double>, - y_dat: MutableStructure2D<Double>, weight: MutableStructure2D<Double>, dp:MutableStructure2D<Double>, settings:LMSettings) : Array<MutableStructure2D<Double>> +private fun lmMatx(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, pOld: MutableStructure2D<Double>, yOld: MutableStructure2D<Double>, + dX2: Int, JInput: MutableStructure2D<Double>, p: MutableStructure2D<Double>, + yDat: MutableStructure2D<Double>, weight: MutableStructure2D<Double>, dp:MutableStructure2D<Double>, settings:LMSettings) : Array<MutableStructure2D<Double>> { // default: dp = 0.001 - - val Npnt = length(y_dat) // number of data points val Npar = length(p) // number of parameters - val y_hat = feval(func, t, p, settings.exampleNumber) // evaluate model using parameters 'p' + val yHat = evaluateFunction(func, t, p, settings.exampleNumber) // evaluate model using parameters 'p' settings.funcCalls += 1 - var J = J_input + var J = JInput - if (settings.iteration % (2 * Npar) == 0 || dX2 > 0) { - J = lm_FD_J(func, t, p, y_hat, dp, settings).as2D() // finite difference + J = if (settings.iteration % (2 * Npar) == 0 || dX2 > 0) { + lmFdJ(func, t, p, yHat, dp, settings).as2D() // finite difference } else { - J = lm_Broyden_J(p_old, y_old, J, p, y_hat).as2D() // rank-1 update + lmBroydenJ(pOld, yOld, J, p, yHat).as2D() // rank-1 update } - val delta_y = y_dat.minus(y_hat) + val deltaY = yDat.minus(yHat) - val Chi_sq = delta_y.transposed().dot( delta_y.times(weight) ).as2D() + val chiSq = deltaY.transposed().dot( deltaY.times(weight) ).as2D() val JtWJ = J.transposed().dot ( J.times( weight.dot(BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(1, Npar)))) ) ).as2D() - val JtWdy = J.transposed().dot( weight.times(delta_y) ).as2D() + val JtWdy = J.transposed().dot( weight.times(deltaY) ).as2D() - return arrayOf(JtWJ,JtWdy,Chi_sq,y_hat,J) + return arrayOf(JtWJ,JtWdy,chiSq,yHat,J) } -private fun lm_Broyden_J(p_old: MutableStructure2D<Double>, y_old: MutableStructure2D<Double>, J_input: MutableStructure2D<Double>, - p: MutableStructure2D<Double>, y: MutableStructure2D<Double>): MutableStructure2D<Double> { - var J = J_input.copyToTensor() +private fun lmBroydenJ(pOld: MutableStructure2D<Double>, yOld: MutableStructure2D<Double>, JInput: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, y: MutableStructure2D<Double>): MutableStructure2D<Double> { + var J = JInput.copyToTensor() - val h = p.minus(p_old) - val increase = y.minus(y_old).minus( J.dot(h) ).dot(h.transposed()).div( (h.transposed().dot(h)).as2D()[0, 0] ) + val h = p.minus(pOld) + val increase = y.minus(yOld).minus( J.dot(h) ).dot(h.transposed()).div( (h.transposed().dot(h)).as2D()[0, 0] ) J = J.plus(increase) return J.as2D() } -private fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, exampleNumber: Int) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y: MutableStructure2D<Double>, - dp: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { +private fun lmFdJ(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, exampleNumber: Int) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y: MutableStructure2D<Double>, + dp: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { // default: dp = 0.001 * ones(1,n) val m = length(y) // number of data points @@ -548,7 +514,7 @@ private fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double val epsilon = 0.0000001 if (kotlin.math.abs(del[j, 0]) > epsilon) { - val y1 = feval(func, t, p, settings.exampleNumber) + val y1 = evaluateFunction(func, t, p, settings.exampleNumber) settings.funcCalls += 1 if (dp[j, 0] < 0) { // backwards difference @@ -558,10 +524,9 @@ private fun lm_FD_J(func: (MutableStructure2D<Double>, MutableStructure2D<Double } else { // Do tests for it - println("Potential mistake") p[j, 0] = ps[j, 0] - del[j, 0] // central difference, additional func call for (i in 0 until J.shape.component1()) { - J[i, j] = (y1.as2D().minus(feval(func, t, p, settings.exampleNumber)).as2D())[i, 0] / (2 * del[j, 0]) + J[i, j] = (y1.as2D().minus(evaluateFunction(func, t, p, settings.exampleNumber)).as2D())[i, 0] / (2 * del[j, 0]) } settings.funcCalls += 1 } diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index c3e5fa16f..114e5f879 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -121,13 +121,9 @@ class TestLmAlgorithm { ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0) ).as2D() - val consts = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) - ).as2D() - val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) - val result = lm(::funcEasyForLm, p_init, t, y_dat, weight, dp, p_min, p_max, consts, opts, 10, example_number) + val result = lm(::funcEasyForLm, p_init, t, y_dat, weight, dp, p_min, p_max, opts, 10, example_number) assertEquals(13, result.iterations) assertEquals(31, result.funcCalls) assertEquals(0.9131368192633, (result.resultChiSq * 1e13).roundToLong() / 1e13) @@ -182,9 +178,6 @@ class TestLmAlgorithm { p_min = p_min.div(1.0 / -50.0) val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) p_min = p_min.div(1.0 / 50.0) - val consts = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) - ).as2D() val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) val result = DoubleTensorAlgebra.lm( @@ -196,7 +189,6 @@ class TestLmAlgorithm { dp, p_min.as2D(), p_max.as2D(), - consts, opts, 10, 1 @@ -238,9 +230,6 @@ class TestLmAlgorithm { p_min = p_min.div(1.0 / -50.0) val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) p_min = p_min.div(1.0 / 50.0) - val consts = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.0) - ).as2D() val opts = doubleArrayOf(3.0, 7000.0, 1e-2, 1e-3, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) val result = DoubleTensorAlgebra.lm( @@ -252,7 +241,6 @@ class TestLmAlgorithm { dp, p_min.as2D(), p_max.as2D(), - consts, opts, 10, 1 From e8dafad6c582646f649f8d94484e9c2643ac0de3 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 7 Jun 2023 05:25:32 +0300 Subject: [PATCH 028/103] the input data is placed in a separate class, to which the documentation is written --- .../StaticLm/staticDifficultTest.kt | 20 +- .../StaticLm/staticEasyTest.kt | 17 +- .../StaticLm/staticMiddleTest.kt | 20 +- .../StreamingLm/streamLm.kt | 32 +-- .../LevenbergMarquardt/functionsToOptimize.kt | 14 +- .../core/LevenbergMarquardtAlgorithm.kt | 193 +++++++++++------- .../kmath/tensors/core/TestLmAlgorithm.kt | 45 ++-- 7 files changed, 197 insertions(+), 144 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt index 95a62e21e..e6f575262 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt @@ -12,7 +12,8 @@ import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.lm +import space.kscience.kmath.tensors.core.LMInput +import space.kscience.kmath.tensors.core.levenbergMarquardt import kotlin.math.roundToInt fun main() { @@ -39,9 +40,7 @@ fun main() { var t = t_example val y_dat = y_hat - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 / Nparams * 1.0 - 0.085 } - ).as2D() + val weight = 1.0 / Nparams * 1.0 - 0.085 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() @@ -52,8 +51,7 @@ fun main() { val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-2, 11.0, 9.0, 1.0) // val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-3, 11.0, 9.0, 1.0) - val result = DoubleTensorAlgebra.lm( - ::funcDifficultForLm, + val inputData = LMInput(::funcDifficultForLm, p_init.as2D(), t, y_dat, @@ -61,10 +59,14 @@ fun main() { dp, p_min.as2D(), p_max.as2D(), - opts, + opts[1].toInt(), + doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), + doubleArrayOf(opts[6], opts[7], opts[8]), + opts[9].toInt(), 10, - 1 - ) + 1) + + val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) println("Parameters:") for (i in 0 until result.resultParameters.shape.component1()) { diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt index 0b26838a0..507943031 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt @@ -12,14 +12,13 @@ import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm import space.kscience.kmath.tensors.LevenbergMarquardt.funcEasyForLm import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncEasy import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.lm +import space.kscience.kmath.tensors.core.LMInput +import space.kscience.kmath.tensors.core.levenbergMarquardt import kotlin.math.roundToInt fun main() { val startedData = getStartDataForFuncEasy() - - val result = DoubleTensorAlgebra.lm( - ::funcEasyForLm, + val inputData = LMInput(::funcEasyForLm, DoubleTensorAlgebra.ones(ShapeND(intArrayOf(4, 1))).as2D(), startedData.t, startedData.y_dat, @@ -27,10 +26,14 @@ fun main() { startedData.dp, startedData.p_min, startedData.p_max, - startedData.opts, + startedData.opts[1].toInt(), + doubleArrayOf(startedData.opts[2], startedData.opts[3], startedData.opts[4], startedData.opts[5]), + doubleArrayOf(startedData.opts[6], startedData.opts[7], startedData.opts[8]), + startedData.opts[9].toInt(), 10, - startedData.example_number - ) + startedData.example_number) + + val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) println("Parameters:") for (i in 0 until result.resultParameters.shape.component1()) { diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt index b60ea1897..0659db103 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt @@ -12,7 +12,8 @@ import space.kscience.kmath.tensors.LevenbergMarquardt.funcMiddleForLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.lm +import space.kscience.kmath.tensors.core.LMInput +import space.kscience.kmath.tensors.core.levenbergMarquardt import kotlin.math.roundToInt fun main() { val NData = 100 @@ -38,9 +39,7 @@ fun main() { var t = t_example val y_dat = y_hat - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 } - ).as2D() + val weight = 1.0 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() @@ -50,8 +49,7 @@ fun main() { p_min = p_min.div(1.0 / 50.0) val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) - val result = DoubleTensorAlgebra.lm( - ::funcMiddleForLm, + val inputData = LMInput(::funcMiddleForLm, p_init.as2D(), t, y_dat, @@ -59,10 +57,14 @@ fun main() { dp, p_min.as2D(), p_max.as2D(), - opts, + opts[1].toInt(), + doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), + doubleArrayOf(opts[6], opts[7], opts[8]), + opts[9].toInt(), 10, - 1 - ) + 1) + + val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) println("Parameters:") for (i in 0 until result.resultParameters.shape.component1()) { diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index 99fb97923..fe96b2fe9 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -11,7 +11,8 @@ import space.kscience.kmath.nd.* import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros import space.kscience.kmath.tensors.core.DoubleTensorAlgebra -import space.kscience.kmath.tensors.core.lm +import space.kscience.kmath.tensors.core.LMInput +import space.kscience.kmath.tensors.core.levenbergMarquardt import kotlin.random.Random import kotlin.reflect.KFunction3 @@ -31,20 +32,23 @@ fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D< var steps = numberOfLaunches val isEndless = (steps <= 0) + val inputData = LMInput(lm_func, + p_init, + t, + y_dat, + weight, + dp, + p_min, + p_max, + opts[1].toInt(), + doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), + doubleArrayOf(opts[6], opts[7], opts[8]), + opts[9].toInt(), + 10, + example_number) + while (isEndless || steps > 0) { - val result = DoubleTensorAlgebra.lm( - lm_func, - p_init, - t, - y_dat, - weight, - dp, - p_min, - p_max, - opts, - 10, - example_number - ) + val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) emit(result.resultParameters) delay(launchFrequencyInMs) p_init = result.resultParameters diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt index 537b86da3..7ccb37ed0 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt @@ -24,7 +24,7 @@ public data class StartDataLm ( var p_init: MutableStructure2D<Double>, var t: MutableStructure2D<Double>, var y_dat: MutableStructure2D<Double>, - var weight: MutableStructure2D<Double>, + var weight: Double, var dp: MutableStructure2D<Double>, var p_min: MutableStructure2D<Double>, var p_max: MutableStructure2D<Double>, @@ -113,9 +113,7 @@ fun getStartDataForFuncDifficult(): StartDataLm { var t = t_example val y_dat = y_hat - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 / Nparams * 1.0 - 0.085 } - ).as2D() + val weight = 1.0 / Nparams * 1.0 - 0.085 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() @@ -154,9 +152,7 @@ fun getStartDataForFuncMiddle(): StartDataLm { } var t = t_example val y_dat = y_hat - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 } - ).as2D() + val weight = 1.0 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() @@ -202,9 +198,7 @@ fun getStartDataForFuncEasy(): StartDataLm { ShapeND(intArrayOf(100, 1)), lm_matx_y_dat ).as2D() - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 4.0 } - ).as2D() + val weight = 4.0 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index af41a7a00..ec9d92c88 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -19,21 +19,21 @@ import kotlin.math.pow import kotlin.reflect.KFunction3 /** - * Type of convergence achieved as a result of executing the Levenberg-Marquardt algorithm + * Type of convergence achieved as a result of executing the Levenberg-Marquardt algorithm. * * InGradient: gradient convergence achieved - * (max(J^T W dy) < epsilon1 = opts[2], + * (max(J^T W dy) < epsilon1, * where J - Jacobi matrix (dy^/dp) for the current approximation y^, - * W - weight matrix from input, dy = (y - y^(p))) + * W - weight matrix from input, dy = (y - y^(p))). * InParameters: convergence in parameters achieved - * (max(h_i / p_i) < epsilon2 = opts[3], - * where h_i - offset for parameter p_i on the current iteration) + * (max(h_i / p_i) < epsilon2, + * where h_i - offset for parameter p_i on the current iteration). * InReducedChiSquare: chi-squared convergence achieved - * (chi squared value divided by (m - n + 1) < epsilon2 = opts[4], - * where n - number of parameters, m - amount of points - * NoConvergence: the maximum number of iterations has been reached without reaching any convergence + * (chi squared value divided by (m - n + 1) < epsilon2, + * where n - number of parameters, m - amount of points). + * NoConvergence: the maximum number of iterations has been reached without reaching any convergence. */ -public enum class TypeOfConvergence{ +public enum class TypeOfConvergence { InGradient, InParameters, InReducedChiSquare, @@ -41,14 +41,14 @@ public enum class TypeOfConvergence{ } /** - * Class for the data obtained as a result of the execution of the Levenberg-Marquardt algorithm + * The data obtained as a result of the execution of the Levenberg-Marquardt algorithm. * - * iterations: number of completed iterations - * funcCalls: the number of evaluations of the input function during execution - * resultChiSq: chi squared value on final parameters - * resultLambda: final lambda parameter used to calculate the offset - * resultParameters: final parameters - * typeOfConvergence: type of convergence + * iterations: number of completed iterations. + * funcCalls: the number of evaluations of the input function during execution. + * resultChiSq: chi squared value on final parameters. + * resultLambda: final lambda parameter used to calculate the offset. + * resultParameters: final parameters. + * typeOfConvergence: type of convergence. */ public data class LMResultInfo ( var iterations:Int, @@ -59,26 +59,65 @@ public data class LMResultInfo ( var typeOfConvergence: TypeOfConvergence, ) -public fun DoubleTensorAlgebra.lm( - func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, Int, MutableStructure2D<Double>>, - pInput: MutableStructure2D<Double>, tInput: MutableStructure2D<Double>, yDatInput: MutableStructure2D<Double>, - weightInput: MutableStructure2D<Double>, dpInput: MutableStructure2D<Double>, pMinInput: MutableStructure2D<Double>, - pMaxInput: MutableStructure2D<Double>, optsInput: DoubleArray, nargin: Int, exampleNumber: Int): LMResultInfo { - +/** + * Input data for the Levenberg-Marquardt function. + * + * func: function of n independent variables x, m parameters an example number, + * rotating a vector of n values y, in which each of the y_i is calculated at its x_i with the given parameters. + * startParameters: starting parameters. + * independentVariables: independent variables, for each of which the real value is known. + * realValues: real values obtained with given independent variables but unknown parameters. + * weight: measurement error for realValues (denominator in each term of sum of weighted squared errors). + * pDelta: delta when calculating the derivative with respect to parameters. + * minParameters: the lower bound of parameter values. + * maxParameters: upper limit of parameter values. + * maxIterations: maximum allowable number of iterations. + * epsilons: epsilon1 - convergence tolerance for gradient, + * epsilon2 - convergence tolerance for parameters, + * epsilon3 - convergence tolerance for reduced chi-square, + * epsilon4 - determines acceptance of a step. + * lambdas: lambda0 - starting lambda value for parameter offset count, + * lambdaUp - factor for increasing lambda, + * lambdaDown - factor for decreasing lambda. + * updateType: 1: Levenberg-Marquardt lambda update, + * 2: Quadratic update, + * 3: Nielsen's lambda update equations. + * nargin: a value that determines which options to use by default + * (<5 - use weight by default, <6 - use pDelta by default, <7 - use minParameters by default, + * <8 - use maxParameters by default, <9 - use updateType by default). + * exampleNumber: a parameter for a function with which you can choose its behavior. + */ +public data class LMInput ( + var func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, Int, MutableStructure2D<Double>>, + var startParameters: MutableStructure2D<Double>, + var independentVariables: MutableStructure2D<Double>, + var realValues: MutableStructure2D<Double>, + var weight: Double, + var pDelta: MutableStructure2D<Double>, + var minParameters: MutableStructure2D<Double>, + var maxParameters: MutableStructure2D<Double>, + var maxIterations: Int, + var epsilons: DoubleArray, + var lambdas: DoubleArray, + var updateType: Int, + var nargin: Int, + var exampleNumber: Int +) +public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultInfo { val resultInfo = LMResultInfo(0, 0, 0.0, - 0.0, pInput, TypeOfConvergence.NoConvergence) + 0.0, inputData.startParameters, TypeOfConvergence.NoConvergence) val eps = 2.2204e-16 - val settings = LMSettings(0, 0, exampleNumber) + val settings = LMSettings(0, 0, inputData.exampleNumber) settings.funcCalls = 0 // running count of function evaluations - var p = pInput - val t = tInput + var p = inputData.startParameters + val t = inputData.independentVariables val Npar = length(p) // number of parameters - val Npnt = length(yDatInput) // number of data points + val Npnt = length(inputData.realValues) // number of data points var pOld = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters var yOld = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) var X2 = 1e-3 / eps // a really big initial Chi-sq value @@ -86,50 +125,55 @@ public fun DoubleTensorAlgebra.lm( var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix val DoF = Npnt - Npar // statistical degrees of freedom - var weight = weightInput - if (nargin < 5) { - weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf((yDatInput.transpose().dot(yDatInput)).as1D()[0])).as2D() + var weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(inputData.weight)).as2D() + if (inputData.nargin < 5) { + weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf((inputData.realValues.transpose().dot(inputData.realValues)).as1D()[0])).as2D() } - var dp = dpInput - if (nargin < 6) { + var dp = inputData.pDelta + if (inputData.nargin < 6) { dp = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(0.001)).as2D() } - var pMin = pMinInput - if (nargin < 7) { - pMin = p - pMin.abs() - pMin = pMin.div(-100.0).as2D() + var minParameters = inputData.minParameters + if (inputData.nargin < 7) { + minParameters = p + minParameters.abs() + minParameters = minParameters.div(-100.0).as2D() } - var pMax = pMaxInput - if (nargin < 8) { - pMax = p - pMax.abs() - pMax = pMax.div(100.0).as2D() + var maxParameters = inputData.maxParameters + if (inputData.nargin < 8) { + maxParameters = p + maxParameters.abs() + maxParameters = maxParameters.div(100.0).as2D() } - var opts = optsInput - if (nargin < 10) { - opts = doubleArrayOf(3.0, 10.0 * Npar, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) + var maxIterations = inputData.maxIterations + var epsilon1 = inputData.epsilons[0] // convergence tolerance for gradient + var epsilon2 = inputData.epsilons[1] // convergence tolerance for parameters + var epsilon3 = inputData.epsilons[2] // convergence tolerance for Chi-square + var epsilon4 = inputData.epsilons[3] // determines acceptance of a L-M step + var lambda0 = inputData.lambdas[0] // initial value of damping paramter, lambda + var lambdaUpFac = inputData.lambdas[1] // factor for increasing lambda + var lambdaDnFac = inputData.lambdas[2] // factor for decreasing lambda + var updateType = inputData.updateType // 1: Levenberg-Marquardt lambda update + // 2: Quadratic update + // 3: Nielsen's lambda update equations + if (inputData.nargin < 9) { + maxIterations = 10 * Npar + epsilon1 = 1e-3 + epsilon2 = 1e-3 + epsilon3 = 1e-1 + epsilon4 = 1e-1 + lambda0 = 1e-2 + lambdaUpFac = 11.0 + lambdaDnFac = 9.0 + updateType = 1 } - val prnt = opts[0] // >1 intermediate results; >2 plots - val maxIterations = opts[1].toInt() // maximum number of iterations - val epsilon1 = opts[2] // convergence tolerance for gradient - val epsilon2 = opts[3] // convergence tolerance for parameters - val epsilon3 = opts[4] // convergence tolerance for Chi-square - val epsilon4 = opts[5] // determines acceptance of a L-M step - val lambda0 = opts[6] // initial value of damping paramter, lambda - val lambdaUpFac = opts[7] // factor for increasing lambda - val lambdaDnFac = opts[8] // factor for decreasing lambda - val updateType = opts[9].toInt() // 1: Levenberg-Marquardt lambda update - // 2: Quadratic update - // 3: Nielsen's lambda update equations - - pMin = makeColumn(pMin) - pMax = makeColumn(pMax) + minParameters = makeColumn(minParameters) + maxParameters = makeColumn(maxParameters) if (length(makeColumn(dp)) == 1) { dp = ones(ShapeND(intArrayOf(Npar, 1))).div(1 / dp[0, 0]).as2D() @@ -146,7 +190,7 @@ public fun DoubleTensorAlgebra.lm( } // initialize Jacobian with finite difference calculation - var lmMatxAns = lmMatx(func, t, pOld, yOld, 1, J, p, yDatInput, weight, dp, settings) + var lmMatxAns = lmMatx(inputData.func, t, pOld, yOld, 1, J, p, inputData.realValues, weight, dp, settings) var JtWJ = lmMatxAns[0] var JtWdy = lmMatxAns[1] X2 = lmMatxAns[2][0, 0] @@ -189,9 +233,9 @@ public fun DoubleTensorAlgebra.lm( } var pTry = (p + h).as2D() // update the [idx] elements - pTry = smallestElementComparison(largestElementComparison(pMin, pTry.as2D()), pMax) // apply constraints + pTry = smallestElementComparison(largestElementComparison(minParameters, pTry.as2D()), maxParameters) // apply constraints - var deltaY = yDatInput.minus(evaluateFunction(func, t, pTry, exampleNumber)) // residual error using p_try + var deltaY = inputData.realValues.minus(evaluateFunction(inputData.func, t, pTry, inputData.exampleNumber)) // residual error using p_try for (i in 0 until deltaY.shape.component1()) { // floating point error; break for (j in 0 until deltaY.shape.component2()) { @@ -214,9 +258,9 @@ public fun DoubleTensorAlgebra.lm( val alpha = JtWdy.transpose().dot(h) / ((X2Try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h))) h = h.dot(alpha) pTry = p.plus(h).as2D() // update only [idx] elements - pTry = smallestElementComparison(largestElementComparison(pMin, pTry), pMax) // apply constraints + pTry = smallestElementComparison(largestElementComparison(minParameters, pTry), maxParameters) // apply constraints - deltaY = yDatInput.minus(evaluateFunction(func, t, pTry, exampleNumber)) // residual error using p_try + deltaY = inputData.realValues.minus(evaluateFunction(inputData.func, t, pTry, inputData.exampleNumber)) // residual error using p_try settings.funcCalls += 1 X2Try = deltaY.as2D().transpose().dot(deltaY.times(weight)) // Chi-squared error criteria @@ -242,7 +286,7 @@ public fun DoubleTensorAlgebra.lm( yOld = yHat.copyToTensor().as2D() p = makeColumn(pTry) // accept p_try - lmMatxAns = lmMatx(func, t, pOld, yOld, dX2.toInt(), J, p, yDatInput, weight, dp, settings) + lmMatxAns = lmMatx(inputData.func, t, pOld, yOld, dX2.toInt(), J, p, inputData.realValues, weight, dp, settings) // decrease lambda ==> Gauss-Newton method JtWJ = lmMatxAns[0] @@ -268,7 +312,7 @@ public fun DoubleTensorAlgebra.lm( } else { // it IS NOT better X2 = X2Old // do not accept p_try if (settings.iteration % (2 * Npar) == 0) { // rank-1 update of Jacobian - lmMatxAns = lmMatx(func, t, pOld, yOld, -1, J, p, yDatInput, weight, dp, settings) + lmMatxAns = lmMatx(inputData.func, t, pOld, yOld, -1, J, p, inputData.realValues, weight, dp, settings) JtWJ = lmMatxAns[0] JtWdy = lmMatxAns[1] yHat = lmMatxAns[3] @@ -292,14 +336,13 @@ public fun DoubleTensorAlgebra.lm( } } - if (prnt > 1) { - val chiSq = X2 / DoF - resultInfo.iterations = settings.iteration - resultInfo.funcCalls = settings.funcCalls - resultInfo.resultChiSq = chiSq - resultInfo.resultLambda = lambda - resultInfo.resultParameters = p - } + val chiSq = X2 / DoF + resultInfo.iterations = settings.iteration + resultInfo.funcCalls = settings.funcCalls + resultInfo.resultChiSq = chiSq + resultInfo.resultLambda = lambda + resultInfo.resultParameters = p + if (abs(JtWdy).max() < epsilon1 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InGradient diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index 114e5f879..4e1df3b08 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -105,9 +105,7 @@ class TestLmAlgorithm { ShapeND(intArrayOf(100, 1)), lm_matx_y_dat ).as2D() - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 4.0 } - ).as2D() + val weight = 4.0 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } @@ -123,7 +121,12 @@ class TestLmAlgorithm { val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) - val result = lm(::funcEasyForLm, p_init, t, y_dat, weight, dp, p_min, p_max, opts, 10, example_number) + val inputData = LMInput(::funcEasyForLm, p_init, t, y_dat, weight, dp, p_min, p_max, opts[1].toInt(), + doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), + doubleArrayOf(opts[6], opts[7], opts[8]), + opts[9].toInt(), 10, example_number) + + val result = levenbergMarquardt(inputData) assertEquals(13, result.iterations) assertEquals(31, result.funcCalls) assertEquals(0.9131368192633, (result.resultChiSq * 1e13).roundToLong() / 1e13) @@ -168,9 +171,7 @@ class TestLmAlgorithm { var t = t_example val y_dat = y_hat - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 } - ).as2D() + val weight = 1.0 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() @@ -180,8 +181,7 @@ class TestLmAlgorithm { p_min = p_min.div(1.0 / 50.0) val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) - val result = DoubleTensorAlgebra.lm( - ::funcMiddleForLm, + val inputData = LMInput(::funcMiddleForLm, p_init.as2D(), t, y_dat, @@ -189,10 +189,14 @@ class TestLmAlgorithm { dp, p_min.as2D(), p_max.as2D(), - opts, + opts[1].toInt(), + doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), + doubleArrayOf(opts[6], opts[7], opts[8]), + opts[9].toInt(), 10, - 1 - ) + 1) + + val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) } @Test @@ -220,9 +224,7 @@ class TestLmAlgorithm { var t = t_example val y_dat = y_hat - val weight = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(1, 1)), DoubleArray(1) { 1.0 / Nparams * 1.0 - 0.085 } - ).as2D() + val weight = 1.0 / Nparams * 1.0 - 0.085 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() @@ -232,8 +234,7 @@ class TestLmAlgorithm { p_min = p_min.div(1.0 / 50.0) val opts = doubleArrayOf(3.0, 7000.0, 1e-2, 1e-3, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) - val result = DoubleTensorAlgebra.lm( - ::funcDifficultForLm, + val inputData = LMInput(::funcDifficultForLm, p_init.as2D(), t, y_dat, @@ -241,9 +242,13 @@ class TestLmAlgorithm { dp, p_min.as2D(), p_max.as2D(), - opts, + opts[1].toInt(), + doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), + doubleArrayOf(opts[6], opts[7], opts[8]), + opts[9].toInt(), 10, - 1 - ) + 1) + + val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) } } \ No newline at end of file From 0655642933a67bf971c043b6583877ea07eb791e Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 7 Jun 2023 06:00:58 +0300 Subject: [PATCH 029/103] add documentation to the main function levenbergMarquardt --- .../tensors/core/LevenbergMarquardtAlgorithm.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index ec9d92c88..b0caf987a 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -104,6 +104,21 @@ public data class LMInput ( var exampleNumber: Int ) + +/** + * Levenberg-Marquardt optimization. + * + * An optimization method that iteratively searches for the optimal function parameters + * that best describe the dataset. The 'input' is the function being optimized, a set of real data + * (calculated with independent variables, but with an unknown set of parameters), a set of + * independent variables, and variables for adjusting the algorithm, described in the documentation for the LMInput class. + * The function returns number of completed iterations, the number of evaluations of the input function during execution, + * chi squared value on final parameters, final lambda parameter used to calculate the offset, final parameters + * and type of convergence in the 'output'. + * + * @receiver the `input`. + * @return the 'output'. + */ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultInfo { val resultInfo = LMResultInfo(0, 0, 0.0, 0.0, inputData.startParameters, TypeOfConvergence.NoConvergence) From 346e2e97f24c27a896ff96b4689c9dae242e9bc7 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 7 Jun 2023 06:14:05 +0300 Subject: [PATCH 030/103] add minor fixes --- .../core/LevenbergMarquardtAlgorithm.kt | 90 +++++++++---------- 1 file changed, 41 insertions(+), 49 deletions(-) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index b0caf987a..d9c282fb6 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -131,14 +131,14 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI var p = inputData.startParameters val t = inputData.independentVariables - val Npar = length(p) // number of parameters - val Npnt = length(inputData.realValues) // number of data points - var pOld = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters - var yOld = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) - var X2 = 1e-3 / eps // a really big initial Chi-sq value - var X2Old = 1e-3 / eps // a really big initial Chi-sq value - var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix - val DoF = Npnt - Npar // statistical degrees of freedom + val Npar = length(p) // number of parameters + val Npnt = length(inputData.realValues) // number of data points + var pOld = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters + var yOld = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) + var X2 = 1e-3 / eps // a really big initial Chi-sq value + var X2Old = 1e-3 / eps // a really big initial Chi-sq value + var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix + val DoF = Npnt - Npar // statistical degrees of freedom var weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(inputData.weight)).as2D() if (inputData.nargin < 5) { @@ -165,16 +165,15 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI } var maxIterations = inputData.maxIterations - var epsilon1 = inputData.epsilons[0] // convergence tolerance for gradient - var epsilon2 = inputData.epsilons[1] // convergence tolerance for parameters - var epsilon3 = inputData.epsilons[2] // convergence tolerance for Chi-square - var epsilon4 = inputData.epsilons[3] // determines acceptance of a L-M step - var lambda0 = inputData.lambdas[0] // initial value of damping paramter, lambda - var lambdaUpFac = inputData.lambdas[1] // factor for increasing lambda - var lambdaDnFac = inputData.lambdas[2] // factor for decreasing lambda - var updateType = inputData.updateType // 1: Levenberg-Marquardt lambda update - // 2: Quadratic update - // 3: Nielsen's lambda update equations + var epsilon1 = inputData.epsilons[0] + var epsilon2 = inputData.epsilons[1] + var epsilon3 = inputData.epsilons[2] + var epsilon4 = inputData.epsilons[3] + var lambda0 = inputData.lambdas[0] + var lambdaUpFac = inputData.lambdas[1] + var lambdaDnFac = inputData.lambdas[2] + var updateType = inputData.updateType + if (inputData.nargin < 9) { maxIterations = 10 * Npar epsilon1 = 1e-3 @@ -194,7 +193,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI dp = ones(ShapeND(intArrayOf(Npar, 1))).div(1 / dp[0, 0]).as2D() } - var stop = false // termination flag + var stop = false // termination flag if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / kotlin.math.abs(weight[0, 0])).as2D() @@ -218,39 +217,35 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI var lambda = 1.0 var nu = 1 - when (updateType) { - 1 -> lambda = lambda0 // Marquardt: init'l lambda - else -> { // Quadratic and Nielsen - lambda = lambda0 * (makeColumnFromDiagonal(JtWJ)).max()!! - nu = 2 - } + + if (updateType == 1) { + lambda = lambda0 // Marquardt: init'l lambda + } + else { + lambda = lambda0 * (makeColumnFromDiagonal(JtWJ)).max() + nu = 2 } X2Old = X2 // previous value of X2 var h: DoubleTensor - while (!stop && settings.iteration <= maxIterations) { //--- Start Main Loop + while (!stop && settings.iteration <= maxIterations) { settings.iteration += 1 // incremental change in parameters - h = when (updateType) { - 1 -> { // Marquardt - val solve = - solve(JtWJ.plus(makeMatrixWithDiagonal(makeColumnFromDiagonal(JtWJ)).div(1 / lambda)).as2D(), JtWdy) - solve.asDoubleTensor() - } - - else -> { // Quadratic and Nielsen - val solve = solve(JtWJ.plus(lmEye(Npar).div(1 / lambda)).as2D(), JtWdy) - solve.asDoubleTensor() - } + h = if (updateType == 1) { // Marquardt + val solve = solve(JtWJ.plus(makeMatrixWithDiagonal(makeColumnFromDiagonal(JtWJ)).div(1 / lambda)).as2D(), JtWdy) + solve.asDoubleTensor() + } else { // Quadratic and Nielsen + val solve = solve(JtWJ.plus(lmEye(Npar).div(1 / lambda)).as2D(), JtWdy) + solve.asDoubleTensor() } var pTry = (p + h).as2D() // update the [idx] elements - pTry = smallestElementComparison(largestElementComparison(minParameters, pTry.as2D()), maxParameters) // apply constraints + pTry = smallestElementComparison(largestElementComparison(minParameters, pTry.as2D()), maxParameters) // apply constraints - var deltaY = inputData.realValues.minus(evaluateFunction(inputData.func, t, pTry, inputData.exampleNumber)) // residual error using p_try + var deltaY = inputData.realValues.minus(evaluateFunction(inputData.func, t, pTry, inputData.exampleNumber)) // residual error using p_try for (i in 0 until deltaY.shape.component1()) { // floating point error; break for (j in 0 until deltaY.shape.component2()) { @@ -264,21 +259,20 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI settings.funcCalls += 1 val tmp = deltaY.times(weight) - var X2Try = deltaY.as2D().transpose().dot(tmp) // Chi-squared error criteria + var X2Try = deltaY.as2D().transpose().dot(tmp) // Chi-squared error criteria val alpha = 1.0 if (updateType == 2) { // Quadratic // One step of quadratic line update in the h direction for minimum X2 - val alpha = JtWdy.transpose().dot(h) / ((X2Try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h))) h = h.dot(alpha) pTry = p.plus(h).as2D() // update only [idx] elements pTry = smallestElementComparison(largestElementComparison(minParameters, pTry), maxParameters) // apply constraints - deltaY = inputData.realValues.minus(evaluateFunction(inputData.func, t, pTry, inputData.exampleNumber)) // residual error using p_try + deltaY = inputData.realValues.minus(evaluateFunction(inputData.func, t, pTry, inputData.exampleNumber)) // residual error using p_try settings.funcCalls += 1 - X2Try = deltaY.as2D().transpose().dot(deltaY.times(weight)) // Chi-squared error criteria + X2Try = deltaY.as2D().transpose().dot(deltaY.times(weight)) // Chi-squared error criteria } val rho = when (updateType) { // Nielsen @@ -287,7 +281,6 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI .dot(makeMatrixWithDiagonal(makeColumnFromDiagonal(JtWJ)).div(1 / lambda).dot(h).plus(JtWdy)) X2.minus(X2Try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] } - else -> { val tmp = h.transposed().dot(h.div(1 / lambda).plus(JtWdy)) X2.minus(X2Try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] @@ -303,7 +296,6 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI lmMatxAns = lmMatx(inputData.func, t, pOld, yOld, dX2.toInt(), J, p, inputData.realValues, weight, dp, settings) // decrease lambda ==> Gauss-Newton method - JtWJ = lmMatxAns[0] JtWdy = lmMatxAns[1] X2 = lmMatxAns[2][0, 0] @@ -519,7 +511,7 @@ private fun lmMatx(func: (MutableStructure2D<Double>, MutableStructure2D<Double> yDat: MutableStructure2D<Double>, weight: MutableStructure2D<Double>, dp:MutableStructure2D<Double>, settings:LMSettings) : Array<MutableStructure2D<Double>> { // default: dp = 0.001 - val Npar = length(p) // number of parameters + val Npar = length(p) // number of parameters val yHat = evaluateFunction(func, t, p, settings.exampleNumber) // evaluate model using parameters 'p' settings.funcCalls += 1 @@ -558,8 +550,8 @@ private fun lmFdJ(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, dp: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { // default: dp = 0.001 * ones(1,n) - val m = length(y) // number of data points - val n = length(p) // number of parameters + val m = length(y) // number of data points + val n = length(p) // number of parameters val ps = p.copyToTensor().as2D() val J = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, n))).as2D() // initialize Jacobian to Zero @@ -568,7 +560,7 @@ private fun lmFdJ(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, for (j in 0 until n) { del[j, 0] = dp[j, 0] * (1 + kotlin.math.abs(p[j, 0])) // parameter perturbation - p[j, 0] = ps[j, 0] + del[j, 0] // perturb parameter p(j) + p[j, 0] = ps[j, 0] + del[j, 0] // perturb parameter p(j) val epsilon = 0.0000001 if (kotlin.math.abs(del[j, 0]) > epsilon) { From f91b018d4f2a330697bc00dd9dd94f71a150dcb7 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 7 Jun 2023 07:24:47 +0300 Subject: [PATCH 031/103] add assertEquals to middle and difficult test --- .../kmath/tensors/core/TestLmAlgorithm.kt | 144 +++++++++++------- 1 file changed, 85 insertions(+), 59 deletions(-) diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index 4e1df3b08..4b031eb11 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -22,63 +22,63 @@ class TestLmAlgorithm { companion object { fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() - var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) + var yHat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) if (exampleNumber == 1) { - y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( + yHat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) ) } else if (exampleNumber == 2) { val mt = t.max() - y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + + yHat = (t.times(1.0 / mt)).times(p[0, 0]) + (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + (t.times(1.0 / mt)).pow(4).times(p[3, 0]) } else if (exampleNumber == 3) { - y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) + yHat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) } - return y_hat.as2D() + return yHat.as2D() } fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() - var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + var yHat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) val mt = t.max() for(i in 0 until p.shape.component1()){ - y_hat += (t.times(1.0 / mt)).times(p[i, 0]) + yHat += (t.times(1.0 / mt)).times(p[i, 0]) } for(i in 0 until 5){ - y_hat = funcEasyForLm(y_hat.as2D(), p, exampleNumber).asDoubleTensor() + yHat = funcEasyForLm(yHat.as2D(), p, exampleNumber).asDoubleTensor() } - return y_hat.as2D() + return yHat.as2D() } fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { val m = t.shape.component1() - var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + var yHat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) val mt = t.max() for(i in 0 until p.shape.component1()){ - y_hat = y_hat.plus( (t.times(1.0 / mt)).times(p[i, 0]) ) + yHat = yHat.plus( (t.times(1.0 / mt)).times(p[i, 0]) ) } for(i in 0 until 4){ - y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, exampleNumber).asDoubleTensor() + yHat = funcEasyForLm((yHat.as2D() + t).as2D(), p, exampleNumber).asDoubleTensor() } - return y_hat.as2D() + return yHat.as2D() } } @Test fun testLMEasy() = DoubleTensorAlgebra { - val lm_matx_y_dat = doubleArrayOf( + val lmMatxYDat = doubleArrayOf( 19.6594, 18.6096, 17.6792, 17.2747, 16.3065, 17.1458, 16.0467, 16.7023, 15.7809, 15.9807, 14.7620, 15.1128, 16.0973, 15.1934, 15.8636, 15.4763, 15.6860, 15.1895, 15.3495, 16.6054, 16.2247, 15.9854, 16.1421, 17.0960, 16.7769, 17.1997, 17.2767, 17.5882, 17.5378, 16.7894, @@ -91,7 +91,7 @@ class TestLmAlgorithm { 14.7665, 13.3718, 15.0587, 13.8320, 14.7873, 13.6824, 14.2579, 14.2154, 13.5818, 13.8157 ) - var example_number = 1 + var exampleNumber = 1 val p_init = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(4, 1)), doubleArrayOf(5.0, 2.0, 0.2, 10.0) ).as2D() @@ -101,8 +101,8 @@ class TestLmAlgorithm { t[i, 0] = t[i, 0] * (i + 1) } - val y_dat = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(100, 1)), lm_matx_y_dat + val yDat = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(100, 1)), lmMatxYDat ).as2D() val weight = 4.0 @@ -111,20 +111,16 @@ class TestLmAlgorithm { ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() - val p_min = BroadcastDoubleTensorAlgebra.fromArray( + val pMin = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(4, 1)), doubleArrayOf(-50.0, -20.0, -2.0, -100.0) ).as2D() - val p_max = BroadcastDoubleTensorAlgebra.fromArray( + val pMax = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0) ).as2D() - val opts = doubleArrayOf(3.0, 100.0, 1e-3, 1e-3, 1e-1, 1e-1, 1e-2, 11.0, 9.0, 1.0) - - val inputData = LMInput(::funcEasyForLm, p_init, t, y_dat, weight, dp, p_min, p_max, opts[1].toInt(), - doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), - doubleArrayOf(opts[6], opts[7], opts[8]), - opts[9].toInt(), 10, example_number) + val inputData = LMInput(::funcEasyForLm, p_init, t, yDat, weight, dp, pMin, pMax, 100, + doubleArrayOf(1e-3, 1e-3, 1e-1, 1e-1), doubleArrayOf(1e-2, 11.0, 9.0), 1, 10, exampleNumber) val result = levenbergMarquardt(inputData) assertEquals(13, result.iterations) @@ -149,46 +145,46 @@ class TestLmAlgorithm { @Test fun TestLMMiddle() = DoubleTensorAlgebra { val NData = 100 - var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() + val tExample = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() for (i in 0 until NData) { - t_example[i, 0] = t_example[i, 0] * (i + 1) + tExample[i, 0] = tExample[i, 0] * (i + 1) } val Nparams = 20 - var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() + val pExample = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { - p_example[i, 0] = p_example[i, 0] + i - 25 + pExample[i, 0] = pExample[i, 0] + i - 25 } val exampleNumber = 1 - var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber) + val yHat = funcMiddleForLm(tExample, pExample, exampleNumber) - var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + val pInit = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { - p_init[i, 0] = (p_example[i, 0] + 0.9) + pInit[i, 0] = (pExample[i, 0] + 0.9) } - var t = t_example - val y_dat = y_hat + val t = tExample + val yDat = yHat val weight = 1.0 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() - var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) - p_min = p_min.div(1.0 / -50.0) - val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) - p_min = p_min.div(1.0 / 50.0) + var pMin = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + pMin = pMin.div(1.0 / -50.0) + val pMax = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + pMin = pMin.div(1.0 / 50.0) val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) val inputData = LMInput(::funcMiddleForLm, - p_init.as2D(), + pInit.as2D(), t, - y_dat, + yDat, weight, dp, - p_min.as2D(), - p_max.as2D(), + pMin.as2D(), + pMax.as2D(), opts[1].toInt(), doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), doubleArrayOf(opts[6], opts[7], opts[8]), @@ -197,51 +193,67 @@ class TestLmAlgorithm { 1) val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) + + assertEquals(46, result.iterations) + assertEquals(113, result.funcCalls) + assertEquals(0.000005977, (result.resultChiSq * 1e9).roundToLong() / 1e9) + assertEquals(1.0 * 1e-7, (result.resultLambda * 1e13).roundToLong() / 1e13) + assertEquals(result.typeOfConvergence, TypeOfConvergence.InReducedChiSquare) + val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(Nparams, 1)), doubleArrayOf( -23.9717, -18.6686, -21.7971, + -20.9681, -22.086, -20.5859, -19.0384, -17.4957, -15.9991, -14.576, -13.2441, - + 12.0201, -10.9256, -9.9878, -9.2309, -8.6589, -8.2365, -7.8783, -7.4598, -6.8511)).as2D() + result.resultParameters = result.resultParameters.map { x -> (x * 1e4).roundToLong() / 1e4}.as2D() + val receivedParameters = zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + receivedParameters[i, 0] = result.resultParameters[i, 0] + assertEquals(expectedParameters[i, 0], result.resultParameters[i, 0]) + } } @Test fun TestLMDifficult() = DoubleTensorAlgebra { val NData = 200 - var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() + var tExample = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() for (i in 0 until NData) { - t_example[i, 0] = t_example[i, 0] * (i + 1) - 104 + tExample[i, 0] = tExample[i, 0] * (i + 1) - 104 } val Nparams = 15 - var p_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() + var pExample = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { - p_example[i, 0] = p_example[i, 0] + i - 25 + pExample[i, 0] = pExample[i, 0] + i - 25 } val exampleNumber = 1 - var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber) + var yHat = funcDifficultForLm(tExample, pExample, exampleNumber) - var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + var pInit = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { - p_init[i, 0] = (p_example[i, 0] + 0.9) + pInit[i, 0] = (pExample[i, 0] + 0.9) } - var t = t_example - val y_dat = y_hat + var t = tExample + val yDat = yHat val weight = 1.0 / Nparams * 1.0 - 0.085 val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() - var p_min = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) - p_min = p_min.div(1.0 / -50.0) - val p_max = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) - p_min = p_min.div(1.0 / 50.0) + var pMin = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + pMin = pMin.div(1.0 / -50.0) + val pMax = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) + pMin = pMin.div(1.0 / 50.0) val opts = doubleArrayOf(3.0, 7000.0, 1e-2, 1e-3, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) val inputData = LMInput(::funcDifficultForLm, - p_init.as2D(), + pInit.as2D(), t, - y_dat, + yDat, weight, dp, - p_min.as2D(), - p_max.as2D(), + pMin.as2D(), + pMax.as2D(), opts[1].toInt(), doubleArrayOf(opts[2], opts[3], opts[4], opts[5]), doubleArrayOf(opts[6], opts[7], opts[8]), @@ -250,5 +262,19 @@ class TestLmAlgorithm { 1) val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) + + assertEquals(2375, result.iterations) + assertEquals(4858, result.funcCalls) + assertEquals(5.14347, (result.resultLambda * 1e5).roundToLong() / 1e5) + assertEquals(result.typeOfConvergence, TypeOfConvergence.InParameters) + val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( + ShapeND(intArrayOf(Nparams, 1)), doubleArrayOf(-23.6412, -16.7402, -21.5705, -21.0464, + -17.2852, -17.2959, -17.298, 0.9999, -17.2885, -17.3008, -17.2941, -17.2923, -17.2976, -17.3028, -17.2891)).as2D() + result.resultParameters = result.resultParameters.map { x -> (x * 1e4).roundToLong() / 1e4}.as2D() + val receivedParameters = zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() + for (i in 0 until Nparams) { + receivedParameters[i, 0] = result.resultParameters[i, 0] + assertEquals(expectedParameters[i, 0], result.resultParameters[i, 0]) + } } } \ No newline at end of file From 1f6b7abf464b1564ff442b3cfc71b3ead72ec791 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 7 Jun 2023 15:16:58 +0300 Subject: [PATCH 032/103] wasm test version --- gradle.properties | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gradle.properties b/gradle.properties index 0fdf1a058..9ffc1ebe3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx4096m org.gradle.parallel=true org.gradle.workers.max=4 -toolsVersion=0.14.9-kotlin-1.9.0-Beta -kotlin.experimental.tryK2=true -kscience.wasm.disabled=true \ No newline at end of file +toolsVersion=0.14.9-kotlin-1.9.0-Beta-dev-3 +#kotlin.experimental.tryK2=true +#kscience.wasm.disabled=true \ No newline at end of file From ef4335bc410fd7fdd82e88bea960ede05a41e2be Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Wed, 7 Jun 2023 15:24:01 +0300 Subject: [PATCH 033/103] use function types for input func --- .../kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt | 2 +- .../kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index fe96b2fe9..f052279ae 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -16,7 +16,7 @@ import space.kscience.kmath.tensors.core.levenbergMarquardt import kotlin.random.Random import kotlin.reflect.KFunction3 -fun streamLm(lm_func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, Int, MutableStructure2D<Double>>, +fun streamLm(lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> (MutableStructure2D<Double>), startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int): Flow<MutableStructure2D<Double>> = flow{ var example_number = startData.example_number diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index d9c282fb6..3cb485d7d 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -88,7 +88,7 @@ public data class LMResultInfo ( * exampleNumber: a parameter for a function with which you can choose its behavior. */ public data class LMInput ( - var func: KFunction3<MutableStructure2D<Double>, MutableStructure2D<Double>, Int, MutableStructure2D<Double>>, + var func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> (MutableStructure2D<Double>), var startParameters: MutableStructure2D<Double>, var independentVariables: MutableStructure2D<Double>, var realValues: MutableStructure2D<Double>, From 009f93adbb5e88f9ec7c2c0c90a5f6856ae27d1f Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Thu, 8 Jun 2023 09:28:26 +0300 Subject: [PATCH 034/103] Add rotation coversion test for XYZ --- .../kotlin/space/kscience/kmath/geometry/RotationTest.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt index 6177382a2..c7c202a70 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt @@ -44,7 +44,9 @@ class RotationTest { @Test fun fromEuler() { val q = Quaternion.fromEuler(0.1.radians, 0.2.radians, 0.3.radians, RotationOrder.ZXY) - assertBufferEquals(DoubleBuffer(0.9818562, 0.0342708, 0.1060205, 0.1534393), q) + + val q1 = Quaternion.fromEuler(0.1.radians, 0.2.radians, 0.3.radians, RotationOrder.XYZ) + assertBufferEquals(DoubleBuffer(0.9818562, 0.0640713, 0.0911575, 0.1534393), q1) } } \ No newline at end of file From 5f2690309b16d27f1fbf10760ff1a8e609149583 Mon Sep 17 00:00:00 2001 From: Margarita Lashina <lashina.2000@gmail.com> Date: Tue, 13 Jun 2023 03:06:55 +0300 Subject: [PATCH 035/103] fix mistake in streaming version --- .../kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index f052279ae..b2818ef2a 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -51,8 +51,8 @@ fun streamLm(lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, I val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) emit(result.resultParameters) delay(launchFrequencyInMs) - p_init = result.resultParameters - y_dat = generateNewYDat(y_dat, 0.1) + inputData.realValues = generateNewYDat(y_dat, 0.1) + inputData.startParameters = result.resultParameters if (!isEndless) steps -= 1 } } From e00c2a4e2b03c1548933aeb035d1f0006c7999ae Mon Sep 17 00:00:00 2001 From: Gleb Minaev <43728100+lounres@users.noreply.github.com> Date: Fri, 16 Jun 2023 16:00:48 +0300 Subject: [PATCH 036/103] Fix version of `matheclipse-core`. --- kmath-symja/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmath-symja/build.gradle.kts b/kmath-symja/build.gradle.kts index 8741de2ae..a996f3bec 100644 --- a/kmath-symja/build.gradle.kts +++ b/kmath-symja/build.gradle.kts @@ -10,7 +10,7 @@ plugins { description = "Symja integration module" dependencies { - api("org.matheclipse:matheclipse-core:2.0.0-SNAPSHOT") { + api("org.matheclipse:matheclipse-core:2.0.0") { // Incorrect transitive dependencies exclude("org.apfloat", "apfloat") exclude("org.hipparchus", "hipparchus-clustering") From d3893ab7e6b38970c5761f4c14c949272331ebc7 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 20 Jun 2023 19:45:21 +0300 Subject: [PATCH 037/103] [WIP] moving from features to attributes --- attributes-kt/build.gradle.kts | 17 +++++ .../space/kscience/attributes/Attribute.kt | 28 ++++++++ .../kscience/attributes/AttributeContainer.kt | 13 ++++ .../space/kscience/attributes/Attributes.kt | 71 +++++++++++++++++++ .../kscience/attributes/AttributesBuilder.kt | 52 ++++++++++++++ build.gradle.kts | 2 +- buildSrc/settings.gradle.kts | 6 -- gradle.properties | 9 ++- .../kscience/kmath/commons/linear/CMMatrix.kt | 2 +- kmath-core/build.gradle.kts | 1 + .../kscience/kmath/linear/MatrixFeatures.kt | 37 +++++----- .../kscience/kmath/linear/MatrixWrapper.kt | 25 +++---- .../space/kscience/kmath/misc/Featured.kt | 61 ---------------- .../space/kscience/kmath/nd/AlgebraND.kt | 5 +- .../space/kscience/kmath/nd/StructureND.kt | 14 ++-- kmath-symja/build.gradle.kts | 2 +- settings.gradle.kts | 1 + 17 files changed, 219 insertions(+), 127 deletions(-) create mode 100644 attributes-kt/build.gradle.kts create mode 100644 attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt create mode 100644 attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt create mode 100644 attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt create mode 100644 attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt delete mode 100644 kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt diff --git a/attributes-kt/build.gradle.kts b/attributes-kt/build.gradle.kts new file mode 100644 index 000000000..fe422f751 --- /dev/null +++ b/attributes-kt/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + id("space.kscience.gradle.mpp") +} + +kscience { + jvm() + js() + native() + wasm() +} + +readme { + maturity = space.kscience.gradle.Maturity.DEVELOPMENT + description = """ + An API and basic implementation for arranging objects in a continuous memory block. + """.trimIndent() +} diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt new file mode 100644 index 000000000..4b9e27655 --- /dev/null +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2018-2023 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.attributes + +import kotlin.reflect.KType + +public interface Attribute<T> + + +public interface AttributeWithDefault<T> : Attribute<T> { + public val default: T +} + +public interface SetAttribute<V> : Attribute<Set<V>> + +/** + * An attribute that has a type parameter for value + */ +public abstract class PolymorphicAttribute<T>(public val type: KType) : Attribute<T> { + override fun equals(other: Any?): Boolean = (other as? PolymorphicAttribute<*>)?.type == this.type + + override fun hashCode(): Int { + return type.hashCode() + } +} diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt new file mode 100644 index 000000000..69b050649 --- /dev/null +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2018-2023 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.attributes + +/** + * A container for attributes. [attributes] could be made mutable by implementation + */ +public interface AttributeContainer { + public val attributes: Attributes +} \ No newline at end of file diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt new file mode 100644 index 000000000..25767a686 --- /dev/null +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -0,0 +1,71 @@ +/* + * Copyright 2018-2023 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.attributes + +import kotlin.jvm.JvmInline + +@JvmInline +public value class Attributes internal constructor(public val content: Map<out Attribute<*>, Any>) { + + public val keys: Set<Attribute<*>> get() = content.keys + + @Suppress("UNCHECKED_CAST") + public operator fun <T> get(attribute: Attribute<T>): T? = content[attribute] as? T + + override fun toString(): String = "Attributes(value=${content.entries})" + + public companion object { + public val EMPTY: Attributes = Attributes(emptyMap()) + } +} + +public fun Attributes.isEmpty(): Boolean = content.isEmpty() + +public fun <T> Attributes.getOrDefault(attribute: AttributeWithDefault<T>): T = get(attribute) ?: attribute.default + +public fun <T, A : Attribute<T>> Attributes.withAttribute( + attribute: A, + attrValue: T?, +): Attributes = Attributes( + if (attrValue == null) { + content - attribute + } else { + content + (attribute to attrValue) + } +) + +/** + * Add an element to a [SetAttribute] + */ +public fun <T, A : SetAttribute<T>> Attributes.withAttributeElement( + attribute: A, + attrValue: T, +): Attributes { + val currentSet: Set<T> = get(attribute) ?: emptySet() + return Attributes( + content + (attribute to (currentSet + attrValue)) + ) +} + +/** + * Remove an element from [SetAttribute] + */ +public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement( + attribute: A, + attrValue: T, +): Attributes { + val currentSet: Set<T> = get(attribute) ?: emptySet() + return Attributes( + content + (attribute to (currentSet - attrValue)) + ) +} + +public fun <T : Any, A : Attribute<T>> Attributes( + attribute: A, + attrValue: T, +): Attributes = Attributes(mapOf(attribute to attrValue)) + +public operator fun Attributes.plus(other: Attributes): Attributes = Attributes(content + other.content) \ No newline at end of file diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt new file mode 100644 index 000000000..588c789f5 --- /dev/null +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2018-2023 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.attributes + +/** + * A safe builder for [Attributes] + */ +public class AttributesBuilder internal constructor(private val map: MutableMap<Attribute<*>, Any> = mutableMapOf()) { + + @Suppress("UNCHECKED_CAST") + public operator fun <T> get(attribute: Attribute<T>): T? = map[attribute] as? T + + public operator fun <V> Attribute<V>.invoke(value: V?) { + if (value == null) { + map.remove(this) + } else { + map[this] = value + } + } + + public fun from(attributes: Attributes) { + map.putAll(attributes.content) + } + + public fun <V> SetAttribute<V>.add( + attrValue: V, + ) { + val currentSet: Set<V> = get(this) ?: emptySet() + map[this] = currentSet + attrValue + } + + /** + * Remove an element from [SetAttribute] + */ + public fun <V> SetAttribute<V>.remove( + attrValue: V, + ) { + val currentSet: Set<V> = get(this) ?: emptySet() + map[this] = currentSet - attrValue + } + + public fun build(): Attributes = Attributes(map) +} + +public fun AttributesBuilder( + attributes: Attributes, +): AttributesBuilder = AttributesBuilder(attributes.content.toMutableMap()) + +public fun Attributes(builder: AttributesBuilder.() -> Unit): Attributes = AttributesBuilder().apply(builder).build() \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 043420577..a132f091c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ allprojects { } group = "space.kscience" - version = "0.3.2-dev-1" + version = "0.4.0-dev-1" } subprojects { diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index e6b69b0b3..38eebeecc 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -1,9 +1,3 @@ -/* - * 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. - */ -rootProject.name = "kmath" - enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") dependencyResolutionManagement { diff --git a/gradle.properties b/gradle.properties index fee75d428..162720167 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,11 +6,10 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.native.ignoreDisabledTargets=true -org.gradle.configureondemand=true -org.gradle.jvmargs=-Xmx4096m - -toolsVersion=0.14.8-kotlin-1.8.20 - +toolsVersion=0.14.9-kotlin-1.8.20 org.gradle.parallel=true org.gradle.workers.max=4 +org.gradle.configureondemand=true +org.gradle.jvmargs=-Xmx4096m + diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index d19bd1be0..e369effdf 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -106,7 +106,7 @@ public object CMLinearSpace : LinearSpace<Double, DoubleField> { val origin = structure.toCM().origin return when (type) { - DiagonalFeature::class -> if (origin is DiagonalMatrix) DiagonalFeature else null + IsDiagonal::class -> if (origin is DiagonalMatrix) IsDiagonal else null DeterminantFeature::class, LupDecompositionFeature::class -> object : DeterminantFeature<Double>, diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index 4ecff77aa..398465fbe 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -10,6 +10,7 @@ kscience{ dependencies { api(projects.kmathMemory) + api(projects.attributesKt) } testDependencies { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt index ce7acdcba..62325b39d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt @@ -5,54 +5,49 @@ package space.kscience.kmath.linear -import space.kscience.kmath.nd.StructureFeature +import space.kscience.attributes.Attribute /** * A marker interface representing some properties of matrices or additional transformations of them. Features are used * to optimize matrix operations performance in some cases or retrieve the APIs. */ -public interface MatrixFeature: StructureFeature +public interface MatrixFeature<T> : Attribute<T> /** - * Matrices with this feature are considered to have only diagonal non-null elements. + * Matrices with this feature are considered to have only diagonal non-zero elements. */ -public interface DiagonalFeature : MatrixFeature { - public companion object : DiagonalFeature +public interface IsDiagonal : MatrixFeature<Unit> { + public companion object : IsDiagonal } /** * Matrices with this feature have all zero elements. */ -public object ZeroFeature : DiagonalFeature +public object IsZero : IsDiagonal /** * Matrices with this feature have unit elements on diagonal and zero elements in all other places. */ -public object UnitFeature : DiagonalFeature +public object IsUnit : IsDiagonal /** * Matrices with this feature can be inverted: *[inverse] = a<sup>−1</sup>* where *a* is the owning matrix. * * @param T the type of matrices' items. */ -public interface InverseMatrixFeature<out T : Any> : MatrixFeature { - /** - * The inverse matrix of the matrix that owns this feature. - */ - public val inverse: Matrix<T> +public class Inverted<T> private constructor() : MatrixFeature<Matrix<T>> { + internal val instance: Inverted<Nothing> = Inverted() } +@Suppress("UNCHECKED_CAST") +public val <T> LinearSpace<T, *>.Inverted: Inverted<T> get() = Inverted.instance as Inverted<T> + /** * Matrices with this feature can compute their determinant. * * @param T the type of matrices' items. */ -public interface DeterminantFeature<out T : Any> : MatrixFeature { - /** - * The determinant of the matrix that owns this feature. - */ - public val determinant: T -} +public class DeterminantFeature<T : Any> : MatrixFeature<T> /** * Produces a [DeterminantFeature] where the [DeterminantFeature.determinant] is [determinant]. @@ -68,12 +63,12 @@ public fun <T : Any> DeterminantFeature(determinant: T): DeterminantFeature<T> = /** * Matrices with this feature are lower triangular ones. */ -public object LFeature : MatrixFeature +public object LFeature : MatrixFeature<Unit> /** * Matrices with this feature are upper triangular ones. */ -public object UFeature : MatrixFeature +public object UFeature : MatrixFeature<Unit> /** * Matrices with this feature support LU factorization: *a = [l] · [u]* where *a* is the owning matrix. @@ -117,7 +112,7 @@ public interface LupDecompositionFeature<out T : Any> : MatrixFeature { /** * Matrices with this feature are orthogonal ones: *a · a<sup>T</sup> = u* where *a* is the owning matrix, *u* - * is the unit matrix ([UnitFeature]). + * is the unit matrix ([IsUnit]). */ public object OrthogonalFeature : MatrixFeature diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index 46454a584..b510cc697 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -5,11 +5,10 @@ package space.kscience.kmath.linear +import space.kscience.attributes.Attributes import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.misc.FeatureSet -import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.operations.Ring -import kotlin.reflect.KClass /** * A [Matrix] that holds [MatrixFeature] objects. @@ -18,18 +17,10 @@ import kotlin.reflect.KClass */ public class MatrixWrapper<out T : Any> internal constructor( public val origin: Matrix<T>, - public val features: FeatureSet<StructureFeature>, + public val attributes: Attributes, ) : Matrix<T> by origin { - /** - * Get the first feature matching given class. Does not guarantee that matrix has only one feature matching the - * criteria. - */ - @Suppress("UNCHECKED_CAST") - override fun <F : StructureFeature> getFeature(type: KClass<out F>): F? = - features.getFeature(type) ?: origin.getFeature(type) - - override fun toString(): String = "MatrixWrapper(matrix=$origin, features=$features)" + override fun toString(): String = "MatrixWrapper(matrix=$origin, features=$attributes)" } /** @@ -44,7 +35,7 @@ public val <T : Any> Matrix<T>.origin: Matrix<T> * Add a single feature to a [Matrix] */ public fun <T : Any> Matrix<T>.withFeature(newFeature: MatrixFeature): MatrixWrapper<T> = if (this is MatrixWrapper) { - MatrixWrapper(origin, features.with(newFeature)) + MatrixWrapper(origin, attributes.with(newFeature)) } else { MatrixWrapper(this, FeatureSet.of(newFeature)) } @@ -57,20 +48,20 @@ public operator fun <T : Any> Matrix<T>.plus(newFeature: MatrixFeature): MatrixW */ public fun <T : Any> Matrix<T>.withFeatures(newFeatures: Iterable<MatrixFeature>): MatrixWrapper<T> = if (this is MatrixWrapper) { - MatrixWrapper(origin, features.with(newFeatures)) + MatrixWrapper(origin, attributes.with(newFeatures)) } else { MatrixWrapper(this, FeatureSet.of(newFeatures)) } /** - * Diagonal matrix of ones. The matrix is virtual no actual matrix is created. + * Diagonal matrix of ones. The matrix is virtual, no actual matrix is created. */ public fun <T : Any> LinearSpace<T, Ring<T>>.one( rows: Int, columns: Int, ): Matrix<T> = VirtualMatrix(rows, columns) { i, j -> if (i == j) elementAlgebra.one else elementAlgebra.zero -}.withFeature(UnitFeature) +}.withFeature(IsUnit) /** @@ -81,7 +72,7 @@ public fun <T : Any> LinearSpace<T, Ring<T>>.zero( columns: Int, ): Matrix<T> = VirtualMatrix(rows, columns) { _, _ -> elementAlgebra.zero -}.withFeature(ZeroFeature) +}.withFeature(IsZero) public class TransposedFeature<out T : Any>(public val original: Matrix<T>) : MatrixFeature diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt deleted file mode 100644 index bdda674dc..000000000 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2018-2022 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.misc - -import kotlin.jvm.JvmInline -import kotlin.reflect.KClass - -/** - * An entity that contains a set of features defined by their types - */ -public interface Featured<F : Any> { - public fun <T : F> getFeature(type: FeatureKey<T>): T? -} - -public typealias FeatureKey<T> = KClass<out T> - -public interface Feature<F : Feature<F>> { - - /** - * A key used for extraction - */ - @Suppress("UNCHECKED_CAST") - public val key: FeatureKey<F> - get() = this::class as FeatureKey<F> -} - -/** - * A container for a set of features - */ -@JvmInline -public value class FeatureSet<F : Feature<F>> private constructor(public val features: Map<FeatureKey<F>, F>) : Featured<F> { - @Suppress("UNCHECKED_CAST") - override fun <T : F> getFeature(type: FeatureKey<T>): T? = features[type]?.let { it as T } - - public inline fun <reified T : F> getFeature(): T? = getFeature(T::class) - - public fun <T : F> with(feature: T, type: FeatureKey<F> = feature.key): FeatureSet<F> = - FeatureSet(features + (type to feature)) - - public fun with(other: FeatureSet<F>): FeatureSet<F> = FeatureSet(features + other.features) - - public fun with(vararg otherFeatures: F): FeatureSet<F> = - FeatureSet(features + otherFeatures.associateBy { it.key }) - - public fun with(otherFeatures: Iterable<F>): FeatureSet<F> = - FeatureSet(features + otherFeatures.associateBy { it.key }) - - public operator fun iterator(): Iterator<F> = features.values.iterator() - - override fun toString(): String = features.values.joinToString(prefix = "[ ", postfix = " ]") - - - public companion object { - public fun <F : Feature<F>> of(vararg features: F): FeatureSet<F> = FeatureSet(features.associateBy { it.key }) - public fun <F : Feature<F>> of(features: Iterable<F>): FeatureSet<F> = - FeatureSet(features.associateBy { it.key }) - } -} diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt index f6626432d..a75807bad 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt @@ -114,7 +114,7 @@ public interface GroupOpsND<T, out A : GroupOps<T>> : GroupOps<StructureND<T>>, override fun add(left: StructureND<T>, right: StructureND<T>): StructureND<T> = zip(left, right) { aValue, bValue -> add(aValue, bValue) } - // TODO move to extensions after KEEP-176 + // TODO implement using context receivers /** * Adds an ND structure to an element of it. @@ -181,8 +181,6 @@ public interface RingOpsND<T, out A : RingOps<T>> : RingOps<StructureND<T>>, Gro override fun multiply(left: StructureND<T>, right: StructureND<T>): StructureND<T> = zip(left, right) { aValue, bValue -> multiply(aValue, bValue) } - //TODO move to extensions with context receivers - /** * Multiplies an ND structure by an element of it. * @@ -232,7 +230,6 @@ public interface FieldOpsND<T, out A : Field<T>> : override fun divide(left: StructureND<T>, right: StructureND<T>): StructureND<T> = zip(left, right) { aValue, bValue -> divide(aValue, bValue) } - //TODO move to extensions after https://github.com/Kotlin/KEEP/blob/master/proposals/context-receivers.md /** * Divides an ND structure by an element of it. * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index f0a258389..e9814acbf 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -5,10 +5,10 @@ package space.kscience.kmath.nd +import space.kscience.attributes.Attribute +import space.kscience.attributes.AttributeContainer import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.linear.LinearSpace -import space.kscience.kmath.misc.Feature -import space.kscience.kmath.misc.Featured import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer @@ -17,7 +17,7 @@ import kotlin.jvm.JvmName import kotlin.math.abs import kotlin.reflect.KClass -public interface StructureFeature : Feature<StructureFeature> +public interface StructureFeature<T> : Attribute<T> /** * Represents n-dimensional structure i.e., multidimensional container of items of the same type and size. The number @@ -28,7 +28,7 @@ public interface StructureFeature : Feature<StructureFeature> * * @param T the type of items. */ -public interface StructureND<out T> : Featured<StructureFeature>, WithShape { +public interface StructureND<out T> : AttributeContainer, WithShape { /** * The shape of structure i.e., non-empty sequence of non-negative integers that specify sizes of dimensions of * this structure. @@ -57,12 +57,6 @@ public interface StructureND<out T> : Featured<StructureFeature>, WithShape { @PerformancePitfall public fun elements(): Sequence<Pair<IntArray, T>> = indices.asSequence().map { it to get(it) } - /** - * Feature is some additional structure information that allows to access it special properties or hints. - * If the feature is not present, `null` is returned. - */ - override fun <F : StructureFeature> getFeature(type: KClass<out F>): F? = null - public companion object { /** * Indicates whether some [StructureND] is equal to another one. diff --git a/kmath-symja/build.gradle.kts b/kmath-symja/build.gradle.kts index 8741de2ae..a996f3bec 100644 --- a/kmath-symja/build.gradle.kts +++ b/kmath-symja/build.gradle.kts @@ -10,7 +10,7 @@ plugins { description = "Symja integration module" dependencies { - api("org.matheclipse:matheclipse-core:2.0.0-SNAPSHOT") { + api("org.matheclipse:matheclipse-core:2.0.0") { // Incorrect transitive dependencies exclude("org.apfloat", "apfloat") exclude("org.hipparchus", "hipparchus-clustering") diff --git a/settings.gradle.kts b/settings.gradle.kts index f158f3444..e660bef85 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,6 +21,7 @@ dependencyResolutionManagement { include( ":test-utils", + ":attributes-kt", ":kmath-memory", ":kmath-complex", ":kmath-core", From a001c7402579aa822a3659b752e58238231f4af7 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Thu, 22 Jun 2023 08:49:51 +0300 Subject: [PATCH 038/103] 1.9.0-RC --- buildSrc/settings.gradle.kts | 1 - gradle.properties | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index e6b69b0b3..02111ba37 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -2,7 +2,6 @@ * 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. */ -rootProject.name = "kmath" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") diff --git a/gradle.properties b/gradle.properties index 9ffc1ebe3..81eb66e34 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx4096m org.gradle.parallel=true org.gradle.workers.max=4 -toolsVersion=0.14.9-kotlin-1.9.0-Beta-dev-3 -#kotlin.experimental.tryK2=true +toolsVersion=0.14.9-kotlin-1.9.0-RC-dev-1 +kotlin.experimental.tryK2=true #kscience.wasm.disabled=true \ No newline at end of file From 6da51b7794f9ccf6d24c29b85b5081bba1cedf65 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 9 Jul 2023 15:51:50 +0300 Subject: [PATCH 039/103] [WIP] Features to Attributes refactoring --- CHANGELOG.md | 4 +- .../space/kscience/attributes/Attribute.kt | 21 +- .../space/kscience/attributes/Attributes.kt | 48 +- .../space/kscience/attributes/SafeType.kt | 26 + .../space/kscience/attributes/annotations.kt | 17 + buildSrc/settings.gradle.kts | 3 +- .../kmath/ejml/codegen/ejmlCodegen.kt | 2 + gradle.properties | 3 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../kscience/kmath/commons/linear/CMMatrix.kt | 31 +- .../kscience/kmath/expressions/DSAlgebra.kt | 2 + .../kmath/linear/BufferedLinearSpace.kt | 3 + .../kmath/linear/DoubleLinearSpace.kt | 4 +- .../kscience/kmath/linear/LinearSpace.kt | 40 +- .../kscience/kmath/linear/LupDecomposition.kt | 188 +-- .../kscience/kmath/linear/MatrixBuilder.kt | 7 +- .../kscience/kmath/linear/MatrixFeatures.kt | 158 +-- .../kscience/kmath/linear/MatrixWrapper.kt | 47 +- .../kscience/kmath/linear/VirtualMatrix.kt | 9 +- .../space/kscience/kmath/nd/AlgebraND.kt | 4 +- .../space/kscience/kmath/nd/BufferND.kt | 4 +- .../space/kscience/kmath/nd/Structure2D.kt | 2 +- .../space/kscience/kmath/nd/StructureND.kt | 22 +- .../kscience/kmath/operations/Algebra.kt | 10 +- .../kmath/operations/BufferAlgebra.kt | 4 + .../space/kscience/kmath/structures/Buffer.kt | 22 +- .../kmath/structures/BufferAccessor2D.kt | 9 +- .../kmath/structures/MutableBuffer.kt | 25 +- .../kscience/kmath/ejml/EjmlLinearSpace.kt | 4 +- .../space/kscience/kmath/ejml/_generated.kt | 1003 ----------------- .../kscience/kmath/ejml/EjmlMatrixTest.kt | 4 +- .../space/kscience/kmath/real/DoubleVector.kt | 1 - .../kscience/kmath/functions/Polynomial.kt | 21 +- .../kmath/distributions/NormalDistribution.kt | 7 +- 34 files changed, 457 insertions(+), 1300 deletions(-) create mode 100644 attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt create mode 100644 attributes-kt/src/commonMain/kotlin/space/kscience/attributes/annotations.kt delete mode 100644 kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e1d9f530..bbfb68501 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,9 +3,11 @@ ## Unreleased ### Added -- Explicit `mutableStructureND` builders for mutable stucures +- New Attributes-kt module that could be used as stand-alone. It declares type-safe attributes containers. +- Explicit `mutableStructureND` builders for mutable structures ### Changed +- Features replaced with Attributes. ### Deprecated diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt index 4b9e27655..6fa142180 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt @@ -9,20 +9,31 @@ import kotlin.reflect.KType public interface Attribute<T> +/** + * An attribute that could be either present or absent + */ +public interface FlagAttribute : Attribute<Unit> +/** + * An attribute with a default value + */ public interface AttributeWithDefault<T> : Attribute<T> { public val default: T } +/** + * Attribute containing a set of values + */ public interface SetAttribute<V> : Attribute<Set<V>> /** * An attribute that has a type parameter for value + * @param type parameter-type */ -public abstract class PolymorphicAttribute<T>(public val type: KType) : Attribute<T> { - override fun equals(other: Any?): Boolean = (other as? PolymorphicAttribute<*>)?.type == this.type +public abstract class PolymorphicAttribute<T>(public val type: SafeType<T>) : Attribute<T> { + override fun equals(other: Any?): Boolean = other != null && + (this::class == other::class) && + (other as? PolymorphicAttribute<*>)?.type == this.type - override fun hashCode(): Int { - return type.hashCode() - } + override fun hashCode(): Int = this::class.hashCode() + type.hashCode() } diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index 25767a686..f93b6446a 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -24,18 +24,45 @@ public value class Attributes internal constructor(public val content: Map<out A public fun Attributes.isEmpty(): Boolean = content.isEmpty() +/** + * Get attribute value or default + */ public fun <T> Attributes.getOrDefault(attribute: AttributeWithDefault<T>): T = get(attribute) ?: attribute.default -public fun <T, A : Attribute<T>> Attributes.withAttribute( +/** + * Check if there is an attribute that matches given key by type and adheres to [predicate]. + */ +@Suppress("UNCHECKED_CAST") +public inline fun <T, reified A : Attribute<T>> Attributes.any(predicate: (value: T) -> Boolean): Boolean = + content.any { (mapKey, mapValue) -> mapKey is A && predicate(mapValue as T) } + +/** + * Check if there is an attribute of given type (subtypes included) + */ +public inline fun <T, reified A : Attribute<T>> Attributes.any(): Boolean = + content.any { (mapKey, _) -> mapKey is A } + +/** + * Check if [Attributes] contains a flag. Multiple keys that are instances of a flag could be present + */ +public inline fun <reified A : FlagAttribute> Attributes.has(): Boolean = + content.keys.any { it is A } + +/** + * Create [Attributes] with an added or replaced attribute key. + */ +public fun <T : Any, A : Attribute<T>> Attributes.withAttribute( attribute: A, - attrValue: T?, -): Attributes = Attributes( - if (attrValue == null) { - content - attribute - } else { - content + (attribute to attrValue) - } -) + attrValue: T, +): Attributes = Attributes(content + (attribute to attrValue)) + +public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attributes = + withAttribute(attribute, Unit) + +/** + * Create new [Attributes] by removing [attribute] key + */ +public fun Attributes.withoutAttribute(attribute: Attribute<*>): Attributes = Attributes(content.minus(attribute)) /** * Add an element to a [SetAttribute] @@ -63,6 +90,9 @@ public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement( ) } +/** + * Create [Attributes] with a single key + */ public fun <T : Any, A : Attribute<T>> Attributes( attribute: A, attrValue: T, diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt new file mode 100644 index 000000000..44ead89cb --- /dev/null +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt @@ -0,0 +1,26 @@ +/* + * Copyright 2018-2023 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.attributes + +import kotlin.reflect.KClass +import kotlin.reflect.KType +import kotlin.reflect.typeOf + +/** + * Safe variant ok Kotlin [KType] that ensures that the type parameter is of the same type ask [kType] + * + * @param kType raw [KType] + */ +public class SafeType<T> @PublishedApi internal constructor(public val kType: KType) + +public inline fun <reified T> safeTypeOf(): SafeType<T> = SafeType(typeOf<T>()) + +/** + * Derive Kotlin [KClass] from this type and fail if the type is not a class (should not happen) + */ +@Suppress("UNCHECKED_CAST") +@UnstableAttributesAPI +public val <T> SafeType<T>.kClass: KClass<T & Any> get() = kType.classifier as KClass<T & Any> \ No newline at end of file diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/annotations.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/annotations.kt new file mode 100644 index 000000000..80d93daaf --- /dev/null +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/annotations.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2018-2023 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.attributes + +/** + * Marks declarations that are still experimental in the Attributes-kt APIs, which means that the design of the corresponding + * declarations has open issues that may (or may not) lead to their changes in the future. Roughly speaking, there is + * a chance of those declarations will be deprecated in the future or the semantics of their behavior may change + * in some way that may break some code. + */ +@MustBeDocumented +@Retention(value = AnnotationRetention.BINARY) +@RequiresOptIn("This API is unstable and could change in future", RequiresOptIn.Level.WARNING) +public annotation class UnstableAttributesAPI \ No newline at end of file diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index 38eebeecc..53c47a814 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -1,4 +1,4 @@ -enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") +rootProject.name = "buildSrc" dependencyResolutionManagement { val projectProperties = java.util.Properties() @@ -13,6 +13,7 @@ dependencyResolutionManagement { val toolsVersion: String = projectProperties["toolsVersion"].toString() + @Suppress("UnstableApiUsage") repositories { mavenLocal() maven("https://repo.kotlin.link") diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt index d973ebae4..22e86c2a2 100644 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt +++ b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt @@ -56,6 +56,8 @@ public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra}, */ override val elementAlgebra: $kmathAlgebra get() = $kmathAlgebra + override val elementType: KType get() = typeOf<$type>() + @Suppress("UNCHECKED_CAST") override fun Matrix<${type}>.toEjml(): Ejml${type}Matrix<${ejmlMatrixType}> = when { this is Ejml${type}Matrix<*> && origin is $ejmlMatrixType -> this as Ejml${type}Matrix<${ejmlMatrixType}> diff --git a/gradle.properties b/gradle.properties index 162720167..2f1a2a030 100644 --- a/gradle.properties +++ b/gradle.properties @@ -11,5 +11,4 @@ toolsVersion=0.14.9-kotlin-1.8.20 org.gradle.parallel=true org.gradle.workers.max=4 org.gradle.configureondemand=true -org.gradle.jvmargs=-Xmx4096m - +org.gradle.jvmargs=-Xmx4096m \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fae08049a..15de90249 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index e369effdf..85ff881ef 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -8,12 +8,14 @@ package space.kscience.kmath.commons.linear import org.apache.commons.math3.linear.* import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* -import space.kscience.kmath.nd.StructureFeature +import space.kscience.kmath.nd.StructureAttribute import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.DoubleBuffer import kotlin.reflect.KClass +import kotlin.reflect.KType import kotlin.reflect.cast +import kotlin.reflect.typeOf public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> { override val rowNum: Int get() = origin.rowDimension @@ -38,6 +40,8 @@ public fun RealVector.toPoint(): CMVector = CMVector(this) public object CMLinearSpace : LinearSpace<Double, DoubleField> { override val elementAlgebra: DoubleField get() = DoubleField + override val elementType: KType = typeOf<Double>() + override fun buildMatrix( rows: Int, columns: Int, @@ -99,7 +103,7 @@ public object CMLinearSpace : LinearSpace<Double, DoubleField> { v * this @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { + override fun <F : StructureAttribute> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { //Return the feature if it is intrinsic to the structure structure.getFeature(type)?.let { return it } @@ -108,36 +112,37 @@ public object CMLinearSpace : LinearSpace<Double, DoubleField> { return when (type) { IsDiagonal::class -> if (origin is DiagonalMatrix) IsDiagonal else null - DeterminantFeature::class, LupDecompositionFeature::class -> object : - DeterminantFeature<Double>, - LupDecompositionFeature<Double> { + Determinant::class, LupDecompositionAttribute::class -> object : + Determinant<Double>, + LupDecompositionAttribute<Double> { private val lup by lazy { LUDecomposition(origin) } override val determinant: Double by lazy { lup.determinant } - override val l: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(lup.l).withFeature(LFeature) } - override val u: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(lup.u).withFeature(UFeature) } + override val l: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(lup.l).withAttribute(LowerTriangular) } + override val u: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(lup.u).withAttribute(UpperTriangular) } override val p: Matrix<Double> by lazy { CMMatrix(lup.p) } } - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> { + CholeskyDecompositionAttribute::class -> object : CholeskyDecompositionAttribute<Double> { override val l: Matrix<Double> by lazy<Matrix<Double>> { val cholesky = CholeskyDecomposition(origin) - CMMatrix(cholesky.l).withFeature(LFeature) + CMMatrix(cholesky.l).withAttribute(LowerTriangular) } } - QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> { + QRDecompositionAttribute::class -> object : QRDecompositionAttribute<Double> { private val qr by lazy { QRDecomposition(origin) } - override val q: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(qr.q).withFeature(OrthogonalFeature) } - override val r: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(qr.r).withFeature(UFeature) } + override val q: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(qr.q).withAttribute(OrthogonalAttribute) } + override val r: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(qr.r).withAttribute(UpperTriangular) } } - SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> { + SingularValueDecompositionAttribute::class -> object : SingularValueDecompositionAttribute<Double> { private val sv by lazy { SingularValueDecomposition(origin) } override val u: Matrix<Double> by lazy { CMMatrix(sv.u) } override val s: Matrix<Double> by lazy { CMMatrix(sv.s) } override val v: Matrix<Double> by lazy { CMMatrix(sv.v) } override val singularValues: Point<Double> by lazy { DoubleBuffer(sv.singularValues) } } + else -> null }?.let(type::cast) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt index 8c7cb0cf1..28546ab98 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt @@ -13,6 +13,8 @@ import space.kscience.kmath.structures.MutableBufferFactory import space.kscience.kmath.structures.asBuffer import kotlin.math.max import kotlin.math.min +import kotlin.reflect.KType +import kotlin.reflect.typeOf /** * Class representing both the value and the differentials of a function. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt index 4bba47a91..6bfe7581b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt @@ -5,12 +5,15 @@ package space.kscience.kmath.linear +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.VirtualBuffer import space.kscience.kmath.structures.indices +import kotlin.reflect.KType +import kotlin.reflect.typeOf public class BufferedLinearSpace<T, out A : Ring<T>>( diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt index 940af4a86..226ededce 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt @@ -12,6 +12,8 @@ import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.DoubleBuffer +import kotlin.reflect.KType +import kotlin.reflect.typeOf public object DoubleLinearSpace : LinearSpace<Double, DoubleField> { @@ -20,7 +22,7 @@ public object DoubleLinearSpace : LinearSpace<Double, DoubleField> { override fun buildMatrix( rows: Int, columns: Int, - initializer: DoubleField.(i: Int, j: Int) -> Double + initializer: DoubleField.(i: Int, j: Int) -> Double, ): Matrix<Double> = DoubleFieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) -> DoubleField.initializer(i, j) }.as2D() diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index a82bafe57..b83316e84 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -5,16 +5,15 @@ package space.kscience.kmath.linear +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.nd.MutableStructure2D -import space.kscience.kmath.nd.Structure2D -import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.nd.as1D +import space.kscience.kmath.nd.* import space.kscience.kmath.operations.BufferRingOps import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer -import kotlin.reflect.KClass +import kotlin.reflect.KType +import kotlin.reflect.typeOf /** * Alias for [Structure2D] with more familiar name. @@ -31,13 +30,19 @@ public typealias MutableMatrix<T> = MutableStructure2D<T> */ public typealias Point<T> = Buffer<T> +/** + * A marker interface for algebras that operate on matrices + * @param T type of matrix element + */ +public interface MatrixOperations<T> + /** * Basic operations on matrices and vectors. * * @param T the type of items in the matrices. * @param A the type of ring over [T]. */ -public interface LinearSpace<T, out A : Ring<T>> { +public interface LinearSpace<T, out A : Ring<T>> : MatrixOperations<T> { public val elementAlgebra: A /** @@ -167,16 +172,16 @@ public interface LinearSpace<T, out A : Ring<T>> { public operator fun T.times(v: Point<T>): Point<T> = v * this /** - * Compute a feature of the structure in this scope. Structure features take precedence other context features. + * Get an attribute value for the structure in this scope. Structure features take precedence other context features. * - * @param F the type of feature. + * @param A the type of feature. * @param structure the structure. - * @param type the [KClass] instance of [F]. + * @param attribute to be computed * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI - public fun <F : StructureFeature> computeFeature(structure: Matrix<T>, type: KClass<out F>): F? = - structure.getFeature(type) + public fun <T, A : StructureAttribute<T>> attributeFor(structure: StructureND<*>, attribute: A): T? = + structure.attributes[attribute] public companion object { @@ -184,23 +189,12 @@ public interface LinearSpace<T, out A : Ring<T>> { * A structured matrix with custom buffer */ public fun <T : Any, A : Ring<T>> buffered( - algebra: A + algebra: A, ): LinearSpace<T, A> = BufferedLinearSpace(BufferRingOps(algebra)) } } -/** - * Get a feature of the structure in this scope. Structure features take precedence other context features. - * - * @param T the type of items in the matrices. - * @param F the type of feature. - * @return a feature object or `null` if it isn't present. - */ -@UnstableKMathAPI -public inline fun <T : Any, reified F : StructureFeature> LinearSpace<T, *>.computeFeature(structure: Matrix<T>): F? = - computeFeature(structure, F::class) - public inline operator fun <LS : LinearSpace<*, *>, R> LS.invoke(block: LS.() -> R): R = run(block) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 650e7be5c..c44564231 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -3,67 +3,92 @@ * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ +@file:Suppress("UnusedReceiverParameter") + package space.kscience.kmath.linear +import space.kscience.attributes.PolymorphicAttribute +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* -import space.kscience.kmath.structures.BufferAccessor2D -import space.kscience.kmath.structures.DoubleBuffer -import space.kscience.kmath.structures.MutableBuffer -import space.kscience.kmath.structures.MutableBufferFactory +import space.kscience.kmath.structures.* /** - * Common implementation of [LupDecompositionFeature]. + * Matrices with this feature support LU factorization with partial pivoting: *[p] · a = [l] · [u]* where + * *a* is the owning matrix. + * + * @param T the type of matrices' items. + * @param l The lower triangular matrix in this decomposition. It may have [LowerTriangular]. + * @param u The upper triangular matrix in this decomposition. It may have [UpperTriangular]. + * @param p he permutation matrix in this decomposition. May have [Determinant] attribute */ -public class LupDecomposition<T : Any>( - public val context: LinearSpace<T, *>, - public val elementContext: Field<T>, - public val lu: Matrix<T>, - public val pivot: IntArray, - private val even: Boolean, -) : LupDecompositionFeature<T>, DeterminantFeature<T> { - /** - * Returns the matrix L of the decomposition. - * - * L is a lower-triangular matrix with [Ring.one] in diagonal - */ - override val l: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> - when { - j < i -> lu[i, j] - j == i -> elementContext.one - else -> elementContext.zero - } - }.withFeature(LFeature) +public data class LupDecomposition<T>( + public val l: Matrix<T>, + public val u: Matrix<T>, + public val p: Matrix<T>, +) - /** - * Returns the matrix U of the decomposition. - * - * U is an upper-triangular matrix including the diagonal - */ - override val u: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> - if (j >= i) lu[i, j] else elementContext.zero - }.withFeature(UFeature) +public class LupDecompositionAttribute<T>(type: SafeType<LupDecomposition<T>>) : + PolymorphicAttribute<LupDecomposition<T>>(type), + MatrixAttribute<LupDecomposition<T>> - /** - * Returns the P rows permutation matrix. - * - * P is a sparse matrix with exactly one element set to [Ring.one] in - * each row and each column, all other elements being set to [Ring.zero]. - */ - override val p: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> - if (j == pivot[i]) elementContext.one else elementContext.zero - } +public val <T> MatrixOperations<T>.LUP: LupDecompositionAttribute<T> + get() = LupDecompositionAttribute(safeTypeOf()) - /** - * Return the determinant of the matrix - * @return determinant of the matrix - */ - override val determinant: T by lazy { - elementContext { (0 until lu.shape[0]).fold(if (even) one else -one) { value, i -> value * lu[i, i] } } - } -} +///** +// * Common implementation of [LupDecomposition]. +// */ +//private class LupDecompositionImpl<T : Any>( +// public val elementContext: Field<T>, +// public val lu: Matrix<T>, +// public val pivot: IntBuffer, +// private val even: Boolean, +//) : LupDecomposition<T> { +// /** +// * Returns the matrix L of the decomposition. +// * +// * L is a lower-triangular matrix with [Ring.one] in diagonal +// */ +// override val l: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> +// when { +// j < i -> lu[i, j] +// j == i -> elementContext.one +// else -> elementContext.zero +// } +// }.withFeature(LowerTriangular) +// +// +// /** +// * Returns the matrix U of the decomposition. +// * +// * U is an upper-triangular matrix including the diagonal +// */ +// override val u: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> +// if (j >= i) lu[i, j] else elementContext.zero +// }.withFeature(UpperTriangular) +// +// /** +// * Returns the P rows permutation matrix. +// * +// * P is a sparse matrix with exactly one element set to [Ring.one] in +// * each row and each column, all other elements being set to [Ring.zero]. +// */ +// override val p: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> +// if (j == pivot[i]) elementContext.one else elementContext.zero +// } +// +// /** +// * Return the determinant of the matrix +// * @return determinant of the matrix +// */ +// override val determinant: T by lazy { +// elementContext { (0 until lu.shape[0]).fold(if(even) one else -one) { value, i -> value * lu[i, i] } } +// } +// +//} @PublishedApi internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T = @@ -73,7 +98,6 @@ internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T = * Create a lup decomposition of generic matrix. */ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( - factory: MutableBufferFactory<T>, matrix: Matrix<T>, checkSingular: (T) -> Boolean, ): LupDecomposition<T> { @@ -82,15 +106,15 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( val pivot = IntArray(matrix.rowNum) //TODO just waits for multi-receivers - BufferAccessor2D(matrix.rowNum, matrix.colNum, factory).run { + BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory).run { elementAlgebra { val lu = create(matrix) - // Initialize permutation array and parity + // Initialize the permutation array and parity for (row in 0 until m) pivot[row] = row var even = true - // Initialize permutation array and parity + // Initialize the permutation array and parity for (row in 0 until m) pivot[row] = row // Loop over columns @@ -145,46 +169,57 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( for (row in col + 1 until m) lu[row, col] /= luDiag } - return LupDecomposition(this@lup, elementAlgebra, lu.collect(), pivot, even) + val l: MatrixWrapper<T> = VirtualMatrix(rowNum, colNum) { i, j -> + when { + j < i -> lu[i, j] + j == i -> one + else -> zero + } + }.withAttribute(LowerTriangular) + + val u = VirtualMatrix(rowNum, colNum) { i, j -> + if (j >= i) lu[i, j] else zero + }.withAttribute(UpperTriangular) + + val p = VirtualMatrix(rowNum, colNum) { i, j -> + if (j == pivot[i]) one else zero + }.withAttribute(Determinant, if (even) one else -one) + + return LupDecomposition(l, u, p) } } } -public inline fun <reified T : Comparable<T>> LinearSpace<T, Field<T>>.lup( - matrix: Matrix<T>, - noinline checkSingular: (T) -> Boolean, -): LupDecomposition<T> = lup(MutableBuffer.Companion::auto, matrix, checkSingular) public fun LinearSpace<Double, DoubleField>.lup( matrix: Matrix<Double>, singularityThreshold: Double = 1e-11, -): LupDecomposition<Double> = - lup(::DoubleBuffer, matrix) { it < singularityThreshold } +): LupDecomposition<Double> = lup(matrix) { it < singularityThreshold } -internal fun <T : Any> LupDecomposition<T>.solve( - factory: MutableBufferFactory<T>, +internal fun <T : Any, A : Field<T>> LinearSpace<T, A>.solve( + lup: LupDecomposition<T>, matrix: Matrix<T>, ): Matrix<T> { - require(matrix.rowNum == pivot.size) { "Matrix dimension mismatch. Expected ${pivot.size}, but got ${matrix.colNum}" } + require(matrix.rowNum == lup.l.rowNum) { "Matrix dimension mismatch. Expected ${lup.l.rowNum}, but got ${matrix.colNum}" } - BufferAccessor2D(matrix.rowNum, matrix.colNum, factory).run { - elementContext { + BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory).run { + elementAlgebra { // Apply permutations to b val bp = create { _, _ -> zero } - for (row in pivot.indices) { + for (row in 0 until rowNum) { val bpRow = bp.row(row) val pRow = pivot[row] for (col in 0 until matrix.colNum) bpRow[col] = matrix[pRow, col] } // Solve LY = b - for (col in pivot.indices) { + for (col in 0 until colNum) { val bpCol = bp.row(col) - for (i in col + 1 until pivot.size) { + for (i in col + 1 until colNum) { val bpI = bp.row(i) - val luICol = lu[i, col] + val luICol = lup.l[i, col] for (j in 0 until matrix.colNum) { bpI[j] -= bpCol[j] * luICol } @@ -192,19 +227,19 @@ internal fun <T : Any> LupDecomposition<T>.solve( } // Solve UX = Y - for (col in pivot.size - 1 downTo 0) { + for (col in colNum - 1 downTo 0) { val bpCol = bp.row(col) - val luDiag = lu[col, col] + val luDiag = lup.u[col, col] for (j in 0 until matrix.colNum) bpCol[j] /= luDiag for (i in 0 until col) { val bpI = bp.row(i) - val luICol = lu[i, col] + val luICol = lup.u[i, col] for (j in 0 until matrix.colNum) bpI[j] -= bpCol[j] * luICol } } - return context.buildMatrix(pivot.size, matrix.colNum) { i, j -> bp[i, j] } + return buildMatrix(matrix.rowNum, matrix.colNum) { i, j -> bp[i, j] } } } } @@ -214,17 +249,16 @@ internal fun <T : Any> LupDecomposition<T>.solve( */ @OptIn(UnstableKMathAPI::class) public fun <T : Comparable<T>, F : Field<T>> LinearSpace<T, F>.lupSolver( - bufferFactory: MutableBufferFactory<T>, singularityCheck: (T) -> Boolean, ): LinearSolver<T> = object : LinearSolver<T> { override fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T> { // Use existing decomposition if it is provided by matrix - val decomposition = computeFeature(a) ?: lup(bufferFactory, a, singularityCheck) - return decomposition.solve(bufferFactory, b) + val decomposition = attributeFor(a, LUP) ?: lup(a, singularityCheck) + return solve(decomposition, b) } override fun inverse(matrix: Matrix<T>): Matrix<T> = solve(matrix, one(matrix.rowNum, matrix.colNum)) } public fun LinearSpace<Double, DoubleField>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> = - lupSolver(::DoubleBuffer) { it < singularityThreshold } + lupSolver { it < singularityThreshold } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt index 4d2f01e68..7b6c36dfc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.linear +import space.kscience.attributes.FlagAttribute import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Ring import space.kscience.kmath.structures.BufferAccessor2D @@ -49,10 +50,10 @@ public inline fun <T : Any> LinearSpace<T, Ring<T>>.column( public fun <T : Any> LinearSpace<T, Ring<T>>.column(vararg values: T): Matrix<T> = column(values.size, values::get) -public object SymmetricMatrixFeature : MatrixFeature +public object Symmetric : MatrixAttribute<Unit>, FlagAttribute /** - * Naive implementation of a symmetric matrix builder, that adds a [SymmetricMatrixFeature] tag. The resulting matrix contains + * Naive implementation of a symmetric matrix builder, that adds a [Symmetric] tag. The resulting matrix contains * full `size^2` number of elements, but caches elements during calls to save [builder] calls. [builder] is always called in the * upper triangle region meaning that `i <= j` */ @@ -72,6 +73,6 @@ public fun <T : Any, A : Ring<T>> MatrixBuilder<T, A>.symmetric( } else { cached } - }.withFeature(SymmetricMatrixFeature) + }.withAttribute(Symmetric) } } \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt index 62325b39d..b494625c7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt @@ -3,20 +3,27 @@ * 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(UnstableKMathAPI::class) +@file:Suppress("UnusedReceiverParameter") + package space.kscience.kmath.linear -import space.kscience.attributes.Attribute +import space.kscience.attributes.* +import space.kscience.kmath.UnstableKMathAPI +import space.kscience.kmath.nd.StructureAttribute +import kotlin.reflect.KType +import kotlin.reflect.typeOf /** * A marker interface representing some properties of matrices or additional transformations of them. Features are used * to optimize matrix operations performance in some cases or retrieve the APIs. */ -public interface MatrixFeature<T> : Attribute<T> +public interface MatrixAttribute<T> : StructureAttribute<T> /** * Matrices with this feature are considered to have only diagonal non-zero elements. */ -public interface IsDiagonal : MatrixFeature<Unit> { +public interface IsDiagonal : MatrixAttribute<Unit>, FlagAttribute { public companion object : IsDiagonal } @@ -31,130 +38,110 @@ public object IsZero : IsDiagonal public object IsUnit : IsDiagonal /** - * Matrices with this feature can be inverted: *[inverse] = a<sup>−1</sup>* where *a* is the owning matrix. + * Matrices with this feature can be inverted. * * @param T the type of matrices' items. */ -public class Inverted<T> private constructor() : MatrixFeature<Matrix<T>> { - internal val instance: Inverted<Nothing> = Inverted() -} +public class Inverted<T>(type: SafeType<Matrix<T>>) : + PolymorphicAttribute<Matrix<T>>(type), + MatrixAttribute<Matrix<T>> -@Suppress("UNCHECKED_CAST") -public val <T> LinearSpace<T, *>.Inverted: Inverted<T> get() = Inverted.instance as Inverted<T> +public val <T> MatrixOperations<T>.Inverted: Inverted<T> get() = Inverted(safeTypeOf()) /** * Matrices with this feature can compute their determinant. * * @param T the type of matrices' items. */ -public class DeterminantFeature<T : Any> : MatrixFeature<T> +public class Determinant<T>(type: SafeType<T>) : + PolymorphicAttribute<T>(type), + MatrixAttribute<T> -/** - * Produces a [DeterminantFeature] where the [DeterminantFeature.determinant] is [determinant]. - * - * @param determinant the value of determinant. - * @return a new [DeterminantFeature]. - */ -@Suppress("FunctionName") -public fun <T : Any> DeterminantFeature(determinant: T): DeterminantFeature<T> = object : DeterminantFeature<T> { - override val determinant: T = determinant -} +public inline val <reified T> MatrixOperations<T>.Determinant: Determinant<T> get() = Determinant(safeTypeOf()) /** * Matrices with this feature are lower triangular ones. */ -public object LFeature : MatrixFeature<Unit> +public object LowerTriangular : MatrixAttribute<Unit>, FlagAttribute /** * Matrices with this feature are upper triangular ones. */ -public object UFeature : MatrixFeature<Unit> +public object UpperTriangular : MatrixAttribute<Unit>, FlagAttribute + +/** + * Matrices with this feature support LU factorization: *a = [l] · [u]* where *a* is the owning matrix. + * @param l The lower triangular matrix in this decomposition. It may have [LowerTriangular]. + * @param u The upper triangular matrix in this decomposition. It may have [UpperTriangular]. + */ +public data class LUDecomposition<T>(val l: Matrix<T>, val u: Matrix<T>) /** * Matrices with this feature support LU factorization: *a = [l] · [u]* where *a* is the owning matrix. * * @param T the type of matrices' items. */ -public interface LUDecompositionFeature<out T : Any> : MatrixFeature { - /** - * The lower triangular matrix in this decomposition. It may have [LFeature]. - */ - public val l: Matrix<T> +public class LuDecompositionAttribute<T>(type: SafeType<LUDecomposition<T>>) : + PolymorphicAttribute<LUDecomposition<T>>(type), + MatrixAttribute<LUDecomposition<T>> - /** - * The upper triangular matrix in this decomposition. It may have [UFeature]. - */ - public val u: Matrix<T> -} +public val <T> MatrixOperations<T>.LU: LuDecompositionAttribute<T> get() = LuDecompositionAttribute(safeTypeOf()) -/** - * Matrices with this feature support LU factorization with partial pivoting: *[p] · a = [l] · [u]* where - * *a* is the owning matrix. - * - * @param T the type of matrices' items. - */ -public interface LupDecompositionFeature<out T : Any> : MatrixFeature { - /** - * The lower triangular matrix in this decomposition. It may have [LFeature]. - */ - public val l: Matrix<T> - - /** - * The upper triangular matrix in this decomposition. It may have [UFeature]. - */ - public val u: Matrix<T> - - /** - * The permutation matrix in this decomposition. - */ - public val p: Matrix<T> -} /** * Matrices with this feature are orthogonal ones: *a · a<sup>T</sup> = u* where *a* is the owning matrix, *u* * is the unit matrix ([IsUnit]). */ -public object OrthogonalFeature : MatrixFeature +public object OrthogonalAttribute : MatrixAttribute<Unit>, FlagAttribute -/** - * Matrices with this feature support QR factorization: *a = [q] · [r]* where *a* is the owning matrix. - * - * @param T the type of matrices' items. - */ -public interface QRDecompositionFeature<out T : Any> : MatrixFeature { + +public interface QRDecomposition<out T> { /** - * The orthogonal matrix in this decomposition. It may have [OrthogonalFeature]. + * The orthogonal matrix in this decomposition. It may have [OrthogonalAttribute]. */ public val q: Matrix<T> /** - * The upper triangular matrix in this decomposition. It may have [UFeature]. + * The upper triangular matrix in this decomposition. It may have [UpperTriangular]. */ public val r: Matrix<T> } +/** + * Matrices with this feature support QR factorization: *a = [QR.q] · [QR.r]* where *a* is the owning matrix. + * + * @param T the type of matrices' items. + */ +public class QRDecompositionAttribute<T>(type: SafeType<QRDecomposition<T>>) : + PolymorphicAttribute<QRDecomposition<T>>(type), + MatrixAttribute<QRDecomposition<T>> + +public val <T> MatrixOperations<T>.QR: QRDecompositionAttribute<T> + get() = QRDecompositionAttribute(safeTypeOf()) + +public interface CholeskyDecomposition<T> { + /** + * The triangular matrix in this decomposition. It may have either [UpperTriangular] or [LowerTriangular]. + */ + public val l: Matrix<T> +} + /** * Matrices with this feature support Cholesky factorization: *a = [l] · [l]<sup>H</sup>* where *a* is the * owning matrix. * * @param T the type of matrices' items. */ -public interface CholeskyDecompositionFeature<out T : Any> : MatrixFeature { - /** - * The triangular matrix in this decomposition. It may have either [UFeature] or [LFeature]. - */ - public val l: Matrix<T> -} +public class CholeskyDecompositionAttribute<T>(type: SafeType<CholeskyDecomposition<T>>) : + PolymorphicAttribute<CholeskyDecomposition<T>>(type), + MatrixAttribute<CholeskyDecomposition<T>> -/** - * Matrices with this feature support SVD: *a = [u] · [s] · [v]<sup>H</sup>* where *a* is the owning - * matrix. - * - * @param T the type of matrices' items. - */ -public interface SingularValueDecompositionFeature<out T : Any> : MatrixFeature { +public val <T> MatrixOperations<T>.Cholesky: CholeskyDecompositionAttribute<T> + get() = CholeskyDecompositionAttribute(safeTypeOf()) + +public interface SingularValueDecomposition<T> { /** - * The matrix in this decomposition. It is unitary, and it consists from left singular vectors. + * The matrix in this decomposition. It is unitary, and it consists of left singular vectors. */ public val u: Matrix<T> @@ -164,14 +151,27 @@ public interface SingularValueDecompositionFeature<out T : Any> : MatrixFeature public val s: Matrix<T> /** - * The matrix in this decomposition. It is unitary, and it consists from right singular vectors. + * The matrix in this decomposition. It is unitary, and it consists of right singular vectors. */ public val v: Matrix<T> /** - * The buffer of singular values of this SVD. + * The buffer of singular values for this SVD. */ public val singularValues: Point<T> } +/** + * Matrices with this feature support SVD: *a = [u] · [s] · [v]<sup>H</sup>* where *a* is the owning + * matrix. + * + * @param T the type of matrices' items. + */ +public class SingularValueDecompositionAttribute<T>(type: SafeType<SingularValueDecomposition<T>>) : + PolymorphicAttribute<SingularValueDecomposition<T>>(type), + MatrixAttribute<SingularValueDecomposition<T>> + +public val <T> MatrixOperations<T>.SVD: SingularValueDecompositionAttribute<T> + get() = SingularValueDecompositionAttribute(safeTypeOf()) + //TODO add sparse matrix feature diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index b510cc697..0f0c9ce3f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -5,19 +5,20 @@ package space.kscience.kmath.linear +import space.kscience.attributes.Attribute import space.kscience.attributes.Attributes +import space.kscience.attributes.withAttribute import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.misc.FeatureSet import space.kscience.kmath.operations.Ring /** - * A [Matrix] that holds [MatrixFeature] objects. + * A [Matrix] that holds [MatrixAttribute] objects. * * @param T the type of items. */ public class MatrixWrapper<out T : Any> internal constructor( public val origin: Matrix<T>, - public val attributes: Attributes, + override val attributes: Attributes, ) : Matrix<T> by origin { override fun toString(): String = "MatrixWrapper(matrix=$origin, features=$attributes)" @@ -34,23 +35,31 @@ public val <T : Any> Matrix<T>.origin: Matrix<T> /** * Add a single feature to a [Matrix] */ -public fun <T : Any> Matrix<T>.withFeature(newFeature: MatrixFeature): MatrixWrapper<T> = if (this is MatrixWrapper) { - MatrixWrapper(origin, attributes.with(newFeature)) +public fun <T : Any, A : Attribute<T>> Matrix<T>.withAttribute( + attribute: A, + attrValue: T, +): MatrixWrapper<T> = if (this is MatrixWrapper) { + MatrixWrapper(origin, attributes.withAttribute(attribute,attrValue)) } else { - MatrixWrapper(this, FeatureSet.of(newFeature)) + MatrixWrapper(this, Attributes(attribute, attrValue)) } -@Deprecated("To be replaced by withFeature") -public operator fun <T : Any> Matrix<T>.plus(newFeature: MatrixFeature): MatrixWrapper<T> = withFeature(newFeature) +public fun <T : Any, A : Attribute<Unit>> Matrix<T>.withAttribute( + attribute: A, +): MatrixWrapper<T> = if (this is MatrixWrapper) { + MatrixWrapper(origin, attributes.withAttribute(attribute)) +} else { + MatrixWrapper(this, Attributes(attribute, Unit)) +} /** - * Add a collection of features to a [Matrix] + * Modify matrix attributes */ -public fun <T : Any> Matrix<T>.withFeatures(newFeatures: Iterable<MatrixFeature>): MatrixWrapper<T> = +public fun <T : Any> Matrix<T>.modifyAttributes(modifier: (Attributes) -> Attributes): MatrixWrapper<T> = if (this is MatrixWrapper) { - MatrixWrapper(origin, attributes.with(newFeatures)) + MatrixWrapper(origin, modifier(attributes)) } else { - MatrixWrapper(this, FeatureSet.of(newFeatures)) + MatrixWrapper(this, modifier(Attributes.EMPTY)) } /** @@ -59,9 +68,9 @@ public fun <T : Any> Matrix<T>.withFeatures(newFeatures: Iterable<MatrixFeature> public fun <T : Any> LinearSpace<T, Ring<T>>.one( rows: Int, columns: Int, -): Matrix<T> = VirtualMatrix(rows, columns) { i, j -> +): MatrixWrapper<T> = VirtualMatrix(rows, columns) { i, j -> if (i == j) elementAlgebra.one else elementAlgebra.zero -}.withFeature(IsUnit) +}.withAttribute(IsUnit) /** @@ -70,16 +79,16 @@ public fun <T : Any> LinearSpace<T, Ring<T>>.one( public fun <T : Any> LinearSpace<T, Ring<T>>.zero( rows: Int, columns: Int, -): Matrix<T> = VirtualMatrix(rows, columns) { _, _ -> +): MatrixWrapper<T> = VirtualMatrix(rows, columns) { _, _ -> elementAlgebra.zero -}.withFeature(IsZero) +}.withAttribute(IsZero) -public class TransposedFeature<out T : Any>(public val original: Matrix<T>) : MatrixFeature +public class TransposedAttribute<out T : Any>(public val original: Matrix<T>) : MatrixAttribute /** * Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A` */ @Suppress("UNCHECKED_CAST") @OptIn(UnstableKMathAPI::class) -public fun <T : Any> Matrix<T>.transpose(): Matrix<T> = getFeature(TransposedFeature::class)?.original as? Matrix<T> - ?: VirtualMatrix(colNum, rowNum) { i, j -> get(j, i) }.withFeature(TransposedFeature(this)) +public fun <T : Any> Matrix<T>.transpose(): Matrix<T> = getFeature(TransposedAttribute::class)?.original as? Matrix<T> + ?: VirtualMatrix(colNum, rowNum) { i, j -> get(j, i) }.withAttribute(TransposedAttribute(this)) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt index 55b970f4a..7927e4dba 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.linear +import space.kscience.attributes.Attributes import space.kscience.kmath.nd.ShapeND @@ -16,6 +17,7 @@ import space.kscience.kmath.nd.ShapeND public class VirtualMatrix<out T : Any>( override val rowNum: Int, override val colNum: Int, + override val attributes: Attributes = Attributes.EMPTY, public val generator: (i: Int, j: Int) -> T, ) : Matrix<T> { @@ -24,5 +26,8 @@ public class VirtualMatrix<out T : Any>( override operator fun get(i: Int, j: Int): T = generator(i, j) } -public fun <T : Any> MatrixBuilder<T, *>.virtual(generator: (i: Int, j: Int) -> T): VirtualMatrix<T> = - VirtualMatrix(rows, columns, generator) +public fun <T : Any> MatrixBuilder<T, *>.virtual( + attributes: Attributes = Attributes.EMPTY, + generator: (i: Int, j: Int) -> T, +): VirtualMatrix<T> = + VirtualMatrix(rows, columns, attributes, generator) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt index a75807bad..3a9a1833a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt @@ -79,7 +79,7 @@ public interface AlgebraND<T, out C : Algebra<T>> : Algebra<StructureND<T>> { * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI - public fun <F : StructureFeature> getFeature(structure: StructureND<T>, type: KClass<out F>): F? = + public fun <F : StructureAttribute> getFeature(structure: StructureND<T>, type: KClass<out F>): F? = structure.getFeature(type) public companion object @@ -93,7 +93,7 @@ public interface AlgebraND<T, out C : Algebra<T>> : Algebra<StructureND<T>> { * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI -public inline fun <T : Any, reified F : StructureFeature> AlgebraND<T, *>.getFeature(structure: StructureND<T>): F? = +public inline fun <T : Any, reified F : StructureAttribute> AlgebraND<T, *>.getFeature(structure: StructureND<T>): F? = getFeature(structure, F::class) /** diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt index 9217f6fdc..72ecc9ef0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt @@ -34,9 +34,9 @@ public open class BufferND<out T>( /** * Create a generic [BufferND] using provided [initializer] */ -public fun <T> BufferND( +public inline fun <reified T> BufferND( shape: ShapeND, - bufferFactory: BufferFactory<T> = BufferFactory.boxing(), + bufferFactory: BufferFactory<T> = BufferFactory.auto(), initializer: (IntArray) -> T, ): BufferND<T> { val strides = Strides(shape) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index e006d09eb..931730399 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -110,7 +110,7 @@ private value class Structure2DWrapper<out T>(val structure: StructureND<T>) : S @PerformancePitfall override operator fun get(i: Int, j: Int): T = structure[i, j] - override fun <F : StructureFeature> getFeature(type: KClass<out F>): F? = structure.getFeature(type) + override fun <F : StructureAttribute> getFeature(type: KClass<out F>): F? = structure.getFeature(type) @PerformancePitfall override fun elements(): Sequence<Pair<IntArray, T>> = structure.elements() diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index e9814acbf..724cc6f69 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.nd import space.kscience.attributes.Attribute import space.kscience.attributes.AttributeContainer +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.operations.Ring @@ -15,9 +16,8 @@ import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory import kotlin.jvm.JvmName import kotlin.math.abs -import kotlin.reflect.KClass -public interface StructureFeature<T> : Attribute<T> +public interface StructureAttribute<T> : Attribute<T> /** * Represents n-dimensional structure i.e., multidimensional container of items of the same type and size. The number @@ -122,9 +122,14 @@ public interface StructureND<out T> : AttributeContainer, WithShape { */ public fun <T> buffered( strides: Strides, - bufferFactory: BufferFactory<T> = BufferFactory.boxing(), initializer: (IntArray) -> T, - ): BufferND<T> = BufferND(strides, bufferFactory(strides.linearSize) { i -> initializer(strides.index(i)) }) + ): BufferND<T> = BufferND(strides, Buffer.boxing(strides.linearSize) { i -> initializer(strides.index(i)) }) + + + public fun <T> buffered( + shape: ShapeND, + initializer: (IntArray) -> T, + ): BufferND<T> = buffered(ColumnStrides(shape), initializer) /** * Inline create NDStructure with non-boxing buffer implementation if it is possible @@ -135,16 +140,11 @@ public interface StructureND<out T> : AttributeContainer, WithShape { ): BufferND<T> = BufferND(strides, Buffer.auto(strides.linearSize) { i -> initializer(strides.index(i)) }) public inline fun <T : Any> auto( - type: KClass<T>, + type: SafeType<T>, strides: Strides, crossinline initializer: (IntArray) -> T, ): BufferND<T> = BufferND(strides, Buffer.auto(type, strides.linearSize) { i -> initializer(strides.index(i)) }) - public fun <T> buffered( - shape: ShapeND, - bufferFactory: BufferFactory<T> = BufferFactory.boxing(), - initializer: (IntArray) -> T, - ): BufferND<T> = buffered(ColumnStrides(shape), bufferFactory, initializer) public inline fun <reified T : Any> auto( shape: ShapeND, @@ -159,7 +159,7 @@ public interface StructureND<out T> : AttributeContainer, WithShape { auto(ColumnStrides(ShapeND(shape)), initializer) public inline fun <T : Any> auto( - type: KClass<T>, + type: SafeType<T>, vararg shape: Int, crossinline initializer: (IntArray) -> T, ): BufferND<T> = auto(type, ColumnStrides(ShapeND(shape)), initializer) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt index 0960ab023..e590dcc3d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt @@ -9,14 +9,14 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.operations.Ring.Companion.optimizedPower import space.kscience.kmath.structures.MutableBufferFactory +import kotlin.reflect.KType /** * Represents an algebraic structure. * - * @param T the type of element of this structure. + * @param T the type of element which Algebra operates on. */ public interface Algebra<T> { - /** * Provide a factory for buffers, associated with this [Algebra] */ @@ -67,12 +67,12 @@ public interface Algebra<T> { * * @param operation the name of operation. * @param arg the argument of operation. - * @return a result of operation. + * @return the result of the operation. */ public fun unaryOperation(operation: String, arg: T): T = unaryOperationFunction(operation)(arg) /** - * Dynamically dispatches a binary operation with the certain name. + * Dynamically dispatches a binary operation with a certain name. * * Implementations must fulfil the following requirements: * @@ -87,7 +87,7 @@ public interface Algebra<T> { error("Binary operation '$operation' not defined in $this") /** - * Dynamically invokes a binary operation with the certain name. + * Dynamically invokes a binary operation with a certain name. * * Implementations must fulfil the following requirements: * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index 26a4b0a53..9047feb29 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -8,6 +8,7 @@ package space.kscience.kmath.operations import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.MutableBufferFactory +import kotlin.reflect.KType public interface WithSize { public val size: Int @@ -18,6 +19,9 @@ public interface WithSize { */ public interface BufferAlgebra<T, out A : Algebra<T>> : Algebra<Buffer<T>> { public val elementAlgebra: A + + public val elementType: KType + public val elementBufferFactory: MutableBufferFactory<T> get() = elementAlgebra.bufferFactory public fun buffer(size: Int, vararg elements: T): Buffer<T> { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index cef8d1d4d..d9ee25321 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -5,10 +5,12 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.operations.WithSize import space.kscience.kmath.operations.asSequence import kotlin.jvm.JvmInline -import kotlin.reflect.KClass +import kotlin.reflect.typeOf /** * Function that produces [Buffer] from its size and function that supplies values. @@ -99,13 +101,13 @@ public interface Buffer<out T> : WithSize { * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @Suppress("UNCHECKED_CAST") - public inline fun <T : Any> auto(type: KClass<T>, size: Int, initializer: (Int) -> T): Buffer<T> = - when (type) { - Double::class -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T> - Short::class -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T> - Int::class -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> - Long::class -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> - Float::class -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> + public inline fun <T> auto(type: SafeType<T>, size: Int, initializer: (Int) -> T): Buffer<T> = + when (type.kType) { + typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T> + typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T> + typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> + typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> + typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> else -> boxing(size, initializer) } @@ -115,8 +117,8 @@ public interface Buffer<out T> : WithSize { * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ - public inline fun <reified T : Any> auto(size: Int, initializer: (Int) -> T): Buffer<T> = - auto(T::class, size, initializer) + public inline fun <reified T> auto(size: Int, initializer: (Int) -> T): Buffer<T> = + auto(safeTypeOf<T>(), size, initializer) } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt index 48f3e919b..3edd7d3b1 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt @@ -27,12 +27,9 @@ internal class BufferAccessor2D<T>( fun create(mat: Structure2D<T>): MutableBuffer<T> = create { i, j -> mat[i, j] } //TODO optimize wrapper - fun MutableBuffer<T>.collect(): Structure2D<T> = StructureND.buffered( - ColumnStrides(ShapeND(rowNum, colNum)), - factory - ) { (i, j) -> - get(i, j) - }.as2D() + fun MutableBuffer<T>.toStructure2D(): Structure2D<T> = StructureND.buffered( + ColumnStrides(ShapeND(rowNum, colNum)) + ) { (i, j) -> get(i, j) }.as2D() inner class Row(val buffer: MutableBuffer<T>, val rowIndex: Int) : MutableBuffer<T> { override val size: Int get() = colNum diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt index c0bfc6ecc..48b05e412 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt @@ -5,7 +5,9 @@ package space.kscience.kmath.structures -import kotlin.reflect.KClass +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf +import kotlin.reflect.typeOf /** * A generic mutable random-access structure for both primitives and objects. @@ -74,13 +76,13 @@ public interface MutableBuffer<T> : Buffer<T> { * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @Suppress("UNCHECKED_CAST") - public inline fun <T : Any> auto(type: KClass<out T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> = - when (type) { - Double::class -> double(size) { initializer(it) as Double } as MutableBuffer<T> - Short::class -> short(size) { initializer(it) as Short } as MutableBuffer<T> - Int::class -> int(size) { initializer(it) as Int } as MutableBuffer<T> - Float::class -> float(size) { initializer(it) as Float } as MutableBuffer<T> - Long::class -> long(size) { initializer(it) as Long } as MutableBuffer<T> + public inline fun <T> auto(type: SafeType<T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> = + when (type.kType) { + typeOf<Double>() -> double(size) { initializer(it) as Double } as MutableBuffer<T> + typeOf<Short>() -> short(size) { initializer(it) as Short } as MutableBuffer<T> + typeOf<Int>() -> int(size) { initializer(it) as Int } as MutableBuffer<T> + typeOf<Float>() -> float(size) { initializer(it) as Float } as MutableBuffer<T> + typeOf<Long>() -> long(size) { initializer(it) as Long } as MutableBuffer<T> else -> boxing(size, initializer) } @@ -90,11 +92,10 @@ public interface MutableBuffer<T> : Buffer<T> { * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ - @Suppress("UNCHECKED_CAST") - public inline fun <reified T : Any> auto(size: Int, initializer: (Int) -> T): MutableBuffer<T> = - auto(T::class, size, initializer) + public inline fun <reified T> auto(size: Int, initializer: (Int) -> T): MutableBuffer<T> = + auto(safeTypeOf<T>(), size, initializer) } } -public sealed interface PrimitiveBuffer<T>: MutableBuffer<T> \ No newline at end of file +public sealed interface PrimitiveBuffer<T> : MutableBuffer<T> \ No newline at end of file diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt index 8925fb045..ec1883128 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt @@ -12,6 +12,8 @@ import space.kscience.kmath.linear.Matrix import space.kscience.kmath.linear.Point import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.operations.Ring +import kotlin.reflect.KType +import kotlin.reflect.typeOf /** * [LinearSpace] implementation specialized for a certain EJML type. @@ -43,5 +45,5 @@ public abstract class EjmlLinearSpace<T : Any, out A : Ring<T>, out M : org.ejml @Suppress("UNCHECKED_CAST") @UnstableKMathAPI public fun EjmlMatrix<T, *>.inverse(): Structure2D<Double> = - computeFeature(this, InverseMatrixFeature::class)?.inverse as Structure2D<Double> + attributeFor(this, InverseMatrixFeature::class)?.inverse as Structure2D<Double> } diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt deleted file mode 100644 index c56583fa8..000000000 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ /dev/null @@ -1,1003 +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 file. - */ - -/* This file is generated with buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt */ - -package space.kscience.kmath.ejml - -import org.ejml.data.* -import org.ejml.dense.row.CommonOps_DDRM -import org.ejml.dense.row.CommonOps_FDRM -import org.ejml.dense.row.factory.DecompositionFactory_DDRM -import org.ejml.dense.row.factory.DecompositionFactory_FDRM -import org.ejml.sparse.FillReducing -import org.ejml.sparse.csc.CommonOps_DSCC -import org.ejml.sparse.csc.CommonOps_FSCC -import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC -import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC -import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC -import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC -import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.linear.* -import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.FloatField -import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.DoubleBuffer -import space.kscience.kmath.structures.FloatBuffer -import kotlin.reflect.KClass -import kotlin.reflect.cast - -/** - * [EjmlVector] specialization for [Double]. - */ -public class EjmlDoubleVector<out M : DMatrix>(override val origin: M) : EjmlVector<Double, M>(origin) { - init { - require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } - } - - override operator fun get(index: Int): Double = origin[0, index] -} - -/** - * [EjmlVector] specialization for [Float]. - */ -public class EjmlFloatVector<out M : FMatrix>(override val origin: M) : EjmlVector<Float, M>(origin) { - init { - require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } - } - - override operator fun get(index: Int): Float = origin[0, index] -} - -/** - * [EjmlMatrix] specialization for [Double]. - */ -public class EjmlDoubleMatrix<out M : DMatrix>(override val origin: M) : EjmlMatrix<Double, M>(origin) { - override operator fun get(i: Int, j: Int): Double = origin[i, j] -} - -/** - * [EjmlMatrix] specialization for [Float]. - */ -public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatrix<Float, M>(origin) { - override operator fun get(i: Int, j: Int): Float = origin[i, j] -} - -/** - * [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and - * [DMatrixRMaj] matrices. - */ -public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrixRMaj>() { - /** - * The [DoubleField] reference. - */ - override val elementAlgebra: DoubleField get() = DoubleField - - @Suppress("UNCHECKED_CAST") - override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when { - this is EjmlDoubleMatrix<*> && origin is DMatrixRMaj -> this as EjmlDoubleMatrix<DMatrixRMaj> - else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } - } - - @Suppress("UNCHECKED_CAST") - override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixRMaj> = when { - this is EjmlDoubleVector<*> && origin is DMatrixRMaj -> this as EjmlDoubleVector<DMatrixRMaj> - else -> EjmlDoubleVector(DMatrixRMaj(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } - }) - } - - override fun buildMatrix( - rows: Int, - columns: Int, - initializer: DoubleField.(i: Int, j: Int) -> Double, - ): EjmlDoubleMatrix<DMatrixRMaj> = DMatrixRMaj(rows, columns).also { - (0 until rows).forEach { row -> - (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } - } - }.wrapMatrix() - - override fun buildVector( - size: Int, - initializer: DoubleField.(Int) -> Double, - ): EjmlDoubleVector<DMatrixRMaj> = EjmlDoubleVector(DMatrixRMaj(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } - }) - - private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this) - private fun <T : DMatrix> T.wrapVector() = EjmlDoubleVector(this) - - override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * elementAlgebra { -one } - - override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { - val out = DMatrixRMaj(1, 1) - CommonOps_DDRM.mult(toEjml().origin, other.toEjml().origin, out) - return out.wrapMatrix() - } - - override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixRMaj> { - val out = DMatrixRMaj(1, 1) - CommonOps_DDRM.mult(toEjml().origin, vector.toEjml().origin, out) - return out.wrapVector() - } - - override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { - val out = DMatrixRMaj(1, 1) - - CommonOps_DDRM.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out, - ) - - return out.wrapMatrix() - } - - override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixRMaj> { - val res = DMatrixRMaj(1, 1) - CommonOps_DDRM.scale(value, toEjml().origin, res) - return res.wrapMatrix() - } - - override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixRMaj> { - val res = DMatrixRMaj(1, 1) - CommonOps_DDRM.changeSign(toEjml().origin, res) - return res.wrapVector() - } - - override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { - val out = DMatrixRMaj(1, 1) - - CommonOps_DDRM.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out, - ) - - return out.wrapMatrix() - } - - override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> { - val out = DMatrixRMaj(1, 1) - - CommonOps_DDRM.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out, - ) - - return out.wrapVector() - } - - override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> { - val out = DMatrixRMaj(1, 1) - - CommonOps_DDRM.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out, - ) - - return out.wrapVector() - } - - override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> = m * this - - override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixRMaj> { - val res = DMatrixRMaj(1, 1) - CommonOps_DDRM.scale(value, toEjml().origin, res) - return res.wrapVector() - } - - override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this - - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } - val origin = structure.toEjml().origin - - return when (type) { - InverseMatrixFeature::class -> object : InverseMatrixFeature<Double> { - override val inverse: Matrix<Double> by lazy { - val res = origin.copy() - CommonOps_DDRM.invert(res) - res.wrapMatrix() - } - } - - DeterminantFeature::class -> object : DeterminantFeature<Double> { - override val determinant: Double by lazy { CommonOps_DDRM.det(origin) } - } - - SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> { - private val svd by lazy { - DecompositionFactory_DDRM.svd(origin.numRows, origin.numCols, true, true, false) - .apply { decompose(origin.copy()) } - } - - override val u: Matrix<Double> by lazy { svd.getU(null, false).wrapMatrix() } - override val s: Matrix<Double> by lazy { svd.getW(null).wrapMatrix() } - override val v: Matrix<Double> by lazy { svd.getV(null, false).wrapMatrix() } - override val singularValues: Point<Double> by lazy { DoubleBuffer(svd.singularValues) } - } - - QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> { - private val qr by lazy { - DecompositionFactory_DDRM.qr().apply { decompose(origin.copy()) } - } - - override val q: Matrix<Double> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<Double> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } - } - - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> { - override val l: Matrix<Double> by lazy { - val cholesky = - DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) } - - cholesky.getT(null).wrapMatrix().withFeature(LFeature) - } - } - - LupDecompositionFeature::class -> object : LupDecompositionFeature<Double> { - private val lup by lazy { - DecompositionFactory_DDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) } - } - - override val l: Matrix<Double> by lazy { - lup.getLower(null).wrapMatrix().withFeature(LFeature) - } - - override val u: Matrix<Double> by lazy { - lup.getUpper(null).wrapMatrix().withFeature(UFeature) - } - - override val p: Matrix<Double> by lazy { lup.getRowPivot(null).wrapMatrix() } - } - - else -> null - }?.let{ - type.cast(it) - } - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p matrix. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<Double>, b: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { - val res = DMatrixRMaj(1, 1) - CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res) - return res.wrapMatrix() - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p vector. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<Double>, b: Point<Double>): EjmlDoubleVector<DMatrixRMaj> { - val res = DMatrixRMaj(1, 1) - CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res) - return EjmlDoubleVector(res) - } -} - -/** - * [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and - * [FMatrixRMaj] matrices. - */ -public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRMaj>() { - /** - * The [FloatField] reference. - */ - override val elementAlgebra: FloatField get() = FloatField - - @Suppress("UNCHECKED_CAST") - override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixRMaj> = when { - this is EjmlFloatMatrix<*> && origin is FMatrixRMaj -> this as EjmlFloatMatrix<FMatrixRMaj> - else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } - } - - @Suppress("UNCHECKED_CAST") - override fun Point<Float>.toEjml(): EjmlFloatVector<FMatrixRMaj> = when { - this is EjmlFloatVector<*> && origin is FMatrixRMaj -> this as EjmlFloatVector<FMatrixRMaj> - else -> EjmlFloatVector(FMatrixRMaj(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } - }) - } - - override fun buildMatrix( - rows: Int, - columns: Int, - initializer: FloatField.(i: Int, j: Int) -> Float, - ): EjmlFloatMatrix<FMatrixRMaj> = FMatrixRMaj(rows, columns).also { - (0 until rows).forEach { row -> - (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } - } - }.wrapMatrix() - - override fun buildVector( - size: Int, - initializer: FloatField.(Int) -> Float, - ): EjmlFloatVector<FMatrixRMaj> = EjmlFloatVector(FMatrixRMaj(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } - }) - - private fun <T : FMatrix> T.wrapMatrix() = EjmlFloatMatrix(this) - private fun <T : FMatrix> T.wrapVector() = EjmlFloatVector(this) - - override fun Matrix<Float>.unaryMinus(): Matrix<Float> = this * elementAlgebra { -one } - - override fun Matrix<Float>.dot(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { - val out = FMatrixRMaj(1, 1) - CommonOps_FDRM.mult(toEjml().origin, other.toEjml().origin, out) - return out.wrapMatrix() - } - - override fun Matrix<Float>.dot(vector: Point<Float>): EjmlFloatVector<FMatrixRMaj> { - val out = FMatrixRMaj(1, 1) - CommonOps_FDRM.mult(toEjml().origin, vector.toEjml().origin, out) - return out.wrapVector() - } - - override operator fun Matrix<Float>.minus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { - val out = FMatrixRMaj(1, 1) - - CommonOps_FDRM.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out, - ) - - return out.wrapMatrix() - } - - override operator fun Matrix<Float>.times(value: Float): EjmlFloatMatrix<FMatrixRMaj> { - val res = FMatrixRMaj(1, 1) - CommonOps_FDRM.scale(value, toEjml().origin, res) - return res.wrapMatrix() - } - - override fun Point<Float>.unaryMinus(): EjmlFloatVector<FMatrixRMaj> { - val res = FMatrixRMaj(1, 1) - CommonOps_FDRM.changeSign(toEjml().origin, res) - return res.wrapVector() - } - - override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { - val out = FMatrixRMaj(1, 1) - - CommonOps_FDRM.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out, - ) - - return out.wrapMatrix() - } - - override fun Point<Float>.plus(other: Point<Float>): EjmlFloatVector<FMatrixRMaj> { - val out = FMatrixRMaj(1, 1) - - CommonOps_FDRM.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out, - ) - - return out.wrapVector() - } - - override fun Point<Float>.minus(other: Point<Float>): EjmlFloatVector<FMatrixRMaj> { - val out = FMatrixRMaj(1, 1) - - CommonOps_FDRM.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out, - ) - - return out.wrapVector() - } - - override fun Float.times(m: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> = m * this - - override fun Point<Float>.times(value: Float): EjmlFloatVector<FMatrixRMaj> { - val res = FMatrixRMaj(1, 1) - CommonOps_FDRM.scale(value, toEjml().origin, res) - return res.wrapVector() - } - - override fun Float.times(v: Point<Float>): EjmlFloatVector<FMatrixRMaj> = v * this - - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Float>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } - val origin = structure.toEjml().origin - - return when (type) { - InverseMatrixFeature::class -> object : InverseMatrixFeature<Float> { - override val inverse: Matrix<Float> by lazy { - val res = origin.copy() - CommonOps_FDRM.invert(res) - res.wrapMatrix() - } - } - - DeterminantFeature::class -> object : DeterminantFeature<Float> { - override val determinant: Float by lazy { CommonOps_FDRM.det(origin) } - } - - SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Float> { - private val svd by lazy { - DecompositionFactory_FDRM.svd(origin.numRows, origin.numCols, true, true, false) - .apply { decompose(origin.copy()) } - } - - override val u: Matrix<Float> by lazy { svd.getU(null, false).wrapMatrix() } - override val s: Matrix<Float> by lazy { svd.getW(null).wrapMatrix() } - override val v: Matrix<Float> by lazy { svd.getV(null, false).wrapMatrix() } - override val singularValues: Point<Float> by lazy { FloatBuffer(svd.singularValues) } - } - - QRDecompositionFeature::class -> object : QRDecompositionFeature<Float> { - private val qr by lazy { - DecompositionFactory_FDRM.qr().apply { decompose(origin.copy()) } - } - - override val q: Matrix<Float> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<Float> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } - } - - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Float> { - override val l: Matrix<Float> by lazy { - val cholesky = - DecompositionFactory_FDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) } - - cholesky.getT(null).wrapMatrix().withFeature(LFeature) - } - } - - LupDecompositionFeature::class -> object : LupDecompositionFeature<Float> { - private val lup by lazy { - DecompositionFactory_FDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) } - } - - override val l: Matrix<Float> by lazy { - lup.getLower(null).wrapMatrix().withFeature(LFeature) - } - - override val u: Matrix<Float> by lazy { - lup.getUpper(null).wrapMatrix().withFeature(UFeature) - } - - override val p: Matrix<Float> by lazy { lup.getRowPivot(null).wrapMatrix() } - } - - else -> null - }?.let{ - type.cast(it) - } - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p matrix. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<Float>, b: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { - val res = FMatrixRMaj(1, 1) - CommonOps_FDRM.solve(FMatrixRMaj(a.toEjml().origin), FMatrixRMaj(b.toEjml().origin), res) - return res.wrapMatrix() - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p vector. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<Float>, b: Point<Float>): EjmlFloatVector<FMatrixRMaj> { - val res = FMatrixRMaj(1, 1) - CommonOps_FDRM.solve(FMatrixRMaj(a.toEjml().origin), FMatrixRMaj(b.toEjml().origin), res) - return EjmlFloatVector(res) - } -} - -/** - * [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and - * [DMatrixSparseCSC] matrices. - */ -public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrixSparseCSC>() { - /** - * The [DoubleField] reference. - */ - override val elementAlgebra: DoubleField get() = DoubleField - - @Suppress("UNCHECKED_CAST") - override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when { - this is EjmlDoubleMatrix<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleMatrix<DMatrixSparseCSC> - else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } - } - - @Suppress("UNCHECKED_CAST") - override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixSparseCSC> = when { - this is EjmlDoubleVector<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleVector<DMatrixSparseCSC> - else -> EjmlDoubleVector(DMatrixSparseCSC(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } - }) - } - - override fun buildMatrix( - rows: Int, - columns: Int, - initializer: DoubleField.(i: Int, j: Int) -> Double, - ): EjmlDoubleMatrix<DMatrixSparseCSC> = DMatrixSparseCSC(rows, columns).also { - (0 until rows).forEach { row -> - (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } - } - }.wrapMatrix() - - override fun buildVector( - size: Int, - initializer: DoubleField.(Int) -> Double, - ): EjmlDoubleVector<DMatrixSparseCSC> = EjmlDoubleVector(DMatrixSparseCSC(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } - }) - - private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this) - private fun <T : DMatrix> T.wrapVector() = EjmlDoubleVector(this) - - override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * elementAlgebra { -one } - - override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { - val out = DMatrixSparseCSC(1, 1) - CommonOps_DSCC.mult(toEjml().origin, other.toEjml().origin, out) - return out.wrapMatrix() - } - - override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> { - val out = DMatrixSparseCSC(1, 1) - CommonOps_DSCC.mult(toEjml().origin, vector.toEjml().origin, out) - return out.wrapVector() - } - - override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { - val out = DMatrixSparseCSC(1, 1) - - CommonOps_DSCC.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out, - null, - null, - ) - - return out.wrapMatrix() - } - - override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixSparseCSC> { - val res = DMatrixSparseCSC(1, 1) - CommonOps_DSCC.scale(value, toEjml().origin, res) - return res.wrapMatrix() - } - - override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixSparseCSC> { - val res = DMatrixSparseCSC(1, 1) - CommonOps_DSCC.changeSign(toEjml().origin, res) - return res.wrapVector() - } - - override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { - val out = DMatrixSparseCSC(1, 1) - - CommonOps_DSCC.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out, - null, - null, - ) - - return out.wrapMatrix() - } - - override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> { - val out = DMatrixSparseCSC(1, 1) - - CommonOps_DSCC.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out, - null, - null, - ) - - return out.wrapVector() - } - - override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> { - val out = DMatrixSparseCSC(1, 1) - - CommonOps_DSCC.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out, - null, - null, - ) - - return out.wrapVector() - } - - override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> = m * this - - override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixSparseCSC> { - val res = DMatrixSparseCSC(1, 1) - CommonOps_DSCC.scale(value, toEjml().origin, res) - return res.wrapVector() - } - - override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> = v * this - - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } - val origin = structure.toEjml().origin - - return when (type) { - QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> { - private val qr by lazy { - DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } - } - - override val q: Matrix<Double> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<Double> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } - } - - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> { - override val l: Matrix<Double> by lazy { - val cholesky = - DecompositionFactory_DSCC.cholesky().apply { decompose(origin.copy()) } - - (cholesky.getT(null) as DMatrix).wrapMatrix().withFeature(LFeature) - } - } - - LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object : - LUDecompositionFeature<Double>, DeterminantFeature<Double>, InverseMatrixFeature<Double> { - private val lu by lazy { - DecompositionFactory_DSCC.lu(FillReducing.NONE).apply { decompose(origin.copy()) } - } - - override val l: Matrix<Double> by lazy { - lu.getLower(null).wrapMatrix().withFeature(LFeature) - } - - override val u: Matrix<Double> by lazy { - lu.getUpper(null).wrapMatrix().withFeature(UFeature) - } - - override val inverse: Matrix<Double> by lazy { - var a = origin - val inverse = DMatrixRMaj(1, 1) - val solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE) - if (solver.modifiesA()) a = a.copy() - val i = CommonOps_DDRM.identity(a.numRows) - solver.solve(i, inverse) - inverse.wrapMatrix() - } - - override val determinant: Double by lazy { elementAlgebra.number(lu.computeDeterminant().real) } - } - - else -> null - }?.let{ - type.cast(it) - } - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p matrix. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<Double>, b: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { - val res = DMatrixSparseCSC(1, 1) - CommonOps_DSCC.solve(DMatrixSparseCSC(a.toEjml().origin), DMatrixSparseCSC(b.toEjml().origin), res) - return res.wrapMatrix() - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p vector. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<Double>, b: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> { - val res = DMatrixSparseCSC(1, 1) - CommonOps_DSCC.solve(DMatrixSparseCSC(a.toEjml().origin), DMatrixSparseCSC(b.toEjml().origin), res) - return EjmlDoubleVector(res) - } -} - -/** - * [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and - * [FMatrixSparseCSC] matrices. - */ -public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSparseCSC>() { - /** - * The [FloatField] reference. - */ - override val elementAlgebra: FloatField get() = FloatField - - @Suppress("UNCHECKED_CAST") - override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixSparseCSC> = when { - this is EjmlFloatMatrix<*> && origin is FMatrixSparseCSC -> this as EjmlFloatMatrix<FMatrixSparseCSC> - else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } - } - - @Suppress("UNCHECKED_CAST") - override fun Point<Float>.toEjml(): EjmlFloatVector<FMatrixSparseCSC> = when { - this is EjmlFloatVector<*> && origin is FMatrixSparseCSC -> this as EjmlFloatVector<FMatrixSparseCSC> - else -> EjmlFloatVector(FMatrixSparseCSC(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } - }) - } - - override fun buildMatrix( - rows: Int, - columns: Int, - initializer: FloatField.(i: Int, j: Int) -> Float, - ): EjmlFloatMatrix<FMatrixSparseCSC> = FMatrixSparseCSC(rows, columns).also { - (0 until rows).forEach { row -> - (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } - } - }.wrapMatrix() - - override fun buildVector( - size: Int, - initializer: FloatField.(Int) -> Float, - ): EjmlFloatVector<FMatrixSparseCSC> = EjmlFloatVector(FMatrixSparseCSC(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } - }) - - private fun <T : FMatrix> T.wrapMatrix() = EjmlFloatMatrix(this) - private fun <T : FMatrix> T.wrapVector() = EjmlFloatVector(this) - - override fun Matrix<Float>.unaryMinus(): Matrix<Float> = this * elementAlgebra { -one } - - override fun Matrix<Float>.dot(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { - val out = FMatrixSparseCSC(1, 1) - CommonOps_FSCC.mult(toEjml().origin, other.toEjml().origin, out) - return out.wrapMatrix() - } - - override fun Matrix<Float>.dot(vector: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> { - val out = FMatrixSparseCSC(1, 1) - CommonOps_FSCC.mult(toEjml().origin, vector.toEjml().origin, out) - return out.wrapVector() - } - - override operator fun Matrix<Float>.minus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { - val out = FMatrixSparseCSC(1, 1) - - CommonOps_FSCC.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out, - null, - null, - ) - - return out.wrapMatrix() - } - - override operator fun Matrix<Float>.times(value: Float): EjmlFloatMatrix<FMatrixSparseCSC> { - val res = FMatrixSparseCSC(1, 1) - CommonOps_FSCC.scale(value, toEjml().origin, res) - return res.wrapMatrix() - } - - override fun Point<Float>.unaryMinus(): EjmlFloatVector<FMatrixSparseCSC> { - val res = FMatrixSparseCSC(1, 1) - CommonOps_FSCC.changeSign(toEjml().origin, res) - return res.wrapVector() - } - - override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { - val out = FMatrixSparseCSC(1, 1) - - CommonOps_FSCC.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out, - null, - null, - ) - - return out.wrapMatrix() - } - - override fun Point<Float>.plus(other: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> { - val out = FMatrixSparseCSC(1, 1) - - CommonOps_FSCC.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out, - null, - null, - ) - - return out.wrapVector() - } - - override fun Point<Float>.minus(other: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> { - val out = FMatrixSparseCSC(1, 1) - - CommonOps_FSCC.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out, - null, - null, - ) - - return out.wrapVector() - } - - override fun Float.times(m: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> = m * this - - override fun Point<Float>.times(value: Float): EjmlFloatVector<FMatrixSparseCSC> { - val res = FMatrixSparseCSC(1, 1) - CommonOps_FSCC.scale(value, toEjml().origin, res) - return res.wrapVector() - } - - override fun Float.times(v: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> = v * this - - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Float>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } - val origin = structure.toEjml().origin - - return when (type) { - QRDecompositionFeature::class -> object : QRDecompositionFeature<Float> { - private val qr by lazy { - DecompositionFactory_FSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } - } - - override val q: Matrix<Float> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<Float> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } - } - - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Float> { - override val l: Matrix<Float> by lazy { - val cholesky = - DecompositionFactory_FSCC.cholesky().apply { decompose(origin.copy()) } - - (cholesky.getT(null) as FMatrix).wrapMatrix().withFeature(LFeature) - } - } - - LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object : - LUDecompositionFeature<Float>, DeterminantFeature<Float>, InverseMatrixFeature<Float> { - private val lu by lazy { - DecompositionFactory_FSCC.lu(FillReducing.NONE).apply { decompose(origin.copy()) } - } - - override val l: Matrix<Float> by lazy { - lu.getLower(null).wrapMatrix().withFeature(LFeature) - } - - override val u: Matrix<Float> by lazy { - lu.getUpper(null).wrapMatrix().withFeature(UFeature) - } - - override val inverse: Matrix<Float> by lazy { - var a = origin - val inverse = FMatrixRMaj(1, 1) - val solver = LinearSolverFactory_FSCC.lu(FillReducing.NONE) - if (solver.modifiesA()) a = a.copy() - val i = CommonOps_FDRM.identity(a.numRows) - solver.solve(i, inverse) - inverse.wrapMatrix() - } - - override val determinant: Float by lazy { elementAlgebra.number(lu.computeDeterminant().real) } - } - - else -> null - }?.let{ - type.cast(it) - } - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p matrix. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<Float>, b: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { - val res = FMatrixSparseCSC(1, 1) - CommonOps_FSCC.solve(FMatrixSparseCSC(a.toEjml().origin), FMatrixSparseCSC(b.toEjml().origin), res) - return res.wrapMatrix() - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p vector. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<Float>, b: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> { - val res = FMatrixSparseCSC(1, 1) - CommonOps_FSCC.solve(FMatrixSparseCSC(a.toEjml().origin), FMatrixSparseCSC(b.toEjml().origin), res) - return EjmlFloatVector(res) - } -} - diff --git a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt index e89810e0d..04cc69708 100644 --- a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt +++ b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt @@ -61,9 +61,9 @@ internal class EjmlMatrixTest { fun features() { val m = randomMatrix val w = EjmlDoubleMatrix(m) - val det: DeterminantFeature<Double> = EjmlLinearSpaceDDRM.computeFeature(w) ?: fail() + val det: Determinant<Double> = EjmlLinearSpaceDDRM.attributeFor(w) ?: fail() assertEquals(CommonOps_DDRM.det(m), det.determinant) - val lup: LupDecompositionFeature<Double> = EjmlLinearSpaceDDRM.computeFeature(w) ?: fail() + val lup: LupDecompositionAttribute<Double> = EjmlLinearSpaceDDRM.attributeFor(w) ?: fail() val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows, m.numCols) .also { it.decompose(m.copy()) } diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt index 411a35188..08dc75789 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt @@ -16,7 +16,6 @@ import kotlin.math.pow public typealias DoubleVector = Point<Double> -@Suppress("FunctionName") public fun DoubleVector(vararg doubles: Double): DoubleVector = doubles.asBuffer() /** diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt index af84f47f2..b8a11c472 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt @@ -7,11 +7,14 @@ package space.kscience.kmath.functions +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.ScaleOperations import space.kscience.kmath.operations.invoke import kotlin.math.max import kotlin.math.min +import kotlin.reflect.KType +import kotlin.reflect.typeOf /** @@ -48,7 +51,7 @@ public data class Polynomial<out C>( * * @usesMathJax */ - public val coefficients: List<C> + public val coefficients: List<C>, ) { override fun toString(): String = "Polynomial$coefficients" } @@ -62,16 +65,17 @@ public data class Polynomial<out C>( * @param ring underlying ring of constants of type [A]. */ public open class PolynomialSpace<C, A>( - /** - * Underlying ring of constants. Its operations on constants are used by local operations on constants and polynomials. - */ public val ring: A, ) : Ring<Polynomial<C>>, ScaleOperations<Polynomial<C>> where A : Ring<C>, A : ScaleOperations<C> { + @UnstableKMathAPI + override val elementType: KType get() = typeOf<Polynomial<C>>() + /** * Instance of zero constant (zero of the underlying ring). */ public val constantZero: C get() = ring.zero + /** * Instance of unit constant (unit of the underlying ring). */ @@ -95,6 +99,7 @@ public open class PolynomialSpace<C, A>( ) } } + /** * Returns difference between the constant represented as a polynomial and the polynomial. */ @@ -115,6 +120,7 @@ public open class PolynomialSpace<C, A>( ) } } + /** * Returns product of the constant represented as a polynomial and the polynomial. */ @@ -147,6 +153,7 @@ public open class PolynomialSpace<C, A>( ) } } + /** * Returns difference between the constant represented as a polynomial and the polynomial. */ @@ -165,6 +172,7 @@ public open class PolynomialSpace<C, A>( ) } } + /** * Returns product of the constant represented as a polynomial and the polynomial. */ @@ -183,6 +191,7 @@ public open class PolynomialSpace<C, A>( * Converts the constant [value] to polynomial. */ public fun number(value: C): Polynomial<C> = Polynomial(listOf(value)) + /** * Converts the constant to polynomial. */ @@ -194,6 +203,7 @@ public open class PolynomialSpace<C, A>( public override operator fun Polynomial<C>.unaryMinus(): Polynomial<C> = ring { Polynomial(coefficients.map { -it }) } + /** * Returns sum of the polynomials. */ @@ -210,6 +220,7 @@ public open class PolynomialSpace<C, A>( } ) } + /** * Returns difference of the polynomials. */ @@ -226,6 +237,7 @@ public open class PolynomialSpace<C, A>( } ) } + /** * Returns product of the polynomials. */ @@ -245,6 +257,7 @@ public open class PolynomialSpace<C, A>( * Instance of zero polynomial (zero of the polynomial ring). */ override val zero: Polynomial<C> = Polynomial(emptyList()) + /** * Instance of unit polynomial (unit of the polynomial ring). */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt index ae814254b..4cd1b89af 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt @@ -5,13 +5,12 @@ package space.kscience.kmath.distributions +import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.chains.Chain import space.kscience.kmath.operations.DoubleField.pow import space.kscience.kmath.random.RandomGenerator -import space.kscience.kmath.samplers.GaussianSampler +import space.kscience.kmath.samplers.* import space.kscience.kmath.samplers.InternalErf -import space.kscience.kmath.samplers.NormalizedGaussianSampler -import space.kscience.kmath.samplers.ZigguratNormalizedGaussianSampler import kotlin.math.* /** @@ -24,7 +23,7 @@ public class NormalDistribution(public val sampler: GaussianSampler) : Distribut return exp(-0.5 * x1 * x1 - (ln(sampler.standardDeviation) + 0.5 * ln(2 * PI))) } - override fun sample(generator: RandomGenerator): Chain<Double> = sampler.sample(generator) + override fun sample(generator: RandomGenerator): BlockingDoubleChain = sampler.sample(generator) override fun cumulative(arg: Double): Double { val dev = arg - sampler.mean From 4abe25c1888cb2ac5ddc1588cfa1d6e048a3855a Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 18 Jul 2023 10:13:36 +0300 Subject: [PATCH 040/103] [WIP] Features to Attributes refactoring --- CHANGELOG.md | 1 + .../space/kscience/attributes/SafeType.kt | 4 ++- .../kmath/structures/typeSafeDimensions.kt | 2 +- .../kmath/commons/optimization/CMOptimizer.kt | 2 +- .../kscience/kmath/linear/LinearSpace.kt | 3 +-- .../kscience/kmath/linear/LupDecomposition.kt | 15 ++++++----- .../kscience/kmath/linear/MatrixFeatures.kt | 9 +++---- .../kscience/kmath/linear/MatrixWrapper.kt | 10 -------- .../space/kscience/kmath/linear/Transposed.kt | 25 +++++++++++++++++++ .../kscience/kmath/linear/VirtualMatrix.kt | 3 +-- .../space/kscience/kmath/nd/AlgebraND.kt | 20 +++------------ .../space/kscience/kmath/nd/BufferND.kt | 4 +-- .../space/kscience/kmath/nd/Structure2D.kt | 4 ++- .../space/kscience/kmath/nd/StructureND.kt | 4 ++- .../kmath/operations/BufferAlgebra.kt | 2 -- .../space/kscience/kmath/structures/Buffer.kt | 2 +- .../kscience/kmath/dimensions/Wrappers.kt | 4 +-- .../kscience/dimensions/DMatrixContextTest.kt | 2 +- kmath-functions/build.gradle.kts | 2 -- .../kscience/kmath/functions/Polynomial.kt | 3 --- .../optimization/FunctionOptimization.kt | 25 +++++++++++++------ .../kmath/optimization/OptimizationProblem.kt | 16 +++--------- .../kscience/kmath/optimization/XYFit.kt | 4 +-- .../kmath/optimization/logLikelihood.kt | 4 +-- 24 files changed, 84 insertions(+), 86 deletions(-) create mode 100644 kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index bbfb68501..e1ff7fbe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Changed - Features replaced with Attributes. +- Transposed refactored. ### Deprecated diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt index 44ead89cb..7225d1a6b 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt @@ -5,6 +5,7 @@ package space.kscience.attributes +import kotlin.jvm.JvmInline import kotlin.reflect.KClass import kotlin.reflect.KType import kotlin.reflect.typeOf @@ -14,7 +15,8 @@ import kotlin.reflect.typeOf * * @param kType raw [KType] */ -public class SafeType<T> @PublishedApi internal constructor(public val kType: KType) +@JvmInline +public value class SafeType<T> @PublishedApi internal constructor(public val kType: KType) public inline fun <reified T> safeTypeOf(): SafeType<T> = SafeType(typeOf<T>()) diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt index 1ba0e3503..45677dcb5 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt @@ -15,7 +15,7 @@ private fun DMatrixContext<Double, *>.simple() { val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() } //Dimension-safe addition - m1.transpose() + m2 + m1.transposed() + m2 } private object D5 : Dimension { diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt index c4dafb6a6..6e0000721 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt @@ -125,7 +125,7 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> { val logger = problem.getFeature<OptimizationLog>() - for (feature in problem.features) { + for (feature in problem.attributes) { when (feature) { is CMOptimizerData -> feature.data.forEach { dataBuilder -> addOptimizationData(dataBuilder()) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index b83316e84..0780be29a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -174,9 +174,8 @@ public interface LinearSpace<T, out A : Ring<T>> : MatrixOperations<T> { /** * Get an attribute value for the structure in this scope. Structure features take precedence other context features. * - * @param A the type of feature. * @param structure the structure. - * @param attribute to be computed + * @param attribute to be computed. * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index c44564231..468248c21 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -21,12 +21,11 @@ import space.kscience.kmath.structures.* * @param T the type of matrices' items. * @param l The lower triangular matrix in this decomposition. It may have [LowerTriangular]. * @param u The upper triangular matrix in this decomposition. It may have [UpperTriangular]. - * @param p he permutation matrix in this decomposition. May have [Determinant] attribute */ public data class LupDecomposition<T>( public val l: Matrix<T>, public val u: Matrix<T>, - public val p: Matrix<T>, + public val pivot: IntBuffer, ) @@ -180,12 +179,12 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( val u = VirtualMatrix(rowNum, colNum) { i, j -> if (j >= i) lu[i, j] else zero }.withAttribute(UpperTriangular) +// +// val p = VirtualMatrix(rowNum, colNum) { i, j -> +// if (j == pivot[i]) one else zero +// }.withAttribute(Determinant, if (even) one else -one) - val p = VirtualMatrix(rowNum, colNum) { i, j -> - if (j == pivot[i]) one else zero - }.withAttribute(Determinant, if (even) one else -one) - - return LupDecomposition(l, u, p) + return LupDecomposition(l, u, pivot.asBuffer()) } } } @@ -209,7 +208,7 @@ internal fun <T : Any, A : Field<T>> LinearSpace<T, A>.solve( for (row in 0 until rowNum) { val bpRow = bp.row(row) - val pRow = pivot[row] + val pRow = lup.pivot[row] for (col in 0 until matrix.colNum) bpRow[col] = matrix[pRow, col] } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt index b494625c7..d109ef1bc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt @@ -11,8 +11,6 @@ package space.kscience.kmath.linear import space.kscience.attributes.* import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureAttribute -import kotlin.reflect.KType -import kotlin.reflect.typeOf /** * A marker interface representing some properties of matrices or additional transformations of them. Features are used @@ -53,11 +51,9 @@ public val <T> MatrixOperations<T>.Inverted: Inverted<T> get() = Inverted(safeTy * * @param T the type of matrices' items. */ -public class Determinant<T>(type: SafeType<T>) : - PolymorphicAttribute<T>(type), - MatrixAttribute<T> +public class Determinant<T> : MatrixAttribute<T> -public inline val <reified T> MatrixOperations<T>.Determinant: Determinant<T> get() = Determinant(safeTypeOf()) +public val <T> MatrixOperations<T>.Determinant: Determinant<T> get() = Determinant() /** * Matrices with this feature are lower triangular ones. @@ -174,4 +170,5 @@ public class SingularValueDecompositionAttribute<T>(type: SafeType<SingularValue public val <T> MatrixOperations<T>.SVD: SingularValueDecompositionAttribute<T> get() = SingularValueDecompositionAttribute(safeTypeOf()) + //TODO add sparse matrix feature diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index 0f0c9ce3f..a129b04f0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -82,13 +82,3 @@ public fun <T : Any> LinearSpace<T, Ring<T>>.zero( ): MatrixWrapper<T> = VirtualMatrix(rows, columns) { _, _ -> elementAlgebra.zero }.withAttribute(IsZero) - -public class TransposedAttribute<out T : Any>(public val original: Matrix<T>) : MatrixAttribute - -/** - * Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A` - */ -@Suppress("UNCHECKED_CAST") -@OptIn(UnstableKMathAPI::class) -public fun <T : Any> Matrix<T>.transpose(): Matrix<T> = getFeature(TransposedAttribute::class)?.original as? Matrix<T> - ?: VirtualMatrix(colNum, rowNum) { i, j -> get(j, i) }.withAttribute(TransposedAttribute(this)) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt new file mode 100644 index 000000000..3e93a2a23 --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2018-2023 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.linear + +import space.kscience.attributes.Attributes + + +public class TransposedMatrix<T>(public val origin: Matrix<T>) : Matrix<T> { + override val rowNum: Int get() = origin.colNum + override val colNum: Int get() = origin.rowNum + + override fun get(i: Int, j: Int): T = origin[j, i] + + override val attributes: Attributes get() = Attributes.EMPTY +} + + +/** + * Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A` + */ +public val <T> Matrix<T>.transposed: Matrix<T> + get() = (this as? TransposedMatrix<T>)?.origin ?: TransposedMatrix(this) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt index 7927e4dba..97de82c7a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt @@ -29,5 +29,4 @@ public class VirtualMatrix<out T : Any>( public fun <T : Any> MatrixBuilder<T, *>.virtual( attributes: Attributes = Attributes.EMPTY, generator: (i: Int, j: Int) -> T, -): VirtualMatrix<T> = - VirtualMatrix(rows, columns, attributes, generator) +): VirtualMatrix<T> = VirtualMatrix(rows, columns, attributes, generator) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt index 3a9a1833a..0611225c1 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt @@ -71,31 +71,19 @@ public interface AlgebraND<T, out C : Algebra<T>> : Algebra<StructureND<T>> { structure.map { value -> this@invoke(value) } /** - * Get a feature of the structure in this scope. Structure features take precedence other context features. + * Get an attribute value for the structure in this scope. Structure features take precedence other context features. * - * @param F the type of feature. * @param structure the structure. - * @param type the [KClass] instance of [F]. + * @param attribute to be computed. * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI - public fun <F : StructureAttribute> getFeature(structure: StructureND<T>, type: KClass<out F>): F? = - structure.getFeature(type) + public fun <T, A : StructureAttribute<T>> attributeFor(structure: StructureND<*>, attribute: A): T? = + structure.attributes[attribute] public companion object } -/** - * Get a feature of the structure in this scope. Structure features take precedence other context features. - * - * @param T the type of items in the matrices. - * @param F the type of feature. - * @return a feature object or `null` if it isn't present. - */ -@UnstableKMathAPI -public inline fun <T : Any, reified F : StructureAttribute> AlgebraND<T, *>.getFeature(structure: StructureND<T>): F? = - getFeature(structure, F::class) - /** * Space of [StructureND]. * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt index 72ecc9ef0..461a82e0a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt @@ -36,8 +36,8 @@ public open class BufferND<out T>( */ public inline fun <reified T> BufferND( shape: ShapeND, - bufferFactory: BufferFactory<T> = BufferFactory.auto(), - initializer: (IntArray) -> T, + bufferFactory: BufferFactory<T> = BufferFactory.auto<T>(), + crossinline initializer: (IntArray) -> T, ): BufferND<T> { val strides = Strides(shape) return BufferND(strides, bufferFactory(strides.linearSize) { initializer(strides.index(it)) }) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index 931730399..eff58acc3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.nd +import space.kscience.attributes.Attributes import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer @@ -110,7 +111,8 @@ private value class Structure2DWrapper<out T>(val structure: StructureND<T>) : S @PerformancePitfall override operator fun get(i: Int, j: Int): T = structure[i, j] - override fun <F : StructureAttribute> getFeature(type: KClass<out F>): F? = structure.getFeature(type) + override val attributes: Attributes + get() = structure.attributes @PerformancePitfall override fun elements(): Sequence<Pair<IntArray, T>> = structure.elements() diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index 724cc6f69..993349487 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -7,13 +7,13 @@ package space.kscience.kmath.nd import space.kscience.attributes.Attribute import space.kscience.attributes.AttributeContainer +import space.kscience.attributes.Attributes import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.BufferFactory import kotlin.jvm.JvmName import kotlin.math.abs @@ -57,6 +57,8 @@ public interface StructureND<out T> : AttributeContainer, WithShape { @PerformancePitfall public fun elements(): Sequence<Pair<IntArray, T>> = indices.asSequence().map { it to get(it) } + override val attributes: Attributes get() = Attributes.EMPTY + public companion object { /** * Indicates whether some [StructureND] is equal to another one. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index 9047feb29..be371a56b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -20,8 +20,6 @@ public interface WithSize { public interface BufferAlgebra<T, out A : Algebra<T>> : Algebra<Buffer<T>> { public val elementAlgebra: A - public val elementType: KType - public val elementBufferFactory: MutableBufferFactory<T> get() = elementAlgebra.bufferFactory public fun buffer(size: Int, vararg elements: T): Buffer<T> { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index d9ee25321..022886279 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -21,7 +21,7 @@ public fun interface BufferFactory<T> { public operator fun invoke(size: Int, builder: (Int) -> T): Buffer<T> public companion object{ - public inline fun <reified T : Any> auto(): BufferFactory<T> = + public inline fun <reified T> auto(): BufferFactory<T> = BufferFactory(Buffer.Companion::auto) public fun <T> boxing(): BufferFactory<T> = diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt index dde2d4fcf..6ff90ba7c 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt @@ -146,8 +146,8 @@ public value class DMatrixContext<T : Any, out A : Ring<T>>(public val context: public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.unaryMinus(): DMatrix<T, C, R> = context.run { this@unaryMinus.unaryMinus() }.coerce() - public inline fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.transpose(): DMatrix<T, R, C> = - context.run { (this@transpose as Matrix<T>).transpose() }.coerce() + public inline fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.transposed(): DMatrix<T, R, C> = + context.run { (this@transposed as Matrix<T>).transposed }.coerce() public companion object { public val real: DMatrixContext<Double, DoubleField> = DMatrixContext(Double.algebra.linearSpace) diff --git a/kmath-dimensions/src/commonTest/kotlin/space/kscience/dimensions/DMatrixContextTest.kt b/kmath-dimensions/src/commonTest/kotlin/space/kscience/dimensions/DMatrixContextTest.kt index e2793855b..65c4cf80b 100644 --- a/kmath-dimensions/src/commonTest/kotlin/space/kscience/dimensions/DMatrixContextTest.kt +++ b/kmath-dimensions/src/commonTest/kotlin/space/kscience/dimensions/DMatrixContextTest.kt @@ -30,7 +30,7 @@ internal class DMatrixContextTest { val m2 = produce<D3, D2> { i, j -> (i + j).toDouble() } //Dimension-safe addition - m1.transpose() + m2 + m1.transposed() + m2 } } } diff --git a/kmath-functions/build.gradle.kts b/kmath-functions/build.gradle.kts index 4ec52f5ee..3c1fbb07c 100644 --- a/kmath-functions/build.gradle.kts +++ b/kmath-functions/build.gradle.kts @@ -9,8 +9,6 @@ kscience{ wasm() - - dependencies { api(projects.kmathCore) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt index b8a11c472..afd96aced 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt @@ -68,9 +68,6 @@ public open class PolynomialSpace<C, A>( public val ring: A, ) : Ring<Polynomial<C>>, ScaleOperations<Polynomial<C>> where A : Ring<C>, A : ScaleOperations<C> { - @UnstableKMathAPI - override val elementType: KType get() = typeOf<Polynomial<C>>() - /** * Instance of zero constant (zero of the underlying ring). */ diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt index 07146625c..fe5f0ca8a 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -5,21 +5,21 @@ package space.kscience.kmath.optimization +import space.kscience.attributes.* import space.kscience.kmath.expressions.DifferentiableExpression import space.kscience.kmath.expressions.Symbol -import space.kscience.kmath.misc.FeatureSet public class OptimizationValue<T>(public val value: T) : OptimizationFeature { override fun toString(): String = "Value($value)" } -public enum class FunctionOptimizationTarget : OptimizationFeature { +public enum class FunctionOptimizationTarget { MAXIMIZE, MINIMIZE } public class FunctionOptimization<T>( - override val features: FeatureSet<OptimizationFeature>, + override val attributes: Attributes, public val expression: DifferentiableExpression<T>, ) : OptimizationProblem<T> { @@ -30,25 +30,36 @@ public class FunctionOptimization<T>( other as FunctionOptimization<*> - if (features != other.features) return false + if (attributes != other.attributes) return false if (expression != other.expression) return false return true } override fun hashCode(): Int { - var result = features.hashCode() + var result = attributes.hashCode() result = 31 * result + expression.hashCode() return result } - override fun toString(): String = "FunctionOptimization(features=$features)" + override fun toString(): String = "FunctionOptimization(features=$attributes)" + + public companion object } + + +public class OptimizationPrior<T>(type: SafeType<T>): + PolymorphicAttribute<DifferentiableExpression<T>>(safeTypeOf()), + Attribute<DifferentiableExpression<T>> + +public val <T> FunctionOptimization.Companion.Optimization get() = + + public fun <T> FunctionOptimization<T>.withFeatures( vararg newFeature: OptimizationFeature, ): FunctionOptimization<T> = FunctionOptimization( - features.with(*newFeature), + attributes.with(*newFeature), expression, ) diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt index 9fdcfc53d..46ba8c1c0 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt @@ -5,21 +5,16 @@ package space.kscience.kmath.optimization +import space.kscience.attributes.* import space.kscience.kmath.expressions.DifferentiableExpression import space.kscience.kmath.expressions.NamedMatrix import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.misc.* import kotlin.reflect.KClass -public interface OptimizationFeature : Feature<OptimizationFeature> { - // enforce toString override - override fun toString(): String -} +public interface OptimizationAttribute<T>: Attribute<T> -public interface OptimizationProblem<T> : Featured<OptimizationFeature> { - public val features: FeatureSet<OptimizationFeature> - override fun <F : OptimizationFeature> getFeature(type: KClass<out F>): F? = features.getFeature(type) -} +public interface OptimizationProblem<T> : AttributeContainer public inline fun <reified F : OptimizationFeature> OptimizationProblem<*>.getFeature(): F? = getFeature(F::class) @@ -27,11 +22,6 @@ public open class OptimizationStartPoint<T>(public val point: Map<Symbol, T>) : override fun toString(): String = "StartPoint($point)" } - -public interface OptimizationPrior<T> : OptimizationFeature, DifferentiableExpression<T> { - override val key: FeatureKey<OptimizationFeature> get() = OptimizationPrior::class -} - /** * Covariance matrix for */ diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt index 9e5396491..cda37af4f 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt @@ -79,7 +79,7 @@ public interface PointWeight : OptimizationFeature { public class XYFit( public val data: XYColumnarData<Double, Double, Double>, public val model: DifferentiableExpression<Double>, - override val features: FeatureSet<OptimizationFeature>, + override val attributes: FeatureSet<OptimizationFeature>, internal val pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY, internal val pointWeight: PointWeight = PointWeight.byYSigma, public val xSymbol: Symbol = Symbol.x, @@ -90,7 +90,7 @@ public class XYFit( } public fun XYFit.withFeature(vararg features: OptimizationFeature): XYFit { - return XYFit(data, model, this.features.with(*features), pointToCurveDistance, pointWeight) + return XYFit(data, model, this.attributes.with(*features), pointToCurveDistance, pointWeight) } public suspend fun XYColumnarData<Double, Double, Double>.fitWith( diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt index 8ab9de48d..40081ed81 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt @@ -53,9 +53,9 @@ internal fun XYFit.logLikelihood(): DifferentiableExpression<Double> = object : */ @UnstableKMathAPI public suspend fun Optimizer<Double, FunctionOptimization<Double>>.maximumLogLikelihood(problem: XYFit): XYFit { - val functionOptimization = FunctionOptimization(problem.features, problem.logLikelihood()) + val functionOptimization = FunctionOptimization(problem.attributes, problem.logLikelihood()) val result = optimize(functionOptimization.withFeatures(FunctionOptimizationTarget.MAXIMIZE)) - return XYFit(problem.data, problem.model, result.features) + return XYFit(problem.data, problem.model, result.attributes) } @UnstableKMathAPI From a3c65e5b178e361d66506b145e1e0a471ca7b3b4 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 18 Jul 2023 11:14:23 +0300 Subject: [PATCH 041/103] [WIP] Features to Attributes refactoring --- .../space/kscience/kmath/ejml/_generated.kt | 1011 +++++++++++++++++ 1 file changed, 1011 insertions(+) create mode 100644 kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt new file mode 100644 index 000000000..fa438775d --- /dev/null +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -0,0 +1,1011 @@ +/* + * 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. + */ + +/* This file is generated with buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt */ + +package space.kscience.kmath.ejml + +import org.ejml.data.* +import org.ejml.dense.row.CommonOps_DDRM +import org.ejml.dense.row.CommonOps_FDRM +import org.ejml.dense.row.factory.DecompositionFactory_DDRM +import org.ejml.dense.row.factory.DecompositionFactory_FDRM +import org.ejml.sparse.FillReducing +import org.ejml.sparse.csc.CommonOps_DSCC +import org.ejml.sparse.csc.CommonOps_FSCC +import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC +import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC +import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC +import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.kmath.linear.* +import space.kscience.kmath.linear.Matrix +import space.kscience.kmath.UnstableKMathAPI +import space.kscience.kmath.nd.StructureFeature +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.FloatField +import space.kscience.kmath.operations.invoke +import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.FloatBuffer +import kotlin.reflect.KClass +import kotlin.reflect.cast + +/** + * [EjmlVector] specialization for [Double]. + */ +public class EjmlDoubleVector<out M : DMatrix>(override val origin: M) : EjmlVector<Double, M>(origin) { + init { + require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } + } + + override operator fun get(index: Int): Double = origin[0, index] +} + +/** + * [EjmlVector] specialization for [Float]. + */ +public class EjmlFloatVector<out M : FMatrix>(override val origin: M) : EjmlVector<Float, M>(origin) { + init { + require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } + } + + override operator fun get(index: Int): Float = origin[0, index] +} + +/** + * [EjmlMatrix] specialization for [Double]. + */ +public class EjmlDoubleMatrix<out M : DMatrix>(override val origin: M) : EjmlMatrix<Double, M>(origin) { + override operator fun get(i: Int, j: Int): Double = origin[i, j] +} + +/** + * [EjmlMatrix] specialization for [Float]. + */ +public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatrix<Float, M>(origin) { + override operator fun get(i: Int, j: Int): Float = origin[i, j] +} + +/** + * [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and + * [DMatrixRMaj] matrices. + */ +public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrixRMaj>() { + /** + * The [DoubleField] reference. + */ + override val elementAlgebra: DoubleField get() = DoubleField + + override val elementType: KType get() = typeOf<Double>() + + @Suppress("UNCHECKED_CAST") + override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when { + this is EjmlDoubleMatrix<*> && origin is DMatrixRMaj -> this as EjmlDoubleMatrix<DMatrixRMaj> + else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } + } + + @Suppress("UNCHECKED_CAST") + override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixRMaj> = when { + this is EjmlDoubleVector<*> && origin is DMatrixRMaj -> this as EjmlDoubleVector<DMatrixRMaj> + else -> EjmlDoubleVector(DMatrixRMaj(size, 1).also { + (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } + }) + } + + override fun buildMatrix( + rows: Int, + columns: Int, + initializer: DoubleField.(i: Int, j: Int) -> Double, + ): EjmlDoubleMatrix<DMatrixRMaj> = DMatrixRMaj(rows, columns).also { + (0 until rows).forEach { row -> + (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } + } + }.wrapMatrix() + + override fun buildVector( + size: Int, + initializer: DoubleField.(Int) -> Double, + ): EjmlDoubleVector<DMatrixRMaj> = EjmlDoubleVector(DMatrixRMaj(size, 1).also { + (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } + }) + + private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this) + private fun <T : DMatrix> T.wrapVector() = EjmlDoubleVector(this) + + override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * elementAlgebra { -one } + + override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { + val out = DMatrixRMaj(1, 1) + CommonOps_DDRM.mult(toEjml().origin, other.toEjml().origin, out) + return out.wrapMatrix() + } + + override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixRMaj> { + val out = DMatrixRMaj(1, 1) + CommonOps_DDRM.mult(toEjml().origin, vector.toEjml().origin, out) + return out.wrapVector() + } + + override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { + val out = DMatrixRMaj(1, 1) + + CommonOps_DDRM.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra { -one }, + other.toEjml().origin, + out, + ) + + return out.wrapMatrix() + } + + override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixRMaj> { + val res = DMatrixRMaj(1, 1) + CommonOps_DDRM.scale(value, toEjml().origin, res) + return res.wrapMatrix() + } + + override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixRMaj> { + val res = DMatrixRMaj(1, 1) + CommonOps_DDRM.changeSign(toEjml().origin, res) + return res.wrapVector() + } + + override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { + val out = DMatrixRMaj(1, 1) + + CommonOps_DDRM.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra.one, + other.toEjml().origin, + out, + ) + + return out.wrapMatrix() + } + + override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> { + val out = DMatrixRMaj(1, 1) + + CommonOps_DDRM.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra.one, + other.toEjml().origin, + out, + ) + + return out.wrapVector() + } + + override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixRMaj> { + val out = DMatrixRMaj(1, 1) + + CommonOps_DDRM.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra { -one }, + other.toEjml().origin, + out, + ) + + return out.wrapVector() + } + + override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> = m * this + + override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixRMaj> { + val res = DMatrixRMaj(1, 1) + CommonOps_DDRM.scale(value, toEjml().origin, res) + return res.wrapVector() + } + + override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this + + @UnstableKMathAPI + override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { + structure.getFeature(type)?.let { return it } + val origin = structure.toEjml().origin + + return when (type) { + InverseMatrixFeature::class -> object : InverseMatrixFeature<Double> { + override val inverse: Matrix<Double> by lazy { + val res = origin.copy() + CommonOps_DDRM.invert(res) + res.wrapMatrix() + } + } + + DeterminantFeature::class -> object : DeterminantFeature<Double> { + override val determinant: Double by lazy { CommonOps_DDRM.det(origin) } + } + + SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> { + private val svd by lazy { + DecompositionFactory_DDRM.svd(origin.numRows, origin.numCols, true, true, false) + .apply { decompose(origin.copy()) } + } + + override val u: Matrix<Double> by lazy { svd.getU(null, false).wrapMatrix() } + override val s: Matrix<Double> by lazy { svd.getW(null).wrapMatrix() } + override val v: Matrix<Double> by lazy { svd.getV(null, false).wrapMatrix() } + override val singularValues: Point<Double> by lazy { DoubleBuffer(svd.singularValues) } + } + + QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> { + private val qr by lazy { + DecompositionFactory_DDRM.qr().apply { decompose(origin.copy()) } + } + + override val q: Matrix<Double> by lazy { + qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) + } + + override val r: Matrix<Double> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } + } + + CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> { + override val l: Matrix<Double> by lazy { + val cholesky = + DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) } + + cholesky.getT(null).wrapMatrix().withFeature(LFeature) + } + } + + LupDecompositionFeature::class -> object : LupDecompositionFeature<Double> { + private val lup by lazy { + DecompositionFactory_DDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) } + } + + override val l: Matrix<Double> by lazy { + lup.getLower(null).wrapMatrix().withFeature(LFeature) + } + + override val u: Matrix<Double> by lazy { + lup.getUpper(null).wrapMatrix().withFeature(UFeature) + } + + override val p: Matrix<Double> by lazy { lup.getRowPivot(null).wrapMatrix() } + } + + else -> null + }?.let{ + type.cast(it) + } + } + + /** + * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. + * + * @param a the base matrix. + * @param b n by p matrix. + * @return the solution for *x* that is n by p. + */ + public fun solve(a: Matrix<Double>, b: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { + val res = DMatrixRMaj(1, 1) + CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res) + return res.wrapMatrix() + } + + /** + * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. + * + * @param a the base matrix. + * @param b n by p vector. + * @return the solution for *x* that is n by p. + */ + public fun solve(a: Matrix<Double>, b: Point<Double>): EjmlDoubleVector<DMatrixRMaj> { + val res = DMatrixRMaj(1, 1) + CommonOps_DDRM.solve(DMatrixRMaj(a.toEjml().origin), DMatrixRMaj(b.toEjml().origin), res) + return EjmlDoubleVector(res) + } +} + +/** + * [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and + * [FMatrixRMaj] matrices. + */ +public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRMaj>() { + /** + * The [FloatField] reference. + */ + override val elementAlgebra: FloatField get() = FloatField + + override val elementType: KType get() = typeOf<Float>() + + @Suppress("UNCHECKED_CAST") + override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixRMaj> = when { + this is EjmlFloatMatrix<*> && origin is FMatrixRMaj -> this as EjmlFloatMatrix<FMatrixRMaj> + else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } + } + + @Suppress("UNCHECKED_CAST") + override fun Point<Float>.toEjml(): EjmlFloatVector<FMatrixRMaj> = when { + this is EjmlFloatVector<*> && origin is FMatrixRMaj -> this as EjmlFloatVector<FMatrixRMaj> + else -> EjmlFloatVector(FMatrixRMaj(size, 1).also { + (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } + }) + } + + override fun buildMatrix( + rows: Int, + columns: Int, + initializer: FloatField.(i: Int, j: Int) -> Float, + ): EjmlFloatMatrix<FMatrixRMaj> = FMatrixRMaj(rows, columns).also { + (0 until rows).forEach { row -> + (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } + } + }.wrapMatrix() + + override fun buildVector( + size: Int, + initializer: FloatField.(Int) -> Float, + ): EjmlFloatVector<FMatrixRMaj> = EjmlFloatVector(FMatrixRMaj(size, 1).also { + (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } + }) + + private fun <T : FMatrix> T.wrapMatrix() = EjmlFloatMatrix(this) + private fun <T : FMatrix> T.wrapVector() = EjmlFloatVector(this) + + override fun Matrix<Float>.unaryMinus(): Matrix<Float> = this * elementAlgebra { -one } + + override fun Matrix<Float>.dot(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { + val out = FMatrixRMaj(1, 1) + CommonOps_FDRM.mult(toEjml().origin, other.toEjml().origin, out) + return out.wrapMatrix() + } + + override fun Matrix<Float>.dot(vector: Point<Float>): EjmlFloatVector<FMatrixRMaj> { + val out = FMatrixRMaj(1, 1) + CommonOps_FDRM.mult(toEjml().origin, vector.toEjml().origin, out) + return out.wrapVector() + } + + override operator fun Matrix<Float>.minus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { + val out = FMatrixRMaj(1, 1) + + CommonOps_FDRM.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra { -one }, + other.toEjml().origin, + out, + ) + + return out.wrapMatrix() + } + + override operator fun Matrix<Float>.times(value: Float): EjmlFloatMatrix<FMatrixRMaj> { + val res = FMatrixRMaj(1, 1) + CommonOps_FDRM.scale(value, toEjml().origin, res) + return res.wrapMatrix() + } + + override fun Point<Float>.unaryMinus(): EjmlFloatVector<FMatrixRMaj> { + val res = FMatrixRMaj(1, 1) + CommonOps_FDRM.changeSign(toEjml().origin, res) + return res.wrapVector() + } + + override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { + val out = FMatrixRMaj(1, 1) + + CommonOps_FDRM.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra.one, + other.toEjml().origin, + out, + ) + + return out.wrapMatrix() + } + + override fun Point<Float>.plus(other: Point<Float>): EjmlFloatVector<FMatrixRMaj> { + val out = FMatrixRMaj(1, 1) + + CommonOps_FDRM.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra.one, + other.toEjml().origin, + out, + ) + + return out.wrapVector() + } + + override fun Point<Float>.minus(other: Point<Float>): EjmlFloatVector<FMatrixRMaj> { + val out = FMatrixRMaj(1, 1) + + CommonOps_FDRM.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra { -one }, + other.toEjml().origin, + out, + ) + + return out.wrapVector() + } + + override fun Float.times(m: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> = m * this + + override fun Point<Float>.times(value: Float): EjmlFloatVector<FMatrixRMaj> { + val res = FMatrixRMaj(1, 1) + CommonOps_FDRM.scale(value, toEjml().origin, res) + return res.wrapVector() + } + + override fun Float.times(v: Point<Float>): EjmlFloatVector<FMatrixRMaj> = v * this + + @UnstableKMathAPI + override fun <F : StructureFeature> computeFeature(structure: Matrix<Float>, type: KClass<out F>): F? { + structure.getFeature(type)?.let { return it } + val origin = structure.toEjml().origin + + return when (type) { + InverseMatrixFeature::class -> object : InverseMatrixFeature<Float> { + override val inverse: Matrix<Float> by lazy { + val res = origin.copy() + CommonOps_FDRM.invert(res) + res.wrapMatrix() + } + } + + DeterminantFeature::class -> object : DeterminantFeature<Float> { + override val determinant: Float by lazy { CommonOps_FDRM.det(origin) } + } + + SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Float> { + private val svd by lazy { + DecompositionFactory_FDRM.svd(origin.numRows, origin.numCols, true, true, false) + .apply { decompose(origin.copy()) } + } + + override val u: Matrix<Float> by lazy { svd.getU(null, false).wrapMatrix() } + override val s: Matrix<Float> by lazy { svd.getW(null).wrapMatrix() } + override val v: Matrix<Float> by lazy { svd.getV(null, false).wrapMatrix() } + override val singularValues: Point<Float> by lazy { FloatBuffer(svd.singularValues) } + } + + QRDecompositionFeature::class -> object : QRDecompositionFeature<Float> { + private val qr by lazy { + DecompositionFactory_FDRM.qr().apply { decompose(origin.copy()) } + } + + override val q: Matrix<Float> by lazy { + qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) + } + + override val r: Matrix<Float> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } + } + + CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Float> { + override val l: Matrix<Float> by lazy { + val cholesky = + DecompositionFactory_FDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) } + + cholesky.getT(null).wrapMatrix().withFeature(LFeature) + } + } + + LupDecompositionFeature::class -> object : LupDecompositionFeature<Float> { + private val lup by lazy { + DecompositionFactory_FDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) } + } + + override val l: Matrix<Float> by lazy { + lup.getLower(null).wrapMatrix().withFeature(LFeature) + } + + override val u: Matrix<Float> by lazy { + lup.getUpper(null).wrapMatrix().withFeature(UFeature) + } + + override val p: Matrix<Float> by lazy { lup.getRowPivot(null).wrapMatrix() } + } + + else -> null + }?.let{ + type.cast(it) + } + } + + /** + * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. + * + * @param a the base matrix. + * @param b n by p matrix. + * @return the solution for *x* that is n by p. + */ + public fun solve(a: Matrix<Float>, b: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { + val res = FMatrixRMaj(1, 1) + CommonOps_FDRM.solve(FMatrixRMaj(a.toEjml().origin), FMatrixRMaj(b.toEjml().origin), res) + return res.wrapMatrix() + } + + /** + * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. + * + * @param a the base matrix. + * @param b n by p vector. + * @return the solution for *x* that is n by p. + */ + public fun solve(a: Matrix<Float>, b: Point<Float>): EjmlFloatVector<FMatrixRMaj> { + val res = FMatrixRMaj(1, 1) + CommonOps_FDRM.solve(FMatrixRMaj(a.toEjml().origin), FMatrixRMaj(b.toEjml().origin), res) + return EjmlFloatVector(res) + } +} + +/** + * [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and + * [DMatrixSparseCSC] matrices. + */ +public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrixSparseCSC>() { + /** + * The [DoubleField] reference. + */ + override val elementAlgebra: DoubleField get() = DoubleField + + override val elementType: KType get() = typeOf<Double>() + + @Suppress("UNCHECKED_CAST") + override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when { + this is EjmlDoubleMatrix<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleMatrix<DMatrixSparseCSC> + else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } + } + + @Suppress("UNCHECKED_CAST") + override fun Point<Double>.toEjml(): EjmlDoubleVector<DMatrixSparseCSC> = when { + this is EjmlDoubleVector<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleVector<DMatrixSparseCSC> + else -> EjmlDoubleVector(DMatrixSparseCSC(size, 1).also { + (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } + }) + } + + override fun buildMatrix( + rows: Int, + columns: Int, + initializer: DoubleField.(i: Int, j: Int) -> Double, + ): EjmlDoubleMatrix<DMatrixSparseCSC> = DMatrixSparseCSC(rows, columns).also { + (0 until rows).forEach { row -> + (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } + } + }.wrapMatrix() + + override fun buildVector( + size: Int, + initializer: DoubleField.(Int) -> Double, + ): EjmlDoubleVector<DMatrixSparseCSC> = EjmlDoubleVector(DMatrixSparseCSC(size, 1).also { + (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } + }) + + private fun <T : DMatrix> T.wrapMatrix() = EjmlDoubleMatrix(this) + private fun <T : DMatrix> T.wrapVector() = EjmlDoubleVector(this) + + override fun Matrix<Double>.unaryMinus(): Matrix<Double> = this * elementAlgebra { -one } + + override fun Matrix<Double>.dot(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { + val out = DMatrixSparseCSC(1, 1) + CommonOps_DSCC.mult(toEjml().origin, other.toEjml().origin, out) + return out.wrapMatrix() + } + + override fun Matrix<Double>.dot(vector: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> { + val out = DMatrixSparseCSC(1, 1) + CommonOps_DSCC.mult(toEjml().origin, vector.toEjml().origin, out) + return out.wrapVector() + } + + override operator fun Matrix<Double>.minus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { + val out = DMatrixSparseCSC(1, 1) + + CommonOps_DSCC.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra { -one }, + other.toEjml().origin, + out, + null, + null, + ) + + return out.wrapMatrix() + } + + override operator fun Matrix<Double>.times(value: Double): EjmlDoubleMatrix<DMatrixSparseCSC> { + val res = DMatrixSparseCSC(1, 1) + CommonOps_DSCC.scale(value, toEjml().origin, res) + return res.wrapMatrix() + } + + override fun Point<Double>.unaryMinus(): EjmlDoubleVector<DMatrixSparseCSC> { + val res = DMatrixSparseCSC(1, 1) + CommonOps_DSCC.changeSign(toEjml().origin, res) + return res.wrapVector() + } + + override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { + val out = DMatrixSparseCSC(1, 1) + + CommonOps_DSCC.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra.one, + other.toEjml().origin, + out, + null, + null, + ) + + return out.wrapMatrix() + } + + override fun Point<Double>.plus(other: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> { + val out = DMatrixSparseCSC(1, 1) + + CommonOps_DSCC.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra.one, + other.toEjml().origin, + out, + null, + null, + ) + + return out.wrapVector() + } + + override fun Point<Double>.minus(other: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> { + val out = DMatrixSparseCSC(1, 1) + + CommonOps_DSCC.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra { -one }, + other.toEjml().origin, + out, + null, + null, + ) + + return out.wrapVector() + } + + override fun Double.times(m: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> = m * this + + override fun Point<Double>.times(value: Double): EjmlDoubleVector<DMatrixSparseCSC> { + val res = DMatrixSparseCSC(1, 1) + CommonOps_DSCC.scale(value, toEjml().origin, res) + return res.wrapVector() + } + + override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> = v * this + + @UnstableKMathAPI + override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { + structure.getFeature(type)?.let { return it } + val origin = structure.toEjml().origin + + return when (type) { + QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> { + private val qr by lazy { + DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } + } + + override val q: Matrix<Double> by lazy { + qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) + } + + override val r: Matrix<Double> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } + } + + CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> { + override val l: Matrix<Double> by lazy { + val cholesky = + DecompositionFactory_DSCC.cholesky().apply { decompose(origin.copy()) } + + (cholesky.getT(null) as DMatrix).wrapMatrix().withFeature(LFeature) + } + } + + LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object : + LUDecompositionFeature<Double>, DeterminantFeature<Double>, InverseMatrixFeature<Double> { + private val lu by lazy { + DecompositionFactory_DSCC.lu(FillReducing.NONE).apply { decompose(origin.copy()) } + } + + override val l: Matrix<Double> by lazy { + lu.getLower(null).wrapMatrix().withFeature(LFeature) + } + + override val u: Matrix<Double> by lazy { + lu.getUpper(null).wrapMatrix().withFeature(UFeature) + } + + override val inverse: Matrix<Double> by lazy { + var a = origin + val inverse = DMatrixRMaj(1, 1) + val solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE) + if (solver.modifiesA()) a = a.copy() + val i = CommonOps_DDRM.identity(a.numRows) + solver.solve(i, inverse) + inverse.wrapMatrix() + } + + override val determinant: Double by lazy { elementAlgebra.number(lu.computeDeterminant().real) } + } + + else -> null + }?.let{ + type.cast(it) + } + } + + /** + * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. + * + * @param a the base matrix. + * @param b n by p matrix. + * @return the solution for *x* that is n by p. + */ + public fun solve(a: Matrix<Double>, b: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { + val res = DMatrixSparseCSC(1, 1) + CommonOps_DSCC.solve(DMatrixSparseCSC(a.toEjml().origin), DMatrixSparseCSC(b.toEjml().origin), res) + return res.wrapMatrix() + } + + /** + * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. + * + * @param a the base matrix. + * @param b n by p vector. + * @return the solution for *x* that is n by p. + */ + public fun solve(a: Matrix<Double>, b: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> { + val res = DMatrixSparseCSC(1, 1) + CommonOps_DSCC.solve(DMatrixSparseCSC(a.toEjml().origin), DMatrixSparseCSC(b.toEjml().origin), res) + return EjmlDoubleVector(res) + } +} + +/** + * [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and + * [FMatrixSparseCSC] matrices. + */ +public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSparseCSC>() { + /** + * The [FloatField] reference. + */ + override val elementAlgebra: FloatField get() = FloatField + + override val elementType: KType get() = typeOf<Float>() + + @Suppress("UNCHECKED_CAST") + override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixSparseCSC> = when { + this is EjmlFloatMatrix<*> && origin is FMatrixSparseCSC -> this as EjmlFloatMatrix<FMatrixSparseCSC> + else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } + } + + @Suppress("UNCHECKED_CAST") + override fun Point<Float>.toEjml(): EjmlFloatVector<FMatrixSparseCSC> = when { + this is EjmlFloatVector<*> && origin is FMatrixSparseCSC -> this as EjmlFloatVector<FMatrixSparseCSC> + else -> EjmlFloatVector(FMatrixSparseCSC(size, 1).also { + (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } + }) + } + + override fun buildMatrix( + rows: Int, + columns: Int, + initializer: FloatField.(i: Int, j: Int) -> Float, + ): EjmlFloatMatrix<FMatrixSparseCSC> = FMatrixSparseCSC(rows, columns).also { + (0 until rows).forEach { row -> + (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } + } + }.wrapMatrix() + + override fun buildVector( + size: Int, + initializer: FloatField.(Int) -> Float, + ): EjmlFloatVector<FMatrixSparseCSC> = EjmlFloatVector(FMatrixSparseCSC(size, 1).also { + (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } + }) + + private fun <T : FMatrix> T.wrapMatrix() = EjmlFloatMatrix(this) + private fun <T : FMatrix> T.wrapVector() = EjmlFloatVector(this) + + override fun Matrix<Float>.unaryMinus(): Matrix<Float> = this * elementAlgebra { -one } + + override fun Matrix<Float>.dot(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { + val out = FMatrixSparseCSC(1, 1) + CommonOps_FSCC.mult(toEjml().origin, other.toEjml().origin, out) + return out.wrapMatrix() + } + + override fun Matrix<Float>.dot(vector: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> { + val out = FMatrixSparseCSC(1, 1) + CommonOps_FSCC.mult(toEjml().origin, vector.toEjml().origin, out) + return out.wrapVector() + } + + override operator fun Matrix<Float>.minus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { + val out = FMatrixSparseCSC(1, 1) + + CommonOps_FSCC.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra { -one }, + other.toEjml().origin, + out, + null, + null, + ) + + return out.wrapMatrix() + } + + override operator fun Matrix<Float>.times(value: Float): EjmlFloatMatrix<FMatrixSparseCSC> { + val res = FMatrixSparseCSC(1, 1) + CommonOps_FSCC.scale(value, toEjml().origin, res) + return res.wrapMatrix() + } + + override fun Point<Float>.unaryMinus(): EjmlFloatVector<FMatrixSparseCSC> { + val res = FMatrixSparseCSC(1, 1) + CommonOps_FSCC.changeSign(toEjml().origin, res) + return res.wrapVector() + } + + override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { + val out = FMatrixSparseCSC(1, 1) + + CommonOps_FSCC.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra.one, + other.toEjml().origin, + out, + null, + null, + ) + + return out.wrapMatrix() + } + + override fun Point<Float>.plus(other: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> { + val out = FMatrixSparseCSC(1, 1) + + CommonOps_FSCC.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra.one, + other.toEjml().origin, + out, + null, + null, + ) + + return out.wrapVector() + } + + override fun Point<Float>.minus(other: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> { + val out = FMatrixSparseCSC(1, 1) + + CommonOps_FSCC.add( + elementAlgebra.one, + toEjml().origin, + elementAlgebra { -one }, + other.toEjml().origin, + out, + null, + null, + ) + + return out.wrapVector() + } + + override fun Float.times(m: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> = m * this + + override fun Point<Float>.times(value: Float): EjmlFloatVector<FMatrixSparseCSC> { + val res = FMatrixSparseCSC(1, 1) + CommonOps_FSCC.scale(value, toEjml().origin, res) + return res.wrapVector() + } + + override fun Float.times(v: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> = v * this + + @UnstableKMathAPI + override fun <F : StructureFeature> computeFeature(structure: Matrix<Float>, type: KClass<out F>): F? { + structure.getFeature(type)?.let { return it } + val origin = structure.toEjml().origin + + return when (type) { + QRDecompositionFeature::class -> object : QRDecompositionFeature<Float> { + private val qr by lazy { + DecompositionFactory_FSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } + } + + override val q: Matrix<Float> by lazy { + qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) + } + + override val r: Matrix<Float> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } + } + + CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Float> { + override val l: Matrix<Float> by lazy { + val cholesky = + DecompositionFactory_FSCC.cholesky().apply { decompose(origin.copy()) } + + (cholesky.getT(null) as FMatrix).wrapMatrix().withFeature(LFeature) + } + } + + LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object : + LUDecompositionFeature<Float>, DeterminantFeature<Float>, InverseMatrixFeature<Float> { + private val lu by lazy { + DecompositionFactory_FSCC.lu(FillReducing.NONE).apply { decompose(origin.copy()) } + } + + override val l: Matrix<Float> by lazy { + lu.getLower(null).wrapMatrix().withFeature(LFeature) + } + + override val u: Matrix<Float> by lazy { + lu.getUpper(null).wrapMatrix().withFeature(UFeature) + } + + override val inverse: Matrix<Float> by lazy { + var a = origin + val inverse = FMatrixRMaj(1, 1) + val solver = LinearSolverFactory_FSCC.lu(FillReducing.NONE) + if (solver.modifiesA()) a = a.copy() + val i = CommonOps_FDRM.identity(a.numRows) + solver.solve(i, inverse) + inverse.wrapMatrix() + } + + override val determinant: Float by lazy { elementAlgebra.number(lu.computeDeterminant().real) } + } + + else -> null + }?.let{ + type.cast(it) + } + } + + /** + * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. + * + * @param a the base matrix. + * @param b n by p matrix. + * @return the solution for *x* that is n by p. + */ + public fun solve(a: Matrix<Float>, b: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { + val res = FMatrixSparseCSC(1, 1) + CommonOps_FSCC.solve(FMatrixSparseCSC(a.toEjml().origin), FMatrixSparseCSC(b.toEjml().origin), res) + return res.wrapMatrix() + } + + /** + * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. + * + * @param a the base matrix. + * @param b n by p vector. + * @return the solution for *x* that is n by p. + */ + public fun solve(a: Matrix<Float>, b: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> { + val res = FMatrixSparseCSC(1, 1) + CommonOps_FSCC.solve(FMatrixSparseCSC(a.toEjml().origin), FMatrixSparseCSC(b.toEjml().origin), res) + return EjmlFloatVector(res) + } +} + From 1e2a8a40e5334a6dc2a8d5900ef04b7597666d36 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 28 Jul 2023 20:39:05 +0300 Subject: [PATCH 042/103] levenbergMarquardt cleanup --- build.gradle.kts | 2 +- .../core/LevenbergMarquardtAlgorithm.kt | 314 +++++++++++------- .../kmath/tensors/core/TestLmAlgorithm.kt | 224 +++++++------ 3 files changed, 313 insertions(+), 227 deletions(-) rename kmath-tensors/src/{commonTest => jvmTest}/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt (52%) diff --git a/build.gradle.kts b/build.gradle.kts index aed79909c..7dbe87445 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ allprojects { } group = "space.kscience" - version = "0.3.1" + version = "0.3.2-dev-1" } subprojects { diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index 3cb485d7d..72752f855 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -5,18 +5,13 @@ package space.kscience.kmath.tensors.core +import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.linear.transpose import space.kscience.kmath.nd.* -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.div -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.dot -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.minus -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.times -import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.transposed -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus +import kotlin.math.abs import kotlin.math.max import kotlin.math.min import kotlin.math.pow -import kotlin.reflect.KFunction3 /** * Type of convergence achieved as a result of executing the Levenberg-Marquardt algorithm. @@ -50,8 +45,8 @@ public enum class TypeOfConvergence { * resultParameters: final parameters. * typeOfConvergence: type of convergence. */ -public data class LMResultInfo ( - var iterations:Int, +public data class LMResultInfo( + var iterations: Int, var funcCalls: Int, var resultChiSq: Double, var resultLambda: Double, @@ -87,7 +82,7 @@ public data class LMResultInfo ( * <8 - use maxParameters by default, <9 - use updateType by default). * exampleNumber: a parameter for a function with which you can choose its behavior. */ -public data class LMInput ( +public data class LMInput( var func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> (MutableStructure2D<Double>), var startParameters: MutableStructure2D<Double>, var independentVariables: MutableStructure2D<Double>, @@ -101,7 +96,7 @@ public data class LMInput ( var lambdas: DoubleArray, var updateType: Int, var nargin: Int, - var exampleNumber: Int + var exampleNumber: Int, ) @@ -120,8 +115,10 @@ public data class LMInput ( * @return the 'output'. */ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultInfo { - val resultInfo = LMResultInfo(0, 0, 0.0, - 0.0, inputData.startParameters, TypeOfConvergence.NoConvergence) + val resultInfo = LMResultInfo( + 0, 0, 0.0, + 0.0, inputData.startParameters, TypeOfConvergence.NoConvergence + ) val eps = 2.2204e-16 @@ -131,18 +128,21 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI var p = inputData.startParameters val t = inputData.independentVariables - val Npar = length(p) // number of parameters - val Npnt = length(inputData.realValues) // number of data points - var pOld = zeros(ShapeND(intArrayOf(Npar, 1))).as2D() // previous set of parameters - var yOld = zeros(ShapeND(intArrayOf(Npnt, 1))).as2D() // previous model, y_old = y_hat(t;p_old) - var X2 = 1e-3 / eps // a really big initial Chi-sq value - var X2Old = 1e-3 / eps // a really big initial Chi-sq value - var J = zeros(ShapeND(intArrayOf(Npnt, Npar))).as2D() // Jacobian matrix - val DoF = Npnt - Npar // statistical degrees of freedom + val nPar = length(p) // number of parameters + val nPoints = length(inputData.realValues) // number of data points + var pOld = zeros(ShapeND(intArrayOf(nPar, 1))).as2D() // previous set of parameters + var yOld = zeros(ShapeND(intArrayOf(nPoints, 1))).as2D() // previous model, y_old = y_hat(t;p_old) + var x2: Double // a really big initial Chi-sq value + var x2Old: Double // a really big initial Chi-sq value + var jacobian = zeros(ShapeND(intArrayOf(nPoints, nPar))).as2D() // Jacobian matrix + val dof = nPoints - nPar // statistical degrees of freedom var weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf(inputData.weight)).as2D() - if (inputData.nargin < 5) { - weight = fromArray(ShapeND(intArrayOf(1, 1)), doubleArrayOf((inputData.realValues.transpose().dot(inputData.realValues)).as1D()[0])).as2D() + if (inputData.nargin < 5) { + weight = fromArray( + ShapeND(intArrayOf(1, 1)), + doubleArrayOf((inputData.realValues.transpose().dot(inputData.realValues)).as1D()[0]) + ).as2D() } var dp = inputData.pDelta @@ -169,13 +169,13 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI var epsilon2 = inputData.epsilons[1] var epsilon3 = inputData.epsilons[2] var epsilon4 = inputData.epsilons[3] - var lambda0 = inputData.lambdas[0] + var lambda0 = inputData.lambdas[0] var lambdaUpFac = inputData.lambdas[1] var lambdaDnFac = inputData.lambdas[2] var updateType = inputData.updateType if (inputData.nargin < 9) { - maxIterations = 10 * Npar + maxIterations = 10 * nPar epsilon1 = 1e-3 epsilon2 = 1e-3 epsilon3 = 1e-1 @@ -190,28 +190,27 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI maxParameters = makeColumn(maxParameters) if (length(makeColumn(dp)) == 1) { - dp = ones(ShapeND(intArrayOf(Npar, 1))).div(1 / dp[0, 0]).as2D() + dp = ones(ShapeND(intArrayOf(nPar, 1))).div(1 / dp[0, 0]).as2D() } var stop = false // termination flag if (weight.shape.component1() == 1 || variance(weight) == 0.0) { // identical weights vector - weight = ones(ShapeND(intArrayOf(Npnt, 1))).div(1 / kotlin.math.abs(weight[0, 0])).as2D() - } - else { + weight = ones(ShapeND(intArrayOf(nPoints, 1))).div(1 / abs(weight[0, 0])).as2D() + } else { weight = makeColumn(weight) weight.abs() } // initialize Jacobian with finite difference calculation - var lmMatxAns = lmMatx(inputData.func, t, pOld, yOld, 1, J, p, inputData.realValues, weight, dp, settings) - var JtWJ = lmMatxAns[0] - var JtWdy = lmMatxAns[1] - X2 = lmMatxAns[2][0, 0] + var lmMatxAns = lmMatx(inputData.func, t, pOld, yOld, 1, jacobian, p, inputData.realValues, weight, dp, settings) + var jtWJ = lmMatxAns[0] + var jtWdy = lmMatxAns[1] + x2 = lmMatxAns[2][0, 0] var yHat = lmMatxAns[3] - J = lmMatxAns[4] + jacobian = lmMatxAns[4] - if ( abs(JtWdy).max() < epsilon1 ) { + if (abs(jtWdy).max() < epsilon1) { stop = true } @@ -219,14 +218,13 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI var nu = 1 if (updateType == 1) { - lambda = lambda0 // Marquardt: init'l lambda - } - else { - lambda = lambda0 * (makeColumnFromDiagonal(JtWJ)).max() + lambda = lambda0 // Marquardt: init'l lambda + } else { + lambda = lambda0 * (makeColumnFromDiagonal(jtWJ)).max() nu = 2 } - X2Old = X2 // previous value of X2 + x2Old = x2 // previous value of X2 var h: DoubleTensor @@ -235,20 +233,31 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI // incremental change in parameters h = if (updateType == 1) { // Marquardt - val solve = solve(JtWJ.plus(makeMatrixWithDiagonal(makeColumnFromDiagonal(JtWJ)).div(1 / lambda)).as2D(), JtWdy) + val solve = + solve((jtWJ + makeMatrixWithDiagonal(makeColumnFromDiagonal(jtWJ)) / (1 / lambda)).as2D(), jtWdy) solve.asDoubleTensor() } else { // Quadratic and Nielsen - val solve = solve(JtWJ.plus(lmEye(Npar).div(1 / lambda)).as2D(), JtWdy) + val solve = solve(jtWJ.plus(lmEye(nPar) * lambda).as2D(), jtWdy) solve.asDoubleTensor() } var pTry = (p + h).as2D() // update the [idx] elements - pTry = smallestElementComparison(largestElementComparison(minParameters, pTry.as2D()), maxParameters) // apply constraints + pTry = smallestElementComparison( + largestElementComparison(minParameters, pTry), + maxParameters + ) // apply constraints - var deltaY = inputData.realValues.minus(evaluateFunction(inputData.func, t, pTry, inputData.exampleNumber)) // residual error using p_try + var deltaY = inputData.realValues.minus( + evaluateFunction( + inputData.func, + t, + pTry, + inputData.exampleNumber + ) + ) // residual error using p_try - for (i in 0 until deltaY.shape.component1()) { // floating point error; break - for (j in 0 until deltaY.shape.component2()) { + for (i in 0 until deltaY.shape[0]) { // floating point error; break + for (j in 0 until deltaY.shape[1]) { if (deltaY[i, j] == Double.POSITIVE_INFINITY || deltaY[i, j] == Double.NEGATIVE_INFINITY) { stop = true break @@ -258,49 +267,72 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI settings.funcCalls += 1 - val tmp = deltaY.times(weight) - var X2Try = deltaY.as2D().transpose().dot(tmp) // Chi-squared error criteria +// val tmp = deltaY.times(weight) + var X2Try = deltaY.as2D().transpose().dot(deltaY.times(weight)) // Chi-squared error criteria val alpha = 1.0 if (updateType == 2) { // Quadratic // One step of quadratic line update in the h direction for minimum X2 - val alpha = JtWdy.transpose().dot(h) / ((X2Try.minus(X2)).div(2.0).plus(2 * JtWdy.transpose().dot(h))) - h = h.dot(alpha) - pTry = p.plus(h).as2D() // update only [idx] elements - pTry = smallestElementComparison(largestElementComparison(minParameters, pTry), maxParameters) // apply constraints + val alpha = (jtWdy.transpose() dot h) / ((X2Try - x2) / 2.0 + 2 * (jtWdy.transpose() dot h)) + h = h dot alpha + pTry = (p + h).as2D() // update only [idx] elements + pTry = smallestElementComparison( + largestElementComparison(minParameters, pTry), + maxParameters + ) // apply constraints - deltaY = inputData.realValues.minus(evaluateFunction(inputData.func, t, pTry, inputData.exampleNumber)) // residual error using p_try + deltaY = inputData.realValues.minus( + evaluateFunction( + inputData.func, + t, + pTry, + inputData.exampleNumber + ) + ) // residual error using p_try settings.funcCalls += 1 - X2Try = deltaY.as2D().transpose().dot(deltaY.times(weight)) // Chi-squared error criteria + X2Try = deltaY.as2D().transpose() dot deltaY * weight // Chi-squared error criteria } val rho = when (updateType) { // Nielsen 1 -> { val tmp = h.transposed() - .dot(makeMatrixWithDiagonal(makeColumnFromDiagonal(JtWJ)).div(1 / lambda).dot(h).plus(JtWdy)) - X2.minus(X2Try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] + .dot((makeMatrixWithDiagonal(makeColumnFromDiagonal(jtWJ)) * lambda dot h) + jtWdy) + (x2 - X2Try)[0, 0] / abs(tmp.as2D())[0, 0] } + else -> { - val tmp = h.transposed().dot(h.div(1 / lambda).plus(JtWdy)) - X2.minus(X2Try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] + val tmp = h.transposed().dot((h * lambda) + jtWdy) + x2.minus(X2Try).as2D()[0, 0] / abs(tmp.as2D()).as2D()[0, 0] } } if (rho > epsilon4) { // it IS significantly better - val dX2 = X2.minus(X2Old) - X2Old = X2 + val dX2 = x2.minus(x2Old) + x2Old = x2 pOld = p.copyToTensor().as2D() yOld = yHat.copyToTensor().as2D() p = makeColumn(pTry) // accept p_try - lmMatxAns = lmMatx(inputData.func, t, pOld, yOld, dX2.toInt(), J, p, inputData.realValues, weight, dp, settings) + lmMatxAns = lmMatx( + inputData.func, + t, + pOld, + yOld, + dX2.toInt(), + jacobian, + p, + inputData.realValues, + weight, + dp, + settings + ) // decrease lambda ==> Gauss-Newton method - JtWJ = lmMatxAns[0] - JtWdy = lmMatxAns[1] - X2 = lmMatxAns[2][0, 0] + jtWJ = lmMatxAns[0] + jtWdy = lmMatxAns[1] + x2 = lmMatxAns[2][0, 0] yHat = lmMatxAns[3] - J = lmMatxAns[4] + jacobian = lmMatxAns[4] lambda = when (updateType) { 1 -> { // Levenberg @@ -317,13 +349,14 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI } } } else { // it IS NOT better - X2 = X2Old // do not accept p_try - if (settings.iteration % (2 * Npar) == 0) { // rank-1 update of Jacobian - lmMatxAns = lmMatx(inputData.func, t, pOld, yOld, -1, J, p, inputData.realValues, weight, dp, settings) - JtWJ = lmMatxAns[0] - JtWdy = lmMatxAns[1] + x2 = x2Old // do not accept p_try + if (settings.iteration % (2 * nPar) == 0) { // rank-1 update of Jacobian + lmMatxAns = + lmMatx(inputData.func, t, pOld, yOld, -1, jacobian, p, inputData.realValues, weight, dp, settings) + jtWJ = lmMatxAns[0] + jtWdy = lmMatxAns[1] yHat = lmMatxAns[3] - J = lmMatxAns[4] + jacobian = lmMatxAns[4] } // increase lambda ==> gradient descent method @@ -333,7 +366,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI } 2 -> { // Quadratic - lambda + kotlin.math.abs(((X2Try.as2D()[0, 0] - X2) / 2) / alpha) + lambda + abs(((X2Try.as2D()[0, 0] - x2) / 2) / alpha) } else -> { // Nielsen @@ -343,7 +376,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI } } - val chiSq = X2 / DoF + val chiSq = x2 / dof resultInfo.iterations = settings.iteration resultInfo.funcCalls = settings.funcCalls resultInfo.resultChiSq = chiSq @@ -351,7 +384,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI resultInfo.resultParameters = p - if (abs(JtWdy).max() < epsilon1 && settings.iteration > 2) { + if (abs(jtWdy).max() < epsilon1 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InGradient stop = true } @@ -359,7 +392,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI resultInfo.typeOfConvergence = TypeOfConvergence.InParameters stop = true } - if (X2 / DoF < epsilon3 && settings.iteration > 2) { + if (x2 / dof < epsilon3 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InReducedChiSquare stop = true } @@ -371,10 +404,10 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI return resultInfo } -private data class LMSettings ( - var iteration:Int, +private data class LMSettings( + var iteration: Int, var funcCalls: Int, - var exampleNumber:Int + var exampleNumber: Int, ) /* matrix -> column of all elements */ @@ -390,14 +423,14 @@ private fun makeColumn(tensor: MutableStructure2D<Double>): MutableStructure2D<D } /* column length */ -private fun length(column: MutableStructure2D<Double>) : Int { +private fun length(column: MutableStructure2D<Double>): Int { return column.shape.component1() } private fun MutableStructure2D<Double>.abs() { - for (i in 0 until this.shape.component1()) { - for (j in 0 until this.shape.component2()) { - this[i, j] = kotlin.math.abs(this[i, j]) + for (i in 0 until this.shape[0]) { + for (j in 0 until this.shape[1]) { + this[i, j] = abs(this[i, j]) } } } @@ -413,7 +446,7 @@ private fun abs(input: MutableStructure2D<Double>): MutableStructure2D<Double> { ).as2D() for (i in 0 until tensor.shape.component1()) { for (j in 0 until tensor.shape.component2()) { - tensor[i, j] = kotlin.math.abs(input[i, j]) + tensor[i, j] = abs(input[i, j]) } } return tensor @@ -441,21 +474,23 @@ private fun lmEye(size: Int): MutableStructure2D<Double> { return makeMatrixWithDiagonal(column) } -private fun largestElementComparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun largestElementComparison( + a: MutableStructure2D<Double>, + b: MutableStructure2D<Double>, +): MutableStructure2D<Double> { val aSizeX = a.shape.component1() val aSizeY = a.shape.component2() val bSizeX = b.shape.component1() val bSizeY = b.shape.component2() - val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(aSizeX, bSizeX), max(aSizeY, bSizeY)))).as2D() + val tensor = + BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(aSizeX, bSizeX), max(aSizeY, bSizeY)))).as2D() for (i in 0 until tensor.shape.component1()) { for (j in 0 until tensor.shape.component2()) { if (i < aSizeX && i < bSizeX && j < aSizeY && j < bSizeY) { tensor[i, j] = max(a[i, j], b[i, j]) - } - else if (i < aSizeX && j < aSizeY) { + } else if (i < aSizeX && j < aSizeY) { tensor[i, j] = a[i, j] - } - else { + } else { tensor[i, j] = b[i, j] } } @@ -463,21 +498,23 @@ private fun largestElementComparison(a: MutableStructure2D<Double>, b: MutableSt return tensor } -private fun smallestElementComparison(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun smallestElementComparison( + a: MutableStructure2D<Double>, + b: MutableStructure2D<Double>, +): MutableStructure2D<Double> { val aSizeX = a.shape.component1() val aSizeY = a.shape.component2() val bSizeX = b.shape.component1() val bSizeY = b.shape.component2() - val tensor = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(aSizeX, bSizeX), max(aSizeY, bSizeY)))).as2D() + val tensor = + BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(max(aSizeX, bSizeX), max(aSizeY, bSizeY)))).as2D() for (i in 0 until tensor.shape.component1()) { for (j in 0 until tensor.shape.component2()) { if (i < aSizeX && i < bSizeX && j < aSizeY && j < bSizeY) { tensor[i, j] = min(a[i, j], b[i, j]) - } - else if (i < aSizeX && j < aSizeY) { + } else if (i < aSizeX && j < aSizeY) { tensor[i, j] = a[i, j] - } - else { + } else { tensor[i, j] = b[i, j] } } @@ -485,10 +522,13 @@ private fun smallestElementComparison(a: MutableStructure2D<Double>, b: MutableS return tensor } -private fun getZeroIndices(column: MutableStructure2D<Double>, epsilon: Double = 0.000001): MutableStructure2D<Double>? { +private fun getZeroIndices( + column: MutableStructure2D<Double>, + epsilon: Double = 0.000001, +): MutableStructure2D<Double>? { var idx = emptyArray<Double>() for (i in 0 until column.shape.component1()) { - if (kotlin.math.abs(column[i, 0]) > epsilon) { + if (abs(column[i, 0]) > epsilon) { idx += (i + 1.0) } } @@ -498,18 +538,27 @@ private fun getZeroIndices(column: MutableStructure2D<Double>, epsilon: Double = return null } -private fun evaluateFunction(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int) - : MutableStructure2D<Double> -{ +private fun evaluateFunction( + func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int, +) + : MutableStructure2D<Double> { return func(t, p, exampleNumber) } -private fun lmMatx(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, pOld: MutableStructure2D<Double>, yOld: MutableStructure2D<Double>, - dX2: Int, JInput: MutableStructure2D<Double>, p: MutableStructure2D<Double>, - yDat: MutableStructure2D<Double>, weight: MutableStructure2D<Double>, dp:MutableStructure2D<Double>, settings:LMSettings) : Array<MutableStructure2D<Double>> -{ +private fun lmMatx( + func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, + pOld: MutableStructure2D<Double>, + yOld: MutableStructure2D<Double>, + dX2: Int, + JInput: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, + yDat: MutableStructure2D<Double>, + weight: MutableStructure2D<Double>, + dp: MutableStructure2D<Double>, + settings: LMSettings, +): Array<MutableStructure2D<Double>> = with(DoubleTensorAlgebra) { // default: dp = 0.001 val Npar = length(p) // number of parameters @@ -520,63 +569,70 @@ private fun lmMatx(func: (MutableStructure2D<Double>, MutableStructure2D<Double> J = if (settings.iteration % (2 * Npar) == 0 || dX2 > 0) { lmFdJ(func, t, p, yHat, dp, settings).as2D() // finite difference - } - else { + } else { lmBroydenJ(pOld, yOld, J, p, yHat).as2D() // rank-1 update } val deltaY = yDat.minus(yHat) - val chiSq = deltaY.transposed().dot( deltaY.times(weight) ).as2D() - val JtWJ = J.transposed().dot ( J.times( weight.dot(BroadcastDoubleTensorAlgebra.ones(ShapeND(intArrayOf(1, Npar)))) ) ).as2D() - val JtWdy = J.transposed().dot( weight.times(deltaY) ).as2D() + val chiSq = deltaY.transposed().dot(deltaY.times(weight)).as2D() + val JtWJ = + (J.transposed() dot J * (weight dot ones(ShapeND(intArrayOf(1, Npar))))).as2D() + val JtWdy = (J.transposed() dot weight * deltaY).as2D() - return arrayOf(JtWJ,JtWdy,chiSq,yHat,J) + return arrayOf(JtWJ, JtWdy, chiSq, yHat, J) } -private fun lmBroydenJ(pOld: MutableStructure2D<Double>, yOld: MutableStructure2D<Double>, JInput: MutableStructure2D<Double>, - p: MutableStructure2D<Double>, y: MutableStructure2D<Double>): MutableStructure2D<Double> { +private fun lmBroydenJ( + pOld: MutableStructure2D<Double>, yOld: MutableStructure2D<Double>, JInput: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, y: MutableStructure2D<Double>, +): MutableStructure2D<Double> = with(DoubleTensorAlgebra) { var J = JInput.copyToTensor() val h = p.minus(pOld) - val increase = y.minus(yOld).minus( J.dot(h) ).dot(h.transposed()).div( (h.transposed().dot(h)).as2D()[0, 0] ) + val increase = ((y - yOld - (J dot h)) dot h.transposed()) / (h.transposed() dot h)[0, 0] J = J.plus(increase) return J.as2D() } -private fun lmFdJ(func: (MutableStructure2D<Double>, MutableStructure2D<Double>, exampleNumber: Int) -> MutableStructure2D<Double>, - t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y: MutableStructure2D<Double>, - dp: MutableStructure2D<Double>, settings: LMSettings): MutableStructure2D<Double> { +@OptIn(PerformancePitfall::class) +private fun lmFdJ( + func: (MutableStructure2D<Double>, MutableStructure2D<Double>, exampleNumber: Int) -> MutableStructure2D<Double>, + t: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, + y: MutableStructure2D<Double>, + dp: MutableStructure2D<Double>, + settings: LMSettings, +): MutableStructure2D<Double> = with(DoubleTensorAlgebra) { // default: dp = 0.001 * ones(1,n) val m = length(y) // number of data points val n = length(p) // number of parameters - val ps = p.copyToTensor().as2D() - val J = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, n))).as2D() // initialize Jacobian to Zero - val del = BroadcastDoubleTensorAlgebra.zeros(ShapeND(intArrayOf(n, 1))).as2D() + val ps = p.copyToTensor() + val J = zero(m, n) // initialize Jacobian to Zero + val del = zero(n, 1) for (j in 0 until n) { - del[j, 0] = dp[j, 0] * (1 + kotlin.math.abs(p[j, 0])) // parameter perturbation + del[j, 0] = dp[j, 0] * (1 + abs(p[j, 0])) // parameter perturbation p[j, 0] = ps[j, 0] + del[j, 0] // perturb parameter p(j) val epsilon = 0.0000001 - if (kotlin.math.abs(del[j, 0]) > epsilon) { + if (abs(del[j, 0]) > epsilon) { val y1 = evaluateFunction(func, t, p, settings.exampleNumber) settings.funcCalls += 1 if (dp[j, 0] < 0) { // backwards difference - for (i in 0 until J.shape.component1()) { - J[i, j] = (y1.as2D().minus(y).as2D())[i, 0] / del[j, 0] + for (i in 0 until J.shape.first()) { + J[i, j] = (y1 - y)[i, 0] / del[j, 0] } - } - else { + } else { // Do tests for it p[j, 0] = ps[j, 0] - del[j, 0] // central difference, additional func call - for (i in 0 until J.shape.component1()) { - J[i, j] = (y1.as2D().minus(evaluateFunction(func, t, p, settings.exampleNumber)).as2D())[i, 0] / (2 * del[j, 0]) + for (i in 0 until J.shape.first()) { + J[i, j] = (y1 - evaluateFunction(func, t, p, settings.exampleNumber))[i, 0] / (2 * del[j, 0]) } settings.funcCalls += 1 } diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt similarity index 52% rename from kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt rename to kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index 4b031eb11..4c039190a 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -5,77 +5,83 @@ package space.kscience.kmath.tensors.core -import space.kscience.kmath.nd.MutableStructure2D -import space.kscience.kmath.nd.ShapeND -import space.kscience.kmath.nd.as2D -import space.kscience.kmath.nd.component1 +import space.kscience.kmath.PerformancePitfall +import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.max -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.plus -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times -import kotlin.math.roundToLong +import space.kscience.kmath.structures.DoubleBuffer import kotlin.test.Test import kotlin.test.assertEquals +@PerformancePitfall class TestLmAlgorithm { companion object { - fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { + fun funcEasyForLm( + t: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, + exampleNumber: Int, + ): MutableStructure2D<Double> = with(DoubleTensorAlgebra) { val m = t.shape.component1() - var yHat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) + val yHat = when (exampleNumber) { + 1 -> exp((t * (-1.0 / p[1, 0]))) * p[0, 0] + (t * p[2, 0]) * exp((t * (-1.0 / p[3, 0]))) - if (exampleNumber == 1) { - yHat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( - DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) - ) - } - else if (exampleNumber == 2) { - val mt = t.max() - yHat = (t.times(1.0 / mt)).times(p[0, 0]) + - (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + - (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + - (t.times(1.0 / mt)).pow(4).times(p[3, 0]) - } - else if (exampleNumber == 3) { - yHat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) - .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) + 2 -> { + val mt = t.max() + (t * (1.0 / mt)) * p[0, 0] + + (t * (1.0 / mt)).pow(2) * p[1, 0] + + (t * (1.0 / mt)).pow(3) * p[2, 0] + + (t * (1.0 / mt)).pow(4) * p[3, 0] + } + + 3 -> exp(t * (-1.0 / p[1, 0])) * p[0, 0] + + sin((t * (1.0 / p[3, 0]))) * p[2, 0] + + else -> zeros(ShapeND(intArrayOf(m, 1))) } return yHat.as2D() } - fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { + fun funcMiddleForLm( + t: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, + exampleNumber: Int, + ): MutableStructure2D<Double> = with(DoubleTensorAlgebra) { val m = t.shape.component1() - var yHat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + var yHat = zeros(ShapeND(intArrayOf(m, 1))) val mt = t.max() - for(i in 0 until p.shape.component1()){ - yHat += (t.times(1.0 / mt)).times(p[i, 0]) + for (i in 0 until p.shape.component1()) { + yHat.plusAssign(t * (1.0 / mt) * p[i, 0]) } - for(i in 0 until 5){ + for (i in 0 until 5) { yHat = funcEasyForLm(yHat.as2D(), p, exampleNumber).asDoubleTensor() } return yHat.as2D() } - fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { + fun funcDifficultForLm( + t: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, + exampleNumber: Int, + ): MutableStructure2D<Double> = with(DoubleTensorAlgebra) { val m = t.shape.component1() - var yHat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + var yHat = zeros(ShapeND(intArrayOf(m, 1))) val mt = t.max() - for(i in 0 until p.shape.component1()){ - yHat = yHat.plus( (t.times(1.0 / mt)).times(p[i, 0]) ) + for (i in 0 until p.shape.component1()) { + yHat = yHat + (t * (1.0 / mt)) * p[i, 0] } - for(i in 0 until 4){ + for (i in 0 until 4) { yHat = funcEasyForLm((yHat.as2D() + t).as2D(), p, exampleNumber).asDoubleTensor() } return yHat.as2D() } } + @Test fun testLMEasy() = DoubleTensorAlgebra { val lmMatxYDat = doubleArrayOf( @@ -91,12 +97,12 @@ class TestLmAlgorithm { 14.7665, 13.3718, 15.0587, 13.8320, 14.7873, 13.6824, 14.2579, 14.2154, 13.5818, 13.8157 ) - var exampleNumber = 1 - val p_init = BroadcastDoubleTensorAlgebra.fromArray( + val exampleNumber = 1 + val pInit = fromArray( ShapeND(intArrayOf(4, 1)), doubleArrayOf(5.0, 2.0, 0.2, 10.0) ).as2D() - var t = ones(ShapeND(intArrayOf(100, 1))).as2D() + val t = ones(ShapeND(intArrayOf(100, 1))).as2D() for (i in 0 until 100) { t[i, 0] = t[i, 0] * (i + 1) } @@ -119,22 +125,26 @@ class TestLmAlgorithm { ShapeND(intArrayOf(4, 1)), doubleArrayOf(50.0, 20.0, 2.0, 100.0) ).as2D() - val inputData = LMInput(::funcEasyForLm, p_init, t, yDat, weight, dp, pMin, pMax, 100, - doubleArrayOf(1e-3, 1e-3, 1e-1, 1e-1), doubleArrayOf(1e-2, 11.0, 9.0), 1, 10, exampleNumber) + val inputData = LMInput( + Companion::funcEasyForLm, pInit, t, yDat, weight, dp, pMin, pMax, 100, + doubleArrayOf(1e-3, 1e-3, 1e-1, 1e-1), doubleArrayOf(1e-2, 11.0, 9.0), 1, 10, exampleNumber + ) val result = levenbergMarquardt(inputData) assertEquals(13, result.iterations) assertEquals(31, result.funcCalls) - assertEquals(0.9131368192633, (result.resultChiSq * 1e13).roundToLong() / 1e13) - assertEquals(3.7790980 * 1e-7, (result.resultLambda * 1e13).roundToLong() / 1e13) + assertEquals(0.9131368192633, result.resultChiSq, 1e-13) + assertEquals(3.7790980 * 1e-7, result.resultLambda, 1e-13) assertEquals(result.typeOfConvergence, TypeOfConvergence.InParameters) val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(4, 1)), doubleArrayOf(20.527230909086, 9.833627103230, 0.997571256572, 50.174445822506) ).as2D() - result.resultParameters = result.resultParameters.map { x -> (x * 1e12).toLong() / 1e12}.as2D() + result.resultParameters = result.resultParameters.map { x -> (x * 1e12).toLong() / 1e12 }.as2D() val receivedParameters = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(4, 1)), doubleArrayOf(result.resultParameters[0, 0], result.resultParameters[1, 0], - result.resultParameters[2, 0], result.resultParameters[3, 0]) + ShapeND(intArrayOf(4, 1)), doubleArrayOf( + result.resultParameters[0, 0], result.resultParameters[1, 0], + result.resultParameters[2, 0], result.resultParameters[3, 0] + ) ).as2D() assertEquals(expectedParameters[0, 0], receivedParameters[0, 0]) assertEquals(expectedParameters[1, 0], receivedParameters[1, 0]) @@ -143,25 +153,25 @@ class TestLmAlgorithm { } @Test - fun TestLMMiddle() = DoubleTensorAlgebra { - val NData = 100 - val tExample = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() - for (i in 0 until NData) { + fun testLMMiddle() = DoubleTensorAlgebra { + val nData = 100 + val tExample = one(nData, 1).as2D() + for (i in 0 until nData) { tExample[i, 0] = tExample[i, 0] * (i + 1) } - val Nparams = 20 - val pExample = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() - for (i in 0 until Nparams) { + val nParams = 20 + val pExample = one(nParams, 1).as2D() + for (i in 0 until nParams) { pExample[i, 0] = pExample[i, 0] + i - 25 } val exampleNumber = 1 - val yHat = funcMiddleForLm(tExample, pExample, exampleNumber) + val yHat = funcMiddleForLm(tExample, pExample, exampleNumber) - val pInit = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() - for (i in 0 until Nparams) { + val pInit = zeros(ShapeND(intArrayOf(nParams, 1))).as2D() + for (i in 0 until nParams) { pInit[i, 0] = (pExample[i, 0] + 0.9) } @@ -171,13 +181,14 @@ class TestLmAlgorithm { val dp = BroadcastDoubleTensorAlgebra.fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() - var pMin = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) - pMin = pMin.div(1.0 / -50.0) - val pMax = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) - pMin = pMin.div(1.0 / 50.0) + var pMin = ones(ShapeND(intArrayOf(nParams, 1))) + pMin = pMin * (-50.0) + val pMax = ones(ShapeND(intArrayOf(nParams, 1))) + pMin = pMin * 50.0 val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) - val inputData = LMInput(::funcMiddleForLm, + val inputData = LMInput( + Companion::funcMiddleForLm, pInit.as2D(), t, yDat, @@ -190,63 +201,67 @@ class TestLmAlgorithm { doubleArrayOf(opts[6], opts[7], opts[8]), opts[9].toInt(), 10, - 1) + 1 + ) val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) assertEquals(46, result.iterations) assertEquals(113, result.funcCalls) - assertEquals(0.000005977, (result.resultChiSq * 1e9).roundToLong() / 1e9) - assertEquals(1.0 * 1e-7, (result.resultLambda * 1e13).roundToLong() / 1e13) + assertEquals(0.000005977, result.resultChiSq, 1e-9) + assertEquals(1.0 * 1e-7, result.resultLambda, 1e-13) assertEquals(result.typeOfConvergence, TypeOfConvergence.InReducedChiSquare) - val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(Nparams, 1)), doubleArrayOf( -23.9717, -18.6686, -21.7971, + val expectedParameters = fromArray( + ShapeND(intArrayOf(nParams, 1)), doubleArrayOf( + -23.9717, -18.6686, -21.7971, -20.9681, -22.086, -20.5859, -19.0384, -17.4957, -15.9991, -14.576, -13.2441, - - 12.0201, -10.9256, -9.9878, -9.2309, -8.6589, -8.2365, -7.8783, -7.4598, -6.8511)).as2D() - result.resultParameters = result.resultParameters.map { x -> (x * 1e4).roundToLong() / 1e4}.as2D() - val receivedParameters = zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() - for (i in 0 until Nparams) { + 12.0201, -10.9256, -9.9878, -9.2309, -8.6589, -8.2365, -7.8783, -7.4598, -6.8511 + ) + ) + val receivedParameters = zero(nParams, 1) + for (i in 0 until nParams) { receivedParameters[i, 0] = result.resultParameters[i, 0] - assertEquals(expectedParameters[i, 0], result.resultParameters[i, 0]) + assertEquals(expectedParameters[i, 0], result.resultParameters[i, 0], 1e-2) } } @Test fun TestLMDifficult() = DoubleTensorAlgebra { - val NData = 200 - var tExample = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() - for (i in 0 until NData) { + val nData = 200 + val tExample = ones(ShapeND(intArrayOf(nData, 1))).as2D() + for (i in 0 until nData) { tExample[i, 0] = tExample[i, 0] * (i + 1) - 104 } - val Nparams = 15 - var pExample = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))).as2D() - for (i in 0 until Nparams) { + val nParams = 15 + val pExample = ones(ShapeND(intArrayOf(nParams, 1))).as2D() + for (i in 0 until nParams) { pExample[i, 0] = pExample[i, 0] + i - 25 } val exampleNumber = 1 - var yHat = funcDifficultForLm(tExample, pExample, exampleNumber) + val yHat = funcDifficultForLm(tExample, pExample, exampleNumber) - var pInit = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() - for (i in 0 until Nparams) { + val pInit = zeros(ShapeND(intArrayOf(nParams, 1))).as2D() + for (i in 0 until nParams) { pInit[i, 0] = (pExample[i, 0] + 0.9) } - var t = tExample + val t = tExample val yDat = yHat - val weight = 1.0 / Nparams * 1.0 - 0.085 - val dp = BroadcastDoubleTensorAlgebra.fromArray( + val weight = 1.0 / nParams * 1.0 - 0.085 + val dp = fromArray( ShapeND(intArrayOf(1, 1)), DoubleArray(1) { -0.01 } ).as2D() - var pMin = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) - pMin = pMin.div(1.0 / -50.0) - val pMax = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(Nparams, 1))) - pMin = pMin.div(1.0 / 50.0) + var pMin = ones(ShapeND(intArrayOf(nParams, 1))) + pMin = pMin * (-50.0) + val pMax = ones(ShapeND(intArrayOf(nParams, 1))) + pMin = pMin * (50.0) val opts = doubleArrayOf(3.0, 7000.0, 1e-2, 1e-3, 1e-2, 1e-2, 1e-2, 11.0, 9.0, 1.0) - val inputData = LMInput(::funcDifficultForLm, + val inputData = LMInput( + Companion::funcDifficultForLm, pInit.as2D(), t, yDat, @@ -259,22 +274,37 @@ class TestLmAlgorithm { doubleArrayOf(opts[6], opts[7], opts[8]), opts[9].toInt(), 10, - 1) + 1 + ) val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) assertEquals(2375, result.iterations) assertEquals(4858, result.funcCalls) - assertEquals(5.14347, (result.resultLambda * 1e5).roundToLong() / 1e5) + assertEquals(5.14347, result.resultLambda, 1e-5) assertEquals(result.typeOfConvergence, TypeOfConvergence.InParameters) - val expectedParameters = BroadcastDoubleTensorAlgebra.fromArray( - ShapeND(intArrayOf(Nparams, 1)), doubleArrayOf(-23.6412, -16.7402, -21.5705, -21.0464, - -17.2852, -17.2959, -17.298, 0.9999, -17.2885, -17.3008, -17.2941, -17.2923, -17.2976, -17.3028, -17.2891)).as2D() - result.resultParameters = result.resultParameters.map { x -> (x * 1e4).roundToLong() / 1e4}.as2D() - val receivedParameters = zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() - for (i in 0 until Nparams) { + val expectedParameters = DoubleBuffer( + -23.6412, + -16.7402, + -21.5705, + -21.0464, + -17.2852, + -17.2959, + -17.298, + 0.9999, + -17.2885, + -17.3008, + -17.2941, + -17.2923, + -17.2976, + -17.3028, + -17.2891 + ) + + val receivedParameters = zeros(ShapeND(intArrayOf(nParams, 1))).as2D() + for (i in 0 until nParams) { receivedParameters[i, 0] = result.resultParameters[i, 0] - assertEquals(expectedParameters[i, 0], result.resultParameters[i, 0]) + assertEquals(expectedParameters[i], result.resultParameters[i, 0], 1e-2) } } } \ No newline at end of file From 976714475e5a3eb2ff0175b2655ac0d794ecea71 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 28 Jul 2023 20:56:31 +0300 Subject: [PATCH 043/103] levenbergMarquardt cleanup --- .../core/LevenbergMarquardtAlgorithm.kt | 10 ++-- .../kmath/tensors/core/internal/linUtils.kt | 49 ++++++++++--------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index 72752f855..fc87ad1f3 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -120,8 +120,6 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI 0.0, inputData.startParameters, TypeOfConvergence.NoConvergence ) - val eps = 2.2204e-16 - val settings = LMSettings(0, 0, inputData.exampleNumber) settings.funcCalls = 0 // running count of function evaluations @@ -214,7 +212,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI stop = true } - var lambda = 1.0 + var lambda: Double var nu = 1 if (updateType == 1) { @@ -273,8 +271,8 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI val alpha = 1.0 if (updateType == 2) { // Quadratic // One step of quadratic line update in the h direction for minimum X2 - val alpha = (jtWdy.transpose() dot h) / ((X2Try - x2) / 2.0 + 2 * (jtWdy.transpose() dot h)) - h = h dot alpha + val alphaTensor = (jtWdy.transpose() dot h) / ((X2Try - x2) / 2.0 + 2 * (jtWdy.transpose() dot h)) + h = h dot alphaTensor pTry = (p + h).as2D() // update only [idx] elements pTry = smallestElementComparison( largestElementComparison(minParameters, pTry), @@ -388,7 +386,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI resultInfo.typeOfConvergence = TypeOfConvergence.InGradient stop = true } - if ((abs(h.as2D()).div(abs(p) + 1e-12)).max() < epsilon2 && settings.iteration > 2) { + if ((abs(h.as2D()) / (abs(p) + 1e-12)).max() < epsilon2 && settings.iteration > 2) { resultInfo.typeOfConvergence = TypeOfConvergence.InParameters stop = true } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index 086c69e49..7a96001c6 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -7,7 +7,10 @@ package space.kscience.kmath.tensors.core.internal import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.* +import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.asBuffer +import space.kscience.kmath.structures.indices import space.kscience.kmath.tensors.core.* import kotlin.math.abs import kotlin.math.max @@ -329,14 +332,16 @@ private fun SIGN(a: Double, b: Double): Double { return -abs(a) } -internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2D<Double>, w: BufferedTensor<Double>, - v: MutableStructure2D<Double>, iterations: Int, epsilon: Double) { +internal fun MutableStructure2D<Double>.svdGolubKahanHelper( + u: MutableStructure2D<Double>, w: BufferedTensor<Double>, + v: MutableStructure2D<Double>, iterations: Int, epsilon: Double, +) { val shape = this.shape val m = shape.component1() val n = shape.component2() - var f = 0.0 + var f: Double val rv1 = DoubleArray(n) - var s = 0.0 + var s: Double var scale = 0.0 var anorm = 0.0 var g = 0.0 @@ -362,10 +367,10 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2 s += this[k, i] * this[k, i] } f = this[i, i] - if (f >= 0) { - g = (-1) * abs(sqrt(s)) + g = if (f >= 0) { + -abs(sqrt(s)) } else { - g = abs(sqrt(s)) + abs(sqrt(s)) } val h = f * g - s this[i, i] = f - g @@ -402,10 +407,10 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2 s += this[i, k] * this[i, k] } f = this[i, l] - if (f >= 0) { - g = (-1) * abs(sqrt(s)) + g = if (f >= 0) { + -abs(sqrt(s)) } else { - g = abs(sqrt(s)) + abs(sqrt(s)) } val h = f * g - s this[i, l] = f - g @@ -457,7 +462,7 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2 for (i in min(n, m) - 1 downTo 0) { l = i + 1 - g = wBuffer[wStart + i] + g = wBuffer[wStart + i] for (j in l until n) { this[i, j] = 0.0 } @@ -484,13 +489,13 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2 this[i, i] += 1.0 } - var flag = 0 + var flag: Int var nm = 0 - var c = 0.0 - var h = 0.0 - var y = 0.0 - var z = 0.0 - var x = 0.0 + var c: Double + var h: Double + var y: Double + var z: Double + var x: Double for (k in n - 1 downTo 0) { for (its in 1 until iterations) { flag = 1 @@ -531,7 +536,7 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2 } } - z = wBuffer[wStart + k] + z = wBuffer[wStart + k] if (l == k) { if (z < 0.0) { wBuffer[wStart + k] = -z @@ -541,9 +546,9 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2 break } - x = wBuffer[wStart + l] + x = wBuffer[wStart + l] nm = k - 1 - y = wBuffer[wStart + nm] + y = wBuffer[wStart + nm] g = rv1[nm] h = rv1[k] f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y) @@ -552,7 +557,7 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper(u: MutableStructure2 c = 1.0 s = 1.0 - var i = 0 + var i: Int for (j in l until nm + 1) { i = j + 1 g = rv1[i] From 62f1c59d73ab26c2b1a64ea24e2ab04781d367c4 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sat, 12 Aug 2023 10:46:43 +0300 Subject: [PATCH 044/103] Fix Median statistics. Update algebra naming. Add integer fields --- .../ExpressionsInterpretersBenchmark.kt | 10 +-- .../kscience/kmath/benchmarks/DotBenchmark.kt | 14 +-- .../ExpressionsInterpretersBenchmark.kt | 10 +-- .../kmath/benchmarks/JafamaBenchmark.kt | 4 +- .../kmath/benchmarks/NDFieldBenchmark.kt | 10 +-- .../benchmarks/TensorAlgebraBenchmark.kt | 4 +- .../kmath/benchmarks/ViktorBenchmark.kt | 4 +- .../kmath/benchmarks/ViktorLogBenchmark.kt | 4 +- .../space/kscience/kmath/ast/expressions.kt | 4 +- .../kscience/kmath/ast/kotlingradSupport.kt | 8 +- .../space/kscience/kmath/ast/symjaSupport.kt | 6 +- .../kscience/kmath/functions/integrate.kt | 4 +- .../kscience/kmath/functions/interpolate.kt | 6 +- .../kmath/functions/interpolateSquare.kt | 6 +- .../kmath/operations/mixedNDOperations.kt | 4 +- .../kscience/kmath/structures/ComplexND.kt | 4 +- .../kscience/kmath/structures/NDField.kt | 10 +-- .../kmath/structures/StreamDoubleFieldND.kt | 24 +++--- .../kscience/kmath/structures/buffers.kt | 4 +- .../TestCompilerConsistencyWithInterpreter.kt | 12 +-- .../kmath/ast/TestCompilerOperations.kt | 26 +++--- .../kmath/ast/TestCompilerVariables.kt | 12 +-- .../space/kscience/kmath/ast/TestFolding.kt | 16 ++-- .../space/kscience/kmath/ast/TestParser.kt | 4 +- .../kmath/ast/TestParserPrecedence.kt | 4 +- .../kotlin/space/kscience/kmath/ast/utils.kt | 16 ++-- .../kmath/wasm/internal/WasmBuilder.kt | 4 +- .../kotlin/space/kscience/kmath/wasm/wasm.kt | 16 ++-- .../kotlin/space/kscience/kmath/ast/utils.kt | 20 ++--- .../kscience/kmath/wasm/TestWasmSpecific.kt | 12 +-- .../kotlin/space/kscience/kmath/asm/asm.kt | 24 +++--- .../kmath/asm/internal/PrimitiveAsmBuilder.kt | 6 +- .../kotlin/space/kscience/kmath/ast/utils.kt | 20 ++--- .../kscience/kmath/commons/linear/CMMatrix.kt | 14 +-- .../commons/integration/IntegrationTest.kt | 2 +- .../commons/optimization/OptimizeTest.kt | 4 +- .../kscience/kmath/expressions/DSAlgebra.kt | 2 +- .../FunctionalExpressionAlgebra.kt | 4 +- .../kmath/linear/DoubleLinearSpace.kt | 16 ++-- .../kscience/kmath/linear/LupDecomposition.kt | 4 +- .../space/kscience/kmath/misc/sorting.kt | 9 ++ .../space/kscience/kmath/nd/DoubleFieldND.kt | 22 ++--- .../space/kscience/kmath/nd/IntRingND.kt | 10 +-- .../space/kscience/kmath/nd/ShortRingND.kt | 8 +- .../kmath/operations/BufferAlgebra.kt | 8 +- .../kmath/operations/DoubleBufferOps.kt | 16 ++-- .../kmath/operations/integerFields.kt | 85 +++++++++++++++++++ .../kscience/kmath/operations/numbers.kt | 33 ++++--- .../kscience/kmath/structures/BufferView.kt | 6 ++ .../kscience/kmath/expressions/DSTest.kt | 8 +- .../kmath/expressions/ExpressionFieldTest.kt | 8 +- .../kmath/expressions/InterpretTest.kt | 4 +- .../kmath/expressions/SimpleAutoDiffTest.kt | 20 ++--- .../kscience/kmath/nd/NdOperationsTest.kt | 4 +- .../kmath/operations/DoubleFieldTest.kt | 6 +- .../kscience/kmath/structures/NDFieldTest.kt | 6 +- .../kmath/structures/NumberNDFieldTest.kt | 6 +- .../kscience/kmath/dimensions/Wrappers.kt | 8 +- .../space/kscience/kmath/ejml/_generated.kt | 46 +++++----- .../space/kscience/kmath/real/RealMatrix.kt | 6 +- .../space/kscience/kmath/real/realND.kt | 6 +- .../kmath/integration/SimpsonIntegrator.kt | 4 +- .../kmath/integration/SplineIntegrator.kt | 6 +- .../kmath/interpolation/SplineInterpolator.kt | 4 +- .../kmath/integration/GaussIntegralTest.kt | 6 +- .../kmath/integration/SimpsonIntegralTest.kt | 6 +- .../kmath/integration/SplineIntegralTest.kt | 8 +- .../interpolation/LinearInterpolatorTest.kt | 4 +- .../interpolation/SplineInterpolatorTest.kt | 4 +- .../kscience/kmath/geometry/rotations3D.kt | 6 +- .../space/kscience/kmath/histogram/Counter.kt | 4 +- .../histogram/UniformHistogramGroupND.kt | 4 +- .../kmath/histogram/UniformHistogram1DTest.kt | 12 +-- .../kmath/histogram/TreeHistogramTest.kt | 4 +- .../kmath/kotlingrad/AdaptingTests.kt | 28 +++--- .../kmath/multik/MultikDoubleAlgebra.kt | 6 +- .../kmath/multik/MultikFloatAlgebra.kt | 6 +- .../kscience/kmath/multik/MultikIntAlgebra.kt | 6 +- .../kmath/multik/MultikLongAlgebra.kt | 6 +- .../kmath/multik/MultikShortAlgebra.kt | 6 +- .../kscience/kmath/multik/MultikNDTest.kt | 4 +- .../kscience/kmath/nd4j/Nd4jArrayAlgebra.kt | 36 ++++---- .../kscience/kmath/nd4j/Nd4jTensorAlgebra.kt | 8 +- .../kmath/nd4j/Nd4jArrayAlgebraTest.kt | 12 +-- .../kmath/optimization/QowOptimizer.kt | 4 +- .../kmath/distributions/NormalDistribution.kt | 2 +- .../kmath/series/VarianceRatioTest.kt | 2 +- .../kotlin/space/kscience/kmath/stat/Mean.kt | 36 +++----- .../space/kscience/kmath/stat/Median.kt | 29 +++++-- .../space/kscience/kmath/stat/Statistic.kt | 4 +- .../kmath/stat/TestBasicStatistics.kt | 31 +++++++ .../kscience/kmath/stat/StatisticTest.kt | 8 +- .../tensorflow/DoubleTensorFlowAlgebra.kt | 12 +-- .../kmath/tensorflow/DoubleTensorFlowOps.kt | 8 +- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 33 +++---- .../kmath/tensors/core/IntTensorAlgebra.kt | 24 +++--- .../kscience/kmath/viktor/ViktorFieldOpsND.kt | 28 +++--- 97 files changed, 632 insertions(+), 482 deletions(-) create mode 100644 kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt create mode 100644 kmath-stat/src/commonTest/kotlin/space/kscience/kmath/stat/TestBasicStatistics.kt diff --git a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt index cb07e489a..a3cfce52f 100644 --- a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt +++ b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt @@ -11,7 +11,7 @@ import kotlinx.benchmark.Scope import kotlinx.benchmark.State import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.* -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.bindSymbol import space.kscience.kmath.operations.invoke import kotlin.math.sin @@ -84,7 +84,7 @@ class ExpressionsInterpretersBenchmark { private val x by symbol private const val times = 1_000_000 - private val functional = DoubleField.expression { + private val functional = Float64Field.expression { val x = bindSymbol(Symbol.x) x * number(2.0) + 2.0 / x - 16.0 / sin(x) } @@ -93,10 +93,10 @@ class ExpressionsInterpretersBenchmark { x * 2.0 + number(2.0) / x - number(16.0) / sin(x) } - private val mst = node.toExpression(DoubleField) + private val mst = node.toExpression(Float64Field) @OptIn(UnstableKMathAPI::class) - private val wasm = node.wasmCompileToExpression(DoubleField) - private val estree = node.estreeCompileToExpression(DoubleField) + private val wasm = node.wasmCompileToExpression(Float64Field) + private val estree = node.estreeCompileToExpression(Float64Field) private val raw = Expression<Double> { args -> val x = args[x]!! diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt index 7cbe83113..5784c32b1 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt @@ -13,7 +13,7 @@ import space.kscience.kmath.commons.linear.CMLinearSpace import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM import space.kscience.kmath.linear.invoke import space.kscience.kmath.linear.linearSpace -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.tensorflow.produceWithTF import space.kscience.kmath.tensors.core.DoubleTensorAlgebra @@ -27,10 +27,10 @@ internal class DotBenchmark { const val dim = 1000 //creating invertible matrix - val matrix1 = DoubleField.linearSpace.buildMatrix(dim, dim) { _, _ -> + val matrix1 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ -> random.nextDouble() } - val matrix2 = DoubleField.linearSpace.buildMatrix(dim, dim) { _, _ -> + val matrix2 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ -> random.nextDouble() } @@ -45,7 +45,7 @@ internal class DotBenchmark { @Benchmark fun tfDot(blackhole: Blackhole) { blackhole.consume( - DoubleField.produceWithTF { + Float64Field.produceWithTF { matrix1 dot matrix1 } ) @@ -72,7 +72,7 @@ internal class DotBenchmark { } @Benchmark - fun tensorDot(blackhole: Blackhole) = with(DoubleField.tensorAlgebra) { + fun tensorDot(blackhole: Blackhole) = with(Float64Field.tensorAlgebra) { blackhole.consume(matrix1 dot matrix2) } @@ -82,12 +82,12 @@ internal class DotBenchmark { } @Benchmark - fun bufferedDot(blackhole: Blackhole) = with(DoubleField.linearSpace) { + fun bufferedDot(blackhole: Blackhole) = with(Float64Field.linearSpace) { blackhole.consume(matrix1 dot matrix2) } @Benchmark - fun doubleDot(blackhole: Blackhole) = with(DoubleField.linearSpace) { + fun doubleDot(blackhole: Blackhole) = with(Float64Field.linearSpace) { blackhole.consume(matrix1 dot matrix2) } diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt index 4df5f372f..def90ba22 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt @@ -12,7 +12,7 @@ import kotlinx.benchmark.State import space.kscience.kmath.asm.compileToExpression import space.kscience.kmath.expressions.* import space.kscience.kmath.operations.Algebra -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.bindSymbol import space.kscience.kmath.operations.invoke import kotlin.math.sin @@ -100,7 +100,7 @@ internal class ExpressionsInterpretersBenchmark { private val x by symbol private const val times = 1_000_000 - private val functional = DoubleField.expression { + private val functional = Float64Field.expression { val x = bindSymbol(Symbol.x) x * number(2.0) + 2.0 / x - 16.0 / sin(x) } @@ -109,12 +109,12 @@ internal class ExpressionsInterpretersBenchmark { x * 2.0 + number(2.0) / x - number(16.0) / sin(x) } - private val mst = node.toExpression(DoubleField) + private val mst = node.toExpression(Float64Field) - private val asmPrimitive = node.compileToExpression(DoubleField) + private val asmPrimitive = node.compileToExpression(Float64Field) private val xIdx = asmPrimitive.indexer.indexOf(x) - private val asmGeneric = node.compileToExpression(DoubleField as Algebra<Double>) + private val asmGeneric = node.compileToExpression(Float64Field as Algebra<Double>) private val raw = Expression<Double> { args -> val x = args[x]!! diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt index 041f7e92a..355f54c65 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt @@ -11,7 +11,7 @@ import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.State import space.kscience.kmath.jafama.JafamaDoubleField import space.kscience.kmath.jafama.StrictJafamaDoubleField -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -26,7 +26,7 @@ internal class JafamaBenchmark { @Benchmark fun core(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x -> - DoubleField { x * power(x, 4) * exp(x) / cos(x) + sin(x) } + Float64Field { x * power(x, 4) * exp(x) / cos(x) + sin(x) } } @Benchmark diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt index fb8d845e8..ec7f940a0 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt @@ -16,7 +16,7 @@ import org.jetbrains.kotlinx.multik.ndarray.data.DataType import space.kscience.kmath.UnsafeKMathAPI import space.kscience.kmath.nd.* import space.kscience.kmath.nd4j.nd4j -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.tensors.core.DoubleTensor import space.kscience.kmath.tensors.core.one import space.kscience.kmath.tensors.core.tensorAlgebra @@ -86,9 +86,9 @@ internal class NDFieldBenchmark { private const val dim = 1000 private const val n = 100 private val shape = ShapeND(dim, dim) - private val specializedField = DoubleField.ndAlgebra - private val genericField = BufferedFieldOpsND(DoubleField) - private val nd4jField = DoubleField.nd4j - private val viktorField = DoubleField.viktorAlgebra + private val specializedField = Float64Field.ndAlgebra + private val genericField = BufferedFieldOpsND(Float64Field) + private val nd4jField = Float64Field.nd4j + private val viktorField = Float64Field.viktorAlgebra } } diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt index c4382374a..8bdb101f6 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt @@ -12,7 +12,7 @@ import kotlinx.benchmark.State import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.matrix import space.kscience.kmath.linear.symmetric -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.tensors.core.symEigJacobi import space.kscience.kmath.tensors.core.symEigSvd import space.kscience.kmath.tensors.core.tensorAlgebra @@ -24,7 +24,7 @@ internal class TensorAlgebraBenchmark { private val random = Random(12224) private const val dim = 30 - private val matrix = DoubleField.linearSpace.matrix(dim, dim).symmetric { _, _ -> random.nextDouble() } + private val matrix = Float64Field.linearSpace.matrix(dim, dim).symmetric { _, _ -> random.nextDouble() } } @Benchmark diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt index 90f3cb765..b424491f6 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt @@ -14,7 +14,7 @@ import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.one -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.viktor.ViktorFieldND @State(Scope.Benchmark) @@ -52,7 +52,7 @@ internal class ViktorBenchmark { private val shape = ShapeND(dim, dim) // automatically build context most suited for given type. - private val doubleField = DoubleField.ndAlgebra + private val doubleField = Float64Field.ndAlgebra private val viktorField = ViktorFieldND(dim, dim) } } diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt index 4ec4605ed..b6a485821 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt @@ -13,7 +13,7 @@ import org.jetbrains.bio.viktor.F64Array import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.one -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.viktor.ViktorFieldND @State(Scope.Benchmark) @@ -52,7 +52,7 @@ internal class ViktorLogBenchmark { private val shape = ShapeND(dim, dim) // automatically build context most suited for given type. - private val doubleField = DoubleField.ndAlgebra + private val doubleField = Float64Field.ndAlgebra private val viktorField = ViktorFieldND(dim, dim) } } diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt index cacb6683e..784fed63e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt @@ -8,13 +8,13 @@ package space.kscience.kmath.ast import space.kscience.kmath.asm.compileToExpression import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.Symbol.Companion.x -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke fun main() { val expr = MstExtendedField { x * 2.0 + number(2.0) / x - number(16.0) + asinh(x) / sin(x) - }.compileToExpression(DoubleField) + }.compileToExpression(Float64Field) val m = DoubleArray(expr.indexer.symbols.size) val xIdx = expr.indexer.indexOf(x) diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt index b443e639d..f7b169e0b 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt @@ -5,12 +5,12 @@ package space.kscience.kmath.ast +import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.derivative import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.toExpression import space.kscience.kmath.kotlingrad.toKotlingradExpression -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field /** * In this example, *x<sup>2</sup> − 4 x − 44* function is differentiated with Kotlin∇, and the @@ -19,9 +19,9 @@ import space.kscience.kmath.operations.DoubleField fun main() { val actualDerivative = "x^2-4*x-44" .parseMath() - .toKotlingradExpression(DoubleField) + .toKotlingradExpression(Float64Field) .derivative(x) - val expectedDerivative = "2*x-4".parseMath().toExpression(DoubleField) + val expectedDerivative = "2*x-4".parseMath().toExpression(Float64Field) check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0)) } diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/symjaSupport.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/symjaSupport.kt index 92ee1781b..9a4300f82 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/symjaSupport.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/symjaSupport.kt @@ -9,7 +9,7 @@ import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.derivative import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.toExpression -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.symja.toSymjaExpression /** @@ -19,9 +19,9 @@ import space.kscience.kmath.symja.toSymjaExpression fun main() { val actualDerivative = "x^2-4*x-44" .parseMath() - .toSymjaExpression(DoubleField) + .toSymjaExpression(Float64Field) .derivative(x) - val expectedDerivative = "2*x-4".parseMath().toExpression(DoubleField) + val expectedDerivative = "2*x-4".parseMath().toExpression(Float64Field) check(actualDerivative(x to 123.0) == expectedDerivative(x to 123.0)) } diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt index e8534d002..493a89387 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt @@ -13,7 +13,7 @@ import space.kscience.kmath.complex.algebra import space.kscience.kmath.integration.gaussIntegrator import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.value -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.math.pow fun main() { @@ -21,7 +21,7 @@ fun main() { val function: Function1D<Double> = { x -> 3 * x.pow(2) + 2 * x + 1 } //get the result of the integration - val result = DoubleField.gaussIntegrator.integrate(0.0..10.0, function = function) + val result = Float64Field.gaussIntegrator.integrate(0.0..10.0, function = function) //the value is nullable because in some cases the integration could not succeed println(result.value) diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt index b4ce6ad2d..9bde80a87 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.functions import space.kscience.kmath.interpolation.SplineInterpolator import space.kscience.kmath.interpolation.interpolatePolynomials -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.DoubleBuffer import space.kscience.plotly.Plotly import space.kscience.plotly.UnstablePlotlyAPI @@ -25,10 +25,10 @@ fun main() { } val polynomial: PiecewisePolynomial<Double> = SplineInterpolator( - DoubleField, ::DoubleBuffer + Float64Field, ::DoubleBuffer ).interpolatePolynomials(data) - val function = polynomial.asFunction(DoubleField, 0.0) + val function = polynomial.asFunction(Float64Field, 0.0) val cmInterpolate = org.apache.commons.math3.analysis.interpolation.SplineInterpolator().interpolate( data.map { it.first }.toDoubleArray(), diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolateSquare.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolateSquare.kt index 7bcd96990..e621cda08 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolateSquare.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolateSquare.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.functions import space.kscience.kmath.interpolation.interpolatePolynomials import space.kscience.kmath.interpolation.splineInterpolator -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.real.map import space.kscience.kmath.real.step import space.kscience.plotly.Plotly @@ -28,9 +28,9 @@ fun main() { val xs = 0.0..100.0 step 0.5 val ys = xs.map(function) - val polynomial: PiecewisePolynomial<Double> = DoubleField.splineInterpolator.interpolatePolynomials(xs, ys) + val polynomial: PiecewisePolynomial<Double> = Float64Field.splineInterpolator.interpolatePolynomials(xs, ys) - val polyFunction = polynomial.asFunction(DoubleField, 0.0) + val polyFunction = polynomial.asFunction(Float64Field, 0.0) Plotly.plot { scatter { diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt index 4a5d783e1..6094d4d4a 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt @@ -15,13 +15,13 @@ import space.kscience.kmath.viktor.ViktorStructureND import space.kscience.kmath.viktor.viktorAlgebra fun main() { - val viktorStructure: ViktorStructureND = DoubleField.viktorAlgebra.structureND(ShapeND(2, 2)) { (i, j) -> + val viktorStructure: ViktorStructureND = Float64Field.viktorAlgebra.structureND(ShapeND(2, 2)) { (i, j) -> if (i == j) 2.0 else 0.0 } val cmMatrix: Structure2D<Double> = CMLinearSpace.matrix(2, 2)(0.0, 1.0, 0.0, 3.0) - val res: DoubleBufferND = DoubleField.ndAlgebra { + val res: DoubleBufferND = Float64Field.ndAlgebra { exp(viktorStructure) + 2.0 * cmMatrix } diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt index 86d7c0d89..f71f248d9 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt @@ -13,7 +13,7 @@ import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.as2D import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.structureND -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import kotlin.system.measureTimeMillis @@ -21,7 +21,7 @@ fun main() { val dim = 1000 val n = 1000 - val realField = DoubleField.ndAlgebra(dim, dim) + val realField = Float64Field.ndAlgebra(dim, dim) val complexField: ComplexFieldND = ComplexField.ndAlgebra(dim, dim) val realTime = measureTimeMillis { diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt index ba8f047a8..375d4e182 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt @@ -10,7 +10,7 @@ import kotlinx.coroutines.GlobalScope import org.nd4j.linalg.factory.Nd4j import space.kscience.kmath.nd.* import space.kscience.kmath.nd4j.nd4j -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.viktor.ViktorFieldND import kotlin.contracts.InvocationKind @@ -33,15 +33,15 @@ fun main() { // specialized nd-field for Double. It works as generic Double field as well. - val doubleField = DoubleField.ndAlgebra + val doubleField = Float64Field.ndAlgebra //A generic field. It should be used for objects, not primitives. - val genericField = BufferedFieldOpsND(DoubleField) + val genericField = BufferedFieldOpsND(Float64Field) // Nd4j specialized field. - val nd4jField = DoubleField.nd4j + val nd4jField = Float64Field.nd4j //viktor field val viktorField = ViktorFieldND(dim, dim) //parallel processing based on Java Streams - val parallelField = DoubleField.ndStreaming(dim, dim) + val parallelField = Float64Field.ndStreaming(dim, dim) measureAndPrint("Boxing addition") { genericField { diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt index 2ce2c21a6..e46e50821 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt @@ -7,8 +7,8 @@ package space.kscience.kmath.structures import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.ExtendedField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.NumbersAddOps import java.util.* import java.util.stream.IntStream @@ -17,12 +17,12 @@ import java.util.stream.IntStream * A demonstration implementation of NDField over Real using Java [java.util.stream.DoubleStream] for parallel * execution. */ -class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleField>, +class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>>, ExtendedField<StructureND<Double>> { private val strides = ColumnStrides(shape) - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field override val zero: BufferND<Double> by lazy { structureND(shape) { zero } } override val one: BufferND<Double> by lazy { structureND(shape) { one } } @@ -43,10 +43,10 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) } } - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): BufferND<Double> { + override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): BufferND<Double> { val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> val index = strides.index(offset) - DoubleField.initializer(index) + Float64Field.initializer(index) }.toArray() return BufferND(strides, array.asBuffer()) @@ -54,18 +54,18 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF @OptIn(PerformancePitfall::class) override fun StructureND<Double>.map( - transform: DoubleField.(Double) -> Double, + transform: Float64Field.(Double) -> Double, ): BufferND<Double> { - val array = Arrays.stream(buffer.array).parallel().map { DoubleField.transform(it) }.toArray() + val array = Arrays.stream(buffer.array).parallel().map { Float64Field.transform(it) }.toArray() return BufferND(strides, array.asBuffer()) } @OptIn(PerformancePitfall::class) override fun StructureND<Double>.mapIndexed( - transform: DoubleField.(index: IntArray, Double) -> Double, + transform: Float64Field.(index: IntArray, Double) -> Double, ): BufferND<Double> { val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> - DoubleField.transform( + Float64Field.transform( strides.index(offset), buffer.array[offset] ) @@ -78,10 +78,10 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF override fun zip( left: StructureND<Double>, right: StructureND<Double>, - transform: DoubleField.(Double, Double) -> Double, + transform: Float64Field.(Double, Double) -> Double, ): BufferND<Double> { val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> - DoubleField.transform(left.buffer.array[offset], right.buffer.array[offset]) + Float64Field.transform(left.buffer.array[offset], right.buffer.array[offset]) }.toArray() return BufferND(strides, array.asBuffer()) } @@ -111,4 +111,4 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, DoubleF override fun atanh(arg: StructureND<Double>): BufferND<Double> = arg.map { atanh(it) } } -fun DoubleField.ndStreaming(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(ShapeND(shape)) +fun Float64Field.ndStreaming(vararg shape: Int): StreamDoubleFieldND = StreamDoubleFieldND(ShapeND(shape)) diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt index 2ac0dc6a4..8785fa6f2 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.structures -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.buffer import space.kscience.kmath.operations.bufferAlgebra import space.kscience.kmath.operations.withSize @@ -17,7 +17,7 @@ inline fun <reified R : Any> MutableBuffer.Companion.same( fun main() { - with(DoubleField.bufferAlgebra.withSize(5)) { + with(Float64Field.bufferAlgebra.withSize(5)) { println(number(2.0) + buffer(1, 2, 3, 4, 5)) } } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt index 3400db0f8..77f6a191d 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt @@ -9,8 +9,8 @@ import space.kscience.kmath.expressions.MstField import space.kscience.kmath.expressions.MstRing import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.interpret -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals @@ -32,8 +32,8 @@ internal class TestCompilerConsistencyWithInterpreter { } assertEquals( - mst.interpret(IntRing, x to 3), - mst.compile(IntRing, x to 3), + mst.interpret(Int32Ring, x to 3), + mst.compile(Int32Ring, x to 3), ) } @@ -48,8 +48,8 @@ internal class TestCompilerConsistencyWithInterpreter { } assertEquals( - mst.interpret(DoubleField, x to 2.0), - mst.compile(DoubleField, x to 2.0), + mst.interpret(Float64Field, x to 2.0), + mst.compile(Float64Field, x to 2.0), ) } } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt index bf56b80a6..30bb7291d 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.ast import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals @@ -16,73 +16,73 @@ import kotlin.test.assertEquals internal class TestCompilerOperations { @Test fun testUnaryPlus() = runCompilerTest { - val expr = MstExtendedField { +x }.compileToExpression(DoubleField) + val expr = MstExtendedField { +x }.compileToExpression(Float64Field) assertEquals(2.0, expr(x to 2.0)) } @Test fun testUnaryMinus() = runCompilerTest { - val expr = MstExtendedField { -x }.compileToExpression(DoubleField) + val expr = MstExtendedField { -x }.compileToExpression(Float64Field) assertEquals(-2.0, expr(x to 2.0)) } @Test fun testAdd() = runCompilerTest { - val expr = MstExtendedField { x + x }.compileToExpression(DoubleField) + val expr = MstExtendedField { x + x }.compileToExpression(Float64Field) assertEquals(4.0, expr(x to 2.0)) } @Test fun testSine() = runCompilerTest { - val expr = MstExtendedField { sin(x) }.compileToExpression(DoubleField) + val expr = MstExtendedField { sin(x) }.compileToExpression(Float64Field) assertEquals(0.0, expr(x to 0.0)) } @Test fun testCosine() = runCompilerTest { - val expr = MstExtendedField { cos(x) }.compileToExpression(DoubleField) + val expr = MstExtendedField { cos(x) }.compileToExpression(Float64Field) assertEquals(1.0, expr(x to 0.0)) } @Test fun testTangent() = runCompilerTest { - val expr = MstExtendedField { tan(x) }.compileToExpression(DoubleField) + val expr = MstExtendedField { tan(x) }.compileToExpression(Float64Field) assertEquals(0.0, expr(x to 0.0)) } @Test fun testArcSine() = runCompilerTest { - val expr = MstExtendedField { asin(x) }.compileToExpression(DoubleField) + val expr = MstExtendedField { asin(x) }.compileToExpression(Float64Field) assertEquals(0.0, expr(x to 0.0)) } @Test fun testArcCosine() = runCompilerTest { - val expr = MstExtendedField { acos(x) }.compileToExpression(DoubleField) + val expr = MstExtendedField { acos(x) }.compileToExpression(Float64Field) assertEquals(0.0, expr(x to 1.0)) } @Test fun testAreaHyperbolicSine() = runCompilerTest { - val expr = MstExtendedField { asinh(x) }.compileToExpression(DoubleField) + val expr = MstExtendedField { asinh(x) }.compileToExpression(Float64Field) assertEquals(0.0, expr(x to 0.0)) } @Test fun testSubtract() = runCompilerTest { - val expr = MstExtendedField { x - x }.compileToExpression(DoubleField) + val expr = MstExtendedField { x - x }.compileToExpression(Float64Field) assertEquals(0.0, expr(x to 2.0)) } @Test fun testDivide() = runCompilerTest { - val expr = MstExtendedField { x / x }.compileToExpression(DoubleField) + val expr = MstExtendedField { x / x }.compileToExpression(Float64Field) assertEquals(1.0, expr(x to 2.0)) } @Test fun testPower() = runCompilerTest { - val expr = MstExtendedField { x pow 2 }.compileToExpression(DoubleField) + val expr = MstExtendedField { x pow 2 }.compileToExpression(Float64Field) assertEquals(4.0, expr(x to 2.0)) } } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt index f23d36240..3dbdf063a 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt @@ -9,8 +9,8 @@ import space.kscience.kmath.expressions.MstRing import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.y import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals @@ -19,25 +19,25 @@ import kotlin.test.assertFailsWith internal class TestCompilerVariables { @Test fun testNoVariables() = runCompilerTest { - val expr = "0".parseMath().compileToExpression(DoubleField) + val expr = "0".parseMath().compileToExpression(Float64Field) assertEquals(0.0, expr(), 0.0001) } @Test fun testOneVariable() = runCompilerTest { - val expr = MstRing { x }.compileToExpression(IntRing) + val expr = MstRing { x }.compileToExpression(Int32Ring) assertEquals(1, expr(x to 1)) } @Test fun testTwoVariables() = runCompilerTest { - val expr = "y+x/y+x".parseMath().compileToExpression(DoubleField) + val expr = "y+x/y+x".parseMath().compileToExpression(Float64Field) assertEquals(8.0, expr(x to 4.0, y to 2.0)) } @Test fun testUndefinedVariableFails() = runCompilerTest { - val expr = MstRing { x }.compileToExpression(IntRing) + val expr = MstRing { x }.compileToExpression(Int32Ring) assertFailsWith<NoSuchElementException> { expr() } } } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt index 95b804455..d67d965ce 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt @@ -6,8 +6,8 @@ package space.kscience.kmath.ast import space.kscience.kmath.operations.ByteRing -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.operations.pi import kotlin.test.Test import kotlin.test.assertEquals @@ -17,31 +17,31 @@ internal class TestFolding { @Test fun foldUnary() = assertEquals( -1, - ("-(1)".parseMath().evaluateConstants(IntRing) as? TypedMst.Constant<Int> ?: fail()).value, + ("-(1)".parseMath().evaluateConstants(Int32Ring) as? TypedMst.Constant<Int> ?: fail()).value, ) @Test fun foldDeepUnary() = assertEquals( 1, - ("-(-(1))".parseMath().evaluateConstants(IntRing) as? TypedMst.Constant<Int> ?: fail()).value, + ("-(-(1))".parseMath().evaluateConstants(Int32Ring) as? TypedMst.Constant<Int> ?: fail()).value, ) @Test fun foldBinary() = assertEquals( 2, - ("1*2".parseMath().evaluateConstants(IntRing) as? TypedMst.Constant<Int> ?: fail()).value, + ("1*2".parseMath().evaluateConstants(Int32Ring) as? TypedMst.Constant<Int> ?: fail()).value, ) @Test fun foldDeepBinary() = assertEquals( 10, - ("1*2*5".parseMath().evaluateConstants(IntRing) as? TypedMst.Constant<Int> ?: fail()).value, + ("1*2*5".parseMath().evaluateConstants(Int32Ring) as? TypedMst.Constant<Int> ?: fail()).value, ) @Test fun foldSymbol() = assertEquals( - DoubleField.pi, - ("pi".parseMath().evaluateConstants(DoubleField) as? TypedMst.Constant<Double> ?: fail()).value, + Float64Field.pi, + ("pi".parseMath().evaluateConstants(Float64Field) as? TypedMst.Constant<Double> ?: fail()).value, ) @Test diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt index d3c203903..784dcece9 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt @@ -9,7 +9,7 @@ import space.kscience.kmath.complex.Complex import space.kscience.kmath.complex.ComplexField import space.kscience.kmath.expressions.interpret import space.kscience.kmath.operations.Algebra -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.test.Test import kotlin.test.assertEquals @@ -32,7 +32,7 @@ internal class TestParser { @Test fun evaluateMstUnary() { val mst = "sin(0)".parseMath() - val res = mst.interpret(DoubleField) + val res = mst.interpret(Float64Field) assertEquals(0.0, res) } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt index 4b3631663..504ec9bd0 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.ast import space.kscience.kmath.expressions.interpret -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.test.Test import kotlin.test.assertEquals @@ -36,6 +36,6 @@ internal class TestParserPrecedence { fun test8(): Unit = assertEquals(18.0, "2*2^3+2".parseMath().interpret(f)) private companion object { - private val f = DoubleField + private val f = Float64Field } } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt index fe035c69f..27b2f2598 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt @@ -8,17 +8,17 @@ package space.kscience.kmath.ast import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.Symbol -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring internal interface CompilerTestContext { - fun MST.compileToExpression(algebra: IntRing): Expression<Int> - fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int - fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = compile(algebra, mapOf(*arguments)) - fun MST.compileToExpression(algebra: DoubleField): Expression<Double> - fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double + fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> + fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int + fun MST.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>): Int = compile(algebra, mapOf(*arguments)) + fun MST.compileToExpression(algebra: Float64Field): Expression<Double> + fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double - fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double = + fun MST.compile(algebra: Float64Field, vararg arguments: Pair<Symbol, Double>): Double = compile(algebra, mapOf(*arguments)) } diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt index 1908f0659..4917f6f1b 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt @@ -86,7 +86,7 @@ internal sealed class WasmBuilder<T : Number, out E : Expression<T>>( @UnstableKMathAPI internal class DoubleWasmBuilder(target: TypedMst<Double>) : - WasmBuilder<Double, DoubleExpression>(f64, DoubleField, target) { + WasmBuilder<Double, DoubleExpression>(f64, Float64Field, target) { override val instance by lazy { object : DoubleExpression { override val indexer = SimpleSymbolIndexer(keys) @@ -131,7 +131,7 @@ internal class DoubleWasmBuilder(target: TypedMst<Double>) : } @UnstableKMathAPI -internal class IntWasmBuilder(target: TypedMst<Int>) : WasmBuilder<Int, IntExpression>(i32, IntRing, target) { +internal class IntWasmBuilder(target: TypedMst<Int>) : WasmBuilder<Int, IntExpression>(i32, Int32Ring, target) { override val instance by lazy { object : IntExpression { override val indexer = SimpleSymbolIndexer(keys) diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt index acb26f918..f3249adf7 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt @@ -11,8 +11,8 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.ast.TypedMst import space.kscience.kmath.ast.evaluateConstants import space.kscience.kmath.expressions.* -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.wasm.internal.DoubleWasmBuilder import space.kscience.kmath.wasm.internal.IntWasmBuilder @@ -22,7 +22,7 @@ import space.kscience.kmath.wasm.internal.IntWasmBuilder * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compileToExpression(algebra: IntRing): IntExpression { +public fun MST.compileToExpression(algebra: Int32Ring): IntExpression { val typed = evaluateConstants(algebra) return if (typed is TypedMst.Constant) object : IntExpression { @@ -39,7 +39,7 @@ public fun MST.compileToExpression(algebra: IntRing): IntExpression { * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = +public fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = compileToExpression(algebra)(arguments) @@ -49,7 +49,7 @@ public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = +public fun MST.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>): Int = compileToExpression(algebra)(*arguments) /** @@ -58,7 +58,7 @@ public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): I * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> { +public fun MST.compileToExpression(algebra: Float64Field): Expression<Double> { val typed = evaluateConstants(algebra) return if (typed is TypedMst.Constant) object : DoubleExpression { @@ -76,7 +76,7 @@ public fun MST.compileToExpression(algebra: DoubleField): Expression<Double> { * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = +public fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double = compileToExpression(algebra)(arguments) @@ -86,5 +86,5 @@ public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Do * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double = +public fun MST.compile(algebra: Float64Field, vararg arguments: Pair<Symbol, Double>): Double = compileToExpression(algebra)(*arguments) diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt index 7c397d5a0..6d826541c 100644 --- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt +++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt @@ -11,8 +11,8 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.Symbol -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring import kotlin.contracts.InvocationKind import kotlin.contracts.contract import space.kscience.kmath.estree.compile as estreeCompile @@ -21,20 +21,20 @@ import space.kscience.kmath.wasm.compile as wasmCompile import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression private object WasmCompilerTestContext : CompilerTestContext { - override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = wasmCompileToExpression(algebra) - override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = wasmCompile(algebra, arguments) - override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = wasmCompileToExpression(algebra) + override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = wasmCompileToExpression(algebra) + override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = wasmCompile(algebra, arguments) + override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = wasmCompileToExpression(algebra) - override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = + override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double = wasmCompile(algebra, arguments) } private object ESTreeCompilerTestContext : CompilerTestContext { - override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = estreeCompileToExpression(algebra) - override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = estreeCompile(algebra, arguments) - override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = estreeCompileToExpression(algebra) + override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = estreeCompileToExpression(algebra) + override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = estreeCompile(algebra, arguments) + override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = estreeCompileToExpression(algebra) - override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = + override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double = estreeCompile(algebra, arguments) } diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt index 132f9f1bd..c7e898713 100644 --- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt +++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt @@ -10,8 +10,8 @@ import space.kscience.kmath.expressions.MstExtendedField import space.kscience.kmath.expressions.MstRing import space.kscience.kmath.expressions.invoke import space.kscience.kmath.expressions.symbol -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals @@ -20,20 +20,20 @@ import kotlin.test.assertEquals internal class TestWasmSpecific { @Test fun int() { - val res = MstRing { number(100000000) + number(10000000) }.compile(IntRing) + val res = MstRing { number(100000000) + number(10000000) }.compile(Int32Ring) assertEquals(110000000, res) } @Test fun real() { - val res = MstExtendedField { number(100000000) + number(2).pow(10) }.compile(DoubleField) + val res = MstExtendedField { number(100000000) + number(2).pow(10) }.compile(Float64Field) assertEquals(100001024.0, res) } @Test fun argsPassing() { val res = MstExtendedField { y + x.pow(10) }.compile( - DoubleField, + Float64Field, x to 2.0, y to 100000000.0, ) @@ -43,7 +43,7 @@ internal class TestWasmSpecific { @Test fun powFunction() { - val expr = MstExtendedField { x.pow(1.0 / 6.0) }.compileToExpression(DoubleField) + val expr = MstExtendedField { x.pow(1.0 / 6.0) }.compileToExpression(Float64Field) assertEquals(0.9730585187140817, expr(x to 0.8488554755054833)) } diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt index 7094d0442..97fe91ee4 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt @@ -13,9 +13,9 @@ import space.kscience.kmath.ast.TypedMst import space.kscience.kmath.ast.evaluateConstants import space.kscience.kmath.expressions.* import space.kscience.kmath.operations.Algebra -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing -import space.kscience.kmath.operations.LongRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring +import space.kscience.kmath.operations.Int64Ring /** * Compiles given MST to an Expression using AST compiler. @@ -91,7 +91,7 @@ public inline fun <reified T : Any> MST.compile(algebra: Algebra<T>, vararg argu * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compileToExpression(algebra: IntRing): IntExpression { +public fun MST.compileToExpression(algebra: Int32Ring): IntExpression { val typed = evaluateConstants(algebra) return if (typed is TypedMst.Constant) object : IntExpression { @@ -108,7 +108,7 @@ public fun MST.compileToExpression(algebra: IntRing): IntExpression { * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = +public fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = compileToExpression(algebra)(arguments) /** @@ -117,7 +117,7 @@ public fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): Int = +public fun MST.compile(algebra: Int32Ring, vararg arguments: Pair<Symbol, Int>): Int = compileToExpression(algebra)(*arguments) @@ -127,7 +127,7 @@ public fun MST.compile(algebra: IntRing, vararg arguments: Pair<Symbol, Int>): I * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compileToExpression(algebra: LongRing): LongExpression { +public fun MST.compileToExpression(algebra: Int64Ring): LongExpression { val typed = evaluateConstants(algebra) return if (typed is TypedMst.Constant<Long>) object : LongExpression { @@ -144,7 +144,7 @@ public fun MST.compileToExpression(algebra: LongRing): LongExpression { * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: LongRing, arguments: Map<Symbol, Long>): Long = +public fun MST.compile(algebra: Int64Ring, arguments: Map<Symbol, Long>): Long = compileToExpression(algebra)(arguments) @@ -154,7 +154,7 @@ public fun MST.compile(algebra: LongRing, arguments: Map<Symbol, Long>): Long = * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: LongRing, vararg arguments: Pair<Symbol, Long>): Long = +public fun MST.compile(algebra: Int64Ring, vararg arguments: Pair<Symbol, Long>): Long = compileToExpression(algebra)(*arguments) @@ -164,7 +164,7 @@ public fun MST.compile(algebra: LongRing, vararg arguments: Pair<Symbol, Long>): * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compileToExpression(algebra: DoubleField): DoubleExpression { +public fun MST.compileToExpression(algebra: Float64Field): DoubleExpression { val typed = evaluateConstants(algebra) return if (typed is TypedMst.Constant) object : DoubleExpression { @@ -182,7 +182,7 @@ public fun MST.compileToExpression(algebra: DoubleField): DoubleExpression { * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = +public fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double = compileToExpression(algebra)(arguments) /** @@ -191,5 +191,5 @@ public fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Do * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compile(algebra: DoubleField, vararg arguments: Pair<Symbol, Double>): Double = +public fun MST.compile(algebra: Float64Field, vararg arguments: Pair<Symbol, Double>): Double = compileToExpression(algebra)(*arguments) diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt index a3e5b7522..bb8143206 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt @@ -382,7 +382,7 @@ internal sealed class PrimitiveAsmBuilder<T : Number, out E : Expression<T>>( @UnstableKMathAPI internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder<Double, DoubleExpression>( - DoubleField, + Float64Field, java.lang.Double::class.java, java.lang.Double.TYPE, DoubleExpression::class.java, @@ -457,7 +457,7 @@ internal class DoubleAsmBuilder(target: TypedMst<Double>) : PrimitiveAsmBuilder< @UnstableKMathAPI internal class IntAsmBuilder(target: TypedMst<Int>) : PrimitiveAsmBuilder<Int, IntExpression>( - IntRing, + Int32Ring, Integer::class.java, Integer.TYPE, IntExpression::class.java, @@ -487,7 +487,7 @@ internal class IntAsmBuilder(target: TypedMst<Int>) : @UnstableKMathAPI internal class LongAsmBuilder(target: TypedMst<Long>) : PrimitiveAsmBuilder<Long, LongExpression>( - LongRing, + Int64Ring, java.lang.Long::class.java, java.lang.Long.TYPE, LongExpression::class.java, diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt index be890273d..e04e2e5bd 100644 --- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt +++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt @@ -10,34 +10,34 @@ import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.MST import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.operations.Algebra -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring import kotlin.contracts.InvocationKind import kotlin.contracts.contract import space.kscience.kmath.asm.compile as asmCompile import space.kscience.kmath.asm.compileToExpression as asmCompileToExpression private object GenericAsmCompilerTestContext : CompilerTestContext { - override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = + override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = asmCompileToExpression(algebra as Algebra<Int>) - override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = + override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = asmCompile(algebra as Algebra<Int>, arguments) - override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = + override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = asmCompileToExpression(algebra as Algebra<Double>) - override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = + override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double = asmCompile(algebra as Algebra<Double>, arguments) } @OptIn(UnstableKMathAPI::class) private object PrimitiveAsmCompilerTestContext : CompilerTestContext { - override fun MST.compileToExpression(algebra: IntRing): Expression<Int> = asmCompileToExpression(algebra) - override fun MST.compile(algebra: IntRing, arguments: Map<Symbol, Int>): Int = asmCompile(algebra, arguments) - override fun MST.compileToExpression(algebra: DoubleField): Expression<Double> = asmCompileToExpression(algebra) + override fun MST.compileToExpression(algebra: Int32Ring): Expression<Int> = asmCompileToExpression(algebra) + override fun MST.compile(algebra: Int32Ring, arguments: Map<Symbol, Int>): Int = asmCompile(algebra, arguments) + override fun MST.compileToExpression(algebra: Float64Field): Expression<Double> = asmCompileToExpression(algebra) - override fun MST.compile(algebra: DoubleField, arguments: Map<Symbol, Double>): Double = + override fun MST.compile(algebra: Float64Field, arguments: Map<Symbol, Double>): Double = asmCompile(algebra, arguments) } diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index d19bd1be0..449aa79ce 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -9,7 +9,7 @@ import org.apache.commons.math3.linear.* import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.DoubleBuffer import kotlin.reflect.KClass @@ -35,15 +35,15 @@ public value class CMVector(public val origin: RealVector) : Point<Double> { public fun RealVector.toPoint(): CMVector = CMVector(this) -public object CMLinearSpace : LinearSpace<Double, DoubleField> { - override val elementAlgebra: DoubleField get() = DoubleField +public object CMLinearSpace : LinearSpace<Double, Float64Field> { + override val elementAlgebra: Float64Field get() = Float64Field override fun buildMatrix( rows: Int, columns: Int, - initializer: DoubleField.(i: Int, j: Int) -> Double, + initializer: Float64Field.(i: Int, j: Int) -> Double, ): CMMatrix { - val array = Array(rows) { i -> DoubleArray(columns) { j -> DoubleField.initializer(i, j) } } + val array = Array(rows) { i -> DoubleArray(columns) { j -> Float64Field.initializer(i, j) } } return CMMatrix(Array2DRowRealMatrix(array)) } @@ -65,8 +65,8 @@ public object CMLinearSpace : LinearSpace<Double, DoubleField> { internal fun RealMatrix.wrap(): CMMatrix = CMMatrix(this) internal fun RealVector.wrap(): CMVector = CMVector(this) - override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): Point<Double> = - ArrayRealVector(DoubleArray(size) { DoubleField.initializer(it) }).wrap() + override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Point<Double> = + ArrayRealVector(DoubleArray(size) { Float64Field.initializer(it) }).wrap() override fun Matrix<Double>.plus(other: Matrix<Double>): CMMatrix = toCM().origin.add(other.toCM().origin).wrap() diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt index 6541736ce..9a249b29b 100644 --- a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt +++ b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.value -import space.kscience.kmath.operations.DoubleField.sin +import space.kscience.kmath.operations.Float64Field.sin import kotlin.math.PI import kotlin.math.abs import kotlin.test.assertTrue diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt index d2e86bb40..bf687aa72 100644 --- a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt +++ b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt @@ -14,7 +14,7 @@ import space.kscience.kmath.expressions.Symbol.Companion.y import space.kscience.kmath.expressions.autodiff import space.kscience.kmath.expressions.symbol import space.kscience.kmath.operations.DoubleBufferOps.Companion.map -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.optimization.* import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.stat.chiSquaredExpression @@ -24,7 +24,7 @@ import kotlin.test.Test @OptIn(UnstableKMathAPI::class) internal class OptimizeTest { - val normal = DSFieldExpression(DoubleField) { + val normal = DSFieldExpression(Float64Field) { exp(-bindSymbol(x).pow(2) / 2) + exp(-bindSymbol(y).pow(2) / 2) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt index 8c7cb0cf1..192509993 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt @@ -464,4 +464,4 @@ public class DSFieldProcessor<T, A : ExtendedField<T>>( } @UnstableKMathAPI -public val Double.Companion.autodiff: DSFieldProcessor<Double, DoubleField> get() = DSFieldProcessor(DoubleField) \ No newline at end of file +public val Double.Companion.autodiff: DSFieldProcessor<Double, Float64Field> get() = DSFieldProcessor(Float64Field) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt index 1054d1aa1..8e37f3d32 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -191,6 +191,6 @@ public inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField( block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>, ): Expression<T> = FunctionalExpressionExtendedField(this).block() -public inline fun DoubleField.expression( - block: FunctionalExpressionExtendedField<Double, DoubleField>.() -> Expression<Double>, +public inline fun Float64Field.expression( + block: FunctionalExpressionExtendedField<Double, Float64Field>.() -> Expression<Double>, ): Expression<Double> = FunctionalExpressionExtendedField(this).block() diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt index 940af4a86..4f631336c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt @@ -8,25 +8,25 @@ package space.kscience.kmath.linear import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* import space.kscience.kmath.operations.DoubleBufferOps -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.DoubleBuffer -public object DoubleLinearSpace : LinearSpace<Double, DoubleField> { +public object DoubleLinearSpace : LinearSpace<Double, Float64Field> { - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field override fun buildMatrix( rows: Int, columns: Int, - initializer: DoubleField.(i: Int, j: Int) -> Double + initializer: Float64Field.(i: Int, j: Int) -> Double ): Matrix<Double> = DoubleFieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) -> - DoubleField.initializer(i, j) + Float64Field.initializer(i, j) }.as2D() - override fun buildVector(size: Int, initializer: DoubleField.(Int) -> Double): DoubleBuffer = - DoubleBuffer(size) { DoubleField.initializer(it) } + override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): DoubleBuffer = + DoubleBuffer(size) { Float64Field.initializer(it) } override fun Matrix<Double>.unaryMinus(): Matrix<Double> = DoubleFieldOpsND { asND().map { -it }.as2D() @@ -105,4 +105,4 @@ public object DoubleLinearSpace : LinearSpace<Double, DoubleField> { } -public val DoubleField.linearSpace: DoubleLinearSpace get() = DoubleLinearSpace +public val Float64Field.linearSpace: DoubleLinearSpace get() = DoubleLinearSpace diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 650e7be5c..4bb67bce9 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -155,7 +155,7 @@ public inline fun <reified T : Comparable<T>> LinearSpace<T, Field<T>>.lup( noinline checkSingular: (T) -> Boolean, ): LupDecomposition<T> = lup(MutableBuffer.Companion::auto, matrix, checkSingular) -public fun LinearSpace<Double, DoubleField>.lup( +public fun LinearSpace<Double, Float64Field>.lup( matrix: Matrix<Double>, singularityThreshold: Double = 1e-11, ): LupDecomposition<Double> = @@ -226,5 +226,5 @@ public fun <T : Comparable<T>, F : Field<T>> LinearSpace<T, F>.lupSolver( override fun inverse(matrix: Matrix<T>): Matrix<T> = solve(matrix, one(matrix.rowNum, matrix.colNum)) } -public fun LinearSpace<Double, DoubleField>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> = +public fun LinearSpace<Double, Float64Field>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> = lupSolver(::DoubleBuffer) { it < singularityThreshold } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt index 31b8c0037..f369f0614 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt @@ -65,6 +65,15 @@ public fun <V, C : Comparable<C>> Buffer<V>.sortedByDescending(selector: (V) -> public fun <V> Buffer<V>.indicesSortedWith(comparator: Comparator<V>): IntArray = permSortIndicesWith { i1, i2 -> comparator.compare(get(i1), get(i2)) } +/** + * Create virtual zero-copy buffer with elements sorted by [comparator] + */ +@OptIn(UnstableKMathAPI::class) +public fun <V> Buffer<V>.sortedWith(comparator: Comparator<V>): Buffer<V> { + val permutations = indicesSortedWith(comparator) + return VirtualBuffer(size) { this[permutations[it]] } +} + private fun <V> Buffer<V>.permSortIndicesWith(comparator: Comparator<Int>): IntArray { if (size < 2) return IntArray(size) { 0 } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt index 265d1eec8..2f47f0b37 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt @@ -29,7 +29,7 @@ public class DoubleBufferND( } -public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(DoubleField.bufferAlgebra), +public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, Float64Field>(Float64Field.bufferAlgebra), ScaleOperations<StructureND<Double>>, ExtendedFieldOps<StructureND<Double>> { @OptIn(PerformancePitfall::class) @@ -63,18 +63,18 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D } @OptIn(PerformancePitfall::class) - override fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): BufferND<Double> = - mapInline(toBufferND()) { DoubleField.transform(it) } + override fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): BufferND<Double> = + mapInline(toBufferND()) { Float64Field.transform(it) } @OptIn(PerformancePitfall::class) override fun zip( left: StructureND<Double>, right: StructureND<Double>, - transform: DoubleField.(Double, Double) -> Double, - ): BufferND<Double> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> DoubleField.transform(l, r) } + transform: Float64Field.(Double, Double) -> Double, + ): BufferND<Double> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> Float64Field.transform(l, r) } - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): DoubleBufferND { + override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): DoubleBufferND { val indexer = indexerBuilder(shape) return DoubleBufferND( indexer, @@ -190,7 +190,7 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, DoubleField>(D @OptIn(UnstableKMathAPI::class) public class DoubleFieldND(override val shape: ShapeND) : - DoubleFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>>, + DoubleFieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>>, ExtendedField<StructureND<Double>> { override fun power(arg: StructureND<Double>, pow: UInt): DoubleBufferND = mapInline(arg.toBufferND()) { @@ -229,16 +229,16 @@ public class DoubleFieldND(override val shape: ShapeND) : } } -public val DoubleField.ndAlgebra: DoubleFieldOpsND get() = DoubleFieldOpsND +public val Float64Field.ndAlgebra: DoubleFieldOpsND get() = DoubleFieldOpsND -public fun DoubleField.ndAlgebra(vararg shape: Int): DoubleFieldND = DoubleFieldND(ShapeND(shape)) -public fun DoubleField.ndAlgebra(shape: ShapeND): DoubleFieldND = DoubleFieldND(shape) +public fun Float64Field.ndAlgebra(vararg shape: Int): DoubleFieldND = DoubleFieldND(ShapeND(shape)) +public fun Float64Field.ndAlgebra(shape: ShapeND): DoubleFieldND = DoubleFieldND(shape) /** * Produce a context for n-dimensional operations inside this real field */ @UnstableKMathAPI -public inline fun <R> DoubleField.withNdAlgebra(vararg shape: Int, action: DoubleFieldND.() -> R): R { +public inline fun <R> Float64Field.withNdAlgebra(vararg shape: Int, action: DoubleFieldND.() -> R): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } return DoubleFieldND(ShapeND(shape)).run(action) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt index 1491950d6..4ce2b80e6 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.nd import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.operations.NumbersAddOps import space.kscience.kmath.operations.bufferAlgebra import space.kscience.kmath.structures.IntBuffer @@ -18,9 +18,9 @@ public class IntBufferND( override val buffer: IntBuffer, ) : MutableBufferND<Int>(indexes, buffer) -public sealed class IntRingOpsND : BufferedRingOpsND<Int, IntRing>(IntRing.bufferAlgebra) { +public sealed class IntRingOpsND : BufferedRingOpsND<Int, Int32Ring>(Int32Ring.bufferAlgebra) { - override fun structureND(shape: ShapeND, initializer: IntRing.(IntArray) -> Int): IntBufferND { + override fun structureND(shape: ShapeND, initializer: Int32Ring.(IntArray) -> Int): IntBufferND { val indexer = indexerBuilder(shape) return IntBufferND( indexer, @@ -36,7 +36,7 @@ public sealed class IntRingOpsND : BufferedRingOpsND<Int, IntRing>(IntRing.buffe @OptIn(UnstableKMathAPI::class) public class IntRingND( override val shape: ShapeND -) : IntRingOpsND(), RingND<Int, IntRing>, NumbersAddOps<StructureND<Int>> { +) : IntRingOpsND(), RingND<Int, Int32Ring>, NumbersAddOps<StructureND<Int>> { override fun number(value: Number): BufferND<Int> { val int = value.toInt() // minimize conversions @@ -44,7 +44,7 @@ public class IntRingND( } } -public inline fun <R> IntRing.withNdAlgebra(vararg shape: Int, action: IntRingND.() -> R): R { +public inline fun <R> Int32Ring.withNdAlgebra(vararg shape: Int, action: IntRingND.() -> R): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } return IntRingND(ShapeND(shape)).run(action) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt index 1b4647146..12f59dc72 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt @@ -6,20 +6,20 @@ package space.kscience.kmath.nd import space.kscience.kmath.UnstableKMathAPI +import space.kscience.kmath.operations.Int16Ring import space.kscience.kmath.operations.NumbersAddOps -import space.kscience.kmath.operations.ShortRing import space.kscience.kmath.operations.bufferAlgebra import kotlin.contracts.InvocationKind import kotlin.contracts.contract -public sealed class ShortRingOpsND : BufferedRingOpsND<Short, ShortRing>(ShortRing.bufferAlgebra) { +public sealed class ShortRingOpsND : BufferedRingOpsND<Short, Int16Ring>(Int16Ring.bufferAlgebra) { public companion object : ShortRingOpsND() } @OptIn(UnstableKMathAPI::class) public class ShortRingND( override val shape: ShapeND -) : ShortRingOpsND(), RingND<Short, ShortRing>, NumbersAddOps<StructureND<Short>> { +) : ShortRingOpsND(), RingND<Short, Int16Ring>, NumbersAddOps<StructureND<Short>> { override fun number(value: Number): BufferND<Short> { val short @@ -28,7 +28,7 @@ public class ShortRingND( } } -public inline fun <R> ShortRing.withNdAlgebra(vararg shape: Int, action: ShortRingND.() -> R): R { +public inline fun <R> Int16Ring.withNdAlgebra(vararg shape: Int, action: ShortRingND.() -> R): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } return ShortRingND(ShapeND(shape)).run(action) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index af0bc4d9b..0363f39d3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -142,11 +142,11 @@ public open class BufferRingOps<T, A : Ring<T>>( super<BufferAlgebra>.binaryOperationFunction(operation) } -public val IntRing.bufferAlgebra: BufferRingOps<Int, IntRing> - get() = BufferRingOps(IntRing) +public val Int32Ring.bufferAlgebra: BufferRingOps<Int, Int32Ring> + get() = BufferRingOps(Int32Ring) -public val ShortRing.bufferAlgebra: BufferRingOps<Short, ShortRing> - get() = BufferRingOps(ShortRing) +public val Int16Ring.bufferAlgebra: BufferRingOps<Short, Int16Ring> + get() = BufferRingOps(Int16Ring) public open class BufferFieldOps<T, A : Field<T>>( elementAlgebra: A, diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt index 74b41be9d..e15263bef 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt @@ -14,32 +14,32 @@ import kotlin.math.sqrt /** * [ExtendedFieldOps] over [DoubleBuffer]. */ -public abstract class DoubleBufferOps : BufferAlgebra<Double, DoubleField>, ExtendedFieldOps<Buffer<Double>>, +public abstract class DoubleBufferOps : BufferAlgebra<Double, Float64Field>, ExtendedFieldOps<Buffer<Double>>, Norm<Buffer<Double>, Double> { - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field override val elementBufferFactory: MutableBufferFactory<Double> get() = elementAlgebra.bufferFactory @Suppress("OVERRIDE_BY_INLINE") @OptIn(UnstableKMathAPI::class) - final override inline fun Buffer<Double>.map(block: DoubleField.(Double) -> Double): DoubleBuffer = - DoubleArray(size) { DoubleField.block(getDouble(it)) }.asBuffer() + final override inline fun Buffer<Double>.map(block: Float64Field.(Double) -> Double): DoubleBuffer = + DoubleArray(size) { Float64Field.block(getDouble(it)) }.asBuffer() @OptIn(UnstableKMathAPI::class) @Suppress("OVERRIDE_BY_INLINE") - final override inline fun Buffer<Double>.mapIndexed(block: DoubleField.(index: Int, arg: Double) -> Double): DoubleBuffer = - DoubleBuffer(size) { DoubleField.block(it, getDouble(it)) } + final override inline fun Buffer<Double>.mapIndexed(block: Float64Field.(index: Int, arg: Double) -> Double): DoubleBuffer = + DoubleBuffer(size) { Float64Field.block(it, getDouble(it)) } @OptIn(UnstableKMathAPI::class) @Suppress("OVERRIDE_BY_INLINE") final override inline fun Buffer<Double>.zip( other: Buffer<Double>, - block: DoubleField.(left: Double, right: Double) -> Double, + block: Float64Field.(left: Double, right: Double) -> Double, ): DoubleBuffer { require(size == other.size) { "Incompatible buffer sizes. left: ${size}, right: ${other.size}" } - return DoubleBuffer(size) { DoubleField.block(getDouble(it), other.getDouble(it)) } + return DoubleBuffer(size) { Float64Field.block(getDouble(it), other.getDouble(it)) } } override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> = diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt new file mode 100644 index 000000000..a318dea53 --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2018-2023 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.operations + +import space.kscience.kmath.operations.Int16Field.div +import space.kscience.kmath.operations.Int32Field.div +import space.kscience.kmath.operations.Int64Field.div +import space.kscience.kmath.structures.* +import kotlin.math.roundToInt +import kotlin.math.roundToLong + + +/** + * A [Int16] field with integer division and scale. The division operation is done according to [Short.div] rules. + * + * Scaling is done according to [Double.roundToInt] rules. + * + * All results are converted to Int16. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +public object Int16Field : Field<Int16>, Norm<Int16, Int16>, NumericAlgebra<Int16> { + override val bufferFactory: MutableBufferFactory<Int16> = MutableBufferFactory(::ShortBuffer) + override val zero: Int16 get() = 0 + override val one: Int16 get() = 1 + + override fun number(value: Number): Int16 = value.toShort() + override fun add(left: Int16, right: Int16): Int16 = (left + right).toShort() + override fun multiply(left: Int16, right: Int16): Int16 = (left * right).toShort() + override fun norm(arg: Int16): Int16 = abs(arg) + + override fun scale(a: Int16, value: Double): Int16 = (a*value).roundToInt().toShort() + + override fun divide(left: Int16, right: Int16): Int16 = (left / right).toShort() + + override fun Int16.unaryMinus(): Int16 = (-this).toShort() +} + +/** + * A [Int32] field with integer division and scale. The division operation is done according to [Int.div] rules. + * + * Scaling is done according to [Double.roundToInt] rules. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +public object Int32Field : Field<Int32>, Norm<Int32, Int32>, NumericAlgebra<Int32> { + override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::IntBuffer) + override val zero: Int get() = 0 + override val one: Int get() = 1 + + override fun number(value: Number): Int = value.toInt() + override fun add(left: Int, right: Int): Int = left + right + override fun multiply(left: Int, right: Int): Int = left * right + override fun norm(arg: Int): Int = abs(arg) + + override fun scale(a: Int, value: Double): Int = (a*value).roundToInt() + + override fun divide(left: Int, right: Int): Int = left / right + + override fun Int.unaryMinus(): Int = -this +} + +/** + * A [Int64] field with integer division and scale. The division operation is done according to [Long.div] rules. + * + * Scaling is done according to [Double.roundToLong] rules. + */ +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +public object Int64Field : Field<Int64>, Norm<Int64, Int64>, NumericAlgebra<Int64> { + override val bufferFactory: MutableBufferFactory<Int64> = MutableBufferFactory(::LongBuffer) + override val zero: Int64 get() = 0L + override val one: Int64 get() = 1L + + override fun number(value: Number): Int64 = value.toLong() + override fun add(left: Int64, right: Int64): Int64 = left + right + override fun multiply(left: Int64, right: Int64): Int64 = left * right + override fun norm(arg: Int64): Int64 = abs(arg) + + override fun scale(a: Int64, value: Double): Int64 = (a*value).roundToLong() + + override fun divide(left: Int64, right: Int64): Int64 = left / right + + override fun Int64.unaryMinus(): Int64 = -this +} \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt index 224ca1daf..17b3a72cc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt @@ -2,7 +2,6 @@ * Copyright 2018-2022 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. */ -@file:Suppress("NOTHING_TO_INLINE") package space.kscience.kmath.operations import space.kscience.kmath.structures.* @@ -67,7 +66,7 @@ public interface ExtendedField<T> : ExtendedFieldOps<T>, Field<T>, NumericAlgebr * A field for [Double] without boxing. Does not produce appropriate field element. */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") -public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> { +public object Float64Field : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> { override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory(::DoubleBuffer) override inline val zero: Double get() = 0.0 @@ -121,13 +120,15 @@ public object DoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOp override inline fun Double.div(arg: Double): Double = this / arg } -public val Double.Companion.algebra: DoubleField get() = DoubleField +public typealias DoubleField = Float64Field + +public val Double.Companion.algebra: Float64Field get() = Float64Field /** * A field for [Float] without boxing. Does not produce appropriate field element. */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") -public object FloatField : ExtendedField<Float>, Norm<Float, Float> { +public object Float32Field : ExtendedField<Float>, Norm<Float, Float> { override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory(::FloatBuffer) override inline val zero: Float get() = 0.0f @@ -177,13 +178,15 @@ public object FloatField : ExtendedField<Float>, Norm<Float, Float> { override inline fun Float.div(arg: Float): Float = this / arg } -public val Float.Companion.algebra: FloatField get() = FloatField +public typealias FloatField = Float32Field + +public val Float.Companion.algebra: Float32Field get() = Float32Field /** * A field for [Int] without boxing. Does not produce corresponding ring element. */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") -public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> { +public object Int32Ring : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> { override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::IntBuffer) override inline val zero: Int get() = 0 @@ -200,13 +203,15 @@ public object IntRing : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> { override inline fun Int.times(arg: Int): Int = this * arg } -public val Int.Companion.algebra: IntRing get() = IntRing +public typealias IntRing = Int32Ring + +public val Int.Companion.algebra: Int32Ring get() = Int32Ring /** * A field for [Short] without boxing. Does not produce appropriate ring element. */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") -public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> { +public object Int16Ring : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> { override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory(::ShortBuffer) override inline val zero: Short get() = 0 @@ -223,7 +228,9 @@ public object ShortRing : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> override inline fun Short.times(arg: Short): Short = (this * arg).toShort() } -public val Short.Companion.algebra: ShortRing get() = ShortRing +public typealias ShortRing = Int16Ring + +public val Short.Companion.algebra: Int16Ring get() = Int16Ring /** * A field for [Byte] without boxing. Does not produce appropriate ring element. @@ -249,10 +256,10 @@ public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> { public val Byte.Companion.algebra: ByteRing get() = ByteRing /** - * A field for [Double] without boxing. Does not produce appropriate ring element. + * A field for [Double] without boxing. Does not produce an appropriate ring element. */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") -public object LongRing : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> { +public object Int64Ring : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> { override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory(::LongBuffer) override inline val zero: Long get() = 0L @@ -269,4 +276,6 @@ public object LongRing : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> { override inline fun Long.times(arg: Long): Long = (this * arg) } -public val Long.Companion.algebra: LongRing get() = LongRing +public typealias LongRing = Int64Ring + +public val Long.Companion.algebra: Int64Ring get() = Int64Ring diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt index 02fd2600d..f538fdd01 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt @@ -96,6 +96,12 @@ public fun <T> Buffer<T>.slice(range: IntRange): BufferView<T> = if (this is Buf ) } +/** + * Dynamically create a range from the initial range + */ +@UnstableKMathAPI +public inline fun <T> Buffer<T>.slice(rangeBuilder: IntRange.() -> IntRange): BufferView<T> = slice(rangeBuilder(indices)) + /** * Resize original buffer to a given range using given [range], filling additional segments with [defaultValue]. * Range left border could be negative to designate adding new blank segment to the beginning of the buffer diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt index 871119f48..71bbc325c 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.expressions import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.test.Test @@ -18,10 +18,10 @@ import kotlin.test.assertFails internal inline fun diff( order: Int, vararg parameters: Pair<Symbol, Double>, - block: DSField<Double, DoubleField>.() -> Unit, + block: DSField<Double, Float64Field>.() -> Unit, ) { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - DSField(DoubleField, order, mapOf(*parameters)).block() + DSField(Float64Field, order, mapOf(*parameters)).block() } internal class DSTest { @@ -44,7 +44,7 @@ internal class DSTest { @Test fun dsExpressionTest() { - val f = DSFieldExpression(DoubleField) { + val f = DSFieldExpression(Float64Field) { val x by binding val y by binding x.pow(2) + 2 * x * y + y.pow(2) + 1 diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt index def9f91a6..153090d35 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.expressions -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFails @@ -15,7 +15,7 @@ class ExpressionFieldTest { @Test fun testExpression() { - val expression = with(FunctionalExpressionField(DoubleField)) { + val expression = with(FunctionalExpressionField(Float64Field)) { val x by binding x * x + 2 * x + one } @@ -31,7 +31,7 @@ class ExpressionFieldTest { return x * x + 2 * x + one } - val expression = FunctionalExpressionField(DoubleField).expression() + val expression = FunctionalExpressionField(Float64Field).expression() assertEquals(expression(x to 1.0), 4.0) } @@ -42,7 +42,7 @@ class ExpressionFieldTest { x * x + 2 * x + one } - val expression = FunctionalExpressionField(DoubleField).expressionBuilder() + val expression = FunctionalExpressionField(Float64Field).expressionBuilder() assertEquals(expression(x to 1.0), 4.0) } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/InterpretTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/InterpretTest.kt index 83f00ce6c..6533af344 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/InterpretTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/InterpretTest.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.expressions import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.operations.BooleanAlgebra -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import kotlin.test.Test import kotlin.test.assertEquals @@ -19,7 +19,7 @@ internal class InterpretTest { fun interpretation() { val expr = MstField { x * 2.0 + number(2.0) / x - 16.0 - }.toExpression(DoubleField) + }.toExpression(Float64Field) assertEquals(-10.69, expr(x to 2.2), 0.02) } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt index 1618296be..c0c5fc321 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.expressions -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.bindSymbol import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.asBuffer @@ -21,19 +21,19 @@ internal class SimpleAutoDiffTest { fun dx( xBinding: Pair<Symbol, Double>, - body: SimpleAutoDiffField<Double, DoubleField>.(x: AutoDiffValue<Double>) -> AutoDiffValue<Double>, - ): DerivationResult<Double> = DoubleField.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) } + body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Double>) -> AutoDiffValue<Double>, + ): DerivationResult<Double> = Float64Field.simpleAutoDiff(xBinding) { body(bindSymbol(xBinding.first)) } fun dxy( xBinding: Pair<Symbol, Double>, yBinding: Pair<Symbol, Double>, - body: SimpleAutoDiffField<Double, DoubleField>.(x: AutoDiffValue<Double>, y: AutoDiffValue<Double>) -> AutoDiffValue<Double>, - ): DerivationResult<Double> = DoubleField.simpleAutoDiff(xBinding, yBinding) { + body: SimpleAutoDiffField<Double, Float64Field>.(x: AutoDiffValue<Double>, y: AutoDiffValue<Double>) -> AutoDiffValue<Double>, + ): DerivationResult<Double> = Float64Field.simpleAutoDiff(xBinding, yBinding) { body(bindSymbol(xBinding.first), bindSymbol(yBinding.first)) } - fun diff(block: SimpleAutoDiffField<Double, DoubleField>.() -> AutoDiffValue<Double>): SimpleAutoDiffExpression<Double, DoubleField> { - return SimpleAutoDiffExpression(DoubleField, block) + fun diff(block: SimpleAutoDiffField<Double, Float64Field>.() -> AutoDiffValue<Double>): SimpleAutoDiffExpression<Double, Float64Field> { + return SimpleAutoDiffExpression(Float64Field, block) } val x by symbol @@ -42,7 +42,7 @@ internal class SimpleAutoDiffTest { @Test fun testPlusX2() { - val y = DoubleField.simpleAutoDiff(x to 3.0) { + val y = Float64Field.simpleAutoDiff(x to 3.0) { // diff w.r.t this x at 3 val x = bindSymbol(x) x + x @@ -65,7 +65,7 @@ internal class SimpleAutoDiffTest { @Test fun testPlus() { // two variables - val z = DoubleField.simpleAutoDiff(x to 2.0, y to 3.0) { + val z = Float64Field.simpleAutoDiff(x to 2.0, y to 3.0) { val x = bindSymbol(x) val y = bindSymbol(y) x + y @@ -78,7 +78,7 @@ internal class SimpleAutoDiffTest { @Test fun testMinus() { // two variables - val z = DoubleField.simpleAutoDiff(x to 7.0, y to 3.0) { + val z = Float64Field.simpleAutoDiff(x to 7.0, y to 3.0) { val x = bindSymbol(x) val y = bindSymbol(y) diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt index e909a2aea..ada7f4244 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt @@ -5,14 +5,14 @@ package space.kscience.kmath.nd -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.test.Test import kotlin.test.assertEquals class NdOperationsTest { @Test fun roll() { - val structure = DoubleField.ndAlgebra.structureND(5, 5) { index -> + val structure = Float64Field.ndAlgebra.structureND(5, 5) { index -> index.sumOf { it.toDouble() } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt index 688daa7fe..2f0ee28e7 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt @@ -11,16 +11,16 @@ import kotlin.test.assertEquals internal class DoubleFieldTest { @Test - fun verify() = FieldVerifier(DoubleField, 42.0, 66.0, 2.0, 5).verify() + fun verify() = FieldVerifier(Float64Field, 42.0, 66.0, 2.0, 5).verify() @Test fun testSqrt() { - val sqrt = DoubleField { sqrt(25 * one) } + val sqrt = Float64Field { sqrt(25 * one) } assertEquals(5.0, sqrt) } @Test - fun testPow() = DoubleField { + fun testPow() = Float64Field { val num = 5 * one assertEquals(5.0, power(num, 1), 0.01) assertEquals(25.0, power(num, 2), 0.01) diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt index 566145621..d6c6adedd 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.structures import space.kscience.kmath.nd.get import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.structureND -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.testutils.FieldVerifier import kotlin.test.Test @@ -17,12 +17,12 @@ import kotlin.test.assertEquals internal class NDFieldTest { @Test fun verify() { - (DoubleField.ndAlgebra(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) } + (Float64Field.ndAlgebra(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) } } @Test fun testStrides() { - val ndArray = DoubleField.ndAlgebra.structureND(10, 10) { (it[0] + it[1]).toDouble() } + val ndArray = Float64Field.ndAlgebra.structureND(10, 10) { (it[0] + it[1]).toDouble() } assertEquals(ndArray[5, 5], 10.0) } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt index 993fb089f..4ee6d50cb 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt @@ -11,7 +11,7 @@ import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.get import space.kscience.kmath.nd.ndAlgebra import space.kscience.kmath.nd.structureND -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Norm import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.invoke @@ -25,7 +25,7 @@ import kotlin.test.assertEquals @OptIn(PerformancePitfall::class) @Suppress("UNUSED_VARIABLE") class NumberNDFieldTest { - val algebra = DoubleField.ndAlgebra + val algebra = Float64Field.ndAlgebra val array1 = algebra.structureND(3, 3) { (i, j) -> (i + j).toDouble() } val array2 = algebra.structureND(3, 3) { (i, j) -> (i - j).toDouble() } @@ -94,7 +94,7 @@ class NumberNDFieldTest { @Test fun testInternalContext() { algebra { - (DoubleField.ndAlgebra(array1.shape)) { with(L2Norm) { 1 + norm(array1) + exp(array2) } } + (Float64Field.ndAlgebra(array1.shape)) { with(L2Norm) { 1 + norm(array1) + exp(array2) } } } } } diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt index dde2d4fcf..6cade1d5d 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.dimensions import space.kscience.kmath.linear.* import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.Structure2D -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.algebra import kotlin.jvm.JvmInline @@ -150,7 +150,7 @@ public value class DMatrixContext<T : Any, out A : Ring<T>>(public val context: context.run { (this@transpose as Matrix<T>).transpose() }.coerce() public companion object { - public val real: DMatrixContext<Double, DoubleField> = DMatrixContext(Double.algebra.linearSpace) + public val real: DMatrixContext<Double, Float64Field> = DMatrixContext(Double.algebra.linearSpace) } } @@ -158,12 +158,12 @@ public value class DMatrixContext<T : Any, out A : Ring<T>>(public val context: /** * A square unit matrix */ -public inline fun <reified D : Dimension> DMatrixContext<Double, DoubleField>.one(): DMatrix<Double, D, D> = +public inline fun <reified D : Dimension> DMatrixContext<Double, Float64Field>.one(): DMatrix<Double, D, D> = produce { i, j -> if (i == j) 1.0 else 0.0 } -public inline fun <reified R : Dimension, reified C : Dimension> DMatrixContext<Double, DoubleField>.zero(): DMatrix<Double, R, C> = +public inline fun <reified R : Dimension, reified C : Dimension> DMatrixContext<Double, Float64Field>.zero(): DMatrix<Double, R, C> = produce { _, _ -> 0.0 } diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 8ad7f7293..f48ab4c19 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,12 +19,12 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.FloatField +import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer @@ -71,11 +71,11 @@ public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatr * [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and * [DMatrixRMaj] matrices. */ -public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrixRMaj>() { +public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatrixRMaj>() { /** - * The [DoubleField] reference. + * The [Float64Field] reference. */ - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field @Suppress("UNCHECKED_CAST") override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when { @@ -94,7 +94,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix override fun buildMatrix( rows: Int, columns: Int, - initializer: DoubleField.(i: Int, j: Int) -> Double, + initializer: Float64Field.(i: Int, j: Int) -> Double, ): EjmlDoubleMatrix<DMatrixRMaj> = DMatrixRMaj(rows, columns).also { (0 until rows).forEach { row -> (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } @@ -103,7 +103,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix override fun buildVector( size: Int, - initializer: DoubleField.(Int) -> Double, + initializer: Float64Field.(Int) -> Double, ): EjmlDoubleVector<DMatrixRMaj> = EjmlDoubleVector(DMatrixRMaj(size, 1).also { (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } }) @@ -307,11 +307,11 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, DoubleField, DMatrix * [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and * [FMatrixRMaj] matrices. */ -public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRMaj>() { +public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrixRMaj>() { /** - * The [FloatField] reference. + * The [Float32Field] reference. */ - override val elementAlgebra: FloatField get() = FloatField + override val elementAlgebra: Float32Field get() = Float32Field @Suppress("UNCHECKED_CAST") override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixRMaj> = when { @@ -330,7 +330,7 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM override fun buildMatrix( rows: Int, columns: Int, - initializer: FloatField.(i: Int, j: Int) -> Float, + initializer: Float32Field.(i: Int, j: Int) -> Float, ): EjmlFloatMatrix<FMatrixRMaj> = FMatrixRMaj(rows, columns).also { (0 until rows).forEach { row -> (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } @@ -339,7 +339,7 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM override fun buildVector( size: Int, - initializer: FloatField.(Int) -> Float, + initializer: Float32Field.(Int) -> Float, ): EjmlFloatVector<FMatrixRMaj> = EjmlFloatVector(FMatrixRMaj(size, 1).also { (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } }) @@ -543,11 +543,11 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, FloatField, FMatrixRM * [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and * [DMatrixSparseCSC] matrices. */ -public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrixSparseCSC>() { +public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatrixSparseCSC>() { /** - * The [DoubleField] reference. + * The [Float64Field] reference. */ - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field @Suppress("UNCHECKED_CAST") override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when { @@ -566,7 +566,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix override fun buildMatrix( rows: Int, columns: Int, - initializer: DoubleField.(i: Int, j: Int) -> Double, + initializer: Float64Field.(i: Int, j: Int) -> Double, ): EjmlDoubleMatrix<DMatrixSparseCSC> = DMatrixSparseCSC(rows, columns).also { (0 until rows).forEach { row -> (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } @@ -575,7 +575,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix override fun buildVector( size: Int, - initializer: DoubleField.(Int) -> Double, + initializer: Float64Field.(Int) -> Double, ): EjmlDoubleVector<DMatrixSparseCSC> = EjmlDoubleVector(DMatrixSparseCSC(size, 1).also { (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } }) @@ -774,11 +774,11 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, DoubleField, DMatrix * [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and * [FMatrixSparseCSC] matrices. */ -public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSparseCSC>() { +public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrixSparseCSC>() { /** - * The [FloatField] reference. + * The [Float32Field] reference. */ - override val elementAlgebra: FloatField get() = FloatField + override val elementAlgebra: Float32Field get() = Float32Field @Suppress("UNCHECKED_CAST") override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixSparseCSC> = when { @@ -797,7 +797,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSp override fun buildMatrix( rows: Int, columns: Int, - initializer: FloatField.(i: Int, j: Int) -> Float, + initializer: Float32Field.(i: Int, j: Int) -> Float, ): EjmlFloatMatrix<FMatrixSparseCSC> = FMatrixSparseCSC(rows, columns).also { (0 until rows).forEach { row -> (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } @@ -806,7 +806,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, FloatField, FMatrixSp override fun buildVector( size: Int, - initializer: FloatField.(Int) -> Float, + initializer: Float32Field.(Int) -> Float, ): EjmlFloatVector<FMatrixSparseCSC> = EjmlFloatVector(FMatrixSparseCSC(size, 1).also { (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } }) diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt index 40e4a91f1..f86b9ef5f 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt @@ -11,7 +11,7 @@ package space.kscience.kmath.real import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.asIterable import space.kscience.kmath.structures.Buffer @@ -32,11 +32,11 @@ import kotlin.math.pow public typealias RealMatrix = Matrix<Double> -public fun realMatrix(rowNum: Int, colNum: Int, initializer: DoubleField.(i: Int, j: Int) -> Double): RealMatrix = +public fun realMatrix(rowNum: Int, colNum: Int, initializer: Float64Field.(i: Int, j: Int) -> Double): RealMatrix = Double.algebra.linearSpace.buildMatrix(rowNum, colNum, initializer) @OptIn(UnstableKMathAPI::class) -public fun realMatrix(rowNum: Int, colNum: Int): MatrixBuilder<Double, DoubleField> = +public fun realMatrix(rowNum: Int, colNum: Int): MatrixBuilder<Double, Float64Field> = Double.algebra.linearSpace.matrix(rowNum, colNum) public fun Array<DoubleArray>.toMatrix(): RealMatrix { diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt index 2c06b76b7..13b579144 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt @@ -6,14 +6,14 @@ package space.kscience.kmath.real import space.kscience.kmath.nd.BufferND -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.DoubleBuffer /** * Map one [BufferND] using function without indices. */ -public inline fun BufferND<Double>.mapInline(crossinline transform: DoubleField.(Double) -> Double): BufferND<Double> { - val array = DoubleArray(indices.linearSize) { offset -> DoubleField.transform(buffer[offset]) } +public inline fun BufferND<Double>.mapInline(crossinline transform: Float64Field.(Double) -> Double): BufferND<Double> { + val array = DoubleArray(indices.linearSize) { offset -> Float64Field.transform(buffer[offset]) } return BufferND(indices, DoubleBuffer(array)) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt index 73a3cc25b..35ce82351 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt @@ -6,8 +6,8 @@ package space.kscience.kmath.integration import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Field +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.operations.sum @@ -105,4 +105,4 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> { } } -public val DoubleField.simpsonIntegrator: DoubleSimpsonIntegrator get() = DoubleSimpsonIntegrator \ No newline at end of file +public val Float64Field.simpsonIntegrator: DoubleSimpsonIntegrator get() = DoubleSimpsonIntegrator \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt index 993812b29..319e86cd0 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt @@ -85,7 +85,7 @@ public class SplineIntegrator<T : Comparable<T>>( public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0 - val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(DoubleField, ::DoubleBuffer) + val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, ::DoubleBuffer) val nodes: Buffer<Double> = integrand.getFeature<UnivariateIntegrationNodes>()?.nodes ?: run { val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 @@ -95,12 +95,12 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { val values = nodes.mapToBuffer(::DoubleBuffer) { integrand.function(it) } val polynomials = interpolator.interpolatePolynomials(nodes, values) - val res = polynomials.integrate(DoubleField, range) + val res = polynomials.integrate(Float64Field, range) return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + nodes.size) } } @Suppress("unused") @UnstableKMathAPI -public inline val DoubleField.splineIntegrator: UnivariateIntegrator<Double> +public inline val Float64Field.splineIntegrator: UnivariateIntegrator<Double> get() = DoubleSplineIntegrator \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt index a3cc17954..76082af74 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt @@ -9,8 +9,8 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.functions.PiecewisePolynomial import space.kscience.kmath.functions.Polynomial -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Field +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.MutableBufferFactory @@ -79,5 +79,5 @@ public fun <T : Comparable<T>> Field<T>.splineInterpolator( bufferFactory: MutableBufferFactory<T>, ): SplineInterpolator<T> = SplineInterpolator(this, bufferFactory) -public val DoubleField.splineInterpolator: SplineInterpolator<Double> +public val Float64Field.splineInterpolator: SplineInterpolator<Double> get() = SplineInterpolator(this, ::DoubleBuffer) \ No newline at end of file diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt index 7424f3566..dd8069335 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.integration import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.math.PI import kotlin.math.sin import kotlin.test.Test @@ -16,7 +16,7 @@ import kotlin.test.assertEquals class GaussIntegralTest { @Test fun gaussSin() { - val res = DoubleField.gaussIntegrator.integrate(0.0..2 * PI) { x -> + val res = Float64Field.gaussIntegrator.integrate(0.0..2 * PI) { x -> sin(x) } assertEquals(0.0, res.value, 1e-2) @@ -24,7 +24,7 @@ class GaussIntegralTest { @Test fun gaussUniform() { - val res = DoubleField.gaussIntegrator.integrate(35.0..100.0) { x -> + val res = Float64Field.gaussIntegrator.integrate(35.0..100.0) { x -> if(x in 30.0..50.0){ 1.0 } else { diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt index 7b699ebbc..f5a79cdea 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.integration import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.math.PI import kotlin.math.sin import kotlin.test.Test @@ -16,7 +16,7 @@ import kotlin.test.assertEquals class SimpsonIntegralTest { @Test fun gaussSin() { - val res = DoubleField.simpsonIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x -> + val res = Float64Field.simpsonIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x -> sin(x) } assertEquals(0.0, res.value, 1e-2) @@ -24,7 +24,7 @@ class SimpsonIntegralTest { @Test fun gaussUniform() { - val res = DoubleField.simpsonIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x -> + val res = Float64Field.simpsonIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x -> if (x in 30.0..50.0) { 1.0 } else { diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt index b17d21abf..6b62afbd3 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.integration import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.functions.Polynomial import space.kscience.kmath.functions.integrate -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.math.PI import kotlin.math.sin import kotlin.test.Test @@ -20,13 +20,13 @@ class SplineIntegralTest { @Test fun integratePolynomial(){ val polynomial = Polynomial(1.0, 2.0, 3.0) - val integral = polynomial.integrate(DoubleField,1.0..2.0) + val integral = polynomial.integrate(Float64Field,1.0..2.0) assertEquals(11.0, integral, 0.001) } @Test fun gaussSin() { - val res = DoubleField.splineIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x -> + val res = Float64Field.splineIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x -> sin(x) } assertEquals(0.0, res.value, 1e-2) @@ -34,7 +34,7 @@ class SplineIntegralTest { @Test fun gaussUniform() { - val res = DoubleField.splineIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x -> + val res = Float64Field.splineIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x -> if(x in 30.0..50.0){ 1.0 } else { diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt index c0ca6c484..24a664c26 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.interpolation -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.test.Test import kotlin.test.assertEquals @@ -20,7 +20,7 @@ internal class LinearInterpolatorTest { ) //val polynomial: PiecewisePolynomial<Double> = DoubleField.linearInterpolator.interpolatePolynomials(data) - val function = DoubleField.linearInterpolator.interpolate(data) + val function = Float64Field.linearInterpolator.interpolate(data) assertEquals(null, function(-1.0)) assertEquals(0.5, function(0.5)) assertEquals(2.0, function(1.5)) diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/SplineInterpolatorTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/SplineInterpolatorTest.kt index 851a8ab7d..774b6196e 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/SplineInterpolatorTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/SplineInterpolatorTest.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.interpolation -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.math.PI import kotlin.math.sin import kotlin.test.Test @@ -21,7 +21,7 @@ internal class SplineInterpolatorTest { //val polynomial: PiecewisePolynomial<Double> = DoubleField.splineInterpolator.interpolatePolynomials(data) - val function = DoubleField.splineInterpolator.interpolate(data, Double.NaN) + val function = Float64Field.splineInterpolator.interpolate(data, Double.NaN) assertEquals(Double.NaN, function(-1.0)) assertEquals(sin(0.5), function(0.5), 0.1) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/rotations3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/rotations3D.kt index 1f3850c7c..688386e3b 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/rotations3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/rotations3D.kt @@ -14,7 +14,7 @@ import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.Matrix import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.matrix -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.math.pow import kotlin.math.sqrt @@ -66,7 +66,7 @@ public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, composition: Quaterni public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, matrix: Matrix<Double>): DoubleVector3D { require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" } - return with(DoubleField.linearSpace) { matrix.dot(vector).asVector3D() } + return with(Float64Field.linearSpace) { matrix.dot(vector).asVector3D() } } /** @@ -74,7 +74,7 @@ public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, matrix: Matrix<Double */ @OptIn(UnstableKMathAPI::class) public fun Quaternion.toRotationMatrix( - linearSpace: LinearSpace<Double, *> = DoubleField.linearSpace, + linearSpace: LinearSpace<Double, *> = Float64Field.linearSpace, ): Matrix<Double> { val s = QuaternionField.norm(this).pow(-2) return linearSpace.matrix(3, 3)( diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt index 43ed24c70..3d948e1a7 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.histogram import kotlinx.atomicfu.atomic import kotlinx.atomicfu.getAndUpdate -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Group /** @@ -18,7 +18,7 @@ public interface Counter<T : Any> { public val value: T public companion object { - public fun ofDouble(): ObjectCounter<Double> = ObjectCounter(DoubleField) + public fun ofDouble(): ObjectCounter<Double> = ObjectCounter(Float64Field) public fun <T: Any> of(group: Group<T>): ObjectCounter<T> = ObjectCounter(group) } } diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt index 61ce450a7..fe9c3ae01 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt @@ -128,7 +128,7 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges( public fun Histogram.Companion.uniformDoubleNDFromRanges( vararg ranges: ClosedFloatingPointRange<Double>, -): UniformHistogramGroupND<Double, DoubleField> = +): UniformHistogramGroupND<Double, Float64Field> = uniformNDFromRanges(DoubleFieldOpsND, *ranges, bufferFactory = ::DoubleBuffer) @@ -163,5 +163,5 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges( public fun Histogram.Companion.uniformDoubleNDFromRanges( vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>, -): UniformHistogramGroupND<Double, DoubleField> = +): UniformHistogramGroupND<Double, Float64Field> = uniformNDFromRanges(DoubleFieldOpsND, *ranges, bufferFactory = ::DoubleBuffer) \ No newline at end of file diff --git a/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/UniformHistogram1DTest.kt b/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/UniformHistogram1DTest.kt index fa129fad6..bda9d2bea 100644 --- a/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/UniformHistogram1DTest.kt +++ b/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/UniformHistogram1DTest.kt @@ -9,7 +9,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.runTest import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.distributions.NormalDistribution -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.stat.nextBuffer import kotlin.native.concurrent.ThreadLocal @@ -22,7 +22,7 @@ internal class UniformHistogram1DTest { @Test fun normal() = runTest { val distribution = NormalDistribution(0.0, 1.0) - with(Histogram.uniform1D(DoubleField, 0.1)) { + with(Histogram.uniform1D(Float64Field, 0.1)) { val h1 = produce(distribution.nextBuffer(generator, 10000)) val h2 = produce(distribution.nextBuffer(generator, 50000)) @@ -35,16 +35,16 @@ internal class UniformHistogram1DTest { @Test fun rebinDown() = runTest { - val h1 = Histogram.uniform1D(DoubleField, 0.01).produce(generator.nextDoubleBuffer(10000)) - val h2 = Histogram.uniform1D(DoubleField, 0.03).produceFrom(h1) + val h1 = Histogram.uniform1D(Float64Field, 0.01).produce(generator.nextDoubleBuffer(10000)) + val h2 = Histogram.uniform1D(Float64Field, 0.03).produceFrom(h1) assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt()) } @Test fun rebinUp() = runTest { - val h1 = Histogram.uniform1D(DoubleField, 0.03).produce(generator.nextDoubleBuffer(10000)) - val h2 = Histogram.uniform1D(DoubleField, 0.01).produceFrom(h1) + val h1 = Histogram.uniform1D(Float64Field, 0.03).produce(generator.nextDoubleBuffer(10000)) + val h2 = Histogram.uniform1D(Float64Field, 0.01).produceFrom(h1) assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt()) } diff --git a/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt b/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt index b7c1f34ba..00b94c11f 100644 --- a/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt +++ b/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.histogram import org.junit.jupiter.api.Test import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.real.step import kotlin.random.Random import kotlin.test.assertEquals @@ -19,7 +19,7 @@ class TreeHistogramTest { @Test fun normalFill() { val random = Random(123) - val histogram = Histogram.custom1D(DoubleField, 0.0..1.0 step 0.1).produce { + val histogram = Histogram.custom1D(Float64Field, 0.0..1.0 step 0.1).produce { repeat(100_000) { putValue(random.nextDouble()) } diff --git a/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt b/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt index ccd89f063..8d282a58a 100644 --- a/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt +++ b/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt @@ -12,7 +12,7 @@ import space.kscience.kmath.ast.parseMath import space.kscience.kmath.expressions.MstNumericAlgebra import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.invoke -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -22,8 +22,8 @@ import kotlin.test.fail internal class AdaptingTests { @Test fun symbol() { - assertEquals(x.identity, x.toSVar<KMathNumber<Double, DoubleField>>().name) - val c2 = "kitten".parseMath().toSFun<KMathNumber<Double, DoubleField>>() + assertEquals(x.identity, x.toSVar<KMathNumber<Double, Float64Field>>().name) + val c2 = "kitten".parseMath().toSFun<KMathNumber<Double, Float64Field>>() if (c2 is SVar<*>) assertTrue(c2.name == "kitten") else fail() } @@ -31,15 +31,15 @@ internal class AdaptingTests { fun number() { val c1 = MstNumericAlgebra.number(12354324) assertTrue(c1.toSConst<DReal>().doubleValue == 12354324.0) - val c2 = "0.234".parseMath().toSFun<KMathNumber<Double, DoubleField>>() + val c2 = "0.234".parseMath().toSFun<KMathNumber<Double, Float64Field>>() if (c2 is SConst<*>) assertTrue(c2.doubleValue == 0.234) else fail() - val c3 = "1e-3".parseMath().toSFun<KMathNumber<Double, DoubleField>>() + val c3 = "1e-3".parseMath().toSFun<KMathNumber<Double, Float64Field>>() if (c3 is SConst<*>) assertEquals(0.001, c3.value) else fail() } @Test fun simpleFunctionShape() { - val linear = "2*x+16".parseMath().toSFun<KMathNumber<Double, DoubleField>>() + val linear = "2*x+16".parseMath().toSFun<KMathNumber<Double, Float64Field>>() if (linear !is Sum<*>) fail() if (linear.left !is Prod<*>) fail() if (linear.right !is SConst<*>) fail() @@ -47,22 +47,22 @@ internal class AdaptingTests { @Test fun simpleFunctionDerivative() { - val xSVar = x.toSVar<KMathNumber<Double, DoubleField>>() - val quadratic = "x^2-4*x-44".parseMath().toSFun<KMathNumber<Double, DoubleField>>() - val actualDerivative = quadratic.d(xSVar).toMst().compileToExpression(DoubleField) - val expectedDerivative = "2*x-4".parseMath().compileToExpression(DoubleField) + val xSVar = x.toSVar<KMathNumber<Double, Float64Field>>() + val quadratic = "x^2-4*x-44".parseMath().toSFun<KMathNumber<Double, Float64Field>>() + val actualDerivative = quadratic.d(xSVar).toMst().compileToExpression(Float64Field) + val expectedDerivative = "2*x-4".parseMath().compileToExpression(Float64Field) assertEquals(actualDerivative(x to 123.0), expectedDerivative(x to 123.0)) } @Test fun moreComplexDerivative() { - val xSVar = x.toSVar<KMathNumber<Double, DoubleField>>() - val composition = "-sqrt(sin(x^2)-cos(x)^2-16*x)".parseMath().toSFun<KMathNumber<Double, DoubleField>>() - val actualDerivative = composition.d(xSVar).toMst().compileToExpression(DoubleField) + val xSVar = x.toSVar<KMathNumber<Double, Float64Field>>() + val composition = "-sqrt(sin(x^2)-cos(x)^2-16*x)".parseMath().toSFun<KMathNumber<Double, Float64Field>>() + val actualDerivative = composition.d(xSVar).toMst().compileToExpression(Float64Field) val expectedDerivative = "-(2*x*cos(x^2)+2*sin(x)*cos(x)-16)/(2*sqrt(sin(x^2)-16*x-cos(x)^2))" .parseMath() - .compileToExpression(DoubleField) + .compileToExpression(Float64Field) assertEquals(actualDerivative(x to -0.1), expectedDerivative(x to -0.1)) } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt index beab5c18b..8b463a230 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt @@ -11,15 +11,15 @@ import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.ndarray.data.DataType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.ExponentialOperations +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.TrigonometricOperations public class MultikDoubleAlgebra( multikEngine: Engine -) : MultikDivisionTensorAlgebra<Double, DoubleField>(multikEngine), +) : MultikDivisionTensorAlgebra<Double, Float64Field>(multikEngine), TrigonometricOperations<StructureND<Double>>, ExponentialOperations<StructureND<Double>> { - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field override val type: DataType get() = DataType.DoubleDataType override fun sin(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.sin(arg.asMultik().array).wrap() diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt index ee194ae24..7a3dda94b 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt @@ -9,12 +9,12 @@ import org.jetbrains.kotlinx.multik.api.Engine import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.ndarray.data.DataType -import space.kscience.kmath.operations.FloatField +import space.kscience.kmath.operations.Float32Field public class MultikFloatAlgebra( multikEngine: Engine -) : MultikDivisionTensorAlgebra<Float, FloatField>(multikEngine) { - override val elementAlgebra: FloatField get() = FloatField +) : MultikDivisionTensorAlgebra<Float, Float32Field>(multikEngine) { + override val elementAlgebra: Float32Field get() = Float32Field override val type: DataType get() = DataType.FloatDataType override fun scalar(value: Float): MultikTensor<Float> = Multik.ndarrayOf(value).wrap() diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt index 05b240787..5bd1b3388 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt @@ -9,12 +9,12 @@ import org.jetbrains.kotlinx.multik.api.Engine import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.ndarray.data.DataType -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Int32Ring public class MultikIntAlgebra( multikEngine: Engine -) : MultikTensorAlgebra<Int, IntRing>(multikEngine) { - override val elementAlgebra: IntRing get() = IntRing +) : MultikTensorAlgebra<Int, Int32Ring>(multikEngine) { + override val elementAlgebra: Int32Ring get() = Int32Ring override val type: DataType get() = DataType.IntDataType override fun scalar(value: Int): MultikTensor<Int> = Multik.ndarrayOf(value).wrap() } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt index e713e556e..69a8ec042 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt @@ -9,12 +9,12 @@ import org.jetbrains.kotlinx.multik.api.Engine import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.ndarray.data.DataType -import space.kscience.kmath.operations.LongRing +import space.kscience.kmath.operations.Int64Ring public class MultikLongAlgebra( multikEngine: Engine -) : MultikTensorAlgebra<Long, LongRing>(multikEngine) { - override val elementAlgebra: LongRing get() = LongRing +) : MultikTensorAlgebra<Long, Int64Ring>(multikEngine) { + override val elementAlgebra: Int64Ring get() = Int64Ring override val type: DataType get() = DataType.LongDataType override fun scalar(value: Long): MultikTensor<Long> = Multik.ndarrayOf(value).wrap() diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt index 6e5ca5882..7c8740665 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt @@ -9,12 +9,12 @@ import org.jetbrains.kotlinx.multik.api.Engine import org.jetbrains.kotlinx.multik.api.Multik import org.jetbrains.kotlinx.multik.api.ndarrayOf import org.jetbrains.kotlinx.multik.ndarray.data.DataType -import space.kscience.kmath.operations.ShortRing +import space.kscience.kmath.operations.Int16Ring public class MultikShortAlgebra( multikEngine: Engine -) : MultikTensorAlgebra<Short, ShortRing>(multikEngine) { - override val elementAlgebra: ShortRing get() = ShortRing +) : MultikTensorAlgebra<Short, Int16Ring>(multikEngine) { + override val elementAlgebra: Int16Ring get() = Int16Ring override val type: DataType get() = DataType.ShortDataType override fun scalar(value: Short): MultikTensor<Short> = Multik.ndarrayOf(value).wrap() } diff --git a/kmath-multik/src/commonTest/kotlin/space/kscience/kmath/multik/MultikNDTest.kt b/kmath-multik/src/commonTest/kotlin/space/kscience/kmath/multik/MultikNDTest.kt index 1a130aa92..1abcf512d 100644 --- a/kmath-multik/src/commonTest/kotlin/space/kscience/kmath/multik/MultikNDTest.kt +++ b/kmath-multik/src/commonTest/kotlin/space/kscience/kmath/multik/MultikNDTest.kt @@ -10,7 +10,7 @@ import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.one -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.randomNormal import space.kscience.kmath.tensors.core.tensorAlgebra @@ -37,7 +37,7 @@ internal class MultikNDTest { tensor1 dot tensor2 } - val defaultResult = with(DoubleField.tensorAlgebra) { + val defaultResult = with(Float64Field.tensorAlgebra) { tensor1 dot tensor2 } diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt index 0eb147b6f..31523b340 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt @@ -124,7 +124,7 @@ public sealed interface Nd4jArrayRingOps<T, out R : Ring<T>> : RingOpsND<T, R>, */ @Suppress("UNCHECKED_CAST") public inline fun <reified T : Number> auto(): Nd4jArrayRingOps<T, Ring<T>> = when { - T::class == Int::class -> IntRing.nd4j as Nd4jArrayRingOps<T, Ring<T>> + T::class == Int::class -> Int32Ring.nd4j as Nd4jArrayRingOps<T, Ring<T>> else -> throw UnsupportedOperationException("This factory method only supports Long type.") } } @@ -149,8 +149,8 @@ public sealed interface Nd4jArrayField<T, out F : Field<T>> : FieldOpsND<T, F>, */ @Suppress("UNCHECKED_CAST") public inline fun <reified T : Any> auto(): Nd4jArrayField<T, Field<T>> = when { - T::class == Float::class -> FloatField.nd4j as Nd4jArrayField<T, Field<T>> - T::class == Double::class -> DoubleField.nd4j as Nd4jArrayField<T, Field<T>> + T::class == Float::class -> Float32Field.nd4j as Nd4jArrayField<T, Field<T>> + T::class == Double::class -> Float64Field.nd4j as Nd4jArrayField<T, Field<T>> else -> throw UnsupportedOperationException("This factory method only supports Float and Double types.") } } @@ -190,8 +190,8 @@ public sealed interface Nd4jArrayExtendedFieldOps<T, out F : ExtendedField<T>> : /** * Represents [FieldND] over [Nd4jArrayDoubleStructure]. */ -public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, DoubleField> { - override val elementAlgebra: DoubleField get() = DoubleField +public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, Float64Field> { + override val elementAlgebra: Float64Field get() = Float64Field override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure() @@ -223,19 +223,19 @@ public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, Do public companion object : DoubleNd4jArrayFieldOps() } -public val DoubleField.nd4j: DoubleNd4jArrayFieldOps get() = DoubleNd4jArrayFieldOps +public val Float64Field.nd4j: DoubleNd4jArrayFieldOps get() = DoubleNd4jArrayFieldOps -public class DoubleNd4jArrayField(override val shape: ShapeND) : DoubleNd4jArrayFieldOps(), FieldND<Double, DoubleField> +public class DoubleNd4jArrayField(override val shape: ShapeND) : DoubleNd4jArrayFieldOps(), FieldND<Double, Float64Field> -public fun DoubleField.nd4j(shapeFirst: Int, vararg shapeRest: Int): DoubleNd4jArrayField = +public fun Float64Field.nd4j(shapeFirst: Int, vararg shapeRest: Int): DoubleNd4jArrayField = DoubleNd4jArrayField(ShapeND(shapeFirst, * shapeRest)) /** * Represents [FieldND] over [Nd4jArrayStructure] of [Float]. */ -public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, FloatField> { - override val elementAlgebra: FloatField get() = FloatField +public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, Float32Field> { + override val elementAlgebra: Float32Field get() = Float32Field override fun INDArray.wrap(): Nd4jArrayStructure<Float> = asFloatStructure() @@ -272,18 +272,18 @@ public open class FloatNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Float, Floa public companion object : FloatNd4jArrayFieldOps() } -public class FloatNd4jArrayField(override val shape: ShapeND) : FloatNd4jArrayFieldOps(), RingND<Float, FloatField> +public class FloatNd4jArrayField(override val shape: ShapeND) : FloatNd4jArrayFieldOps(), RingND<Float, Float32Field> -public val FloatField.nd4j: FloatNd4jArrayFieldOps get() = FloatNd4jArrayFieldOps +public val Float32Field.nd4j: FloatNd4jArrayFieldOps get() = FloatNd4jArrayFieldOps -public fun FloatField.nd4j(shapeFirst: Int, vararg shapeRest: Int): FloatNd4jArrayField = +public fun Float32Field.nd4j(shapeFirst: Int, vararg shapeRest: Int): FloatNd4jArrayField = FloatNd4jArrayField(ShapeND(shapeFirst, * shapeRest)) /** * Represents [RingND] over [Nd4jArrayIntStructure]. */ -public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, IntRing> { - override val elementAlgebra: IntRing get() = IntRing +public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, Int32Ring> { + override val elementAlgebra: Int32Ring get() = Int32Ring override fun INDArray.wrap(): Nd4jArrayStructure<Int> = asIntStructure() @@ -311,9 +311,9 @@ public open class IntNd4jArrayRingOps : Nd4jArrayRingOps<Int, IntRing> { public companion object : IntNd4jArrayRingOps() } -public val IntRing.nd4j: IntNd4jArrayRingOps get() = IntNd4jArrayRingOps +public val Int32Ring.nd4j: IntNd4jArrayRingOps get() = IntNd4jArrayRingOps -public class IntNd4jArrayRing(override val shape: ShapeND) : IntNd4jArrayRingOps(), RingND<Int, IntRing> +public class IntNd4jArrayRing(override val shape: ShapeND) : IntNd4jArrayRingOps(), RingND<Int, Int32Ring> -public fun IntRing.nd4j(shapeFirst: Int, vararg shapeRest: Int): IntNd4jArrayRing = +public fun Int32Ring.nd4j(shapeFirst: Int, vararg shapeRest: Int): IntNd4jArrayRing = IntNd4jArrayRing(ShapeND(shapeFirst, * shapeRest)) \ No newline at end of file diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt index 5905739f8..c308e64b9 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt @@ -15,8 +15,8 @@ import org.nd4j.linalg.ops.transforms.Transforms import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnsafeKMathAPI import space.kscience.kmath.nd.* -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Field +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.api.TensorAlgebra @@ -171,14 +171,14 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe /** * [Double] specialization of [Nd4jTensorAlgebra]. */ -public object DoubleNd4jTensorAlgebra : Nd4jTensorAlgebra<Double, DoubleField> { +public object DoubleNd4jTensorAlgebra : Nd4jTensorAlgebra<Double, Float64Field> { - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure() @OptIn(UnsafeKMathAPI::class) - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): Nd4jArrayStructure<Double> { + override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): Nd4jArrayStructure<Double> { val array: INDArray = Nd4j.zeros(*shape.asArray()) val indices = ColumnStrides(shape) indices.asSequence().forEach { index -> diff --git a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt index 708778e77..484618de2 100644 --- a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt +++ b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt @@ -10,8 +10,8 @@ import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.one import space.kscience.kmath.nd.structureND -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.operations.invoke import kotlin.math.PI import kotlin.test.Test @@ -23,7 +23,7 @@ import kotlin.test.fail internal class Nd4jArrayAlgebraTest { @Test fun testProduce() { - val res = DoubleField.nd4j.structureND(2, 2) { it.sum().toDouble() } + val res = Float64Field.nd4j.structureND(2, 2) { it.sum().toDouble() } val expected = (Nd4j.create(2, 2) ?: fail()).asDoubleStructure() expected[intArrayOf(0, 0)] = 0.0 expected[intArrayOf(0, 1)] = 1.0 @@ -34,7 +34,7 @@ internal class Nd4jArrayAlgebraTest { @Test fun testMap() { - val res = IntRing.nd4j { + val res = Int32Ring.nd4j { one(2, 2).map { it + it * 2 } } val expected = (Nd4j.create(2, 2) ?: fail()).asIntStructure() @@ -47,7 +47,7 @@ internal class Nd4jArrayAlgebraTest { @Test fun testAdd() { - val res = IntRing.nd4j { one(2, 2) + 25 } + val res = Int32Ring.nd4j { one(2, 2) + 25 } val expected = (Nd4j.create(2, 2) ?: fail()).asIntStructure() expected[intArrayOf(0, 0)] = 26 expected[intArrayOf(0, 1)] = 26 @@ -57,7 +57,7 @@ internal class Nd4jArrayAlgebraTest { } @Test - fun testSin() = DoubleField.nd4j{ + fun testSin() = Float64Field.nd4j{ val initial = structureND(2, 2) { (i, j) -> if (i == j) PI / 2 else 0.0 } val transformed = sin(initial) val expected = structureND(2, 2) { (i, j) -> if (i == j) 1.0 else 0.0 } diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt index b698584aa..2732efac7 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt @@ -9,8 +9,8 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.* import space.kscience.kmath.linear.* import space.kscience.kmath.misc.log -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.DoubleL2Norm +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.algebra import space.kscience.kmath.structures.DoubleBuffer import kotlin.math.abs @@ -32,7 +32,7 @@ public class QowRuns(public val runs: Int) : OptimizationFeature { @UnstableKMathAPI public object QowOptimizer : Optimizer<Double, XYFit> { - private val linearSpace: LinearSpace<Double, DoubleField> = Double.algebra.linearSpace + private val linearSpace: LinearSpace<Double, Float64Field> = Double.algebra.linearSpace private val solver: LinearSolver<Double> = linearSpace.lupSolver() @OptIn(UnstableKMathAPI::class) diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt index ae814254b..10947b732 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.distributions import space.kscience.kmath.chains.Chain -import space.kscience.kmath.operations.DoubleField.pow +import space.kscience.kmath.operations.Float64Field.pow import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.samplers.GaussianSampler import space.kscience.kmath.samplers.InternalErf diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/VarianceRatioTest.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/VarianceRatioTest.kt index 4becb3413..6cd64df9c 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/VarianceRatioTest.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/VarianceRatioTest.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.series import space.kscience.kmath.distributions.NormalDistribution -import space.kscience.kmath.operations.DoubleField.pow +import space.kscience.kmath.operations.Float64Field.pow import space.kscience.kmath.operations.fold import kotlin.math.absoluteValue diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt index 3bf8b33e8..74ef65fa1 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt @@ -13,21 +13,20 @@ import space.kscience.kmath.structures.indices * Arithmetic mean */ public class Mean<T>( - private val group: Ring<T>, - private val division: (sum: T, count: Int) -> T, + private val field: Field<T> ) : ComposableStatistic<T, Pair<T, Int>, T>, BlockingStatistic<T, T> { - override fun evaluateBlocking(data: Buffer<T>): T = group { + override fun evaluateBlocking(data: Buffer<T>): T = with(field) { var res = zero for (i in data.indices) { res += data[i] } - division(res, data.size) + res / data.size } override suspend fun evaluate(data: Buffer<T>): T = super<ComposableStatistic>.evaluate(data) - override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> = group { + override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> = with(field) { var res = zero for (i in data.indices) { res += data[i] @@ -36,32 +35,23 @@ public class Mean<T>( } override suspend fun composeIntermediate(first: Pair<T, Int>, second: Pair<T, Int>): Pair<T, Int> = - group { first.first + second.first } to (first.second + second.second) + with(field) { first.first + second.first } to (first.second + second.second) - override suspend fun toResult(intermediate: Pair<T, Int>): T = group { - division(intermediate.first, intermediate.second) + override suspend fun toResult(intermediate: Pair<T, Int>): T = with(field) { + intermediate.first/ intermediate.second } public companion object { - @Deprecated("Use Double.mean instead") - public val double: Mean<Double> = Mean(DoubleField) { sum, count -> sum / count } - - @Deprecated("Use Int.mean instead") - public val int: Mean<Int> = Mean(IntRing) { sum, count -> sum / count } - - @Deprecated("Use Long.mean instead") - public val long: Mean<Long> = Mean(LongRing) { sum, count -> sum / count } - - public fun evaluate(buffer: Buffer<Double>): Double = DoubleField.mean.evaluateBlocking(buffer) - public fun evaluate(buffer: Buffer<Int>): Int = IntRing.mean.evaluateBlocking(buffer) - public fun evaluate(buffer: Buffer<Long>): Long = LongRing.mean.evaluateBlocking(buffer) + public fun evaluate(buffer: Buffer<Double>): Double = Float64Field.mean.evaluateBlocking(buffer) + public fun evaluate(buffer: Buffer<Int>): Int = Int32Ring.mean.evaluateBlocking(buffer) + public fun evaluate(buffer: Buffer<Long>): Long = Int64Ring.mean.evaluateBlocking(buffer) } } //TODO replace with optimized version which respects overflow -public val DoubleField.mean: Mean<Double> get() = Mean(DoubleField) { sum, count -> sum / count } -public val IntRing.mean: Mean<Int> get() = Mean(IntRing) { sum, count -> sum / count } -public val LongRing.mean: Mean<Long> get() = Mean(LongRing) { sum, count -> sum / count } +public val Float64Field.mean: Mean<Double> get() = Mean(Float64Field) +public val Int32Ring.mean: Mean<Int> get() = Mean(Int32Field) +public val Int64Ring.mean: Mean<Long> get() = Mean(Int64Field) diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt index 87046cd46..dc504f0b7 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt @@ -5,17 +5,34 @@ package space.kscience.kmath.stat -import space.kscience.kmath.operations.asSequence +import space.kscience.kmath.misc.sortedWith +import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer /** * Non-composable median */ -public class Median<T>(private val comparator: Comparator<T>) : BlockingStatistic<T, T> { - override fun evaluateBlocking(data: Buffer<T>): T = - data.asSequence().sortedWith(comparator).toList()[data.size / 2] //TODO check if this is correct +public class Median<T>(private val field: Field<T>, private val comparator: Comparator<T>) : BlockingStatistic<T, T> { + + override fun evaluateBlocking(data: Buffer<T>): T = when { + data.size == 0 -> error("Can't compute median of an empty buffer") + data.size == 1 -> data[0] + data.size % 2 == 0 -> with(field) { + val sorted = data.sortedWith(comparator) + (sorted[data.size / 2 - 1] + sorted[data.size / 2]) / 2 + } + + else -> data.sortedWith(comparator)[(data.size - 1) / 2] + } public companion object { - public val real: Median<Double> = Median { a: Double, b: Double -> a.compareTo(b) } + + public fun evaluate(buffer: Buffer<Double>): Double = Float64Field.mean.evaluateBlocking(buffer) + public fun evaluate(buffer: Buffer<Int>): Int = Int32Ring.mean.evaluateBlocking(buffer) + public fun evaluate(buffer: Buffer<Long>): Long = Int64Ring.mean.evaluateBlocking(buffer) } -} \ No newline at end of file +} + +public val Float64Field.median: Median<Double> get() = Median(Float64Field) { a, b -> a.compareTo(b) } +public val Int32Ring.median: Median<Int> get() = Median(Int32Field) { a, b -> a.compareTo(b) } +public val Int64Ring.median: Median<Long> get() = Median(Int64Field) { a, b -> a.compareTo(b) } \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt index d7638ff81..7cb40a91a 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt @@ -15,7 +15,7 @@ import space.kscience.kmath.coroutines.mapParallel import space.kscience.kmath.structures.Buffer /** - * A function, that transforms a buffer of random quantities to some resulting value + * A function that transforms a buffer of random quantities to some resulting value */ public fun interface Statistic<in T, out R> { public suspend fun evaluate(data: Buffer<T>): R @@ -67,7 +67,7 @@ private fun <T, I, R> ComposableStatistic<T, I, R>.flowIntermediate( /** - * Perform a streaming statistical analysis on a chunked data. The computation of inner representation is done in parallel + * Perform a streaming statistical analysis on chunked data. The computation of inner representation is done in parallel * if [dispatcher] allows it. * * The resulting flow contains values that include the whole previous statistics, not only the last chunk. diff --git a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/stat/TestBasicStatistics.kt b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/stat/TestBasicStatistics.kt new file mode 100644 index 000000000..306574a76 --- /dev/null +++ b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/stat/TestBasicStatistics.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2018-2023 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.stat + +import space.kscience.kmath.UnstableKMathAPI +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.random.RandomGenerator +import space.kscience.kmath.structures.slice +import kotlin.test.Test +import kotlin.test.assertEquals + +@OptIn(UnstableKMathAPI::class) +class TestBasicStatistics { + companion object { + val float64Sample = RandomGenerator.default(123).nextDoubleBuffer(100) + } + + @Test + fun medianFloat64() { + assertEquals(0.508, Float64Field.median(float64Sample), 0.0005) + assertEquals(0.5055, Float64Field.median(float64Sample.slice { 0..<last }), 0.0005) + } + + @Test + fun meanFloat64() { + assertEquals(0.488, Float64Field.mean(float64Sample), 0.0002) + } +} \ No newline at end of file diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt index 3be7fa314..d64dcea4d 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt @@ -9,7 +9,7 @@ import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.last import kotlinx.coroutines.flow.take import kotlinx.coroutines.runBlocking -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.random.chain import space.kscience.kmath.streaming.chunked @@ -29,20 +29,20 @@ internal class StatisticTest { @Test fun singleBlockingMean() { val first = runBlocking { chunked.first() } - val res = DoubleField.mean(first) + val res = Float64Field.mean(first) assertEquals(0.5, res, 1e-1) } @Test fun singleSuspendMean() = runBlocking { val first = runBlocking { chunked.first() } - val res = DoubleField.mean(first) + val res = Float64Field.mean(first) assertEquals(0.5, res, 1e-1) } @Test fun parallelMean() = runBlocking { - val average = DoubleField.mean + val average = Float64Field.mean .flow(chunked) //create a flow from evaluated results .take(100) // Take 100 data chunks from the source and accumulate them .last() //get 1e5 data samples average diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt index 41c7c0b68..df8a01208 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt @@ -16,7 +16,7 @@ import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.nd.ColumnStrides import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.PowerOperations public class DoubleTensorFlowOutput( @@ -32,13 +32,13 @@ internal fun ShapeND.toLongArray(): LongArray = LongArray(size) { get(it).toLong public class DoubleTensorFlowAlgebra internal constructor( graph: Graph, -) : TensorFlowAlgebra<Double, TFloat64, DoubleField>(graph), PowerOperations<StructureND<Double>> { +) : TensorFlowAlgebra<Double, TFloat64, Float64Field>(graph), PowerOperations<StructureND<Double>> { - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field override fun structureND( shape: ShapeND, - initializer: DoubleField.(IntArray) -> Double, + initializer: Float64Field.(IntArray) -> Double, ): StructureND<Double> { val res = TFloat64.tensorOf(org.tensorflow.ndarray.Shape.of(*shape.toLongArray())) { array -> ColumnStrides(shape).forEach { index -> @@ -83,7 +83,7 @@ public class DoubleTensorFlowAlgebra internal constructor( * The resulting tensor is available outside of scope */ @UnstableKMathAPI -public fun DoubleField.produceWithTF( +public fun Float64Field.produceWithTF( block: DoubleTensorFlowAlgebra.() -> StructureND<Double>, ): StructureND<Double> = Graph().use { graph -> val scope = DoubleTensorFlowAlgebra(graph) @@ -96,7 +96,7 @@ public fun DoubleField.produceWithTF( * The resulting tensors are available outside of scope */ @OptIn(UnstableKMathAPI::class) -public fun DoubleField.produceMapWithTF( +public fun Float64Field.produceMapWithTF( block: DoubleTensorFlowAlgebra.() -> Map<Symbol, StructureND<Double>>, ): Map<Symbol, StructureND<Double>> = Graph().use { graph -> val scope = DoubleTensorFlowAlgebra(graph) diff --git a/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt b/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt index 730feede6..fe950f334 100644 --- a/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt +++ b/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt @@ -10,7 +10,7 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.get import space.kscience.kmath.nd.structureND -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.sum import space.kscience.kmath.tensors.core.randomNormal @@ -20,7 +20,7 @@ import kotlin.test.assertEquals class DoubleTensorFlowOps { @Test fun basicOps() { - val res = DoubleField.produceWithTF { + val res = Float64Field.produceWithTF { val initial = structureND(2, 2) { 1.0 } initial + (initial * 2.0) @@ -36,14 +36,14 @@ class DoubleTensorFlowOps { val tensor1 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12224) val tensor2 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12225) - DoubleField.produceWithTF { + Float64Field.produceWithTF { tensor1 dot tensor2 }.sum() } @Test fun extensionOps(){ - val res = DoubleField.produceWithTF { + val res = Float64Field.produceWithTF { val i = structureND(2, 2) { 0.5 } sin(i).pow(2) + cos(i).pow(2) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index c8cf56888..6bcf2753f 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -11,25 +11,28 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* import space.kscience.kmath.operations.DoubleBufferOps -import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra import space.kscience.kmath.tensors.api.LinearOpsTensorAlgebra import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.core.internal.* -import kotlin.math.* +import kotlin.math.abs +import kotlin.math.ceil +import kotlin.math.floor +import kotlin.math.sqrt /** * Implementation of basic operations over double tensors and basic algebra operations on them. */ @OptIn(PerformancePitfall::class) public open class DoubleTensorAlgebra : - AnalyticTensorAlgebra<Double, DoubleField>, - LinearOpsTensorAlgebra<Double, DoubleField> { + AnalyticTensorAlgebra<Double, Float64Field>, + LinearOpsTensorAlgebra<Double, Float64Field> { public companion object : DoubleTensorAlgebra() - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field public val bufferAlgebra: DoubleBufferOps get() = DoubleBufferOps @@ -41,10 +44,10 @@ public open class DoubleTensorAlgebra : * @return the resulting tensor after applying the function. */ @Suppress("OVERRIDE_BY_INLINE") - final override inline fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): DoubleTensor { + final override inline fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): DoubleTensor { val tensor = asDoubleTensor() //TODO remove additional copy - val array = DoubleBuffer(tensor.source.size) { DoubleField.transform(tensor.source[it]) } + val array = DoubleBuffer(tensor.source.size) { Float64Field.transform(tensor.source[it]) } return DoubleTensor( tensor.shape, array, @@ -59,12 +62,12 @@ public open class DoubleTensorAlgebra : } } - public inline fun Tensor<Double>.mapIndexedInPlace(operation: DoubleField.(IntArray, Double) -> Double) { - indices.forEach { set(it, DoubleField.operation(it, get(it))) } + public inline fun Tensor<Double>.mapIndexedInPlace(operation: Float64Field.(IntArray, Double) -> Double) { + indices.forEach { set(it, Float64Field.operation(it, get(it))) } } @Suppress("OVERRIDE_BY_INLINE") - final override inline fun StructureND<Double>.mapIndexed(transform: DoubleField.(index: IntArray, Double) -> Double): DoubleTensor { + final override inline fun StructureND<Double>.mapIndexed(transform: Float64Field.(index: IntArray, Double) -> Double): DoubleTensor { return copyToTensor().apply { mapIndexedInPlace(transform) } } @@ -73,14 +76,14 @@ public open class DoubleTensorAlgebra : final override inline fun zip( left: StructureND<Double>, right: StructureND<Double>, - transform: DoubleField.(Double, Double) -> Double, + transform: Float64Field.(Double, Double) -> Double, ): DoubleTensor { checkShapesCompatible(left, right) val leftTensor = left.asDoubleTensor() val rightTensor = right.asDoubleTensor() val buffer = DoubleBuffer(leftTensor.source.size) { - DoubleField.transform(leftTensor.source[it], rightTensor.source[it]) + Float64Field.transform(leftTensor.source[it], rightTensor.source[it]) } return DoubleTensor(leftTensor.shape, buffer) } @@ -124,9 +127,9 @@ public open class DoubleTensorAlgebra : * @param initializer mapping tensor indices to values. * @return tensor with the [shape] shape and data generated by the [initializer]. */ - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): DoubleTensor = fromArray( + override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): DoubleTensor = fromArray( shape, - RowStrides(shape).asSequence().map { DoubleField.initializer(it) }.toMutableList().toDoubleArray() + RowStrides(shape).asSequence().map { Float64Field.initializer(it) }.toMutableList().toDoubleArray() ) override fun Tensor<Double>.getTensor(i: Int): DoubleTensor { @@ -717,4 +720,4 @@ public open class DoubleTensorAlgebra : } public val Double.Companion.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra -public val DoubleField.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra \ No newline at end of file +public val Float64Field.tensorAlgebra: DoubleTensorAlgebra get() = DoubleTensorAlgebra \ No newline at end of file diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt index d1cdc68d4..a7899e84c 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt @@ -10,7 +10,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* -import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.api.* import space.kscience.kmath.tensors.core.internal.* @@ -19,12 +19,12 @@ import kotlin.math.* /** * Implementation of basic operations over double tensors and basic algebra operations on them. */ -public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> { +public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { public companion object : IntTensorAlgebra() - override val elementAlgebra: IntRing get() = IntRing + override val elementAlgebra: Int32Ring get() = Int32Ring /** @@ -34,10 +34,10 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> { * @return the resulting tensor after applying the function. */ @Suppress("OVERRIDE_BY_INLINE") - final override inline fun StructureND<Int>.map(transform: IntRing.(Int) -> Int): IntTensor { + final override inline fun StructureND<Int>.map(transform: Int32Ring.(Int) -> Int): IntTensor { val tensor = this.asIntTensor() //TODO remove additional copy - val array = IntBuffer(tensor.source.size) { IntRing.transform(tensor.source[it]) } + val array = IntBuffer(tensor.source.size) { Int32Ring.transform(tensor.source[it]) } return IntTensor( tensor.shape, array, @@ -57,11 +57,11 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> { } @Suppress("OVERRIDE_BY_INLINE") - final override inline fun StructureND<Int>.mapIndexed(transform: IntRing.(index: IntArray, Int) -> Int): IntTensor { + final override inline fun StructureND<Int>.mapIndexed(transform: Int32Ring.(index: IntArray, Int) -> Int): IntTensor { val tensor = this.asIntTensor() //TODO remove additional copy val buffer = IntBuffer(tensor.source.size) { - IntRing.transform(tensor.indices.index(it), tensor.source[it]) + Int32Ring.transform(tensor.indices.index(it), tensor.source[it]) } return IntTensor(tensor.shape, buffer) } @@ -70,14 +70,14 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> { final override inline fun zip( left: StructureND<Int>, right: StructureND<Int>, - transform: IntRing.(Int, Int) -> Int, + transform: Int32Ring.(Int, Int) -> Int, ): IntTensor { checkShapesCompatible(left, right) val leftTensor = left.asIntTensor() val rightTensor = right.asIntTensor() val buffer = IntBuffer(leftTensor.source.size) { - IntRing.transform(leftTensor.source[it], rightTensor.source[it]) + Int32Ring.transform(leftTensor.source[it], rightTensor.source[it]) } return IntTensor(leftTensor.shape, buffer) } @@ -118,9 +118,9 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> { * @param initializer mapping tensor indices to values. * @return tensor with the [shape] shape and data generated by the [initializer]. */ - override fun structureND(shape: ShapeND, initializer: IntRing.(IntArray) -> Int): IntTensor = fromArray( + override fun structureND(shape: ShapeND, initializer: Int32Ring.(IntArray) -> Int): IntTensor = fromArray( shape, - RowStrides(shape).asSequence().map { IntRing.initializer(it) }.toMutableList().toIntArray() + RowStrides(shape).asSequence().map { Int32Ring.initializer(it) }.toMutableList().toIntArray() ) override fun Tensor<Int>.getTensor(i: Int): IntTensor { @@ -462,6 +462,6 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, IntRing> { } public val Int.Companion.tensorAlgebra: IntTensorAlgebra get() = IntTensorAlgebra -public val IntRing.tensorAlgebra: IntTensorAlgebra get() = IntTensorAlgebra +public val Int32Ring.tensorAlgebra: IntTensorAlgebra get() = IntTensorAlgebra diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt index 8c7d6d199..f93066423 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt @@ -12,15 +12,15 @@ import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnsafeKMathAPI import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.* -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.ExtendedFieldOps +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.NumbersAddOps import space.kscience.kmath.operations.PowerOperations @OptIn(UnstableKMathAPI::class, PerformancePitfall::class) @Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public open class ViktorFieldOpsND : - FieldOpsND<Double, DoubleField>, + FieldOpsND<Double, Float64Field>, ExtendedFieldOps<StructureND<Double>>, PowerOperations<StructureND<Double>> { @@ -30,13 +30,13 @@ public open class ViktorFieldOpsND : else -> structureND(shape) { this@f64Buffer[it] }.f64Buffer } - override val elementAlgebra: DoubleField get() = DoubleField + override val elementAlgebra: Float64Field get() = Float64Field @OptIn(UnsafeKMathAPI::class) - override fun structureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): ViktorStructureND = + override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): ViktorStructureND = F64Array(*shape.asArray()).apply { ColumnStrides(shape).asSequence().forEach { index -> - set(value = DoubleField.initializer(index), indices = index) + set(value = Float64Field.initializer(index), indices = index) } }.asStructure() @@ -44,20 +44,20 @@ public open class ViktorFieldOpsND : @OptIn(UnsafeKMathAPI::class) @PerformancePitfall - override fun StructureND<Double>.map(transform: DoubleField.(Double) -> Double): ViktorStructureND = + override fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): ViktorStructureND = F64Array(*shape.asArray()).apply { ColumnStrides(ShapeND(shape)).asSequence().forEach { index -> - set(value = DoubleField.transform(this@map[index]), indices = index) + set(value = Float64Field.transform(this@map[index]), indices = index) } }.asStructure() @OptIn(UnsafeKMathAPI::class) @PerformancePitfall override fun StructureND<Double>.mapIndexed( - transform: DoubleField.(index: IntArray, Double) -> Double, + transform: Float64Field.(index: IntArray, Double) -> Double, ): ViktorStructureND = F64Array(*shape.asArray()).apply { ColumnStrides(ShapeND(shape)).asSequence().forEach { index -> - set(value = DoubleField.transform(index, this@mapIndexed[index]), indices = index) + set(value = Float64Field.transform(index, this@mapIndexed[index]), indices = index) } }.asStructure() @@ -66,12 +66,12 @@ public open class ViktorFieldOpsND : override fun zip( left: StructureND<Double>, right: StructureND<Double>, - transform: DoubleField.(Double, Double) -> Double, + transform: Float64Field.(Double, Double) -> Double, ): ViktorStructureND { require(left.shape.contentEquals(right.shape)) return F64Array(*left.shape.asArray()).apply { ColumnStrides(left.shape).asSequence().forEach { index -> - set(value = DoubleField.transform(left[index], right[index]), indices = index) + set(value = Float64Field.transform(left[index], right[index]), indices = index) } }.asStructure() } @@ -120,12 +120,12 @@ public open class ViktorFieldOpsND : public companion object : ViktorFieldOpsND() } -public val DoubleField.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND +public val Float64Field.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND @OptIn(UnstableKMathAPI::class) public open class ViktorFieldND( private val shapeAsArray: IntArray, -) : ViktorFieldOpsND(), FieldND<Double, DoubleField>, NumbersAddOps<StructureND<Double>> { +) : ViktorFieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>> { override val shape: ShapeND = ShapeND(shapeAsArray) @@ -137,6 +137,6 @@ public open class ViktorFieldND( F64Array.full(init = value.toDouble(), shape = shapeAsArray).asStructure() } -public fun DoubleField.viktorAlgebra(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape) +public fun Float64Field.viktorAlgebra(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape) public fun ViktorFieldND(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape) \ No newline at end of file From 19bebfd1ede651aed14e44b8e7326da7c8d9a043 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sat, 12 Aug 2023 11:21:59 +0300 Subject: [PATCH 045/103] Finish naming change --- CHANGELOG.md | 4 + .../kmath/benchmarks/BufferBenchmark.kt | 8 +- build.gradle.kts | 2 +- .../kmath/ejml/codegen/ejmlCodegen.kt | 14 +- .../kscience/kmath/functions/interpolate.kt | 4 +- .../space/kscience/kmath/linear/gradient.kt | 6 +- .../kmath/operations/mixedNDOperations.kt | 4 +- .../kmath/structures/StreamDoubleFieldND.kt | 6 +- .../structures/StructureReadBenchmark.kt | 2 +- .../structures/StructureWriteBenchmark.kt | 4 +- .../space/kscience/kmath/ast/TestFolding.kt | 4 +- .../kscience/kmath/commons/linear/CMMatrix.kt | 4 +- .../commons/transform/Transformations.kt | 4 +- .../commons/optimization/OptimizeTest.kt | 6 +- .../space/kscience/kmath/domains/Domain1D.kt | 2 +- .../{DoubleDomain.kt => Float64Domain.kt} | 2 +- .../kmath/domains/HyperSquareDomain.kt | 6 +- .../kmath/domains/UnconstrainedDomain.kt | 2 +- .../kmath/expressions/SymbolIndexer.kt | 6 +- ...leLinearSpace.kt => Float64LinearSpace.kt} | 38 ++-- .../kscience/kmath/linear/LupDecomposition.kt | 6 +- .../{DoubleFieldND.kt => Float64FieldND.kt} | 130 +++++------ .../nd/{ShortRingND.kt => Int16RingND.kt} | 12 +- .../space/kscience/kmath/nd/IntRingND.kt | 6 +- .../kmath/operations/DoubleBufferField.kt | 43 ---- .../kmath/operations/Float64BufferField.kt | 43 ++++ ...DoubleBufferOps.kt => Float64BufferOps.kt} | 100 ++++----- .../kmath/operations/integerFields.kt | 6 +- .../kscience/kmath/operations/numbers.kt | 212 +++++++++--------- .../space/kscience/kmath/structures/Buffer.kt | 8 +- .../{FloatBuffer.kt => Float32Buffer.kt} | 20 +- .../{DoubleBuffer.kt => Float64Buffer.kt} | 36 +-- .../{ShortBuffer.kt => Int16Buffer.kt} | 20 +- .../{IntBuffer.kt => Int32Buffer.kt} | 20 +- .../{LongBuffer.kt => Int64Buffer.kt} | 20 +- .../{ByteBuffer.kt => Int8Buffer.kt} | 18 +- .../kmath/structures/MutableBuffer.kt | 34 +-- .../kmath/structures/bufferPrimitiveAccess.kt | 4 +- .../space/kscience/kmath/misc/PermSortTest.kt | 6 +- .../kmath/chains/BlockingDoubleChain.kt | 8 +- .../kscience/kmath/chains/BlockingIntChain.kt | 4 +- .../kscience/kmath/streaming/BufferFlow.kt | 8 +- .../space/kscience/kmath/real/DoubleVector.kt | 4 +- .../space/kscience/kmath/real/RealMatrix.kt | 10 +- .../kotlin/space/kscience/kmath/real/grids.kt | 16 +- .../space/kscience/kmath/real/realND.kt | 4 +- .../kscience/kmath/real/DoubleVectorTest.kt | 12 +- .../integration/GaussIntegratorRuleFactory.kt | 10 +- .../kmath/integration/SplineIntegrator.kt | 10 +- .../kmath/integration/UnivariateIntegrand.kt | 4 +- .../kmath/interpolation/SplineInterpolator.kt | 4 +- .../kscience/kmath/geometry/RotationTest.kt | 8 +- .../kscience/kmath/histogram/Histogram.kt | 6 +- .../histogram/UniformHistogramGroupND.kt | 6 +- .../kmath/optimization/QowOptimizer.kt | 14 +- .../kscience/kmath/random/RandomChain.kt | 6 +- .../kscience/kmath/random/RandomGenerator.kt | 4 +- .../AhrensDieterExponentialSampler.kt | 4 +- .../kmath/samplers/BoxMullerSampler.kt | 6 +- .../samplers/KempSmallMeanPoissonSampler.kt | 4 +- .../MarsagliaNormalizedGaussianSampler.kt | 4 +- .../kscience/kmath/samplers/PoissonSampler.kt | 6 +- .../space/kscience/kmath/samplers/Sampler.kt | 8 +- .../ZigguratNormalizedGaussianSampler.kt | 4 +- .../core/BroadcastDoubleTensorAlgebra.kt | 10 +- .../kmath/tensors/core/DoubleTensor.kt | 14 +- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 24 +- .../kscience/kmath/tensors/core/IntTensor.kt | 14 +- .../kmath/tensors/core/IntTensorAlgebra.kt | 16 +- .../core/internal/doubleTensorHelpers.kt | 22 +- .../tensors/core/internal/intTensorHelpers.kt | 4 +- .../kmath/tensors/core/internal/linUtils.kt | 10 +- .../kmath/tensors/core/internal/utils.kt | 10 +- .../kscience/kmath/tensors/core/tensorOps.kt | 10 +- .../kmath/tensors/core/tensorTransform.kt | 8 +- .../kmath/tensors/core/TestDoubleTensor.kt | 10 +- .../tensors/core/offsetBufferEquality.kt | 4 +- .../kmath/tensors/core/TestLmAlgorithm.kt | 4 +- .../src/commonMain/kotlin/bufferEquality.kt | 10 +- 79 files changed, 619 insertions(+), 597 deletions(-) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/{DoubleDomain.kt => Float64Domain.kt} (92%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/{DoubleLinearSpace.kt => Float64LinearSpace.kt} (71%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/{DoubleFieldND.kt => Float64FieldND.kt} (57%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/{ShortRingND.kt => Int16RingND.kt} (76%) delete mode 100644 kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferField.kt create mode 100644 kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/{DoubleBufferOps.kt => Float64BufferOps.kt} (54%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/{FloatBuffer.kt => Float32Buffer.kt} (62%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/{DoubleBuffer.kt => Float64Buffer.kt} (50%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/{ShortBuffer.kt => Int16Buffer.kt} (65%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/{IntBuffer.kt => Int32Buffer.kt} (61%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/{LongBuffer.kt => Int64Buffer.kt} (63%) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/{ByteBuffer.kt => Int8Buffer.kt} (67%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f011881f..9235cfd57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,18 @@ ## Unreleased ### Added +- Integer divistion algebras ### Changed +- Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types. +- Remove unnecessary inlines in basic algebras. ### Deprecated ### Removed ### Fixed +- Median statistics ### Security diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt index c2616303b..1675216eb 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt @@ -14,7 +14,7 @@ import space.kscience.kmath.complex.ComplexField import space.kscience.kmath.complex.complex import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.getDouble import space.kscience.kmath.structures.permute @@ -33,7 +33,7 @@ internal class BufferBenchmark { @Benchmark fun doubleBufferReadWrite(blackhole: Blackhole) { - val buffer = DoubleBuffer(size) { it.toDouble() } + val buffer = Float64Buffer(size) { it.toDouble() } var res = 0.0 (0 until size).forEach { res += buffer[it] @@ -43,7 +43,7 @@ internal class BufferBenchmark { @Benchmark fun bufferViewReadWrite(blackhole: Blackhole) { - val buffer = DoubleBuffer(size) { it.toDouble() }.permute(reversedIndices) + val buffer = Float64Buffer(size) { it.toDouble() }.permute(reversedIndices) var res = 0.0 (0 until size).forEach { res += buffer[it] @@ -53,7 +53,7 @@ internal class BufferBenchmark { @Benchmark fun bufferViewReadWriteSpecialized(blackhole: Blackhole) { - val buffer = DoubleBuffer(size) { it.toDouble() }.permute(reversedIndices) + val buffer = Float64Buffer(size) { it.toDouble() }.permute(reversedIndices) var res = 0.0 (0 until size).forEach { res += buffer.getDouble(it) diff --git a/build.gradle.kts b/build.gradle.kts index 7dbe87445..e2c5fc44f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -15,7 +15,7 @@ allprojects { } group = "space.kscience" - version = "0.3.2-dev-1" + version = "0.4.0-dev-2" } subprojects { diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt index d973ebae4..41b88f093 100644 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt +++ b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt @@ -387,9 +387,15 @@ import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature +import space.kscience.kmath.structures.Float64 +import space.kscience.kmath.structures.Float32 +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Float32Field import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.FloatField import space.kscience.kmath.operations.invoke +import space.kscience.kmath.structures.Float64Buffer +import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass @@ -399,12 +405,12 @@ import kotlin.reflect.cast""") it.appendEjmlVector("Float", "FMatrix") it.appendEjmlMatrix("Double", "DMatrix") it.appendEjmlMatrix("Float", "FMatrix") - it.appendEjmlLinearSpace("Double", "DoubleField", "DMatrix", "DMatrixRMaj", "DMatrixRMaj", "DDRM", "DDRM", true) - it.appendEjmlLinearSpace("Float", "FloatField", "FMatrix", "FMatrixRMaj", "FMatrixRMaj", "FDRM", "FDRM", true) + it.appendEjmlLinearSpace("Double", "Float64Field", "DMatrix", "DMatrixRMaj", "DMatrixRMaj", "DDRM", "DDRM", true) + it.appendEjmlLinearSpace("Float", "Float32Field", "FMatrix", "FMatrixRMaj", "FMatrixRMaj", "FDRM", "FDRM", true) it.appendEjmlLinearSpace( type = "Double", - kmathAlgebra = "DoubleField", + kmathAlgebra = "Float64Field", ejmlMatrixParentTypeMatrix = "DMatrix", ejmlMatrixType = "DMatrixSparseCSC", ejmlMatrixDenseType = "DMatrixRMaj", @@ -415,7 +421,7 @@ import kotlin.reflect.cast""") it.appendEjmlLinearSpace( type = "Float", - kmathAlgebra = "FloatField", + kmathAlgebra = "Float32Field", ejmlMatrixParentTypeMatrix = "FMatrix", ejmlMatrixType = "FMatrixSparseCSC", ejmlMatrixDenseType = "FMatrixRMaj", diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt index 9bde80a87..6908eebdd 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.functions import space.kscience.kmath.interpolation.SplineInterpolator import space.kscience.kmath.interpolation.interpolatePolynomials import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.plotly.Plotly import space.kscience.plotly.UnstablePlotlyAPI import space.kscience.plotly.makeFile @@ -25,7 +25,7 @@ fun main() { } val polynomial: PiecewisePolynomial<Double> = SplineInterpolator( - Float64Field, ::DoubleBuffer + Float64Field, ::Float64Buffer ).interpolatePolynomials(data) val function = polynomial.asFunction(Float64Field, 0.0) diff --git a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt index 52ed8f05f..eb170e7fa 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.linear import space.kscience.kmath.real.* -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer fun main() { val x0 = DoubleVector(0.0, 0.0, 0.0) @@ -19,9 +19,9 @@ fun main() { fun ((Point<Double>) -> Double).grad(x: Point<Double>): Point<Double> { require(x.size == x0.size) - return DoubleBuffer(x.size) { i -> + return Float64Buffer(x.size) { i -> val h = sigma[i] / 5 - val dVector = DoubleBuffer(x.size) { if (it == i) h else 0.0 } + val dVector = Float64Buffer(x.size) { if (it == i) h else 0.0 } val f1 = this(x + dVector / 2) val f0 = this(x - dVector / 2) (f1 - f0) / h diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt index 6094d4d4a..bb69c6aff 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.operations import space.kscience.kmath.commons.linear.CMLinearSpace import space.kscience.kmath.linear.matrix -import space.kscience.kmath.nd.DoubleBufferND +import space.kscience.kmath.nd.Float64BufferND import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.nd.ndAlgebra @@ -21,7 +21,7 @@ fun main() { val cmMatrix: Structure2D<Double> = CMLinearSpace.matrix(2, 2)(0.0, 1.0, 0.0, 3.0) - val res: DoubleBufferND = Float64Field.ndAlgebra { + val res: Float64BufferND = Float64Field.ndAlgebra { exp(viktorStructure) + 2.0 * cmMatrix } diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt index e46e50821..a0e25b81b 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt @@ -32,15 +32,15 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64 } @OptIn(PerformancePitfall::class) - private val StructureND<Double>.buffer: DoubleBuffer + private val StructureND<Double>.buffer: Float64Buffer get() = when { !shape.contentEquals(this@StreamDoubleFieldND.shape) -> throw ShapeMismatchException( this@StreamDoubleFieldND.shape, shape ) - this is BufferND && indices == this@StreamDoubleFieldND.strides -> this.buffer as DoubleBuffer - else -> DoubleBuffer(strides.linearSize) { offset -> get(strides.index(offset)) } + this is BufferND && indices == this@StreamDoubleFieldND.strides -> this.buffer as Float64Buffer + else -> Float64Buffer(strides.linearSize) { offset -> get(strides.index(offset)) } } override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): BufferND<Double> { diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt index e6ff0ee28..1e50ef7da 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt @@ -16,7 +16,7 @@ import kotlin.system.measureTimeMillis fun main() { val n = 6000 val array = DoubleArray(n * n) { 1.0 } - val buffer = DoubleBuffer(array) + val buffer = Float64Buffer(array) val strides = ColumnStrides(ShapeND(n, n)) val structure = BufferND(strides, buffer) diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt index 14c058417..4aa7b74dd 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt @@ -32,10 +32,10 @@ fun main() { println("Array mapping finished in $time2 millis") - val buffer = DoubleBuffer(DoubleArray(n * n) { 1.0 }) + val buffer = Float64Buffer(DoubleArray(n * n) { 1.0 }) val time3 = measureTimeMillis { - val target = DoubleBuffer(DoubleArray(n * n)) + val target = Float64Buffer(DoubleArray(n * n)) val res = array.forEachIndexed { index, value -> target[index] = value + 1 } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt index d67d965ce..61a37944a 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt @@ -5,9 +5,9 @@ package space.kscience.kmath.ast -import space.kscience.kmath.operations.ByteRing import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Int32Ring +import space.kscience.kmath.operations.Int8Ring import space.kscience.kmath.operations.pi import kotlin.test.Test import kotlin.test.assertEquals @@ -47,6 +47,6 @@ internal class TestFolding { @Test fun foldNumeric() = assertEquals( 42.toByte(), - ("42".parseMath().evaluateConstants(ByteRing) as? TypedMst.Constant<Byte> ?: fail()).value, + ("42".parseMath().evaluateConstants(Int8Ring) as? TypedMst.Constant<Byte> ?: fail()).value, ) } diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index 449aa79ce..4d2e2aa90 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -11,7 +11,7 @@ import space.kscience.kmath.linear.* import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.reflect.KClass import kotlin.reflect.cast @@ -136,7 +136,7 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> { override val u: Matrix<Double> by lazy { CMMatrix(sv.u) } override val s: Matrix<Double> by lazy { CMMatrix(sv.s) } override val v: Matrix<Double> by lazy { CMMatrix(sv.v) } - override val singularValues: Point<Double> by lazy { DoubleBuffer(sv.singularValues) } + override val singularValues: Point<Double> by lazy { Float64Buffer(sv.singularValues) } } else -> null }?.let(type::cast) diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt index a77da2d2f..de271aedc 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt @@ -47,7 +47,7 @@ public object Transformations { public fun sine( normalization: DstNormalization = DstNormalization.STANDARD_DST_I, direction: TransformType = TransformType.FORWARD, - ): BufferTransform<Double, Double> = DoubleBufferTransform { + ): BufferTransform<Double, Double> = Float64BufferTransform { FastSineTransformer(normalization).transform(it.array, direction).asBuffer() } @@ -60,7 +60,7 @@ public object Transformations { public fun hadamard( direction: TransformType = TransformType.FORWARD, - ): BufferTransform<Double, Double> = DoubleBufferTransform { + ): BufferTransform<Double, Double> = Float64BufferTransform { FastHadamardTransformer().transform(it.array, direction).asBuffer() } } diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt index bf687aa72..5933d0d36 100644 --- a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt +++ b/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt @@ -13,12 +13,12 @@ import space.kscience.kmath.expressions.Symbol.Companion.x import space.kscience.kmath.expressions.Symbol.Companion.y import space.kscience.kmath.expressions.autodiff import space.kscience.kmath.expressions.symbol -import space.kscience.kmath.operations.DoubleBufferOps.Companion.map +import space.kscience.kmath.operations.Float64BufferOps.Companion.map import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.optimization.* import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.stat.chiSquaredExpression -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.asBuffer import kotlin.test.Test @@ -61,7 +61,7 @@ internal class OptimizeTest { it.pow(2) + it + 1 + chain.next() } - val yErr = DoubleBuffer(x.size) { sigma } + val yErr = Float64Buffer(x.size) { sigma } val chi2 = Double.autodiff.chiSquaredExpression( x, y, yErr diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain1D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain1D.kt index d619883b4..b03e60e95 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain1D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain1D.kt @@ -23,7 +23,7 @@ public abstract class Domain1D<T : Comparable<T>>(public val range: ClosedRange< @UnstableKMathAPI public class DoubleDomain1D( @Suppress("CanBeParameter") public val doubleRange: ClosedFloatingPointRange<Double>, -) : Domain1D<Double>(doubleRange), DoubleDomain { +) : Domain1D<Double>(doubleRange), Float64Domain { override fun getLowerBound(num: Int): Double { require(num == 0) return range.start diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/DoubleDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Float64Domain.kt similarity index 92% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/DoubleDomain.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Float64Domain.kt index e56173624..7878f2551 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/DoubleDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Float64Domain.kt @@ -12,7 +12,7 @@ import space.kscience.kmath.UnstableKMathAPI * @author Alexander Nozik */ @UnstableKMathAPI -public interface DoubleDomain : Domain<Double> { +public interface Float64Domain : Domain<Double> { /** * Global lower edge * @param num axis number diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt index 1049a251a..03a080a70 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.domains import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.Point import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.indices /** @@ -15,7 +15,7 @@ import space.kscience.kmath.structures.indices * and a [Buffer] of upper boundaries. Upper should be greater or equals than lower. */ @UnstableKMathAPI -public class HyperSquareDomain(public val lower: Buffer<Double>, public val upper: Buffer<Double>) : DoubleDomain { +public class HyperSquareDomain(public val lower: Buffer<Double>, public val upper: Buffer<Double>) : Float64Domain { init { require(lower.size == upper.size) { "Domain borders size mismatch. Lower borders size is ${lower.size}, but upper borders size is ${upper.size}." @@ -27,7 +27,7 @@ public class HyperSquareDomain(public val lower: Buffer<Double>, public val uppe override val dimension: Int get() = lower.size - public val center: DoubleBuffer get() = DoubleBuffer(dimension) { (lower[it] + upper[it]) / 2.0 } + public val center: Float64Buffer get() = Float64Buffer(dimension) { (lower[it] + upper[it]) / 2.0 } override operator fun contains(point: Point<Double>): Boolean = point.indices.all { i -> point[i] in lower[i]..upper[i] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt index 5351a295d..b78190c9b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt @@ -8,7 +8,7 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.Point @UnstableKMathAPI -public class UnconstrainedDomain(override val dimension: Int) : DoubleDomain { +public class UnconstrainedDomain(override val dimension: Int) : Float64Domain { override operator fun contains(point: Point<Double>): Boolean = true override fun getLowerBound(num: Int): Double = Double.NEGATIVE_INFINITY diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt index 7112e921a..f0e39d489 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt @@ -9,7 +9,7 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.Point import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.jvm.JvmInline @@ -62,8 +62,8 @@ public interface SymbolIndexer { public fun <T> Map<Symbol, T>.toPoint(bufferFactory: BufferFactory<T>): Point<T> = bufferFactory(symbols.size) { getValue(symbols[it]) } - public fun Map<Symbol, Double>.toPoint(): DoubleBuffer = - DoubleBuffer(symbols.size) { getValue(symbols[it]) } + public fun Map<Symbol, Double>.toPoint(): Float64Buffer = + Float64Buffer(symbols.size) { getValue(symbols[it]) } public fun Map<Symbol, Double>.toDoubleArray(): DoubleArray = DoubleArray(symbols.size) { getValue(symbols[it]) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt similarity index 71% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt index 4f631336c..eb4434c00 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/DoubleLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt @@ -7,13 +7,13 @@ package space.kscience.kmath.linear import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* -import space.kscience.kmath.operations.DoubleBufferOps +import space.kscience.kmath.operations.Float64BufferOps import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer -public object DoubleLinearSpace : LinearSpace<Double, Float64Field> { +public object Float64LinearSpace : LinearSpace<Double, Float64Field> { override val elementAlgebra: Float64Field get() = Float64Field @@ -21,29 +21,29 @@ public object DoubleLinearSpace : LinearSpace<Double, Float64Field> { rows: Int, columns: Int, initializer: Float64Field.(i: Int, j: Int) -> Double - ): Matrix<Double> = DoubleFieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) -> + ): Matrix<Double> = Floa64FieldOpsND.structureND(ShapeND(rows, columns)) { (i, j) -> Float64Field.initializer(i, j) }.as2D() - override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): DoubleBuffer = - DoubleBuffer(size) { Float64Field.initializer(it) } + override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Float64Buffer = + Float64Buffer(size) { Float64Field.initializer(it) } - override fun Matrix<Double>.unaryMinus(): Matrix<Double> = DoubleFieldOpsND { + override fun Matrix<Double>.unaryMinus(): Matrix<Double> = Floa64FieldOpsND { asND().map { -it }.as2D() } - override fun Matrix<Double>.plus(other: Matrix<Double>): Matrix<Double> = DoubleFieldOpsND { + override fun Matrix<Double>.plus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND { require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" } asND().plus(other.asND()).as2D() } - override fun Matrix<Double>.minus(other: Matrix<Double>): Matrix<Double> = DoubleFieldOpsND { + override fun Matrix<Double>.minus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND { require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" } asND().minus(other.asND()).as2D() } // Create a continuous in-memory representation of this vector for better memory layout handling - private fun Buffer<Double>.linearize() = if (this is DoubleBuffer) { + private fun Buffer<Double>.linearize() = if (this is Float64Buffer) { this.array } else { DoubleArray(size) { get(it) } @@ -66,10 +66,10 @@ public object DoubleLinearSpace : LinearSpace<Double, Float64Field> { } @OptIn(PerformancePitfall::class) - override fun Matrix<Double>.dot(vector: Point<Double>): DoubleBuffer { + override fun Matrix<Double>.dot(vector: Point<Double>): Float64Buffer { require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" } val rows = this@dot.rows.map { it.linearize() } - return DoubleBuffer(rowNum) { i -> + return Float64Buffer(rowNum) { i -> val r = rows[i] var res = 0.0 for (j in r.indices) { @@ -80,29 +80,29 @@ public object DoubleLinearSpace : LinearSpace<Double, Float64Field> { } - override fun Matrix<Double>.times(value: Double): Matrix<Double> = DoubleFieldOpsND { + override fun Matrix<Double>.times(value: Double): Matrix<Double> = Floa64FieldOpsND { asND().map { it * value }.as2D() } - public override fun Point<Double>.plus(other: Point<Double>): DoubleBuffer = DoubleBufferOps.run { + public override fun Point<Double>.plus(other: Point<Double>): Float64Buffer = Float64BufferOps.run { this@plus + other } - public override fun Point<Double>.minus(other: Point<Double>): DoubleBuffer = DoubleBufferOps.run { + public override fun Point<Double>.minus(other: Point<Double>): Float64Buffer = Float64BufferOps.run { this@minus - other } - public override fun Point<Double>.times(value: Double): DoubleBuffer = DoubleBufferOps.run { + public override fun Point<Double>.times(value: Double): Float64Buffer = Float64BufferOps.run { scale(this@times, value) } - public operator fun Point<Double>.div(value: Double): DoubleBuffer = DoubleBufferOps.run { + public operator fun Point<Double>.div(value: Double): Float64Buffer = Float64BufferOps.run { scale(this@div, 1.0 / value) } - public override fun Double.times(v: Point<Double>): DoubleBuffer = v * this + public override fun Double.times(v: Point<Double>): Float64Buffer = v * this } -public val Float64Field.linearSpace: DoubleLinearSpace get() = DoubleLinearSpace +public val Float64Field.linearSpace: Float64LinearSpace get() = Float64LinearSpace diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 4bb67bce9..ce55623de 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.linear import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* import space.kscience.kmath.structures.BufferAccessor2D -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.MutableBufferFactory @@ -159,7 +159,7 @@ public fun LinearSpace<Double, Float64Field>.lup( matrix: Matrix<Double>, singularityThreshold: Double = 1e-11, ): LupDecomposition<Double> = - lup(::DoubleBuffer, matrix) { it < singularityThreshold } + lup(::Float64Buffer, matrix) { it < singularityThreshold } internal fun <T : Any> LupDecomposition<T>.solve( factory: MutableBufferFactory<T>, @@ -227,4 +227,4 @@ public fun <T : Comparable<T>, F : Field<T>> LinearSpace<T, F>.lupSolver( } public fun LinearSpace<Double, Float64Field>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> = - lupSolver(::DoubleBuffer) { it < singularityThreshold } + lupSolver(::Float64Buffer) { it < singularityThreshold } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt similarity index 57% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt index 2f47f0b37..464ee16b9 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/DoubleFieldND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.nd import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.math.pow @@ -17,9 +17,9 @@ import kotlin.math.pow as kpow /** * A simple mutable [StructureND] of doubles */ -public class DoubleBufferND( +public class Float64BufferND( indexes: ShapeIndexer, - override val buffer: DoubleBuffer, + override val buffer: Float64Buffer, ) : MutableBufferND<Double>(indexes, buffer), MutableStructureNDOfDouble{ override fun getDouble(index: IntArray): Double = buffer[indices.offset(index)] @@ -29,37 +29,37 @@ public class DoubleBufferND( } -public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, Float64Field>(Float64Field.bufferAlgebra), +public sealed class Floa64FieldOpsND : BufferedFieldOpsND<Double, Float64Field>(Float64Field.bufferAlgebra), ScaleOperations<StructureND<Double>>, ExtendedFieldOps<StructureND<Double>> { @OptIn(PerformancePitfall::class) - override fun StructureND<Double>.toBufferND(): DoubleBufferND = when (this) { - is DoubleBufferND -> this + override fun StructureND<Double>.toBufferND(): Float64BufferND = when (this) { + is Float64BufferND -> this else -> { val indexer = indexerBuilder(shape) - DoubleBufferND(indexer, DoubleBuffer(indexer.linearSize) { offset -> get(indexer.index(offset)) }) + Float64BufferND(indexer, Float64Buffer(indexer.linearSize) { offset -> get(indexer.index(offset)) }) } } protected inline fun mapInline( - arg: DoubleBufferND, + arg: Float64BufferND, transform: (Double) -> Double, - ): DoubleBufferND { + ): Float64BufferND { val indexes = arg.indices val array = arg.buffer.array - return DoubleBufferND(indexes, DoubleBuffer(indexes.linearSize) { transform(array[it]) }) + return Float64BufferND(indexes, Float64Buffer(indexes.linearSize) { transform(array[it]) }) } private inline fun zipInline( - l: DoubleBufferND, - r: DoubleBufferND, + l: Float64BufferND, + r: Float64BufferND, block: (l: Double, r: Double) -> Double, - ): DoubleBufferND { + ): Float64BufferND { require(l.indices == r.indices) { "Zip requires the same shapes, but found ${l.shape} on the left and ${r.shape} on the right" } val indexes = l.indices val lArray = l.buffer.array val rArray = r.buffer.array - return DoubleBufferND(indexes, DoubleBuffer(indexes.linearSize) { block(lArray[it], rArray[it]) }) + return Float64BufferND(indexes, Float64Buffer(indexes.linearSize) { block(lArray[it], rArray[it]) }) } @OptIn(PerformancePitfall::class) @@ -74,56 +74,56 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, Float64Field>( transform: Float64Field.(Double, Double) -> Double, ): BufferND<Double> = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> Float64Field.transform(l, r) } - override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): DoubleBufferND { + override fun structureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): Float64BufferND { val indexer = indexerBuilder(shape) - return DoubleBufferND( + return Float64BufferND( indexer, - DoubleBuffer(indexer.linearSize) { offset -> + Float64Buffer(indexer.linearSize) { offset -> elementAlgebra.initializer(indexer.index(offset)) } ) } - override fun add(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND = + override fun add(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l + r } - override fun multiply(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND = + override fun multiply(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND = zipInline(left.toBufferND(), right.toBufferND()) { l, r -> l * r } - override fun StructureND<Double>.unaryMinus(): DoubleBufferND = mapInline(toBufferND()) { -it } + override fun StructureND<Double>.unaryMinus(): Float64BufferND = mapInline(toBufferND()) { -it } - override fun StructureND<Double>.div(arg: StructureND<Double>): DoubleBufferND = + override fun StructureND<Double>.div(arg: StructureND<Double>): Float64BufferND = zipInline(toBufferND(), arg.toBufferND()) { l, r -> l / r } - override fun divide(left: StructureND<Double>, right: StructureND<Double>): DoubleBufferND = + override fun divide(left: StructureND<Double>, right: StructureND<Double>): Float64BufferND = zipInline(left.toBufferND(), right.toBufferND()) { l: Double, r: Double -> l / r } - override fun StructureND<Double>.div(arg: Double): DoubleBufferND = + override fun StructureND<Double>.div(arg: Double): Float64BufferND = mapInline(toBufferND()) { it / arg } - override fun Double.div(arg: StructureND<Double>): DoubleBufferND = + override fun Double.div(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { this / it } - override fun StructureND<Double>.unaryPlus(): DoubleBufferND = toBufferND() + override fun StructureND<Double>.unaryPlus(): Float64BufferND = toBufferND() - override fun StructureND<Double>.plus(arg: StructureND<Double>): DoubleBufferND = + override fun StructureND<Double>.plus(arg: StructureND<Double>): Float64BufferND = zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l + r } - override fun StructureND<Double>.minus(arg: StructureND<Double>): DoubleBufferND = + override fun StructureND<Double>.minus(arg: StructureND<Double>): Float64BufferND = zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l - r } - override fun StructureND<Double>.times(arg: StructureND<Double>): DoubleBufferND = + override fun StructureND<Double>.times(arg: StructureND<Double>): Float64BufferND = zipInline(toBufferND(), arg.toBufferND()) { l: Double, r: Double -> l * r } - override fun StructureND<Double>.times(k: Number): DoubleBufferND = + override fun StructureND<Double>.times(k: Number): Float64BufferND = mapInline(toBufferND()) { it * k.toDouble() } - override fun StructureND<Double>.div(k: Number): DoubleBufferND = + override fun StructureND<Double>.div(k: Number): Float64BufferND = mapInline(toBufferND()) { it / k.toDouble() } - override fun Number.times(arg: StructureND<Double>): DoubleBufferND = arg * this + override fun Number.times(arg: StructureND<Double>): Float64BufferND = arg * this - override fun StructureND<Double>.plus(arg: Double): DoubleBufferND = mapInline(toBufferND()) { it + arg } + override fun StructureND<Double>.plus(arg: Double): Float64BufferND = mapInline(toBufferND()) { it + arg } override fun StructureND<Double>.minus(arg: Double): StructureND<Double> = mapInline(toBufferND()) { it - arg } @@ -131,49 +131,49 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, Float64Field>( override fun Double.minus(arg: StructureND<Double>): StructureND<Double> = mapInline(arg.toBufferND()) { this - it } - override fun scale(a: StructureND<Double>, value: Double): DoubleBufferND = + override fun scale(a: StructureND<Double>, value: Double): Float64BufferND = mapInline(a.toBufferND()) { it * value } - override fun exp(arg: StructureND<Double>): DoubleBufferND = + override fun exp(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.exp(it) } - override fun ln(arg: StructureND<Double>): DoubleBufferND = + override fun ln(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.ln(it) } - override fun sin(arg: StructureND<Double>): DoubleBufferND = + override fun sin(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.sin(it) } - override fun cos(arg: StructureND<Double>): DoubleBufferND = + override fun cos(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.cos(it) } - override fun tan(arg: StructureND<Double>): DoubleBufferND = + override fun tan(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.tan(it) } - override fun asin(arg: StructureND<Double>): DoubleBufferND = + override fun asin(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.asin(it) } - override fun acos(arg: StructureND<Double>): DoubleBufferND = + override fun acos(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.acos(it) } - override fun atan(arg: StructureND<Double>): DoubleBufferND = + override fun atan(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.atan(it) } - override fun sinh(arg: StructureND<Double>): DoubleBufferND = + override fun sinh(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.sinh(it) } - override fun cosh(arg: StructureND<Double>): DoubleBufferND = + override fun cosh(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.cosh(it) } - override fun tanh(arg: StructureND<Double>): DoubleBufferND = + override fun tanh(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.tanh(it) } - override fun asinh(arg: StructureND<Double>): DoubleBufferND = + override fun asinh(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.asinh(it) } - override fun acosh(arg: StructureND<Double>): DoubleBufferND = + override fun acosh(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.acosh(it) } - override fun atanh(arg: StructureND<Double>): DoubleBufferND = + override fun atanh(arg: StructureND<Double>): Float64BufferND = mapInline(arg.toBufferND()) { kotlin.math.atanh(it) } override fun power( @@ -185,23 +185,23 @@ public sealed class DoubleFieldOpsND : BufferedFieldOpsND<Double, Float64Field>( mapInline(arg.toBufferND()) { it.pow(pow.toDouble()) } } - public companion object : DoubleFieldOpsND() + public companion object : Floa64FieldOpsND() } @OptIn(UnstableKMathAPI::class) -public class DoubleFieldND(override val shape: ShapeND) : - DoubleFieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>>, +public class Float64FieldND(override val shape: ShapeND) : + Floa64FieldOpsND(), FieldND<Double, Float64Field>, NumbersAddOps<StructureND<Double>>, ExtendedField<StructureND<Double>> { - override fun power(arg: StructureND<Double>, pow: UInt): DoubleBufferND = mapInline(arg.toBufferND()) { + override fun power(arg: StructureND<Double>, pow: UInt): Float64BufferND = mapInline(arg.toBufferND()) { it.kpow(pow.toInt()) } - override fun power(arg: StructureND<Double>, pow: Int): DoubleBufferND = mapInline(arg.toBufferND()) { + override fun power(arg: StructureND<Double>, pow: Int): Float64BufferND = mapInline(arg.toBufferND()) { it.kpow(pow) } - override fun power(arg: StructureND<Double>, pow: Number): DoubleBufferND = if (pow.isInteger()) { + override fun power(arg: StructureND<Double>, pow: Number): Float64BufferND = if (pow.isInteger()) { power(arg, pow.toInt()) } else { val dpow = pow.toDouble() @@ -211,34 +211,34 @@ public class DoubleFieldND(override val shape: ShapeND) : } } - override fun sinh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.sinh(arg) + override fun sinh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.sinh(arg) - override fun cosh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.cosh(arg) + override fun cosh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.cosh(arg) - override fun tanh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.tan(arg) + override fun tanh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.tan(arg) - override fun asinh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.asinh(arg) + override fun asinh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.asinh(arg) - override fun acosh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.acosh(arg) + override fun acosh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.acosh(arg) - override fun atanh(arg: StructureND<Double>): DoubleBufferND = super<DoubleFieldOpsND>.atanh(arg) + override fun atanh(arg: StructureND<Double>): Float64BufferND = super<Floa64FieldOpsND>.atanh(arg) - override fun number(value: Number): DoubleBufferND { + override fun number(value: Number): Float64BufferND { val d = value.toDouble() // minimize conversions return structureND(shape) { d } } } -public val Float64Field.ndAlgebra: DoubleFieldOpsND get() = DoubleFieldOpsND +public val Float64Field.ndAlgebra: Floa64FieldOpsND get() = Floa64FieldOpsND -public fun Float64Field.ndAlgebra(vararg shape: Int): DoubleFieldND = DoubleFieldND(ShapeND(shape)) -public fun Float64Field.ndAlgebra(shape: ShapeND): DoubleFieldND = DoubleFieldND(shape) +public fun Float64Field.ndAlgebra(vararg shape: Int): Float64FieldND = Float64FieldND(ShapeND(shape)) +public fun Float64Field.ndAlgebra(shape: ShapeND): Float64FieldND = Float64FieldND(shape) /** * Produce a context for n-dimensional operations inside this real field */ @UnstableKMathAPI -public inline fun <R> Float64Field.withNdAlgebra(vararg shape: Int, action: DoubleFieldND.() -> R): R { +public inline fun <R> Float64Field.withNdAlgebra(vararg shape: Int, action: Float64FieldND.() -> R): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } - return DoubleFieldND(ShapeND(shape)).run(action) + return Float64FieldND(ShapeND(shape)).run(action) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt similarity index 76% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt index 12f59dc72..758a486f5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShortRingND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt @@ -12,14 +12,14 @@ import space.kscience.kmath.operations.bufferAlgebra import kotlin.contracts.InvocationKind import kotlin.contracts.contract -public sealed class ShortRingOpsND : BufferedRingOpsND<Short, Int16Ring>(Int16Ring.bufferAlgebra) { - public companion object : ShortRingOpsND() +public sealed class Int16RingOpsND : BufferedRingOpsND<Short, Int16Ring>(Int16Ring.bufferAlgebra) { + public companion object : Int16RingOpsND() } @OptIn(UnstableKMathAPI::class) -public class ShortRingND( +public class Int16RingND( override val shape: ShapeND -) : ShortRingOpsND(), RingND<Short, Int16Ring>, NumbersAddOps<StructureND<Short>> { +) : Int16RingOpsND(), RingND<Short, Int16Ring>, NumbersAddOps<StructureND<Short>> { override fun number(value: Number): BufferND<Short> { val short @@ -28,7 +28,7 @@ public class ShortRingND( } } -public inline fun <R> Int16Ring.withNdAlgebra(vararg shape: Int, action: ShortRingND.() -> R): R { +public inline fun <R> Int16Ring.withNdAlgebra(vararg shape: Int, action: Int16RingND.() -> R): R { contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) } - return ShortRingND(ShapeND(shape)).run(action) + return Int16RingND(ShapeND(shape)).run(action) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt index 4ce2b80e6..039432bc7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt @@ -9,13 +9,13 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.operations.NumbersAddOps import space.kscience.kmath.operations.bufferAlgebra -import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.Int32Buffer import kotlin.contracts.InvocationKind import kotlin.contracts.contract public class IntBufferND( indexes: ShapeIndexer, - override val buffer: IntBuffer, + override val buffer: Int32Buffer, ) : MutableBufferND<Int>(indexes, buffer) public sealed class IntRingOpsND : BufferedRingOpsND<Int, Int32Ring>(Int32Ring.bufferAlgebra) { @@ -24,7 +24,7 @@ public sealed class IntRingOpsND : BufferedRingOpsND<Int, Int32Ring>(Int32Ring.b val indexer = indexerBuilder(shape) return IntBufferND( indexer, - IntBuffer(indexer.linearSize) { offset -> + Int32Buffer(indexer.linearSize) { offset -> elementAlgebra.initializer(indexer.index(offset)) } ) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferField.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferField.kt deleted file mode 100644 index 2e6b63a92..000000000 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferField.kt +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2018-2022 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.operations - -import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer - -/** - * [ExtendedField] over [DoubleBuffer]. - * - * @property size the size of buffers to operate on. - */ -public class DoubleBufferField(public val size: Int) : ExtendedField<Buffer<Double>>, DoubleBufferOps() { - override val zero: Buffer<Double> by lazy { DoubleBuffer(size) { 0.0 } } - override val one: Buffer<Double> by lazy { DoubleBuffer(size) { 1.0 } } - - override fun sinh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.sinh(arg) - - override fun cosh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.cosh(arg) - - override fun tanh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.tanh(arg) - - override fun asinh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.asinh(arg) - - override fun acosh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.acosh(arg) - - override fun atanh(arg: Buffer<Double>): DoubleBuffer = super<DoubleBufferOps>.atanh(arg) - - override fun power(arg: Buffer<Double>, pow: Number): DoubleBuffer = if (pow.isInteger()) { - arg.map { it.pow(pow.toInt()) } - } else { - arg.map { - if(it<0) throw IllegalArgumentException("Negative argument $it could not be raised to the fractional power") - it.pow(pow.toDouble()) - } - } - - override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> = - super<ExtendedField>.unaryOperationFunction(operation) -} \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt new file mode 100644 index 000000000..e33cb2c6e --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2018-2022 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.operations + +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.Float64Buffer + +/** + * [ExtendedField] over [Float64Buffer]. + * + * @property size the size of buffers to operate on. + */ +public class Float64BufferField(public val size: Int) : ExtendedField<Buffer<Double>>, Float64BufferOps() { + override val zero: Buffer<Double> by lazy { Float64Buffer(size) { 0.0 } } + override val one: Buffer<Double> by lazy { Float64Buffer(size) { 1.0 } } + + override fun sinh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.sinh(arg) + + override fun cosh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.cosh(arg) + + override fun tanh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.tanh(arg) + + override fun asinh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.asinh(arg) + + override fun acosh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.acosh(arg) + + override fun atanh(arg: Buffer<Double>): Float64Buffer = super<Float64BufferOps>.atanh(arg) + + override fun power(arg: Buffer<Double>, pow: Number): Float64Buffer = if (pow.isInteger()) { + arg.map { it.pow(pow.toInt()) } + } else { + arg.map { + if(it<0) throw IllegalArgumentException("Negative argument $it could not be raised to the fractional power") + it.pow(pow.toDouble()) + } + } + + override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> = + super<ExtendedField>.unaryOperationFunction(operation) +} \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferOps.kt similarity index 54% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferOps.kt index e15263bef..923534e1c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/DoubleBufferOps.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferOps.kt @@ -12,9 +12,9 @@ import kotlin.math.pow import kotlin.math.sqrt /** - * [ExtendedFieldOps] over [DoubleBuffer]. + * [ExtendedFieldOps] over [Float64Buffer]. */ -public abstract class DoubleBufferOps : BufferAlgebra<Double, Float64Field>, ExtendedFieldOps<Buffer<Double>>, +public abstract class Float64BufferOps : BufferAlgebra<Double, Float64Field>, ExtendedFieldOps<Buffer<Double>>, Norm<Buffer<Double>, Double> { override val elementAlgebra: Float64Field get() = Float64Field @@ -23,23 +23,23 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, Float64Field>, Ext @Suppress("OVERRIDE_BY_INLINE") @OptIn(UnstableKMathAPI::class) - final override inline fun Buffer<Double>.map(block: Float64Field.(Double) -> Double): DoubleBuffer = + final override inline fun Buffer<Double>.map(block: Float64Field.(Double) -> Double): Float64Buffer = DoubleArray(size) { Float64Field.block(getDouble(it)) }.asBuffer() @OptIn(UnstableKMathAPI::class) @Suppress("OVERRIDE_BY_INLINE") - final override inline fun Buffer<Double>.mapIndexed(block: Float64Field.(index: Int, arg: Double) -> Double): DoubleBuffer = - DoubleBuffer(size) { Float64Field.block(it, getDouble(it)) } + final override inline fun Buffer<Double>.mapIndexed(block: Float64Field.(index: Int, arg: Double) -> Double): Float64Buffer = + Float64Buffer(size) { Float64Field.block(it, getDouble(it)) } @OptIn(UnstableKMathAPI::class) @Suppress("OVERRIDE_BY_INLINE") final override inline fun Buffer<Double>.zip( other: Buffer<Double>, block: Float64Field.(left: Double, right: Double) -> Double, - ): DoubleBuffer { + ): Float64Buffer { require(size == other.size) { "Incompatible buffer sizes. left: ${size}, right: ${other.size}" } - return DoubleBuffer(size) { Float64Field.block(getDouble(it), other.getDouble(it)) } + return Float64Buffer(size) { Float64Field.block(getDouble(it), other.getDouble(it)) } } override fun unaryOperationFunction(operation: String): (arg: Buffer<Double>) -> Buffer<Double> = @@ -48,32 +48,32 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, Float64Field>, Ext override fun binaryOperationFunction(operation: String): (left: Buffer<Double>, right: Buffer<Double>) -> Buffer<Double> = super<ExtendedFieldOps>.binaryOperationFunction(operation) - override fun Buffer<Double>.unaryMinus(): DoubleBuffer = map { -it } + override fun Buffer<Double>.unaryMinus(): Float64Buffer = map { -it } - override fun add(left: Buffer<Double>, right: Buffer<Double>): DoubleBuffer { + override fun add(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer { require(right.size == left.size) { "The size of the first buffer ${left.size} should be the same as for second one: ${right.size} " } - return if (left is DoubleBuffer && right is DoubleBuffer) { + return if (left is Float64Buffer && right is Float64Buffer) { val aArray = left.array val bArray = right.array - DoubleBuffer(DoubleArray(left.size) { aArray[it] + bArray[it] }) - } else DoubleBuffer(DoubleArray(left.size) { left[it] + right[it] }) + Float64Buffer(DoubleArray(left.size) { aArray[it] + bArray[it] }) + } else Float64Buffer(DoubleArray(left.size) { left[it] + right[it] }) } - override fun Buffer<Double>.plus(arg: Buffer<Double>): DoubleBuffer = add(this, arg) + override fun Buffer<Double>.plus(arg: Buffer<Double>): Float64Buffer = add(this, arg) - override fun Buffer<Double>.minus(arg: Buffer<Double>): DoubleBuffer { + override fun Buffer<Double>.minus(arg: Buffer<Double>): Float64Buffer { require(arg.size == this.size) { "The size of the first buffer ${this.size} should be the same as for second one: ${arg.size} " } - return if (this is DoubleBuffer && arg is DoubleBuffer) { + return if (this is Float64Buffer && arg is Float64Buffer) { val aArray = this.array val bArray = arg.array - DoubleBuffer(DoubleArray(this.size) { aArray[it] - bArray[it] }) - } else DoubleBuffer(DoubleArray(this.size) { this[it] - arg[it] }) + Float64Buffer(DoubleArray(this.size) { aArray[it] - bArray[it] }) + } else Float64Buffer(DoubleArray(this.size) { this[it] - arg[it] }) } // @@ -96,61 +96,61 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, Float64Field>, Ext // } @UnstableKMathAPI - override fun multiply(left: Buffer<Double>, right: Buffer<Double>): DoubleBuffer { + override fun multiply(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer { require(right.size == left.size) { "The size of the first buffer ${left.size} should be the same as for second one: ${right.size} " } - return if (left is DoubleBuffer && right is DoubleBuffer) { + return if (left is Float64Buffer && right is Float64Buffer) { val aArray = left.array val bArray = right.array - DoubleBuffer(DoubleArray(left.size) { aArray[it] * bArray[it] }) - } else DoubleBuffer(DoubleArray(left.size) { left[it] * right[it] }) + Float64Buffer(DoubleArray(left.size) { aArray[it] * bArray[it] }) + } else Float64Buffer(DoubleArray(left.size) { left[it] * right[it] }) } - override fun divide(left: Buffer<Double>, right: Buffer<Double>): DoubleBuffer { + override fun divide(left: Buffer<Double>, right: Buffer<Double>): Float64Buffer { require(right.size == left.size) { "The size of the first buffer ${left.size} should be the same as for second one: ${right.size} " } - return if (left is DoubleBuffer && right is DoubleBuffer) { + return if (left is Float64Buffer && right is Float64Buffer) { val aArray = left.array val bArray = right.array - DoubleBuffer(DoubleArray(left.size) { aArray[it] / bArray[it] }) - } else DoubleBuffer(DoubleArray(left.size) { left[it] / right[it] }) + Float64Buffer(DoubleArray(left.size) { aArray[it] / bArray[it] }) + } else Float64Buffer(DoubleArray(left.size) { left[it] / right[it] }) } - override fun sin(arg: Buffer<Double>): DoubleBuffer = arg.map { sin(it) } + override fun sin(arg: Buffer<Double>): Float64Buffer = arg.map { sin(it) } - override fun cos(arg: Buffer<Double>): DoubleBuffer = arg.map { cos(it) } + override fun cos(arg: Buffer<Double>): Float64Buffer = arg.map { cos(it) } - override fun tan(arg: Buffer<Double>): DoubleBuffer = arg.map { tan(it) } + override fun tan(arg: Buffer<Double>): Float64Buffer = arg.map { tan(it) } - override fun asin(arg: Buffer<Double>): DoubleBuffer = arg.map { asin(it) } + override fun asin(arg: Buffer<Double>): Float64Buffer = arg.map { asin(it) } - override fun acos(arg: Buffer<Double>): DoubleBuffer = arg.map { acos(it) } + override fun acos(arg: Buffer<Double>): Float64Buffer = arg.map { acos(it) } - override fun atan(arg: Buffer<Double>): DoubleBuffer = arg.map { atan(it) } + override fun atan(arg: Buffer<Double>): Float64Buffer = arg.map { atan(it) } - override fun sinh(arg: Buffer<Double>): DoubleBuffer = arg.map { sinh(it) } + override fun sinh(arg: Buffer<Double>): Float64Buffer = arg.map { sinh(it) } - override fun cosh(arg: Buffer<Double>): DoubleBuffer = arg.map { cosh(it) } + override fun cosh(arg: Buffer<Double>): Float64Buffer = arg.map { cosh(it) } - override fun tanh(arg: Buffer<Double>): DoubleBuffer = arg.map { tanh(it) } + override fun tanh(arg: Buffer<Double>): Float64Buffer = arg.map { tanh(it) } - override fun asinh(arg: Buffer<Double>): DoubleBuffer = arg.map { asinh(it) } + override fun asinh(arg: Buffer<Double>): Float64Buffer = arg.map { asinh(it) } - override fun acosh(arg: Buffer<Double>): DoubleBuffer = arg.map { acosh(it) } + override fun acosh(arg: Buffer<Double>): Float64Buffer = arg.map { acosh(it) } - override fun atanh(arg: Buffer<Double>): DoubleBuffer = arg.map { atanh(it) } + override fun atanh(arg: Buffer<Double>): Float64Buffer = arg.map { atanh(it) } - override fun exp(arg: Buffer<Double>): DoubleBuffer = arg.map { exp(it) } + override fun exp(arg: Buffer<Double>): Float64Buffer = arg.map { exp(it) } - override fun ln(arg: Buffer<Double>): DoubleBuffer = arg.map { ln(it) } + override fun ln(arg: Buffer<Double>): Float64Buffer = arg.map { ln(it) } - override fun norm(arg: Buffer<Double>): Double = DoubleL2Norm.norm(arg) + override fun norm(arg: Buffer<Double>): Double = Float64L2Norm.norm(arg) - override fun scale(a: Buffer<Double>, value: Double): DoubleBuffer = a.map { it * value } + override fun scale(a: Buffer<Double>, value: Double): Float64Buffer = a.map { it * value } override fun power(arg: Buffer<Double>, pow: Number): Buffer<Double> = if (pow is Int) { arg.map { it.pow(pow) } @@ -158,37 +158,37 @@ public abstract class DoubleBufferOps : BufferAlgebra<Double, Float64Field>, Ext arg.map { it.pow(pow.toDouble()) } } - public companion object : DoubleBufferOps() + public companion object : Float64BufferOps() } -public object DoubleL2Norm : Norm<Point<Double>, Double> { +public object Float64L2Norm : Norm<Point<Double>, Double> { override fun norm(arg: Point<Double>): Double = sqrt(arg.fold(0.0) { acc: Double, d: Double -> acc + d.pow(2) }) } -public fun DoubleBufferOps.sum(buffer: Buffer<Double>): Double = buffer.reduce(Double::plus) +public fun Float64BufferOps.sum(buffer: Buffer<Double>): Double = buffer.reduce(Double::plus) /** * Sum of elements using given [conversion] */ -public inline fun <T> DoubleBufferOps.sumOf(buffer: Buffer<T>, conversion: (T) -> Double): Double = +public inline fun <T> Float64BufferOps.sumOf(buffer: Buffer<T>, conversion: (T) -> Double): Double = buffer.fold(0.0) { acc, value -> acc + conversion(value) } -public fun DoubleBufferOps.average(buffer: Buffer<Double>): Double = sum(buffer) / buffer.size +public fun Float64BufferOps.average(buffer: Buffer<Double>): Double = sum(buffer) / buffer.size /** * Average of elements using given [conversion] */ -public inline fun <T> DoubleBufferOps.averageOf(buffer: Buffer<T>, conversion: (T) -> Double): Double = +public inline fun <T> Float64BufferOps.averageOf(buffer: Buffer<T>, conversion: (T) -> Double): Double = sumOf(buffer, conversion) / buffer.size -public fun DoubleBufferOps.dispersion(buffer: Buffer<Double>): Double { +public fun Float64BufferOps.dispersion(buffer: Buffer<Double>): Double { val av = average(buffer) return buffer.fold(0.0) { acc, value -> acc + (value - av).pow(2) } / buffer.size } -public fun DoubleBufferOps.std(buffer: Buffer<Double>): Double = sqrt(dispersion(buffer)) +public fun Float64BufferOps.std(buffer: Buffer<Double>): Double = sqrt(dispersion(buffer)) -public fun DoubleBufferOps.covariance(x: Buffer<Double>, y: Buffer<Double>): Double { +public fun Float64BufferOps.covariance(x: Buffer<Double>, y: Buffer<Double>): Double { require(x.size == y.size) { "Expected buffers of the same size, but x.size == ${x.size} and y.size == ${y.size}" } val xMean = average(x) val yMean = average(y) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt index a318dea53..72e33c523 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt @@ -22,7 +22,7 @@ import kotlin.math.roundToLong */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int16Field : Field<Int16>, Norm<Int16, Int16>, NumericAlgebra<Int16> { - override val bufferFactory: MutableBufferFactory<Int16> = MutableBufferFactory(::ShortBuffer) + override val bufferFactory: MutableBufferFactory<Int16> = MutableBufferFactory(::Int16Buffer) override val zero: Int16 get() = 0 override val one: Int16 get() = 1 @@ -45,7 +45,7 @@ public object Int16Field : Field<Int16>, Norm<Int16, Int16>, NumericAlgebra<Int1 */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int32Field : Field<Int32>, Norm<Int32, Int32>, NumericAlgebra<Int32> { - override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::IntBuffer) + override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::Int32Buffer) override val zero: Int get() = 0 override val one: Int get() = 1 @@ -68,7 +68,7 @@ public object Int32Field : Field<Int32>, Norm<Int32, Int32>, NumericAlgebra<Int3 */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int64Field : Field<Int64>, Norm<Int64, Int64>, NumericAlgebra<Int64> { - override val bufferFactory: MutableBufferFactory<Int64> = MutableBufferFactory(::LongBuffer) + override val bufferFactory: MutableBufferFactory<Int64> = MutableBufferFactory(::Int64Buffer) override val zero: Int64 get() = 0L override val one: Int64 get() = 1L diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt index 17b3a72cc..0b7bef852 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt @@ -63,16 +63,16 @@ public interface ExtendedField<T> : ExtendedFieldOps<T>, Field<T>, NumericAlgebr } /** - * A field for [Double] without boxing. Does not produce appropriate field element. + * A field for [Double] without boxing. Does not produce an appropriate field element. */ -@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Float64Field : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> { - override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory(::DoubleBuffer) + override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory(::Float64Buffer) - override inline val zero: Double get() = 0.0 - override inline val one: Double get() = 1.0 + override val zero: Double get() = 0.0 + override val one: Double get() = 1.0 - override inline fun number(value: Number): Double = value.toDouble() + override fun number(value: Number): Double = value.toDouble() override fun binaryOperationFunction(operation: String): (left: Double, right: Double) -> Double = when (operation) { @@ -80,26 +80,26 @@ public object Float64Field : ExtendedField<Double>, Norm<Double, Double>, ScaleO else -> super<ExtendedField>.binaryOperationFunction(operation) } - override inline fun add(left: Double, right: Double): Double = left + right + override fun add(left: Double, right: Double): Double = left + right - override inline fun multiply(left: Double, right: Double): Double = left * right - override inline fun divide(left: Double, right: Double): Double = left / right + override fun multiply(left: Double, right: Double): Double = left * right + override fun divide(left: Double, right: Double): Double = left / right - override inline fun scale(a: Double, value: Double): Double = a * value + override fun scale(a: Double, value: Double): Double = a * value - override inline fun sin(arg: Double): Double = kotlin.math.sin(arg) - override inline fun cos(arg: Double): Double = kotlin.math.cos(arg) - override inline fun tan(arg: Double): Double = kotlin.math.tan(arg) - override inline fun acos(arg: Double): Double = kotlin.math.acos(arg) - override inline fun asin(arg: Double): Double = kotlin.math.asin(arg) - override inline fun atan(arg: Double): Double = kotlin.math.atan(arg) + override fun sin(arg: Double): Double = kotlin.math.sin(arg) + override fun cos(arg: Double): Double = kotlin.math.cos(arg) + override fun tan(arg: Double): Double = kotlin.math.tan(arg) + override fun acos(arg: Double): Double = kotlin.math.acos(arg) + override fun asin(arg: Double): Double = kotlin.math.asin(arg) + override fun atan(arg: Double): Double = kotlin.math.atan(arg) - override inline fun sinh(arg: Double): Double = kotlin.math.sinh(arg) - override inline fun cosh(arg: Double): Double = kotlin.math.cosh(arg) - override inline fun tanh(arg: Double): Double = kotlin.math.tanh(arg) - override inline fun asinh(arg: Double): Double = kotlin.math.asinh(arg) - override inline fun acosh(arg: Double): Double = kotlin.math.acosh(arg) - override inline fun atanh(arg: Double): Double = kotlin.math.atanh(arg) + override fun sinh(arg: Double): Double = kotlin.math.sinh(arg) + override fun cosh(arg: Double): Double = kotlin.math.cosh(arg) + override fun tanh(arg: Double): Double = kotlin.math.tanh(arg) + override fun asinh(arg: Double): Double = kotlin.math.asinh(arg) + override fun acosh(arg: Double): Double = kotlin.math.acosh(arg) + override fun atanh(arg: Double): Double = kotlin.math.atanh(arg) override fun sqrt(arg: Double): Double = kotlin.math.sqrt(arg) override fun power(arg: Double, pow: Number): Double = when { @@ -108,16 +108,16 @@ public object Float64Field : ExtendedField<Double>, Norm<Double, Double>, ScaleO else -> arg.kpow(pow.toDouble()) } - override inline fun exp(arg: Double): Double = kotlin.math.exp(arg) - override inline fun ln(arg: Double): Double = kotlin.math.ln(arg) + override fun exp(arg: Double): Double = kotlin.math.exp(arg) + override fun ln(arg: Double): Double = kotlin.math.ln(arg) - override inline fun norm(arg: Double): Double = abs(arg) + override fun norm(arg: Double): Double = abs(arg) - override inline fun Double.unaryMinus(): Double = -this - override inline fun Double.plus(arg: Double): Double = this + arg - override inline fun Double.minus(arg: Double): Double = this - arg - override inline fun Double.times(arg: Double): Double = this * arg - override inline fun Double.div(arg: Double): Double = this / arg + override fun Double.unaryMinus(): Double = -this + override fun Double.plus(arg: Double): Double = this + arg + override fun Double.minus(arg: Double): Double = this - arg + override fun Double.times(arg: Double): Double = this * arg + override fun Double.div(arg: Double): Double = this / arg } public typealias DoubleField = Float64Field @@ -125,14 +125,14 @@ public typealias DoubleField = Float64Field public val Double.Companion.algebra: Float64Field get() = Float64Field /** - * A field for [Float] without boxing. Does not produce appropriate field element. + * A field for [Float] without boxing. Does not produce an appropriate field element. */ -@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Float32Field : ExtendedField<Float>, Norm<Float, Float> { - override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory(::FloatBuffer) + override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory(::Float32Buffer) - override inline val zero: Float get() = 0.0f - override inline val one: Float get() = 1.0f + override val zero: Float get() = 0.0f + override val one: Float get() = 1.0f override fun number(value: Number): Float = value.toFloat() @@ -142,40 +142,40 @@ public object Float32Field : ExtendedField<Float>, Norm<Float, Float> { else -> super.binaryOperationFunction(operation) } - override inline fun add(left: Float, right: Float): Float = left + right + override fun add(left: Float, right: Float): Float = left + right override fun scale(a: Float, value: Double): Float = a * value.toFloat() - override inline fun multiply(left: Float, right: Float): Float = left * right + override fun multiply(left: Float, right: Float): Float = left * right - override inline fun divide(left: Float, right: Float): Float = left / right + override fun divide(left: Float, right: Float): Float = left / right - override inline fun sin(arg: Float): Float = kotlin.math.sin(arg) - override inline fun cos(arg: Float): Float = kotlin.math.cos(arg) - override inline fun tan(arg: Float): Float = kotlin.math.tan(arg) - override inline fun acos(arg: Float): Float = kotlin.math.acos(arg) - override inline fun asin(arg: Float): Float = kotlin.math.asin(arg) - override inline fun atan(arg: Float): Float = kotlin.math.atan(arg) + override fun sin(arg: Float): Float = kotlin.math.sin(arg) + override fun cos(arg: Float): Float = kotlin.math.cos(arg) + override fun tan(arg: Float): Float = kotlin.math.tan(arg) + override fun acos(arg: Float): Float = kotlin.math.acos(arg) + override fun asin(arg: Float): Float = kotlin.math.asin(arg) + override fun atan(arg: Float): Float = kotlin.math.atan(arg) - override inline fun sinh(arg: Float): Float = kotlin.math.sinh(arg) - override inline fun cosh(arg: Float): Float = kotlin.math.cosh(arg) - override inline fun tanh(arg: Float): Float = kotlin.math.tanh(arg) - override inline fun asinh(arg: Float): Float = kotlin.math.asinh(arg) - override inline fun acosh(arg: Float): Float = kotlin.math.acosh(arg) - override inline fun atanh(arg: Float): Float = kotlin.math.atanh(arg) + override fun sinh(arg: Float): Float = kotlin.math.sinh(arg) + override fun cosh(arg: Float): Float = kotlin.math.cosh(arg) + override fun tanh(arg: Float): Float = kotlin.math.tanh(arg) + override fun asinh(arg: Float): Float = kotlin.math.asinh(arg) + override fun acosh(arg: Float): Float = kotlin.math.acosh(arg) + override fun atanh(arg: Float): Float = kotlin.math.atanh(arg) - override inline fun sqrt(arg: Float): Float = kotlin.math.sqrt(arg) - override inline fun power(arg: Float, pow: Number): Float = arg.kpow(pow.toFloat()) + override fun sqrt(arg: Float): Float = kotlin.math.sqrt(arg) + override fun power(arg: Float, pow: Number): Float = arg.kpow(pow.toFloat()) - override inline fun exp(arg: Float): Float = kotlin.math.exp(arg) - override inline fun ln(arg: Float): Float = kotlin.math.ln(arg) + override fun exp(arg: Float): Float = kotlin.math.exp(arg) + override fun ln(arg: Float): Float = kotlin.math.ln(arg) - override inline fun norm(arg: Float): Float = abs(arg) + override fun norm(arg: Float): Float = abs(arg) - override inline fun Float.unaryMinus(): Float = -this - override inline fun Float.plus(arg: Float): Float = this + arg - override inline fun Float.minus(arg: Float): Float = this - arg - override inline fun Float.times(arg: Float): Float = this * arg - override inline fun Float.div(arg: Float): Float = this / arg + override fun Float.unaryMinus(): Float = -this + override fun Float.plus(arg: Float): Float = this + arg + override fun Float.minus(arg: Float): Float = this - arg + override fun Float.times(arg: Float): Float = this * arg + override fun Float.div(arg: Float): Float = this / arg } public typealias FloatField = Float32Field @@ -183,24 +183,24 @@ public typealias FloatField = Float32Field public val Float.Companion.algebra: Float32Field get() = Float32Field /** - * A field for [Int] without boxing. Does not produce corresponding ring element. + * A field for [Int] without boxing. Does not produce a corresponding ring element. */ -@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int32Ring : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> { - override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::IntBuffer) + override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::Int32Buffer) - override inline val zero: Int get() = 0 - override inline val one: Int get() = 1 + override val zero: Int get() = 0 + override val one: Int get() = 1 override fun number(value: Number): Int = value.toInt() - override inline fun add(left: Int, right: Int): Int = left + right - override inline fun multiply(left: Int, right: Int): Int = left * right - override inline fun norm(arg: Int): Int = abs(arg) + override fun add(left: Int, right: Int): Int = left + right + override fun multiply(left: Int, right: Int): Int = left * right + override fun norm(arg: Int): Int = abs(arg) - override inline fun Int.unaryMinus(): Int = -this - override inline fun Int.plus(arg: Int): Int = this + arg - override inline fun Int.minus(arg: Int): Int = this - arg - override inline fun Int.times(arg: Int): Int = this * arg + override fun Int.unaryMinus(): Int = -this + override fun Int.plus(arg: Int): Int = this + arg + override fun Int.minus(arg: Int): Int = this - arg + override fun Int.times(arg: Int): Int = this * arg } public typealias IntRing = Int32Ring @@ -208,24 +208,24 @@ public typealias IntRing = Int32Ring public val Int.Companion.algebra: Int32Ring get() = Int32Ring /** - * A field for [Short] without boxing. Does not produce appropriate ring element. + * A field for [Short] without boxing. Does not produce an appropriate ring element. */ -@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int16Ring : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> { - override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory(::ShortBuffer) + override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory(::Int16Buffer) - override inline val zero: Short get() = 0 - override inline val one: Short get() = 1 + override val zero: Short get() = 0 + override val one: Short get() = 1 override fun number(value: Number): Short = value.toShort() - override inline fun add(left: Short, right: Short): Short = (left + right).toShort() - override inline fun multiply(left: Short, right: Short): Short = (left * right).toShort() + override fun add(left: Short, right: Short): Short = (left + right).toShort() + override fun multiply(left: Short, right: Short): Short = (left * right).toShort() override fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort() - override inline fun Short.unaryMinus(): Short = (-this).toShort() - override inline fun Short.plus(arg: Short): Short = (this + arg).toShort() - override inline fun Short.minus(arg: Short): Short = (this - arg).toShort() - override inline fun Short.times(arg: Short): Short = (this * arg).toShort() + override fun Short.unaryMinus(): Short = (-this).toShort() + override fun Short.plus(arg: Short): Short = (this + arg).toShort() + override fun Short.minus(arg: Short): Short = (this - arg).toShort() + override fun Short.times(arg: Short): Short = (this * arg).toShort() } public typealias ShortRing = Int16Ring @@ -235,45 +235,47 @@ public val Short.Companion.algebra: Int16Ring get() = Int16Ring /** * A field for [Byte] without boxing. Does not produce appropriate ring element. */ -@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") -public object ByteRing : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> { - override val bufferFactory: MutableBufferFactory<Byte> = MutableBufferFactory(::ByteBuffer) +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") +public object Int8Ring : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> { + override val bufferFactory: MutableBufferFactory<Byte> = MutableBufferFactory(::Int8Buffer) - override inline val zero: Byte get() = 0 - override inline val one: Byte get() = 1 + override val zero: Byte get() = 0 + override val one: Byte get() = 1 override fun number(value: Number): Byte = value.toByte() - override inline fun add(left: Byte, right: Byte): Byte = (left + right).toByte() - override inline fun multiply(left: Byte, right: Byte): Byte = (left * right).toByte() + override fun add(left: Byte, right: Byte): Byte = (left + right).toByte() + override fun multiply(left: Byte, right: Byte): Byte = (left * right).toByte() override fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte() - override inline fun Byte.unaryMinus(): Byte = (-this).toByte() - override inline fun Byte.plus(arg: Byte): Byte = (this + arg).toByte() - override inline fun Byte.minus(arg: Byte): Byte = (this - arg).toByte() - override inline fun Byte.times(arg: Byte): Byte = (this * arg).toByte() + override fun Byte.unaryMinus(): Byte = (-this).toByte() + override fun Byte.plus(arg: Byte): Byte = (this + arg).toByte() + override fun Byte.minus(arg: Byte): Byte = (this - arg).toByte() + override fun Byte.times(arg: Byte): Byte = (this * arg).toByte() } -public val Byte.Companion.algebra: ByteRing get() = ByteRing +public typealias ByteRing = Int8Ring + +public val Byte.Companion.algebra: Int8Ring get() = Int8Ring /** * A field for [Double] without boxing. Does not produce an appropriate ring element. */ -@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") +@Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int64Ring : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> { - override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory(::LongBuffer) + override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory(::Int64Buffer) - override inline val zero: Long get() = 0L - override inline val one: Long get() = 1L + override val zero: Long get() = 0L + override val one: Long get() = 1L override fun number(value: Number): Long = value.toLong() - override inline fun add(left: Long, right: Long): Long = left + right - override inline fun multiply(left: Long, right: Long): Long = left * right + override fun add(left: Long, right: Long): Long = left + right + override fun multiply(left: Long, right: Long): Long = left * right override fun norm(arg: Long): Long = abs(arg) - override inline fun Long.unaryMinus(): Long = (-this) - override inline fun Long.plus(arg: Long): Long = (this + arg) - override inline fun Long.minus(arg: Long): Long = (this - arg) - override inline fun Long.times(arg: Long): Long = (this * arg) + override fun Long.unaryMinus(): Long = (-this) + override fun Long.plus(arg: Long): Long = (this + arg) + override fun Long.minus(arg: Long): Long = (this - arg) + override fun Long.times(arg: Long): Long = (this * arg) } public typealias LongRing = Int64Ring diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index cef8d1d4d..4c8ba0652 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -93,8 +93,8 @@ public interface Buffer<out T> : WithSize { List(size, initializer).asBuffer() /** - * Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([IntBuffer], - * [DoubleBuffer], etc.), [ListBuffer] is returned otherwise. + * Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([Int32Buffer], + * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @@ -110,8 +110,8 @@ public interface Buffer<out T> : WithSize { } /** - * Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([IntBuffer], - * [DoubleBuffer], etc.), [ListBuffer] is returned otherwise. + * Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([Int32Buffer], + * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FloatBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt similarity index 62% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FloatBuffer.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt index f1533ee3a..44ef4dcf0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FloatBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt @@ -14,7 +14,7 @@ import kotlin.jvm.JvmInline * @author Iaroslav Postovalov */ @JvmInline -public value class FloatBuffer(public val array: FloatArray) : PrimitiveBuffer<Float> { +public value class Float32Buffer(public val array: FloatArray) : PrimitiveBuffer<Float> { override val size: Int get() = array.size override operator fun get(index: Int): Float = array[index] @@ -26,35 +26,37 @@ public value class FloatBuffer(public val array: FloatArray) : PrimitiveBuffer<F override operator fun iterator(): FloatIterator = array.iterator() override fun copy(): MutableBuffer<Float> = - FloatBuffer(array.copyOf()) + Float32Buffer(array.copyOf()) } +public typealias FloatBuffer = Float32Buffer + /** - * Creates a new [FloatBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a new [Float32Buffer] with the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for a buffer element given its index. */ -public inline fun FloatBuffer(size: Int, init: (Int) -> Float): FloatBuffer = FloatBuffer(FloatArray(size) { init(it) }) +public inline fun Float32Buffer(size: Int, init: (Int) -> Float): Float32Buffer = Float32Buffer(FloatArray(size) { init(it) }) /** - * Returns a new [FloatBuffer] of given elements. + * Returns a new [Float32Buffer] of given elements. */ -public fun FloatBuffer(vararg floats: Float): FloatBuffer = FloatBuffer(floats) +public fun Float32Buffer(vararg floats: Float): Float32Buffer = Float32Buffer(floats) /** * Returns a new [FloatArray] containing all the elements of this [Buffer]. */ public fun Buffer<Float>.toFloatArray(): FloatArray = when (this) { - is FloatBuffer -> array.copyOf() + is Float32Buffer -> array.copyOf() else -> FloatArray(size, ::get) } /** - * Returns [FloatBuffer] over this array. + * Returns [Float32Buffer] over this array. * * @receiver the array. * @return the new buffer. */ -public fun FloatArray.asBuffer(): FloatBuffer = FloatBuffer(this) +public fun FloatArray.asBuffer(): Float32Buffer = Float32Buffer(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt similarity index 50% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt index 1696d5055..0542c1bf4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/DoubleBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt @@ -14,7 +14,7 @@ import kotlin.jvm.JvmInline * @property array the underlying array. */ @JvmInline -public value class DoubleBuffer(public val array: DoubleArray) : PrimitiveBuffer<Double> { +public value class Float64Buffer(public val array: DoubleArray) : PrimitiveBuffer<Double> { override val size: Int get() = array.size override operator fun get(index: Int): Double = array[index] @@ -25,57 +25,59 @@ public value class DoubleBuffer(public val array: DoubleArray) : PrimitiveBuffer override operator fun iterator(): DoubleIterator = array.iterator() - override fun copy(): DoubleBuffer = DoubleBuffer(array.copyOf()) + override fun copy(): Float64Buffer = Float64Buffer(array.copyOf()) override fun toString(): String = Buffer.toString(this) public companion object { - public fun zero(size: Int): DoubleBuffer = DoubleArray(size).asBuffer() + public fun zero(size: Int): Float64Buffer = DoubleArray(size).asBuffer() } } +public typealias DoubleBuffer = Float64Buffer + /** - * Creates a new [DoubleBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a new [Float64Buffer] with the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for a buffer element given its index. */ -public inline fun DoubleBuffer(size: Int, init: (Int) -> Double): DoubleBuffer = - DoubleBuffer(DoubleArray(size) { init(it) }) +public inline fun Float64Buffer(size: Int, init: (Int) -> Double): Float64Buffer = + Float64Buffer(DoubleArray(size) { init(it) }) /** - * Returns a new [DoubleBuffer] of given elements. + * Returns a new [Float64Buffer] of given elements. */ -public fun DoubleBuffer(vararg doubles: Double): DoubleBuffer = DoubleBuffer(doubles) +public fun Float64Buffer(vararg doubles: Double): Float64Buffer = Float64Buffer(doubles) /** * Returns a new [DoubleArray] containing all the elements of this [Buffer]. */ public fun Buffer<Double>.toDoubleArray(): DoubleArray = when (this) { - is DoubleBuffer -> array + is Float64Buffer -> array else -> DoubleArray(size, ::get) } /** - * Represent this buffer as [DoubleBuffer]. Does not guarantee that changes in the original buffer are reflected on this buffer. + * Represent this buffer as [Float64Buffer]. Does not guarantee that changes in the original buffer are reflected on this buffer. */ -public fun Buffer<Double>.toDoubleBuffer(): DoubleBuffer = when (this) { - is DoubleBuffer -> this +public fun Buffer<Double>.toFloat64Buffer(): Float64Buffer = when (this) { + is Float64Buffer -> this else -> DoubleArray(size, ::get).asBuffer() } /** - * Returns [DoubleBuffer] over this array. + * Returns [Float64Buffer] over this array. * * @receiver the array. * @return the new buffer. */ -public fun DoubleArray.asBuffer(): DoubleBuffer = DoubleBuffer(this) +public fun DoubleArray.asBuffer(): Float64Buffer = Float64Buffer(this) -public fun interface DoubleBufferTransform : BufferTransform<Double, Double> { - public fun transform(arg: DoubleBuffer): DoubleBuffer +public fun interface Float64BufferTransform : BufferTransform<Double, Double> { + public fun transform(arg: Float64Buffer): Float64Buffer - override fun transform(arg: Buffer<Double>): DoubleBuffer = arg.toDoubleBuffer() + override fun transform(arg: Buffer<Double>): Float64Buffer = arg.toFloat64Buffer() } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ShortBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt similarity index 65% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ShortBuffer.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt index 7dbb2b58e..1ba40c934 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ShortBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt @@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline * @property array the underlying array. */ @JvmInline -public value class ShortBuffer(public val array: ShortArray) : MutableBuffer<Short> { +public value class Int16Buffer(public val array: ShortArray) : MutableBuffer<Short> { override val size: Int get() = array.size override operator fun get(index: Int): Short = array[index] @@ -23,35 +23,37 @@ public value class ShortBuffer(public val array: ShortArray) : MutableBuffer<Sho } override operator fun iterator(): ShortIterator = array.iterator() - override fun copy(): MutableBuffer<Short> = ShortBuffer(array.copyOf()) + override fun copy(): MutableBuffer<Short> = Int16Buffer(array.copyOf()) } +public typealias ShortBuffer = Int16Buffer + /** - * Creates a new [ShortBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a new [Int16Buffer] with the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for a buffer element given its index. */ -public inline fun ShortBuffer(size: Int, init: (Int) -> Short): ShortBuffer = ShortBuffer(ShortArray(size) { init(it) }) +public inline fun Int16Buffer(size: Int, init: (Int) -> Short): Int16Buffer = Int16Buffer(ShortArray(size) { init(it) }) /** - * Returns a new [ShortBuffer] of given elements. + * Returns a new [Int16Buffer] of given elements. */ -public fun ShortBuffer(vararg shorts: Short): ShortBuffer = ShortBuffer(shorts) +public fun Int16Buffer(vararg shorts: Short): Int16Buffer = Int16Buffer(shorts) /** * Returns a new [ShortArray] containing all the elements of this [Buffer]. */ public fun Buffer<Short>.toShortArray(): ShortArray = when (this) { - is ShortBuffer -> array.copyOf() + is Int16Buffer -> array.copyOf() else -> ShortArray(size, ::get) } /** - * Returns [ShortBuffer] over this array. + * Returns [Int16Buffer] over this array. * * @receiver the array. * @return the new buffer. */ -public fun ShortArray.asBuffer(): ShortBuffer = ShortBuffer(this) +public fun ShortArray.asBuffer(): Int16Buffer = Int16Buffer(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/IntBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt similarity index 61% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/IntBuffer.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt index 0de7119b1..afd94e9cd 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/IntBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt @@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline * @property array the underlying array. */ @JvmInline -public value class IntBuffer(public val array: IntArray) : PrimitiveBuffer<Int> { +public value class Int32Buffer(public val array: IntArray) : PrimitiveBuffer<Int> { override val size: Int get() = array.size override operator fun get(index: Int): Int = array[index] @@ -24,35 +24,37 @@ public value class IntBuffer(public val array: IntArray) : PrimitiveBuffer<Int> override operator fun iterator(): IntIterator = array.iterator() - override fun copy(): IntBuffer = IntBuffer(array.copyOf()) + override fun copy(): Int32Buffer = Int32Buffer(array.copyOf()) } +public typealias IntBuffer = Int32Buffer + /** - * Creates a new [IntBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a new [Int32Buffer] with the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for a buffer element given its index. */ -public inline fun IntBuffer(size: Int, init: (Int) -> Int): IntBuffer = IntBuffer(IntArray(size) { init(it) }) +public inline fun Int32Buffer(size: Int, init: (Int) -> Int): Int32Buffer = Int32Buffer(IntArray(size) { init(it) }) /** - * Returns a new [IntBuffer] of given elements. + * Returns a new [Int32Buffer] of given elements. */ -public fun IntBuffer(vararg ints: Int): IntBuffer = IntBuffer(ints) +public fun Int32Buffer(vararg ints: Int): Int32Buffer = Int32Buffer(ints) /** * Returns a new [IntArray] containing all the elements of this [Buffer]. */ public fun Buffer<Int>.toIntArray(): IntArray = when (this) { - is IntBuffer -> array.copyOf() + is Int32Buffer -> array.copyOf() else -> IntArray(size, ::get) } /** - * Returns [IntBuffer] over this array. + * Returns [Int32Buffer] over this array. * * @receiver the array. * @return the new buffer. */ -public fun IntArray.asBuffer(): IntBuffer = IntBuffer(this) +public fun IntArray.asBuffer(): Int32Buffer = Int32Buffer(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/LongBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt similarity index 63% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/LongBuffer.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt index 9f77fc9d8..c67d109aa 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/LongBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt @@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline * @property array the underlying array. */ @JvmInline -public value class LongBuffer(public val array: LongArray) : PrimitiveBuffer<Long> { +public value class Int64Buffer(public val array: LongArray) : PrimitiveBuffer<Long> { override val size: Int get() = array.size override operator fun get(index: Int): Long = array[index] @@ -25,35 +25,37 @@ public value class LongBuffer(public val array: LongArray) : PrimitiveBuffer<Lon override operator fun iterator(): LongIterator = array.iterator() override fun copy(): MutableBuffer<Long> = - LongBuffer(array.copyOf()) + Int64Buffer(array.copyOf()) } +public typealias LongBuffer = Int64Buffer + /** - * Creates a new [LongBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a new [Int64Buffer] with the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for a buffer element given its index. */ -public inline fun LongBuffer(size: Int, init: (Int) -> Long): LongBuffer = LongBuffer(LongArray(size) { init(it) }) +public inline fun Int64Buffer(size: Int, init: (Int) -> Long): Int64Buffer = Int64Buffer(LongArray(size) { init(it) }) /** - * Returns a new [LongBuffer] of given elements. + * Returns a new [Int64Buffer] of given elements. */ -public fun LongBuffer(vararg longs: Long): LongBuffer = LongBuffer(longs) +public fun Int64Buffer(vararg longs: Long): Int64Buffer = Int64Buffer(longs) /** * Returns a new [LongArray] containing all the elements of this [Buffer]. */ public fun Buffer<Long>.toLongArray(): LongArray = when (this) { - is LongBuffer -> array.copyOf() + is Int64Buffer -> array.copyOf() else -> LongArray(size, ::get) } /** - * Returns [LongBuffer] over this array. + * Returns [Int64Buffer] over this array. * * @receiver the array. * @return the new buffer. */ -public fun LongArray.asBuffer(): LongBuffer = LongBuffer(this) +public fun LongArray.asBuffer(): Int64Buffer = Int64Buffer(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ByteBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt similarity index 67% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ByteBuffer.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt index 2be17c5e4..923fbec06 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ByteBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt @@ -13,7 +13,7 @@ import kotlin.jvm.JvmInline * @property array the underlying array. */ @JvmInline -public value class ByteBuffer(public val array: ByteArray) : MutableBuffer<Byte> { +public value class Int8Buffer(public val array: ByteArray) : MutableBuffer<Byte> { override val size: Int get() = array.size override operator fun get(index: Int): Byte = array[index] @@ -23,35 +23,35 @@ public value class ByteBuffer(public val array: ByteArray) : MutableBuffer<Byte> } override operator fun iterator(): ByteIterator = array.iterator() - override fun copy(): MutableBuffer<Byte> = ByteBuffer(array.copyOf()) + override fun copy(): MutableBuffer<Byte> = Int8Buffer(array.copyOf()) } /** - * Creates a new [ByteBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a new [Int8Buffer] with the specified [size], where each element is calculated by calling the specified * [init] function. * * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for a buffer element given its index. */ -public inline fun ByteBuffer(size: Int, init: (Int) -> Byte): ByteBuffer = ByteBuffer(ByteArray(size) { init(it) }) +public inline fun Int8Buffer(size: Int, init: (Int) -> Byte): Int8Buffer = Int8Buffer(ByteArray(size) { init(it) }) /** - * Returns a new [ByteBuffer] of given elements. + * Returns a new [Int8Buffer] of given elements. */ -public fun ByteBuffer(vararg bytes: Byte): ByteBuffer = ByteBuffer(bytes) +public fun Int8Buffer(vararg bytes: Byte): Int8Buffer = Int8Buffer(bytes) /** * Returns a new [ByteArray] containing all the elements of this [Buffer]. */ public fun Buffer<Byte>.toByteArray(): ByteArray = when (this) { - is ByteBuffer -> array.copyOf() + is Int8Buffer -> array.copyOf() else -> ByteArray(size, ::get) } /** - * Returns [ByteBuffer] over this array. + * Returns [Int8Buffer] over this array. * * @receiver the array. * @return the new buffer. */ -public fun ByteArray.asBuffer(): ByteBuffer = ByteBuffer(this) +public fun ByteArray.asBuffer(): Int8Buffer = Int8Buffer(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt index c0bfc6ecc..772c670ea 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt @@ -25,40 +25,40 @@ public interface MutableBuffer<T> : Buffer<T> { public companion object { /** - * Creates a [DoubleBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a [Float64Buffer] with the specified [size], where each element is calculated by calling the specified * [initializer] function. */ - public inline fun double(size: Int, initializer: (Int) -> Double): DoubleBuffer = - DoubleBuffer(size, initializer) + public inline fun double(size: Int, initializer: (Int) -> Double): Float64Buffer = + Float64Buffer(size, initializer) /** - * Creates a [ShortBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a [Int16Buffer] with the specified [size], where each element is calculated by calling the specified * [initializer] function. */ - public inline fun short(size: Int, initializer: (Int) -> Short): ShortBuffer = - ShortBuffer(size, initializer) + public inline fun short(size: Int, initializer: (Int) -> Short): Int16Buffer = + Int16Buffer(size, initializer) /** - * Creates a [IntBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a [Int32Buffer] with the specified [size], where each element is calculated by calling the specified * [initializer] function. */ - public inline fun int(size: Int, initializer: (Int) -> Int): IntBuffer = - IntBuffer(size, initializer) + public inline fun int(size: Int, initializer: (Int) -> Int): Int32Buffer = + Int32Buffer(size, initializer) /** - * Creates a [LongBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a [Int64Buffer] with the specified [size], where each element is calculated by calling the specified * [initializer] function. */ - public inline fun long(size: Int, initializer: (Int) -> Long): LongBuffer = - LongBuffer(size, initializer) + public inline fun long(size: Int, initializer: (Int) -> Long): Int64Buffer = + Int64Buffer(size, initializer) /** - * Creates a [FloatBuffer] with the specified [size], where each element is calculated by calling the specified + * Creates a [Float32Buffer] with the specified [size], where each element is calculated by calling the specified * [initializer] function. */ - public inline fun float(size: Int, initializer: (Int) -> Float): FloatBuffer = - FloatBuffer(size, initializer) + public inline fun float(size: Int, initializer: (Int) -> Float): Float32Buffer = + Float32Buffer(size, initializer) /** @@ -69,7 +69,7 @@ public interface MutableBuffer<T> : Buffer<T> { /** * Creates a [MutableBuffer] of given [type]. If the type is primitive, specialized buffers are used - * ([IntBuffer], [DoubleBuffer], etc.), [ListBuffer] is returned otherwise. + * ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @@ -86,7 +86,7 @@ public interface MutableBuffer<T> : Buffer<T> { /** * Creates a [MutableBuffer] of given type [T]. If the type is primitive, specialized buffers are used - * ([IntBuffer], [DoubleBuffer], etc.), [ListBuffer] is returned otherwise. + * ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferPrimitiveAccess.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferPrimitiveAccess.kt index 353892105..9033dea98 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferPrimitiveAccess.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferPrimitiveAccess.kt @@ -13,7 +13,7 @@ public fun Buffer<Double>.getDouble(index: Int): Double = if (this is BufferView } else { get(index) } -} else if (this is DoubleBuffer) { +} else if (this is Float64Buffer) { array[index] } else { get(index) @@ -30,7 +30,7 @@ public fun Buffer<Int>.getInt(index: Int): Int = if (this is BufferView) { } else { get(index) } -} else if (this is IntBuffer) { +} else if (this is Int32Buffer) { array[index] } else { get(index) diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt index dd97df1e8..fa9ac19c0 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.misc import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.misc.PermSortTest.Platform.* -import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.Int32Buffer import space.kscience.kmath.structures.asBuffer import kotlin.random.Random import kotlin.test.Test @@ -29,7 +29,7 @@ class PermSortTest { */ @Test fun testOnEmptyBuffer() { - val emptyBuffer = IntBuffer(0) {it} + val emptyBuffer = Int32Buffer(0) {it} var permutations = emptyBuffer.indicesSorted() assertTrue(permutations.isEmpty(), "permutation on an empty buffer should return an empty result") permutations = emptyBuffer.indicesSortedDescending() @@ -100,5 +100,5 @@ class PermSortTest { } } - private fun Random.buffer(size : Int) = IntBuffer(size) { nextInt() } + private fun Random.buffer(size : Int) = Int32Buffer(size) { nextInt() } } diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt index 797d2db4a..e67cab72d 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.chains -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer /** * Chunked, specialized chain for double values, which supports blocking [nextBlocking] operation @@ -15,7 +15,7 @@ public interface BlockingDoubleChain : BlockingBufferChain<Double> { /** * Returns an [DoubleArray] chunk of [size] values of [next]. */ - override fun nextBufferBlocking(size: Int): DoubleBuffer + override fun nextBufferBlocking(size: Int): Float64Buffer override suspend fun fork(): BlockingDoubleChain @@ -23,9 +23,9 @@ public interface BlockingDoubleChain : BlockingBufferChain<Double> { } public fun BlockingDoubleChain.map(transform: (Double) -> Double): BlockingDoubleChain = object : BlockingDoubleChain { - override fun nextBufferBlocking(size: Int): DoubleBuffer { + override fun nextBufferBlocking(size: Int): Float64Buffer { val block = this@map.nextBufferBlocking(size) - return DoubleBuffer(size) { transform(block[it]) } + return Float64Buffer(size) { transform(block[it]) } } override suspend fun fork(): BlockingDoubleChain = this@map.fork().map(transform) diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt index a481156f2..172aa95cd 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt @@ -5,13 +5,13 @@ package space.kscience.kmath.chains -import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.Int32Buffer /** * Performance optimized chain for integer values */ public interface BlockingIntChain : BlockingBufferChain<Int> { - override fun nextBufferBlocking(size: Int): IntBuffer + override fun nextBufferBlocking(size: Int): Int32Buffer override suspend fun fork(): BlockingIntChain } \ No newline at end of file diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt index 2cc8b8393..c52b6c3d5 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt @@ -16,7 +16,7 @@ import kotlinx.coroutines.flow.flow import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer /** * Create a [Flow] from buffer @@ -55,7 +55,7 @@ public fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>) /** * Specialized flow chunker for real buffer */ -public fun Flow<Double>.chunked(bufferSize: Int): Flow<DoubleBuffer> = flow { +public fun Flow<Double>.chunked(bufferSize: Int): Flow<Float64Buffer> = flow { require(bufferSize > 0) { "Resulting chunk size must be more than zero" } if (this@chunked is BlockingDoubleChain) { @@ -70,13 +70,13 @@ public fun Flow<Double>.chunked(bufferSize: Int): Flow<DoubleBuffer> = flow { counter++ if (counter == bufferSize) { - val buffer = DoubleBuffer(array) + val buffer = Float64Buffer(array) emit(buffer) counter = 0 } } - if (counter > 0) emit(DoubleBuffer(counter) { array[it] }) + if (counter > 0) emit(Float64Buffer(counter) { array[it] }) } } diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt index 411a35188..108b840dd 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.real import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.Point -import space.kscience.kmath.operations.DoubleL2Norm +import space.kscience.kmath.operations.Float64L2Norm import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer.Companion.double import space.kscience.kmath.structures.asBuffer @@ -103,4 +103,4 @@ public fun DoubleVector.sum(): Double { return res } -public val DoubleVector.norm: Double get() = DoubleL2Norm.norm(this) \ No newline at end of file +public val DoubleVector.norm: Double get() = Float64L2Norm.norm(this) \ No newline at end of file diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt index f86b9ef5f..fe5593eaa 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt @@ -15,7 +15,7 @@ import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.asIterable import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.math.pow /* @@ -130,19 +130,19 @@ public fun RealMatrix.extractColumns(columnRange: IntRange): RealMatrix = public fun RealMatrix.extractColumn(columnIndex: Int): RealMatrix = extractColumns(columnIndex..columnIndex) -public fun RealMatrix.sumByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j -> +public fun RealMatrix.sumByColumn(): Float64Buffer = Float64Buffer(colNum) { j -> columns[j].sum() } -public fun RealMatrix.minByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j -> +public fun RealMatrix.minByColumn(): Float64Buffer = Float64Buffer(colNum) { j -> columns[j].asIterable().minOrNull() ?: error("Cannot produce min on empty column") } -public fun RealMatrix.maxByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j -> +public fun RealMatrix.maxByColumn(): Float64Buffer = Float64Buffer(colNum) { j -> columns[j].asIterable().maxOrNull() ?: error("Cannot produce min on empty column") } -public fun RealMatrix.averageByColumn(): DoubleBuffer = DoubleBuffer(colNum) { j -> +public fun RealMatrix.averageByColumn(): Float64Buffer = Float64Buffer(colNum) { j -> columns[j].asIterable().average() } diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt index adb62b173..79af446e2 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.real import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.math.floor public val ClosedFloatingPointRange<Double>.length: Double get() = endInclusive - start @@ -16,30 +16,30 @@ public val ClosedFloatingPointRange<Double>.length: Double get() = endInclusive * Create a Buffer-based grid with equally distributed [numberOfPoints] points. The range could be increasing or decreasing. * If range has a zero size, then the buffer consisting of [numberOfPoints] equal values is returned. */ -public fun Buffer.Companion.fromRange(range: ClosedFloatingPointRange<Double>, numberOfPoints: Int): DoubleBuffer { +public fun Buffer.Companion.fromRange(range: ClosedFloatingPointRange<Double>, numberOfPoints: Int): Float64Buffer { require(numberOfPoints >= 2) { "Number of points in grid must be more than 1" } val normalizedRange = when { range.endInclusive > range.start -> range range.endInclusive < range.start -> range.endInclusive..range.start - else -> return DoubleBuffer(numberOfPoints) { range.start } + else -> return Float64Buffer(numberOfPoints) { range.start } } val step = normalizedRange.length / (numberOfPoints - 1) - return DoubleBuffer(numberOfPoints) { normalizedRange.start + step * it } + return Float64Buffer(numberOfPoints) { normalizedRange.start + step * it } } /** * Create a Buffer-based grid with equally distributed points with a fixed [step]. The range could be increasing or decreasing. * If the step is larger than the range size, single point is returned. */ -public fun Buffer.Companion.withFixedStep(range: ClosedFloatingPointRange<Double>, step: Double): DoubleBuffer { +public fun Buffer.Companion.withFixedStep(range: ClosedFloatingPointRange<Double>, step: Double): Float64Buffer { require(step > 0) { "The grid step must be positive" } val normalizedRange = when { range.endInclusive > range.start -> range range.endInclusive < range.start -> range.endInclusive..range.start - else -> return DoubleBuffer(range.start) + else -> return Float64Buffer(range.start) } val numberOfPoints = floor(normalizedRange.length / step).toInt() + 1 - return DoubleBuffer(numberOfPoints) { normalizedRange.start + step * it } + return Float64Buffer(numberOfPoints) { normalizedRange.start + step * it } } /** @@ -51,4 +51,4 @@ public fun Buffer.Companion.withFixedStep(range: ClosedFloatingPointRange<Double * If step is negative, the same goes from upper boundary downwards */ @UnstableKMathAPI -public infix fun ClosedFloatingPointRange<Double>.step(step: Double): DoubleBuffer = Buffer.withFixedStep(this, step) \ No newline at end of file +public infix fun ClosedFloatingPointRange<Double>.step(step: Double): Float64Buffer = Buffer.withFixedStep(this, step) \ No newline at end of file diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt index 13b579144..1b9f0f4e2 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt @@ -7,14 +7,14 @@ package space.kscience.kmath.real import space.kscience.kmath.nd.BufferND import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer /** * Map one [BufferND] using function without indices. */ public inline fun BufferND<Double>.mapInline(crossinline transform: Float64Field.(Double) -> Double): BufferND<Double> { val array = DoubleArray(indices.linearSize) { offset -> Float64Field.transform(buffer[offset]) } - return BufferND(indices, DoubleBuffer(array)) + return BufferND(indices, Float64Buffer(array)) } /** diff --git a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt index a25091ac2..16eccd79b 100644 --- a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt @@ -9,30 +9,30 @@ import space.kscience.kmath.linear.asMatrix import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.transpose import space.kscience.kmath.operations.algebra -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.test.Test import kotlin.test.assertEquals internal class DoubleVectorTest { @Test fun testSum() { - val vector1 = DoubleBuffer(5) { it.toDouble() } - val vector2 = DoubleBuffer(5) { 5 - it.toDouble() } + val vector1 = Float64Buffer(5) { it.toDouble() } + val vector2 = Float64Buffer(5) { 5 - it.toDouble() } val sum = vector1 + vector2 assertEquals(5.0, sum[2]) } @Test fun testVectorToMatrix() { - val vector = DoubleBuffer(5) { it.toDouble() } + val vector = Float64Buffer(5) { it.toDouble() } val matrix = vector.asMatrix() assertEquals(4.0, matrix[4, 0]) } @Test fun testDot() = Double.algebra.linearSpace.run { - val vector1 = DoubleBuffer(5) { it.toDouble() } - val vector2 = DoubleBuffer(5) { 5 - it.toDouble() } + val vector1 = Float64Buffer(5) { it.toDouble() } + val vector2 = Float64Buffer(5) { 5 - it.toDouble() } val matrix1 = vector1.asMatrix() val matrix2 = vector2.asMatrix().transpose() val product = matrix1 dot matrix2 diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt index 4ed4965c9..975fcd3a8 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.integration import space.kscience.kmath.operations.mapToBuffer import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.asBuffer import kotlin.math.ulp import kotlin.native.concurrent.ThreadLocal @@ -32,11 +32,11 @@ public fun GaussIntegratorRuleFactory.build( val normalized: Pair<Buffer<Double>, Buffer<Double>> = build(numPoints) val length = range.endInclusive - range.start - val points = normalized.first.mapToBuffer(::DoubleBuffer) { + val points = normalized.first.mapToBuffer(::Float64Buffer) { range.start + length / 2 + length / 2 * it } - val weights = normalized.second.mapToBuffer(::DoubleBuffer) { + val weights = normalized.second.mapToBuffer(::Float64Buffer) { it * length / 2 } @@ -64,8 +64,8 @@ public object GaussLegendreRuleFactory : GaussIntegratorRuleFactory { if (numPoints == 1) { // Break recursion. return Pair( - DoubleBuffer(0.0), - DoubleBuffer(0.0) + Float64Buffer(0.0), + Float64Buffer(0.0) ) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt index 319e86cd0..1306e501f 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt @@ -14,7 +14,7 @@ import space.kscience.kmath.interpolation.SplineInterpolator import space.kscience.kmath.interpolation.interpolatePolynomials import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.MutableBufferFactory /** @@ -62,7 +62,7 @@ public class SplineIntegrator<T : Comparable<T>>( val nodes: Buffer<Double> = integrand.getFeature<UnivariateIntegrationNodes>()?.nodes ?: run { val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 val step = (range.endInclusive - range.start) / (numPoints - 1) - DoubleBuffer(numPoints) { i -> range.start + i * step } + Float64Buffer(numPoints) { i -> range.start + i * step } } val values = nodes.mapToBuffer(bufferFactory) { integrand.function(it) } @@ -85,15 +85,15 @@ public class SplineIntegrator<T : Comparable<T>>( public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0 - val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, ::DoubleBuffer) + val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, ::Float64Buffer) val nodes: Buffer<Double> = integrand.getFeature<UnivariateIntegrationNodes>()?.nodes ?: run { val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 val step = (range.endInclusive - range.start) / (numPoints - 1) - DoubleBuffer(numPoints) { i -> range.start + i * step } + Float64Buffer(numPoints) { i -> range.start + i * step } } - val values = nodes.mapToBuffer(::DoubleBuffer) { integrand.function(it) } + val values = nodes.mapToBuffer(::Float64Buffer) { integrand.function(it) } val polynomials = interpolator.interpolatePolynomials(nodes, values) val res = polynomials.integrate(Float64Field, range) return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + nodes.size) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index f18e86b80..e29a6c881 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.integration import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.misc.FeatureSet import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer public class UnivariateIntegrand<T> internal constructor( override val features: FeatureSet<IntegrandFeature>, @@ -46,7 +46,7 @@ public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange< } public class UnivariateIntegrationNodes(public val nodes: Buffer<Double>) : IntegrandFeature { - public constructor(vararg nodes: Double) : this(DoubleBuffer(nodes)) + public constructor(vararg nodes: Double) : this(Float64Buffer(nodes)) override fun toString(): String = "UnivariateNodes($nodes)" } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt index 76082af74..ed4657d53 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt @@ -12,7 +12,7 @@ import space.kscience.kmath.functions.Polynomial import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.MutableBufferFactory /** @@ -80,4 +80,4 @@ public fun <T : Comparable<T>> Field<T>.splineInterpolator( ): SplineInterpolator<T> = SplineInterpolator(this, bufferFactory) public val Float64Field.splineInterpolator: SplineInterpolator<Double> - get() = SplineInterpolator(this, ::DoubleBuffer) \ No newline at end of file + get() = SplineInterpolator(this, ::Float64Buffer) \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt index c7c202a70..33a9bcc01 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.geometry import space.kscience.kmath.complex.Quaternion import space.kscience.kmath.complex.normalized -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.testutils.assertBufferEquals import kotlin.test.Test @@ -38,15 +38,15 @@ class RotationTest { fun fromRotation() { val q = Quaternion.fromRotation(0.3.radians, Euclidean3DSpace.vector(1.0, 1.0, 1.0)) - assertBufferEquals(DoubleBuffer(0.9887711, 0.0862781, 0.0862781, 0.0862781), q) + assertBufferEquals(Float64Buffer(0.9887711, 0.0862781, 0.0862781, 0.0862781), q) } @Test fun fromEuler() { val q = Quaternion.fromEuler(0.1.radians, 0.2.radians, 0.3.radians, RotationOrder.ZXY) - assertBufferEquals(DoubleBuffer(0.9818562, 0.0342708, 0.1060205, 0.1534393), q) + assertBufferEquals(Float64Buffer(0.9818562, 0.0342708, 0.1060205, 0.1534393), q) val q1 = Quaternion.fromEuler(0.1.radians, 0.2.radians, 0.3.radians, RotationOrder.XYZ) - assertBufferEquals(DoubleBuffer(0.9818562, 0.0640713, 0.0911575, 0.1534393), q1) + assertBufferEquals(Float64Buffer(0.9818562, 0.0640713, 0.0911575, 0.1534393), q1) } } \ No newline at end of file diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt index a4ae6d935..3303fa172 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.histogram import space.kscience.kmath.domains.Domain import space.kscience.kmath.linear.Point -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.asBuffer /** @@ -66,9 +66,9 @@ public fun <T : Any> HistogramBuilder<T, *>.put(point: Point<out T>): Unit = put public fun <T : Any> HistogramBuilder<T, *>.put(vararg point: T): Unit = put(point.asBuffer()) public fun HistogramBuilder<Double, *>.put(vararg point: Number): Unit = - put(DoubleBuffer(point.map { it.toDouble() }.toDoubleArray())) + put(Float64Buffer(point.map { it.toDouble() }.toDoubleArray())) -public fun HistogramBuilder<Double, *>.put(vararg point: Double): Unit = put(DoubleBuffer(point)) +public fun HistogramBuilder<Double, *>.put(vararg point: Double): Unit = put(Float64Buffer(point)) public fun <T : Any> HistogramBuilder<T, *>.fill(sequence: Iterable<Point<T>>): Unit = sequence.forEach { put(it) } /** diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt index fe9c3ae01..f7094f7a9 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt @@ -41,7 +41,7 @@ public class UniformHistogramGroupND<V : Any, A : Field<V>>( override val shape: ShapeND = ShapeND(IntArray(binNums.size) { binNums[it] + 2 }) - private val binSize = DoubleBuffer(dimension) { (upper[it] - lower[it]) / binNums[it] } + private val binSize = Float64Buffer(dimension) { (upper[it] - lower[it]) / binNums[it] } /** * Get internal [StructureND] bin index for given axis @@ -129,7 +129,7 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges( public fun Histogram.Companion.uniformDoubleNDFromRanges( vararg ranges: ClosedFloatingPointRange<Double>, ): UniformHistogramGroupND<Double, Float64Field> = - uniformNDFromRanges(DoubleFieldOpsND, *ranges, bufferFactory = ::DoubleBuffer) + uniformNDFromRanges(Floa64FieldOpsND, *ranges, bufferFactory = ::Float64Buffer) /** @@ -164,4 +164,4 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges( public fun Histogram.Companion.uniformDoubleNDFromRanges( vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>, ): UniformHistogramGroupND<Double, Float64Field> = - uniformNDFromRanges(DoubleFieldOpsND, *ranges, bufferFactory = ::DoubleBuffer) \ No newline at end of file + uniformNDFromRanges(Floa64FieldOpsND, *ranges, bufferFactory = ::Float64Buffer) \ No newline at end of file diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt index 2732efac7..e922fd423 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt @@ -9,10 +9,10 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.* import space.kscience.kmath.linear.* import space.kscience.kmath.misc.log -import space.kscience.kmath.operations.DoubleL2Norm import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Float64L2Norm import space.kscience.kmath.operations.algebra -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.math.abs @@ -63,7 +63,7 @@ public object QowOptimizer : Optimizer<Double, XYFit> { * Array of dispersions in each point */ val dispersion: Point<Double> by lazy { - DoubleBuffer(problem.data.size) { d -> + Float64Buffer(problem.data.size) { d -> 1.0 / problem.weight(d).invoke(allParameters) } } @@ -148,8 +148,8 @@ public object QowOptimizer : Optimizer<Double, XYFit> { * Quasi optimal weights equations values */ private fun QoWeight.getEqValues(theta: Map<Symbol, Double>): Point<Double> { - val distances = DoubleBuffer(data.size) { d -> distance(d, theta) } - return DoubleBuffer(size) { s -> + val distances = Float64Buffer(data.size) { d -> distance(d, theta) } + return Float64Buffer(size) { s -> val base = (0 until data.size).sumOf { d -> distances[d] * derivs[d, s] / dispersion[d] } //Prior probability correction prior?.let { prior -> @@ -186,7 +186,7 @@ public object QowOptimizer : Optimizer<Double, XYFit> { var eqvalues = getEqValues(par) //Values of the weight functions - dis = DoubleL2Norm.norm(eqvalues) // discrepancy + dis = Float64L2Norm.norm(eqvalues) // discrepancy logger?.log { "Starting discrepancy is $dis" } var i = 0 var flag = false @@ -205,7 +205,7 @@ public object QowOptimizer : Optimizer<Double, XYFit> { logger?.log { "Parameter values after step are: \n\t$currentSolution" } eqvalues = getEqValues(currentSolution.freeParameters) - val currentDis = DoubleL2Norm.norm(eqvalues)// discrepancy after the step + val currentDis = Float64L2Norm.norm(eqvalues)// discrepancy after the step logger?.log { "The discrepancy after step is: $currentDis." } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt index 7e0ee3cd4..1cc409393 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.random import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.chains.Chain -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer /** * A possibly stateful chain producing random values. @@ -31,8 +31,8 @@ public fun <R> RandomGenerator.chain(generator: suspend RandomGenerator.() -> R) * A type-specific double chunk random chain */ public class UniformDoubleChain(public val generator: RandomGenerator) : BlockingDoubleChain { - override fun nextBufferBlocking(size: Int): DoubleBuffer = generator.nextDoubleBuffer(size) - override suspend fun nextBuffer(size: Int): DoubleBuffer = nextBufferBlocking(size) + override fun nextBufferBlocking(size: Int): Float64Buffer = generator.nextDoubleBuffer(size) + override suspend fun nextBuffer(size: Int): Float64Buffer = nextBufferBlocking(size) override suspend fun fork(): UniformDoubleChain = UniformDoubleChain(generator.fork()) } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomGenerator.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomGenerator.kt index f7388006e..ece6bfcc1 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomGenerator.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomGenerator.kt @@ -5,7 +5,7 @@ package space.kscience.kmath.random -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.random.Random /** @@ -25,7 +25,7 @@ public interface RandomGenerator { /** * A chunk of doubles of given [size]. */ - public fun nextDoubleBuffer(size: Int): DoubleBuffer = DoubleBuffer(size) { nextDouble() } + public fun nextDoubleBuffer(size: Int): Float64Buffer = Float64Buffer(size) { nextDouble() } /** * Gets the next random `Int` from the random number generator. diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt index e5a48d4d8..04e1221ca 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.samplers import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.stat.Sampler -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.math.ln import kotlin.math.pow @@ -56,7 +56,7 @@ public class AhrensDieterExponentialSampler(public val mean: Double) : Sampler<D return mean * (a + umin * EXPONENTIAL_SA_QI[0]) } - override fun nextBufferBlocking(size: Int): DoubleBuffer = DoubleBuffer(size) { nextBlocking() } + override fun nextBufferBlocking(size: Int): Float64Buffer = Float64Buffer(size) { nextBlocking() } override suspend fun fork(): BlockingDoubleChain = sample(generator.fork()) } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt index 7795ff297..c8ee745dd 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.samplers import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.random.RandomGenerator -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.math.* /** @@ -22,11 +22,11 @@ public object BoxMullerSampler : NormalizedGaussianSampler { override fun sample(generator: RandomGenerator): BlockingDoubleChain = object : BlockingDoubleChain { var state = Double.NaN - override fun nextBufferBlocking(size: Int): DoubleBuffer { + override fun nextBufferBlocking(size: Int): Float64Buffer { val xs = generator.nextDoubleBuffer(size) val ys = generator.nextDoubleBuffer(size) - return DoubleBuffer(size) { index -> + return Float64Buffer(size) { index -> if (state.isNaN()) { // Generate a pair of Gaussian numbers. val x = xs[index] diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt index 6d2899314..44834b5bf 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.samplers import space.kscience.kmath.chains.BlockingIntChain import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.stat.Sampler -import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.Int32Buffer import kotlin.math.exp /** @@ -55,7 +55,7 @@ public class KempSmallMeanPoissonSampler internal constructor( return x } - override fun nextBufferBlocking(size: Int): IntBuffer = IntBuffer(size) { nextBlocking() } + override fun nextBufferBlocking(size: Int): Int32Buffer = Int32Buffer(size) { nextBlocking() } override suspend fun fork(): BlockingIntChain = sample(generator.fork()) } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt index 3c3fe10fd..961883af5 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.samplers import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.random.RandomGenerator -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.math.ln import kotlin.math.sqrt @@ -59,7 +59,7 @@ public object MarsagliaNormalizedGaussianSampler : NormalizedGaussianSampler { } } - override fun nextBufferBlocking(size: Int): DoubleBuffer = DoubleBuffer(size) { nextBlocking() } + override fun nextBufferBlocking(size: Int): Float64Buffer = Float64Buffer(size) { nextBlocking() } override suspend fun fork(): BlockingDoubleChain = sample(generator.fork()) } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt index 454691e05..964a57178 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt @@ -9,7 +9,7 @@ import space.kscience.kmath.chains.BlockingIntChain import space.kscience.kmath.misc.toIntExact import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.stat.Sampler -import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.Int32Buffer import kotlin.math.* @@ -71,7 +71,7 @@ public class SmallMeanPoissonSampler(public val mean: Double) : Sampler<Int> { return n } - override fun nextBufferBlocking(size: Int): IntBuffer = IntBuffer(size) { nextBlocking() } + override fun nextBufferBlocking(size: Int): Int32Buffer = Int32Buffer(size) { nextBlocking() } override suspend fun fork(): BlockingIntChain = sample(generator.fork()) } @@ -191,7 +191,7 @@ public class LargeMeanPoissonSampler(public val mean: Double) : Sampler<Int> { return min(y2 + y.toLong(), Int.MAX_VALUE.toLong()).toIntExact() } - override fun nextBufferBlocking(size: Int): IntBuffer = IntBuffer(size) { nextBlocking() } + override fun nextBufferBlocking(size: Int): Int32Buffer = Int32Buffer(size) { nextBlocking() } override suspend fun fork(): BlockingIntChain = sample(generator.fork()) } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt index b87a429df..34355dca7 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt @@ -12,8 +12,8 @@ import space.kscience.kmath.chains.combine import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.DoubleBuffer -import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.Float64Buffer +import space.kscience.kmath.structures.Int32Buffer import kotlin.jvm.JvmName /** @@ -62,14 +62,14 @@ public suspend fun <T : Any> Sampler<T>.next(generator: RandomGenerator): T = sa */ @JvmName("sampleRealBuffer") public fun Sampler<Double>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<Double>> = - sampleBuffer(generator, size, ::DoubleBuffer) + sampleBuffer(generator, size, ::Float64Buffer) /** * Generates [size] integer samples and chunks them into some buffers. */ @JvmName("sampleIntBuffer") public fun Sampler<Int>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<Int>> = - sampleBuffer(generator, size, ::IntBuffer) + sampleBuffer(generator, size, ::Int32Buffer) /** diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt index 40ce37d15..062894c90 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.samplers import space.kscience.kmath.chains.BlockingDoubleChain import space.kscience.kmath.random.RandomGenerator -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.math.* /** @@ -63,7 +63,7 @@ public object ZigguratNormalizedGaussianSampler : NormalizedGaussianSampler { } override fun sample(generator: RandomGenerator): BlockingDoubleChain = object : BlockingDoubleChain { - override fun nextBufferBlocking(size: Int): DoubleBuffer = DoubleBuffer(size) { sampleOne(generator) } + override fun nextBufferBlocking(size: Int): Float64Buffer = Float64Buffer(size) { sampleOne(generator) } override suspend fun fork(): BlockingDoubleChain = sample(generator.fork()) } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt index 7db91722f..662469bf3 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.core.internal.broadcastTensors import space.kscience.kmath.tensors.core.internal.broadcastTo @@ -22,7 +22,7 @@ public object BroadcastDoubleTensorAlgebra : DoubleTensorAlgebra() { val broadcast = broadcastTensors(asDoubleTensor(), arg.asDoubleTensor()) val newThis = broadcast[0] val newOther = broadcast[1] - val resBuffer = DoubleBuffer(newThis.indices.linearSize) { i -> + val resBuffer = Float64Buffer(newThis.indices.linearSize) { i -> newThis.source[i] + newOther.source[i] } return DoubleTensor(newThis.shape, resBuffer) @@ -39,7 +39,7 @@ public object BroadcastDoubleTensorAlgebra : DoubleTensorAlgebra() { val broadcast = broadcastTensors(asDoubleTensor(), arg.asDoubleTensor()) val newThis = broadcast[0] val newOther = broadcast[1] - val resBuffer = DoubleBuffer(newThis.indices.linearSize) { i -> + val resBuffer = Float64Buffer(newThis.indices.linearSize) { i -> newThis.source[i] - newOther.source[i] } return DoubleTensor(newThis.shape, resBuffer) @@ -56,7 +56,7 @@ public object BroadcastDoubleTensorAlgebra : DoubleTensorAlgebra() { val broadcast = broadcastTensors(asDoubleTensor(), arg.asDoubleTensor()) val newThis = broadcast[0] val newOther = broadcast[1] - val resBuffer = DoubleBuffer(newThis.indices.linearSize) { i -> + val resBuffer = Float64Buffer(newThis.indices.linearSize) { i -> newThis.source[i] * newOther.source[i] } return DoubleTensor(newThis.shape, resBuffer) @@ -73,7 +73,7 @@ public object BroadcastDoubleTensorAlgebra : DoubleTensorAlgebra() { val broadcast = broadcastTensors(asDoubleTensor(), arg.asDoubleTensor()) val newThis = broadcast[0] val newOther = broadcast[1] - val resBuffer = DoubleBuffer(newThis.indices.linearSize) { i -> + val resBuffer = Float64Buffer(newThis.indices.linearSize) { i -> newThis.source[i] / newOther.source[i] } return DoubleTensor(newThis.shape, resBuffer) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt index d2c2e9d5d..8a97114c3 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt @@ -13,7 +13,7 @@ import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.core.internal.toPrettyString public class OffsetDoubleBuffer( - override val origin: DoubleBuffer, + override val origin: Float64Buffer, private val offset: Int, override val size: Int, ) : MutableBuffer<Double>, BufferView<Double> { @@ -34,7 +34,7 @@ public class OffsetDoubleBuffer( /** * Copy only a part of buffer that belongs to this [OffsetDoubleBuffer] */ - override fun copy(): DoubleBuffer = origin.array.copyOfRange(offset, offset + size).asBuffer() + override fun copy(): Float64Buffer = origin.array.copyOfRange(offset, offset + size).asBuffer() override fun iterator(): Iterator<Double> = iterator { for (i in indices) { @@ -60,15 +60,15 @@ public fun OffsetDoubleBuffer.slice(range: IntRange): OffsetDoubleBuffer = view( /** * Map only operable content of the offset buffer */ -public inline fun OffsetDoubleBuffer.map(operation: (Double) -> Double): DoubleBuffer = - DoubleBuffer(size) { operation(get(it)) } +public inline fun OffsetDoubleBuffer.map(operation: (Double) -> Double): Float64Buffer = + Float64Buffer(size) { operation(get(it)) } public inline fun OffsetDoubleBuffer.zip( other: OffsetDoubleBuffer, operation: (l: Double, r: Double) -> Double, -): DoubleBuffer { +): Float64Buffer { require(size == other.size) { "The sizes of zipped buffers must be the same" } - return DoubleBuffer(size) { operation(get(it), other[it]) } + return Float64Buffer(size) { operation(get(it), other[it]) } } /** @@ -92,7 +92,7 @@ public open class DoubleTensor( require(linearSize == source.size) { "Source buffer size must be equal tensor size" } } - public constructor(shape: ShapeND, buffer: DoubleBuffer) : this(shape, OffsetDoubleBuffer(buffer, 0, buffer.size)) + public constructor(shape: ShapeND, buffer: Float64Buffer) : this(shape, OffsetDoubleBuffer(buffer, 0, buffer.size)) @OptIn(PerformancePitfall::class) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 6bcf2753f..334a27c5b 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -10,7 +10,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* -import space.kscience.kmath.operations.DoubleBufferOps +import space.kscience.kmath.operations.Float64BufferOps import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.api.AnalyticTensorAlgebra @@ -34,7 +34,7 @@ public open class DoubleTensorAlgebra : override val elementAlgebra: Float64Field get() = Float64Field - public val bufferAlgebra: DoubleBufferOps get() = DoubleBufferOps + public val bufferAlgebra: Float64BufferOps get() = Float64BufferOps /** @@ -47,7 +47,7 @@ public open class DoubleTensorAlgebra : final override inline fun StructureND<Double>.map(transform: Float64Field.(Double) -> Double): DoubleTensor { val tensor = asDoubleTensor() //TODO remove additional copy - val array = DoubleBuffer(tensor.source.size) { Float64Field.transform(tensor.source[it]) } + val array = Float64Buffer(tensor.source.size) { Float64Field.transform(tensor.source[it]) } return DoubleTensor( tensor.shape, array, @@ -82,14 +82,14 @@ public open class DoubleTensorAlgebra : val leftTensor = left.asDoubleTensor() val rightTensor = right.asDoubleTensor() - val buffer = DoubleBuffer(leftTensor.source.size) { + val buffer = Float64Buffer(leftTensor.source.size) { Float64Field.transform(leftTensor.source[it], rightTensor.source[it]) } return DoubleTensor(leftTensor.shape, buffer) } - public inline fun StructureND<Double>.reduceElements(transform: (DoubleBuffer) -> Double): Double = + public inline fun StructureND<Double>.reduceElements(transform: (Float64Buffer) -> Double): Double = transform(asDoubleTensor().source.copy()) //TODO Add read-only DoubleBuffer wrapper. To avoid protective copy @@ -107,7 +107,7 @@ public open class DoubleTensorAlgebra : check(buffer.size == shape.linearSize) { "Inconsistent shape $shape for buffer of size ${buffer.size} provided" } - return DoubleTensor(shape, buffer.toDoubleBuffer()) + return DoubleTensor(shape, buffer.toFloat64Buffer()) } @@ -151,7 +151,7 @@ public open class DoubleTensorAlgebra : */ public fun full(value: Double, shape: ShapeND): DoubleTensor { checkNotEmptyShape(shape) - val buffer = DoubleBuffer(shape.linearSize) { value } + val buffer = Float64Buffer(shape.linearSize) { value } return DoubleTensor(shape, buffer) } @@ -163,7 +163,7 @@ public open class DoubleTensorAlgebra : */ public fun fullLike(structureND: StructureND<*>, value: Double): DoubleTensor { val shape = structureND.shape - val buffer = DoubleBuffer(structureND.indices.linearSize) { value } + val buffer = Float64Buffer(structureND.indices.linearSize) { value } return DoubleTensor(shape, buffer) } @@ -205,7 +205,7 @@ public open class DoubleTensorAlgebra : */ public fun eye(n: Int): DoubleTensor { val shape = ShapeND(n, n) - val buffer = DoubleBuffer(n * n) { 0.0 } + val buffer = Float64Buffer(n * n) { 0.0 } val res = DoubleTensor(shape, buffer) for (i in 0 until n) { res[intArrayOf(i, i)] = 1.0 @@ -353,7 +353,7 @@ public open class DoubleTensorAlgebra : */ public infix fun StructureND<Double>.matmul(other: StructureND<Double>): DoubleTensor { if (shape.size == 1 && other.shape.size == 1) { - return DoubleTensor(ShapeND(1), DoubleBuffer(times(other).sum())) + return DoubleTensor(ShapeND(1), Float64Buffer(times(other).sum())) } var penultimateDim = false @@ -529,7 +529,7 @@ public open class DoubleTensorAlgebra : val init = foldFunction(DoubleArray(1) { 0.0 }) val resTensor = DoubleTensor( resShape, - DoubleBuffer(resNumElements) { init } + Float64Buffer(resNumElements) { init } ) val dt = asDoubleTensor() for (index in resTensor.indices) { @@ -557,7 +557,7 @@ public open class DoubleTensorAlgebra : val init = foldFunction(DoubleArray(1) { 0.0 }) val resTensor = IntTensor( resShape, - IntBuffer(resNumElements) { init } + Int32Buffer(resNumElements) { init } ) for (index in resTensor.indices) { val prefix = index.take(dim).toIntArray() diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt index f028e2cbb..1066793a7 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt @@ -13,7 +13,7 @@ import space.kscience.kmath.structures.* * Default [BufferedTensor] implementation for [Int] values */ public class OffsetIntBuffer( - private val source: IntBuffer, + private val source: Int32Buffer, private val offset: Int, override val size: Int, ) : MutableBuffer<Int> { @@ -34,7 +34,7 @@ public class OffsetIntBuffer( /** * Copy only a part of buffer that belongs to this tensor */ - override fun copy(): IntBuffer = source.array.copyOfRange(offset, offset + size).asBuffer() + override fun copy(): Int32Buffer = source.array.copyOfRange(offset, offset + size).asBuffer() override fun iterator(): Iterator<Int> = iterator { for (i in indices) { @@ -53,15 +53,15 @@ public fun OffsetIntBuffer.slice(range: IntRange): OffsetIntBuffer = view(range. /** * Map only operable content of the offset buffer */ -public inline fun OffsetIntBuffer.map(operation: (Int) -> Int): IntBuffer = - IntBuffer(size) { operation(get(it)) } +public inline fun OffsetIntBuffer.map(operation: (Int) -> Int): Int32Buffer = + Int32Buffer(size) { operation(get(it)) } public inline fun OffsetIntBuffer.zip( other: OffsetIntBuffer, operation: (l: Int, r: Int) -> Int, -): IntBuffer { +): Int32Buffer { require(size == other.size) { "The sizes of zipped buffers must be the same" } - return IntBuffer(size) { operation(get(it), other[it]) } + return Int32Buffer(size) { operation(get(it), other[it]) } } /** @@ -83,7 +83,7 @@ public class IntTensor( require(linearSize == source.size) { "Source buffer size must be equal tensor size" } } - public constructor(shape: ShapeND, buffer: IntBuffer) : this(shape, OffsetIntBuffer(buffer, 0, buffer.size)) + public constructor(shape: ShapeND, buffer: Int32Buffer) : this(shape, OffsetIntBuffer(buffer, 0, buffer.size)) @OptIn(PerformancePitfall::class) override fun get(index: IntArray): Int = this.source[indices.offset(index)] diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt index a7899e84c..a09351b85 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt @@ -37,7 +37,7 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { final override inline fun StructureND<Int>.map(transform: Int32Ring.(Int) -> Int): IntTensor { val tensor = this.asIntTensor() //TODO remove additional copy - val array = IntBuffer(tensor.source.size) { Int32Ring.transform(tensor.source[it]) } + val array = Int32Buffer(tensor.source.size) { Int32Ring.transform(tensor.source[it]) } return IntTensor( tensor.shape, array, @@ -60,7 +60,7 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { final override inline fun StructureND<Int>.mapIndexed(transform: Int32Ring.(index: IntArray, Int) -> Int): IntTensor { val tensor = this.asIntTensor() //TODO remove additional copy - val buffer = IntBuffer(tensor.source.size) { + val buffer = Int32Buffer(tensor.source.size) { Int32Ring.transform(tensor.indices.index(it), tensor.source[it]) } return IntTensor(tensor.shape, buffer) @@ -76,14 +76,14 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { val leftTensor = left.asIntTensor() val rightTensor = right.asIntTensor() - val buffer = IntBuffer(leftTensor.source.size) { + val buffer = Int32Buffer(leftTensor.source.size) { Int32Ring.transform(leftTensor.source[it], rightTensor.source[it]) } return IntTensor(leftTensor.shape, buffer) } - public inline fun StructureND<Int>.reduceElements(transform: (IntBuffer) -> Int): Int = + public inline fun StructureND<Int>.reduceElements(transform: (Int32Buffer) -> Int): Int = transform(asIntTensor().source.copy()) //TODO do we need protective copy? @@ -139,7 +139,7 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { */ public fun full(value: Int, shape: ShapeND): IntTensor { checkNotEmptyShape(shape) - val buffer = IntBuffer(shape.linearSize) { value } + val buffer = Int32Buffer(shape.linearSize) { value } return IntTensor(shape, buffer) } @@ -151,7 +151,7 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { */ public fun fullLike(structureND: StructureND<*>, value: Int): IntTensor { val shape = structureND.shape - val buffer = IntBuffer(structureND.indices.linearSize) { value } + val buffer = Int32Buffer(structureND.indices.linearSize) { value } return IntTensor(shape, buffer) } @@ -193,7 +193,7 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { */ public fun eye(n: Int): IntTensor { val shape = ShapeND(n, n) - val buffer = IntBuffer(n * n) { 0 } + val buffer = Int32Buffer(n * n) { 0 } val res = IntTensor(shape, buffer) for (i in 0 until n) { res[intArrayOf(i, i)] = 1 @@ -420,7 +420,7 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { val init = foldFunction(IntArray(1) { 0 }) val resTensor = IntTensor( resShape, - IntBuffer(resNumElements) { init } + Int32Buffer(resNumElements) { init } ) for (index in resTensor.indices) { val prefix = index.take(dim).toIntArray() diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/doubleTensorHelpers.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/doubleTensorHelpers.kt index a293c8da3..0c1ffdbf3 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/doubleTensorHelpers.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/doubleTensorHelpers.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.tensors.core.internal import space.kscience.kmath.nd.* -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.structures.indices import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.eye @@ -22,13 +22,13 @@ import kotlin.math.sqrt internal fun MutableStructure2D<Double>.jacobiHelper( maxIteration: Int, epsilon: Double, -): Pair<DoubleBuffer, Structure2D<Double>> { +): Pair<Float64Buffer, Structure2D<Double>> { val n = rowNum val A_ = copyToTensor() val V = eye(n) - val D = DoubleBuffer(n) { get(it, it) } - val B = DoubleBuffer(n) { get(it, it) } - val Z = DoubleBuffer(n) { 0.0 } + val D = Float64Buffer(n) { get(it, it) } + val B = Float64Buffer(n) { get(it, it) } + val Z = Float64Buffer(n) { 0.0 } // assume that buffered tensor is square matrix operator fun DoubleTensor.get(i: Int, j: Int): Double { @@ -59,8 +59,8 @@ internal fun MutableStructure2D<Double>.jacobiHelper( fun jacobiIteration( a: DoubleTensor, v: DoubleTensor, - d: DoubleBuffer, - z: DoubleBuffer, + d: Float64Buffer, + z: Float64Buffer, ) { for (ip in 0 until n - 1) { for (iq in ip + 1 until n) { @@ -108,9 +108,9 @@ internal fun MutableStructure2D<Double>.jacobiHelper( } fun updateDiagonal( - d: DoubleBuffer, - z: DoubleBuffer, - b: DoubleBuffer, + d: Float64Buffer, + z: Float64Buffer, + b: Float64Buffer, ) { for (ip in 0 until d.size) { b[ip] += z[ip] @@ -137,7 +137,7 @@ internal fun MutableStructure2D<Double>.jacobiHelper( /** * Concatenate a list of arrays */ -internal fun List<OffsetDoubleBuffer>.concat(): DoubleBuffer { +internal fun List<OffsetDoubleBuffer>.concat(): Float64Buffer { val array = DoubleArray(sumOf { it.size }) var pointer = 0 while (pointer < array.size) { diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt index 35f0bf324..c47d94a92 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt @@ -9,7 +9,7 @@ import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.first import space.kscience.kmath.nd.last import space.kscience.kmath.operations.asSequence -import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.Int32Buffer import space.kscience.kmath.structures.VirtualBuffer import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.structures.indices @@ -19,7 +19,7 @@ import space.kscience.kmath.tensors.core.OffsetIntBuffer /** * Concatenate a list of arrays */ -internal fun List<OffsetIntBuffer>.concat(): IntBuffer { +internal fun List<OffsetIntBuffer>.concat(): Int32Buffer { val array = IntArray(sumOf { it.size }) var pointer = 0 while (pointer < array.size) { diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index 7a96001c6..272af41d5 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -7,8 +7,8 @@ package space.kscience.kmath.tensors.core.internal import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.DoubleBuffer -import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.Float64Buffer +import space.kscience.kmath.structures.Int32Buffer import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.structures.indices import space.kscience.kmath.tensors.core.* @@ -97,7 +97,7 @@ internal fun <T> StructureND<T>.setUpPivots(): IntTensor { return IntTensor( ShapeND(pivotsShape), - IntBuffer(pivotsShape.reduce(Int::times)) { 0 } + Int32Buffer(pivotsShape.reduce(Int::times)) { 0 } ) } @@ -241,10 +241,10 @@ internal fun DoubleTensorAlgebra.svd1d(a: DoubleTensor, epsilon: Double = 1e-10) val b: DoubleTensor if (n > m) { b = a.transposed(0, 1).dot(a) - v = DoubleTensor(ShapeND(m), DoubleBuffer.randomUnitVector(m, 0)) + v = DoubleTensor(ShapeND(m), Float64Buffer.randomUnitVector(m, 0)) } else { b = a.dot(a.transposed(0, 1)) - v = DoubleTensor(ShapeND(n), DoubleBuffer.randomUnitVector(n, 0)) + v = DoubleTensor(ShapeND(n), Float64Buffer.randomUnitVector(n, 0)) } var lastV: DoubleTensor diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt index 2709ac474..d48086d57 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt @@ -8,22 +8,22 @@ package space.kscience.kmath.tensors.core.internal import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.asList import space.kscience.kmath.nd.last -import space.kscience.kmath.operations.DoubleBufferOps.Companion.map +import space.kscience.kmath.operations.Float64BufferOps.Companion.map import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.samplers.GaussianSampler -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.tensors.core.BufferedTensor import space.kscience.kmath.tensors.core.DoubleTensor import kotlin.math.* -internal fun DoubleBuffer.Companion.randomNormals(n: Int, seed: Long): DoubleBuffer { +internal fun Float64Buffer.Companion.randomNormals(n: Int, seed: Long): Float64Buffer { val distribution = GaussianSampler(0.0, 1.0) val generator = RandomGenerator.default(seed) return distribution.sample(generator).nextBufferBlocking(n) } -internal fun DoubleBuffer.Companion.randomUnitVector(n: Int, seed: Long): DoubleBuffer { - val unnorm: DoubleBuffer = randomNormals(n, seed) +internal fun Float64Buffer.Companion.randomUnitVector(n: Int, seed: Long): Float64Buffer { + val unnorm: Float64Buffer = randomNormals(n, seed) val norm = sqrt(unnorm.array.sumOf { it * it }) return unnorm.map { it / norm } } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt index 88ffb0bfe..1b630a0ef 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.nd.* import space.kscience.kmath.operations.covariance import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.tensors.api.Tensor import space.kscience.kmath.tensors.core.internal.* import kotlin.math.min @@ -24,7 +24,7 @@ import kotlin.math.sign * with `0.0` mean and `1.0` standard deviation. */ public fun DoubleTensorAlgebra.randomNormal(shape: ShapeND, seed: Long = 0): DoubleTensor = - fromBuffer(shape, DoubleBuffer.randomNormals(shape.linearSize, seed)) + fromBuffer(shape, Float64Buffer.randomNormals(shape.linearSize, seed)) /** * Returns a tensor with the same shape as `input` of random numbers drawn from normal distributions @@ -36,7 +36,7 @@ public fun DoubleTensorAlgebra.randomNormal(shape: ShapeND, seed: Long = 0): Dou * with `0.0` mean and `1.0` standard deviation. */ public fun DoubleTensorAlgebra.randomNormalLike(structure: WithShape, seed: Long = 0): DoubleTensor = - DoubleTensor(structure.shape, DoubleBuffer.randomNormals(structure.shape.linearSize, seed)) + DoubleTensor(structure.shape, Float64Buffer.randomNormals(structure.shape.linearSize, seed)) /** * Concatenates a sequence of tensors with equal shapes along the first dimension. @@ -336,7 +336,7 @@ public fun DoubleTensorAlgebra.detLU(structureND: StructureND<Double>, epsilon: set(n - 2, 1) }) - val resBuffer = DoubleBuffer(detTensorShape.linearSize) { 0.0 } + val resBuffer = Float64Buffer(detTensorShape.linearSize) { 0.0 } val detTensor = DoubleTensor( detTensorShape, @@ -389,7 +389,7 @@ public fun DoubleTensorAlgebra.covariance(vectors: List<Buffer<Double>>): Double check(vectors.all { it.size == m }) { "Vectors must have same shapes" } val resTensor = DoubleTensor( ShapeND(n, n), - DoubleBuffer(n * n) { 0.0 } + Float64Buffer(n * n) { 0.0 } ) for (i in 0 until n) { for (j in 0 until n) { diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt index 3b0d15400..52a530652 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.nd.* -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.tensors.api.Tensor @@ -16,7 +16,7 @@ import space.kscience.kmath.tensors.api.Tensor */ public fun StructureND<Double>.copyToTensor(): DoubleTensor = if (this is DoubleTensor) { DoubleTensor(shape, source.copy()) -} else if (this is DoubleBufferND && indices is RowStrides) { +} else if (this is Float64BufferND && indices is RowStrides) { DoubleTensor(shape, buffer.copy()) } else { DoubleTensor( @@ -29,7 +29,7 @@ public fun StructureND<Int>.toDoubleTensor(): DoubleTensor { return if (this is IntTensor) { DoubleTensor( shape, - DoubleBuffer(linearSize) { source[it].toDouble() } + Float64Buffer(linearSize) { source[it].toDouble() } ) } else { val tensor = DoubleTensorAlgebra.zeroesLike(this) @@ -45,7 +45,7 @@ public fun StructureND<Int>.toDoubleTensor(): DoubleTensor { */ public fun StructureND<Double>.asDoubleTensor(): DoubleTensor = if (this is DoubleTensor) { this -} else if (this is DoubleBufferND && indices is RowStrides) { +} else if (this is Float64BufferND && indices is RowStrides) { DoubleTensor(shape, buffer) } else { copyToTensor() diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt index 811fc1117..3081639af 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.toDoubleArray import space.kscience.kmath.tensors.core.internal.matrixSequence import space.kscience.kmath.testutils.assertBufferEquals @@ -65,10 +65,10 @@ internal class TestDoubleTensor { fun testNoBufferProtocol() { // create buffer - val doubleArray = DoubleBuffer(1.0, 2.0, 3.0) + val doubleArray = Float64Buffer(1.0, 2.0, 3.0) // create ND buffers, no data is copied - val ndArray: MutableBufferND<Double> = DoubleBufferND(ColumnStrides(ShapeND(3)), doubleArray) + val ndArray: MutableBufferND<Double> = Float64BufferND(ColumnStrides(ShapeND(3)), doubleArray) // map to tensors val tensorArray = ndArray.asDoubleTensor() // Data is copied because of strides change. @@ -95,8 +95,8 @@ internal class TestDoubleTensor { val tensor: DoubleTensor = structureND(ShapeND(3, 3)) { (i, j) -> (i - j).toDouble() } //println(tensor.toPrettyString()) val tensor2d = tensor.asDoubleTensor2D() - assertBufferEquals(DoubleBuffer(1.0, 0.0, -1.0), tensor2d.rows[1]) - assertBufferEquals(DoubleBuffer(-2.0, -1.0, 0.0), tensor2d.columns[2]) + assertBufferEquals(Float64Buffer(1.0, 0.0, -1.0), tensor2d.rows[1]) + assertBufferEquals(Float64Buffer(-2.0, -1.0, 0.0), tensor2d.columns[2]) } @Test diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/offsetBufferEquality.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/offsetBufferEquality.kt index e9fc7fb9c..c3127ed97 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/offsetBufferEquality.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/offsetBufferEquality.kt @@ -6,13 +6,13 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.indices import kotlin.jvm.JvmName /** - * Simplified [DoubleBuffer] to array comparison + * Simplified [Float64Buffer] to array comparison */ public fun OffsetDoubleBuffer.contentEquals(vararg doubles: Double): Boolean = indices.all { get(it) == doubles[it] } diff --git a/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index 4c039190a..0d0332395 100644 --- a/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.test.Test import kotlin.test.assertEquals @@ -283,7 +283,7 @@ class TestLmAlgorithm { assertEquals(4858, result.funcCalls) assertEquals(5.14347, result.resultLambda, 1e-5) assertEquals(result.typeOfConvergence, TypeOfConvergence.InParameters) - val expectedParameters = DoubleBuffer( + val expectedParameters = Float64Buffer( -23.6412, -16.7402, -21.5705, diff --git a/test-utils/src/commonMain/kotlin/bufferEquality.kt b/test-utils/src/commonMain/kotlin/bufferEquality.kt index 9e4d9ec22..c4485abbd 100644 --- a/test-utils/src/commonMain/kotlin/bufferEquality.kt +++ b/test-utils/src/commonMain/kotlin/bufferEquality.kt @@ -5,16 +5,16 @@ package space.kscience.kmath.testutils -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import kotlin.jvm.JvmName /** - * Simplified [DoubleBuffer] to array comparison + * Simplified [Float64Buffer] to array comparison */ -public fun DoubleBuffer.contentEquals(vararg doubles: Double): Boolean = array.contentEquals(doubles) +public fun Float64Buffer.contentEquals(vararg doubles: Double): Boolean = array.contentEquals(doubles) @JvmName("contentEqualsArray") -public infix fun DoubleBuffer.contentEquals(otherArray: DoubleArray): Boolean = array.contentEquals(otherArray) +public infix fun Float64Buffer.contentEquals(otherArray: DoubleArray): Boolean = array.contentEquals(otherArray) @JvmName("contentEqualsBuffer") -public infix fun DoubleBuffer.contentEquals(otherBuffer: DoubleBuffer): Boolean = array.contentEquals(otherBuffer.array) \ No newline at end of file +public infix fun Float64Buffer.contentEquals(otherBuffer: Float64Buffer): Boolean = array.contentEquals(otherBuffer.array) \ No newline at end of file From efb853c1bcd0ad9aa3f7bf8d5b978ef8fd74843d Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sat, 12 Aug 2023 13:16:18 +0300 Subject: [PATCH 046/103] Refactor geometry --- CHANGELOG.md | 5 +- .../kscience/kmath/complex/Quaternion.kt | 35 +++--- .../kscience/kmath/complex/QuaternionTest.kt | 24 ++-- .../kscience/kmath/operations/Algebra.kt | 8 +- .../kmath/operations/NumericAlgebra.kt | 4 +- .../kmath/operations/OptionalOperations.kt | 4 +- .../space/kscience/kmath/real/DoubleVector.kt | 1 - .../space/kscience/kmath/geometry/Line.kt | 2 + .../space/kscience/kmath/geometry/Vector2D.kt | 29 +++++ .../space/kscience/kmath/geometry/Vector3D.kt | 41 +++++++ .../geometry/{ => euclidean2d}/Circle2D.kt | 9 +- .../geometry/euclidean2d/Float32Space2D.kt | 79 +++++++++++++ .../Float64Space2D.kt} | 33 ++---- .../geometry/{ => euclidean2d}/Polygon.kt | 4 +- .../geometry/euclidean3d/Float32Space3D.kt | 108 ++++++++++++++++++ .../Float64Space3D.kt} | 71 ++++-------- .../geometry/{ => euclidean3d}/rotations3D.kt | 21 ++-- .../kscience/kmath/geometry/floatPrecision.kt | 8 +- .../kmath/geometry/quaternionOperations.kt | 55 +++++++++ .../kmath/geometry/Euclidean2DSpaceTest.kt | 11 +- .../kmath/geometry/Euclidean3DSpaceTest.kt | 17 +-- .../kmath/geometry/ProjectionAlongTest.kt | 10 +- .../kmath/geometry/ProjectionOntoLineTest.kt | 12 +- .../kscience/kmath/geometry/RotationTest.kt | 5 +- .../kscience/kmath/geometry/Vector2DTest.kt | 3 +- .../kscience/kmath/geometry/Vector3DTest.kt | 3 +- .../kscience/kmath/geometry/testUtils.kt | 2 + .../tensorflow/DoubleTensorFlowAlgebra.kt | 4 +- 28 files changed, 454 insertions(+), 154 deletions(-) create mode 100644 kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt create mode 100644 kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt rename kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/{ => euclidean2d}/Circle2D.kt (56%) create mode 100644 kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt rename kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/{Euclidean2DSpace.kt => euclidean2d/Float64Space2D.kt} (75%) rename kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/{ => euclidean2d}/Polygon.kt (74%) create mode 100644 kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt rename kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/{Euclidean3DSpace.kt => euclidean3d/Float64Space3D.kt} (66%) rename kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/{ => euclidean3d}/rotations3D.kt (89%) create mode 100644 kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 9235cfd57..27b67a4d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,14 @@ ## Unreleased ### Added -- Integer divistion algebras +- Integer division algebras +- Float32 geometries ### Changed - Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types. - Remove unnecessary inlines in basic algebras. +- QuaternionField -> QuaternionAlgebra and does not implement `Field` anymore since it is non-commutative +- kmath-geometry is split into `euclidean2d` and `euclidean3d` ### Deprecated diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt index d4259c4dc..8f3d15a26 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt @@ -122,16 +122,17 @@ public val Quaternion.reciprocal: Quaternion /** * Produce a normalized version of this quaternion */ -public fun Quaternion.normalized(): Quaternion = with(QuaternionField){ this@normalized / norm(this@normalized) } +public fun Quaternion.normalized(): Quaternion = with(QuaternionAlgebra){ this@normalized / norm(this@normalized) } /** * A field of [Quaternion]. */ @OptIn(UnstableKMathAPI::class) -public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, PowerOperations<Quaternion>, +public object QuaternionAlgebra : Group<Quaternion>, Norm<Quaternion, Double>, PowerOperations<Quaternion>, ExponentialOperations<Quaternion>, NumbersAddOps<Quaternion>, ScaleOperations<Quaternion> { + override val zero: Quaternion = Quaternion(0.0) - override val one: Quaternion = Quaternion(1.0) + public val one: Quaternion = Quaternion(1.0) /** * The `i` quaternion unit. @@ -154,14 +155,16 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, Pow override fun scale(a: Quaternion, value: Double): Quaternion = Quaternion(a.w * value, a.x * value, a.y * value, a.z * value) - override fun multiply(left: Quaternion, right: Quaternion): Quaternion = Quaternion( + public fun multiply(left: Quaternion, right: Quaternion): Quaternion = Quaternion( left.w * right.w - left.x * right.x - left.y * right.y - left.z * right.z, left.w * right.x + left.x * right.w + left.y * right.z - left.z * right.y, left.w * right.y - left.x * right.z + left.y * right.w + left.z * right.x, left.w * right.z + left.x * right.y - left.y * right.x + left.z * right.w, ) - override fun divide(left: Quaternion, right: Quaternion): Quaternion { + public operator fun Quaternion.times(other: Quaternion): Quaternion = multiply(this, other) + + public fun divide(left: Quaternion, right: Quaternion): Quaternion { val s = right.w * right.w + right.x * right.x + right.y * right.y + right.z * right.z return Quaternion( @@ -172,14 +175,17 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, Pow ) } + public operator fun Quaternion.div(other: Quaternion): Quaternion = divide(this, other) + + override fun power(arg: Quaternion, pow: Number): Quaternion { - if (pow is Int) return pwr(arg, pow) - if (floor(pow.toDouble()) == pow.toDouble()) return pwr(arg, pow.toInt()) + if (pow is Int) return power(arg, pow) + if (floor(pow.toDouble()) == pow.toDouble()) return power(arg, pow.toInt()) return exp(pow * ln(arg)) } - private fun pwr(x: Quaternion, a: Int): Quaternion = when { - a < 0 -> -(pwr(x, -a)) + private fun power(x: Quaternion, a: Int): Quaternion = when { + a < 0 -> -(power(x, -a)) a == 0 -> one a == 1 -> x a == 2 -> pwr2(x) @@ -243,14 +249,15 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, Pow return Quaternion(ln(n), th * arg.x, th * arg.y, th * arg.z) } - override operator fun Number.plus(other: Quaternion): Quaternion = + public override operator fun Number.plus(other: Quaternion): Quaternion = Quaternion(toDouble() + other.w, other.x, other.y, other.z) - override operator fun Number.minus(other: Quaternion): Quaternion = + public override operator fun Number.minus(other: Quaternion): Quaternion = Quaternion(toDouble() - other.w, -other.x, -other.y, -other.z) - override operator fun Quaternion.plus(other: Number): Quaternion = Quaternion(w + other.toDouble(), x, y, z) - override operator fun Quaternion.minus(other: Number): Quaternion = Quaternion(w - other.toDouble(), x, y, z) + public override operator fun Quaternion.plus(other: Number): Quaternion = Quaternion(w + other.toDouble(), x, y, z) + + public override operator fun Quaternion.minus(other: Number): Quaternion = Quaternion(w - other.toDouble(), x, y, z) override operator fun Number.times(arg: Quaternion): Quaternion = Quaternion(toDouble() * arg.w, toDouble() * arg.x, toDouble() * arg.y, toDouble() * arg.z) @@ -275,7 +282,7 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Double>, Pow override fun sinh(arg: Quaternion): Quaternion = (exp(arg) - exp(-arg)) / 2.0 override fun cosh(arg: Quaternion): Quaternion = (exp(arg) + exp(-arg)) / 2.0 override fun tanh(arg: Quaternion): Quaternion = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg)) - override fun asinh(arg: Quaternion): Quaternion = ln(sqrt(arg * arg + one) + arg) + override fun asinh(arg: Quaternion): Quaternion = ln(sqrt(pwr2(arg) + one) + arg) override fun acosh(arg: Quaternion): Quaternion = ln(arg + sqrt((arg - one) * (arg + one))) override fun atanh(arg: Quaternion): Quaternion = (ln(arg + one) - ln(one - arg)) / 2.0 } diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/QuaternionTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/QuaternionTest.kt index fd0fd46a7..1b371adca 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/QuaternionTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/QuaternionTest.kt @@ -14,20 +14,20 @@ internal class QuaternionTest { @Test fun testNorm() { - assertEquals(2.0, QuaternionField.norm(Quaternion(1.0, 1.0, 1.0, 1.0))) + assertEquals(2.0, QuaternionAlgebra.norm(Quaternion(1.0, 1.0, 1.0, 1.0))) } @Test - fun testInverse() = QuaternionField { + fun testInverse() = QuaternionAlgebra { val q = Quaternion(1.0, 2.0, -3.0, 4.0) assertBufferEquals(one, q * q.reciprocal, 1e-4) } @Test fun testAddition() { - assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(16, 16) + Quaternion(26, 26) }) - assertEquals(Quaternion(42, 16), QuaternionField { Quaternion(16, 16) + 26 }) - assertEquals(Quaternion(42, 16), QuaternionField { 26 + Quaternion(16, 16) }) + assertEquals(Quaternion(42, 42), QuaternionAlgebra { Quaternion(16, 16) + Quaternion(26, 26) }) + assertEquals(Quaternion(42, 16), QuaternionAlgebra { Quaternion(16, 16) + 26 }) + assertEquals(Quaternion(42, 16), QuaternionAlgebra { 26 + Quaternion(16, 16) }) } // @Test @@ -39,9 +39,9 @@ internal class QuaternionTest { @Test fun testMultiplication() { - assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(4.2, 0) * Quaternion(10, 10) }) - assertEquals(Quaternion(42, 21), QuaternionField { Quaternion(4.2, 2.1) * 10 }) - assertEquals(Quaternion(42, 21), QuaternionField { 10 * Quaternion(4.2, 2.1) }) + assertEquals(Quaternion(42, 42), QuaternionAlgebra { Quaternion(4.2, 0) * Quaternion(10, 10) }) + assertEquals(Quaternion(42, 21), QuaternionAlgebra { Quaternion(4.2, 2.1) * 10 }) + assertEquals(Quaternion(42, 21), QuaternionAlgebra { 10 * Quaternion(4.2, 2.1) }) } // @Test @@ -53,11 +53,11 @@ internal class QuaternionTest { @Test fun testPower() { - assertEquals(QuaternionField.zero, QuaternionField { zero pow 2 }) - assertEquals(QuaternionField.zero, QuaternionField { zero pow 2 }) + assertEquals(QuaternionAlgebra.zero, QuaternionAlgebra { zero pow 2 }) + assertEquals(QuaternionAlgebra.zero, QuaternionAlgebra { zero pow 2 }) assertEquals( - QuaternionField { i * 8 }.let { it.x.toInt() to it.w.toInt() }, - QuaternionField { Quaternion(2, 2) pow 2 }.let { it.x.toInt() to it.w.toInt() }) + QuaternionAlgebra { i * 8 }.let { it.x.toInt() to it.w.toInt() }, + QuaternionAlgebra { Quaternion(2, 2) pow 2 }.let { it.x.toInt() to it.w.toInt() }) } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt index 0960ab023..67f37ed62 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt @@ -300,7 +300,7 @@ public interface Ring<T> : Group<T>, RingOps<T> { * commutative operations [add] and [multiply]; binary operation [divide] as multiplication of left operand by * reciprocal of right one. * - * @param T the type of element of this semifield. + * @param T the type of the semifield element. */ public interface FieldOps<T> : RingOps<T> { /** @@ -336,10 +336,12 @@ public interface FieldOps<T> : RingOps<T> { /** * Represents field i.e., algebraic structure with three operations: associative, commutative addition and - * multiplication, and division. **This interface differs from the eponymous mathematical definition: fields in KMath + * multiplication, and division. + * + * **This interface differs from the eponymous mathematical definition: fields in KMath * also support associative multiplication by scalar.** * - * @param T the type of element of this field. + * @param T the type of the field element. */ public interface Field<T> : Ring<T>, FieldOps<T>, ScaleOperations<T>, NumericAlgebra<T> { override fun number(value: Number): T = scale(one, value.toDouble()) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt index 9bcfb00a2..06ad68298 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt @@ -150,7 +150,7 @@ public interface ScaleOperations<T> : Algebra<T> { * TODO to be removed and replaced by extensions after multiple receivers are there */ @UnstableKMathAPI -public interface NumbersAddOps<T> : RingOps<T>, NumericAlgebra<T> { +public interface NumbersAddOps<T> : GroupOps<T>, NumericAlgebra<T> { /** * Addition of element and scalar. * @@ -177,7 +177,7 @@ public interface NumbersAddOps<T> : RingOps<T>, NumericAlgebra<T> { public operator fun T.minus(other: Number): T = this - number(other) /** - * Subtraction of number from element. + * Subtraction of number from the element. * * @receiver the minuend. * @param other the subtrahend. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt index c24394add..48cac2870 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt @@ -82,9 +82,9 @@ public expect fun Number.isInteger(): Boolean /** * A context extension to include power operations based on exponentiation. * - * @param T the type of element of this structure. + * @param T the type of this structure element */ -public interface PowerOperations<T> : FieldOps<T> { +public interface PowerOperations<T>: Algebra<T> { /** * Raises [arg] to a power if possible (negative number could not be raised to a fractional power). diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt index 108b840dd..d13528636 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt @@ -16,7 +16,6 @@ import kotlin.math.pow public typealias DoubleVector = Point<Double> -@Suppress("FunctionName") public fun DoubleVector(vararg doubles: Double): DoubleVector = doubles.asBuffer() /** diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt index a7f6ae35d..92d31a7cb 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt @@ -7,6 +7,8 @@ package space.kscience.kmath.geometry import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.kmath.geometry.euclidean2d.DoubleVector2D +import space.kscience.kmath.geometry.euclidean3d.DoubleVector3D /** * A line formed by [start] vector of start and a [direction] vector. Direction vector is not necessarily normalized, diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt new file mode 100644 index 000000000..9eced7ba9 --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2018-2023 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.geometry + +import space.kscience.kmath.linear.Point + +public interface Vector2D<T> : Point<T>, Vector { + public val x: T + public val y: T + override val size: Int get() = 2 + + override operator fun get(index: Int): T = when (index) { + 0 -> x + 1 -> y + else -> error("Accessing outside of point bounds") + } + + override operator fun iterator(): Iterator<T> = iterator { + yield(x) + yield(y) + } +} + + +public operator fun <T> Vector2D<T>.component1(): T = x +public operator fun <T> Vector2D<T>.component2(): T = y \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt new file mode 100644 index 000000000..7e7c6c4ed --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2018-2023 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.geometry + +import space.kscience.kmath.linear.Point +import space.kscience.kmath.structures.Buffer + +public interface Vector3D<T> : Point<T>, Vector { + public val x: T + public val y: T + public val z: T + override val size: Int get() = 3 + + override operator fun get(index: Int): T = when (index) { + 0 -> x + 1 -> y + 2 -> z + else -> error("Accessing outside of point bounds") + } + + override operator fun iterator(): Iterator<T> = listOf(x, y, z).iterator() +} + +public operator fun <T> Vector3D<T>.component1(): T = x +public operator fun <T> Vector3D<T>.component2(): T = y +public operator fun <T> Vector3D<T>.component3(): T = z + +public fun <T> Buffer<T>.asVector3D(): Vector3D<T> = object : Vector3D<T> { + init { + require(this@asVector3D.size == 3) { "Buffer of size 3 is required for Vector3D" } + } + + override val x: T get() = this@asVector3D[0] + override val y: T get() = this@asVector3D[1] + override val z: T get() = this@asVector3D[2] + + override fun toString(): String = this@asVector3D.toString() +} \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt similarity index 56% rename from kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt rename to kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt index d37ed45c0..7841be8ff 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Circle2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt @@ -1,20 +1,19 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2023 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.geometry +package space.kscience.kmath.geometry.euclidean2d import kotlinx.serialization.Serializable -import space.kscience.kmath.geometry.Euclidean2DSpace.distanceTo -import kotlin.math.* +import kotlin.math.PI /** * A circle in 2D space */ @Serializable public data class Circle2D( - @Serializable(Euclidean2DSpace.VectorSerializer::class) public val center: DoubleVector2D, + @Serializable(Float64Space2D.VectorSerializer::class) public val center: DoubleVector2D, public val radius: Double ) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt new file mode 100644 index 000000000..89c3dc204 --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt @@ -0,0 +1,79 @@ +/* + * Copyright 2018-2023 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.geometry.euclidean2d + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import space.kscience.kmath.geometry.GeometrySpace +import space.kscience.kmath.geometry.Vector2D +import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.operations.ScaleOperations +import kotlin.math.pow +import kotlin.math.sqrt + +@Serializable(Float32Space2D.VectorSerializer::class) +public interface Float32Vector2D: Vector2D<Float> + + +public object Float32Space2D : + GeometrySpace<Float32Vector2D>, + ScaleOperations<Float32Vector2D> { + + @Serializable + @SerialName("Float32Vector2D") + private data class Vector2DImpl( + override val x: Float, + override val y: Float, + ) : Float32Vector2D + + public object VectorSerializer : KSerializer<Float32Vector2D> { + private val proxySerializer = Vector2DImpl.serializer() + override val descriptor: SerialDescriptor get() = proxySerializer.descriptor + + override fun deserialize(decoder: Decoder): Float32Vector2D = decoder.decodeSerializableValue(proxySerializer) + + override fun serialize(encoder: Encoder, value: Float32Vector2D) { + val vector = value as? Vector2DImpl ?: Vector2DImpl(value.x, value.y) + encoder.encodeSerializableValue(proxySerializer, vector) + } + } + + public fun vector(x: Float, y: Float): Float32Vector2D = + Vector2DImpl(x, y) + + public fun vector(x: Number, y: Number): Float32Vector2D = + vector(x.toFloat(), y.toFloat()) + + override val zero: Float32Vector2D by lazy { vector(0f, 0f) } + + override fun norm(arg: Float32Vector2D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2)).toDouble() + + public fun Float32Vector2D.norm(): Double = norm(this) + + override fun Float32Vector2D.unaryMinus(): Float32Vector2D = vector(-x, -y) + + override fun Float32Vector2D.distanceTo(other: Float32Vector2D): Double = (this - other).norm() + + override fun add(left: Float32Vector2D, right: Float32Vector2D): Float32Vector2D = + vector(left.x + right.x, left.y + right.y) + + override fun scale(a: Float32Vector2D, value: Double): Float32Vector2D = + vector(a.x * value, a.y * value) + + override fun Float32Vector2D.dot(other: Float32Vector2D): Double = + (x * other.x + y * other.y).toDouble() + + public val xAxis: Float32Vector2D = vector(1.0, 0.0) + public val yAxis: Float32Vector2D = vector(0.0, 1.0) +} + +public fun Float32Vector2D(x: Number, y: Number): Float32Vector2D = Float32Space2D.vector(x, y) + +public val Float32Field.euclidean2D: Float32Space2D get() = Float32Space2D diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt similarity index 75% rename from kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt rename to kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt index 3df8dba7b..030a46185 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean2DSpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt @@ -1,9 +1,9 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2023 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.geometry +package space.kscience.kmath.geometry.euclidean2d import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialName @@ -11,43 +11,26 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import space.kscience.kmath.linear.Point +import space.kscience.kmath.geometry.GeometrySpace +import space.kscience.kmath.geometry.Vector2D +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Norm import space.kscience.kmath.operations.ScaleOperations import kotlin.math.pow import kotlin.math.sqrt -public interface Vector2D<T> : Point<T>, Vector { - public val x: T - public val y: T - override val size: Int get() = 2 - override operator fun get(index: Int): T = when (index) { - 0 -> x - 1 -> y - else -> error("Accessing outside of point bounds") - } - - override operator fun iterator(): Iterator<T> = iterator { - yield(x) - yield(y) - } -} - - -public operator fun <T> Vector2D<T>.component1(): T = x -public operator fun <T> Vector2D<T>.component2(): T = y public typealias DoubleVector2D = Vector2D<Double> public typealias Float64Vector2D = Vector2D<Double> -public val Vector2D<Double>.r: Double get() = Euclidean2DSpace.norm(this) +public val Vector2D<Double>.r: Double get() = Float64Space2D.norm(this) /** * 2D Euclidean space */ -public object Euclidean2DSpace : GeometrySpace<DoubleVector2D>, +public object Float64Space2D : GeometrySpace<DoubleVector2D>, ScaleOperations<DoubleVector2D>, Norm<DoubleVector2D, Double> { @@ -88,3 +71,5 @@ public object Euclidean2DSpace : GeometrySpace<DoubleVector2D>, public val xAxis: DoubleVector2D = vector(1.0, 0.0) public val yAxis: DoubleVector2D = vector(0.0, 1.0) } + +public val Float64Field.euclidean2D: Float64Space2D get() = Float64Space2D \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt similarity index 74% rename from kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt rename to kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt index 20f4a031e..85b377a56 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt @@ -3,7 +3,9 @@ * 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.geometry +package space.kscience.kmath.geometry.euclidean2d + +import space.kscience.kmath.geometry.Vector2D /** diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt new file mode 100644 index 000000000..1413a885b --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt @@ -0,0 +1,108 @@ +/* + * Copyright 2018-2023 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.geometry.euclidean3d + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import space.kscience.kmath.geometry.GeometrySpace +import space.kscience.kmath.geometry.Vector3D +import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.operations.ScaleOperations +import kotlin.math.pow +import kotlin.math.sqrt + +@Serializable(Float32Space3D.VectorSerializer::class) +public interface Float32Vector3D: Vector3D<Float> + + +public object Float32Space3D : + GeometrySpace<Float32Vector3D>, + ScaleOperations<Float32Vector3D>{ + + @Serializable + @SerialName("Float32Vector3D") + private data class Vector3DImpl( + override val x: Float, + override val y: Float, + override val z: Float, + ) : Float32Vector3D + + public object VectorSerializer : KSerializer<Float32Vector3D> { + private val proxySerializer = Vector3DImpl.serializer() + override val descriptor: SerialDescriptor get() = proxySerializer.descriptor + + override fun deserialize(decoder: Decoder): Float32Vector3D = decoder.decodeSerializableValue(proxySerializer) + + override fun serialize(encoder: Encoder, value: Float32Vector3D) { + val vector = value as? Vector3DImpl ?: Vector3DImpl(value.x, value.y, value.z) + encoder.encodeSerializableValue(proxySerializer, vector) + } + } + + public fun vector(x: Float, y: Float, z: Float): Float32Vector3D = + Vector3DImpl(x, y, z) + + public fun vector(x: Number, y: Number, z: Number): Float32Vector3D = + vector(x.toFloat(), y.toFloat(), z.toFloat()) + + override val zero: Float32Vector3D by lazy { vector(0.0, 0.0, 0.0) } + + override fun norm(arg: Float32Vector3D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)).toDouble() + + public fun Float32Vector3D.norm(): Double = norm(this) + + override fun Float32Vector3D.unaryMinus(): Float32Vector3D = vector(-x, -y, -z) + + override fun Float32Vector3D.distanceTo(other: Float32Vector3D): Double = (this - other).norm() + + override fun add(left: Float32Vector3D, right: Float32Vector3D): Float32Vector3D = + vector(left.x + right.x, left.y + right.y, left.z + right.z) + + override fun scale(a: Float32Vector3D, value: Double): Float32Vector3D = + vector(a.x * value, a.y * value, a.z * value) + + override fun Float32Vector3D.dot(other: Float32Vector3D): Double = + (x * other.x + y * other.y + z * other.z).toDouble() + + /** + * Compute vector product of [first] and [second]. The basis is assumed to be right-handed. + */ + public fun vectorProduct( + first: Float32Vector3D, + second: Float32Vector3D, + ): Float32Vector3D { + var x = 0.0 + var y = 0.0 + var z = 0.0 + + for (j in (0..2)) { + for (k in (0..2)) { + x += leviCivita(0, j, k) * first[j] * second[k] + y += leviCivita(1, j, k) * first[j] * second[k] + z += leviCivita(2, j, k) * first[j] * second[k] + } + } + + return vector(x, y, z) + } + + /** + * Vector product in a right-handed basis + */ + public infix fun Float32Vector3D.cross(other: Float32Vector3D): Float32Vector3D = vectorProduct(this, other) + + public val xAxis: Float32Vector3D = vector(1.0, 0.0, 0.0) + public val yAxis: Float32Vector3D = vector(0.0, 1.0, 0.0) + public val zAxis: Float32Vector3D = vector(0.0, 0.0, 1.0) +} + +public fun Float32Vector3D(x: Number, y: Number, z: Number): Float32Vector3D = Float32Space3D.vector(x, y, z) + +public val Float32Field.euclidean3D: Float32Space3D get() = Float32Space3D \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt similarity index 66% rename from kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt rename to kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt index 3059cefe6..a8c7e1d17 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Euclidean3DSpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt @@ -1,9 +1,9 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2023 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.geometry +package space.kscience.kmath.geometry.euclidean3d import kotlinx.serialization.KSerializer import kotlinx.serialization.SerialName @@ -11,51 +11,33 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import space.kscience.kmath.linear.Point +import space.kscience.kmath.geometry.GeometrySpace +import space.kscience.kmath.geometry.Vector3D +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Norm import space.kscience.kmath.operations.ScaleOperations -import space.kscience.kmath.structures.Buffer import kotlin.math.pow import kotlin.math.sqrt -public interface Vector3D<T> : Point<T>, Vector { - public val x: T - public val y: T - public val z: T - override val size: Int get() = 3 +internal fun leviCivita(i: Int, j: Int, k: Int): Int = when { + // even permutation + i == 0 && j == 1 && k == 2 -> 1 + i == 1 && j == 2 && k == 0 -> 1 + i == 2 && j == 0 && k == 1 -> 1 + // odd permutations + i == 2 && j == 1 && k == 0 -> -1 + i == 0 && j == 2 && k == 1 -> -1 + i == 1 && j == 0 && k == 2 -> -1 - override operator fun get(index: Int): T = when (index) { - 0 -> x - 1 -> y - 2 -> z - else -> error("Accessing outside of point bounds") - } - - override operator fun iterator(): Iterator<T> = listOf(x, y, z).iterator() -} - -public operator fun <T> Vector3D<T>.component1(): T = x -public operator fun <T> Vector3D<T>.component2(): T = y -public operator fun <T> Vector3D<T>.component3(): T = z - -public fun <T> Buffer<T>.asVector3D(): Vector3D<T> = object : Vector3D<T> { - init { - require(this@asVector3D.size == 3) { "Buffer of size 3 is required for Vector3D" } - } - - override val x: T get() = this@asVector3D[0] - override val y: T get() = this@asVector3D[1] - override val z: T get() = this@asVector3D[2] - - override fun toString(): String = this@asVector3D.toString() + else -> 0 } public typealias DoubleVector3D = Vector3D<Double> public typealias Float64Vector3D = Vector3D<Double> -public val DoubleVector3D.r: Double get() = Euclidean3DSpace.norm(this) +public val DoubleVector3D.r: Double get() = Float64Space3D.norm(this) -public object Euclidean3DSpace : GeometrySpace<DoubleVector3D>, ScaleOperations<DoubleVector3D>, +public object Float64Space3D : GeometrySpace<DoubleVector3D>, ScaleOperations<DoubleVector3D>, Norm<DoubleVector3D, Double> { @Serializable @@ -103,21 +85,8 @@ public object Euclidean3DSpace : GeometrySpace<DoubleVector3D>, ScaleOperations< override fun DoubleVector3D.dot(other: DoubleVector3D): Double = x * other.x + y * other.y + z * other.z - private fun leviCivita(i: Int, j: Int, k: Int): Int = when { - // even permutation - i == 0 && j == 1 && k == 2 -> 1 - i == 1 && j == 2 && k == 0 -> 1 - i == 2 && j == 0 && k == 1 -> 1 - // odd permutations - i == 2 && j == 1 && k == 0 -> -1 - i == 0 && j == 2 && k == 1 -> -1 - i == 1 && j == 0 && k == 2 -> -1 - - else -> 0 - } - /** - * Compute vector product of [first] and [second]. The basis assumed to be right-handed. + * Compute vector product of [first] and [second]. The basis is assumed to be right-handed. */ public fun vectorProduct( first: DoubleVector3D, @@ -139,7 +108,7 @@ public object Euclidean3DSpace : GeometrySpace<DoubleVector3D>, ScaleOperations< } /** - * Vector product with right basis + * Vector product with the right basis */ public infix fun DoubleVector3D.cross(other: DoubleVector3D): Vector3D<Double> = vectorProduct(this, other) @@ -147,3 +116,5 @@ public object Euclidean3DSpace : GeometrySpace<DoubleVector3D>, ScaleOperations< public val yAxis: DoubleVector3D = vector(0.0, 1.0, 0.0) public val zAxis: DoubleVector3D = vector(0.0, 0.0, 1.0) } + +public val Float64Field.euclidean3D: Float64Space3D get() = Float64Space3D diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/rotations3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt similarity index 89% rename from kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/rotations3D.kt rename to kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt index 688386e3b..deb8b0a93 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/rotations3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt @@ -1,15 +1,16 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2023 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.geometry +package space.kscience.kmath.geometry.euclidean3d import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.complex.Quaternion -import space.kscience.kmath.complex.QuaternionField +import space.kscience.kmath.complex.QuaternionAlgebra import space.kscience.kmath.complex.normalized import space.kscience.kmath.complex.reciprocal +import space.kscience.kmath.geometry.* import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.Matrix import space.kscience.kmath.linear.linearSpace @@ -31,7 +32,7 @@ public val Quaternion.theta: Radians get() = (kotlin.math.acos(normalized().w) * public fun Quaternion.Companion.fromRotation(theta: Angle, vector: DoubleVector3D): Quaternion { val s = sin(theta / 2) val c = cos(theta / 2) - val norm = with(Euclidean3DSpace) { vector.norm() } + val norm = with(Float64Space3D) { vector.norm() } return Quaternion(c, vector.x * s / norm, vector.y * s / norm, vector.z * s / norm) } @@ -50,9 +51,9 @@ public val Quaternion.vector: DoubleVector3D } /** - * Rotate a vector in a [Euclidean3DSpace] + * Rotate a vector in a [Float64Space3D] */ -public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, q: Quaternion): DoubleVector3D = with(QuaternionField) { +public fun Float64Space3D.rotate(vector: DoubleVector3D, q: Quaternion): DoubleVector3D = with(QuaternionAlgebra) { val p = vector.toQuaternion() (q * p * q.reciprocal).vector } @@ -61,10 +62,10 @@ public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, q: Quaternion): Doubl * Use a composition of quaternions to create a rotation */ @UnstableKMathAPI -public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, composition: QuaternionField.() -> Quaternion): DoubleVector3D = - rotate(vector, QuaternionField.composition()) +public fun Float64Space3D.rotate(vector: DoubleVector3D, composition: QuaternionAlgebra.() -> Quaternion): DoubleVector3D = + rotate(vector, QuaternionAlgebra.composition()) -public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, matrix: Matrix<Double>): DoubleVector3D { +public fun Float64Space3D.rotate(vector: DoubleVector3D, matrix: Matrix<Double>): DoubleVector3D { require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" } return with(Float64Field.linearSpace) { matrix.dot(vector).asVector3D() } } @@ -76,7 +77,7 @@ public fun Euclidean3DSpace.rotate(vector: DoubleVector3D, matrix: Matrix<Double public fun Quaternion.toRotationMatrix( linearSpace: LinearSpace<Double, *> = Float64Field.linearSpace, ): Matrix<Double> { - val s = QuaternionField.norm(this).pow(-2) + val s = QuaternionAlgebra.norm(this).pow(-2) return linearSpace.matrix(3, 3)( 1.0 - 2 * s * (y * y + z * z), 2 * s * (x * y - z * w), 2 * s * (x * z + y * w), 2 * s * (x * y + z * w), 1.0 - 2 * s * (x * x + z * z), 2 * s * (y * z - x * w), diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt index ea46ab90f..2ed02182d 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt @@ -6,6 +6,10 @@ package space.kscience.kmath.geometry import space.kscience.kmath.geometry.GeometrySpace.Companion.DEFAULT_PRECISION +import space.kscience.kmath.geometry.euclidean2d.Float64Space2D +import space.kscience.kmath.geometry.euclidean2d.Float64Vector2D +import space.kscience.kmath.geometry.euclidean3d.Float64Space3D +import space.kscience.kmath.geometry.euclidean3d.Float64Vector3D /** * Float equality within given [precision] @@ -36,7 +40,7 @@ public fun <V : Vector> V.equalsVector( public fun Float64Vector2D.equalsVector( other: Float64Vector2D, precision: Double = DEFAULT_PRECISION, -): Boolean = equalsVector(Euclidean2DSpace, other, precision) +): Boolean = equalsVector(Float64Space2D, other, precision) /** * Vector equality using Euclidian L2 norm and given [precision] @@ -44,7 +48,7 @@ public fun Float64Vector2D.equalsVector( public fun Float64Vector3D.equalsVector( other: Float64Vector3D, precision: Double = DEFAULT_PRECISION, -): Boolean = equalsVector(Euclidean3DSpace, other, precision) +): Boolean = equalsVector(Float64Space3D, other, precision) /** * Line equality using [GeometrySpace.norm] provided by the [space] and given [precision] diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt new file mode 100644 index 000000000..49ceda04c --- /dev/null +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt @@ -0,0 +1,55 @@ +/* + * Copyright 2018-2023 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.geometry + +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.complex.QuaternionAlgebra +import space.kscience.kmath.complex.conjugate +import space.kscience.kmath.complex.normalized +import space.kscience.kmath.geometry.euclidean3d.Float32Space3D +import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D +import space.kscience.kmath.geometry.euclidean3d.theta +import kotlin.math.asin +import kotlin.math.atan2 +import kotlin.math.pow + +public operator fun Quaternion.times(other: Quaternion): Quaternion = QuaternionAlgebra.multiply(this, other) + +public operator fun Quaternion.div(other: Quaternion): Quaternion = QuaternionAlgebra.divide(this, other) + +public fun Quaternion.power(number: Number): Quaternion = QuaternionAlgebra.power(this, number) + +/** + * Linear interpolation between [from] and [to] in spherical space + */ +public fun QuaternionAlgebra.slerp(from: Quaternion, to: Quaternion, fraction: Double): Quaternion = + (to / from).pow(fraction) * from + +public fun QuaternionAlgebra.angleBetween(q1: Quaternion, q2: Quaternion): Angle = (q1.conjugate * q2).theta + +public val Quaternion.inclination: Radians get() = asin(2 * (w * y - x * z)).radians + +public val Quaternion.azimuth: Angle get() = atan2(2 * (w * z + x * y), 1 - 2 * (y.pow(2) + z.pow(2))).radians.normalized() + +public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * other.x + y * other.y + z * other.z + + +private fun Quaternion.normalizedToEuler(): Float32Vector3D { + val roll = atan2(2 * y * w + 2 * x * z, 1 - 2 * y * y - 2 * z * z); + val pitch = atan2(2 * x * w - 2 * y * z, 1 - 2 * x * x - 2 * z * z); + val yaw = asin(2 * x * y + 2 * z * w); + + return Float32Vector3D(roll, pitch, yaw) +} + +/** + * Quaternion to XYZ Cardan angles + */ +public fun Quaternion.toEuler(): Float32Vector3D = if (QuaternionAlgebra.norm(this) == 0.0) { + Float32Space3D.zero +} else { + normalized().normalizedToEuler() +} \ No newline at end of file diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt index 22cbee6f0..7c5ee3485 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.geometry +import space.kscience.kmath.geometry.euclidean2d.Float64Space2D import kotlin.math.sqrt import kotlin.test.Test import kotlin.test.assertEquals @@ -12,12 +13,12 @@ import kotlin.test.assertEquals internal class Euclidean2DSpaceTest { @Test fun zero() { - assertVectorEquals(Euclidean2DSpace.vector(0.0, 0.0), Euclidean2DSpace.zero) + assertVectorEquals(Float64Space2D.vector(0.0, 0.0), Float64Space2D.zero) } @Test fun norm() { - with(Euclidean2DSpace) { + with(Float64Space2D) { assertEquals(0.0, norm(zero)) assertEquals(1.0, norm(vector(1.0, 0.0))) assertEquals(sqrt(2.0), norm(vector(1.0, 1.0))) @@ -27,7 +28,7 @@ internal class Euclidean2DSpaceTest { @Test fun dotProduct() { - with(Euclidean2DSpace) { + with(Float64Space2D) { assertEquals(0.0, zero dot zero) assertEquals(0.0, zero dot vector(1.0, 0.0)) assertEquals(0.0, vector(-2.0, 0.001) dot zero) @@ -44,7 +45,7 @@ internal class Euclidean2DSpaceTest { @Test fun add() { - with(Euclidean2DSpace) { + with(Float64Space2D) { assertVectorEquals( vector(-2.0, 0.001), vector(-2.0, 0.001) + zero @@ -58,7 +59,7 @@ internal class Euclidean2DSpaceTest { @Test fun multiply() { - with(Euclidean2DSpace) { + with(Float64Space2D) { assertVectorEquals(vector(-4.0, 0.0), vector(-2.0, 0.0) * 2) assertVectorEquals(vector(4.0, 0.0), vector(-2.0, 0.0) * -2) assertVectorEquals(vector(300.0, 0.0003), vector(100.0, 0.0001) * 3) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt index 20e112ad1..f881deb1b 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt @@ -5,18 +5,19 @@ package space.kscience.kmath.geometry +import space.kscience.kmath.geometry.euclidean3d.Float64Space3D import kotlin.test.Test import kotlin.test.assertEquals internal class Euclidean3DSpaceTest { @Test fun zero() { - assertVectorEquals(Euclidean3DSpace.vector(0.0, 0.0, 0.0), Euclidean3DSpace.zero) + assertVectorEquals(Float64Space3D.vector(0.0, 0.0, 0.0), Float64Space3D.zero) } @Test fun distance() { - with(Euclidean3DSpace) { + with(Float64Space3D) { assertEquals(0.0, zero.distanceTo(zero)) assertEquals(1.0, zero.distanceTo(vector(1.0, 0.0, 0.0))) assertEquals(kotlin.math.sqrt(5.000001), vector(1.0, -2.0, 0.001).distanceTo(zero)) @@ -31,7 +32,7 @@ internal class Euclidean3DSpaceTest { @Test fun norm() { - with(Euclidean3DSpace) { + with(Float64Space3D) { assertEquals(0.0, zero.norm()) assertEquals(1.0, vector(1.0, 0.0, 0.0).norm()) assertEquals(kotlin.math.sqrt(3.0), vector(1.0, 1.0, 1.0).norm()) @@ -41,7 +42,7 @@ internal class Euclidean3DSpaceTest { @Test fun dotProduct() { - with(Euclidean3DSpace) { + with(Float64Space3D) { assertEquals(0.0, zero dot zero) assertEquals(0.0, zero dot vector(1.0, 0.0, 0.0)) assertEquals(0.0, vector(1.0, -2.0, 0.001) dot zero) @@ -57,7 +58,7 @@ internal class Euclidean3DSpaceTest { } @Test - fun add() = with(Euclidean3DSpace) { + fun add() = with(Float64Space3D) { assertVectorEquals( vector(1.0, -2.0, 0.001), vector(1.0, -2.0, 0.001) + zero @@ -69,19 +70,19 @@ internal class Euclidean3DSpaceTest { } @Test - fun multiply() = with(Euclidean3DSpace) { + fun multiply() = with(Float64Space3D) { assertVectorEquals(vector(2.0, -4.0, 0.0), vector(1.0, -2.0, 0.0) * 2) } @Test - fun vectorProduct() = with(Euclidean3DSpace) { + fun vectorProduct() = with(Float64Space3D) { assertVectorEquals(zAxis, vectorProduct(xAxis, yAxis)) assertVectorEquals(zAxis, xAxis cross yAxis) assertVectorEquals(-zAxis, vectorProduct(yAxis, xAxis)) } @Test - fun doubleVectorProduct() = with(Euclidean3DSpace) { + fun doubleVectorProduct() = with(Float64Space3D) { val a = vector(1, 2, -3) val b = vector(-1, 0, 1) val c = vector(4, 5, 6) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt index cc74b06e3..9b3f40c4c 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt @@ -5,13 +5,15 @@ package space.kscience.kmath.geometry +import space.kscience.kmath.geometry.euclidean2d.Float64Space2D +import space.kscience.kmath.geometry.euclidean3d.Float64Space3D import kotlin.test.Test import kotlin.test.assertTrue internal class ProjectionAlongTest { @Test fun projectionIntoYEqualsX() { - with(Euclidean2DSpace) { + with(Float64Space2D) { val normal = vector(-2.0, 2.0) val base = vector(2.3, 2.3) @@ -26,7 +28,7 @@ internal class ProjectionAlongTest { @Test fun projectionOntoLine() { - with(Euclidean2DSpace) { + with(Float64Space2D) { val a = 5.0 val b = -3.0 val c = -15.0 @@ -42,11 +44,11 @@ internal class ProjectionAlongTest { } @Test - fun projectOntoPlane() = with(Euclidean3DSpace){ + fun projectOntoPlane() = with(Float64Space3D){ val normal = vector(1.0, 3.5, 0.07) val base = vector(2.0, -0.0037, 11.1111) - with(Euclidean3DSpace) { + with(Float64Space3D) { val testDomain = (-10.0..10.0).generateList(0.43) for (x in testDomain) { for (y in testDomain) { diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt index 7c6c105cf..d3a9d1171 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt @@ -5,13 +5,15 @@ package space.kscience.kmath.geometry +import space.kscience.kmath.geometry.euclidean2d.Float64Space2D +import space.kscience.kmath.geometry.euclidean3d.Float64Space3D import kotlin.test.Test import kotlin.test.assertTrue internal class ProjectionOntoLineTest { @Test fun projectionIntoOx() { - with(Euclidean2DSpace) { + with(Float64Space2D) { val ox = Line(zero, vector(1.0, 0.0)) grid(-10.0..10.0, -10.0..10.0, 0.15).forEach { (x, y) -> @@ -22,7 +24,7 @@ internal class ProjectionOntoLineTest { @Test fun projectionIntoOy() { - with(Euclidean2DSpace) { + with(Float64Space2D) { val line = Line(zero, vector(0.0, 1.0)) grid(-10.0..10.0, -10.0..10.0, 0.15).forEach { (x, y) -> @@ -33,7 +35,7 @@ internal class ProjectionOntoLineTest { @Test fun projectionIntoYEqualsX() { - with(Euclidean2DSpace) { + with(Float64Space2D) { val line = Line(zero, vector(1.0, 1.0)) assertVectorEquals(zero, projectToLine(zero, line)) @@ -47,7 +49,7 @@ internal class ProjectionOntoLineTest { @Test fun projectionOntoLine2d() { - with(Euclidean2DSpace) { + with(Float64Space2D) { val a = 5.0 val b = -3.0 val c = -15.0 @@ -62,7 +64,7 @@ internal class ProjectionOntoLineTest { } @Test - fun projectionOntoLine3d() = with(Euclidean3DSpace) { + fun projectionOntoLine3d() = with(Float64Space3D) { val line = Line( base = vector(1.0, 3.5, 0.07), direction = vector(2.0, -0.0037, 11.1111) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt index 33a9bcc01..1d354bf72 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.geometry import space.kscience.kmath.complex.Quaternion import space.kscience.kmath.complex.normalized +import space.kscience.kmath.geometry.euclidean3d.* import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.testutils.assertBufferEquals import kotlin.test.Test @@ -14,7 +15,7 @@ import kotlin.test.Test class RotationTest { @Test - fun differentRotations() = with(Euclidean3DSpace) { + fun differentRotations() = with(Float64Space3D) { val vector = vector(1.0, 1.0, 1.0) val q = Quaternion(1.0, 2.0, -3.0, 4.0).normalized() val rotatedByQ = rotate(vector, q) @@ -36,7 +37,7 @@ class RotationTest { @Test fun fromRotation() { - val q = Quaternion.fromRotation(0.3.radians, Euclidean3DSpace.vector(1.0, 1.0, 1.0)) + val q = Quaternion.fromRotation(0.3.radians, Float64Space3D.vector(1.0, 1.0, 1.0)) assertBufferEquals(Float64Buffer(0.9887711, 0.0862781, 0.0862781, 0.0862781), q) } diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt index 0db06f4c8..af27b5e00 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt @@ -6,12 +6,13 @@ package space.kscience.kmath.geometry +import space.kscience.kmath.geometry.euclidean2d.Float64Space2D import space.kscience.kmath.operations.toList import kotlin.test.Test import kotlin.test.assertEquals internal class Vector2DTest { - private val vector = Euclidean2DSpace.vector(1.0, -7.999) + private val vector = Float64Space2D.vector(1.0, -7.999) @Test fun size() { diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt index 1c8607838..b10e650a6 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt @@ -5,12 +5,13 @@ package space.kscience.kmath.geometry +import space.kscience.kmath.geometry.euclidean3d.Float64Space3D import space.kscience.kmath.operations.toList import kotlin.test.Test import kotlin.test.assertEquals internal class Vector3DTest { - private val vector = Euclidean3DSpace.vector(1.0, -7.999, 0.001) + private val vector = Float64Space3D.vector(1.0, -7.999, 0.001) @Test fun size() { diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt index c62af3cd3..521ce9e75 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.geometry +import space.kscience.kmath.geometry.euclidean2d.DoubleVector2D +import space.kscience.kmath.geometry.euclidean3d.DoubleVector3D import kotlin.math.abs import kotlin.test.assertEquals diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt index df8a01208..027318f99 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt @@ -16,6 +16,7 @@ import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.nd.ColumnStrides import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.StructureND +import space.kscience.kmath.operations.FieldOps import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.PowerOperations @@ -32,7 +33,8 @@ internal fun ShapeND.toLongArray(): LongArray = LongArray(size) { get(it).toLong public class DoubleTensorFlowAlgebra internal constructor( graph: Graph, -) : TensorFlowAlgebra<Double, TFloat64, Float64Field>(graph), PowerOperations<StructureND<Double>> { +) : TensorFlowAlgebra<Double, TFloat64, + Float64Field>(graph), FieldOps<StructureND<Double>>, PowerOperations<StructureND<Double>> { override val elementAlgebra: Float64Field get() = Float64Field From eff70eb69099ae3fedea5086cd9a1cda5f3c61c2 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 13 Aug 2023 14:51:50 +0300 Subject: [PATCH 047/103] Refactor rotations. Add Rotation matrix to Euler conversion --- .../space/kscience/kmath/geometry/Vector2D.kt | 2 +- .../space/kscience/kmath/geometry/Vector3D.kt | 2 +- .../kmath/geometry/euclidean2d/Circle2D.kt | 4 +- .../geometry/euclidean2d/Float32Space2D.kt | 16 +- .../geometry/euclidean2d/Float64Space2D.kt | 11 +- .../geometry/euclidean3d/Float32Space3D.kt | 16 +- .../geometry/euclidean3d/Float64Space3D.kt | 8 +- .../kmath/geometry/euclidean3d/rotations3D.kt | 193 ++++++++++++++++-- .../kmath/geometry/quaternionOperations.kt | 55 ----- .../kmath/geometry/vectorPrecision.kt | 9 +- .../kscience/kmath/geometry/RotationTest.kt | 23 ++- 11 files changed, 228 insertions(+), 111 deletions(-) delete mode 100644 kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt index 9eced7ba9..58069981e 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.geometry import space.kscience.kmath.linear.Point -public interface Vector2D<T> : Point<T>, Vector { +public interface Vector2D<T> : Point<T> { public val x: T public val y: T override val size: Int get() = 2 diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt index 7e7c6c4ed..c7fb70fc6 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.geometry import space.kscience.kmath.linear.Point import space.kscience.kmath.structures.Buffer -public interface Vector3D<T> : Point<T>, Vector { +public interface Vector3D<T> : Point<T> { public val x: T public val y: T public val z: T diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt index 077735b28..1c1305c8b 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt @@ -6,8 +6,6 @@ package space.kscience.kmath.geometry.euclidean2d import kotlinx.serialization.Serializable -import space.kscience.kmath.geometry.Euclidean2DSpace.distanceTo -import kotlin.math.* import kotlin.math.PI /** @@ -16,7 +14,7 @@ import kotlin.math.PI @Serializable public data class Circle2D( @Serializable(Float64Space2D.VectorSerializer::class) public val center: DoubleVector2D, - public val radius: Double + public val radius: Double, ) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt index 89c3dc204..0cba56bb5 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt @@ -14,17 +14,15 @@ import kotlinx.serialization.encoding.Encoder import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector2D import space.kscience.kmath.operations.Float32Field -import space.kscience.kmath.operations.ScaleOperations +import space.kscience.kmath.structures.Float32 import kotlin.math.pow import kotlin.math.sqrt @Serializable(Float32Space2D.VectorSerializer::class) -public interface Float32Vector2D: Vector2D<Float> +public interface Float32Vector2D : Vector2D<Float> -public object Float32Space2D : - GeometrySpace<Float32Vector2D>, - ScaleOperations<Float32Vector2D> { +public object Float32Space2D : GeometrySpace<Float32Vector2D, Float32> { @Serializable @SerialName("Float32Vector2D") @@ -53,13 +51,13 @@ public object Float32Space2D : override val zero: Float32Vector2D by lazy { vector(0f, 0f) } - override fun norm(arg: Float32Vector2D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2)).toDouble() + override fun norm(arg: Float32Vector2D): Float32 = sqrt(arg.x.pow(2) + arg.y.pow(2)) - public fun Float32Vector2D.norm(): Double = norm(this) + public fun Float32Vector2D.norm(): Float32 = norm(this) override fun Float32Vector2D.unaryMinus(): Float32Vector2D = vector(-x, -y) - override fun Float32Vector2D.distanceTo(other: Float32Vector2D): Double = (this - other).norm() + override fun Float32Vector2D.distanceTo(other: Float32Vector2D): Float32 = (this - other).norm() override fun add(left: Float32Vector2D, right: Float32Vector2D): Float32Vector2D = vector(left.x + right.x, left.y + right.y) @@ -72,6 +70,8 @@ public object Float32Space2D : public val xAxis: Float32Vector2D = vector(1.0, 0.0) public val yAxis: Float32Vector2D = vector(0.0, 1.0) + + override val defaultPrecision: Float32 = 1e-3f } public fun Float32Vector2D(x: Number, y: Number): Float32Vector2D = Float32Space2D.vector(x, y) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt index 320924fbf..ae7cefd8f 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt @@ -13,14 +13,12 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector2D +import space.kscience.kmath.linear.Float64LinearSpace import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.operations.Norm -import space.kscience.kmath.operations.ScaleOperations import kotlin.math.pow import kotlin.math.sqrt - public typealias DoubleVector2D = Vector2D<Double> public typealias Float64Vector2D = Vector2D<Double> @@ -30,10 +28,9 @@ public val Vector2D<Double>.r: Double get() = Float64Space2D.norm(this) /** * 2D Euclidean space */ -public object Float64Space2D : - GeometrySpace<DoubleVector2D, Double>, - ScaleOperations<DoubleVector2D>, - Norm<DoubleVector2D, Double> { +public object Float64Space2D : GeometrySpace<DoubleVector2D, Double> { + + public val linearSpace: Float64LinearSpace = Float64LinearSpace @Serializable @SerialName("Float64Vector2D") diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt index 1413a885b..ce6bbd8fd 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt @@ -14,17 +14,15 @@ import kotlinx.serialization.encoding.Encoder import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector3D import space.kscience.kmath.operations.Float32Field -import space.kscience.kmath.operations.ScaleOperations +import space.kscience.kmath.structures.Float32 import kotlin.math.pow import kotlin.math.sqrt @Serializable(Float32Space3D.VectorSerializer::class) -public interface Float32Vector3D: Vector3D<Float> +public interface Float32Vector3D : Vector3D<Float> -public object Float32Space3D : - GeometrySpace<Float32Vector3D>, - ScaleOperations<Float32Vector3D>{ +public object Float32Space3D : GeometrySpace<Float32Vector3D, Float32> { @Serializable @SerialName("Float32Vector3D") @@ -54,13 +52,13 @@ public object Float32Space3D : override val zero: Float32Vector3D by lazy { vector(0.0, 0.0, 0.0) } - override fun norm(arg: Float32Vector3D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)).toDouble() + override fun norm(arg: Float32Vector3D): Float32 = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)) - public fun Float32Vector3D.norm(): Double = norm(this) + public fun Float32Vector3D.norm(): Float32 = norm(this) override fun Float32Vector3D.unaryMinus(): Float32Vector3D = vector(-x, -y, -z) - override fun Float32Vector3D.distanceTo(other: Float32Vector3D): Double = (this - other).norm() + override fun Float32Vector3D.distanceTo(other: Float32Vector3D): Float32 = (this - other).norm() override fun add(left: Float32Vector3D, right: Float32Vector3D): Float32Vector3D = vector(left.x + right.x, left.y + right.y, left.z + right.z) @@ -101,6 +99,8 @@ public object Float32Space3D : public val xAxis: Float32Vector3D = vector(1.0, 0.0, 0.0) public val yAxis: Float32Vector3D = vector(0.0, 1.0, 0.0) public val zAxis: Float32Vector3D = vector(0.0, 0.0, 1.0) + + override val defaultPrecision: Float32 = 1e-3f } public fun Float32Vector3D(x: Number, y: Number, z: Number): Float32Vector3D = Float32Space3D.vector(x, y, z) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt index b51796012..e808f6129 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt @@ -13,9 +13,8 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector3D +import space.kscience.kmath.linear.Float64LinearSpace import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.operations.Norm -import space.kscience.kmath.operations.ScaleOperations import kotlin.math.pow import kotlin.math.sqrt @@ -37,8 +36,9 @@ public typealias Float64Vector3D = Vector3D<Double> public val DoubleVector3D.r: Double get() = Float64Space3D.norm(this) -public object Float64Space3D : GeometrySpace<DoubleVector3D, Double>, ScaleOperations<DoubleVector3D>, - Norm<DoubleVector3D, Double> { +public object Float64Space3D : GeometrySpace<DoubleVector3D, Double>{ + + public val linearSpace: Float64LinearSpace = Float64LinearSpace @Serializable @SerialName("Float64Vector3D") diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt index deb8b0a93..bf34e2ed2 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt @@ -6,20 +6,36 @@ package space.kscience.kmath.geometry.euclidean3d import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.complex.Quaternion -import space.kscience.kmath.complex.QuaternionAlgebra -import space.kscience.kmath.complex.normalized -import space.kscience.kmath.complex.reciprocal +import space.kscience.kmath.complex.* import space.kscience.kmath.geometry.* import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.linear.Matrix import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.matrix import space.kscience.kmath.operations.Float64Field -import kotlin.math.pow -import kotlin.math.sqrt +import kotlin.math.* -internal fun DoubleVector3D.toQuaternion(): Quaternion = Quaternion(0.0, x, y, z) +public operator fun Quaternion.times(other: Quaternion): Quaternion = QuaternionAlgebra.multiply(this, other) + +public operator fun Quaternion.div(other: Quaternion): Quaternion = QuaternionAlgebra.divide(this, other) + +public fun Quaternion.power(number: Number): Quaternion = QuaternionAlgebra.power(this, number) + +/** + * Linear interpolation between [from] and [to] in spherical space + */ +public fun QuaternionAlgebra.slerp(from: Quaternion, to: Quaternion, fraction: Double): Quaternion = + (to / from).pow(fraction) * from + +public fun QuaternionAlgebra.angleBetween(q1: Quaternion, q2: Quaternion): Angle = (q1.conjugate * q2).theta + +public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * other.x + y * other.y + z * other.z + + +/** + * Represent a vector as quaternion with zero a rotation angle. + */ +internal fun DoubleVector3D.asQuaternion(): Quaternion = Quaternion(0.0, x, y, z) /** * Angle in radians denoted by this quaternion rotation @@ -51,23 +67,30 @@ public val Quaternion.vector: DoubleVector3D } /** - * Rotate a vector in a [Float64Space3D] + * Rotate a vector in a [Float64Space3D] with [quaternion] */ -public fun Float64Space3D.rotate(vector: DoubleVector3D, q: Quaternion): DoubleVector3D = with(QuaternionAlgebra) { - val p = vector.toQuaternion() - (q * p * q.reciprocal).vector -} +public fun Float64Space3D.rotate(vector: DoubleVector3D, quaternion: Quaternion): DoubleVector3D = + with(QuaternionAlgebra) { + val p = vector.asQuaternion() + (quaternion * p * quaternion.reciprocal).vector + } /** * Use a composition of quaternions to create a rotation */ @UnstableKMathAPI -public fun Float64Space3D.rotate(vector: DoubleVector3D, composition: QuaternionAlgebra.() -> Quaternion): DoubleVector3D = +public fun Float64Space3D.rotate( + vector: DoubleVector3D, + composition: QuaternionAlgebra.() -> Quaternion, +): DoubleVector3D = rotate(vector, QuaternionAlgebra.composition()) +/** + * Rotate a [Float64] vector in 3D space with a rotation matrix + */ public fun Float64Space3D.rotate(vector: DoubleVector3D, matrix: Matrix<Double>): DoubleVector3D { require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" } - return with(Float64Field.linearSpace) { matrix.dot(vector).asVector3D() } + return with(linearSpace) { (matrix dot vector).asVector3D() } } /** @@ -86,6 +109,8 @@ public fun Quaternion.toRotationMatrix( } /** + * Convert a quaternion to a rotation matrix + * * taken from https://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ */ public fun Quaternion.Companion.fromRotationMatrix(matrix: Matrix<Double>): Quaternion { @@ -146,6 +171,8 @@ public enum class RotationOrder { } /** + * Create a quaternion from Euler angles + * * Based on https://github.com/mrdoob/three.js/blob/master/src/math/Quaternion.js */ public fun Quaternion.Companion.fromEuler( @@ -154,13 +181,13 @@ public fun Quaternion.Companion.fromEuler( c: Angle, rotationOrder: RotationOrder, ): Quaternion { - val c1 = cos (a / 2) - val c2 = cos (b / 2) - val c3 = cos (c / 2) + val c1 = cos(a / 2) + val c2 = cos(b / 2) + val c3 = cos(c / 2) - val s1 = sin (a / 2) - val s2 = sin (b / 2) - val s3 = sin (c / 2) + val s1 = sin(a / 2) + val s2 = sin(b / 2) + val s3 = sin(c / 2) return when (rotationOrder) { @@ -206,6 +233,130 @@ public fun Quaternion.Companion.fromEuler( c1 * s2 * c3 - s1 * c2 * s3, c1 * c2 * s3 + s1 * s2 * c3 ) - else -> TODO("Proper Euler rotation orders are not supported yet") + + else -> TODO("Proper Euler rotation orders are not supported yet") } +} + +/** + * A vector consisting of angles + */ +public data class AngleVector(override val x: Angle, override val y: Angle, override val z: Angle) : Vector3D<Angle> { + public companion object +} + +public fun Quaternion.Companion.fromEuler( + angles: AngleVector, + rotationOrder: RotationOrder, +): Quaternion = fromEuler(angles.x, angles.y, angles.z, rotationOrder) + +/** + * Based on https://github.com/mrdoob/three.js/blob/master/src/math/Euler.js + */ +public fun AngleVector.Companion.fromRotationMatrix( + matrix: Matrix<Double>, + rotationOrder: RotationOrder, + gimbaldLockThreshold: Double = 0.9999999, +): AngleVector = when (rotationOrder) { + + RotationOrder.XYZ -> { + if (abs(matrix[0, 2]) < gimbaldLockThreshold) { + AngleVector( + atan2(-matrix[1, 2], matrix[2, 2]).radians, + asin(matrix[0, 2].coerceIn(-1.0, 1.0)).radians, + atan2(-matrix[0, 1], matrix[0, 0]).radians + ) + + } else { + AngleVector( + atan2(matrix[2, 1], matrix[1, 1]).radians, + asin(matrix[0, 2].coerceIn(-1.0, 1.0)).radians, + Angle.zero + ) + } + } + + RotationOrder.YXZ -> { + if (abs(matrix[1, 2]) < gimbaldLockThreshold) { + AngleVector( + x = asin(-matrix[1, 2].coerceIn(-1.0, 1.0)).radians, + y = atan2(matrix[0, 2], matrix[2, 2]).radians, + z = atan2(matrix[1, 0], matrix[1, 1]).radians, + ) + } else { + AngleVector( + x = asin(-matrix[1, 2].coerceIn(-1.0, 1.0)).radians, + y = atan2(-matrix[2, 0], matrix[0, 0]).radians, + z = Angle.zero, + ) + + } + } + + RotationOrder.ZXY -> { + if (abs(matrix[2, 1]) < gimbaldLockThreshold) { + AngleVector( + x = asin(matrix[2, 1].coerceIn(-1.0, 1.0)).radians, + y = atan2(-matrix[2, 0], matrix[2, 2]).radians, + z = atan2(-matrix[0, 1], matrix[1, 1]).radians, + ) + + } else { + AngleVector( + x = asin(matrix[2, 1].coerceIn(-1.0, 1.0)).radians, + y = Angle.zero, + z = atan2(matrix[1, 0], matrix[0, 0]).radians, + ) + } + } + + RotationOrder.ZYX -> { + if (abs(matrix[2, 0]) < gimbaldLockThreshold) { + AngleVector( + x = atan2(matrix[2, 1], matrix[2, 2]).radians, + y = asin(-matrix[2, 0].coerceIn(-1.0, 1.0)).radians, + z = atan2(matrix[1, 0], matrix[0, 0]).radians, + ) + } else { + AngleVector( + x = Angle.zero, + y = asin(-matrix[2, 0].coerceIn(-1.0, 1.0)).radians, + z = atan2(-matrix[0, 1], matrix[1, 1]).radians, + ) + } + } + + RotationOrder.YZX -> { + if (abs(matrix[1, 0]) < gimbaldLockThreshold) { + AngleVector( + x = atan2(-matrix[1, 2], matrix[1, 1]).radians, + y = atan2(-matrix[2, 0], matrix[0, 0]).radians, + z = asin(matrix[1, 0].coerceIn(-1.0, 1.0)).radians, + ) + } else { + AngleVector( + x = Angle.zero, + y = atan2(matrix[0, 2], matrix[2, 2]).radians, + z = asin(matrix[1, 0].coerceIn(-1.0, 1.0)).radians, + ) + } + } + + RotationOrder.XZY -> { + if (abs(matrix[0, 1]) < gimbaldLockThreshold) { + AngleVector( + x = atan2(matrix[2, 1], matrix[1, 1]).radians, + y = atan2(matrix[0, 2], matrix[0, 0]).radians, + z = asin(-matrix[0, 1].coerceIn(-1.0, 1.0)).radians, + ) + } else { + AngleVector( + x = atan2(-matrix[1, 2], matrix[2, 2]).radians, + y = Angle.zero, + z = asin(-matrix[0, 1].coerceIn(-1.0, 1.0)).radians, + ) + } + } + + else -> TODO("Proper Euler rotation orders are not supported yet") } \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt deleted file mode 100644 index 49ceda04c..000000000 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018-2023 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.geometry - -import space.kscience.kmath.complex.Quaternion -import space.kscience.kmath.complex.QuaternionAlgebra -import space.kscience.kmath.complex.conjugate -import space.kscience.kmath.complex.normalized -import space.kscience.kmath.geometry.euclidean3d.Float32Space3D -import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D -import space.kscience.kmath.geometry.euclidean3d.theta -import kotlin.math.asin -import kotlin.math.atan2 -import kotlin.math.pow - -public operator fun Quaternion.times(other: Quaternion): Quaternion = QuaternionAlgebra.multiply(this, other) - -public operator fun Quaternion.div(other: Quaternion): Quaternion = QuaternionAlgebra.divide(this, other) - -public fun Quaternion.power(number: Number): Quaternion = QuaternionAlgebra.power(this, number) - -/** - * Linear interpolation between [from] and [to] in spherical space - */ -public fun QuaternionAlgebra.slerp(from: Quaternion, to: Quaternion, fraction: Double): Quaternion = - (to / from).pow(fraction) * from - -public fun QuaternionAlgebra.angleBetween(q1: Quaternion, q2: Quaternion): Angle = (q1.conjugate * q2).theta - -public val Quaternion.inclination: Radians get() = asin(2 * (w * y - x * z)).radians - -public val Quaternion.azimuth: Angle get() = atan2(2 * (w * z + x * y), 1 - 2 * (y.pow(2) + z.pow(2))).radians.normalized() - -public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * other.x + y * other.y + z * other.z - - -private fun Quaternion.normalizedToEuler(): Float32Vector3D { - val roll = atan2(2 * y * w + 2 * x * z, 1 - 2 * y * y - 2 * z * z); - val pitch = atan2(2 * x * w - 2 * y * z, 1 - 2 * x * x - 2 * z * z); - val yaw = asin(2 * x * y + 2 * z * w); - - return Float32Vector3D(roll, pitch, yaw) -} - -/** - * Quaternion to XYZ Cardan angles - */ -public fun Quaternion.toEuler(): Float32Vector3D = if (QuaternionAlgebra.norm(this) == 0.0) { - Float32Space3D.zero -} else { - normalized().normalizedToEuler() -} \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt index 7d3fc7867..dd82a2926 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt @@ -5,6 +5,11 @@ package space.kscience.kmath.geometry +import space.kscience.kmath.geometry.euclidean2d.Float64Space2D +import space.kscience.kmath.geometry.euclidean2d.Float64Vector2D +import space.kscience.kmath.geometry.euclidean3d.Float64Space3D +import space.kscience.kmath.geometry.euclidean3d.Float64Vector3D + /** * Vector equality within given [precision] (using [GeometrySpace.norm] provided by the space @@ -22,7 +27,7 @@ public fun <V : Any, D : Comparable<D>> V.equalsVector( */ public fun Float64Vector2D.equalsVector( other: Float64Vector2D, - precision: Double = Euclidean3DSpace.defaultPrecision, + precision: Double = Float64Space2D.defaultPrecision, ): Boolean = equalsVector(Float64Space2D, other, precision) /** @@ -30,7 +35,7 @@ public fun Float64Vector2D.equalsVector( */ public fun Float64Vector3D.equalsVector( other: Float64Vector3D, - precision: Double = Euclidean3DSpace.defaultPrecision, + precision: Double = Float64Space3D.defaultPrecision, ): Boolean = equalsVector(Float64Space3D, other, precision) /** diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt index 1d354bf72..7d1687ecb 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.geometry import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.complex.QuaternionAlgebra import space.kscience.kmath.complex.normalized import space.kscience.kmath.geometry.euclidean3d.* import space.kscience.kmath.structures.Float64Buffer @@ -26,12 +27,31 @@ class RotationTest { } @Test - fun matrixConversion() { + fun matrixConversion() = with(QuaternionAlgebra){ val q = Quaternion(1.0, 2.0, -3.0, 4.0).normalized() val matrix = q.toRotationMatrix() + for (ro in listOf( + RotationOrder.XYZ, + RotationOrder.YXZ, + RotationOrder.ZXY, + RotationOrder.ZYX, + RotationOrder.YZX, + RotationOrder.XZY + )) { + val angles = AngleVector.fromRotationMatrix(matrix, ro) + + val reconstructed = Quaternion.fromEuler(angles, ro) + + if( reconstructed.w>0) { + assertBufferEquals(q, reconstructed) + } else{ + assertBufferEquals(q, -reconstructed) + } + } + assertBufferEquals(q, Quaternion.fromRotationMatrix(matrix)) } @@ -50,4 +70,5 @@ class RotationTest { val q1 = Quaternion.fromEuler(0.1.radians, 0.2.radians, 0.3.radians, RotationOrder.XYZ) assertBufferEquals(Float64Buffer(0.9818562, 0.0640713, 0.0911575, 0.1534393), q1) } + } \ No newline at end of file From 5196322b7a42ff9a629e4208fb0c0adac678ed4f Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 13 Aug 2023 19:13:39 +0300 Subject: [PATCH 048/103] Update integration to use Attributes --- .../space/kscience/attributes/Attributes.kt | 8 ++ .../kscience/attributes/AttributesBuilder.kt | 7 +- .../kmath/commons/integration/CMIntegrator.kt | 19 ++--- .../kscience/kmath/commons/linear/CMMatrix.kt | 2 +- .../kscience/kmath/linear/LupDecomposition.kt | 9 +-- ...{MatrixFeatures.kt => matrixAttributes.kt} | 6 +- .../space/kscience/kmath/nd/StructureND.kt | 1 - .../kmath/functions/polynomialConstructors.kt | 7 +- .../kmath/integration/GaussIntegrator.kt | 34 +++++---- .../integration/GaussIntegratorRuleFactory.kt | 4 +- .../kscience/kmath/integration/Integrand.kt | 63 ++++++++-------- .../integration/MultivariateIntegrand.kt | 22 +++--- .../kmath/integration/SimpsonIntegrator.kt | 32 +++++--- .../kmath/integration/SplineIntegrator.kt | 22 ++++-- .../kmath/integration/UnivariateIntegrand.kt | 73 +++++++------------ .../kmath/integration/SimpsonIntegralTest.kt | 10 ++- .../kscience/kmath/geometry/testUtils.kt | 2 +- .../optimization/FunctionOptimization.kt | 2 +- .../core/LevenbergMarquardtAlgorithm.kt | 10 +-- 19 files changed, 173 insertions(+), 160 deletions(-) rename kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/{MatrixFeatures.kt => matrixAttributes.kt} (95%) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index f93b6446a..705e61436 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -59,6 +59,14 @@ public fun <T : Any, A : Attribute<T>> Attributes.withAttribute( public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attributes = withAttribute(attribute, Unit) +/** + * Create a new [Attributes] by modifying the current one + */ +public fun Attributes.modify(block: AttributesBuilder.() -> Unit): Attributes = Attributes { + from(this@modify) + block() +} + /** * Create new [Attributes] by removing [attribute] key */ diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index 588c789f5..d0aed08c9 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -8,7 +8,9 @@ package space.kscience.attributes /** * A safe builder for [Attributes] */ -public class AttributesBuilder internal constructor(private val map: MutableMap<Attribute<*>, Any> = mutableMapOf()) { +public class AttributesBuilder internal constructor(private val map: MutableMap<Attribute<*>, Any>) { + + public constructor() : this(mutableMapOf()) @Suppress("UNCHECKED_CAST") public operator fun <T> get(attribute: Attribute<T>): T? = map[attribute] as? T @@ -49,4 +51,5 @@ public fun AttributesBuilder( attributes: Attributes, ): AttributesBuilder = AttributesBuilder(attributes.content.toMutableMap()) -public fun Attributes(builder: AttributesBuilder.() -> Unit): Attributes = AttributesBuilder().apply(builder).build() \ No newline at end of file +public inline fun Attributes(builder: AttributesBuilder.() -> Unit): Attributes = + AttributesBuilder().apply(builder).build() \ No newline at end of file diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt index c3e581d31..82a371100 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt @@ -20,10 +20,9 @@ public class CMIntegrator( override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { val integrator = integratorBuilder(integrand) - val maxCalls = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: defaultMaxCalls + val maxCalls = integrand[IntegrandMaxCalls] ?: defaultMaxCalls val remainingCalls = maxCalls - integrand.calls - val range = integrand.getFeature<IntegrationRange>()?.range - ?: error("Integration range is not provided") + val range = integrand[IntegrationRange] ?: error("Integration range is not provided") val res = integrator.integrate(remainingCalls, integrand.function, range.start, range.endInclusive) return integrand + @@ -39,11 +38,9 @@ public class CMIntegrator( * Create a Simpson integrator based on [SimpsonIntegrator] */ public fun simpson(defaultMaxCalls: Int = 200): CMIntegrator = CMIntegrator(defaultMaxCalls) { integrand -> - val absoluteAccuracy = integrand.getFeature<IntegrandAbsoluteAccuracy>()?.accuracy - ?: SimpsonIntegrator.DEFAULT_ABSOLUTE_ACCURACY - val relativeAccuracy = integrand.getFeature<IntegrandRelativeAccuracy>()?.accuracy - ?: SimpsonIntegrator.DEFAULT_ABSOLUTE_ACCURACY - val iterations = integrand.getFeature<IntegrandIterationsRange>()?.range + val absoluteAccuracy = integrand[IntegrandAbsoluteAccuracy] ?: SimpsonIntegrator.DEFAULT_ABSOLUTE_ACCURACY + val relativeAccuracy = integrand[IntegrandRelativeAccuracy] ?: SimpsonIntegrator.DEFAULT_ABSOLUTE_ACCURACY + val iterations = integrand[IntegrandIterationsRange] ?: SimpsonIntegrator.DEFAULT_MIN_ITERATIONS_COUNT..SimpsonIntegrator.SIMPSON_MAX_ITERATIONS_COUNT @@ -55,11 +52,11 @@ public class CMIntegrator( */ public fun legandre(numPoints: Int, defaultMaxCalls: Int = numPoints * 5): CMIntegrator = CMIntegrator(defaultMaxCalls) { integrand -> - val absoluteAccuracy = integrand.getFeature<IntegrandAbsoluteAccuracy>()?.accuracy + val absoluteAccuracy = integrand[IntegrandAbsoluteAccuracy] ?: IterativeLegendreGaussIntegrator.DEFAULT_ABSOLUTE_ACCURACY - val relativeAccuracy = integrand.getFeature<IntegrandRelativeAccuracy>()?.accuracy + val relativeAccuracy = integrand[IntegrandRelativeAccuracy] ?: IterativeLegendreGaussIntegrator.DEFAULT_ABSOLUTE_ACCURACY - val iterations = integrand.getFeature<IntegrandIterationsRange>()?.range + val iterations = integrand[IntegrandIterationsRange] ?: IterativeLegendreGaussIntegrator.DEFAULT_MIN_ITERATIONS_COUNT..IterativeLegendreGaussIntegrator.DEFAULT_MAX_ITERATIONS_COUNT IterativeLegendreGaussIntegrator( diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index ebf4dc65a..d29650e3f 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -135,7 +135,7 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> { override val r: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(qr.r).withAttribute(UpperTriangular) } } - SingularValueDecompositionAttribute::class -> object : SingularValueDecompositionAttribute<Double> { + SVDAttribute::class -> object : SVDAttribute<Double> { private val sv by lazy { SingularValueDecomposition(origin) } override val u: Matrix<Double> by lazy { CMMatrix(sv.u) } override val s: Matrix<Double> by lazy { CMMatrix(sv.s) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 6ccafa5f1..9fe8397d8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -13,10 +13,6 @@ import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* import space.kscience.kmath.structures.* -import space.kscience.kmath.structures.BufferAccessor2D -import space.kscience.kmath.structures.Float64Buffer -import space.kscience.kmath.structures.MutableBuffer -import space.kscience.kmath.structures.MutableBufferFactory /** * Matrices with this feature support LU factorization with partial pivoting: *[p] · a = [l] · [u]* where @@ -197,8 +193,7 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( public fun LinearSpace<Double, Float64Field>.lup( matrix: Matrix<Double>, singularityThreshold: Double = 1e-11, -): LupDecomposition<Double> = - lup(::Float64Buffer, matrix) { it < singularityThreshold } +): LupDecomposition<Double> = lup(matrix) { it < singularityThreshold } internal fun <T : Any, A : Field<T>> LinearSpace<T, A>.solve( lup: LupDecomposition<T>, @@ -265,4 +260,4 @@ public fun <T : Comparable<T>, F : Field<T>> LinearSpace<T, F>.lupSolver( } public fun LinearSpace<Double, Float64Field>.lupSolver(singularityThreshold: Double = 1e-11): LinearSolver<Double> = - lupSolver(::Float64Buffer) { it < singularityThreshold } + lupSolver { it < singularityThreshold } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt similarity index 95% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt index d109ef1bc..5bb35edef 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt @@ -163,12 +163,12 @@ public interface SingularValueDecomposition<T> { * * @param T the type of matrices' items. */ -public class SingularValueDecompositionAttribute<T>(type: SafeType<SingularValueDecomposition<T>>) : +public class SVDAttribute<T>(type: SafeType<SingularValueDecomposition<T>>) : PolymorphicAttribute<SingularValueDecomposition<T>>(type), MatrixAttribute<SingularValueDecomposition<T>> -public val <T> MatrixOperations<T>.SVD: SingularValueDecompositionAttribute<T> - get() = SingularValueDecompositionAttribute(safeTypeOf()) +public val <T> MatrixOperations<T>.SVD: SVDAttribute<T> + get() = SVDAttribute(safeTypeOf()) //TODO add sparse matrix feature diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index 993349487..bc86f62ae 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -240,7 +240,6 @@ public interface MutableStructureND<T> : StructureND<T> { * Set value at specified indices */ @PerformancePitfall -@Deprecated("") public operator fun <T> MutableStructureND<T>.set(vararg index: Int, value: T) { set(index, value) } \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt index 4e9791a87..e07ff764c 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt @@ -20,9 +20,4 @@ public fun <C> Polynomial(coefficients: List<C>, reverse: Boolean = false): Poly */ @Suppress("FunctionName") public fun <C> Polynomial(vararg coefficients: C, reverse: Boolean = false): Polynomial<C> = - Polynomial(with(coefficients) { if (reverse) reversed() else toList() }) - -/** - * Represents [this] constant as a [Polynomial]. - */ -public fun <C> C.asPolynomial() : Polynomial<C> = Polynomial(listOf(this)) \ No newline at end of file + Polynomial(with(coefficients) { if (reverse) reversed() else toList() }) \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index f2ac0a296..f0aab2c6c 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -4,6 +4,7 @@ */ package space.kscience.kmath.integration +import space.kscience.attributes.AttributesBuilder import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Field import space.kscience.kmath.structures.Buffer @@ -11,14 +12,14 @@ import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.structures.indices /** - * A simple one-pass integrator based on Gauss rule - * Following integrand features are accepted: + * A simple one-pass integrator based on Gauss rule. + * The following integrand features are accepted: * * * [GaussIntegratorRuleFactory]—a factory for computing the Gauss integration rule. By default, uses * [GaussLegendreRuleFactory]. * * [IntegrationRange]—the univariate range of integration. By default, uses `0..1` interval. * * [IntegrandMaxCalls]—the maximum number of function calls during integration. For non-iterative rules, always - * uses the maximum number of points. By default, uses 10 points. + * use the maximum number of points. By default, uses 10 points. * * [UnivariateIntegrandRanges]—set of ranges and number of points per range. Defaults to given * [IntegrationRange] and [IntegrandMaxCalls]. */ @@ -27,11 +28,11 @@ public class GaussIntegrator<T : Any>( ) : UnivariateIntegrator<T> { private fun buildRule(integrand: UnivariateIntegrand<T>): Pair<Buffer<Double>, Buffer<Double>> { - val factory = integrand.getFeature<GaussIntegratorRuleFactory>() ?: GaussLegendreRuleFactory - val predefinedRanges = integrand.getFeature<UnivariateIntegrandRanges>() + val factory = integrand[GaussIntegratorRuleFactory] ?: GaussLegendreRuleFactory + val predefinedRanges = integrand[UnivariateIntegrandRanges] if (predefinedRanges == null || predefinedRanges.ranges.isEmpty()) { - val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 - val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0 + val numPoints = integrand[IntegrandMaxCalls] ?: 100 + val range = integrand[IntegrationRange] ?: 0.0..1.0 return factory.build(numPoints, range) } else { val ranges = predefinedRanges.ranges @@ -66,7 +67,10 @@ public class GaussIntegrator<T : Any>( c = t - res - y res = t } - return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + points.size) + return integrand.modify { + value(res) + IntegrandCallsPerformed(integrand.calls + points.size) + } } public companion object @@ -88,7 +92,7 @@ public fun <T : Any> GaussIntegrator<T>.integrate( range: ClosedRange<Double>, order: Int = 10, intervals: Int = 10, - vararg features: IntegrandFeature, + attributesBuilder: AttributesBuilder.() -> Unit, function: (Double) -> T, ): UnivariateIntegrand<T> { require(range.endInclusive > range.start) { "The range upper bound should be higher than lower bound" } @@ -100,11 +104,13 @@ public fun <T : Any> GaussIntegrator<T>.integrate( ) return process( UnivariateIntegrand( - function, - IntegrationRange(range), - GaussLegendreRuleFactory, - ranges, - *features + attributeBuilder = { + IntegrationRange(range) + GaussIntegratorRuleFactory(GaussLegendreRuleFactory) + UnivariateIntegrandRanges(ranges) + attributesBuilder() + }, + function = function, ) ) } \ No newline at end of file diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt index 975fcd3a8..91b3811c0 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt @@ -12,10 +12,10 @@ import space.kscience.kmath.structures.asBuffer import kotlin.math.ulp import kotlin.native.concurrent.ThreadLocal -public interface GaussIntegratorRuleFactory : IntegrandFeature { +public interface GaussIntegratorRuleFactory { public fun build(numPoints: Int): Pair<Buffer<Double>, Buffer<Double>> - public companion object { + public companion object: IntegrandAttribute<GaussIntegratorRuleFactory>{ public fun double(numPoints: Int, range: ClosedRange<Double>): Pair<Buffer<Double>, Buffer<Double>> = GaussLegendreRuleFactory.build(numPoints, range) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt index 40fe78898..09c32aeff 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt @@ -5,44 +5,49 @@ package space.kscience.kmath.integration -import space.kscience.kmath.misc.Feature -import space.kscience.kmath.misc.FeatureSet -import space.kscience.kmath.misc.Featured -import kotlin.reflect.KClass +import space.kscience.attributes.* +import kotlin.reflect.typeOf -public interface IntegrandFeature : Feature<IntegrandFeature> { - override fun toString(): String +public interface IntegrandAttribute<T> : Attribute<T> + +public interface Integrand<T> : AttributeContainer { + + public fun modify(block: AttributesBuilder.() -> Unit): Integrand<T> + + public fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): Integrand<T> + + public companion object } -public interface Integrand : Featured<IntegrandFeature> { - public val features: FeatureSet<IntegrandFeature> - override fun <T : IntegrandFeature> getFeature(type: KClass<out T>): T? = features.getFeature(type) +public operator fun <T> Integrand<*>.get(attribute: Attribute<T>): T? = attributes[attribute] + +public class IntegrandValue<T>(type: SafeType<T>) : PolymorphicAttribute<T>(type), IntegrandAttribute<T> + +public inline val <reified T : Any> Integrand<T>.Value: IntegrandValue<T> get() = IntegrandValue(safeTypeOf()) + +public fun <T> AttributesBuilder.value(value: T){ + val type: SafeType<T> = typeOf<T>() + IntegrandValue(type).invoke(value) } -public inline fun <reified T : IntegrandFeature> Integrand.getFeature(): T? = getFeature(T::class) +/** + * Value of the integrand if it is present or null + */ +public inline val <reified T : Any> Integrand<T>.valueOrNull: T? get() = attributes[Value] -public class IntegrandValue<out T : Any>(public val value: T) : IntegrandFeature { - override fun toString(): String = "Value($value)" -} +/** + * Value of the integrand or error + */ +public inline val <reified T : Any> Integrand<T>.value: T get() = valueOrNull ?: error("No value in the integrand") -public class IntegrandRelativeAccuracy(public val accuracy: Double) : IntegrandFeature { - override fun toString(): String = "TargetRelativeAccuracy($accuracy)" -} +public object IntegrandRelativeAccuracy : IntegrandAttribute<Double> -public class IntegrandAbsoluteAccuracy(public val accuracy: Double) : IntegrandFeature { - override fun toString(): String = "TargetAbsoluteAccuracy($accuracy)" -} +public object IntegrandAbsoluteAccuracy : IntegrandAttribute<Double> -public class IntegrandCallsPerformed(public val calls: Int) : IntegrandFeature { - override fun toString(): String = "Calls($calls)" -} +public object IntegrandCallsPerformed : IntegrandAttribute<Int> -public val Integrand.calls: Int get() = getFeature<IntegrandCallsPerformed>()?.calls ?: 0 +public val Integrand<*>.calls: Int get() = attributes[IntegrandCallsPerformed] ?: 0 -public class IntegrandMaxCalls(public val maxCalls: Int) : IntegrandFeature { - override fun toString(): String = "MaxCalls($maxCalls)" -} +public object IntegrandMaxCalls : IntegrandAttribute<Int> -public class IntegrandIterationsRange(public val range: IntRange) : IntegrandFeature { - override fun toString(): String = "Iterations(${range.first}..${range.last})" -} +public object IntegrandIterationsRange : IntegrandAttribute<IntRange> diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt index 53a563086..a3b2ed44f 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -5,22 +5,22 @@ package space.kscience.kmath.integration +import space.kscience.attributes.* import space.kscience.kmath.linear.Point -import space.kscience.kmath.misc.FeatureSet -public class MultivariateIntegrand<T : Any> internal constructor( - override val features: FeatureSet<IntegrandFeature>, +public class MultivariateIntegrand<T> internal constructor( + override val attributes: Attributes, public val function: (Point<T>) -> T, -) : Integrand { +) : Integrand<T> { - public operator fun <F : IntegrandFeature> plus(feature: F): MultivariateIntegrand<T> = - MultivariateIntegrand(features.with(feature), function) + override fun modify(block: AttributesBuilder.() -> Unit): MultivariateIntegrand<T> = + MultivariateIntegrand(attributes.modify(block), function) + + override fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): MultivariateIntegrand<T> = + MultivariateIntegrand(attributes.withAttribute(attribute, value), function) } -@Suppress("FunctionName") public fun <T : Any> MultivariateIntegrand( - vararg features: IntegrandFeature, + attributeBuilder: AttributesBuilder.() -> Unit, function: (Point<T>) -> T, -): MultivariateIntegrand<T> = MultivariateIntegrand(FeatureSet.of(*features), function) - -public val <T : Any> MultivariateIntegrand<T>.value: T? get() = getFeature<IntegrandValue<T>>()?.value +): MultivariateIntegrand<T> = MultivariateIntegrand(Attributes(attributeBuilder), function) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt index 35ce82351..16d71a743 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt @@ -45,16 +45,22 @@ public class SimpsonIntegrator<T : Any>( } override fun process(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> { - val ranges = integrand.getFeature<UnivariateIntegrandRanges>() + val ranges = integrand[UnivariateIntegrandRanges] return if (ranges != null) { val res = algebra.sum(ranges.ranges.map { integrateRange(integrand, it.first, it.second) }) - integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second }) + integrand.modify { + value(res) + IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second }) + } } else { - val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 + val numPoints = integrand[IntegrandMaxCalls] ?: 100 require(numPoints >= 4) { "Simpson integrator requires at least 4 nodes" } - val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0 + val range = integrand[IntegrationRange] ?: 0.0..1.0 val res = integrateRange(integrand, range, numPoints) - integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + numPoints) + integrand.modify { + value(res) + IntegrandCallsPerformed(integrand.calls + numPoints) + } } } } @@ -91,16 +97,22 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> { } override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { - val ranges = integrand.getFeature<UnivariateIntegrandRanges>() + val ranges = integrand[UnivariateIntegrandRanges] return if (ranges != null) { val res = ranges.ranges.sumOf { integrateRange(integrand, it.first, it.second) } - integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second }) + integrand.modify { + value(res) + IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second }) + } } else { - val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 + val numPoints = integrand[IntegrandMaxCalls] ?: 100 require(numPoints >= 4) { "Simpson integrator requires at least 4 nodes" } - val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0 + val range = integrand[IntegrationRange] ?: 0.0..1.0 val res = integrateRange(integrand, range, numPoints) - integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + numPoints) + integrand.modify { + value(res) + IntegrandCallsPerformed(integrand.calls + numPoints) + } } } } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt index 1306e501f..bbec9ff45 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt @@ -55,12 +55,12 @@ public class SplineIntegrator<T : Comparable<T>>( public val bufferFactory: MutableBufferFactory<T>, ) : UnivariateIntegrator<T> { override fun process(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> = algebra { - val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0 + val range = integrand[IntegrationRange] ?: 0.0..1.0 val interpolator: PolynomialInterpolator<T> = SplineInterpolator(algebra, bufferFactory) - val nodes: Buffer<Double> = integrand.getFeature<UnivariateIntegrationNodes>()?.nodes ?: run { - val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 + val nodes: Buffer<Double> = integrand[UnivariateIntegrationNodes] ?: run { + val numPoints = integrand[IntegrandMaxCalls] ?: 100 val step = (range.endInclusive - range.start) / (numPoints - 1) Float64Buffer(numPoints) { i -> range.start + i * step } } @@ -71,7 +71,10 @@ public class SplineIntegrator<T : Comparable<T>>( values ) val res = polynomials.integrate(algebra, number(range.start)..number(range.endInclusive)) - integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + nodes.size) + integrand.modify { + value(res) + IntegrandCallsPerformed(integrand.calls + nodes.size) + } } } @@ -84,11 +87,11 @@ public class SplineIntegrator<T : Comparable<T>>( @UnstableKMathAPI public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { - val range = integrand.getFeature<IntegrationRange>()?.range ?: 0.0..1.0 + val range = integrand[IntegrationRange] ?: 0.0..1.0 val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, ::Float64Buffer) - val nodes: Buffer<Double> = integrand.getFeature<UnivariateIntegrationNodes>()?.nodes ?: run { - val numPoints = integrand.getFeature<IntegrandMaxCalls>()?.maxCalls ?: 100 + val nodes: Buffer<Double> = integrand[UnivariateIntegrationNodes] ?: run { + val numPoints = integrand[IntegrandMaxCalls] ?: 100 val step = (range.endInclusive - range.start) / (numPoints - 1) Float64Buffer(numPoints) { i -> range.start + i * step } } @@ -96,7 +99,10 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { val values = nodes.mapToBuffer(::Float64Buffer) { integrand.function(it) } val polynomials = interpolator.interpolatePolynomials(nodes, values) val res = polynomials.integrate(Float64Field, range) - return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + nodes.size) + return integrand.modify { + value(res) + IntegrandCallsPerformed(integrand.calls + nodes.size) + } } } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index e29a6c881..3c30f303e 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -5,36 +5,38 @@ package space.kscience.kmath.integration +import space.kscience.attributes.* import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.misc.FeatureSet import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Float64Buffer public class UnivariateIntegrand<T> internal constructor( - override val features: FeatureSet<IntegrandFeature>, + override val attributes: Attributes, public val function: (Double) -> T, -) : Integrand { - public operator fun <F : IntegrandFeature> plus(feature: F): UnivariateIntegrand<T> = - UnivariateIntegrand(features.with(feature), function) +) : Integrand<T> { + + override fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): UnivariateIntegrand<T> = + UnivariateIntegrand(attributes.withAttribute(attribute, value), function) + + override fun modify(block: AttributesBuilder.() -> Unit): UnivariateIntegrand<T> = + UnivariateIntegrand(attributes.modify(block), function) } -@Suppress("FunctionName") public fun <T : Any> UnivariateIntegrand( + attributeBuilder: AttributesBuilder.() -> Unit, function: (Double) -> T, - vararg features: IntegrandFeature, -): UnivariateIntegrand<T> = UnivariateIntegrand(FeatureSet.of(*features), function) +): UnivariateIntegrand<T> = UnivariateIntegrand(Attributes(attributeBuilder), function) public typealias UnivariateIntegrator<T> = Integrator<UnivariateIntegrand<T>> -public class IntegrationRange(public val range: ClosedRange<Double>) : IntegrandFeature { - override fun toString(): String = "Range(${range.start}..${range.endInclusive})" -} +public object IntegrationRange : IntegrandAttribute<ClosedRange<Double>> + /** * Set of univariate integration ranges. First components correspond to the ranges themselves, second components to - * number of integration nodes per range. + * the number of integration nodes per range. */ -public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange<Double>, Int>>) : IntegrandFeature { +public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange<Double>, Int>>) { public constructor(vararg pairs: Pair<ClosedRange<Double>, Int>) : this(pairs.toList()) override fun toString(): String { @@ -43,45 +45,25 @@ public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange< } return "UnivariateRanges($rangesString)" } + + public companion object : IntegrandAttribute<UnivariateIntegrandRanges> } -public class UnivariateIntegrationNodes(public val nodes: Buffer<Double>) : IntegrandFeature { - public constructor(vararg nodes: Double) : this(Float64Buffer(nodes)) +public object UnivariateIntegrationNodes : IntegrandAttribute<Buffer<Double>> - override fun toString(): String = "UnivariateNodes($nodes)" +public fun AttributesBuilder.integrationNodes(vararg nodes: Double) { + UnivariateIntegrationNodes(Float64Buffer(nodes)) } - -/** - * Value of the integrand if it is present or null - */ -public val <T : Any> UnivariateIntegrand<T>.valueOrNull: T? get() = getFeature<IntegrandValue<T>>()?.value - -/** - * Value of the integrand or error - */ -public val <T : Any> UnivariateIntegrand<T>.value: T get() = valueOrNull ?: error("No value in the integrand") - /** * A shortcut method to integrate a [function] with additional [features]. Range must be provided in features. * The [function] is placed in the end position to allow passing a lambda. */ @UnstableKMathAPI public fun <T : Any> UnivariateIntegrator<T>.integrate( - vararg features: IntegrandFeature, + attributesBuilder: AttributesBuilder.() -> Unit, function: (Double) -> T, -): UnivariateIntegrand<T> = process(UnivariateIntegrand(function, *features)) - -/** - * A shortcut method to integrate a [function] in [range] with additional [features]. - * The [function] is placed in the end position to allow passing a lambda. - */ -@UnstableKMathAPI -public fun <T : Any> UnivariateIntegrator<T>.integrate( - range: ClosedRange<Double>, - vararg features: IntegrandFeature, - function: (Double) -> T, -): UnivariateIntegrand<T> = process(UnivariateIntegrand(function, IntegrationRange(range), *features)) +): UnivariateIntegrand<T> = process(UnivariateIntegrand(attributesBuilder, function)) /** * A shortcut method to integrate a [function] in [range] with additional features. @@ -90,13 +72,12 @@ public fun <T : Any> UnivariateIntegrator<T>.integrate( @UnstableKMathAPI public fun <T : Any> UnivariateIntegrator<T>.integrate( range: ClosedRange<Double>, - featureBuilder: MutableList<IntegrandFeature>.() -> Unit = {}, + attributeBuilder: AttributesBuilder.() -> Unit = {}, function: (Double) -> T, ): UnivariateIntegrand<T> { - //TODO use dedicated feature builder class instead or add extensions to MutableList<IntegrandFeature> - val features = buildList { - featureBuilder() - add(IntegrationRange(range)) + val attributes = Attributes { + IntegrationRange(range) + attributeBuilder() } - return process(UnivariateIntegrand(function, *features.toTypedArray())) + return process(UnivariateIntegrand(attributes, function)) } diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt index f5a79cdea..aafabf302 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt @@ -16,7 +16,10 @@ import kotlin.test.assertEquals class SimpsonIntegralTest { @Test fun gaussSin() { - val res = Float64Field.simpsonIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x -> + val res = Float64Field.simpsonIntegrator.integrate( + 0.0..2 * PI, + { IntegrandMaxCalls(5) } + ) { x -> sin(x) } assertEquals(0.0, res.value, 1e-2) @@ -24,7 +27,10 @@ class SimpsonIntegralTest { @Test fun gaussUniform() { - val res = Float64Field.simpsonIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x -> + val res = Float64Field.simpsonIntegrator.integrate( + 35.0..100.0, + { IntegrandMaxCalls(20) } + ) { x -> if (x in 30.0..50.0) { 1.0 } else { diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt index ac72af10c..abc57eb42 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -27,7 +27,7 @@ fun grid( return xs.flatMap { x -> ys.map { y -> x to y } } } -fun assertVectorEquals(expected: DoubleVector2D, actual: DoubleVector2D, absoluteTolerance: Double = 1e-6) { +fun assertVectorEquals(expected: DoubleVector2D, actual: DoubleVector2D, absoluteTolerance: Double = 1e-3) { assertEquals(expected.x, actual.x, absoluteTolerance) assertEquals(expected.y, actual.y, absoluteTolerance) } diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt index fe5f0ca8a..8025428e6 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -53,7 +53,7 @@ public class OptimizationPrior<T>(type: SafeType<T>): PolymorphicAttribute<DifferentiableExpression<T>>(safeTypeOf()), Attribute<DifferentiableExpression<T>> -public val <T> FunctionOptimization.Companion.Optimization get() = +//public val <T> FunctionOptimization.Companion.Optimization get() = public fun <T> FunctionOptimization<T>.withFeatures( diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index fc87ad1f3..8011b332e 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -6,7 +6,7 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall -import space.kscience.kmath.linear.transpose +import space.kscience.kmath.linear.transposed import space.kscience.kmath.nd.* import kotlin.math.abs import kotlin.math.max @@ -139,7 +139,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI if (inputData.nargin < 5) { weight = fromArray( ShapeND(intArrayOf(1, 1)), - doubleArrayOf((inputData.realValues.transpose().dot(inputData.realValues)).as1D()[0]) + doubleArrayOf((inputData.realValues.transposed dot inputData.realValues).as1D()[0]) ).as2D() } @@ -266,12 +266,12 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI settings.funcCalls += 1 // val tmp = deltaY.times(weight) - var X2Try = deltaY.as2D().transpose().dot(deltaY.times(weight)) // Chi-squared error criteria + var X2Try = deltaY.as2D().transposed dot deltaY.times(weight) // Chi-squared error criteria val alpha = 1.0 if (updateType == 2) { // Quadratic // One step of quadratic line update in the h direction for minimum X2 - val alphaTensor = (jtWdy.transpose() dot h) / ((X2Try - x2) / 2.0 + 2 * (jtWdy.transpose() dot h)) + val alphaTensor = (jtWdy.transposed dot h) / ((X2Try - x2) / 2.0 + 2 * (jtWdy.transposed dot h)) h = h dot alphaTensor pTry = (p + h).as2D() // update only [idx] elements pTry = smallestElementComparison( @@ -289,7 +289,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI ) // residual error using p_try settings.funcCalls += 1 - X2Try = deltaY.as2D().transpose() dot deltaY * weight // Chi-squared error criteria + X2Try = deltaY.as2D().transposed dot deltaY * weight // Chi-squared error criteria } val rho = when (updateType) { // Nielsen From 9da14089e03939d940000df5a9628101be5dc01a Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Mon, 14 Aug 2023 10:06:23 +0300 Subject: [PATCH 049/103] Update integration to use Attributes --- .../integration/CMGaussRuleIntegrator.kt | 19 +++++----- .../kmath/commons/integration/CMIntegrator.kt | 14 ++++---- .../kscience/kmath/integration/Integrand.kt | 24 ++++++++----- .../integration/MultivariateIntegrand.kt | 13 +++---- .../kmath/integration/UnivariateIntegrand.kt | 36 +++++++++++-------- 5 files changed, 62 insertions(+), 44 deletions(-) diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt index 263463d37..7befc60a3 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt @@ -13,26 +13,29 @@ import space.kscience.kmath.integration.* */ public class CMGaussRuleIntegrator( private val numpoints: Int, - private var type: GaussRule = GaussRule.LEGANDRE, + private var type: GaussRule = GaussRule.LEGENDRE, ) : UnivariateIntegrator<Double> { override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { - val range = integrand.getFeature<IntegrationRange>()?.range + val range = integrand[IntegrationRange] ?: error("Integration range is not provided") val integrator: GaussIntegrator = getIntegrator(range) //TODO check performance val res: Double = integrator.integrate(integrand.function) - return integrand + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + numpoints) + return integrand.modify { + IntegrandValue(res) + IntegrandCallsPerformed(integrand.calls + numpoints) + } } private fun getIntegrator(range: ClosedRange<Double>): GaussIntegrator { return when (type) { - GaussRule.LEGANDRE -> factory.legendre( + GaussRule.LEGENDRE -> factory.legendre( numpoints, range.start, range.endInclusive ) - GaussRule.LEGANDREHP -> factory.legendreHighPrecision( + GaussRule.LEGENDREHP -> factory.legendreHighPrecision( numpoints, range.start, range.endInclusive @@ -65,7 +68,7 @@ public class CMGaussRuleIntegrator( } public enum class GaussRule { - UNIFORM, LEGANDRE, LEGANDREHP + UNIFORM, LEGENDRE, LEGENDREHP } public companion object { @@ -74,10 +77,10 @@ public class CMGaussRuleIntegrator( public fun integrate( range: ClosedRange<Double>, numPoints: Int = 100, - type: GaussRule = GaussRule.LEGANDRE, + type: GaussRule = GaussRule.LEGENDRE, function: (Double) -> Double, ): Double = CMGaussRuleIntegrator(numPoints, type).process( - UnivariateIntegrand(function, IntegrationRange(range)) + UnivariateIntegrand({IntegrationRange(range)},function) ).value } } \ No newline at end of file diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt index 82a371100..7a807c25f 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt @@ -9,13 +9,14 @@ import org.apache.commons.math3.analysis.integration.IterativeLegendreGaussInteg import org.apache.commons.math3.analysis.integration.SimpsonIntegrator import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.integration.* +import org.apache.commons.math3.analysis.integration.UnivariateIntegrator as CMUnivariateIntegrator /** * Integration wrapper for Common-maths UnivariateIntegrator */ public class CMIntegrator( private val defaultMaxCalls: Int = 200, - public val integratorBuilder: (Integrand) -> org.apache.commons.math3.analysis.integration.UnivariateIntegrator, + public val integratorBuilder: (Integrand<Double>) -> CMUnivariateIntegrator, ) : UnivariateIntegrator<Double> { override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { @@ -25,11 +26,12 @@ public class CMIntegrator( val range = integrand[IntegrationRange] ?: error("Integration range is not provided") val res = integrator.integrate(remainingCalls, integrand.function, range.start, range.endInclusive) - return integrand + - IntegrandValue(res) + - IntegrandAbsoluteAccuracy(integrator.absoluteAccuracy) + - IntegrandRelativeAccuracy(integrator.relativeAccuracy) + - IntegrandCallsPerformed(integrator.evaluations + integrand.calls) + return integrand.modify { + value(res) + IntegrandAbsoluteAccuracy(integrator.absoluteAccuracy) + IntegrandRelativeAccuracy(integrator.relativeAccuracy) + IntegrandCallsPerformed(integrator.evaluations + integrand.calls) + } } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt index 09c32aeff..9e2b8d0d7 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt @@ -5,13 +5,17 @@ package space.kscience.kmath.integration -import space.kscience.attributes.* -import kotlin.reflect.typeOf +import space.kscience.attributes.Attribute +import space.kscience.attributes.AttributeContainer +import space.kscience.attributes.AttributesBuilder +import space.kscience.attributes.SafeType public interface IntegrandAttribute<T> : Attribute<T> public interface Integrand<T> : AttributeContainer { + public val type: SafeType<T> + public fun modify(block: AttributesBuilder.() -> Unit): Integrand<T> public fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): Integrand<T> @@ -21,19 +25,21 @@ public interface Integrand<T> : AttributeContainer { public operator fun <T> Integrand<*>.get(attribute: Attribute<T>): T? = attributes[attribute] -public class IntegrandValue<T>(type: SafeType<T>) : PolymorphicAttribute<T>(type), IntegrandAttribute<T> +public sealed class IntegrandValue<T> private constructor(): IntegrandAttribute<T>{ + public companion object: IntegrandValue<Any?>(){ + @Suppress("UNCHECKED_CAST") + public fun <T> forType(): IntegrandValue<T> = this as IntegrandValue<T> + } +} -public inline val <reified T : Any> Integrand<T>.Value: IntegrandValue<T> get() = IntegrandValue(safeTypeOf()) - -public fun <T> AttributesBuilder.value(value: T){ - val type: SafeType<T> = typeOf<T>() - IntegrandValue(type).invoke(value) +public fun <T> AttributesBuilder.value(value: T) { + IntegrandValue.forType<T>().invoke(value) } /** * Value of the integrand if it is present or null */ -public inline val <reified T : Any> Integrand<T>.valueOrNull: T? get() = attributes[Value] +public inline val <reified T : Any> Integrand<T>.valueOrNull: T? get() = attributes[IntegrandValue.forType<T>()] /** * Value of the integrand or error diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt index a3b2ed44f..f8937efd2 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -8,19 +8,20 @@ package space.kscience.kmath.integration import space.kscience.attributes.* import space.kscience.kmath.linear.Point -public class MultivariateIntegrand<T> internal constructor( +public class MultivariateIntegrand<T>( + override val type: SafeType<T>, override val attributes: Attributes, public val function: (Point<T>) -> T, ) : Integrand<T> { override fun modify(block: AttributesBuilder.() -> Unit): MultivariateIntegrand<T> = - MultivariateIntegrand(attributes.modify(block), function) + MultivariateIntegrand(type, attributes.modify(block), function) override fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): MultivariateIntegrand<T> = - MultivariateIntegrand(attributes.withAttribute(attribute, value), function) + MultivariateIntegrand(type, attributes.withAttribute(attribute, value), function) } -public fun <T : Any> MultivariateIntegrand( +public inline fun <reified T : Any> MultivariateIntegrand( attributeBuilder: AttributesBuilder.() -> Unit, - function: (Point<T>) -> T, -): MultivariateIntegrand<T> = MultivariateIntegrand(Attributes(attributeBuilder), function) + noinline function: (Point<T>) -> T, +): MultivariateIntegrand<T> = MultivariateIntegrand(safeTypeOf<T>(), Attributes(attributeBuilder), function) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index 3c30f303e..a5291152a 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -10,22 +10,23 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Float64Buffer -public class UnivariateIntegrand<T> internal constructor( +public class UnivariateIntegrand<T>( + override val type: SafeType<T>, override val attributes: Attributes, public val function: (Double) -> T, ) : Integrand<T> { override fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): UnivariateIntegrand<T> = - UnivariateIntegrand(attributes.withAttribute(attribute, value), function) + UnivariateIntegrand(type, attributes.withAttribute(attribute, value), function) override fun modify(block: AttributesBuilder.() -> Unit): UnivariateIntegrand<T> = - UnivariateIntegrand(attributes.modify(block), function) + UnivariateIntegrand(type, attributes.modify(block), function) } -public fun <T : Any> UnivariateIntegrand( +public inline fun <reified T : Any> UnivariateIntegrand( attributeBuilder: AttributesBuilder.() -> Unit, - function: (Double) -> T, -): UnivariateIntegrand<T> = UnivariateIntegrand(Attributes(attributeBuilder), function) + noinline function: (Double) -> T, +): UnivariateIntegrand<T> = UnivariateIntegrand(safeTypeOf(), Attributes(attributeBuilder), function) public typealias UnivariateIntegrator<T> = Integrator<UnivariateIntegrand<T>> @@ -60,9 +61,9 @@ public fun AttributesBuilder.integrationNodes(vararg nodes: Double) { * The [function] is placed in the end position to allow passing a lambda. */ @UnstableKMathAPI -public fun <T : Any> UnivariateIntegrator<T>.integrate( +public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( attributesBuilder: AttributesBuilder.() -> Unit, - function: (Double) -> T, + noinline function: (Double) -> T, ): UnivariateIntegrand<T> = process(UnivariateIntegrand(attributesBuilder, function)) /** @@ -70,14 +71,19 @@ public fun <T : Any> UnivariateIntegrator<T>.integrate( * The [function] is placed in the end position to allow passing a lambda. */ @UnstableKMathAPI -public fun <T : Any> UnivariateIntegrator<T>.integrate( +public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( range: ClosedRange<Double>, attributeBuilder: AttributesBuilder.() -> Unit = {}, - function: (Double) -> T, + noinline function: (Double) -> T, ): UnivariateIntegrand<T> { - val attributes = Attributes { - IntegrationRange(range) - attributeBuilder() - } - return process(UnivariateIntegrand(attributes, function)) + + return process( + UnivariateIntegrand( + attributeBuilder = { + IntegrationRange(range) + attributeBuilder() + }, + function = function + ) + ) } From dd3d38490ae5b1758ae4dff7b138cd866b321f30 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 13 Sep 2023 09:00:56 +0300 Subject: [PATCH 050/103] [WIP] refactor features to attributes --- .../kscience/attributes/AttributesBuilder.kt | 6 ++++- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- kmath-ast/build.gradle.kts | 2 +- .../integration/CMGaussRuleIntegrator.kt | 2 +- .../kmath/commons/integration/CMIntegrator.kt | 2 +- .../kmath/integration/GaussIntegrator.kt | 14 +++++------ .../kscience/kmath/integration/Integrand.kt | 14 +++++------ .../integration/MultivariateIntegrand.kt | 17 +++++++++---- .../kmath/integration/SimpsonIntegrator.kt | 8 +++---- .../kmath/integration/SplineIntegrator.kt | 4 ++-- .../kmath/integration/UnivariateIntegrand.kt | 24 ++++++++++++------- kmath-tensors/build.gradle.kts | 2 +- 13 files changed, 57 insertions(+), 42 deletions(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index d0aed08c9..79df91c3e 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -7,8 +7,10 @@ package space.kscience.attributes /** * A safe builder for [Attributes] + * + * @param O type marker of an owner object, for which these attributes are made */ -public class AttributesBuilder internal constructor(private val map: MutableMap<Attribute<*>, Any>) { +public class TypedAttributesBuilder<in O> internal constructor(private val map: MutableMap<Attribute<*>, Any>) { public constructor() : this(mutableMapOf()) @@ -47,6 +49,8 @@ public class AttributesBuilder internal constructor(private val map: MutableMap< public fun build(): Attributes = Attributes(map) } +public typealias AttributesBuilder = TypedAttributesBuilder<Any?> + public fun AttributesBuilder( attributes: Attributes, ): AttributesBuilder = AttributesBuilder(attributes.content.toMutableMap()) diff --git a/gradle.properties b/gradle.properties index 2f1a2a030..bcb32fede 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.native.ignoreDisabledTargets=true -toolsVersion=0.14.9-kotlin-1.8.20 +toolsVersion=0.14.9-kotlin-1.9.0 org.gradle.parallel=true org.gradle.workers.max=4 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 15de90249..db9a6b825 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index 7cdb745f0..fe10716af 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -31,7 +31,7 @@ kscience{ kotlin { js { nodejs { - testTask { + testTask{ useMocha().timeout = "0" } } diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt index 7befc60a3..a3fc49d32 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt @@ -22,7 +22,7 @@ public class CMGaussRuleIntegrator( val integrator: GaussIntegrator = getIntegrator(range) //TODO check performance val res: Double = integrator.integrate(integrand.function) - return integrand.modify { + return integrand.withAttributes { IntegrandValue(res) IntegrandCallsPerformed(integrand.calls + numpoints) } diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt index 7a807c25f..2cc60fb77 100644 --- a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt +++ b/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt @@ -26,7 +26,7 @@ public class CMIntegrator( val range = integrand[IntegrationRange] ?: error("Integration range is not provided") val res = integrator.integrate(remainingCalls, integrand.function, range.start, range.endInclusive) - return integrand.modify { + return integrand.withAttributes { value(res) IntegrandAbsoluteAccuracy(integrator.absoluteAccuracy) IntegrandRelativeAccuracy(integrator.relativeAccuracy) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index f0aab2c6c..4753edcd0 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -4,7 +4,7 @@ */ package space.kscience.kmath.integration -import space.kscience.attributes.AttributesBuilder +import space.kscience.attributes.TypedAttributesBuilder import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Field import space.kscience.kmath.structures.Buffer @@ -57,7 +57,7 @@ public class GaussIntegrator<T : Any>( override fun process(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> = with(algebra) { val f = integrand.function val (points, weights) = buildRule(integrand) - var res = zero + var res: T = zero var c = zero for (i in points.indices) { val x = points[i] @@ -67,7 +67,7 @@ public class GaussIntegrator<T : Any>( c = t - res - y res = t } - return integrand.modify { + return integrand.withAttributes { value(res) IntegrandCallsPerformed(integrand.calls + points.size) } @@ -88,12 +88,12 @@ public val <T : Any> Field<T>.gaussIntegrator: GaussIntegrator<T> get() = GaussI * Integrate using [intervals] segments with Gauss-Legendre rule of [order] order. */ @UnstableKMathAPI -public fun <T : Any> GaussIntegrator<T>.integrate( +public inline fun <reified T : Any> GaussIntegrator<T>.integrate( range: ClosedRange<Double>, order: Int = 10, intervals: Int = 10, - attributesBuilder: AttributesBuilder.() -> Unit, - function: (Double) -> T, + attributesBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, + noinline function: (Double) -> T, ): UnivariateIntegrand<T> { require(range.endInclusive > range.start) { "The range upper bound should be higher than lower bound" } require(order > 1) { "The order of polynomial must be more than 1" } @@ -103,7 +103,7 @@ public fun <T : Any> GaussIntegrator<T>.integrate( (0 until intervals).map { i -> (range.start + rangeSize * i)..(range.start + rangeSize * (i + 1)) to order } ) return process( - UnivariateIntegrand( + UnivariateIntegrand<T>( attributeBuilder = { IntegrationRange(range) GaussIntegratorRuleFactory(GaussLegendreRuleFactory) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt index 9e2b8d0d7..d465e87c7 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt @@ -5,10 +5,7 @@ package space.kscience.kmath.integration -import space.kscience.attributes.Attribute -import space.kscience.attributes.AttributeContainer -import space.kscience.attributes.AttributesBuilder -import space.kscience.attributes.SafeType +import space.kscience.attributes.* public interface IntegrandAttribute<T> : Attribute<T> @@ -16,9 +13,10 @@ public interface Integrand<T> : AttributeContainer { public val type: SafeType<T> - public fun modify(block: AttributesBuilder.() -> Unit): Integrand<T> - - public fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): Integrand<T> + /** + * Create a copy of this integrand with a new set of attributes + */ + public fun withAttributes(attributes: Attributes): Integrand<T> public companion object } @@ -32,7 +30,7 @@ public sealed class IntegrandValue<T> private constructor(): IntegrandAttribute< } } -public fun <T> AttributesBuilder.value(value: T) { +public fun <T> TypedAttributesBuilder<Integrand<T>>.value(value: T) { IntegrandValue.forType<T>().invoke(value) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt index f8937efd2..2081947ec 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -14,14 +14,21 @@ public class MultivariateIntegrand<T>( public val function: (Point<T>) -> T, ) : Integrand<T> { - override fun modify(block: AttributesBuilder.() -> Unit): MultivariateIntegrand<T> = - MultivariateIntegrand(type, attributes.modify(block), function) + override fun withAttributes(attributes: Attributes): MultivariateIntegrand<T> = + MultivariateIntegrand(type, attributes, function) - override fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): MultivariateIntegrand<T> = - MultivariateIntegrand(type, attributes.withAttribute(attribute, value), function) } +public fun <T, A : Any> MultivariateIntegrand<T>.withAttribute( + attribute: Attribute<A>, + value: A, +): MultivariateIntegrand<T> = withAttributes(attributes.withAttribute(attribute, value)) + +public fun <T> MultivariateIntegrand<T>.withAttributes( + block: TypedAttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, +): MultivariateIntegrand<T> = withAttributes(attributes.modify(block)) + public inline fun <reified T : Any> MultivariateIntegrand( - attributeBuilder: AttributesBuilder.() -> Unit, + attributeBuilder: TypedAttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, noinline function: (Point<T>) -> T, ): MultivariateIntegrand<T> = MultivariateIntegrand(safeTypeOf<T>(), Attributes(attributeBuilder), function) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt index 16d71a743..c0e4fb394 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt @@ -48,7 +48,7 @@ public class SimpsonIntegrator<T : Any>( val ranges = integrand[UnivariateIntegrandRanges] return if (ranges != null) { val res = algebra.sum(ranges.ranges.map { integrateRange(integrand, it.first, it.second) }) - integrand.modify { + integrand.withAttributes { value(res) IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second }) } @@ -57,7 +57,7 @@ public class SimpsonIntegrator<T : Any>( require(numPoints >= 4) { "Simpson integrator requires at least 4 nodes" } val range = integrand[IntegrationRange] ?: 0.0..1.0 val res = integrateRange(integrand, range, numPoints) - integrand.modify { + integrand.withAttributes { value(res) IntegrandCallsPerformed(integrand.calls + numPoints) } @@ -100,7 +100,7 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> { val ranges = integrand[UnivariateIntegrandRanges] return if (ranges != null) { val res = ranges.ranges.sumOf { integrateRange(integrand, it.first, it.second) } - integrand.modify { + integrand.withAttributes { value(res) IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second }) } @@ -109,7 +109,7 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> { require(numPoints >= 4) { "Simpson integrator requires at least 4 nodes" } val range = integrand[IntegrationRange] ?: 0.0..1.0 val res = integrateRange(integrand, range, numPoints) - integrand.modify { + integrand.withAttributes { value(res) IntegrandCallsPerformed(integrand.calls + numPoints) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt index bbec9ff45..636ca5a74 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt @@ -71,7 +71,7 @@ public class SplineIntegrator<T : Comparable<T>>( values ) val res = polynomials.integrate(algebra, number(range.start)..number(range.endInclusive)) - integrand.modify { + integrand.withAttributes { value(res) IntegrandCallsPerformed(integrand.calls + nodes.size) } @@ -99,7 +99,7 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { val values = nodes.mapToBuffer(::Float64Buffer) { integrand.function(it) } val polynomials = interpolator.interpolatePolynomials(nodes, values) val res = polynomials.integrate(Float64Field, range) - return integrand.modify { + return integrand.withAttributes { value(res) IntegrandCallsPerformed(integrand.calls + nodes.size) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index a5291152a..6a6d47667 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -16,15 +16,21 @@ public class UnivariateIntegrand<T>( public val function: (Double) -> T, ) : Integrand<T> { - override fun <A : Any> withAttribute(attribute: Attribute<A>, value: A): UnivariateIntegrand<T> = - UnivariateIntegrand(type, attributes.withAttribute(attribute, value), function) - - override fun modify(block: AttributesBuilder.() -> Unit): UnivariateIntegrand<T> = - UnivariateIntegrand(type, attributes.modify(block), function) + override fun withAttributes(attributes: Attributes): UnivariateIntegrand<T> = + UnivariateIntegrand(type, attributes, function) } +public fun <T, A : Any> UnivariateIntegrand<T>.withAttribute( + attribute: Attribute<A>, + value: A, +): UnivariateIntegrand<T> = withAttributes(attributes.withAttribute(attribute, value)) + +public fun <T> UnivariateIntegrand<T>.withAttributes( + block: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, +): UnivariateIntegrand<T> = withAttributes(attributes.modify(block)) + public inline fun <reified T : Any> UnivariateIntegrand( - attributeBuilder: AttributesBuilder.() -> Unit, + attributeBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, noinline function: (Double) -> T, ): UnivariateIntegrand<T> = UnivariateIntegrand(safeTypeOf(), Attributes(attributeBuilder), function) @@ -52,7 +58,7 @@ public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange< public object UnivariateIntegrationNodes : IntegrandAttribute<Buffer<Double>> -public fun AttributesBuilder.integrationNodes(vararg nodes: Double) { +public fun TypedAttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(vararg nodes: Double) { UnivariateIntegrationNodes(Float64Buffer(nodes)) } @@ -62,7 +68,7 @@ public fun AttributesBuilder.integrationNodes(vararg nodes: Double) { */ @UnstableKMathAPI public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( - attributesBuilder: AttributesBuilder.() -> Unit, + attributesBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, noinline function: (Double) -> T, ): UnivariateIntegrand<T> = process(UnivariateIntegrand(attributesBuilder, function)) @@ -73,7 +79,7 @@ public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( @UnstableKMathAPI public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( range: ClosedRange<Double>, - attributeBuilder: AttributesBuilder.() -> Unit = {}, + attributeBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {}, noinline function: (Double) -> T, ): UnivariateIntegrand<T> { diff --git a/kmath-tensors/build.gradle.kts b/kmath-tensors/build.gradle.kts index 2497314f0..8977183da 100644 --- a/kmath-tensors/build.gradle.kts +++ b/kmath-tensors/build.gradle.kts @@ -6,7 +6,7 @@ kscience{ jvm() js { browser { - testTask { + testTask{ useMocha().timeout = "0" } } From 23c0758ba6e523b587df4d2329b39c3acc4253b4 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 13 Sep 2023 13:25:54 +0300 Subject: [PATCH 051/103] Kotlin 1.9.20 --- build.gradle.kts | 12 ++---------- gradle.properties | 4 ++-- gradle/wrapper/gradle-wrapper.properties | 2 +- .../kotlin/space/kscience/kmath/misc/numbers.kt | 0 .../space/kscience/kmath/operations/isInteger.kt | 0 .../kscience/kmath/memory/WasmDataViewMemory.kt | 0 6 files changed, 5 insertions(+), 13 deletions(-) rename kmath-core/src/{wasmMain => wasmJsMain}/kotlin/space/kscience/kmath/misc/numbers.kt (100%) rename kmath-core/src/{wasmMain => wasmJsMain}/kotlin/space/kscience/kmath/operations/isInteger.kt (100%) rename kmath-memory/src/{wasmMain => wasmJsMain}/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt (100%) diff --git a/build.gradle.kts b/build.gradle.kts index 7dbe87445..e4be11db2 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,3 @@ -import space.kscience.gradle.isInDevelopment import space.kscience.gradle.useApache2Licence import space.kscience.gradle.useSPCTeam @@ -64,17 +63,10 @@ ksciencePublish { useApache2Licence() useSPCTeam() } - github("kmath", "SciProgCentre") - space( - if (isInDevelopment) { - "https://maven.pkg.jetbrains.space/spc/p/sci/dev" - } else { - "https://maven.pkg.jetbrains.space/spc/p/sci/maven" - } - ) + repository("spc","https://maven.sciprog.center/kscience") sonatype("https://oss.sonatype.org") } apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI") -val multikVersion by extra("0.2.0") +val multikVersion by extra("0.2.2") diff --git a/gradle.properties b/gradle.properties index 81eb66e34..fc9bb4ee7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx4096m org.gradle.parallel=true org.gradle.workers.max=4 -toolsVersion=0.14.9-kotlin-1.9.0-RC-dev-1 -kotlin.experimental.tryK2=true +toolsVersion=0.15.0-kotlin-1.9.20-Beta +#kotlin.experimental.tryK2=true #kscience.wasm.disabled=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index fae08049a..db9a6b825 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kmath-core/src/wasmMain/kotlin/space/kscience/kmath/misc/numbers.kt b/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/misc/numbers.kt similarity index 100% rename from kmath-core/src/wasmMain/kotlin/space/kscience/kmath/misc/numbers.kt rename to kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/misc/numbers.kt diff --git a/kmath-core/src/wasmMain/kotlin/space/kscience/kmath/operations/isInteger.kt b/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/operations/isInteger.kt similarity index 100% rename from kmath-core/src/wasmMain/kotlin/space/kscience/kmath/operations/isInteger.kt rename to kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/operations/isInteger.kt diff --git a/kmath-memory/src/wasmMain/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt b/kmath-memory/src/wasmJsMain/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt similarity index 100% rename from kmath-memory/src/wasmMain/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt rename to kmath-memory/src/wasmJsMain/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt From 7a4e9e70f99dcb215b349d4842448b36ba0096b1 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 22 Sep 2023 08:21:14 +0300 Subject: [PATCH 052/103] add some quaternion operations --- .../space/kscience/kmath/ejml/_generated.kt | 10 +++++-- .../kmath/geometry/quaternionOperations.kt | 29 +++++++++++-------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index f48ab4c19..984f1619b 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,13 +19,19 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.structures.Float64 +import space.kscience.kmath.structures.Float32 import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.FloatField import space.kscience.kmath.operations.invoke +import space.kscience.kmath.structures.Float64Buffer +import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt index 49ceda04c..b6ad5009e 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt @@ -28,22 +28,27 @@ public fun Quaternion.power(number: Number): Quaternion = QuaternionAlgebra.powe public fun QuaternionAlgebra.slerp(from: Quaternion, to: Quaternion, fraction: Double): Quaternion = (to / from).pow(fraction) * from +/** + * Scalar angle between two quaternions + */ public fun QuaternionAlgebra.angleBetween(q1: Quaternion, q2: Quaternion): Angle = (q1.conjugate * q2).theta -public val Quaternion.inclination: Radians get() = asin(2 * (w * y - x * z)).radians - -public val Quaternion.azimuth: Angle get() = atan2(2 * (w * z + x * y), 1 - 2 * (y.pow(2) + z.pow(2))).radians.normalized() - +/** + * Euclidean product of two quaternions + */ public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * other.x + y * other.y + z * other.z - -private fun Quaternion.normalizedToEuler(): Float32Vector3D { - val roll = atan2(2 * y * w + 2 * x * z, 1 - 2 * y * y - 2 * z * z); - val pitch = atan2(2 * x * w - 2 * y * z, 1 - 2 * x * x - 2 * z * z); - val yaw = asin(2 * x * y + 2 * z * w); - - return Float32Vector3D(roll, pitch, yaw) -} +// +///** +// * Convert a quaternion to XYZ Cardan angles assuming it is normalized. +// */ +//private fun Quaternion.normalizedToEuler(): Float32Vector3D { +// val roll = atan2(2 * y * w + 2 * x * z, 1 - 2 * y * y - 2 * z * z) +// val pitch = atan2(2 * x * w - 2 * y * z, 1 - 2 * x * x - 2 * z * z) +// val yaw = asin(2 * x * y + 2 * z * w) +// +// return Float32Vector3D(roll, pitch, yaw) +//} /** * Quaternion to XYZ Cardan angles From 56933ecff3d259a9ab1396ecae40fcca035571f7 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 22 Sep 2023 09:04:39 +0300 Subject: [PATCH 053/103] 1.9.20-Beta2 --- build.gradle.kts | 10 +-------- gradle.properties | 2 +- .../space/kscience/kmath/ejml/_generated.kt | 10 ++------- .../kmath/geometry/quaternionOperations.kt | 22 +++++++------------ 4 files changed, 12 insertions(+), 32 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e2c5fc44f..3050699f0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,3 @@ -import space.kscience.gradle.isInDevelopment import space.kscience.gradle.useApache2Licence import space.kscience.gradle.useSPCTeam @@ -64,14 +63,7 @@ ksciencePublish { useApache2Licence() useSPCTeam() } - github("kmath", "SciProgCentre") - space( - if (isInDevelopment) { - "https://maven.pkg.jetbrains.space/spc/p/sci/dev" - } else { - "https://maven.pkg.jetbrains.space/spc/p/sci/maven" - } - ) + repository("spc","https://maven.sciprog.center/kscience") sonatype("https://oss.sonatype.org") } diff --git a/gradle.properties b/gradle.properties index fc9bb4ee7..b6bb24a6f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx4096m org.gradle.parallel=true org.gradle.workers.max=4 -toolsVersion=0.15.0-kotlin-1.9.20-Beta +toolsVersion=0.15.0-kotlin-1.9.20-Beta2 #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true \ No newline at end of file diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 984f1619b..f48ab4c19 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,19 +19,13 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.structures.Float64 -import space.kscience.kmath.structures.Float32 -import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Float32Field -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.FloatField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.Float64Buffer -import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt index b6ad5009e..859255004 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt @@ -8,13 +8,7 @@ package space.kscience.kmath.geometry import space.kscience.kmath.complex.Quaternion import space.kscience.kmath.complex.QuaternionAlgebra import space.kscience.kmath.complex.conjugate -import space.kscience.kmath.complex.normalized -import space.kscience.kmath.geometry.euclidean3d.Float32Space3D -import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D import space.kscience.kmath.geometry.euclidean3d.theta -import kotlin.math.asin -import kotlin.math.atan2 -import kotlin.math.pow public operator fun Quaternion.times(other: Quaternion): Quaternion = QuaternionAlgebra.multiply(this, other) @@ -50,11 +44,11 @@ public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * o // return Float32Vector3D(roll, pitch, yaw) //} -/** - * Quaternion to XYZ Cardan angles - */ -public fun Quaternion.toEuler(): Float32Vector3D = if (QuaternionAlgebra.norm(this) == 0.0) { - Float32Space3D.zero -} else { - normalized().normalizedToEuler() -} \ No newline at end of file +///** +// * Quaternion to XYZ Cardan angles +// */ +//public fun Quaternion.toEuler(): Float32Vector3D = if (QuaternionAlgebra.norm(this) == 0.0) { +// Float32Space3D.zero +//} else { +// normalized().normalizedToEuler() +//} \ No newline at end of file From 5129f29084ed810871a93d0d816205e0f638fa71 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 22 Sep 2023 09:53:44 +0300 Subject: [PATCH 054/103] update geometry --- build.gradle.kts | 2 +- .../space/kscience/kmath/ejml/_generated.kt | 10 ++------- .../kmath/geometry/euclidean2d/Circle2D.kt | 20 ++++++++++++----- .../geometry/euclidean2d/Float32Space2D.kt | 6 ++--- .../geometry/euclidean2d/Float64Space2D.kt | 8 +++---- .../kmath/geometry/quaternionOperations.kt | 22 +++++++------------ 6 files changed, 31 insertions(+), 37 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index e2c5fc44f..a7487f916 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -77,4 +77,4 @@ ksciencePublish { apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI") -val multikVersion by extra("0.2.0") +val multikVersion by extra("0.2.2") diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 984f1619b..f48ab4c19 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,19 +19,13 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.structures.Float64 -import space.kscience.kmath.structures.Float32 -import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Float32Field -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.FloatField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.Float64Buffer -import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt index 7841be8ff..1cf8d5dc2 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt @@ -6,16 +6,26 @@ package space.kscience.kmath.geometry.euclidean2d import kotlinx.serialization.Serializable +import space.kscience.kmath.geometry.Vector2D import kotlin.math.PI + +public interface Circle2D<T>{ + public val center: Vector2D<T> + public val radius: Double +} + +public val Circle2D<*>.circumference: Double get() = radius * 2 * PI + /** * A circle in 2D space */ @Serializable -public data class Circle2D( - @Serializable(Float64Space2D.VectorSerializer::class) public val center: DoubleVector2D, - public val radius: Double -) +public data class Float64Circle2D( + @Serializable(Float64Space2D.VectorSerializer::class) override val center: Float64Vector2D, + override val radius: Double +): Circle2D<Double> + +public fun Circle2D(center: Float64Vector2D, radius: Double): Circle2D<Double> = Float64Circle2D(center, radius) -public val Circle2D.circumference: Double get() = radius * 2 * PI diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt index 89c3dc204..4dd188d49 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt @@ -19,12 +19,10 @@ import kotlin.math.pow import kotlin.math.sqrt @Serializable(Float32Space2D.VectorSerializer::class) -public interface Float32Vector2D: Vector2D<Float> +public interface Float32Vector2D : Vector2D<Float> -public object Float32Space2D : - GeometrySpace<Float32Vector2D>, - ScaleOperations<Float32Vector2D> { +public object Float32Space2D : GeometrySpace<Float32Vector2D>, ScaleOperations<Float32Vector2D> { @Serializable @SerialName("Float32Vector2D") diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt index 030a46185..423e43c30 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt @@ -14,13 +14,11 @@ import kotlinx.serialization.encoding.Encoder import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector2D import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.operations.Norm import space.kscience.kmath.operations.ScaleOperations import kotlin.math.pow import kotlin.math.sqrt - public typealias DoubleVector2D = Vector2D<Double> public typealias Float64Vector2D = Vector2D<Double> @@ -30,9 +28,7 @@ public val Vector2D<Double>.r: Double get() = Float64Space2D.norm(this) /** * 2D Euclidean space */ -public object Float64Space2D : GeometrySpace<DoubleVector2D>, - ScaleOperations<DoubleVector2D>, - Norm<DoubleVector2D, Double> { +public object Float64Space2D : GeometrySpace<DoubleVector2D>, ScaleOperations<DoubleVector2D> { @Serializable @SerialName("Float64Vector2D") @@ -72,4 +68,6 @@ public object Float64Space2D : GeometrySpace<DoubleVector2D>, public val yAxis: DoubleVector2D = vector(0.0, 1.0) } +public fun Float64Vector2D(x: Number, y: Number): Float64Vector2D = Float64Space2D.vector(x, y) + public val Float64Field.euclidean2D: Float64Space2D get() = Float64Space2D \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt index b6ad5009e..859255004 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt @@ -8,13 +8,7 @@ package space.kscience.kmath.geometry import space.kscience.kmath.complex.Quaternion import space.kscience.kmath.complex.QuaternionAlgebra import space.kscience.kmath.complex.conjugate -import space.kscience.kmath.complex.normalized -import space.kscience.kmath.geometry.euclidean3d.Float32Space3D -import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D import space.kscience.kmath.geometry.euclidean3d.theta -import kotlin.math.asin -import kotlin.math.atan2 -import kotlin.math.pow public operator fun Quaternion.times(other: Quaternion): Quaternion = QuaternionAlgebra.multiply(this, other) @@ -50,11 +44,11 @@ public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * o // return Float32Vector3D(roll, pitch, yaw) //} -/** - * Quaternion to XYZ Cardan angles - */ -public fun Quaternion.toEuler(): Float32Vector3D = if (QuaternionAlgebra.norm(this) == 0.0) { - Float32Space3D.zero -} else { - normalized().normalizedToEuler() -} \ No newline at end of file +///** +// * Quaternion to XYZ Cardan angles +// */ +//public fun Quaternion.toEuler(): Float32Vector3D = if (QuaternionAlgebra.norm(this) == 0.0) { +// Float32Space3D.zero +//} else { +// normalized().normalizedToEuler() +//} \ No newline at end of file From bfb556b013fc9ca654066e3a5a07717a29a77567 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 3 Oct 2023 19:33:39 +0300 Subject: [PATCH 055/103] remove webpack and node version fixture --- .../kotlin/space/kscience/kmath/operations/LogicAlgebra.kt | 5 ++--- kmath-memory/build.gradle.kts | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt index 7aa5aed80..d8bf0fb57 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt @@ -7,7 +7,6 @@ package space.kscience.kmath.operations import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol -import space.kscience.kmath.expressions.symbol /** * An algebra for generic boolean logic @@ -61,8 +60,8 @@ public interface LogicAlgebra<T : Any> : Algebra<T> { public companion object { - public val TRUE: Symbol by symbol - public val FALSE: Symbol by symbol + public val TRUE: Symbol = Symbol("TRUE")//by symbol + public val FALSE: Symbol = Symbol("FALSE")// by symbol } } diff --git a/kmath-memory/build.gradle.kts b/kmath-memory/build.gradle.kts index 63811d784..f1dff3b75 100644 --- a/kmath-memory/build.gradle.kts +++ b/kmath-memory/build.gradle.kts @@ -1,5 +1,3 @@ -import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension - plugins { id("space.kscience.gradle.mpp") } @@ -18,5 +16,5 @@ readme { """.trimIndent() } -rootProject.the<NodeJsRootExtension>().versions.webpack.version = "5.76.2" -rootProject.the<NodeJsRootExtension>().nodeVersion = "20.2.0" +//rootProject.the<NodeJsRootExtension>().versions.webpack.version = "5.76.2" +//rootProject.the<NodeJsRootExtension>().nodeVersion = "20.8.0" From 1765f8cf8c81a6f72d58f839af32bebdad29f474 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 25 Oct 2023 10:28:39 +0300 Subject: [PATCH 056/103] Remove `asPolynomial` --- CHANGELOG.md | 1 + build.gradle.kts | 2 +- buildSrc/settings.gradle.kts | 4 +++ gradle.properties | 2 +- .../kmath/internal/binaryen/index.binaryen.kt | 2 +- .../kscience/kmath/data/XYColumnarData.kt | 31 +++++++++++++++++-- .../kscience/kmath/streaming/RingBuffer.kt | 4 +-- .../kmath/functions/polynomialConstructors.kt | 7 +---- 8 files changed, 38 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27b67a4d8..3c6523a0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ ### Deprecated ### Removed +- `asPolynomial` function due to scope pollution ### Fixed - Median statistics diff --git a/build.gradle.kts b/build.gradle.kts index 3050699f0..f40cb88ee 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -69,4 +69,4 @@ ksciencePublish { apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI") -val multikVersion by extra("0.2.0") +val multikVersion by extra("0.2.2") diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index 02111ba37..c455f5ae9 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -5,6 +5,10 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") +plugins { + id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" +} + dependencyResolutionManagement { val projectProperties = java.util.Properties() file("../gradle.properties").inputStream().use { diff --git a/gradle.properties b/gradle.properties index b6bb24a6f..0c2a6f455 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx4096m org.gradle.parallel=true org.gradle.workers.max=4 -toolsVersion=0.15.0-kotlin-1.9.20-Beta2 +toolsVersion=0.15.0-kotlin-1.9.20-RC2 #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true \ No newline at end of file diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt index f2e1aae83..143ae7ad4 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt @@ -52,7 +52,7 @@ internal external fun createType(types: Array<Type>): Type internal external fun expandType(type: Type): Array<Type> -internal external enum class ExpressionIds { +internal external enum class ExpressionIds { Invalid, Block, If, diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt index de7e6f79b..23cbcd0c7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt @@ -10,6 +10,7 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.VirtualBuffer import kotlin.math.max /** @@ -33,7 +34,10 @@ public interface XYColumnarData<out T, out X : T, out Y : T> : ColumnarData<T> { else -> null } - public companion object{ + public companion object { + /** + * Create data form two buffers (zero-copy) + */ @UnstableKMathAPI public fun <T, X : T, Y : T> of(x: Buffer<X>, y: Buffer<Y>): XYColumnarData<T, X, Y> { require(x.size == y.size) { "Buffer size mismatch. x buffer size is ${x.size}, y buffer size is ${y.size}" } @@ -43,6 +47,26 @@ public interface XYColumnarData<out T, out X : T, out Y : T> : ColumnarData<T> { override val y: Buffer<Y> = y } } + + /** + * Create two-column data from a list of row-objects (zero-copy) + */ + @UnstableKMathAPI + public fun <I, T, X : T, Y : T> ofList( + list: List<I>, + xConverter: (I) -> X, + yConverter: (I) -> Y, + ): XYColumnarData<T, X, Y> = object : XYColumnarData<T, X, Y> { + override val size: Int get() = list.size + + override val x: Buffer<X> = VirtualBuffer(list.size) { + xConverter(list[it]) + } + + override val y: Buffer<Y> = VirtualBuffer(list.size) { + yConverter(list[it]) + } + } } } @@ -56,9 +80,10 @@ public fun <T> ColumnarData<T>.asXYData( ySymbol: Symbol, ): XYColumnarData<T, T, T> = object : XYColumnarData<T, T, T> { init { - requireNotNull(this@asXYData[xSymbol]){"The column with name $xSymbol is not present in $this"} - requireNotNull(this@asXYData[ySymbol]){"The column with name $ySymbol is not present in $this"} + requireNotNull(this@asXYData[xSymbol]) { "The column with name $xSymbol is not present in $this" } + requireNotNull(this@asXYData[ySymbol]) { "The column with name $ySymbol is not present in $this" } } + override val size: Int get() = this@asXYData.size override val x: Buffer<T> get() = this@asXYData[xSymbol]!! override val y: Buffer<T> get() = this@asXYData[ySymbol]!! diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt index 2ac8c1eb4..bb07fede1 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt @@ -65,9 +65,7 @@ public class RingBuffer<T>( } } - - @Suppress("NOTHING_TO_INLINE") - private inline fun Int.forward(n: Int): Int = (this + n) % (buffer.size) + private fun Int.forward(n: Int): Int = (this + n) % (buffer.size) override fun toString(): String = Buffer.toString(this) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt index 4e9791a87..e07ff764c 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt @@ -20,9 +20,4 @@ public fun <C> Polynomial(coefficients: List<C>, reverse: Boolean = false): Poly */ @Suppress("FunctionName") public fun <C> Polynomial(vararg coefficients: C, reverse: Boolean = false): Polynomial<C> = - Polynomial(with(coefficients) { if (reverse) reversed() else toList() }) - -/** - * Represents [this] constant as a [Polynomial]. - */ -public fun <C> C.asPolynomial() : Polynomial<C> = Polynomial(listOf(this)) \ No newline at end of file + Polynomial(with(coefficients) { if (reverse) reversed() else toList() }) \ No newline at end of file From 328d45444c061bb1cafeb856980e93355a5856ee Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 31 Oct 2023 14:05:17 +0300 Subject: [PATCH 057/103] 1.9.20 finalization --- buildSrc/build.gradle.kts | 2 +- .../benchmarks/addBenchmarkProperties.kt | 4 ++-- gradle.properties | 2 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../kmath/internal/binaryen/index.binaryen.kt | 2 +- kmath-commons/build.gradle.kts | 21 +++++++++++-------- .../commons/expressions/CmDsExpression.kt | 0 .../integration/CMGaussRuleIntegrator.kt | 0 .../kmath/commons/integration/CMIntegrator.kt | 0 .../kscience/kmath/commons/linear/CMMatrix.kt | 0 .../kscience/kmath/commons/linear/CMSolver.kt | 0 .../kmath/commons/optimization/CMOptimizer.kt | 0 .../random/CMRandomGeneratorWrapper.kt | 0 .../commons/transform/Transformations.kt | 0 .../DerivativeStructureExpressionTest.kt | 0 .../commons/integration/IntegrationTest.kt | 0 .../commons/optimization/OptimizeTest.kt | 0 17 files changed, 18 insertions(+), 15 deletions(-) rename kmath-commons/src/{main => jvmMain}/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt (100%) rename kmath-commons/src/{main => jvmMain}/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt (100%) rename kmath-commons/src/{main => jvmMain}/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt (100%) rename kmath-commons/src/{main => jvmMain}/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt (100%) rename kmath-commons/src/{main => jvmMain}/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt (100%) rename kmath-commons/src/{main => jvmMain}/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt (100%) rename kmath-commons/src/{main => jvmMain}/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt (100%) rename kmath-commons/src/{main => jvmMain}/kotlin/space/kscience/kmath/commons/transform/Transformations.kt (100%) rename kmath-commons/src/{test => jvmTest}/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt (100%) rename kmath-commons/src/{test => jvmTest}/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt (100%) rename kmath-commons/src/{test => jvmTest}/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt (100%) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 734f60091..08db49244 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -17,7 +17,7 @@ val benchmarksVersion = spclibs.versions.kotlinx.benchmark.get() dependencies { api("space.kscience:gradle-tools:$toolsVersion") //plugins form benchmarks - api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.4.7") + api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.4.9") //api("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion") //to be used inside build-script only //implementation(spclibs.kotlinx.serialization.json) diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt index a3a475885..83cb786e3 100644 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt +++ b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt @@ -54,9 +54,9 @@ fun Project.addBenchmarkProperties() { p.extensions.findByType(KScienceReadmeExtension::class.java)?.run { benchmarksProject.extensions.findByType(BenchmarksExtension::class.java)?.configurations?.forEach { cfg -> property("benchmark${cfg.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}") { - val launches = benchmarksProject.buildDir.resolve("reports/benchmarks/${cfg.name}") + val launches = benchmarksProject.layout.buildDirectory.dir("reports/benchmarks/${cfg.name}").get() - val resDirectory = launches.listFiles()?.maxByOrNull { + val resDirectory = launches.files().maxByOrNull { LocalDateTime.parse(it.name, ISO_DATE_TIME).atZone(ZoneId.systemDefault()).toInstant() } diff --git a/gradle.properties b/gradle.properties index 0c2a6f455..5d62bf88e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx4096m org.gradle.parallel=true org.gradle.workers.max=4 -toolsVersion=0.15.0-kotlin-1.9.20-RC2 +toolsVersion=0.15.0-kotlin-1.9.20 #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index db9a6b825..e411586a5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt index 143ae7ad4..59c9a40a6 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt @@ -9,7 +9,7 @@ "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", "PropertyName", - "ClassName", + "ClassName", "ENUM_CLASS_IN_EXTERNAL_DECLARATION_WARNING", ) @file:JsModule("binaryen") diff --git a/kmath-commons/build.gradle.kts b/kmath-commons/build.gradle.kts index 50fef7ac8..5c2c4a304 100644 --- a/kmath-commons/build.gradle.kts +++ b/kmath-commons/build.gradle.kts @@ -1,17 +1,20 @@ plugins { - id("space.kscience.gradle.jvm") + id("space.kscience.gradle.mpp") } description = "Commons math binding for kmath" -dependencies { - api(project(":kmath-core")) - api(project(":kmath-complex")) - api(project(":kmath-coroutines")) - api(project(":kmath-optimization")) - api(project(":kmath-stat")) - api(project(":kmath-functions")) - api("org.apache.commons:commons-math3:3.6.1") +kscience { + jvm() + jvmMain { + api(projects.kmathCore) + api(projects.kmathComplex) + api(projects.kmathCoroutines) + api(projects.kmathOptimization) + api(projects.kmathStat) + api(projects.kmathFunctions) + api("org.apache.commons:commons-math3:3.6.1") + } } readme { diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt similarity index 100% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt rename to kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt similarity index 100% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt rename to kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt similarity index 100% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt rename to kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt similarity index 100% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt rename to kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt similarity index 100% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt rename to kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt similarity index 100% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt rename to kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt similarity index 100% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt rename to kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt diff --git a/kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/transform/Transformations.kt similarity index 100% rename from kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt rename to kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/transform/Transformations.kt diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt similarity index 100% rename from kmath-commons/src/test/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt rename to kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt similarity index 100% rename from kmath-commons/src/test/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt rename to kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt diff --git a/kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt similarity index 100% rename from kmath-commons/src/test/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt rename to kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt From ea887b8c728b9a902c80d37a6a092cdf7e7b9a1e Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 1 Nov 2023 08:55:47 +0300 Subject: [PATCH 058/103] 0.4 WIP --- .../space/kscience/kmath/ejml/_generated.kt | 10 ++++- .../kmath/integration/GaussIntegrator.kt | 6 +-- .../kscience/kmath/integration/Integrator.kt | 4 +- .../kmath/integration/SimpsonIntegrator.kt | 12 +++--- .../kmath/integration/SplineIntegrator.kt | 8 ++-- .../kmath/integration/UnivariateIntegrand.kt | 6 +-- .../kmath/geometry/quaternionOperations.kt | 23 +--------- .../kmath/tensors/core/internal/linUtils.kt | 42 ++++++++----------- 8 files changed, 45 insertions(+), 66 deletions(-) diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 881649d01..0cef96f49 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,13 +19,19 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.structures.Float64 +import space.kscience.kmath.structures.Float32 import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.FloatField import space.kscience.kmath.operations.invoke +import space.kscience.kmath.structures.Float64Buffer +import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index 4753edcd0..7d37711cd 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -54,7 +54,7 @@ public class GaussIntegrator<T : Any>( } } - override fun process(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> = with(algebra) { + override fun integrate(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> = with(algebra) { val f = integrand.function val (points, weights) = buildRule(integrand) var res: T = zero @@ -68,7 +68,7 @@ public class GaussIntegrator<T : Any>( res = t } return integrand.withAttributes { - value(res) + IntegrandValue(res) IntegrandCallsPerformed(integrand.calls + points.size) } } @@ -102,7 +102,7 @@ public inline fun <reified T : Any> GaussIntegrator<T>.integrate( val ranges = UnivariateIntegrandRanges( (0 until intervals).map { i -> (range.start + rangeSize * i)..(range.start + rangeSize * (i + 1)) to order } ) - return process( + return integrate( UnivariateIntegrand<T>( attributeBuilder = { IntegrationRange(range) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt index 18c46b83b..76fcd0e29 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt @@ -8,9 +8,9 @@ package space.kscience.kmath.integration /** * A general interface for all integrators. */ -public interface Integrator<I : Integrand> { +public interface Integrator<T, I : Integrand<T>> { /** * Runs one integration pass and return a new [Integrand] with a new set of features. */ - public fun process(integrand: I): I + public fun integrate(integrand: I): I } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt index c0e4fb394..699d3f0ae 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt @@ -44,12 +44,12 @@ public class SimpsonIntegrator<T : Any>( return res } - override fun process(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> { + override fun integrate(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> { val ranges = integrand[UnivariateIntegrandRanges] return if (ranges != null) { val res = algebra.sum(ranges.ranges.map { integrateRange(integrand, it.first, it.second) }) integrand.withAttributes { - value(res) + IntegrandValue(res) IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second }) } } else { @@ -58,7 +58,7 @@ public class SimpsonIntegrator<T : Any>( val range = integrand[IntegrationRange] ?: 0.0..1.0 val res = integrateRange(integrand, range, numPoints) integrand.withAttributes { - value(res) + IntegrandValue(res) IntegrandCallsPerformed(integrand.calls + numPoints) } } @@ -96,12 +96,12 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> { return res } - override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { + override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { val ranges = integrand[UnivariateIntegrandRanges] return if (ranges != null) { val res = ranges.ranges.sumOf { integrateRange(integrand, it.first, it.second) } integrand.withAttributes { - value(res) + IntegrandValue(res) IntegrandCallsPerformed(integrand.calls + ranges.ranges.sumOf { it.second }) } } else { @@ -110,7 +110,7 @@ public object DoubleSimpsonIntegrator : UnivariateIntegrator<Double> { val range = integrand[IntegrationRange] ?: 0.0..1.0 val res = integrateRange(integrand, range, numPoints) integrand.withAttributes { - value(res) + IntegrandValue(res) IntegrandCallsPerformed(integrand.calls + numPoints) } } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt index 636ca5a74..c03b248d4 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt @@ -54,7 +54,7 @@ public class SplineIntegrator<T : Comparable<T>>( public val algebra: Field<T>, public val bufferFactory: MutableBufferFactory<T>, ) : UnivariateIntegrator<T> { - override fun process(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> = algebra { + override fun integrate(integrand: UnivariateIntegrand<T>): UnivariateIntegrand<T> = algebra { val range = integrand[IntegrationRange] ?: 0.0..1.0 val interpolator: PolynomialInterpolator<T> = SplineInterpolator(algebra, bufferFactory) @@ -72,7 +72,7 @@ public class SplineIntegrator<T : Comparable<T>>( ) val res = polynomials.integrate(algebra, number(range.start)..number(range.endInclusive)) integrand.withAttributes { - value(res) + IntegrandValue(res) IntegrandCallsPerformed(integrand.calls + nodes.size) } } @@ -86,7 +86,7 @@ public class SplineIntegrator<T : Comparable<T>>( */ @UnstableKMathAPI public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { - override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { + override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { val range = integrand[IntegrationRange] ?: 0.0..1.0 val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, ::Float64Buffer) @@ -100,7 +100,7 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { val polynomials = interpolator.interpolatePolynomials(nodes, values) val res = polynomials.integrate(Float64Field, range) return integrand.withAttributes { - value(res) + IntegrandValue(res) IntegrandCallsPerformed(integrand.calls + nodes.size) } } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index 6a6d47667..9c39e7edc 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -34,7 +34,7 @@ public inline fun <reified T : Any> UnivariateIntegrand( noinline function: (Double) -> T, ): UnivariateIntegrand<T> = UnivariateIntegrand(safeTypeOf(), Attributes(attributeBuilder), function) -public typealias UnivariateIntegrator<T> = Integrator<UnivariateIntegrand<T>> +public typealias UnivariateIntegrator<T> = Integrator<T, UnivariateIntegrand<T>> public object IntegrationRange : IntegrandAttribute<ClosedRange<Double>> @@ -70,7 +70,7 @@ public fun TypedAttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(varar public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( attributesBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, noinline function: (Double) -> T, -): UnivariateIntegrand<T> = process(UnivariateIntegrand(attributesBuilder, function)) +): UnivariateIntegrand<T> = integrate(UnivariateIntegrand(attributesBuilder, function)) /** * A shortcut method to integrate a [function] in [range] with additional features. @@ -83,7 +83,7 @@ public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( noinline function: (Double) -> T, ): UnivariateIntegrand<T> { - return process( + return integrate( UnivariateIntegrand( attributeBuilder = { IntegrationRange(range) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt index 859255004..4fb3a720c 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt @@ -30,25 +30,4 @@ public fun QuaternionAlgebra.angleBetween(q1: Quaternion, q2: Quaternion): Angle /** * Euclidean product of two quaternions */ -public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * other.x + y * other.y + z * other.z - -// -///** -// * Convert a quaternion to XYZ Cardan angles assuming it is normalized. -// */ -//private fun Quaternion.normalizedToEuler(): Float32Vector3D { -// val roll = atan2(2 * y * w + 2 * x * z, 1 - 2 * y * y - 2 * z * z) -// val pitch = atan2(2 * x * w - 2 * y * z, 1 - 2 * x * x - 2 * z * z) -// val yaw = asin(2 * x * y + 2 * z * w) -// -// return Float32Vector3D(roll, pitch, yaw) -//} - -///** -// * Quaternion to XYZ Cardan angles -// */ -//public fun Quaternion.toEuler(): Float32Vector3D = if (QuaternionAlgebra.norm(this) == 0.0) { -// Float32Space3D.zero -//} else { -// normalized().normalizedToEuler() -//} \ No newline at end of file +public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * other.x + y * other.y + z * other.z \ No newline at end of file diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index 272af41d5..66092a532 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -310,32 +310,26 @@ internal fun DoubleTensorAlgebra.svdHelper( } } -private fun pythag(a: Double, b: Double): Double { - val at: Double = abs(a) - val bt: Double = abs(b) - val ct: Double - val result: Double - if (at > bt) { - ct = bt / at - result = at * sqrt(1.0 + ct * ct) - } else if (bt > 0.0) { - ct = at / bt - result = bt * sqrt(1.0 + ct * ct) - } else result = 0.0 - return result -} - -private fun SIGN(a: Double, b: Double): Double { - if (b >= 0.0) - return abs(a) - else - return -abs(a) -} - internal fun MutableStructure2D<Double>.svdGolubKahanHelper( u: MutableStructure2D<Double>, w: BufferedTensor<Double>, v: MutableStructure2D<Double>, iterations: Int, epsilon: Double, ) { + fun pythag(a: Double, b: Double): Double { + val at: Double = abs(a) + val bt: Double = abs(b) + val ct: Double + val result: Double + if (at > bt) { + ct = bt / at + result = at * sqrt(1.0 + ct * ct) + } else if (bt > 0.0) { + ct = at / bt + result = bt * sqrt(1.0 + ct * ct) + } else result = 0.0 + return result + } + + val shape = this.shape val m = shape.component1() val n = shape.component2() @@ -553,7 +547,7 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper( h = rv1[k] f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y) g = pythag(f, 1.0) - f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x + f = ((x - z) * (x + z) + h * ((y / (f + if (f >= 0.0) abs(g) else -abs(g) )) - h)) / x c = 1.0 s = 1.0 @@ -563,7 +557,7 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper( g = rv1[i] y = wBuffer[wStart + i] h = s * g - g = c * g + g *= c z = pythag(f, h) rv1[j] = z c = f / z From 46eacbb7506d40962fa91f70cc0a047d63ed5a17 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 3 Nov 2023 09:56:19 +0300 Subject: [PATCH 059/103] 0.4 WIP --- CHANGELOG.md | 9 +- .../space/kscience/attributes/SafeType.kt | 2 +- .../kscience/kmath/data/XYColumnarData.kt | 6 +- .../kscience/kmath/expressions/DSAlgebra.kt | 4 +- .../FunctionalExpressionAlgebra.kt | 4 + .../kscience/kmath/expressions/MstAlgebra.kt | 25 ++- .../kmath/expressions/SimpleAutoDiff.kt | 32 ++-- .../kscience/kmath/linear/LinearSpace.kt | 9 +- .../kscience/kmath/linear/LupDecomposition.kt | 26 ++- .../kscience/kmath/linear/MatrixBuilder.kt | 11 +- .../kscience/kmath/linear/MatrixWrapper.kt | 6 +- .../space/kscience/kmath/linear/Transposed.kt | 4 + .../kscience/kmath/linear/VirtualMatrix.kt | 6 +- .../kscience/kmath/linear/matrixAttributes.kt | 8 +- .../space/kscience/kmath/misc/sorting.kt | 17 +- .../space/kscience/kmath/nd/AlgebraND.kt | 4 +- .../kscience/kmath/nd/BufferAlgebraND.kt | 5 + .../space/kscience/kmath/nd/BufferND.kt | 11 +- .../kscience/kmath/nd/PermutedStructureND.kt | 4 + .../space/kscience/kmath/nd/Structure1D.kt | 15 +- .../space/kscience/kmath/nd/Structure2D.kt | 23 ++- .../space/kscience/kmath/nd/StructureND.kt | 105 ++++++------ .../kscience/kmath/nd/VirtualStructureND.kt | 7 +- .../space/kscience/kmath/nd/operationsND.kt | 4 +- .../kscience/kmath/operations/Algebra.kt | 26 ++- .../space/kscience/kmath/operations/BigInt.kt | 9 +- .../kmath/operations/BufferAlgebra.kt | 5 +- .../kscience/kmath/operations/LogicAlgebra.kt | 4 + .../kmath/operations/integerFields.kt | 12 +- .../kscience/kmath/operations/numbers.kt | 2 +- .../space/kscience/kmath/structures/Buffer.kt | 154 ++++++++++-------- .../kmath/structures/BufferAccessor2D.kt | 14 +- .../kmath/structures/FlaggedBuffer.kt | 5 + .../kmath/structures/Float32Buffer.kt | 5 + .../kmath/structures/Float64Buffer.kt | 5 + .../kscience/kmath/structures/Int16Buffer.kt | 4 + .../kscience/kmath/structures/Int32Buffer.kt | 5 + .../kscience/kmath/structures/Int64Buffer.kt | 5 + .../kscience/kmath/structures/Int8Buffer.kt | 5 + .../kscience/kmath/structures/ListBuffer.kt | 37 +++-- .../kmath/structures/MutableBuffer.kt | 60 +++---- .../kmath/linear/DoubleLUSolverTest.kt | 2 +- .../space/kscience/kmath/ejml/_generated.kt | 10 +- .../histogram/UniformHistogramGroupND.kt | 4 +- 44 files changed, 451 insertions(+), 269 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1b23d817..ef5e0490c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,11 @@ ## Unreleased ### Added -- Integer division algebras -- Float32 geometries -- New Attributes-kt module that could be used as stand-alone. It declares type-safe attributes containers. -- Explicit `mutableStructureND` builders for mutable structures +- Explicit `SafeType` for algebras and buffers. +- Integer division algebras. +- Float32 geometries. +- New Attributes-kt module that could be used as stand-alone. It declares. type-safe attributes containers. +- Explicit `mutableStructureND` builders for mutable structures. ### Changed - Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types. diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt index 7225d1a6b..0fac2477c 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt @@ -16,7 +16,7 @@ import kotlin.reflect.typeOf * @param kType raw [KType] */ @JvmInline -public value class SafeType<T> @PublishedApi internal constructor(public val kType: KType) +public value class SafeType<out T> @PublishedApi internal constructor(public val kType: KType) public inline fun <reified T> safeTypeOf(): SafeType<T> = SafeType(typeOf<T>()) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt index 23cbcd0c7..b06ce1349 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt @@ -52,10 +52,10 @@ public interface XYColumnarData<out T, out X : T, out Y : T> : ColumnarData<T> { * Create two-column data from a list of row-objects (zero-copy) */ @UnstableKMathAPI - public fun <I, T, X : T, Y : T> ofList( + public inline fun <I, T, reified X : T, reified Y : T> ofList( list: List<I>, - xConverter: (I) -> X, - yConverter: (I) -> Y, + noinline xConverter: (I) -> X, + noinline yConverter: (I) -> Y, ): XYColumnarData<T, X, Y> = object : XYColumnarData<T, X, Y> { override val size: Int get() = list.size diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt index 63f96b0af..817f38ff0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt @@ -13,8 +13,6 @@ import space.kscience.kmath.structures.MutableBufferFactory import space.kscience.kmath.structures.asBuffer import kotlin.math.max import kotlin.math.min -import kotlin.reflect.KType -import kotlin.reflect.typeOf /** * Class representing both the value and the differentials of a function. @@ -84,6 +82,8 @@ public abstract class DSAlgebra<T, A : Ring<T>>( bindings: Map<Symbol, T>, ) : ExpressionAlgebra<T, DS<T, A>>, SymbolIndexer { + override val bufferFactory: MutableBufferFactory<DS<T, A>> = MutableBufferFactory() + /** * Get the compiler for number of free parameters and order. * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt index 8e37f3d32..5b4dcd638 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.expressions import space.kscience.kmath.operations.* +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -17,6 +18,8 @@ import kotlin.contracts.contract public abstract class FunctionalExpressionAlgebra<T, out A : Algebra<T>>( public val algebra: A, ) : ExpressionAlgebra<T, Expression<T>> { + override val bufferFactory: MutableBufferFactory<Expression<T>> = MutableBufferFactory<Expression<T>>() + /** * Builds an Expression of constant expression that does not depend on arguments. */ @@ -49,6 +52,7 @@ public abstract class FunctionalExpressionAlgebra<T, out A : Algebra<T>>( public open class FunctionalExpressionGroup<T, out A : Group<T>>( algebra: A, ) : FunctionalExpressionAlgebra<T, A>(algebra), Group<Expression<T>> { + override val zero: Expression<T> get() = const(algebra.zero) override fun Expression<T>.unaryMinus(): Expression<T> = diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt index c894cf00a..c568eece0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt @@ -7,11 +7,14 @@ package space.kscience.kmath.expressions import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* +import space.kscience.kmath.structures.MutableBufferFactory /** * [Algebra] over [MST] nodes. */ public object MstNumericAlgebra : NumericAlgebra<MST> { + override val bufferFactory: MutableBufferFactory<MST> = MutableBufferFactory() + override fun number(value: Number): MST.Numeric = MST.Numeric(value) override fun bindSymbolOrNull(value: String): Symbol = StringSymbol(value) override fun bindSymbol(value: String): Symbol = bindSymbolOrNull(value) @@ -27,6 +30,9 @@ public object MstNumericAlgebra : NumericAlgebra<MST> { * [Group] over [MST] nodes. */ public object MstGroup : Group<MST>, NumericAlgebra<MST>, ScaleOperations<MST> { + + override val bufferFactory: MutableBufferFactory<MST> = MutableBufferFactory() + override val zero: MST.Numeric = number(0.0) override fun number(value: Number): MST.Numeric = MstNumericAlgebra.number(value) @@ -57,7 +63,11 @@ public object MstGroup : Group<MST>, NumericAlgebra<MST>, ScaleOperations<MST> { @Suppress("OVERRIDE_BY_INLINE") @OptIn(UnstableKMathAPI::class) public object MstRing : Ring<MST>, NumbersAddOps<MST>, ScaleOperations<MST> { + + override val bufferFactory: MutableBufferFactory<MST> = MutableBufferFactory() + override inline val zero: MST.Numeric get() = MstGroup.zero + override val one: MST.Numeric = number(1.0) override fun number(value: Number): MST.Numeric = MstGroup.number(value) @@ -87,7 +97,11 @@ public object MstRing : Ring<MST>, NumbersAddOps<MST>, ScaleOperations<MST> { @Suppress("OVERRIDE_BY_INLINE") @OptIn(UnstableKMathAPI::class) public object MstField : Field<MST>, NumbersAddOps<MST>, ScaleOperations<MST> { + + override val bufferFactory: MutableBufferFactory<MST> = MutableBufferFactory() + override inline val zero: MST.Numeric get() = MstRing.zero + override inline val one: MST.Numeric get() = MstRing.one override fun bindSymbolOrNull(value: String): Symbol = MstNumericAlgebra.bindSymbolOrNull(value) @@ -117,7 +131,11 @@ public object MstField : Field<MST>, NumbersAddOps<MST>, ScaleOperations<MST> { */ @Suppress("OVERRIDE_BY_INLINE") public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> { + + override val bufferFactory: MutableBufferFactory<MST> = MutableBufferFactory() + override inline val zero: MST.Numeric get() = MstField.zero + override inline val one: MST.Numeric get() = MstField.one override fun bindSymbolOrNull(value: String): Symbol = MstNumericAlgebra.bindSymbolOrNull(value) @@ -164,6 +182,9 @@ public object MstExtendedField : ExtendedField<MST>, NumericAlgebra<MST> { */ @UnstableKMathAPI public object MstLogicAlgebra : LogicAlgebra<MST> { + + override val bufferFactory: MutableBufferFactory<MST> = MutableBufferFactory() + override fun bindSymbolOrNull(value: String): MST = super.bindSymbolOrNull(value) ?: StringSymbol(value) override fun const(boolean: Boolean): Symbol = if (boolean) { @@ -176,7 +197,7 @@ public object MstLogicAlgebra : LogicAlgebra<MST> { override fun MST.and(other: MST): MST = MST.Binary(Boolean::and.name, this, other) - override fun MST.or(other: MST): MST = MST.Binary(Boolean::or.name, this, other) + override fun MST.or(other: MST): MST = MST.Binary(Boolean::or.name, this, other) - override fun MST.xor(other: MST): MST = MST.Binary(Boolean::xor.name, this, other) + override fun MST.xor(other: MST): MST = MST.Binary(Boolean::xor.name, this, other) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt index 2bb5043b7..6d22b18dc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt @@ -5,9 +5,11 @@ package space.kscience.kmath.expressions +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.Point import space.kscience.kmath.operations.* +import space.kscience.kmath.structures.MutableBufferFactory import space.kscience.kmath.structures.asBuffer import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -30,9 +32,10 @@ public open class AutoDiffValue<out T>(public val value: T) */ public class DerivationResult<T : Any>( public val value: T, + override val type: SafeType<T>, private val derivativeValues: Map<String, T>, public val context: Field<T>, -) { +) : WithType<T> { /** * Returns derivative of [variable] or returns [Ring.zero] in [context]. */ @@ -49,19 +52,23 @@ public class DerivationResult<T : Any>( */ public fun <T : Any> DerivationResult<T>.grad(vararg variables: Symbol): Point<T> { check(variables.isNotEmpty()) { "Variable order is not provided for gradient construction" } - return variables.map(::derivative).asBuffer() + return variables.map(::derivative).asBuffer(type) } /** - * Represents field in context of which functions can be derived. + * Represents field. Function derivatives could be computed in this field */ @OptIn(UnstableKMathAPI::class) public open class SimpleAutoDiffField<T : Any, F : Field<T>>( - public val context: F, + public val algebra: F, bindings: Map<Symbol, T>, ) : Field<AutoDiffValue<T>>, ExpressionAlgebra<T, AutoDiffValue<T>>, NumbersAddOps<AutoDiffValue<T>> { - override val zero: AutoDiffValue<T> get() = const(context.zero) - override val one: AutoDiffValue<T> get() = const(context.one) + + override val bufferFactory: MutableBufferFactory<AutoDiffValue<T>> = MutableBufferFactory<AutoDiffValue<T>>() + + override val zero: AutoDiffValue<T> get() = const(algebra.zero) + + override val one: AutoDiffValue<T> get() = const(algebra.one) // this stack contains pairs of blocks and values to apply them to private var stack: Array<Any?> = arrayOfNulls<Any?>(8) @@ -69,7 +76,7 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>( private val derivatives: MutableMap<AutoDiffValue<T>, T> = hashMapOf() private val bindings: Map<String, AutoDiffVariableWithDerivative<T>> = bindings.entries.associate { - it.key.identity to AutoDiffVariableWithDerivative(it.key.identity, it.value, context.zero) + it.key.identity to AutoDiffVariableWithDerivative(it.key.identity, it.value, algebra.zero) } /** @@ -92,7 +99,7 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>( override fun bindSymbolOrNull(value: String): AutoDiffValue<T>? = bindings[value] private fun getDerivative(variable: AutoDiffValue<T>): T = - (variable as? AutoDiffVariableWithDerivative)?.d ?: derivatives[variable] ?: context.zero + (variable as? AutoDiffVariableWithDerivative)?.d ?: derivatives[variable] ?: algebra.zero private fun setDerivative(variable: AutoDiffValue<T>, value: T) { if (variable is AutoDiffVariableWithDerivative) variable.d = value else derivatives[variable] = value @@ -103,7 +110,7 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>( while (sp > 0) { val value = stack[--sp] val block = stack[--sp] as F.(Any?) -> Unit - context.block(value) + algebra.block(value) } } @@ -130,7 +137,6 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>( * } * ``` */ - @Suppress("UNCHECKED_CAST") public fun <R> derive(value: R, block: F.(R) -> Unit): R { // save block to stack for backward pass if (sp >= stack.size) stack = stack.copyOf(stack.size * 2) @@ -142,9 +148,9 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>( internal fun differentiate(function: SimpleAutoDiffField<T, F>.() -> AutoDiffValue<T>): DerivationResult<T> { val result = function() - result.d = context.one // computing derivative w.r.t result + result.d = algebra.one // computing derivative w.r.t result runBackwardPass() - return DerivationResult(result.value, bindings.mapValues { it.value.d }, context) + return DerivationResult(result.value, algebra.type, bindings.mapValues { it.value.d }, algebra) } // // Overloads for Double constants @@ -194,7 +200,7 @@ public open class SimpleAutoDiffField<T : Any, F : Field<T>>( public inline fun <T : Any, F : Field<T>> SimpleAutoDiffField<T, F>.const(block: F.() -> T): AutoDiffValue<T> { contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } - return const(context.block()) + return const(algebra.block()) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index 0780be29a..ddf4f17d4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -10,10 +10,9 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.* import space.kscience.kmath.operations.BufferRingOps import space.kscience.kmath.operations.Ring +import space.kscience.kmath.operations.WithType import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer -import kotlin.reflect.KType -import kotlin.reflect.typeOf /** * Alias for [Structure2D] with more familiar name. @@ -34,7 +33,7 @@ public typealias Point<T> = Buffer<T> * A marker interface for algebras that operate on matrices * @param T type of matrix element */ -public interface MatrixOperations<T> +public interface MatrixOperations<T> : WithType<T> /** * Basic operations on matrices and vectors. @@ -45,6 +44,8 @@ public interface MatrixOperations<T> public interface LinearSpace<T, out A : Ring<T>> : MatrixOperations<T> { public val elementAlgebra: A + override val type: SafeType<T> get() = elementAlgebra.type + /** * Produces a matrix with this context and given dimensions. */ @@ -212,4 +213,4 @@ public fun <T : Any> Matrix<T>.asVector(): Point<T> = * @receiver a buffer. * @return the new matrix. */ -public fun <T : Any> Point<T>.asMatrix(): VirtualMatrix<T> = VirtualMatrix(size, 1) { i, _ -> get(i) } \ No newline at end of file +public fun <T : Any> Point<T>.asMatrix(): VirtualMatrix<T> = VirtualMatrix(type, size, 1) { i, _ -> get(i) } \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 9fe8397d8..1ac2ca5c6 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -22,11 +22,27 @@ import space.kscience.kmath.structures.* * @param l The lower triangular matrix in this decomposition. It may have [LowerTriangular]. * @param u The upper triangular matrix in this decomposition. It may have [UpperTriangular]. */ -public data class LupDecomposition<T>( +public class LupDecomposition<T>( + public val linearSpace: LinearSpace<T, Ring<T>>, public val l: Matrix<T>, public val u: Matrix<T>, public val pivot: IntBuffer, -) +) { + public val elementAlgebra: Ring<T> get() = linearSpace.elementAlgebra + + public val pivotMatrix: VirtualMatrix<T> + get() = VirtualMatrix(linearSpace.type, l.rowNum, l.colNum) { row, column -> + if (column == pivot[row]) elementAlgebra.one else elementAlgebra.zero + } + + public val <T> LupDecomposition<T>.determinant by lazy { + elementAlgebra { (0 until l.shape[0]).fold(if (even) one else -one) { value, i -> value * lu[i, i] } } + } + +} + + + public class LupDecompositionAttribute<T>(type: SafeType<LupDecomposition<T>>) : @@ -168,7 +184,7 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( for (row in col + 1 until m) lu[row, col] /= luDiag } - val l: MatrixWrapper<T> = VirtualMatrix(rowNum, colNum) { i, j -> + val l: MatrixWrapper<T> = VirtualMatrix(type, rowNum, colNum) { i, j -> when { j < i -> lu[i, j] j == i -> one @@ -176,7 +192,7 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( } }.withAttribute(LowerTriangular) - val u = VirtualMatrix(rowNum, colNum) { i, j -> + val u = VirtualMatrix(type, rowNum, colNum) { i, j -> if (j >= i) lu[i, j] else zero }.withAttribute(UpperTriangular) // @@ -184,7 +200,7 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( // if (j == pivot[i]) one else zero // }.withAttribute(Determinant, if (even) one else -one) - return LupDecomposition(l, u, pivot.asBuffer()) + return LupDecomposition(this@lup, l, u, pivot.asBuffer()) } } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt index 7b6c36dfc..9543555e0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt @@ -6,16 +6,21 @@ package space.kscience.kmath.linear import space.kscience.attributes.FlagAttribute +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Ring +import space.kscience.kmath.operations.WithType import space.kscience.kmath.structures.BufferAccessor2D -import space.kscience.kmath.structures.MutableBuffer +import space.kscience.kmath.structures.MutableBufferFactory public class MatrixBuilder<T : Any, out A : Ring<T>>( public val linearSpace: LinearSpace<T, A>, public val rows: Int, public val columns: Int, -) { +) : WithType<T> { + + override val type: SafeType<T> get() = linearSpace.type + public operator fun invoke(vararg elements: T): Matrix<T> { require(rows * columns == elements.size) { "The number of elements ${elements.size} is not equal $rows * $columns" } return linearSpace.buildMatrix(rows, columns) { i, j -> elements[i * columns + j] } @@ -61,7 +66,7 @@ public fun <T : Any, A : Ring<T>> MatrixBuilder<T, A>.symmetric( builder: (i: Int, j: Int) -> T, ): Matrix<T> { require(columns == rows) { "In order to build symmetric matrix, number of rows $rows should be equal to number of columns $columns" } - return with(BufferAccessor2D<T?>(rows, rows, MutableBuffer.Companion::boxing)) { + return with(BufferAccessor2D<T?>(rows, rows, MutableBufferFactory(type))) { val cache = factory(rows * rows) { null } linearSpace.buildMatrix(rows, rows) { i, j -> val cached = cache[i, j] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index a129b04f0..9d89f7636 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -39,7 +39,7 @@ public fun <T : Any, A : Attribute<T>> Matrix<T>.withAttribute( attribute: A, attrValue: T, ): MatrixWrapper<T> = if (this is MatrixWrapper) { - MatrixWrapper(origin, attributes.withAttribute(attribute,attrValue)) + MatrixWrapper(origin, attributes.withAttribute(attribute, attrValue)) } else { MatrixWrapper(this, Attributes(attribute, attrValue)) } @@ -68,7 +68,7 @@ public fun <T : Any> Matrix<T>.modifyAttributes(modifier: (Attributes) -> Attrib public fun <T : Any> LinearSpace<T, Ring<T>>.one( rows: Int, columns: Int, -): MatrixWrapper<T> = VirtualMatrix(rows, columns) { i, j -> +): MatrixWrapper<T> = VirtualMatrix(type, rows, columns) { i, j -> if (i == j) elementAlgebra.one else elementAlgebra.zero }.withAttribute(IsUnit) @@ -79,6 +79,6 @@ public fun <T : Any> LinearSpace<T, Ring<T>>.one( public fun <T : Any> LinearSpace<T, Ring<T>>.zero( rows: Int, columns: Int, -): MatrixWrapper<T> = VirtualMatrix(rows, columns) { _, _ -> +): MatrixWrapper<T> = VirtualMatrix(type, rows, columns) { _, _ -> elementAlgebra.zero }.withAttribute(IsZero) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt index 3e93a2a23..2cc566f92 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt @@ -6,10 +6,14 @@ package space.kscience.kmath.linear import space.kscience.attributes.Attributes +import space.kscience.attributes.SafeType public class TransposedMatrix<T>(public val origin: Matrix<T>) : Matrix<T> { + override val type: SafeType<T> get() = origin.type + override val rowNum: Int get() = origin.colNum + override val colNum: Int get() = origin.rowNum override fun get(i: Int, j: Int): T = origin[j, i] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt index 97de82c7a..9cb7c5771 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.linear import space.kscience.attributes.Attributes +import space.kscience.attributes.SafeType import space.kscience.kmath.nd.ShapeND @@ -14,7 +15,8 @@ import space.kscience.kmath.nd.ShapeND * * @property generator the function that provides elements. */ -public class VirtualMatrix<out T : Any>( +public class VirtualMatrix<out T>( + override val type: SafeType<T>, override val rowNum: Int, override val colNum: Int, override val attributes: Attributes = Attributes.EMPTY, @@ -29,4 +31,4 @@ public class VirtualMatrix<out T : Any>( public fun <T : Any> MatrixBuilder<T, *>.virtual( attributes: Attributes = Attributes.EMPTY, generator: (i: Int, j: Int) -> T, -): VirtualMatrix<T> = VirtualMatrix(rows, columns, attributes, generator) +): VirtualMatrix<T> = VirtualMatrix(type, rows, columns, attributes, generator) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt index 5bb35edef..8787d0e09 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt @@ -3,13 +3,11 @@ * 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(UnstableKMathAPI::class) @file:Suppress("UnusedReceiverParameter") package space.kscience.kmath.linear import space.kscience.attributes.* -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureAttribute /** @@ -51,9 +49,11 @@ public val <T> MatrixOperations<T>.Inverted: Inverted<T> get() = Inverted(safeTy * * @param T the type of matrices' items. */ -public class Determinant<T> : MatrixAttribute<T> +public class Determinant<T>(type: SafeType<T>) : + PolymorphicAttribute<T>(type), + MatrixAttribute<T> -public val <T> MatrixOperations<T>.Determinant: Determinant<T> get() = Determinant() +public val <T> MatrixOperations<T>.Determinant: Determinant<T> get() = Determinant(type) /** * Matrices with this feature are lower triangular ones. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt index f369f0614..0c0ef82fb 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt @@ -4,6 +4,8 @@ */ +@file:OptIn(UnstableKMathAPI::class) + package space.kscience.kmath.misc import space.kscience.kmath.UnstableKMathAPI @@ -22,10 +24,9 @@ public fun <V : Comparable<V>> Buffer<V>.indicesSorted(): IntArray = permSortInd /** * Create a zero-copy virtual buffer that contains the same elements but in ascending order */ -@OptIn(UnstableKMathAPI::class) public fun <V : Comparable<V>> Buffer<V>.sorted(): Buffer<V> { val permutations = indicesSorted() - return VirtualBuffer(size) { this[permutations[it]] } + return VirtualBuffer(type, size) { this[permutations[it]] } } @UnstableKMathAPI @@ -35,30 +36,27 @@ public fun <V : Comparable<V>> Buffer<V>.indicesSortedDescending(): IntArray = /** * Create a zero-copy virtual buffer that contains the same elements but in descending order */ -@OptIn(UnstableKMathAPI::class) public fun <V : Comparable<V>> Buffer<V>.sortedDescending(): Buffer<V> { val permutations = indicesSortedDescending() - return VirtualBuffer(size) { this[permutations[it]] } + return VirtualBuffer(type, size) { this[permutations[it]] } } @UnstableKMathAPI public fun <V, C : Comparable<C>> Buffer<V>.indicesSortedBy(selector: (V) -> C): IntArray = permSortIndicesWith(compareBy { selector(get(it)) }) -@OptIn(UnstableKMathAPI::class) public fun <V, C : Comparable<C>> Buffer<V>.sortedBy(selector: (V) -> C): Buffer<V> { val permutations = indicesSortedBy(selector) - return VirtualBuffer(size) { this[permutations[it]] } + return VirtualBuffer(type, size) { this[permutations[it]] } } @UnstableKMathAPI public fun <V, C : Comparable<C>> Buffer<V>.indicesSortedByDescending(selector: (V) -> C): IntArray = permSortIndicesWith(compareByDescending { selector(get(it)) }) -@OptIn(UnstableKMathAPI::class) public fun <V, C : Comparable<C>> Buffer<V>.sortedByDescending(selector: (V) -> C): Buffer<V> { val permutations = indicesSortedByDescending(selector) - return VirtualBuffer(size) { this[permutations[it]] } + return VirtualBuffer(type, size) { this[permutations[it]] } } @UnstableKMathAPI @@ -68,10 +66,9 @@ public fun <V> Buffer<V>.indicesSortedWith(comparator: Comparator<V>): IntArray /** * Create virtual zero-copy buffer with elements sorted by [comparator] */ -@OptIn(UnstableKMathAPI::class) public fun <V> Buffer<V>.sortedWith(comparator: Comparator<V>): Buffer<V> { val permutations = indicesSortedWith(comparator) - return VirtualBuffer(size) { this[permutations[it]] } + return VirtualBuffer(type,size) { this[permutations[it]] } } private fun <V> Buffer<V>.permSortIndicesWith(comparator: Comparator<Int>): IntArray { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt index 0611225c1..88aa52387 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.nd import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* -import kotlin.reflect.KClass +import space.kscience.kmath.structures.MutableBufferFactory /** * The base interface for all ND-algebra implementations. @@ -91,6 +91,8 @@ public interface AlgebraND<T, out C : Algebra<T>> : Algebra<StructureND<T>> { * @param A the type of group over structure elements. */ public interface GroupOpsND<T, out A : GroupOps<T>> : GroupOps<StructureND<T>>, AlgebraND<T, A> { + override val bufferFactory: MutableBufferFactory<StructureND<T>> get() = MutableBufferFactory<StructureND<T>>() + /** * Element-wise addition. * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt index 78bc83826..365d013f9 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt @@ -7,6 +7,8 @@ package space.kscience.kmath.nd +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* @@ -105,6 +107,9 @@ public open class BufferedGroupNDOps<T, out A : Group<T>>( override val bufferAlgebra: BufferAlgebra<T, A>, override val indexerBuilder: (ShapeND) -> ShapeIndexer = BufferAlgebraND.defaultIndexerBuilder, ) : GroupOpsND<T, A>, BufferAlgebraND<T, A> { + + override val type: SafeType<StructureND<T>> get() = safeTypeOf<StructureND<T>>() + override fun StructureND<T>.unaryMinus(): StructureND<T> = map { -it } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt index 461a82e0a..1caf0c662 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.nd +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory @@ -23,6 +24,8 @@ public open class BufferND<out T>( public open val buffer: Buffer<T>, ) : StructureND<T> { + override val type: SafeType<T> get() = buffer.type + @PerformancePitfall override operator fun get(index: IntArray): T = buffer[indices.offset(index)] @@ -36,7 +39,7 @@ public open class BufferND<out T>( */ public inline fun <reified T> BufferND( shape: ShapeND, - bufferFactory: BufferFactory<T> = BufferFactory.auto<T>(), + bufferFactory: BufferFactory<T> = BufferFactory<T>(), crossinline initializer: (IntArray) -> T, ): BufferND<T> { val strides = Strides(shape) @@ -84,10 +87,10 @@ public open class MutableBufferND<T>( /** * Create a generic [BufferND] using provided [initializer] */ -public fun <T> MutableBufferND( +public inline fun <reified T> MutableBufferND( shape: ShapeND, - bufferFactory: MutableBufferFactory<T> = MutableBufferFactory.boxing(), - initializer: (IntArray) -> T, + bufferFactory: MutableBufferFactory<T> = MutableBufferFactory(), + crossinline initializer: (IntArray) -> T, ): MutableBufferND<T> { val strides = Strides(shape) return MutableBufferND(strides, bufferFactory(strides.linearSize) { initializer(strides.index(it)) }) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt index 6c35e2f44..56ccf2df8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.nd +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall @@ -13,6 +14,8 @@ public class PermutedStructureND<T>( public val permutation: (IntArray) -> IntArray, ) : StructureND<T> { + override val type: SafeType<T> get() = origin.type + override val shape: ShapeND get() = origin.shape @@ -32,6 +35,7 @@ public class PermutedMutableStructureND<T>( public val permutation: (IntArray) -> IntArray, ) : MutableStructureND<T> { + override val type: SafeType<T> get() = origin.type @OptIn(PerformancePitfall::class) override fun set(index: IntArray, value: T) { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt index 984b5ad0f..ee9eff8dc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.nd +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.operations.asSequence import space.kscience.kmath.structures.Buffer @@ -46,6 +47,9 @@ public interface MutableStructure1D<T> : Structure1D<T>, MutableStructureND<T>, */ @JvmInline private value class Structure1DWrapper<out T>(val structure: StructureND<T>) : Structure1D<T> { + + override val type: SafeType<T> get() = structure.type + override val shape: ShapeND get() = structure.shape override val size: Int get() = structure.shape[0] @@ -60,6 +64,9 @@ private value class Structure1DWrapper<out T>(val structure: StructureND<T>) : S * A 1D wrapper for a mutable nd-structure */ private class MutableStructure1DWrapper<T>(val structure: MutableStructureND<T>) : MutableStructure1D<T> { + + override val type: SafeType<T> get() = structure.type + override val shape: ShapeND get() = structure.shape override val size: Int get() = structure.shape[0] @@ -79,7 +86,7 @@ private class MutableStructure1DWrapper<T>(val structure: MutableStructureND<T>) .elements() .map(Pair<IntArray, T>::second) .toMutableList() - .asMutableBuffer() + .asMutableBuffer(type) override fun toString(): String = Buffer.toString(this) } @@ -90,6 +97,9 @@ private class MutableStructure1DWrapper<T>(val structure: MutableStructureND<T>) */ @JvmInline private value class Buffer1DWrapper<out T>(val buffer: Buffer<T>) : Structure1D<T> { + + override val type: SafeType<T> get() = buffer.type + override val shape: ShapeND get() = ShapeND(buffer.size) override val size: Int get() = buffer.size @@ -102,6 +112,9 @@ private value class Buffer1DWrapper<out T>(val buffer: Buffer<T>) : Structure1D< } internal class MutableBuffer1DWrapper<T>(val buffer: MutableBuffer<T>) : MutableStructure1D<T> { + + override val type: SafeType<T> get() = buffer.type + override val shape: ShapeND get() = ShapeND(buffer.size) override val size: Int get() = buffer.size diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index eff58acc3..49e8c7dd7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -6,13 +6,12 @@ package space.kscience.kmath.nd import space.kscience.attributes.Attributes +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer -import space.kscience.kmath.structures.MutableListBuffer import space.kscience.kmath.structures.VirtualBuffer import kotlin.jvm.JvmInline -import kotlin.reflect.KClass /** * A structure that is guaranteed to be two-dimensional. @@ -33,18 +32,18 @@ public interface Structure2D<out T> : StructureND<T> { override val shape: ShapeND get() = ShapeND(rowNum, colNum) /** - * The buffer of rows of this structure. It gets elements from the structure dynamically. + * The buffer of rows for this structure. It gets elements from the structure dynamically. */ @PerformancePitfall public val rows: List<Buffer<T>> - get() = List(rowNum) { i -> VirtualBuffer(colNum) { j -> get(i, j) } } + get() = List(rowNum) { i -> VirtualBuffer(type, colNum) { j -> get(i, j) } } /** - * The buffer of columns of this structure. It gets elements from the structure dynamically. + * The buffer of columns for this structure. It gets elements from the structure dynamically. */ @PerformancePitfall public val columns: List<Buffer<T>> - get() = List(colNum) { j -> VirtualBuffer(rowNum) { i -> get(i, j) } } + get() = List(colNum) { j -> VirtualBuffer(type, rowNum) { i -> get(i, j) } } /** * Retrieves an element from the structure by two indices. @@ -88,14 +87,14 @@ public interface MutableStructure2D<T> : Structure2D<T>, MutableStructureND<T> { */ @PerformancePitfall override val rows: List<MutableBuffer<T>> - get() = List(rowNum) { i -> MutableListBuffer(colNum) { j -> get(i, j) } } + get() = List(rowNum) { i -> MutableBuffer(type, colNum) { j -> get(i, j) } } /** - * The buffer of columns of this structure. It gets elements from the structure dynamically. + * The buffer of columns for this structure. It gets elements from the structure dynamically. */ @PerformancePitfall override val columns: List<MutableBuffer<T>> - get() = List(colNum) { j -> MutableListBuffer(rowNum) { i -> get(i, j) } } + get() = List(colNum) { j -> MutableBuffer(type, rowNum) { i -> get(i, j) } } } /** @@ -103,6 +102,9 @@ public interface MutableStructure2D<T> : Structure2D<T>, MutableStructureND<T> { */ @JvmInline private value class Structure2DWrapper<out T>(val structure: StructureND<T>) : Structure2D<T> { + + override val type: SafeType<T> get() = structure.type + override val shape: ShapeND get() = structure.shape override val rowNum: Int get() = shape[0] @@ -122,6 +124,9 @@ private value class Structure2DWrapper<out T>(val structure: StructureND<T>) : S * A 2D wrapper for a mutable nd-structure */ private class MutableStructure2DWrapper<T>(val structure: MutableStructureND<T>) : MutableStructure2D<T> { + + override val type: SafeType<T> get() = structure.type + override val shape: ShapeND get() = structure.shape override val rowNum: Int get() = shape[0] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index bc86f62ae..d0d078609 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -12,6 +12,7 @@ import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.operations.Ring +import space.kscience.kmath.operations.WithType import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer import kotlin.jvm.JvmName @@ -28,9 +29,9 @@ public interface StructureAttribute<T> : Attribute<T> * * @param T the type of items. */ -public interface StructureND<out T> : AttributeContainer, WithShape { +public interface StructureND<out T> : AttributeContainer, WithShape, WithType<T> { /** - * The shape of structure i.e., non-empty sequence of non-negative integers that specify sizes of dimensions of + * The shape of structure i.e., non-empty sequence of non-negative integers that specify sizes of dimensions for * this structure. */ override val shape: ShapeND @@ -117,57 +118,61 @@ public interface StructureND<out T> : AttributeContainer, WithShape { return "$className(shape=${structure.shape}, buffer=$bufferRepr)" } - /** - * Creates a NDStructure with explicit buffer factory. - * - * Strides should be reused if possible. - */ - public fun <T> buffered( - strides: Strides, - initializer: (IntArray) -> T, - ): BufferND<T> = BufferND(strides, Buffer.boxing(strides.linearSize) { i -> initializer(strides.index(i)) }) - - - public fun <T> buffered( - shape: ShapeND, - initializer: (IntArray) -> T, - ): BufferND<T> = buffered(ColumnStrides(shape), initializer) - - /** - * Inline create NDStructure with non-boxing buffer implementation if it is possible - */ - public inline fun <reified T : Any> auto( - strides: Strides, - crossinline initializer: (IntArray) -> T, - ): BufferND<T> = BufferND(strides, Buffer.auto(strides.linearSize) { i -> initializer(strides.index(i)) }) - - public inline fun <T : Any> auto( - type: SafeType<T>, - strides: Strides, - crossinline initializer: (IntArray) -> T, - ): BufferND<T> = BufferND(strides, Buffer.auto(type, strides.linearSize) { i -> initializer(strides.index(i)) }) - - - public inline fun <reified T : Any> auto( - shape: ShapeND, - crossinline initializer: (IntArray) -> T, - ): BufferND<T> = auto(ColumnStrides(shape), initializer) - - @JvmName("autoVarArg") - public inline fun <reified T : Any> auto( - vararg shape: Int, - crossinline initializer: (IntArray) -> T, - ): BufferND<T> = - auto(ColumnStrides(ShapeND(shape)), initializer) - - public inline fun <T : Any> auto( - type: SafeType<T>, - vararg shape: Int, - crossinline initializer: (IntArray) -> T, - ): BufferND<T> = auto(type, ColumnStrides(ShapeND(shape)), initializer) } } + +/** + * Creates a NDStructure with explicit buffer factory. + * + * Strides should be reused if possible. + */ +public fun <T> BufferND( + type: SafeType<T>, + strides: Strides, + initializer: (IntArray) -> T, +): BufferND<T> = BufferND(strides, Buffer(type, strides.linearSize) { i -> initializer(strides.index(i)) }) + + +public fun <T> BufferND( + type: SafeType<T>, + shape: ShapeND, + initializer: (IntArray) -> T, +): BufferND<T> = BufferND(type, ColumnStrides(shape), initializer) + +/** + * Inline create NDStructure with non-boxing buffer implementation if it is possible + */ +public inline fun <reified T : Any> BufferND( + strides: Strides, + crossinline initializer: (IntArray) -> T, +): BufferND<T> = BufferND(strides, Buffer(strides.linearSize) { i -> initializer(strides.index(i)) }) + +public inline fun <T : Any> BufferND( + type: SafeType<T>, + strides: Strides, + crossinline initializer: (IntArray) -> T, +): BufferND<T> = BufferND(strides, Buffer(type, strides.linearSize) { i -> initializer(strides.index(i)) }) + + +public inline fun <reified T : Any> BufferND( + shape: ShapeND, + crossinline initializer: (IntArray) -> T, +): BufferND<T> = BufferND(ColumnStrides(shape), initializer) + +@JvmName("autoVarArg") +public inline fun <reified T : Any> BufferND( + vararg shape: Int, + crossinline initializer: (IntArray) -> T, +): BufferND<T> = BufferND(ColumnStrides(ShapeND(shape)), initializer) + +public inline fun <T : Any> BufferND( + type: SafeType<T>, + vararg shape: Int, + crossinline initializer: (IntArray) -> T, +): BufferND<T> = BufferND(type, ColumnStrides(ShapeND(shape)), initializer) + + /** * Indicates whether some [StructureND] is equal to another one. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt index 606b9a631..824d82b06 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt @@ -5,10 +5,13 @@ package space.kscience.kmath.nd +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI public open class VirtualStructureND<T>( + override val type: SafeType<T>, override val shape: ShapeND, public val producer: (IntArray) -> T, ) : StructureND<T> { @@ -24,10 +27,10 @@ public open class VirtualStructureND<T>( public class VirtualDoubleStructureND( shape: ShapeND, producer: (IntArray) -> Double, -) : VirtualStructureND<Double>(shape, producer) +) : VirtualStructureND<Double>(safeTypeOf(), shape, producer) @UnstableKMathAPI public class VirtualIntStructureND( shape: ShapeND, producer: (IntArray) -> Int, -) : VirtualStructureND<Int>(shape, producer) \ No newline at end of file +) : VirtualStructureND<Int>(safeTypeOf(), shape, producer) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt index 40db5187f..0376da116 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt @@ -10,7 +10,7 @@ import space.kscience.kmath.PerformancePitfall @OptIn(PerformancePitfall::class) 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 -> + return VirtualStructureND(type, shape) { index -> val newIndex: IntArray = IntArray(index.size) { indexAxis -> if (indexAxis == axis) { (index[indexAxis] + step).mod(shape[indexAxis]) @@ -26,7 +26,7 @@ public fun <T> StructureND<T>.roll(axis: Int, step: Int = 1): StructureND<T> { 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 -> + return VirtualStructureND(type, shape) { index -> val newIndex: IntArray = IntArray(index.size) { indexAxis -> val offset = axisMap[indexAxis] ?: 0 (index[indexAxis] + offset).mod(shape[indexAxis]) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt index ca8a4f59d..44e9a0b17 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt @@ -5,22 +5,32 @@ package space.kscience.kmath.operations +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.operations.Ring.Companion.optimizedPower import space.kscience.kmath.structures.MutableBufferFactory -import kotlin.reflect.KType + +/** + * An interface containing [type] for dynamic type checking. + */ +public interface WithType<out T> { + public val type: SafeType<T> +} + /** * Represents an algebraic structure. * * @param T the type of element which Algebra operates on. */ -public interface Algebra<T> { +public interface Algebra<T> : WithType<T> { /** * Provide a factory for buffers, associated with this [Algebra] */ - public val bufferFactory: MutableBufferFactory<T> get() = MutableBufferFactory.boxing() + public val bufferFactory: MutableBufferFactory<T> + + override val type: SafeType<T> get() = bufferFactory.type /** * Wraps a raw string to [T] object. This method is designed for three purposes: @@ -265,7 +275,7 @@ public interface Ring<T> : Group<T>, RingOps<T> { */ public fun power(arg: T, pow: UInt): T = optimizedPower(arg, pow) - public companion object{ + public companion object { /** * Raises [arg] to the non-negative integer power [exponent]. * @@ -348,7 +358,7 @@ public interface Field<T> : Ring<T>, FieldOps<T>, ScaleOperations<T>, NumericAlg public fun power(arg: T, pow: Int): T = optimizedPower(arg, pow) - public companion object{ + public companion object { /** * Raises [arg] to the integer power [exponent]. * @@ -361,7 +371,11 @@ public interface Field<T> : Ring<T>, FieldOps<T>, ScaleOperations<T>, NumericAlg * @author Iaroslav Postovalov, Evgeniy Zhelenskiy */ private fun <T> Field<T>.optimizedPower(arg: T, exponent: Int): T = when { - exponent < 0 -> one / (this as Ring<T>).optimizedPower(arg, if (exponent == Int.MIN_VALUE) Int.MAX_VALUE.toUInt().inc() else (-exponent).toUInt()) + exponent < 0 -> one / (this as Ring<T>).optimizedPower( + arg, + if (exponent == Int.MIN_VALUE) Int.MAX_VALUE.toUInt().inc() else (-exponent).toUInt() + ) + else -> (this as Ring<T>).optimizedPower(arg, exponent.toUInt()) } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt index 34a6d4a80..25554477c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.operations +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.BufferedRingOpsND import space.kscience.kmath.operations.BigInt.Companion.BASE @@ -26,6 +28,9 @@ private typealias TBase = ULong */ @OptIn(UnstableKMathAPI::class) public object BigIntField : Field<BigInt>, NumbersAddOps<BigInt>, ScaleOperations<BigInt> { + + override val type: SafeType<BigInt> = safeTypeOf() + override val zero: BigInt = BigInt.ZERO override val one: BigInt = BigInt.ONE @@ -528,10 +533,10 @@ public fun String.parseBigInteger(): BigInt? { public val BigInt.algebra: BigIntField get() = BigIntField public inline fun BigInt.Companion.buffer(size: Int, initializer: (Int) -> BigInt): Buffer<BigInt> = - Buffer.boxing(size, initializer) + Buffer(size, initializer) public inline fun BigInt.Companion.mutableBuffer(size: Int, initializer: (Int) -> BigInt): Buffer<BigInt> = - Buffer.boxing(size, initializer) + Buffer(size, initializer) public val BigIntField.nd: BufferedRingOpsND<BigInt, BigIntField> get() = BufferedRingOpsND(BufferRingOps(BigIntField)) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index 526d024ca..5a8b26571 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -5,10 +5,11 @@ package space.kscience.kmath.operations +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.MutableBufferFactory -import kotlin.reflect.KType public interface WithSize { public val size: Int @@ -20,6 +21,8 @@ public interface WithSize { public interface BufferAlgebra<T, out A : Algebra<T>> : Algebra<Buffer<T>> { public val elementAlgebra: A + override val type: SafeType<Buffer<T>> get() = safeTypeOf<Buffer<T>>() + public val elementBufferFactory: MutableBufferFactory<T> get() = elementAlgebra.bufferFactory public fun buffer(size: Int, vararg elements: T): Buffer<T> { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt index d8bf0fb57..312fd1396 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.operations +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol @@ -72,6 +74,8 @@ public interface LogicAlgebra<T : Any> : Algebra<T> { @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object BooleanAlgebra : LogicAlgebra<Boolean> { + override val type: SafeType<Boolean> get() = safeTypeOf() + override fun const(boolean: Boolean): Boolean = boolean override fun Boolean.not(): Boolean = !this diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt index 72e33c523..a3a819a9b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt @@ -8,7 +8,10 @@ package space.kscience.kmath.operations import space.kscience.kmath.operations.Int16Field.div import space.kscience.kmath.operations.Int32Field.div import space.kscience.kmath.operations.Int64Field.div -import space.kscience.kmath.structures.* +import space.kscience.kmath.structures.Int16 +import space.kscience.kmath.structures.Int32 +import space.kscience.kmath.structures.Int64 +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.roundToInt import kotlin.math.roundToLong @@ -22,7 +25,7 @@ import kotlin.math.roundToLong */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int16Field : Field<Int16>, Norm<Int16, Int16>, NumericAlgebra<Int16> { - override val bufferFactory: MutableBufferFactory<Int16> = MutableBufferFactory(::Int16Buffer) + override val bufferFactory: MutableBufferFactory<Int16> = MutableBufferFactory<Int16>() override val zero: Int16 get() = 0 override val one: Int16 get() = 1 @@ -45,7 +48,8 @@ public object Int16Field : Field<Int16>, Norm<Int16, Int16>, NumericAlgebra<Int1 */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int32Field : Field<Int32>, Norm<Int32, Int32>, NumericAlgebra<Int32> { - override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::Int32Buffer) + override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory() + override val zero: Int get() = 0 override val one: Int get() = 1 @@ -68,7 +72,7 @@ public object Int32Field : Field<Int32>, Norm<Int32, Int32>, NumericAlgebra<Int3 */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int64Field : Field<Int64>, Norm<Int64, Int64>, NumericAlgebra<Int64> { - override val bufferFactory: MutableBufferFactory<Int64> = MutableBufferFactory(::Int64Buffer) + override val bufferFactory: MutableBufferFactory<Int64> = MutableBufferFactory() override val zero: Int64 get() = 0L override val one: Int64 get() = 1L diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt index 0b7bef852..7d8e12139 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt @@ -67,7 +67,7 @@ public interface ExtendedField<T> : ExtendedFieldOps<T>, Field<T>, NumericAlgebr */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Float64Field : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> { - override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory(::Float64Buffer) + override val bufferFactory: MutableBufferFactory<Double> = MutableBufferFactory() override val zero: Double get() = 0.0 override val one: Double get() = 1.0 diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index 91baac2bf..c3dbfbfe2 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -8,8 +8,8 @@ package space.kscience.kmath.structures import space.kscience.attributes.SafeType import space.kscience.attributes.safeTypeOf import space.kscience.kmath.operations.WithSize +import space.kscience.kmath.operations.WithType import space.kscience.kmath.operations.asSequence -import kotlin.jvm.JvmInline import kotlin.reflect.typeOf /** @@ -17,35 +17,46 @@ import kotlin.reflect.typeOf * * @param T the type of buffer. */ -public fun interface BufferFactory<T> { +public interface BufferFactory<T> : WithType<T> { + public operator fun invoke(size: Int, builder: (Int) -> T): Buffer<T> - - public companion object{ - public inline fun <reified T> auto(): BufferFactory<T> = - BufferFactory(Buffer.Companion::auto) - - public fun <T> boxing(): BufferFactory<T> = - BufferFactory(Buffer.Companion::boxing) - } } +/** + * Create a [BufferFactory] for given [type], using primitive storage if possible + */ +public fun <T> BufferFactory(type: SafeType<T>): BufferFactory<T> = object : BufferFactory<T> { + override val type: SafeType<T> = type + override fun invoke(size: Int, builder: (Int) -> T): Buffer<T> = Buffer(type, size, builder) +} + +/** + * Create [BufferFactory] using the reified type + */ +public inline fun <reified T> BufferFactory(): BufferFactory<T> = BufferFactory(safeTypeOf()) + /** * Function that produces [MutableBuffer] from its size and function that supplies values. * * @param T the type of buffer. */ -public fun interface MutableBufferFactory<T> : BufferFactory<T> { +public interface MutableBufferFactory<T> : BufferFactory<T> { override fun invoke(size: Int, builder: (Int) -> T): MutableBuffer<T> - - public companion object { - public inline fun <reified T : Any> auto(): MutableBufferFactory<T> = - MutableBufferFactory(MutableBuffer.Companion::auto) - - public fun <T> boxing(): MutableBufferFactory<T> = - MutableBufferFactory(MutableBuffer.Companion::boxing) - } } +/** + * Create a [MutableBufferFactory] for given [type], using primitive storage if possible + */ +public fun <T> MutableBufferFactory(type: SafeType<T>): MutableBufferFactory<T> = object : MutableBufferFactory<T> { + override val type: SafeType<T> = type + override fun invoke(size: Int, builder: (Int) -> T): MutableBuffer<T> = MutableBuffer(type, size, builder) +} + +/** + * Create [BufferFactory] using the reified type + */ +public inline fun <reified T> MutableBufferFactory(): MutableBufferFactory<T> = MutableBufferFactory(safeTypeOf()) + /** * A generic read-only random-access structure for both primitives and objects. * @@ -53,14 +64,14 @@ public fun interface MutableBufferFactory<T> : BufferFactory<T> { * * @param T the type of elements contained in the buffer. */ -public interface Buffer<out T> : WithSize { +public interface Buffer<out T> : WithSize, WithType<T> { /** * The size of this buffer. */ override val size: Int /** - * Gets element at given index. + * Gets an element at given index. */ public operator fun get(index: Int): T @@ -87,41 +98,48 @@ public interface Buffer<out T> : WithSize { return true } - /** - * Creates a [ListBuffer] of given type [T] with given [size]. Each element is calculated by calling the - * specified [initializer] function. - */ - public inline fun <T> boxing(size: Int, initializer: (Int) -> T): Buffer<T> = - List(size, initializer).asBuffer() - - /** - * Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([Int32Buffer], - * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. - * - * The [size] is specified, and each element is calculated by calling the specified [initializer] function. - */ - @Suppress("UNCHECKED_CAST") - public inline fun <T> auto(type: SafeType<T>, size: Int, initializer: (Int) -> T): Buffer<T> = - when (type.kType) { - typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T> - typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T> - typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> - typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> - typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> - else -> boxing(size, initializer) - } - - /** - * Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([Int32Buffer], - * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. - * - * The [size] is specified, and each element is calculated by calling the specified [initializer] function. - */ - public inline fun <reified T> auto(size: Int, initializer: (Int) -> T): Buffer<T> = - auto(safeTypeOf<T>(), size, initializer) } } +/** + * Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([Int32Buffer], + * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. + */ +@Suppress("UNCHECKED_CAST") +public inline fun <reified T> Buffer(size: Int, initializer: (Int) -> T): Buffer<T> { + val type = safeTypeOf<T>() + return when (type.kType) { + typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T> + typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T> + typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> + typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> + typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> + else -> List(size, initializer).asBuffer(type) + } +} + +/** + * Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([Int32Buffer], + * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. + */ +@Suppress("UNCHECKED_CAST") +public fun <T> Buffer( + type: SafeType<T>, + size: Int, + initializer: (Int) -> T, +): Buffer<T> = when (type.kType) { + typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T> + typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T> + typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> + typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> + typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> + else -> List(size, initializer).asBuffer(type) +} + /** * Returns an [IntRange] of the valid indices for this [Buffer]. */ @@ -144,28 +162,17 @@ public fun <T> Buffer<T>.last(): T { return get(size - 1) } -/** - * Immutable wrapper for [MutableBuffer]. - * - * @param T the type of elements contained in the buffer. - * @property buffer The underlying buffer. - */ -@JvmInline -public value class ReadOnlyBuffer<T>(public val buffer: MutableBuffer<T>) : Buffer<T> { - override val size: Int get() = buffer.size - - override operator fun get(index: Int): T = buffer[index] - - override operator fun iterator(): Iterator<T> = buffer.iterator() -} - /** * A buffer with content calculated on-demand. The calculated content is not stored, so it is recalculated on each call. - * Useful when one needs single element from the buffer. + * Useful when one needs a single element from the buffer. * * @param T the type of elements provided by the buffer. */ -public class VirtualBuffer<out T>(override val size: Int, private val generator: (Int) -> T) : Buffer<T> { +public class VirtualBuffer<out T>( + override val type: SafeType<T>, + override val size: Int, + private val generator: (Int) -> T, +) : Buffer<T> { override operator fun get(index: Int): T { if (index < 0 || index >= size) throw IndexOutOfBoundsException("Expected index from 0 to ${size - 1}, but found $index") return generator(index) @@ -177,6 +184,9 @@ public class VirtualBuffer<out T>(override val size: Int, private val generator: } /** - * Convert this buffer to read-only buffer. + * Inline builder for [VirtualBuffer] */ -public fun <T> Buffer<T>.asReadOnly(): Buffer<T> = if (this is MutableBuffer) ReadOnlyBuffer(this) else this \ No newline at end of file +public inline fun <reified T> VirtualBuffer( + size: Int, + noinline generator: (Int) -> T, +): VirtualBuffer<T> = VirtualBuffer(safeTypeOf(), size, generator) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt index 3edd7d3b1..a2f01137c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt @@ -5,7 +5,13 @@ package space.kscience.kmath.structures -import space.kscience.kmath.nd.* +import space.kscience.attributes.SafeType +import space.kscience.kmath.nd.BufferND +import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.nd.Structure2D +import space.kscience.kmath.nd.as2D +import kotlin.collections.component1 +import kotlin.collections.component2 /** * A context that allows to operate on a [MutableBuffer] as on 2d array @@ -27,11 +33,13 @@ internal class BufferAccessor2D<T>( fun create(mat: Structure2D<T>): MutableBuffer<T> = create { i, j -> mat[i, j] } //TODO optimize wrapper - fun MutableBuffer<T>.toStructure2D(): Structure2D<T> = StructureND.buffered( - ColumnStrides(ShapeND(rowNum, colNum)) + fun MutableBuffer<T>.toStructure2D(): Structure2D<T> = BufferND( + type, ShapeND(rowNum, colNum) ) { (i, j) -> get(i, j) }.as2D() inner class Row(val buffer: MutableBuffer<T>, val rowIndex: Int) : MutableBuffer<T> { + override val type: SafeType<T> get() = buffer.type + override val size: Int get() = colNum override operator fun get(index: Int): T = buffer[rowIndex, index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt index d99e02996..10419a074 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import kotlin.experimental.and /** @@ -57,6 +59,9 @@ public class FlaggedDoubleBuffer( public val values: DoubleArray, public val flags: ByteArray ) : FlaggedBuffer<Double?>, Buffer<Double?> { + + override val type: SafeType<Double?> = safeTypeOf() + init { require(values.size == flags.size) { "Values and flags must have the same dimensions" } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt index 44ef4dcf0..b8fbe3436 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -15,6 +17,9 @@ import kotlin.jvm.JvmInline */ @JvmInline public value class Float32Buffer(public val array: FloatArray) : PrimitiveBuffer<Float> { + + override val type: SafeType<Float32> get() = safeTypeOf<Float32>() + override val size: Int get() = array.size override operator fun get(index: Int): Float = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt index 0542c1bf4..5837adf83 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.operations.BufferTransform import kotlin.jvm.JvmInline @@ -15,6 +17,9 @@ import kotlin.jvm.JvmInline */ @JvmInline public value class Float64Buffer(public val array: DoubleArray) : PrimitiveBuffer<Double> { + + override val type: SafeType<Double> get() = safeTypeOf() + override val size: Int get() = array.size override operator fun get(index: Int): Double = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt index 1ba40c934..cf3af61a7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -14,6 +16,8 @@ import kotlin.jvm.JvmInline */ @JvmInline public value class Int16Buffer(public val array: ShortArray) : MutableBuffer<Short> { + + override val type: SafeType<Short> get() = safeTypeOf() override val size: Int get() = array.size override operator fun get(index: Int): Short = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt index afd94e9cd..365ec8688 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -14,6 +16,9 @@ import kotlin.jvm.JvmInline */ @JvmInline public value class Int32Buffer(public val array: IntArray) : PrimitiveBuffer<Int> { + + override val type: SafeType<Int> get() = safeTypeOf() + override val size: Int get() = array.size override operator fun get(index: Int): Int = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt index c67d109aa..5f831ed3e 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -14,6 +16,9 @@ import kotlin.jvm.JvmInline */ @JvmInline public value class Int64Buffer(public val array: LongArray) : PrimitiveBuffer<Long> { + + override val type: SafeType<Long> get() = safeTypeOf() + override val size: Int get() = array.size override operator fun get(index: Int): Long = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt index 923fbec06..e61056979 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -14,6 +16,9 @@ import kotlin.jvm.JvmInline */ @JvmInline public value class Int8Buffer(public val array: ByteArray) : MutableBuffer<Byte> { + + override val type: SafeType<Byte> get() = safeTypeOf() + override val size: Int get() = array.size override operator fun get(index: Int): Byte = array[index] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt index fbc9a489b..ad065a0c3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt @@ -5,7 +5,8 @@ package space.kscience.kmath.structures -import kotlin.jvm.JvmInline +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf /** * [Buffer] implementation over [List]. @@ -13,9 +14,7 @@ import kotlin.jvm.JvmInline * @param T the type of elements contained in the buffer. * @property list The underlying list. */ -public class ListBuffer<T>(public val list: List<T>) : Buffer<T> { - - public constructor(size: Int, initializer: (Int) -> T) : this(List(size, initializer)) +public class ListBuffer<T>(override val type: SafeType<T>, public val list: List<T>) : Buffer<T> { override val size: Int get() = list.size @@ -29,7 +28,12 @@ public class ListBuffer<T>(public val list: List<T>) : Buffer<T> { /** * Returns an [ListBuffer] that wraps the original list. */ -public fun <T> List<T>.asBuffer(): ListBuffer<T> = ListBuffer(this) +public fun <T> List<T>.asBuffer(type: SafeType<T>): ListBuffer<T> = ListBuffer(type, this) + +/** + * Returns an [ListBuffer] that wraps the original list. + */ +public inline fun <reified T> List<T>.asBuffer(): ListBuffer<T> = asBuffer(safeTypeOf()) /** * [MutableBuffer] implementation over [MutableList]. @@ -37,10 +41,7 @@ public fun <T> List<T>.asBuffer(): ListBuffer<T> = ListBuffer(this) * @param T the type of elements contained in the buffer. * @property list The underlying list. */ -@JvmInline -public value class MutableListBuffer<T>(public val list: MutableList<T>) : MutableBuffer<T> { - - public constructor(size: Int, initializer: (Int) -> T) : this(MutableList(size, initializer)) +public class MutableListBuffer<T>(override val type: SafeType<T>, public val list: MutableList<T>) : MutableBuffer<T> { override val size: Int get() = list.size @@ -51,10 +52,24 @@ public value class MutableListBuffer<T>(public val list: MutableList<T>) : Mutab } override operator fun iterator(): Iterator<T> = list.iterator() - override fun copy(): MutableBuffer<T> = MutableListBuffer(ArrayList(list)) + override fun copy(): MutableBuffer<T> = MutableListBuffer(type, ArrayList(list)) + + override fun toString(): String = Buffer.toString(this) } + /** * Returns an [MutableListBuffer] that wraps the original list. */ -public fun <T> MutableList<T>.asMutableBuffer(): MutableListBuffer<T> = MutableListBuffer(this) +public fun <T> MutableList<T>.asMutableBuffer(type: SafeType<T>): MutableListBuffer<T> = MutableListBuffer( + type, + this +) + +/** + * Returns an [MutableListBuffer] that wraps the original list. + */ +public inline fun <reified T> MutableList<T>.asMutableBuffer(): MutableListBuffer<T> = MutableListBuffer( + safeTypeOf(), + this +) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt index eb0074734..21d3f9c6f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt @@ -61,41 +61,35 @@ public interface MutableBuffer<T> : Buffer<T> { */ public inline fun float(size: Int, initializer: (Int) -> Float): Float32Buffer = Float32Buffer(size, initializer) - - - /** - * Create a boxing mutable buffer of given type - */ - public inline fun <T> boxing(size: Int, initializer: (Int) -> T): MutableBuffer<T> = - MutableListBuffer(MutableList(size, initializer)) - - /** - * Creates a [MutableBuffer] of given [type]. If the type is primitive, specialized buffers are used - * ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise. - * - * The [size] is specified, and each element is calculated by calling the specified [initializer] function. - */ - @Suppress("UNCHECKED_CAST") - public inline fun <T> auto(type: SafeType<T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> = - when (type.kType) { - typeOf<Double>() -> double(size) { initializer(it) as Double } as MutableBuffer<T> - typeOf<Short>() -> short(size) { initializer(it) as Short } as MutableBuffer<T> - typeOf<Int>() -> int(size) { initializer(it) as Int } as MutableBuffer<T> - typeOf<Float>() -> float(size) { initializer(it) as Float } as MutableBuffer<T> - typeOf<Long>() -> long(size) { initializer(it) as Long } as MutableBuffer<T> - else -> boxing(size, initializer) - } - - /** - * Creates a [MutableBuffer] of given type [T]. If the type is primitive, specialized buffers are used - * ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise. - * - * The [size] is specified, and each element is calculated by calling the specified [initializer] function. - */ - public inline fun <reified T> auto(size: Int, initializer: (Int) -> T): MutableBuffer<T> = - auto(safeTypeOf<T>(), size, initializer) } } +/** + * Creates a [MutableBuffer] of given [type]. If the type is primitive, specialized buffers are used + * ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. + */ +@Suppress("UNCHECKED_CAST") +public inline fun <T> MutableBuffer(type: SafeType<T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> = + when (type.kType) { + typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as MutableBuffer<T> + typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as MutableBuffer<T> + typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as MutableBuffer<T> + typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as MutableBuffer<T> + typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as MutableBuffer<T> + else -> MutableListBuffer(type, MutableList(size, initializer)) + } + +/** + * Creates a [MutableBuffer] of given type [T]. If the type is primitive, specialized buffers are used + * ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. + */ +public inline fun <reified T> MutableBuffer(size: Int, initializer: (Int) -> T): MutableBuffer<T> = + MutableBuffer(safeTypeOf<T>(), size, initializer) + + public sealed interface PrimitiveBuffer<T> : MutableBuffer<T> \ No newline at end of file diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt index 4d05f9043..17b6d69b8 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt @@ -40,7 +40,7 @@ class DoubleLUSolverTest { //Check determinant assertEquals(7.0, lup.determinant) - assertMatrixEquals(lup.p dot matrix, lup.l dot lup.u) + assertMatrixEquals(lup.pivotMatrix dot matrix, lup.l dot lup.u) } @Test diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 0cef96f49..881649d01 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,19 +19,13 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.structures.Float64 -import space.kscience.kmath.structures.Float32 -import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Float32Field -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.FloatField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.Float64Buffer -import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt index f7094f7a9..f9e2e14f2 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt @@ -147,12 +147,12 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges( bufferFactory: BufferFactory<V> = valueAlgebraND.elementAlgebra.bufferFactory, ): UniformHistogramGroupND<V, A> = UniformHistogramGroupND( valueAlgebraND, - ListBuffer( + DoubleBuffer( ranges .map(Pair<ClosedFloatingPointRange<Double>, Int>::first) .map(ClosedFloatingPointRange<Double>::start) ), - ListBuffer( + DoubleBuffer( ranges .map(Pair<ClosedFloatingPointRange<Double>, Int>::first) .map(ClosedFloatingPointRange<Double>::endInclusive) From 2386ecba41ff00e234bf5a282e71deda3ec135aa Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sat, 4 Nov 2023 11:49:31 +0300 Subject: [PATCH 060/103] 0.4 WIP --- .../space/kscience/attributes/Attributes.kt | 7 + .../space/kscience/attributes/SafeType.kt | 9 +- .../benchmarks/MatrixInverseBenchmark.kt | 2 +- .../space/kscience/kmath/ast/TestParser.kt | 3 + kmath-complex/build.gradle.kts | 1 + .../space/kscience/kmath/complex/Complex.kt | 23 +- .../kscience/kmath/complex/Quaternion.kt | 16 +- kmath-core/build.gradle.kts | 1 - .../space/kscience/kmath/annotations.kt | 0 .../kscience/kmath/expressions/DSAlgebra.kt | 2 +- .../kmath/expressions/SimpleAutoDiff.kt | 1 + .../kmath/linear/BufferedLinearSpace.kt | 3 - .../kscience/kmath/linear/LinearSpace.kt | 8 +- .../kscience/kmath/linear/LupDecomposition.kt | 210 +++++++----------- .../kscience/kmath/linear/MatrixBuilder.kt | 2 +- .../kscience/kmath/linear/MatrixWrapper.kt | 2 +- .../space/kscience/kmath/nd/StructureND.kt | 19 +- .../kscience/kmath/operations/Algebra.kt | 9 +- .../space/kscience/kmath/operations/BigInt.kt | 6 +- .../kmath/operations/BufferAlgebra.kt | 6 +- .../kscience/kmath/operations/LogicAlgebra.kt | 5 +- .../kscience/kmath/operations/numbers.kt | 12 +- .../kscience/kmath/structures/ArrayBuffer.kt | 13 +- .../space/kscience/kmath/structures/Buffer.kt | 2 +- .../kscience/kmath/structures/BufferView.kt | 7 +- .../kmath/structures/MutableBuffer.kt | 24 +- .../space/kscience/kmath/linear/MatrixTest.kt | 9 +- .../kscience/kmath/operations/BigNumbers.kt | 4 + .../kscience/kmath/chains/BlockingChain.kt | 4 +- .../kscience/kmath/streaming/BufferFlow.kt | 5 +- .../kscience/kmath/streaming/RingBuffer.kt | 42 ++-- .../kmath/structures/LazyStructureND.kt | 12 +- .../kscience/kmath/dimensions/Wrappers.kt | 10 +- .../kscience/kmath/ejml/EjmlLinearSpace.kt | 14 +- .../space/kscience/kmath/ejml/_generated.kt | 56 ++--- .../kscience/kmath/ejml/EjmlMatrixTest.kt | 2 +- .../space/kscience/kmath/real/RealMatrix.kt | 2 +- .../kscience/kmath/functions/Polynomial.kt | 5 +- .../integration/GaussIntegratorRuleFactory.kt | 5 +- .../kmath/integration/SplineIntegrator.kt | 4 +- .../kmath/interpolation/Interpolator.kt | 10 +- .../kmath/interpolation/SplineInterpolator.kt | 3 +- kmath-memory/build.gradle.kts | 4 + .../kscience/kmath/memory}/MemoryBuffer.kt | 17 +- .../space/kscience/kmath/memory/MemorySpec.kt | 5 +- 45 files changed, 297 insertions(+), 309 deletions(-) rename {kmath-memory => kmath-core}/src/commonMain/kotlin/space/kscience/kmath/annotations.kt (100%) rename {kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures => kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory}/MemoryBuffer.kt (84%) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index 705e61436..a1bccc211 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -106,4 +106,11 @@ public fun <T : Any, A : Attribute<T>> Attributes( attrValue: T, ): Attributes = Attributes(mapOf(attribute to attrValue)) +/** + * Create Attributes with a single [Unit] valued attribute + */ +public fun <A : Attribute<Unit>> Attributes( + attribute: A +): Attributes = Attributes(mapOf(attribute to Unit)) + public operator fun Attributes.plus(other: Attributes): Attributes = Attributes(content + other.content) \ No newline at end of file diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt index 0fac2477c..1c7b0991a 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt @@ -25,4 +25,11 @@ public inline fun <reified T> safeTypeOf(): SafeType<T> = SafeType(typeOf<T>()) */ @Suppress("UNCHECKED_CAST") @UnstableAttributesAPI -public val <T> SafeType<T>.kClass: KClass<T & Any> get() = kType.classifier as KClass<T & Any> \ No newline at end of file +public val <T> SafeType<T>.kClass: KClass<T & Any> get() = kType.classifier as KClass<T & Any> + +/** + * An interface containing [type] for dynamic type checking. + */ +public interface WithType<out T> { + public val type: SafeType<T> +} \ No newline at end of file diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt index f7aac8199..16e017432 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt @@ -47,7 +47,7 @@ internal class MatrixInverseBenchmark { @Benchmark fun ejmlInverse(blackhole: Blackhole) { EjmlLinearSpaceDDRM { - blackhole.consume(matrix.toEjml().inverse()) + blackhole.consume(matrix.toEjml().inverted()) } } } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt index 784dcece9..045890e71 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt @@ -10,6 +10,7 @@ import space.kscience.kmath.complex.ComplexField import space.kscience.kmath.expressions.interpret import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.test.Test import kotlin.test.assertEquals @@ -39,6 +40,8 @@ internal class TestParser { @Test fun evaluateMstBinary() { val magicalAlgebra = object : Algebra<String> { + override val bufferFactory: MutableBufferFactory<String> get() = MutableBufferFactory() + override fun bindSymbolOrNull(value: String): String = value override fun unaryOperationFunction(operation: String): (arg: String) -> String { diff --git a/kmath-complex/build.gradle.kts b/kmath-complex/build.gradle.kts index 3e8b3b75e..9ac2d5ab4 100644 --- a/kmath-complex/build.gradle.kts +++ b/kmath-complex/build.gradle.kts @@ -10,6 +10,7 @@ kscience { dependencies { api(projects.kmathCore) + api(projects.kmathMemory) } testDependencies { diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt index b5f1aabe7..3a524bbb3 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt @@ -5,12 +5,14 @@ package space.kscience.kmath.complex +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.memory.MemoryReader -import space.kscience.kmath.memory.MemorySpec -import space.kscience.kmath.memory.MemoryWriter +import space.kscience.kmath.memory.* import space.kscience.kmath.operations.* -import space.kscience.kmath.structures.* +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.MutableBuffer +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.* /** @@ -51,8 +53,11 @@ public object ComplexField : Norm<Complex, Complex>, NumbersAddOps<Complex>, ScaleOperations<Complex> { - override val bufferFactory: MutableBufferFactory<Complex> = MutableBufferFactory { size, init -> - MutableMemoryBuffer.create(Complex, size, init) + override val bufferFactory: MutableBufferFactory<Complex> = object : MutableBufferFactory<Complex> { + override fun invoke(size: Int, builder: (Int) -> Complex): MutableBuffer<Complex> = + MutableMemoryBuffer.create(Complex, size, builder) + + override val type: SafeType<Complex> = safeTypeOf() } override val zero: Complex = 0.0.toComplex() @@ -202,8 +207,10 @@ public data class Complex(val re: Double, val im: Double) { override fun toString(): String = "($re + i * $im)" public companion object : MemorySpec<Complex> { - override val objectSize: Int - get() = 16 + + override val type: SafeType<Complex> get() = safeTypeOf() + + override val objectSize: Int get() = 16 override fun MemoryReader.read(offset: Int): Complex = Complex(readDouble(offset), readDouble(offset + 8)) diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt index 8f3d15a26..f6f9e9047 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt @@ -5,15 +5,14 @@ package space.kscience.kmath.complex +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.memory.MemoryReader -import space.kscience.kmath.memory.MemorySpec -import space.kscience.kmath.memory.MemoryWriter +import space.kscience.kmath.memory.* import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.MemoryBuffer import space.kscience.kmath.structures.MutableBuffer -import space.kscience.kmath.structures.MutableMemoryBuffer +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.* /** @@ -37,6 +36,8 @@ public class Quaternion( require(!z.isNaN()) { "z-component of quaternion is not-a-number" } } + override val type: SafeType<Double> get() = safeTypeOf() + /** * Returns a string representation of this quaternion. */ @@ -78,6 +79,7 @@ public class Quaternion( public companion object : MemorySpec<Quaternion> { override val objectSize: Int get() = 32 + override val type: SafeType<Quaternion> get() = safeTypeOf() override fun MemoryReader.read(offset: Int): Quaternion = Quaternion( readDouble(offset), @@ -122,7 +124,7 @@ public val Quaternion.reciprocal: Quaternion /** * Produce a normalized version of this quaternion */ -public fun Quaternion.normalized(): Quaternion = with(QuaternionAlgebra){ this@normalized / norm(this@normalized) } +public fun Quaternion.normalized(): Quaternion = with(QuaternionAlgebra) { this@normalized / norm(this@normalized) } /** * A field of [Quaternion]. @@ -131,6 +133,8 @@ public fun Quaternion.normalized(): Quaternion = with(QuaternionAlgebra){ this@n public object QuaternionAlgebra : Group<Quaternion>, Norm<Quaternion, Double>, PowerOperations<Quaternion>, ExponentialOperations<Quaternion>, NumbersAddOps<Quaternion>, ScaleOperations<Quaternion> { + override val bufferFactory: MutableBufferFactory<Quaternion> = MutableBufferFactory() + override val zero: Quaternion = Quaternion(0.0) public val one: Quaternion = Quaternion(1.0) diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index 398465fbe..23fedbda4 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -9,7 +9,6 @@ kscience{ wasm() dependencies { - api(projects.kmathMemory) api(projects.attributesKt) } diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/annotations.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/annotations.kt similarity index 100% rename from kmath-memory/src/commonMain/kotlin/space/kscience/kmath/annotations.kt rename to kmath-core/src/commonMain/kotlin/space/kscience/kmath/annotations.kt diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt index 817f38ff0..8ef751859 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt @@ -188,7 +188,7 @@ public abstract class DSAlgebra<T, A : Ring<T>>( vararg derivatives: T, ): DS<T, A> { require(derivatives.size == compiler.size) { "dimension mismatch: ${derivatives.size} and ${compiler.size}" } - val data = derivatives.asBuffer() + val data = derivatives.asList().asBuffer(algebra.type) return DS(data) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt index 6d22b18dc..fd7bf9fdc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.expressions import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.Point import space.kscience.kmath.operations.* diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt index 6bfe7581b..4bba47a91 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt @@ -5,15 +5,12 @@ package space.kscience.kmath.linear -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.VirtualBuffer import space.kscience.kmath.structures.indices -import kotlin.reflect.KType -import kotlin.reflect.typeOf public class BufferedLinearSpace<T, out A : Ring<T>>( diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index ddf4f17d4..00ebad5ee 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -6,11 +6,11 @@ package space.kscience.kmath.linear import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.* import space.kscience.kmath.operations.BufferRingOps import space.kscience.kmath.operations.Ring -import space.kscience.kmath.operations.WithType import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer @@ -173,15 +173,15 @@ public interface LinearSpace<T, out A : Ring<T>> : MatrixOperations<T> { public operator fun T.times(v: Point<T>): Point<T> = v * this /** - * Get an attribute value for the structure in this scope. Structure features take precedence other context features. + * Get an attribute value for the structure in this scope. Structure attributes are preferred to computed attributes. * * @param structure the structure. * @param attribute to be computed. * @return a feature object or `null` if it isn't present. */ @UnstableKMathAPI - public fun <T, A : StructureAttribute<T>> attributeFor(structure: StructureND<*>, attribute: A): T? = - structure.attributes[attribute] + public fun <T, A : StructureAttribute<T>> attributeFor(structure: StructureND<*>, attribute: A): T = + structure.attributes[attribute] ?: error("Can't compute attribute $attribute for $structure") public companion object { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 1ac2ca5c6..6592a3da4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.linear +import space.kscience.attributes.Attributes import space.kscience.attributes.PolymorphicAttribute import space.kscience.attributes.SafeType import space.kscience.attributes.safeTypeOf @@ -19,32 +20,42 @@ import space.kscience.kmath.structures.* * *a* is the owning matrix. * * @param T the type of matrices' items. - * @param l The lower triangular matrix in this decomposition. It may have [LowerTriangular]. - * @param u The upper triangular matrix in this decomposition. It may have [UpperTriangular]. + * @param lu combined L and U matrix */ public class LupDecomposition<T>( public val linearSpace: LinearSpace<T, Ring<T>>, - public val l: Matrix<T>, - public val u: Matrix<T>, + private val lu: Matrix<T>, public val pivot: IntBuffer, + private val even: Boolean, ) { public val elementAlgebra: Ring<T> get() = linearSpace.elementAlgebra - public val pivotMatrix: VirtualMatrix<T> + public val l: Matrix<T> + get() = VirtualMatrix(lu.type, lu.rowNum, lu.colNum, attributes = Attributes(LowerTriangular)) { i, j -> + when { + j < i -> lu[i, j] + j == i -> elementAlgebra.one + else -> elementAlgebra.zero + } + } + + public val u: Matrix<T> + get() = VirtualMatrix(lu.type, lu.rowNum, lu.colNum, attributes = Attributes(UpperTriangular)) { i, j -> + if (j >= i) lu[i, j] else elementAlgebra.zero + } + + public val pivotMatrix: Matrix<T> get() = VirtualMatrix(linearSpace.type, l.rowNum, l.colNum) { row, column -> if (column == pivot[row]) elementAlgebra.one else elementAlgebra.zero } - public val <T> LupDecomposition<T>.determinant by lazy { + public val determinant: T by lazy { elementAlgebra { (0 until l.shape[0]).fold(if (even) one else -one) { value, i -> value * lu[i, i] } } } } - - - public class LupDecompositionAttribute<T>(type: SafeType<LupDecomposition<T>>) : PolymorphicAttribute<LupDecomposition<T>>(type), MatrixAttribute<LupDecomposition<T>> @@ -52,59 +63,6 @@ public class LupDecompositionAttribute<T>(type: SafeType<LupDecomposition<T>>) : public val <T> MatrixOperations<T>.LUP: LupDecompositionAttribute<T> get() = LupDecompositionAttribute(safeTypeOf()) - -///** -// * Common implementation of [LupDecomposition]. -// */ -//private class LupDecompositionImpl<T : Any>( -// public val elementContext: Field<T>, -// public val lu: Matrix<T>, -// public val pivot: IntBuffer, -// private val even: Boolean, -//) : LupDecomposition<T> { -// /** -// * Returns the matrix L of the decomposition. -// * -// * L is a lower-triangular matrix with [Ring.one] in diagonal -// */ -// override val l: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> -// when { -// j < i -> lu[i, j] -// j == i -> elementContext.one -// else -> elementContext.zero -// } -// }.withFeature(LowerTriangular) -// -// -// /** -// * Returns the matrix U of the decomposition. -// * -// * U is an upper-triangular matrix including the diagonal -// */ -// override val u: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> -// if (j >= i) lu[i, j] else elementContext.zero -// }.withFeature(UpperTriangular) -// -// /** -// * Returns the P rows permutation matrix. -// * -// * P is a sparse matrix with exactly one element set to [Ring.one] in -// * each row and each column, all other elements being set to [Ring.zero]. -// */ -// override val p: Matrix<T> = VirtualMatrix(lu.shape[0], lu.shape[1]) { i, j -> -// if (j == pivot[i]) elementContext.one else elementContext.zero -// } -// -// /** -// * Return the determinant of the matrix -// * @return determinant of the matrix -// */ -// override val determinant: T by lazy { -// elementContext { (0 until lu.shape[0]).fold(if(even) one else -one) { value, i -> value * lu[i, i] } } -// } -// -//} - @PublishedApi internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T = if (value > elementAlgebra.zero) value else elementAlgebra { -value } @@ -115,97 +73,81 @@ internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T = public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( matrix: Matrix<T>, checkSingular: (T) -> Boolean, -): LupDecomposition<T> { +): LupDecomposition<T> = elementAlgebra { require(matrix.rowNum == matrix.colNum) { "LU decomposition supports only square matrices" } val m = matrix.colNum val pivot = IntArray(matrix.rowNum) //TODO just waits for multi-receivers - BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory).run { - elementAlgebra { - val lu = create(matrix) + with(BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory)){ - // Initialize the permutation array and parity - for (row in 0 until m) pivot[row] = row - var even = true + val lu = create(matrix) - // Initialize the permutation array and parity - for (row in 0 until m) pivot[row] = row + // Initialize the permutation array and parity + for (row in 0 until m) pivot[row] = row + var even = true - // Loop over columns - for (col in 0 until m) { - // upper - for (row in 0 until col) { - val luRow = lu.row(row) - var sum = luRow[col] - for (i in 0 until row) sum -= luRow[i] * lu[i, col] - luRow[col] = sum - } + // Initialize the permutation array and parity + for (row in 0 until m) pivot[row] = row - // lower - var max = col // permutation row - var largest = -one - - for (row in col until m) { - val luRow = lu.row(row) - var sum = luRow[col] - for (i in 0 until col) sum -= luRow[i] * lu[i, col] - luRow[col] = sum - - // maintain the best permutation choice - if (abs(sum) > largest) { - largest = abs(sum) - max = row - } - } - - // Singularity check - check(!checkSingular(abs(lu[max, col]))) { "The matrix is singular" } - - // Pivot if necessary - if (max != col) { - val luMax = lu.row(max) - val luCol = lu.row(col) - - for (i in 0 until m) { - val tmp = luMax[i] - luMax[i] = luCol[i] - luCol[i] = tmp - } - - val temp = pivot[max] - pivot[max] = pivot[col] - pivot[col] = temp - even = !even - } - - // Divide the lower elements by the "winning" diagonal elt. - val luDiag = lu[col, col] - for (row in col + 1 until m) lu[row, col] /= luDiag + // Loop over columns + for (col in 0 until m) { + // upper + for (row in 0 until col) { + val luRow = lu.row(row) + var sum = luRow[col] + for (i in 0 until row) sum -= luRow[i] * lu[i, col] + luRow[col] = sum } - val l: MatrixWrapper<T> = VirtualMatrix(type, rowNum, colNum) { i, j -> - when { - j < i -> lu[i, j] - j == i -> one - else -> zero + // lower + var max = col // permutation row + var largest = -one + + for (row in col until m) { + val luRow = lu.row(row) + var sum = luRow[col] + for (i in 0 until col) sum -= luRow[i] * lu[i, col] + luRow[col] = sum + + // maintain the best permutation choice + if (abs(sum) > largest) { + largest = abs(sum) + max = row } - }.withAttribute(LowerTriangular) + } - val u = VirtualMatrix(type, rowNum, colNum) { i, j -> - if (j >= i) lu[i, j] else zero - }.withAttribute(UpperTriangular) -// -// val p = VirtualMatrix(rowNum, colNum) { i, j -> -// if (j == pivot[i]) one else zero -// }.withAttribute(Determinant, if (even) one else -one) + // Singularity check + check(!checkSingular(abs(lu[max, col]))) { "The matrix is singular" } - return LupDecomposition(this@lup, l, u, pivot.asBuffer()) + // Pivot if necessary + if (max != col) { + val luMax = lu.row(max) + val luCol = lu.row(col) + + for (i in 0 until m) { + val tmp = luMax[i] + luMax[i] = luCol[i] + luCol[i] = tmp + } + + val temp = pivot[max] + pivot[max] = pivot[col] + pivot[col] = temp + even = !even + } + + // Divide the lower elements by the "winning" diagonal elt. + val luDiag = lu[col, col] + for (row in col + 1 until m) lu[row, col] /= luDiag } + + return LupDecomposition(this@lup, lu.toStructure2D(), pivot.asBuffer(), even) } } + public fun LinearSpace<Double, Float64Field>.lup( matrix: Matrix<Double>, singularityThreshold: Double = 1e-11, diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt index 9543555e0..b15d4883c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt @@ -7,9 +7,9 @@ package space.kscience.kmath.linear import space.kscience.attributes.FlagAttribute import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Ring -import space.kscience.kmath.operations.WithType import space.kscience.kmath.structures.BufferAccessor2D import space.kscience.kmath.structures.MutableBufferFactory diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index 9d89f7636..eb14de3c7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -16,7 +16,7 @@ import space.kscience.kmath.operations.Ring * * @param T the type of items. */ -public class MatrixWrapper<out T : Any> internal constructor( +public class MatrixWrapper<out T> internal constructor( public val origin: Matrix<T>, override val attributes: Attributes, ) : Matrix<T> by origin { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index d0d078609..1456d5ed8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -5,17 +5,12 @@ package space.kscience.kmath.nd -import space.kscience.attributes.Attribute -import space.kscience.attributes.AttributeContainer -import space.kscience.attributes.Attributes -import space.kscience.attributes.SafeType +import space.kscience.attributes.* import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.operations.Ring -import space.kscience.kmath.operations.WithType import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer -import kotlin.jvm.JvmName import kotlin.math.abs public interface StructureAttribute<T> : Attribute<T> @@ -148,28 +143,20 @@ public inline fun <reified T : Any> BufferND( crossinline initializer: (IntArray) -> T, ): BufferND<T> = BufferND(strides, Buffer(strides.linearSize) { i -> initializer(strides.index(i)) }) -public inline fun <T : Any> BufferND( - type: SafeType<T>, - strides: Strides, - crossinline initializer: (IntArray) -> T, -): BufferND<T> = BufferND(strides, Buffer(type, strides.linearSize) { i -> initializer(strides.index(i)) }) - - public inline fun <reified T : Any> BufferND( shape: ShapeND, crossinline initializer: (IntArray) -> T, ): BufferND<T> = BufferND(ColumnStrides(shape), initializer) -@JvmName("autoVarArg") public inline fun <reified T : Any> BufferND( vararg shape: Int, crossinline initializer: (IntArray) -> T, ): BufferND<T> = BufferND(ColumnStrides(ShapeND(shape)), initializer) -public inline fun <T : Any> BufferND( +public fun <T : Any> BufferND( type: SafeType<T>, vararg shape: Int, - crossinline initializer: (IntArray) -> T, + initializer: (IntArray) -> T, ): BufferND<T> = BufferND(type, ColumnStrides(ShapeND(shape)), initializer) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt index 44e9a0b17..310daa65b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt @@ -6,19 +6,12 @@ package space.kscience.kmath.operations import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.operations.Ring.Companion.optimizedPower import space.kscience.kmath.structures.MutableBufferFactory -/** - * An interface containing [type] for dynamic type checking. - */ -public interface WithType<out T> { - public val type: SafeType<T> -} - - /** * Represents an algebraic structure. * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt index 25554477c..eee991d27 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt @@ -5,20 +5,18 @@ package space.kscience.kmath.operations -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.BufferedRingOpsND import space.kscience.kmath.operations.BigInt.Companion.BASE import space.kscience.kmath.operations.BigInt.Companion.BASE_SIZE import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.log2 import kotlin.math.max import kotlin.math.min import kotlin.math.sign private typealias Magnitude = UIntArray -private typealias TBase = ULong /** * Kotlin Multiplatform implementation of Big Integer numbers (KBigInteger). @@ -29,7 +27,7 @@ private typealias TBase = ULong @OptIn(UnstableKMathAPI::class) public object BigIntField : Field<BigInt>, NumbersAddOps<BigInt>, ScaleOperations<BigInt> { - override val type: SafeType<BigInt> = safeTypeOf() + override val bufferFactory: MutableBufferFactory<BigInt> = MutableBufferFactory() override val zero: BigInt = BigInt.ZERO override val one: BigInt = BigInt.ONE diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index 5a8b26571..42e2d9876 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.operations -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.MutableBufferFactory @@ -21,10 +19,10 @@ public interface WithSize { public interface BufferAlgebra<T, out A : Algebra<T>> : Algebra<Buffer<T>> { public val elementAlgebra: A - override val type: SafeType<Buffer<T>> get() = safeTypeOf<Buffer<T>>() - public val elementBufferFactory: MutableBufferFactory<T> get() = elementAlgebra.bufferFactory + override val bufferFactory: MutableBufferFactory<Buffer<T>> get() = MutableBufferFactory() + public fun buffer(size: Int, vararg elements: T): Buffer<T> { require(elements.size == size) { "Expected $size elements but found ${elements.size}" } return elementBufferFactory(size) { elements[it] } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt index 312fd1396..1538b096b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt @@ -5,10 +5,9 @@ package space.kscience.kmath.operations -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol +import space.kscience.kmath.structures.MutableBufferFactory /** * An algebra for generic boolean logic @@ -74,7 +73,7 @@ public interface LogicAlgebra<T : Any> : Algebra<T> { @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object BooleanAlgebra : LogicAlgebra<Boolean> { - override val type: SafeType<Boolean> get() = safeTypeOf() + override val bufferFactory: MutableBufferFactory<Boolean> get() = MutableBufferFactory() override fun const(boolean: Boolean): Boolean = boolean diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt index 7d8e12139..28b87aa2f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt @@ -4,7 +4,7 @@ */ package space.kscience.kmath.operations -import space.kscience.kmath.structures.* +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.pow as kpow @@ -129,7 +129,7 @@ public val Double.Companion.algebra: Float64Field get() = Float64Field */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Float32Field : ExtendedField<Float>, Norm<Float, Float> { - override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory(::Float32Buffer) + override val bufferFactory: MutableBufferFactory<Float> = MutableBufferFactory() override val zero: Float get() = 0.0f override val one: Float get() = 1.0f @@ -187,7 +187,7 @@ public val Float.Companion.algebra: Float32Field get() = Float32Field */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int32Ring : Ring<Int>, Norm<Int, Int>, NumericAlgebra<Int> { - override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory(::Int32Buffer) + override val bufferFactory: MutableBufferFactory<Int> = MutableBufferFactory() override val zero: Int get() = 0 override val one: Int get() = 1 @@ -212,7 +212,7 @@ public val Int.Companion.algebra: Int32Ring get() = Int32Ring */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int16Ring : Ring<Short>, Norm<Short, Short>, NumericAlgebra<Short> { - override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory(::Int16Buffer) + override val bufferFactory: MutableBufferFactory<Short> = MutableBufferFactory() override val zero: Short get() = 0 override val one: Short get() = 1 @@ -237,7 +237,7 @@ public val Short.Companion.algebra: Int16Ring get() = Int16Ring */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int8Ring : Ring<Byte>, Norm<Byte, Byte>, NumericAlgebra<Byte> { - override val bufferFactory: MutableBufferFactory<Byte> = MutableBufferFactory(::Int8Buffer) + override val bufferFactory: MutableBufferFactory<Byte> = MutableBufferFactory() override val zero: Byte get() = 0 override val one: Byte get() = 1 @@ -262,7 +262,7 @@ public val Byte.Companion.algebra: Int8Ring get() = Int8Ring */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER") public object Int64Ring : Ring<Long>, Norm<Long, Long>, NumericAlgebra<Long> { - override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory(::Int64Buffer) + override val bufferFactory: MutableBufferFactory<Long> = MutableBufferFactory() override val zero: Long get() = 0L override val one: Long get() = 1L diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt index 8e81dd941..47817661f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt @@ -5,13 +5,16 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf + /** * [MutableBuffer] implementation over [Array]. * * @param T the type of elements contained in the buffer. * @property array The underlying array. */ -public class ArrayBuffer<T>(internal val array: Array<T>) : MutableBuffer<T> { +public class ArrayBuffer<T>(override val type: SafeType<T>, internal val array: Array<T>) : MutableBuffer<T> { // Can't inline because array is invariant override val size: Int get() = array.size @@ -22,13 +25,17 @@ public class ArrayBuffer<T>(internal val array: Array<T>) : MutableBuffer<T> { } override operator fun iterator(): Iterator<T> = array.iterator() - override fun copy(): MutableBuffer<T> = ArrayBuffer(array.copyOf()) + override fun copy(): MutableBuffer<T> = ArrayBuffer(type, array.copyOf()) override fun toString(): String = Buffer.toString(this) } +/** + * Returns an [ArrayBuffer] that wraps the original array. + */ +public fun <T> Array<T>.asBuffer(type: SafeType<T>): ArrayBuffer<T> = ArrayBuffer(type, this) /** * Returns an [ArrayBuffer] that wraps the original array. */ -public fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(this) \ No newline at end of file +public inline fun <reified T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(safeTypeOf<T>(), this) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index c3dbfbfe2..26e238145 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -6,9 +6,9 @@ package space.kscience.kmath.structures import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.attributes.safeTypeOf import space.kscience.kmath.operations.WithSize -import space.kscience.kmath.operations.WithType import space.kscience.kmath.operations.asSequence import kotlin.reflect.typeOf diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt index f538fdd01..db22bd41a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt @@ -1,5 +1,6 @@ package space.kscience.kmath.structures +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI /** @@ -8,6 +9,8 @@ import space.kscience.kmath.UnstableKMathAPI public interface BufferView<T> : Buffer<T> { public val origin: Buffer<T> + override val type: SafeType<T> get() = origin.type + /** * Get the index in [origin] buffer from index in this buffer. * Return -1 if element not present in the original buffer @@ -36,6 +39,7 @@ public class BufferSlice<T>( } } + override fun get(index: Int): T = if (index >= size) { throw IndexOutOfBoundsException("$index is out of ${0 until size} rage") } else { @@ -100,7 +104,8 @@ public fun <T> Buffer<T>.slice(range: IntRange): BufferView<T> = if (this is Buf * Dynamically create a range from the initial range */ @UnstableKMathAPI -public inline fun <T> Buffer<T>.slice(rangeBuilder: IntRange.() -> IntRange): BufferView<T> = slice(rangeBuilder(indices)) +public inline fun <T> Buffer<T>.slice(rangeBuilder: IntRange.() -> IntRange): BufferView<T> = + slice(rangeBuilder(indices)) /** * Resize original buffer to a given range using given [range], filling additional segments with [defaultValue]. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt index 21d3f9c6f..0a2117d5d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt @@ -72,15 +72,21 @@ public interface MutableBuffer<T> : Buffer<T> { * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ @Suppress("UNCHECKED_CAST") -public inline fun <T> MutableBuffer(type: SafeType<T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> = - when (type.kType) { - typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as MutableBuffer<T> - typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as MutableBuffer<T> - typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as MutableBuffer<T> - typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as MutableBuffer<T> - typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as MutableBuffer<T> - else -> MutableListBuffer(type, MutableList(size, initializer)) - } +public inline fun <T> MutableBuffer( + type: SafeType<T>, + size: Int, + initializer: (Int) -> T, +): MutableBuffer<T> = when (type.kType) { + typeOf<Boolean>() -> TODO() + typeOf<Int8>() -> Int8Buffer(size) { initializer(it) as Int8 } as MutableBuffer<T> + typeOf<Int16>() -> MutableBuffer.short(size) { initializer(it) as Int16 } as MutableBuffer<T> + typeOf<Int32>() -> MutableBuffer.int(size) { initializer(it) as Int32 } as MutableBuffer<T> + typeOf<Int64>() -> MutableBuffer.long(size) { initializer(it) as Int64 } as MutableBuffer<T> + typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as MutableBuffer<T> + typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as MutableBuffer<T> + //TODO add unsigned types + else -> MutableListBuffer(type, MutableList(size, initializer)) +} /** * Creates a [MutableBuffer] of given type [T]. If the type is primitive, specialized buffers are used diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt index 531aee259..d0e5fa884 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt @@ -8,7 +8,6 @@ package space.kscience.kmath.linear import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureND -import space.kscience.kmath.nd.as2D import space.kscience.kmath.operations.algebra import kotlin.test.Test import kotlin.test.assertEquals @@ -22,7 +21,7 @@ class MatrixTest { @Test fun testTranspose() = Double.algebra.linearSpace.run { val matrix = one(3, 3) - val transposed = matrix.transpose() + val transposed = matrix.transposed assertTrue { StructureND.contentEquals(matrix, transposed) } } @@ -38,7 +37,7 @@ class MatrixTest { @Test fun testMatrixExtension() = Double.algebra.linearSpace.run { - val transitionMatrix: Matrix<Double> = VirtualMatrix(6, 6) { row, col -> + val transitionMatrix: Matrix<Double> = VirtualMatrix(type,6, 6) { row, col -> when { col == 0 -> .50 row + 1 == col -> .50 @@ -60,8 +59,8 @@ class MatrixTest { @Test fun test2DDot() = Double.algebra.linearSpace.run { - val firstMatrix = StructureND.auto(2, 3) { (i, j) -> (i + j).toDouble() }.as2D() - val secondMatrix = StructureND.auto(3, 2) { (i, j) -> (i + j).toDouble() }.as2D() + val firstMatrix = buildMatrix(2, 3) { i, j -> (i + j).toDouble() } + val secondMatrix = buildMatrix(3, 2) { i, j -> (i + j).toDouble() } // val firstMatrix = produce(2, 3) { i, j -> (i + j).toDouble() } // val secondMatrix = produce(3, 2) { i, j -> (i + j).toDouble() } diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/BigNumbers.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/BigNumbers.kt index 584748bd7..59c4380ab 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/BigNumbers.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/BigNumbers.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.operations +import space.kscience.kmath.structures.MutableBufferFactory import java.math.BigDecimal import java.math.BigInteger import java.math.MathContext @@ -13,6 +14,8 @@ import java.math.MathContext * A field over [BigInteger]. */ public object JBigIntegerField : Ring<BigInteger>, NumericAlgebra<BigInteger> { + + override val bufferFactory: MutableBufferFactory<BigInteger> = MutableBufferFactory() override val zero: BigInteger get() = BigInteger.ZERO override val one: BigInteger get() = BigInteger.ONE @@ -33,6 +36,7 @@ public object JBigIntegerField : Ring<BigInteger>, NumericAlgebra<BigInteger> { public abstract class JBigDecimalFieldBase internal constructor( private val mathContext: MathContext = MathContext.DECIMAL64, ) : Field<BigDecimal>, PowerOperations<BigDecimal>, NumericAlgebra<BigDecimal>, ScaleOperations<BigDecimal> { + override val bufferFactory: MutableBufferFactory<BigDecimal> = MutableBufferFactory() override val zero: BigDecimal get() = BigDecimal.ZERO diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt index 2e9a15eed..c1fb097d9 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt @@ -43,7 +43,7 @@ public interface BlockingBufferChain<out T> : BlockingChain<T>, BufferChain<T> { public suspend inline fun <reified T : Any> Chain<T>.nextBuffer(size: Int): Buffer<T> = if (this is BufferChain) { nextBuffer(size) } else { - Buffer.auto(size) { next() } + Buffer(size) { next() } } public inline fun <reified T : Any> BlockingChain<T>.nextBufferBlocking( @@ -51,5 +51,5 @@ public inline fun <reified T : Any> BlockingChain<T>.nextBufferBlocking( ): Buffer<T> = if (this is BlockingBufferChain) { nextBufferBlocking(size) } else { - Buffer.auto(size) { nextBlocking() } + Buffer(size) { nextBlocking() } } \ No newline at end of file diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt index c52b6c3d5..5ab03cc4a 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt @@ -14,6 +14,7 @@ import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.flatMapConcat import kotlinx.coroutines.flow.flow import space.kscience.kmath.chains.BlockingDoubleChain +import space.kscience.kmath.operations.Group import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory import space.kscience.kmath.structures.Float64Buffer @@ -84,9 +85,9 @@ public fun Flow<Double>.chunked(bufferSize: Int): Flow<Float64Buffer> = flow { * Map a flow to a moving window buffer. The window step is one. * To get different steps, one could use skip operation. */ -public fun <T> Flow<T>.windowed(window: Int): Flow<Buffer<T>> = flow { +public fun <T> Flow<T>.windowed(window: Int, algebra: Group<T>): Flow<Buffer<T>> = flow { require(window > 1) { "Window size must be more than one" } - val ringBuffer = RingBuffer.boxing<T>(window) + val ringBuffer = RingBuffer(window, algebra) this@windowed.collect { element -> ringBuffer.push(element) diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt index bb07fede1..57f42819e 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt @@ -7,6 +7,8 @@ package space.kscience.kmath.streaming import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import space.kscience.attributes.SafeType +import space.kscience.kmath.operations.Group import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer import space.kscience.kmath.structures.VirtualBuffer @@ -14,12 +16,14 @@ import space.kscience.kmath.structures.VirtualBuffer /** * Thread-safe ring buffer */ -@Suppress("UNCHECKED_CAST") public class RingBuffer<T>( - private val buffer: MutableBuffer<T?>, + private val buffer: MutableBuffer<T>, private var startIndex: Int = 0, size: Int = 0, ) : Buffer<T> { + + override val type: SafeType<T> get() = buffer.type + private val mutex: Mutex = Mutex() override var size: Int = size @@ -28,7 +32,7 @@ public class RingBuffer<T>( override operator fun get(index: Int): T { require(index >= 0) { "Index must be positive" } require(index < size) { "Index $index is out of circular buffer size $size" } - return buffer[startIndex.forward(index)] as T + return buffer[startIndex.forward(index)] } public fun isFull(): Boolean = size == buffer.size @@ -43,7 +47,7 @@ public class RingBuffer<T>( override fun computeNext() { if (count == 0) done() else { - setNext(copy[index] as T) + setNext(copy[index]) index = index.forward(1) count-- } @@ -55,7 +59,7 @@ public class RingBuffer<T>( */ public suspend fun snapshot(): Buffer<T> = mutex.withLock { val copy = buffer.copy() - VirtualBuffer(size) { i -> copy[startIndex.forward(i)] as T } + VirtualBuffer(type, size) { i -> copy[startIndex.forward(i)] } } public suspend fun push(element: T) { @@ -68,19 +72,17 @@ public class RingBuffer<T>( private fun Int.forward(n: Int): Int = (this + n) % (buffer.size) override fun toString(): String = Buffer.toString(this) - - public companion object { - public inline fun <reified T : Any> build(size: Int, empty: T): RingBuffer<T> { - val buffer = MutableBuffer.auto(size) { empty } as MutableBuffer<T?> - return RingBuffer(buffer) - } - - /** - * Slow yet universal buffer - */ - public fun <T> boxing(size: Int): RingBuffer<T> { - val buffer: MutableBuffer<T?> = MutableBuffer.boxing(size) { null } - return RingBuffer(buffer) - } - } +} + +public inline fun <reified T : Any> RingBuffer(size: Int, empty: T): RingBuffer<T> { + val buffer = MutableBuffer(size) { empty } + return RingBuffer(buffer) +} + +/** + * Slow yet universal buffer + */ +public fun <T> RingBuffer(size: Int, algebra: Group<T>): RingBuffer<T> { + val buffer: MutableBuffer<T> = MutableBuffer(algebra.type, size) { algebra.zero } + return RingBuffer(buffer) } diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt index 22c2ac3ff..d87335a9b 100644 --- a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt +++ b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt @@ -6,6 +6,8 @@ package space.kscience.kmath.structures import kotlinx.coroutines.* +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.coroutines.Math import space.kscience.kmath.nd.ColumnStrides @@ -14,9 +16,11 @@ import space.kscience.kmath.nd.StructureND public class LazyStructureND<out T>( public val scope: CoroutineScope, + override val type: SafeType<T>, override val shape: ShapeND, public val function: suspend (IntArray) -> T, ) : StructureND<T> { + private val cache: MutableMap<IntArray, Deferred<T>> = HashMap() public fun async(index: IntArray): Deferred<T> = cache.getOrPut(index) { @@ -47,13 +51,13 @@ public suspend fun <T> StructureND<T>.await(index: IntArray): T = * PENDING would benefit from KEEP-176 */ @OptIn(PerformancePitfall::class) -public inline fun <T, R> StructureND<T>.mapAsyncIndexed( +public inline fun <T, reified R> StructureND<T>.mapAsyncIndexed( scope: CoroutineScope, crossinline function: suspend (T, index: IntArray) -> R, -): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index), index) } +): LazyStructureND<R> = LazyStructureND(scope, safeTypeOf(), shape) { index -> function(get(index), index) } @OptIn(PerformancePitfall::class) -public inline fun <T, R> StructureND<T>.mapAsync( +public inline fun <T, reified R> StructureND<T>.mapAsync( scope: CoroutineScope, crossinline function: suspend (T) -> R, -): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index)) } +): LazyStructureND<R> = LazyStructureND(scope, safeTypeOf(), shape) { index -> function(get(index)) } diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt index f9d0f624d..fe8896075 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.dimensions +import space.kscience.attributes.SafeType import space.kscience.kmath.linear.* import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.Structure2D @@ -48,6 +49,9 @@ public interface DMatrix<out T, R : Dimension, C : Dimension> : Structure2D<T> { public value class DMatrixWrapper<out T, R : Dimension, C : Dimension>( private val structure: Structure2D<T>, ) : DMatrix<T, R, C> { + + override val type: SafeType<T> get() = structure.type + override val shape: ShapeND get() = structure.shape override val rowNum: Int get() = shape[0] override val colNum: Int get() = shape[1] @@ -75,8 +79,10 @@ public interface DPoint<out T, D : Dimension> : Point<T> { * Dimension-safe point wrapper */ @JvmInline -public value class DPointWrapper<out T, D : Dimension>(public val point: Point<T>) : - DPoint<T, D> { +public value class DPointWrapper<out T, D : Dimension>(public val point: Point<T>) : DPoint<T, D> { + + override val type: SafeType<T> get() = point.type + override val size: Int get() = point.size override operator fun get(index: Int): T = point[index] diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt index ec1883128..a8f316650 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt @@ -6,14 +6,9 @@ package space.kscience.kmath.ejml import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.linear.InverseMatrixFeature -import space.kscience.kmath.linear.LinearSpace -import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.linear.Point -import space.kscience.kmath.nd.Structure2D +import space.kscience.kmath.linear.* +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Ring -import kotlin.reflect.KType -import kotlin.reflect.typeOf /** * [LinearSpace] implementation specialized for a certain EJML type. @@ -42,8 +37,7 @@ public abstract class EjmlLinearSpace<T : Any, out A : Ring<T>, out M : org.ejml public abstract override fun buildVector(size: Int, initializer: A.(Int) -> T): EjmlVector<T, M> - @Suppress("UNCHECKED_CAST") @UnstableKMathAPI - public fun EjmlMatrix<T, *>.inverse(): Structure2D<Double> = - attributeFor(this, InverseMatrixFeature::class)?.inverse as Structure2D<Double> + public fun EjmlMatrix<T, *>.inverted(): Matrix<Double> = + attributeFor(this, Float64Field.linearSpace.Inverted) } diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 881649d01..bf797fed4 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -131,10 +131,10 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri val out = DMatrixRMaj(1, 1) CommonOps_DDRM.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -155,12 +155,12 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { val out = DMatrixRMaj(1, 1) - + CommonOps_DDRM.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -369,10 +369,10 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix val out = FMatrixRMaj(1, 1) CommonOps_FDRM.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -393,12 +393,12 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { val out = FMatrixRMaj(1, 1) - + CommonOps_FDRM.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -607,12 +607,12 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri val out = DMatrixSparseCSC(1, 1) CommonOps_DSCC.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -633,14 +633,14 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { val out = DMatrixSparseCSC(1, 1) - + CommonOps_DSCC.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -656,7 +656,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri elementAlgebra.one, other.toEjml().origin, out, - null, + null, null, ) @@ -672,7 +672,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri elementAlgebra { -one }, other.toEjml().origin, out, - null, + null, null, ) @@ -840,12 +840,12 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix val out = FMatrixSparseCSC(1, 1) CommonOps_FSCC.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -866,14 +866,14 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { val out = FMatrixSparseCSC(1, 1) - + CommonOps_FSCC.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -889,7 +889,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix elementAlgebra.one, other.toEjml().origin, out, - null, + null, null, ) @@ -905,7 +905,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix elementAlgebra { -one }, other.toEjml().origin, out, - null, + null, null, ) diff --git a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt index 04cc69708..724c33f5f 100644 --- a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt +++ b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt @@ -96,7 +96,7 @@ internal class EjmlMatrixTest { val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 } val matrix = space { l dot u } - val inverted = matrix.toEjml().inverse() + val inverted = matrix.toEjml().inverted() val res = matrix dot inverted diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt index fe5593eaa..9b71e2500 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt @@ -48,7 +48,7 @@ public fun Sequence<DoubleArray>.toMatrix(): RealMatrix = toList().let { } public fun RealMatrix.repeatStackVertical(n: Int): RealMatrix = - VirtualMatrix(rowNum * n, colNum) { row, col -> + VirtualMatrix(type, rowNum * n, colNum) { row, col -> get(if (row == 0) 0 else row % rowNum, col) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt index afd96aced..d4a414a5e 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt @@ -7,14 +7,12 @@ package space.kscience.kmath.functions -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.ScaleOperations import space.kscience.kmath.operations.invoke +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.max import kotlin.math.min -import kotlin.reflect.KType -import kotlin.reflect.typeOf /** @@ -67,6 +65,7 @@ public data class Polynomial<out C>( public open class PolynomialSpace<C, A>( public val ring: A, ) : Ring<Polynomial<C>>, ScaleOperations<Polynomial<C>> where A : Ring<C>, A : ScaleOperations<C> { + override val bufferFactory: MutableBufferFactory<Polynomial<C>> get() = MutableBufferFactory() /** * Instance of zero constant (zero of the underlying ring). diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt index 91b3811c0..22dea15da 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.integration +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.mapToBuffer import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Float64Buffer @@ -32,11 +33,11 @@ public fun GaussIntegratorRuleFactory.build( val normalized: Pair<Buffer<Double>, Buffer<Double>> = build(numPoints) val length = range.endInclusive - range.start - val points = normalized.first.mapToBuffer(::Float64Buffer) { + val points = normalized.first.mapToBuffer(Float64Field.bufferFactory) { range.start + length / 2 + length / 2 * it } - val weights = normalized.second.mapToBuffer(::Float64Buffer) { + val weights = normalized.second.mapToBuffer(Float64Field.bufferFactory) { it * length / 2 } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt index c03b248d4..f9a6edcb5 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt @@ -88,7 +88,7 @@ public class SplineIntegrator<T : Comparable<T>>( public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { val range = integrand[IntegrationRange] ?: 0.0..1.0 - val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, ::Float64Buffer) + val interpolator: PolynomialInterpolator<Double> = SplineInterpolator(Float64Field, Float64Field.bufferFactory) val nodes: Buffer<Double> = integrand[UnivariateIntegrationNodes] ?: run { val numPoints = integrand[IntegrandMaxCalls] ?: 100 @@ -96,7 +96,7 @@ public object DoubleSplineIntegrator : UnivariateIntegrator<Double> { Float64Buffer(numPoints) { i -> range.start + i * step } } - val values = nodes.mapToBuffer(::Float64Buffer) { integrand.function(it) } + val values = nodes.mapToBuffer(Float64Field.bufferFactory) { integrand.function(it) } val polynomials = interpolator.interpolatePolynomials(nodes, values) val res = polynomials.integrate(Float64Field, range) return integrand.withAttributes { diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt index 191e7dfd9..a65a41a62 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt @@ -7,6 +7,8 @@ package space.kscience.kmath.interpolation +import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.functions.PiecewisePolynomial @@ -26,9 +28,11 @@ public fun interface Interpolator<T, in X : T, Y : T> { /** * And interpolator returning [PiecewisePolynomial] function */ -public interface PolynomialInterpolator<T : Comparable<T>> : Interpolator<T, T, T> { +public interface PolynomialInterpolator<T : Comparable<T>> : Interpolator<T, T, T>, WithType<T> { public val algebra: Ring<T> + override val type: SafeType<T> get() = algebra.type + public fun getDefaultValue(): T = error("Out of bounds") public fun interpolatePolynomials(points: XYColumnarData<T, T, T>): PiecewisePolynomial<T> @@ -50,14 +54,14 @@ public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials( public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials( data: Map<T, T>, ): PiecewisePolynomial<T> { - val pointSet = XYColumnarData.of(data.keys.toList().asBuffer(), data.values.toList().asBuffer()) + val pointSet = XYColumnarData.of(data.keys.toList().asBuffer(type), data.values.toList().asBuffer(type)) return interpolatePolynomials(pointSet) } public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials( data: List<Pair<T, T>>, ): PiecewisePolynomial<T> { - val pointSet = XYColumnarData.of(data.map { it.first }.asBuffer(), data.map { it.second }.asBuffer()) + val pointSet = XYColumnarData.of(data.map { it.first }.asBuffer(type), data.map { it.second }.asBuffer(type)) return interpolatePolynomials(pointSet) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt index ed4657d53..e43e18050 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt @@ -12,7 +12,6 @@ import space.kscience.kmath.functions.Polynomial import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.MutableBufferFactory /** @@ -80,4 +79,4 @@ public fun <T : Comparable<T>> Field<T>.splineInterpolator( ): SplineInterpolator<T> = SplineInterpolator(this, bufferFactory) public val Float64Field.splineInterpolator: SplineInterpolator<Double> - get() = SplineInterpolator(this, ::Float64Buffer) \ No newline at end of file + get() = SplineInterpolator(this, bufferFactory) \ No newline at end of file diff --git a/kmath-memory/build.gradle.kts b/kmath-memory/build.gradle.kts index f1dff3b75..d2e50b10b 100644 --- a/kmath-memory/build.gradle.kts +++ b/kmath-memory/build.gradle.kts @@ -7,6 +7,10 @@ kscience { js() native() wasm() + + dependencies { + api(projects.kmathCore) + } } readme { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MemoryBuffer.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemoryBuffer.kt similarity index 84% rename from kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MemoryBuffer.kt rename to kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemoryBuffer.kt index cbfd6b9cd..f462be40e 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MemoryBuffer.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemoryBuffer.kt @@ -1,11 +1,13 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2023 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.structures +package space.kscience.kmath.memory -import space.kscience.kmath.memory.* +import space.kscience.attributes.SafeType +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.MutableBuffer /** * A non-boxing buffer over [Memory] object. @@ -15,6 +17,9 @@ import space.kscience.kmath.memory.* * @property spec the spec of [T] type. */ public open class MemoryBuffer<T : Any>(protected val memory: Memory, protected val spec: MemorySpec<T>) : Buffer<T> { + + override val type: SafeType<T> get() = spec.type + override val size: Int get() = memory.size / spec.objectSize override operator fun get(index: Int): T = memory.read { read(spec, spec.objectSize * index) } @@ -43,8 +48,10 @@ public open class MemoryBuffer<T : Any>(protected val memory: Memory, protected * @property memory the underlying memory segment. * @property spec the spec of [T] type. */ -public class MutableMemoryBuffer<T : Any>(memory: Memory, spec: MemorySpec<T>) : MemoryBuffer<T>(memory, spec), - MutableBuffer<T> { +public class MutableMemoryBuffer<T : Any>( + memory: Memory, + spec: MemorySpec<T>, +) : MemoryBuffer<T>(memory, spec), MutableBuffer<T> { private val writer: MemoryWriter = memory.writer() diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt index 19bc3bae4..a1d2b1f28 100644 --- a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt @@ -5,12 +5,15 @@ package space.kscience.kmath.memory +import space.kscience.attributes.WithType + /** * A specification to read or write custom objects with fixed size in bytes. * * @param T the type of object this spec manages. */ -public interface MemorySpec<T : Any> { +public interface MemorySpec<T : Any>: WithType<T> { + /** * Size of [T] in bytes after serialization. */ From 2f2f5526488b0606832fdb50e143ea8202583329 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sat, 11 Nov 2023 10:19:09 +0300 Subject: [PATCH 061/103] 0.4 WIP --- .../space/kscience/attributes/Attribute.kt | 2 - .../space/kscience/attributes/Attributes.kt | 6 +- .../kscience/attributes/AttributesBuilder.kt | 2 +- .../kscience/kmath/linear/LinearSpace.kt | 35 ++++++++++-- .../kscience/kmath/linear/LupDecomposition.kt | 4 +- .../kscience/kmath/ejml/EjmlLinearSpace.kt | 2 +- .../space/kscience/kmath/ejml/_generated.kt | 56 +++++++++---------- .../kscience/kmath/ejml/EjmlMatrixTest.kt | 4 +- .../space/kscience/kmath/samplers/Sampler.kt | 17 ++---- .../kscience/kmath/samplers/SamplerAlgebra.kt | 3 + .../kscience/kmath/stat/ValueAndErrorField.kt | 48 ++++++++++++++++ 11 files changed, 121 insertions(+), 58 deletions(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt index 6fa142180..a507cd698 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt @@ -5,8 +5,6 @@ package space.kscience.attributes -import kotlin.reflect.KType - public interface Attribute<T> /** diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index a1bccc211..b50436dd2 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -8,7 +8,7 @@ package space.kscience.attributes import kotlin.jvm.JvmInline @JvmInline -public value class Attributes internal constructor(public val content: Map<out Attribute<*>, Any>) { +public value class Attributes internal constructor(public val content: Map<out Attribute<*>, Any?>) { public val keys: Set<Attribute<*>> get() = content.keys @@ -51,7 +51,7 @@ public inline fun <reified A : FlagAttribute> Attributes.has(): Boolean = /** * Create [Attributes] with an added or replaced attribute key. */ -public fun <T : Any, A : Attribute<T>> Attributes.withAttribute( +public fun <T, A : Attribute<T>> Attributes.withAttribute( attribute: A, attrValue: T, ): Attributes = Attributes(content + (attribute to attrValue)) @@ -101,7 +101,7 @@ public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement( /** * Create [Attributes] with a single key */ -public fun <T : Any, A : Attribute<T>> Attributes( +public fun <T, A : Attribute<T>> Attributes( attribute: A, attrValue: T, ): Attributes = Attributes(mapOf(attribute to attrValue)) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index 79df91c3e..6d74b90c1 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -10,7 +10,7 @@ package space.kscience.attributes * * @param O type marker of an owner object, for which these attributes are made */ -public class TypedAttributesBuilder<in O> internal constructor(private val map: MutableMap<Attribute<*>, Any>) { +public class TypedAttributesBuilder<in O> internal constructor(private val map: MutableMap<Attribute<*>, Any?>) { public constructor() : this(mutableMapOf()) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index 00ebad5ee..6b547e2c5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -5,8 +5,10 @@ package space.kscience.kmath.linear +import space.kscience.attributes.Attributes import space.kscience.attributes.SafeType import space.kscience.attributes.WithType +import space.kscience.attributes.withAttribute import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.* import space.kscience.kmath.operations.BufferRingOps @@ -173,15 +175,36 @@ public interface LinearSpace<T, out A : Ring<T>> : MatrixOperations<T> { public operator fun T.times(v: Point<T>): Point<T> = v * this /** - * Get an attribute value for the structure in this scope. Structure attributes are preferred to computed attributes. + * Compute an [attribute] value for given [structure]. Return null if the attribute could not be computed. + */ + public fun <V, A : StructureAttribute<V>> computeAttribute(structure: StructureND<*>, attribute: A): V? = null + + @UnstableKMathAPI + public fun <V, A : StructureAttribute<V>> StructureND<*>.getOrComputeAttribute(attribute: A): V? { + return attributes[attribute] ?: computeAttribute(this, attribute) + } + + /** + * If the structure holds given [attribute] return itself. Otherwise, return a new [Matrix] that contains a computed attribute. * - * @param structure the structure. - * @param attribute to be computed. - * @return a feature object or `null` if it isn't present. + * This method is used to compute and cache attribute inside the structure. If one needs an attribute only once, + * better use [StructureND.getOrComputeAttribute]. */ @UnstableKMathAPI - public fun <T, A : StructureAttribute<T>> attributeFor(structure: StructureND<*>, attribute: A): T = - structure.attributes[attribute] ?: error("Can't compute attribute $attribute for $structure") + public fun <V : Any, A : StructureAttribute<V>> Matrix<T>.compute( + attribute: A, + ): Matrix<T>? { + return if (attributes[attribute] != null) { + this + } else { + val value = computeAttribute(this, attribute) ?: return null + if (this is MatrixWrapper) { + MatrixWrapper(this, attributes.withAttribute(attribute, value)) + } else { + MatrixWrapper(this, Attributes(attribute, value)) + } + } + } public companion object { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 6592a3da4..fab4ef3db 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -209,8 +209,8 @@ public fun <T : Comparable<T>, F : Field<T>> LinearSpace<T, F>.lupSolver( singularityCheck: (T) -> Boolean, ): LinearSolver<T> = object : LinearSolver<T> { override fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T> { - // Use existing decomposition if it is provided by matrix - val decomposition = attributeFor(a, LUP) ?: lup(a, singularityCheck) + // Use existing decomposition if it is provided by matrix or linear space itself + val decomposition = a.getOrComputeAttribute(LUP) ?: lup(a, singularityCheck) return solve(decomposition, b) } diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt index a8f316650..37b14f8d1 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt @@ -39,5 +39,5 @@ public abstract class EjmlLinearSpace<T : Any, out A : Ring<T>, out M : org.ejml @UnstableKMathAPI public fun EjmlMatrix<T, *>.inverted(): Matrix<Double> = - attributeFor(this, Float64Field.linearSpace.Inverted) + attributeForOrNull(this, Float64Field.linearSpace.Inverted) } diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index bf797fed4..881649d01 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -131,10 +131,10 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri val out = DMatrixRMaj(1, 1) CommonOps_DDRM.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -155,12 +155,12 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { val out = DMatrixRMaj(1, 1) - + CommonOps_DDRM.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -369,10 +369,10 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix val out = FMatrixRMaj(1, 1) CommonOps_FDRM.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -393,12 +393,12 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { val out = FMatrixRMaj(1, 1) - + CommonOps_FDRM.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -607,12 +607,12 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri val out = DMatrixSparseCSC(1, 1) CommonOps_DSCC.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -633,14 +633,14 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { val out = DMatrixSparseCSC(1, 1) - + CommonOps_DSCC.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -656,7 +656,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri elementAlgebra.one, other.toEjml().origin, out, - null, + null, null, ) @@ -672,7 +672,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri elementAlgebra { -one }, other.toEjml().origin, out, - null, + null, null, ) @@ -840,12 +840,12 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix val out = FMatrixSparseCSC(1, 1) CommonOps_FSCC.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -866,14 +866,14 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { val out = FMatrixSparseCSC(1, 1) - + CommonOps_FSCC.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -889,7 +889,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix elementAlgebra.one, other.toEjml().origin, out, - null, + null, null, ) @@ -905,7 +905,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix elementAlgebra { -one }, other.toEjml().origin, out, - null, + null, null, ) diff --git a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt index 724c33f5f..6bfb3fecf 100644 --- a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt +++ b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt @@ -61,9 +61,9 @@ internal class EjmlMatrixTest { fun features() { val m = randomMatrix val w = EjmlDoubleMatrix(m) - val det: Determinant<Double> = EjmlLinearSpaceDDRM.attributeFor(w) ?: fail() + val det: Determinant<Double> = EjmlLinearSpaceDDRM.attributeForOrNull(w) ?: fail() assertEquals(CommonOps_DDRM.det(m), det.determinant) - val lup: LupDecompositionAttribute<Double> = EjmlLinearSpaceDDRM.attributeFor(w) ?: fail() + val lup: LupDecompositionAttribute<Double> = EjmlLinearSpaceDDRM.attributeForOrNull(w) ?: fail() val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows, m.numCols) .also { it.decompose(m.copy()) } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt index 34355dca7..c064641a9 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt @@ -12,8 +12,6 @@ import space.kscience.kmath.chains.combine import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory -import space.kscience.kmath.structures.Float64Buffer -import space.kscience.kmath.structures.Int32Buffer import kotlin.jvm.JvmName /** @@ -36,7 +34,7 @@ public fun interface Sampler<out T : Any> { public fun <T : Any> Sampler<T>.sampleBuffer( generator: RandomGenerator, size: Int, - bufferFactory: BufferFactory<T> = BufferFactory.boxing(), + bufferFactory: BufferFactory<T> ): Chain<Buffer<T>> { require(size > 1) //creating temporary storage once @@ -58,18 +56,11 @@ public fun <T : Any> Sampler<T>.sampleBuffer( public suspend fun <T : Any> Sampler<T>.next(generator: RandomGenerator): T = sample(generator).first() /** - * Generates [size] real samples and chunks them into some buffers. + * Generates [size] samples and chunks them into some buffers. */ @JvmName("sampleRealBuffer") -public fun Sampler<Double>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<Double>> = - sampleBuffer(generator, size, ::Float64Buffer) - -/** - * Generates [size] integer samples and chunks them into some buffers. - */ -@JvmName("sampleIntBuffer") -public fun Sampler<Int>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<Int>> = - sampleBuffer(generator, size, ::Int32Buffer) +public inline fun <reified T:Any> Sampler<T>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<T>> = + sampleBuffer(generator, size, BufferFactory()) /** diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/SamplerAlgebra.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/SamplerAlgebra.kt index 44b87a431..e23b5928e 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/SamplerAlgebra.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/SamplerAlgebra.kt @@ -14,6 +14,7 @@ import space.kscience.kmath.operations.ScaleOperations import space.kscience.kmath.operations.invoke import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.stat.Sampler +import space.kscience.kmath.structures.MutableBufferFactory /** * Implements [Sampler] by sampling only certain [value]. @@ -41,6 +42,8 @@ public class BasicSampler<out T : Any>(public val chainBuilder: (RandomGenerator public class SamplerSpace<T : Any, out S>(public val algebra: S) : Group<Sampler<T>>, ScaleOperations<Sampler<T>> where S : Group<T>, S : ScaleOperations<T> { + override val bufferFactory: MutableBufferFactory<Sampler<T>> = MutableBufferFactory() + override val zero: Sampler<T> = ConstantSampler(algebra.zero) override fun add(left: Sampler<T>, right: Sampler<T>): Sampler<T> = BasicSampler { generator -> diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt index 38cd5f900..53df87947 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt @@ -5,10 +5,14 @@ package space.kscience.kmath.stat +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.operations.Field +import space.kscience.kmath.structures.* import kotlin.math.pow import kotlin.math.sqrt + /** * A combination of a random [value] and its [dispersion]. * @@ -53,4 +57,48 @@ public object ValueAndErrorField : Field<ValueAndError> { override fun scale(a: ValueAndError, value: Double): ValueAndError = ValueAndError(a.value * value, a.dispersion * value.pow(2)) + + + private class ValueAndErrorBuffer(val values: DoubleBuffer, val ds: DoubleBuffer) : MutableBuffer<ValueAndError> { + init { + require(values.size == ds.size) + } + + override val type: SafeType<ValueAndError> get() = safeTypeOf() + override val size: Int + get() = values.size + + override fun get(index: Int): ValueAndError = ValueAndError(values[index], ds[index]) + + override fun toString(): String = Buffer.toString(this) + + override fun set(index: Int, value: ValueAndError) { + values[index] = value.value + values[index] = value.dispersion + } + + override fun copy(): MutableBuffer<ValueAndError> = ValueAndErrorBuffer(values.copy(), ds.copy()) + } + + override val bufferFactory: MutableBufferFactory<ValueAndError> = object : MutableBufferFactory<ValueAndError> { + override fun invoke( + size: Int, + builder: (Int) -> ValueAndError, + ): MutableBuffer<ValueAndError> { + val values: DoubleArray = DoubleArray(size) + val ds = DoubleArray(size) + repeat(size){ + val (v, d) = builder(it) + values[it] = v + ds[it] = d + } + return ValueAndErrorBuffer( + values.asBuffer(), + ds.asBuffer() + ) + } + + override val type: SafeType<ValueAndError> get() = safeTypeOf() + + } } \ No newline at end of file From 5c82a5e1fa2dced56af94a12cd5ca8f4e0a0ff51 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sat, 18 Nov 2023 22:29:59 +0300 Subject: [PATCH 062/103] 0.4 WIP --- CHANGELOG.md | 3 +- .../space/kscience/attributes/Attribute.kt | 11 --- .../kscience/attributes/AttributeContainer.kt | 10 +- .../space/kscience/attributes/Attributes.kt | 42 ++++---- .../kscience/attributes/AttributesBuilder.kt | 33 ++++--- .../attributes/PolymorphicAttribute.kt | 31 ++++++ .../kmath/ejml/codegen/ejmlCodegen.kt | 12 ++- .../space/kscience/kmath/fit/chiSquared.kt | 4 +- .../kotlin/space/kscience/kmath/fit/qowFit.kt | 4 +- .../space/kscience/kmath/ast/TypedMst.kt | 36 +++++-- .../kscience/kmath/ast/evaluateConstants.kt | 9 +- .../space/kscience/kmath/estree/estree.kt | 4 +- .../kmath/estree/internal/ESTreeBuilder.kt | 15 ++- .../kotlin/space/kscience/kmath/asm/asm.kt | 2 +- .../commons/expressions/CmDsExpression.kt | 19 +++- .../integration/CMGaussRuleIntegrator.kt | 4 +- .../kmath/commons/integration/CMIntegrator.kt | 17 ++-- .../kscience/kmath/commons/linear/CMMatrix.kt | 38 ++++---- .../kmath/commons/optimization/CMOptimizer.kt | 35 +++---- .../commons/optimization/OptimizeTest.kt | 4 +- .../kscience/kmath/expressions/DSAlgebra.kt | 11 ++- .../kscience/kmath/expressions/Expression.kt | 29 +++++- .../expressions/ExpressionWithDefault.kt | 8 ++ .../FunctionalExpressionAlgebra.kt | 19 ++-- .../space/kscience/kmath/expressions/MST.kt | 2 +- .../kmath/expressions/SimpleAutoDiff.kt | 5 +- .../kscience/kmath/linear/LinearSolver.kt | 2 +- .../kscience/kmath/linear/LinearSpace.kt | 21 ++-- .../kscience/kmath/linear/LupDecomposition.kt | 41 ++++---- .../kscience/kmath/linear/MatrixWrapper.kt | 10 +- .../kscience/kmath/linear/matrixAttributes.kt | 44 +++++---- .../kscience/kmath/ejml/EjmlLinearSpace.kt | 2 +- .../space/kscience/kmath/ejml/_generated.kt | 39 +++++++- .../kmath/integration/GaussIntegrator.kt | 4 +- .../kscience/kmath/integration/Integrand.kt | 2 +- .../integration/MultivariateIntegrand.kt | 4 +- .../kmath/integration/UnivariateIntegrand.kt | 10 +- kmath-jafama/build.gradle.kts | 2 +- .../kscience/kmath/jafama/KMathJafama.kt | 12 ++- .../kmath/multik/MultikDoubleAlgebra.kt | 2 +- .../kmath/multik/MultikFloatAlgebra.kt | 2 +- .../kscience/kmath/multik/MultikIntAlgebra.kt | 2 +- .../kmath/multik/MultikLongAlgebra.kt | 2 +- .../kmath/multik/MultikShortAlgebra.kt | 2 +- .../kscience/kmath/multik/MultikTensor.kt | 20 ++++ .../kmath/multik/MultikTensorAlgebra.kt | 14 +-- .../optimization/FunctionOptimization.kt | 53 ++++++---- .../kmath/optimization/OptimizationBuilder.kt | 96 ------------------- .../kmath/optimization/OptimizationProblem.kt | 61 +++++------- .../kmath/optimization/QowOptimizer.kt | 27 +++--- .../kscience/kmath/optimization/XYFit.kt | 64 ++++++++----- .../kmath/optimization/logLikelihood.kt | 19 +++- .../kmath/tensors/core/DoubleTensor.kt | 4 + .../kscience/kmath/tensors/core/IntTensor.kt | 6 ++ 54 files changed, 541 insertions(+), 433 deletions(-) create mode 100644 attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt delete mode 100644 kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index ef5e0490c..58df6f1bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## Unreleased ### Added -- Explicit `SafeType` for algebras and buffers. +- Reification. Explicit `SafeType` for algebras and buffers. - Integer division algebras. - Float32 geometries. - New Attributes-kt module that could be used as stand-alone. It declares. type-safe attributes containers. @@ -16,6 +16,7 @@ - kmath-geometry is split into `euclidean2d` and `euclidean3d` - Features replaced with Attributes. - Transposed refactored. +- Kmath-memory is moved on top of core. ### Deprecated diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt index a507cd698..dda7c6ed5 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt @@ -24,14 +24,3 @@ public interface AttributeWithDefault<T> : Attribute<T> { */ public interface SetAttribute<V> : Attribute<Set<V>> -/** - * An attribute that has a type parameter for value - * @param type parameter-type - */ -public abstract class PolymorphicAttribute<T>(public val type: SafeType<T>) : Attribute<T> { - override fun equals(other: Any?): Boolean = other != null && - (this::class == other::class) && - (other as? PolymorphicAttribute<*>)?.type == this.type - - override fun hashCode(): Int = this::class.hashCode() + type.hashCode() -} diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt index 69b050649..19e5c224a 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt @@ -6,8 +6,14 @@ package space.kscience.attributes /** - * A container for attributes. [attributes] could be made mutable by implementation + * A container for [Attributes] */ public interface AttributeContainer { public val attributes: Attributes -} \ No newline at end of file +} + +/** + * A scope, where attribute keys could be resolved + */ +public interface AttributeScope<O> + diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index b50436dd2..6c8dabc50 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -7,21 +7,27 @@ package space.kscience.attributes import kotlin.jvm.JvmInline -@JvmInline -public value class Attributes internal constructor(public val content: Map<out Attribute<*>, Any?>) { +/** + * A set of attributes. The implementation must guarantee that [content] keys correspond to its value types. + */ +public interface Attributes { + public val content: Map<out Attribute<*>, Any?> public val keys: Set<Attribute<*>> get() = content.keys @Suppress("UNCHECKED_CAST") public operator fun <T> get(attribute: Attribute<T>): T? = content[attribute] as? T - override fun toString(): String = "Attributes(value=${content.entries})" - public companion object { - public val EMPTY: Attributes = Attributes(emptyMap()) + public val EMPTY: Attributes = AttributesImpl(emptyMap()) } } +@JvmInline +internal value class AttributesImpl(override val content: Map<out Attribute<*>, Any?>) : Attributes { + override fun toString(): String = "Attributes(value=${content.entries})" +} + public fun Attributes.isEmpty(): Boolean = content.isEmpty() /** @@ -33,19 +39,19 @@ public fun <T> Attributes.getOrDefault(attribute: AttributeWithDefault<T>): T = * Check if there is an attribute that matches given key by type and adheres to [predicate]. */ @Suppress("UNCHECKED_CAST") -public inline fun <T, reified A : Attribute<T>> Attributes.any(predicate: (value: T) -> Boolean): Boolean = +public inline fun <T, reified A : Attribute<T>> Attributes.hasAny(predicate: (value: T) -> Boolean): Boolean = content.any { (mapKey, mapValue) -> mapKey is A && predicate(mapValue as T) } /** * Check if there is an attribute of given type (subtypes included) */ -public inline fun <T, reified A : Attribute<T>> Attributes.any(): Boolean = +public inline fun <reified A : Attribute<*>> Attributes.hasAny(): Boolean = content.any { (mapKey, _) -> mapKey is A } /** * Check if [Attributes] contains a flag. Multiple keys that are instances of a flag could be present */ -public inline fun <reified A : FlagAttribute> Attributes.has(): Boolean = +public inline fun <reified A : FlagAttribute> Attributes.hasFlag(): Boolean = content.keys.any { it is A } /** @@ -54,7 +60,7 @@ public inline fun <reified A : FlagAttribute> Attributes.has(): Boolean = public fun <T, A : Attribute<T>> Attributes.withAttribute( attribute: A, attrValue: T, -): Attributes = Attributes(content + (attribute to attrValue)) +): Attributes = AttributesImpl(content + (attribute to attrValue)) public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attributes = withAttribute(attribute, Unit) @@ -62,7 +68,7 @@ public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attribu /** * Create a new [Attributes] by modifying the current one */ -public fun Attributes.modify(block: AttributesBuilder.() -> Unit): Attributes = Attributes { +public fun <T> Attributes.modify(block: AttributesBuilder<T>.() -> Unit): Attributes = Attributes<T> { from(this@modify) block() } @@ -70,7 +76,7 @@ public fun Attributes.modify(block: AttributesBuilder.() -> Unit): Attributes = /** * Create new [Attributes] by removing [attribute] key */ -public fun Attributes.withoutAttribute(attribute: Attribute<*>): Attributes = Attributes(content.minus(attribute)) +public fun Attributes.withoutAttribute(attribute: Attribute<*>): Attributes = AttributesImpl(content.minus(attribute)) /** * Add an element to a [SetAttribute] @@ -80,7 +86,7 @@ public fun <T, A : SetAttribute<T>> Attributes.withAttributeElement( attrValue: T, ): Attributes { val currentSet: Set<T> = get(attribute) ?: emptySet() - return Attributes( + return AttributesImpl( content + (attribute to (currentSet + attrValue)) ) } @@ -93,9 +99,7 @@ public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement( attrValue: T, ): Attributes { val currentSet: Set<T> = get(attribute) ?: emptySet() - return Attributes( - content + (attribute to (currentSet - attrValue)) - ) + return AttributesImpl(content + (attribute to (currentSet - attrValue))) } /** @@ -104,13 +108,13 @@ public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement( public fun <T, A : Attribute<T>> Attributes( attribute: A, attrValue: T, -): Attributes = Attributes(mapOf(attribute to attrValue)) +): Attributes = AttributesImpl(mapOf(attribute to attrValue)) /** * Create Attributes with a single [Unit] valued attribute */ public fun <A : Attribute<Unit>> Attributes( - attribute: A -): Attributes = Attributes(mapOf(attribute to Unit)) + attribute: A, +): Attributes = AttributesImpl(mapOf(attribute to Unit)) -public operator fun Attributes.plus(other: Attributes): Attributes = Attributes(content + other.content) \ No newline at end of file +public operator fun Attributes.plus(other: Attributes): Attributes = AttributesImpl(content + other.content) \ No newline at end of file diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index 6d74b90c1..0acf4e004 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -10,19 +10,24 @@ package space.kscience.attributes * * @param O type marker of an owner object, for which these attributes are made */ -public class TypedAttributesBuilder<in O> internal constructor(private val map: MutableMap<Attribute<*>, Any?>) { +public class AttributesBuilder<out O> internal constructor( + private val map: MutableMap<Attribute<*>, Any?>, +) : Attributes { public constructor() : this(mutableMapOf()) - @Suppress("UNCHECKED_CAST") - public operator fun <T> get(attribute: Attribute<T>): T? = map[attribute] as? T + override val content: Map<out Attribute<*>, Any?> get() = map + + public operator fun <T> set(attribute: Attribute<T>, value: T?) { + if (value == null) { + map.remove(attribute) + } else { + map[attribute] = value + } + } public operator fun <V> Attribute<V>.invoke(value: V?) { - if (value == null) { - map.remove(this) - } else { - map[this] = value - } + set(this, value) } public fun from(attributes: Attributes) { @@ -46,14 +51,8 @@ public class TypedAttributesBuilder<in O> internal constructor(private val map: map[this] = currentSet - attrValue } - public fun build(): Attributes = Attributes(map) + public fun build(): Attributes = AttributesImpl(map) } -public typealias AttributesBuilder = TypedAttributesBuilder<Any?> - -public fun AttributesBuilder( - attributes: Attributes, -): AttributesBuilder = AttributesBuilder(attributes.content.toMutableMap()) - -public inline fun Attributes(builder: AttributesBuilder.() -> Unit): Attributes = - AttributesBuilder().apply(builder).build() \ No newline at end of file +public inline fun <O> Attributes(builder: AttributesBuilder<O>.() -> Unit): Attributes = + AttributesBuilder<O>().apply(builder).build() \ No newline at end of file diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt new file mode 100644 index 000000000..b61d4c477 --- /dev/null +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2018-2023 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.attributes + +/** + * An attribute that has a type parameter for value + * @param type parameter-type + */ +public abstract class PolymorphicAttribute<T>(public val type: SafeType<T>) : Attribute<T> { + override fun equals(other: Any?): Boolean = other != null && + (this::class == other::class) && + (other as? PolymorphicAttribute<*>)?.type == this.type + + override fun hashCode(): Int = this::class.hashCode() + type.hashCode() +} + + +/** + * Get a polymorphic attribute using attribute factory + */ +public operator fun <T> Attributes.get(attributeKeyBuilder: () -> PolymorphicAttribute<T>): T? = get(attributeKeyBuilder()) + +/** + * Set a polymorphic attribute using its factory + */ +public operator fun <O, T> AttributesBuilder<O>.set(attributeKeyBuilder: () -> PolymorphicAttribute<T>, value: T) { + set(attributeKeyBuilder(), value) +} diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt index b8c895196..bb46a085b 100644 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt +++ b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt @@ -19,6 +19,8 @@ public class Ejml${type}Vector<out M : $ejmlMatrixType>(override val origin: M) require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } } + override val type: SafeType<${type}> get() = safeTypeOf() + override operator fun get(index: Int): $type = origin[0, index] }""" appendLine(text) @@ -30,6 +32,8 @@ private fun Appendable.appendEjmlMatrix(type: String, ejmlMatrixType: String) { * [EjmlMatrix] specialization for [$type]. */ public class Ejml${type}Matrix<out M : $ejmlMatrixType>(override val origin: M) : EjmlMatrix<$type, M>(origin) { + override val type: SafeType<${type}> get() = safeTypeOf() + override operator fun get(i: Int, j: Int): $type = origin[i, j] }""" appendLine(text) @@ -46,7 +50,9 @@ private fun Appendable.appendEjmlLinearSpace( denseOps: String, isDense: Boolean, ) { - @Language("kotlin") val text = """/** + @Language("kotlin") val text = """ + +/** * [EjmlLinearSpace] implementation based on [CommonOps_$ops], [DecompositionFactory_${ops}] operations and * [${ejmlMatrixType}] matrices. */ @@ -56,7 +62,7 @@ public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra}, */ override val elementAlgebra: $kmathAlgebra get() = $kmathAlgebra - override val elementType: KType get() = typeOf<$type>() + override val type: SafeType<${type}> get() = safeTypeOf() @Suppress("UNCHECKED_CAST") override fun Matrix<${type}>.toEjml(): Ejml${type}Matrix<${ejmlMatrixType}> = when { @@ -385,6 +391,8 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix import space.kscience.kmath.UnstableKMathAPI diff --git a/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt b/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt index 258ed0c84..f2c0c7cf4 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt @@ -15,7 +15,7 @@ import space.kscience.kmath.operations.asIterable import space.kscience.kmath.operations.toList import space.kscience.kmath.optimization.FunctionOptimizationTarget import space.kscience.kmath.optimization.optimizeWith -import space.kscience.kmath.optimization.resultPoint +import space.kscience.kmath.optimization.result import space.kscience.kmath.optimization.resultValue import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.real.DoubleVector @@ -98,7 +98,7 @@ suspend fun main() { scatter { mode = ScatterMode.lines x(x) - y(x.map { result.resultPoint[a]!! * it.pow(2) + result.resultPoint[b]!! * it + 1 }) + y(x.map { result.result[a]!! * it.pow(2) + result.result[b]!! * it + 1 }) name = "fit" } } diff --git a/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt b/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt index fe7f48b72..a092b8870 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt @@ -94,13 +94,13 @@ suspend fun main() { scatter { mode = ScatterMode.lines x(x) - y(x.map { result.model(result.startPoint + result.resultPoint + (Symbol.x to it)) }) + y(x.map { result.model(result.startPoint + result.result + (Symbol.x to it)) }) name = "fit" } } br() h3 { - +"Fit result: ${result.resultPoint}" + +"Fit result: ${result.result}" } h3 { +"Chi2/dof = ${result.chiSquaredOrNull!! / result.dof}" diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt index e82f7a3ab..d824a652e 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.ast +import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.operations.Algebra @@ -15,7 +17,7 @@ import space.kscience.kmath.operations.NumericAlgebra * * @param T the type. */ -public sealed interface TypedMst<T> { +public sealed interface TypedMst<T> : WithType<T> { /** * A node containing a unary operation. * @@ -24,8 +26,13 @@ public sealed interface TypedMst<T> { * @property function The function implementing this operation. * @property value The argument of this operation. */ - public class Unary<T>(public val operation: String, public val function: (T) -> T, public val value: TypedMst<T>) : - TypedMst<T> { + public class Unary<T>( + public val operation: String, + public val function: (T) -> T, + public val value: TypedMst<T>, + ) : TypedMst<T> { + override val type: SafeType<T> get() = value.type + override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false @@ -59,6 +66,13 @@ public sealed interface TypedMst<T> { public val left: TypedMst<T>, public val right: TypedMst<T>, ) : TypedMst<T> { + + init { + require(left.type==right.type){"Left and right expressions must be of the same type"} + } + + override val type: SafeType<T> get() = left.type + override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false @@ -89,7 +103,12 @@ public sealed interface TypedMst<T> { * @property value The held value. * @property number The number this value corresponds. */ - public class Constant<T>(public val value: T, public val number: Number?) : TypedMst<T> { + public class Constant<T>( + override val type: SafeType<T>, + public val value: T, + public val number: Number?, + ) : TypedMst<T> { + override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false @@ -114,7 +133,7 @@ public sealed interface TypedMst<T> { * @param T the type. * @property symbol The symbol of the variable. */ - public class Variable<T>(public val symbol: Symbol) : TypedMst<T> { + public class Variable<T>(override val type: SafeType<T>, public val symbol: Symbol) : TypedMst<T> { override fun equals(other: Any?): Boolean { if (this === other) return true if (other == null || this::class != other::class) return false @@ -167,6 +186,7 @@ public fun <T> TypedMst<T>.interpret(algebra: Algebra<T>, vararg arguments: Pair /** * Interpret this [TypedMst] node as expression. */ -public fun <T : Any> TypedMst<T>.toExpression(algebra: Algebra<T>): Expression<T> = Expression { arguments -> - interpret(algebra, arguments) -} +public fun <T : Any> TypedMst<T>.toExpression(algebra: Algebra<T>): Expression<T> = + Expression(algebra.type) { arguments -> + interpret(algebra, arguments) + } diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/evaluateConstants.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/evaluateConstants.kt index 8fc5a6aaf..4298a9788 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/evaluateConstants.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/evaluateConstants.kt @@ -16,6 +16,7 @@ import space.kscience.kmath.operations.bindSymbolOrNull */ public fun <T> MST.evaluateConstants(algebra: Algebra<T>): TypedMst<T> = when (this) { is MST.Numeric -> TypedMst.Constant( + algebra.type, (algebra as? NumericAlgebra<T>)?.number(value) ?: error("Numeric nodes are not supported by $algebra"), value, ) @@ -27,7 +28,7 @@ public fun <T> MST.evaluateConstants(algebra: Algebra<T>): TypedMst<T> = when (t arg.value, ) - TypedMst.Constant(value, if (value is Number) value else null) + TypedMst.Constant(algebra.type, value, if (value is Number) value else null) } else -> TypedMst.Unary(operation, algebra.unaryOperationFunction(operation), arg) @@ -59,7 +60,7 @@ public fun <T> MST.evaluateConstants(algebra: Algebra<T>): TypedMst<T> = when (t ) } - TypedMst.Constant(value, if (value is Number) value else null) + TypedMst.Constant(algebra.type, value, if (value is Number) value else null) } algebra is NumericAlgebra && left is TypedMst.Constant && left.number != null -> TypedMst.Binary( @@ -84,8 +85,8 @@ public fun <T> MST.evaluateConstants(algebra: Algebra<T>): TypedMst<T> = when (t val boundSymbol = algebra.bindSymbolOrNull(this) if (boundSymbol != null) - TypedMst.Constant(boundSymbol, if (boundSymbol is Number) boundSymbol else null) + TypedMst.Constant(algebra.type, boundSymbol, if (boundSymbol is Number) boundSymbol else null) else - TypedMst.Variable(this) + TypedMst.Variable(algebra.type, this) } } diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt index 87c2df2d2..33626eaa1 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt @@ -22,7 +22,7 @@ import space.kscience.kmath.operations.Algebra @OptIn(UnstableKMathAPI::class) public fun <T : Any> MST.compileToExpression(algebra: Algebra<T>): Expression<T> { val typed = evaluateConstants(algebra) - if (typed is TypedMst.Constant<T>) return Expression { typed.value } + if (typed is TypedMst.Constant<T>) return Expression(algebra.type) { typed.value } fun ESTreeBuilder<T>.visit(node: TypedMst<T>): BaseExpression = when (node) { is TypedMst.Constant -> constant(node.value) @@ -36,7 +36,7 @@ public fun <T : Any> MST.compileToExpression(algebra: Algebra<T>): Expression<T> ) } - return ESTreeBuilder { visit(typed) }.instance + return ESTreeBuilder(algebra.type) { visit(typed) }.instance } /** diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt index 1517cdef2..ed2b62336 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt @@ -5,13 +5,22 @@ package space.kscience.kmath.estree.internal +import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.internal.astring.generate import space.kscience.kmath.internal.estree.* -internal class ESTreeBuilder<T>(val bodyCallback: ESTreeBuilder<T>.() -> BaseExpression) { - private class GeneratedExpression<T>(val executable: dynamic, val constants: Array<dynamic>) : Expression<T> { +internal class ESTreeBuilder<T>( + override val type: SafeType<T>, + val bodyCallback: ESTreeBuilder<T>.() -> BaseExpression, +) : WithType<T> { + private class GeneratedExpression<T>( + override val type: SafeType<T>, + val executable: dynamic, + val constants: Array<dynamic>, + ) : Expression<T> { @Suppress("UNUSED_VARIABLE") override fun invoke(arguments: Map<Symbol, T>): T { val e = executable @@ -30,7 +39,7 @@ internal class ESTreeBuilder<T>(val bodyCallback: ESTreeBuilder<T>.() -> BaseExp ) val code = generate(node) - GeneratedExpression(js("new Function('constants', 'arguments_0', code)"), constants.toTypedArray()) + GeneratedExpression(type, js("new Function('constants', 'arguments_0', code)"), constants.toTypedArray()) } private val constants = mutableListOf<Any>() diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt index 97fe91ee4..50e6a2001 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt @@ -29,7 +29,7 @@ import space.kscience.kmath.operations.Int64Ring @PublishedApi internal fun <T : Any> MST.compileWith(type: Class<T>, algebra: Algebra<T>): Expression<T> { val typed = evaluateConstants(algebra) - if (typed is TypedMst.Constant<T>) return Expression { typed.value } + if (typed is TypedMst.Constant<T>) return Expression(algebra.type) { typed.value } fun GenericAsmBuilder<T>.variablesVisitor(node: TypedMst<T>): Unit = when (node) { is TypedMst.Unary -> variablesVisitor(node.value) diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt index 38eaf8868..65ae8dd2d 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt @@ -8,10 +8,13 @@ package space.kscience.kmath.commons.expressions import org.apache.commons.math3.analysis.differentiation.DerivativeStructure +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.* +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.ExtendedField import space.kscience.kmath.operations.NumbersAddOps +import space.kscience.kmath.structures.MutableBufferFactory /** * A field over commons-math [DerivativeStructure]. @@ -26,6 +29,9 @@ public class CmDsField( bindings: Map<Symbol, Double>, ) : ExtendedField<DerivativeStructure>, ExpressionAlgebra<Double, DerivativeStructure>, NumbersAddOps<DerivativeStructure> { + + override val bufferFactory: MutableBufferFactory<DerivativeStructure> = MutableBufferFactory() + public val numberOfVariables: Int = bindings.size override val zero: DerivativeStructure by lazy { DerivativeStructure(numberOfVariables, order) } @@ -77,7 +83,9 @@ public class CmDsField( override fun scale(a: DerivativeStructure, value: Double): DerivativeStructure = a.multiply(value) - override fun multiply(left: DerivativeStructure, right: DerivativeStructure): DerivativeStructure = left.multiply(right) + override fun multiply(left: DerivativeStructure, right: DerivativeStructure): DerivativeStructure = + left.multiply(right) + override fun divide(left: DerivativeStructure, right: DerivativeStructure): DerivativeStructure = left.divide(right) override fun sin(arg: DerivativeStructure): DerivativeStructure = arg.sin() override fun cos(arg: DerivativeStructure): DerivativeStructure = arg.cos() @@ -113,8 +121,8 @@ public class CmDsField( */ @Deprecated("Use generic DSAlgebra from the core") public object CmDsProcessor : AutoDiffProcessor<Double, DerivativeStructure, CmDsField> { - override fun differentiate( - function: CmDsField.() -> DerivativeStructure, + override fun differentiate( + function: CmDsField.() -> DerivativeStructure, ): CmDsExpression = CmDsExpression(function) } @@ -125,13 +133,16 @@ public object CmDsProcessor : AutoDiffProcessor<Double, DerivativeStructure, CmD public class CmDsExpression( public val function: CmDsField.() -> DerivativeStructure, ) : DifferentiableExpression<Double> { + + override val type: SafeType<Double> get() = DoubleField.type + override operator fun invoke(arguments: Map<Symbol, Double>): Double = CmDsField(0, arguments).function().value /** * Get the derivative expression with given orders */ - override fun derivativeOrNull(symbols: List<Symbol>): Expression<Double> = Expression { arguments -> + override fun derivativeOrNull(symbols: List<Symbol>): Expression<Double> = Expression(type) { arguments -> with(CmDsField(symbols.size, arguments)) { function().derivative(symbols) } } } diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt index a3fc49d32..f087987bf 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt @@ -16,7 +16,7 @@ public class CMGaussRuleIntegrator( private var type: GaussRule = GaussRule.LEGENDRE, ) : UnivariateIntegrator<Double> { - override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { + override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { val range = integrand[IntegrationRange] ?: error("Integration range is not provided") val integrator: GaussIntegrator = getIntegrator(range) @@ -79,7 +79,7 @@ public class CMGaussRuleIntegrator( numPoints: Int = 100, type: GaussRule = GaussRule.LEGENDRE, function: (Double) -> Double, - ): Double = CMGaussRuleIntegrator(numPoints, type).process( + ): Double = CMGaussRuleIntegrator(numPoints, type).integrate( UnivariateIntegrand({IntegrationRange(range)},function) ).value } diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt index 2cc60fb77..ce3dabd08 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.commons.integration import org.apache.commons.math3.analysis.integration.IterativeLegendreGaussIntegrator import org.apache.commons.math3.analysis.integration.SimpsonIntegrator +import space.kscience.attributes.Attributes import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.integration.* import org.apache.commons.math3.analysis.integration.UnivariateIntegrator as CMUnivariateIntegrator @@ -19,7 +20,7 @@ public class CMIntegrator( public val integratorBuilder: (Integrand<Double>) -> CMUnivariateIntegrator, ) : UnivariateIntegrator<Double> { - override fun process(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { + override fun integrate(integrand: UnivariateIntegrand<Double>): UnivariateIntegrand<Double> { val integrator = integratorBuilder(integrand) val maxCalls = integrand[IntegrandMaxCalls] ?: defaultMaxCalls val remainingCalls = maxCalls - integrand.calls @@ -73,15 +74,9 @@ public class CMIntegrator( } @UnstableKMathAPI -public var MutableList<IntegrandFeature>.targetAbsoluteAccuracy: Double? - get() = filterIsInstance<IntegrandAbsoluteAccuracy>().lastOrNull()?.accuracy - set(value) { - value?.let { add(IntegrandAbsoluteAccuracy(value)) } - } +public val Attributes.targetAbsoluteAccuracy: Double? + get() = get(IntegrandAbsoluteAccuracy) @UnstableKMathAPI -public var MutableList<IntegrandFeature>.targetRelativeAccuracy: Double? - get() = filterIsInstance<IntegrandRelativeAccuracy>().lastOrNull()?.accuracy - set(value) { - value?.let { add(IntegrandRelativeAccuracy(value)) } - } \ No newline at end of file +public val Attributes.targetRelativeAccuracy: Double? + get() = get(IntegrandRelativeAccuracy) diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index d29650e3f..625e7292a 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -6,18 +6,20 @@ package space.kscience.kmath.commons.linear import org.apache.commons.math3.linear.* +import org.apache.commons.math3.linear.LUDecomposition +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* +import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.nd.StructureAttribute +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.Float64Buffer -import kotlin.reflect.KClass -import kotlin.reflect.KType import kotlin.reflect.cast -import kotlin.reflect.typeOf public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> { + override val type: SafeType<Double> get() = DoubleField.type override val rowNum: Int get() = origin.rowDimension override val colNum: Int get() = origin.columnDimension @@ -26,6 +28,7 @@ public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> { @JvmInline public value class CMVector(public val origin: RealVector) : Point<Double> { + override val type: SafeType<Double> get() = DoubleField.type override val size: Int get() = origin.dimension override operator fun get(index: Int): Double = origin.getEntry(index) @@ -40,7 +43,7 @@ public fun RealVector.toPoint(): CMVector = CMVector(this) public object CMLinearSpace : LinearSpace<Double, Float64Field> { override val elementAlgebra: Float64Field get() = Float64Field - override val elementType: KType = typeOf<Double>() + override val type: SafeType<Double> get() = DoubleField.type override fun buildMatrix( rows: Int, @@ -102,19 +105,14 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> { override fun Double.times(v: Point<Double>): CMVector = v * this - @UnstableKMathAPI - override fun <F : StructureAttribute> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { - //Return the feature if it is intrinsic to the structure - structure.getFeature(type)?.let { return it } + override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Double>, attribute: A): V? { val origin = structure.toCM().origin - return when (type) { - IsDiagonal::class -> if (origin is DiagonalMatrix) IsDiagonal else null - - Determinant::class, LupDecompositionAttribute::class -> object : - Determinant<Double>, - LupDecompositionAttribute<Double> { + return when (attribute) { + IsDiagonal -> if (origin is DiagonalMatrix) IsDiagonal else null + Determinant -> LUDecomposition(origin).determinant + LUP -> GenericLupDecomposition { private val lup by lazy { LUDecomposition(origin) } override val determinant: Double by lazy { lup.determinant } override val l: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(lup.l).withAttribute(LowerTriangular) } @@ -122,20 +120,24 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> { override val p: Matrix<Double> by lazy { CMMatrix(lup.p) } } - CholeskyDecompositionAttribute::class -> object : CholeskyDecompositionAttribute<Double> { + CholeskyDecompositionAttribute -> object : CholeskyDecompositionAttribute<Double> { override val l: Matrix<Double> by lazy<Matrix<Double>> { val cholesky = CholeskyDecomposition(origin) CMMatrix(cholesky.l).withAttribute(LowerTriangular) } } - QRDecompositionAttribute::class -> object : QRDecompositionAttribute<Double> { + QRDecompositionAttribute -> object : QRDecompositionAttribute<Double> { private val qr by lazy { QRDecomposition(origin) } - override val q: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(qr.q).withAttribute(OrthogonalAttribute) } + override val q: Matrix<Double> by lazy<Matrix<Double>> { + CMMatrix(qr.q).withAttribute( + OrthogonalAttribute + ) + } override val r: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(qr.r).withAttribute(UpperTriangular) } } - SVDAttribute::class -> object : SVDAttribute<Double> { + SVDAttribute -> object : SVDAttribute<Double> { private val sv by lazy { SingularValueDecomposition(origin) } override val u: Matrix<Double> by lazy { CMMatrix(sv.u) } override val s: Matrix<Double> by lazy { CMMatrix(sv.s) } diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt index 6e0000721..e834d404b 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt @@ -13,6 +13,8 @@ import org.apache.commons.math3.optim.nonlinear.scalar.ObjectiveFunctionGradient import org.apache.commons.math3.optim.nonlinear.scalar.gradient.NonLinearConjugateGradientOptimizer import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.NelderMeadSimplex import org.apache.commons.math3.optim.nonlinear.scalar.noderiv.SimplexOptimizer +import space.kscience.attributes.AttributesBuilder +import space.kscience.attributes.SetAttribute import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.expressions.SymbolIndexer @@ -26,34 +28,25 @@ import kotlin.reflect.KClass public operator fun PointValuePair.component1(): DoubleArray = point public operator fun PointValuePair.component2(): Double = value -public class CMOptimizerEngine(public val optimizerBuilder: () -> MultivariateOptimizer) : OptimizationFeature { - override fun toString(): String = "CMOptimizer($optimizerBuilder)" -} +public object CMOptimizerEngine: OptimizationAttribute<() -> MultivariateOptimizer> /** * Specify a Commons-maths optimization engine */ -public fun FunctionOptimizationBuilder<Double>.cmEngine(optimizerBuilder: () -> MultivariateOptimizer) { - addFeature(CMOptimizerEngine(optimizerBuilder)) +public fun AttributesBuilder<FunctionOptimization<Double>>.cmEngine(optimizerBuilder: () -> MultivariateOptimizer) { + set(CMOptimizerEngine, optimizerBuilder) } -public class CMOptimizerData(public val data: List<SymbolIndexer.() -> OptimizationData>) : OptimizationFeature { - public constructor(vararg data: (SymbolIndexer.() -> OptimizationData)) : this(data.toList()) - - override fun toString(): String = "CMOptimizerData($data)" -} +public object CMOptimizerData: SetAttribute<SymbolIndexer.() -> OptimizationData> /** * Specify Commons-maths optimization data. */ -public fun FunctionOptimizationBuilder<Double>.cmOptimizationData(data: SymbolIndexer.() -> OptimizationData) { - updateFeature<CMOptimizerData> { - val newData = (it?.data ?: emptyList()) + data - CMOptimizerData(newData) - } +public fun AttributesBuilder<FunctionOptimization<Double>>.cmOptimizationData(data: SymbolIndexer.() -> OptimizationData) { + CMOptimizerData.add(data) } -public fun FunctionOptimizationBuilder<Double>.simplexSteps(vararg steps: Pair<Symbol, Double>) { +public fun AttributesBuilder<FunctionOptimization<Double>>.simplexSteps(vararg steps: Pair<Symbol, Double>) { //TODO use convergence checker from features cmEngine { SimplexOptimizer(CMOptimizer.defaultConvergenceChecker) } cmOptimizationData { NelderMeadSimplex(mapOf(*steps).toDoubleArray()) } @@ -78,8 +71,8 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> { ): FunctionOptimization<Double> { val startPoint = problem.startPoint - val parameters = problem.getFeature<OptimizationParameters>()?.symbols - ?: problem.getFeature<OptimizationStartPoint<Double>>()?.point?.keys + val parameters = problem.attributes[OptimizationParameters] + ?: problem.attributes[OptimizationStartPoint<Double>()]?.keys ?: startPoint.keys @@ -90,7 +83,7 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> { DEFAULT_MAX_ITER ) - val cmOptimizer: MultivariateOptimizer = problem.getFeature<CMOptimizerEngine>()?.optimizerBuilder?.invoke() + val cmOptimizer: MultivariateOptimizer = problem.attributes[CMOptimizerEngine]?.invoke() ?: NonLinearConjugateGradientOptimizer( NonLinearConjugateGradientOptimizer.Formula.FLETCHER_REEVES, convergenceChecker @@ -123,7 +116,7 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> { } addOptimizationData(gradientFunction) - val logger = problem.getFeature<OptimizationLog>() + val logger = problem.attributes[OptimizationLog] for (feature in problem.attributes) { when (feature) { @@ -139,7 +132,7 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> { } val (point, value) = cmOptimizer.optimize(*optimizationData.values.toTypedArray()) - return problem.withFeatures(OptimizationResult(point.toMap()), OptimizationValue(value)) + return problem.withAttributes(OptimizationResult(point.toMap()), OptimizationValue(value)) } } } diff --git a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt index 5933d0d36..5b8c7868a 100644 --- a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt +++ b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt @@ -31,7 +31,7 @@ internal class OptimizeTest { @Test fun testGradientOptimization() = runBlocking { val result = normal.optimizeWith(CMOptimizer, x to 1.0, y to 1.0) - println(result.resultPoint) + println(result.result) println(result.resultValue) } @@ -42,7 +42,7 @@ internal class OptimizeTest { //this sets simplex optimizer } - println(result.resultPoint) + println(result.result) println(result.resultValue) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt index 8ef751859..3e9f8707e 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.expressions +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* import space.kscience.kmath.structures.Buffer @@ -331,10 +332,13 @@ public class DerivativeStructureRingExpression<T, A>( public val elementBufferFactory: MutableBufferFactory<T> = algebra.bufferFactory, public val function: DSRing<T, A>.() -> DS<T, A>, ) : DifferentiableExpression<T> where A : Ring<T>, A : ScaleOperations<T>, A : NumericAlgebra<T> { + + override val type: SafeType<T> get() = elementBufferFactory.type + override operator fun invoke(arguments: Map<Symbol, T>): T = DSRing(algebra, 0, arguments).function().value - override fun derivativeOrNull(symbols: List<Symbol>): Expression<T> = Expression { arguments -> + override fun derivativeOrNull(symbols: List<Symbol>): Expression<T> = Expression(type) { arguments -> with( DSRing( algebra, @@ -443,10 +447,13 @@ public class DSFieldExpression<T, A : ExtendedField<T>>( public val algebra: A, public val function: DSField<T, A>.() -> DS<T, A>, ) : DifferentiableExpression<T> { + + override val type: SafeType<T> get() = algebra.type + override operator fun invoke(arguments: Map<Symbol, T>): T = DSField(algebra, 0, arguments).function().value - override fun derivativeOrNull(symbols: List<Symbol>): Expression<T> = Expression { arguments -> + override fun derivativeOrNull(symbols: List<Symbol>): Expression<T> = Expression(type) { arguments -> DSField( algebra, symbols.size, diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt index f350303bc..81ceaae8a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt @@ -5,8 +5,13 @@ package space.kscience.kmath.expressions +import space.kscience.attributes.SafeType +import space.kscience.attributes.WithType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Algebra +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.IntRing +import space.kscience.kmath.operations.LongRing import kotlin.jvm.JvmName import kotlin.properties.ReadOnlyProperty @@ -15,7 +20,7 @@ import kotlin.properties.ReadOnlyProperty * * @param T the type this expression takes as argument and returns. */ -public fun interface Expression<T> { +public interface Expression<T> : WithType<T> { /** * Calls this expression from arguments. * @@ -25,11 +30,20 @@ public fun interface Expression<T> { public operator fun invoke(arguments: Map<Symbol, T>): T } +public fun <T> Expression(type: SafeType<T>, block: (Map<Symbol, T>) -> T): Expression<T> = object : Expression<T> { + override fun invoke(arguments: Map<Symbol, T>): T = block(arguments) + + override val type: SafeType<T> = type +} + /** * Specialization of [Expression] for [Double] allowing better performance because of using array. */ @UnstableKMathAPI public interface DoubleExpression : Expression<Double> { + + override val type: SafeType<Double> get() = DoubleField.type + /** * The indexer of this expression's arguments that should be used to build array for [invoke]. * @@ -49,7 +63,7 @@ public interface DoubleExpression : Expression<Double> { */ public operator fun invoke(arguments: DoubleArray): Double - public companion object{ + public companion object { internal val EMPTY_DOUBLE_ARRAY = DoubleArray(0) } } @@ -59,6 +73,9 @@ public interface DoubleExpression : Expression<Double> { */ @UnstableKMathAPI public interface IntExpression : Expression<Int> { + + override val type: SafeType<Int> get() = IntRing.type + /** * The indexer of this expression's arguments that should be used to build array for [invoke]. * @@ -78,7 +95,7 @@ public interface IntExpression : Expression<Int> { */ public operator fun invoke(arguments: IntArray): Int - public companion object{ + public companion object { internal val EMPTY_INT_ARRAY = IntArray(0) } } @@ -88,6 +105,9 @@ public interface IntExpression : Expression<Int> { */ @UnstableKMathAPI public interface LongExpression : Expression<Long> { + + override val type: SafeType<Long> get() = LongRing.type + /** * The indexer of this expression's arguments that should be used to build array for [invoke]. * @@ -107,7 +127,7 @@ public interface LongExpression : Expression<Long> { */ public operator fun invoke(arguments: LongArray): Long - public companion object{ + public companion object { internal val EMPTY_LONG_ARRAY = LongArray(0) } } @@ -158,7 +178,6 @@ public operator fun <T> Expression<T>.invoke(vararg pairs: Pair<String, T>): T = ) - /** * Calls this expression without providing any arguments. * diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/ExpressionWithDefault.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/ExpressionWithDefault.kt index c802fe04c..8045817e6 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/ExpressionWithDefault.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/ExpressionWithDefault.kt @@ -5,10 +5,15 @@ package space.kscience.kmath.expressions +import space.kscience.attributes.SafeType + public class ExpressionWithDefault<T>( private val origin: Expression<T>, private val defaultArgs: Map<Symbol, T>, ) : Expression<T> { + override val type: SafeType<T> + get() = origin.type + override fun invoke(arguments: Map<Symbol, T>): T = origin.invoke(defaultArgs + arguments) } @@ -21,6 +26,9 @@ public class DiffExpressionWithDefault<T>( private val defaultArgs: Map<Symbol, T>, ) : DifferentiableExpression<T> { + override val type: SafeType<T> + get() = origin.type + override fun invoke(arguments: Map<Symbol, T>): T = origin.invoke(defaultArgs + arguments) override fun derivativeOrNull(symbols: List<Symbol>): Expression<T>? = diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt index 5b4dcd638..5ff408732 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -23,26 +23,27 @@ public abstract class FunctionalExpressionAlgebra<T, out A : Algebra<T>>( /** * Builds an Expression of constant expression that does not depend on arguments. */ - override fun const(value: T): Expression<T> = Expression { value } + override fun const(value: T): Expression<T> = Expression(algebra.type) { value } /** * Builds an Expression to access a variable. */ - override fun bindSymbolOrNull(value: String): Expression<T>? = Expression { arguments -> + override fun bindSymbolOrNull(value: String): Expression<T>? = Expression(algebra.type) { arguments -> algebra.bindSymbolOrNull(value) ?: arguments[StringSymbol(value)] ?: error("Symbol '$value' is not supported in $this") } - override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> = - { left, right -> - Expression { arguments -> - algebra.binaryOperationFunction(operation)(left(arguments), right(arguments)) - } + override fun binaryOperationFunction( + operation: String, + ): (left: Expression<T>, right: Expression<T>) -> Expression<T> = { left, right -> + Expression(algebra.type) { arguments -> + algebra.binaryOperationFunction(operation)(left(arguments), right(arguments)) } + } override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> = { arg -> - Expression { arguments -> algebra.unaryOperation(operation, arg(arguments)) } + Expression(algebra.type) { arguments -> algebra.unaryOperation(operation, arg(arguments)) } } } @@ -124,7 +125,7 @@ public open class FunctionalExpressionField<T, out A : Field<T>>( super<FunctionalExpressionRing>.binaryOperationFunction(operation) override fun scale(a: Expression<T>, value: Double): Expression<T> = algebra { - Expression { args -> a(args) * value } + Expression(algebra.type) { args -> a(args) * value } } override fun bindSymbolOrNull(value: String): Expression<T>? = diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt index 9705a3f03..7ceb23b37 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt @@ -108,4 +108,4 @@ public fun <T> MST.interpret(algebra: Algebra<T>, vararg arguments: Pair<Symbol, * Interpret this [MST] as expression. */ public fun <T : Any> MST.toExpression(algebra: Algebra<T>): Expression<T> = - Expression { arguments -> interpret(algebra, arguments) } + Expression(algebra.type) { arguments -> interpret(algebra, arguments) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt index fd7bf9fdc..7a67e12cc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt @@ -243,12 +243,15 @@ public class SimpleAutoDiffExpression<T : Any, F : Field<T>>( public val field: F, public val function: SimpleAutoDiffField<T, F>.() -> AutoDiffValue<T>, ) : FirstDerivativeExpression<T>() { + + override val type: SafeType<T> get() = this.field.type + override operator fun invoke(arguments: Map<Symbol, T>): T { //val bindings = arguments.entries.map { it.key.bind(it.value) } return SimpleAutoDiffField(field, arguments).function().value } - override fun derivativeOrNull(symbol: Symbol): Expression<T> = Expression { arguments -> + override fun derivativeOrNull(symbol: Symbol): Expression<T> = Expression(type) { arguments -> //val bindings = arguments.entries.map { it.key.bind(it.value) } val derivationResult = SimpleAutoDiffField(field, arguments).differentiate(function) derivationResult.derivative(symbol) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt index af9ebb463..93d84025f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt @@ -11,7 +11,7 @@ package space.kscience.kmath.linear * * @param T the type of items. */ -public interface LinearSolver<T : Any> { +public interface LinearSolver<T> { /** * Solve a dot x = b matrix equation and return x */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index 6b547e2c5..789164e02 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -5,10 +5,7 @@ package space.kscience.kmath.linear -import space.kscience.attributes.Attributes -import space.kscience.attributes.SafeType -import space.kscience.attributes.WithType -import space.kscience.attributes.withAttribute +import space.kscience.attributes.* import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.* import space.kscience.kmath.operations.BufferRingOps @@ -31,19 +28,13 @@ public typealias MutableMatrix<T> = MutableStructure2D<T> */ public typealias Point<T> = Buffer<T> -/** - * A marker interface for algebras that operate on matrices - * @param T type of matrix element - */ -public interface MatrixOperations<T> : WithType<T> - /** * Basic operations on matrices and vectors. * * @param T the type of items in the matrices. * @param A the type of ring over [T]. */ -public interface LinearSpace<T, out A : Ring<T>> : MatrixOperations<T> { +public interface LinearSpace<T, out A : Ring<T>> : MatrixScope<T> { public val elementAlgebra: A override val type: SafeType<T> get() = elementAlgebra.type @@ -177,10 +168,10 @@ public interface LinearSpace<T, out A : Ring<T>> : MatrixOperations<T> { /** * Compute an [attribute] value for given [structure]. Return null if the attribute could not be computed. */ - public fun <V, A : StructureAttribute<V>> computeAttribute(structure: StructureND<*>, attribute: A): V? = null + public fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<T>, attribute: A): V? = null @UnstableKMathAPI - public fun <V, A : StructureAttribute<V>> StructureND<*>.getOrComputeAttribute(attribute: A): V? { + public fun <V, A : StructureAttribute<V>> Structure2D<T>.getOrComputeAttribute(attribute: A): V? { return attributes[attribute] ?: computeAttribute(this, attribute) } @@ -225,7 +216,7 @@ public inline operator fun <LS : LinearSpace<*, *>, R> LS.invoke(block: LS.() -> /** * Convert matrix to vector if it is possible. */ -public fun <T : Any> Matrix<T>.asVector(): Point<T> = +public fun <T> Matrix<T>.asVector(): Point<T> = if (this.colNum == 1) as1D() else error("Can't convert matrix with more than one column to vector") @@ -236,4 +227,4 @@ public fun <T : Any> Matrix<T>.asVector(): Point<T> = * @receiver a buffer. * @return the new matrix. */ -public fun <T : Any> Point<T>.asMatrix(): VirtualMatrix<T> = VirtualMatrix(type, size, 1) { i, _ -> get(i) } \ No newline at end of file +public fun <T> Point<T>.asMatrix(): VirtualMatrix<T> = VirtualMatrix(type, size, 1) { i, _ -> get(i) } \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index fab4ef3db..bf595d332 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -9,12 +9,20 @@ package space.kscience.kmath.linear import space.kscience.attributes.Attributes import space.kscience.attributes.PolymorphicAttribute -import space.kscience.attributes.SafeType import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* import space.kscience.kmath.structures.* +public interface LupDecomposition<T> { + public val linearSpace: LinearSpace<T, Field<T>> + public val elementAlgebra: Field<T> get() = linearSpace.elementAlgebra + + public val pivot: IntBuffer + public val l: Matrix<T> + public val u: Matrix<T> +} + /** * Matrices with this feature support LU factorization with partial pivoting: *[p] · a = [l] · [u]* where * *a* is the owning matrix. @@ -22,15 +30,14 @@ import space.kscience.kmath.structures.* * @param T the type of matrices' items. * @param lu combined L and U matrix */ -public class LupDecomposition<T>( - public val linearSpace: LinearSpace<T, Ring<T>>, +public class GenericLupDecomposition<T>( + override val linearSpace: LinearSpace<T, Field<T>>, private val lu: Matrix<T>, - public val pivot: IntBuffer, + override val pivot: IntBuffer, private val even: Boolean, -) { - public val elementAlgebra: Ring<T> get() = linearSpace.elementAlgebra +) : LupDecomposition<T> { - public val l: Matrix<T> + override val l: Matrix<T> get() = VirtualMatrix(lu.type, lu.rowNum, lu.colNum, attributes = Attributes(LowerTriangular)) { i, j -> when { j < i -> lu[i, j] @@ -39,7 +46,7 @@ public class LupDecomposition<T>( } } - public val u: Matrix<T> + override val u: Matrix<T> get() = VirtualMatrix(lu.type, lu.rowNum, lu.colNum, attributes = Attributes(UpperTriangular)) { i, j -> if (j >= i) lu[i, j] else elementAlgebra.zero } @@ -55,13 +62,12 @@ public class LupDecomposition<T>( } - -public class LupDecompositionAttribute<T>(type: SafeType<LupDecomposition<T>>) : - PolymorphicAttribute<LupDecomposition<T>>(type), +public class LupDecompositionAttribute<T> : + PolymorphicAttribute<LupDecomposition<T>>(safeTypeOf()), MatrixAttribute<LupDecomposition<T>> -public val <T> MatrixOperations<T>.LUP: LupDecompositionAttribute<T> - get() = LupDecompositionAttribute(safeTypeOf()) +public val <T> MatrixScope<T>.LUP: LupDecompositionAttribute<T> + get() = LupDecompositionAttribute() @PublishedApi internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T = @@ -79,7 +85,7 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( val pivot = IntArray(matrix.rowNum) //TODO just waits for multi-receivers - with(BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory)){ + with(BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory)) { val lu = create(matrix) @@ -142,18 +148,17 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( for (row in col + 1 until m) lu[row, col] /= luDiag } - return LupDecomposition(this@lup, lu.toStructure2D(), pivot.asBuffer(), even) + return GenericLupDecomposition(this@lup, lu.toStructure2D(), pivot.asBuffer(), even) } } - public fun LinearSpace<Double, Float64Field>.lup( matrix: Matrix<Double>, singularityThreshold: Double = 1e-11, ): LupDecomposition<Double> = lup(matrix) { it < singularityThreshold } -internal fun <T : Any, A : Field<T>> LinearSpace<T, A>.solve( +internal fun <T> LinearSpace<T, Field<T>>.solve( lup: LupDecomposition<T>, matrix: Matrix<T>, ): Matrix<T> { @@ -205,7 +210,7 @@ internal fun <T : Any, A : Field<T>> LinearSpace<T, A>.solve( * Produce a generic solver based on LUP decomposition */ @OptIn(UnstableKMathAPI::class) -public fun <T : Comparable<T>, F : Field<T>> LinearSpace<T, F>.lupSolver( +public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lupSolver( singularityCheck: (T) -> Boolean, ): LinearSolver<T> = object : LinearSolver<T> { override fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T> { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index eb14de3c7..4707f6cfe 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -35,7 +35,7 @@ public val <T : Any> Matrix<T>.origin: Matrix<T> /** * Add a single feature to a [Matrix] */ -public fun <T : Any, A : Attribute<T>> Matrix<T>.withAttribute( +public fun <T, A : Attribute<T>> Matrix<T>.withAttribute( attribute: A, attrValue: T, ): MatrixWrapper<T> = if (this is MatrixWrapper) { @@ -44,7 +44,7 @@ public fun <T : Any, A : Attribute<T>> Matrix<T>.withAttribute( MatrixWrapper(this, Attributes(attribute, attrValue)) } -public fun <T : Any, A : Attribute<Unit>> Matrix<T>.withAttribute( +public fun <T, A : Attribute<Unit>> Matrix<T>.withAttribute( attribute: A, ): MatrixWrapper<T> = if (this is MatrixWrapper) { MatrixWrapper(origin, attributes.withAttribute(attribute)) @@ -55,7 +55,7 @@ public fun <T : Any, A : Attribute<Unit>> Matrix<T>.withAttribute( /** * Modify matrix attributes */ -public fun <T : Any> Matrix<T>.modifyAttributes(modifier: (Attributes) -> Attributes): MatrixWrapper<T> = +public fun <T> Matrix<T>.modifyAttributes(modifier: (Attributes) -> Attributes): MatrixWrapper<T> = if (this is MatrixWrapper) { MatrixWrapper(origin, modifier(attributes)) } else { @@ -65,7 +65,7 @@ public fun <T : Any> Matrix<T>.modifyAttributes(modifier: (Attributes) -> Attrib /** * Diagonal matrix of ones. The matrix is virtual, no actual matrix is created. */ -public fun <T : Any> LinearSpace<T, Ring<T>>.one( +public fun <T> LinearSpace<T, Ring<T>>.one( rows: Int, columns: Int, ): MatrixWrapper<T> = VirtualMatrix(type, rows, columns) { i, j -> @@ -76,7 +76,7 @@ public fun <T : Any> LinearSpace<T, Ring<T>>.one( /** * A virtual matrix of zeroes */ -public fun <T : Any> LinearSpace<T, Ring<T>>.zero( +public fun <T> LinearSpace<T, Ring<T>>.zero( rows: Int, columns: Int, ): MatrixWrapper<T> = VirtualMatrix(type, rows, columns) { _, _ -> diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt index 8787d0e09..dadb2f3d7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/matrixAttributes.kt @@ -10,6 +10,13 @@ package space.kscience.kmath.linear import space.kscience.attributes.* import space.kscience.kmath.nd.StructureAttribute + +/** + * A marker interface for algebras that operate on matrices + * @param T type of matrix element + */ +public interface MatrixScope<T> : AttributeScope<Matrix<T>>, WithType<T> + /** * A marker interface representing some properties of matrices or additional transformations of them. Features are used * to optimize matrix operations performance in some cases or retrieve the APIs. @@ -38,11 +45,11 @@ public object IsUnit : IsDiagonal * * @param T the type of matrices' items. */ -public class Inverted<T>(type: SafeType<Matrix<T>>) : - PolymorphicAttribute<Matrix<T>>(type), +public class Inverted<T>() : + PolymorphicAttribute<Matrix<T>>(safeTypeOf()), MatrixAttribute<Matrix<T>> -public val <T> MatrixOperations<T>.Inverted: Inverted<T> get() = Inverted(safeTypeOf()) +public val <T> MatrixScope<T>.Inverted: Inverted<T> get() = Inverted() /** * Matrices with this feature can compute their determinant. @@ -53,7 +60,7 @@ public class Determinant<T>(type: SafeType<T>) : PolymorphicAttribute<T>(type), MatrixAttribute<T> -public val <T> MatrixOperations<T>.Determinant: Determinant<T> get() = Determinant(type) +public val <T> MatrixScope<T>.Determinant: Determinant<T> get() = Determinant(type) /** * Matrices with this feature are lower triangular ones. @@ -77,11 +84,11 @@ public data class LUDecomposition<T>(val l: Matrix<T>, val u: Matrix<T>) * * @param T the type of matrices' items. */ -public class LuDecompositionAttribute<T>(type: SafeType<LUDecomposition<T>>) : - PolymorphicAttribute<LUDecomposition<T>>(type), +public class LuDecompositionAttribute<T> : + PolymorphicAttribute<LUDecomposition<T>>(safeTypeOf()), MatrixAttribute<LUDecomposition<T>> -public val <T> MatrixOperations<T>.LU: LuDecompositionAttribute<T> get() = LuDecompositionAttribute(safeTypeOf()) +public val <T> MatrixScope<T>.LU: LuDecompositionAttribute<T> get() = LuDecompositionAttribute() /** @@ -108,12 +115,12 @@ public interface QRDecomposition<out T> { * * @param T the type of matrices' items. */ -public class QRDecompositionAttribute<T>(type: SafeType<QRDecomposition<T>>) : - PolymorphicAttribute<QRDecomposition<T>>(type), +public class QRDecompositionAttribute<T>() : + PolymorphicAttribute<QRDecomposition<T>>(safeTypeOf()), MatrixAttribute<QRDecomposition<T>> -public val <T> MatrixOperations<T>.QR: QRDecompositionAttribute<T> - get() = QRDecompositionAttribute(safeTypeOf()) +public val <T> MatrixScope<T>.QR: QRDecompositionAttribute<T> + get() = QRDecompositionAttribute() public interface CholeskyDecomposition<T> { /** @@ -128,12 +135,12 @@ public interface CholeskyDecomposition<T> { * * @param T the type of matrices' items. */ -public class CholeskyDecompositionAttribute<T>(type: SafeType<CholeskyDecomposition<T>>) : - PolymorphicAttribute<CholeskyDecomposition<T>>(type), +public class CholeskyDecompositionAttribute<T> : + PolymorphicAttribute<CholeskyDecomposition<T>>(safeTypeOf()), MatrixAttribute<CholeskyDecomposition<T>> -public val <T> MatrixOperations<T>.Cholesky: CholeskyDecompositionAttribute<T> - get() = CholeskyDecompositionAttribute(safeTypeOf()) +public val <T> MatrixScope<T>.Cholesky: CholeskyDecompositionAttribute<T> + get() = CholeskyDecompositionAttribute() public interface SingularValueDecomposition<T> { /** @@ -163,12 +170,11 @@ public interface SingularValueDecomposition<T> { * * @param T the type of matrices' items. */ -public class SVDAttribute<T>(type: SafeType<SingularValueDecomposition<T>>) : - PolymorphicAttribute<SingularValueDecomposition<T>>(type), +public class SVDAttribute<T>() : + PolymorphicAttribute<SingularValueDecomposition<T>>(safeTypeOf()), MatrixAttribute<SingularValueDecomposition<T>> -public val <T> MatrixOperations<T>.SVD: SVDAttribute<T> - get() = SVDAttribute(safeTypeOf()) +public val <T> MatrixScope<T>.SVD: SVDAttribute<T> get() = SVDAttribute() //TODO add sparse matrix feature diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt index 37b14f8d1..47a4b686f 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt @@ -39,5 +39,5 @@ public abstract class EjmlLinearSpace<T : Any, out A : Ring<T>, out M : org.ejml @UnstableKMathAPI public fun EjmlMatrix<T, *>.inverted(): Matrix<Double> = - attributeForOrNull(this, Float64Field.linearSpace.Inverted) + computeAttribute(this, Float64Field.linearSpace.Inverted)!! } diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 881649d01..882df9536 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,9 +19,13 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix +import space.kscience.kmath.nd.Structure2D +import space.kscience.kmath.nd.StructureAttribute import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.operations.Float32Field import space.kscience.kmath.operations.Float64Field @@ -39,6 +43,8 @@ public class EjmlDoubleVector<out M : DMatrix>(override val origin: M) : EjmlVec require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } } + override val type: SafeType<Double> get() = safeTypeOf() + override operator fun get(index: Int): Double = origin[0, index] } @@ -50,6 +56,8 @@ public class EjmlFloatVector<out M : FMatrix>(override val origin: M) : EjmlVect require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } } + override val type: SafeType<Float> get() = safeTypeOf() + override operator fun get(index: Int): Float = origin[0, index] } @@ -57,6 +65,8 @@ public class EjmlFloatVector<out M : FMatrix>(override val origin: M) : EjmlVect * [EjmlMatrix] specialization for [Double]. */ public class EjmlDoubleMatrix<out M : DMatrix>(override val origin: M) : EjmlMatrix<Double, M>(origin) { + override val type: SafeType<Double> get() = safeTypeOf() + override operator fun get(i: Int, j: Int): Double = origin[i, j] } @@ -64,9 +74,12 @@ public class EjmlDoubleMatrix<out M : DMatrix>(override val origin: M) : EjmlMat * [EjmlMatrix] specialization for [Float]. */ public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatrix<Float, M>(origin) { + override val type: SafeType<Float> get() = safeTypeOf() + override operator fun get(i: Int, j: Int): Float = origin[i, j] } + /** * [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and * [DMatrixRMaj] matrices. @@ -77,7 +90,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri */ override val elementAlgebra: Float64Field get() = Float64Field - override val elementType: KType get() = typeOf<Double>() + override val type: SafeType<Double> get() = safeTypeOf() @Suppress("UNCHECKED_CAST") override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when { @@ -205,6 +218,18 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this + override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Double>, attribute: A): V? { + val origin = structure.toEjml().origin + return when(attribute){ + Inverted -> { + val res = origin.copy() + CommonOps_DDRM.invert(res) + res.wrapMatrix() + } + else-> + } + } + @UnstableKMathAPI override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { structure.getFeature(type)?.let { return it } @@ -305,6 +330,8 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri } } +import org.checkerframework.checker.guieffect.qual.SafeType + /** * [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and * [FMatrixRMaj] matrices. @@ -315,7 +342,7 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix */ override val elementAlgebra: Float32Field get() = Float32Field - override val elementType: KType get() = typeOf<Float>() + override val type: SafeType<Float> get() = safeTypeOf() @Suppress("UNCHECKED_CAST") override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixRMaj> = when { @@ -543,6 +570,8 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix } } +import org.checkerframework.checker.guieffect.qual.SafeType + /** * [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and * [DMatrixSparseCSC] matrices. @@ -553,7 +582,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri */ override val elementAlgebra: Float64Field get() = Float64Field - override val elementType: KType get() = typeOf<Double>() + override val type: SafeType<Double> get() = safeTypeOf() @Suppress("UNCHECKED_CAST") override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when { @@ -776,6 +805,8 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri } } +import org.checkerframework.checker.guieffect.qual.SafeType + /** * [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and * [FMatrixSparseCSC] matrices. @@ -786,7 +817,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix */ override val elementAlgebra: Float32Field get() = Float32Field - override val elementType: KType get() = typeOf<Float>() + override val type: SafeType<Float> get() = safeTypeOf() @Suppress("UNCHECKED_CAST") override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixSparseCSC> = when { diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index 7d37711cd..16b7a90f8 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -4,7 +4,7 @@ */ package space.kscience.kmath.integration -import space.kscience.attributes.TypedAttributesBuilder +import space.kscience.attributes.AttributesBuilder import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Field import space.kscience.kmath.structures.Buffer @@ -92,7 +92,7 @@ public inline fun <reified T : Any> GaussIntegrator<T>.integrate( range: ClosedRange<Double>, order: Int = 10, intervals: Int = 10, - attributesBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, + attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, noinline function: (Double) -> T, ): UnivariateIntegrand<T> { require(range.endInclusive > range.start) { "The range upper bound should be higher than lower bound" } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt index d465e87c7..d8f102b2f 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt @@ -30,7 +30,7 @@ public sealed class IntegrandValue<T> private constructor(): IntegrandAttribute< } } -public fun <T> TypedAttributesBuilder<Integrand<T>>.value(value: T) { +public fun <T> AttributesBuilder<Integrand<T>>.value(value: T) { IntegrandValue.forType<T>().invoke(value) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt index 2081947ec..5c8a21f61 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -25,10 +25,10 @@ public fun <T, A : Any> MultivariateIntegrand<T>.withAttribute( ): MultivariateIntegrand<T> = withAttributes(attributes.withAttribute(attribute, value)) public fun <T> MultivariateIntegrand<T>.withAttributes( - block: TypedAttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, + block: AttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, ): MultivariateIntegrand<T> = withAttributes(attributes.modify(block)) public inline fun <reified T : Any> MultivariateIntegrand( - attributeBuilder: TypedAttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, + attributeBuilder: AttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, noinline function: (Point<T>) -> T, ): MultivariateIntegrand<T> = MultivariateIntegrand(safeTypeOf<T>(), Attributes(attributeBuilder), function) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index 9c39e7edc..05a765858 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -26,11 +26,11 @@ public fun <T, A : Any> UnivariateIntegrand<T>.withAttribute( ): UnivariateIntegrand<T> = withAttributes(attributes.withAttribute(attribute, value)) public fun <T> UnivariateIntegrand<T>.withAttributes( - block: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, + block: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, ): UnivariateIntegrand<T> = withAttributes(attributes.modify(block)) public inline fun <reified T : Any> UnivariateIntegrand( - attributeBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, + attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, noinline function: (Double) -> T, ): UnivariateIntegrand<T> = UnivariateIntegrand(safeTypeOf(), Attributes(attributeBuilder), function) @@ -58,7 +58,7 @@ public class UnivariateIntegrandRanges(public val ranges: List<Pair<ClosedRange< public object UnivariateIntegrationNodes : IntegrandAttribute<Buffer<Double>> -public fun TypedAttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(vararg nodes: Double) { +public fun AttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(vararg nodes: Double) { UnivariateIntegrationNodes(Float64Buffer(nodes)) } @@ -68,7 +68,7 @@ public fun TypedAttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(varar */ @UnstableKMathAPI public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( - attributesBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, + attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, noinline function: (Double) -> T, ): UnivariateIntegrand<T> = integrate(UnivariateIntegrand(attributesBuilder, function)) @@ -79,7 +79,7 @@ public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( @UnstableKMathAPI public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( range: ClosedRange<Double>, - attributeBuilder: TypedAttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {}, + attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {}, noinline function: (Double) -> T, ): UnivariateIntegrand<T> { diff --git a/kmath-jafama/build.gradle.kts b/kmath-jafama/build.gradle.kts index 5a77a97ed..0390224ba 100644 --- a/kmath-jafama/build.gradle.kts +++ b/kmath-jafama/build.gradle.kts @@ -14,7 +14,7 @@ repositories { } readme { - maturity = space.kscience.gradle.Maturity.PROTOTYPE + maturity = space.kscience.gradle.Maturity.DEPRECATED propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) feature("jafama-double", "src/main/kotlin/space/kscience/kmath/jafama/") { diff --git a/kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/KMathJafama.kt b/kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/KMathJafama.kt index f9b8287b4..1c52456f3 100644 --- a/kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/KMathJafama.kt +++ b/kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/KMathJafama.kt @@ -7,16 +7,17 @@ package space.kscience.kmath.jafama import net.jafama.FastMath import net.jafama.StrictFastMath -import space.kscience.kmath.operations.ExtendedField -import space.kscience.kmath.operations.Norm -import space.kscience.kmath.operations.PowerOperations -import space.kscience.kmath.operations.ScaleOperations +import space.kscience.kmath.operations.* +import space.kscience.kmath.structures.MutableBufferFactory /** * A field for [Double] (using FastMath) without boxing. Does not produce appropriate field element. */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object JafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> { + + override val bufferFactory: MutableBufferFactory<Double> get() = DoubleField.bufferFactory + override inline val zero: Double get() = 0.0 override inline val one: Double get() = 1.0 @@ -68,6 +69,9 @@ public object JafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, S */ @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public object StrictJafamaDoubleField : ExtendedField<Double>, Norm<Double, Double>, ScaleOperations<Double> { + + override val bufferFactory: MutableBufferFactory<Double> get() = DoubleField.bufferFactory + override inline val zero: Double get() = 0.0 override inline val one: Double get() = 1.0 diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt index 8b463a230..60413f88c 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt @@ -20,7 +20,7 @@ public class MultikDoubleAlgebra( ) : MultikDivisionTensorAlgebra<Double, Float64Field>(multikEngine), TrigonometricOperations<StructureND<Double>>, ExponentialOperations<StructureND<Double>> { override val elementAlgebra: Float64Field get() = Float64Field - override val type: DataType get() = DataType.DoubleDataType + override val dataType: DataType get() = DataType.DoubleDataType override fun sin(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.sin(arg.asMultik().array).wrap() diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt index 7a3dda94b..26331bd6b 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt @@ -15,7 +15,7 @@ public class MultikFloatAlgebra( multikEngine: Engine ) : MultikDivisionTensorAlgebra<Float, Float32Field>(multikEngine) { override val elementAlgebra: Float32Field get() = Float32Field - override val type: DataType get() = DataType.FloatDataType + override val dataType: DataType get() = DataType.FloatDataType override fun scalar(value: Float): MultikTensor<Float> = Multik.ndarrayOf(value).wrap() } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt index 5bd1b3388..46acbdf9d 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt @@ -15,7 +15,7 @@ public class MultikIntAlgebra( multikEngine: Engine ) : MultikTensorAlgebra<Int, Int32Ring>(multikEngine) { override val elementAlgebra: Int32Ring get() = Int32Ring - override val type: DataType get() = DataType.IntDataType + override val dataType: DataType get() = DataType.IntDataType override fun scalar(value: Int): MultikTensor<Int> = Multik.ndarrayOf(value).wrap() } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt index 69a8ec042..97e86d86a 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt @@ -15,7 +15,7 @@ public class MultikLongAlgebra( multikEngine: Engine ) : MultikTensorAlgebra<Long, Int64Ring>(multikEngine) { override val elementAlgebra: Int64Ring get() = Int64Ring - override val type: DataType get() = DataType.LongDataType + override val dataType: DataType get() = DataType.LongDataType override fun scalar(value: Long): MultikTensor<Long> = Multik.ndarrayOf(value).wrap() } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt index 7c8740665..27d43f7b8 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt @@ -15,7 +15,7 @@ public class MultikShortAlgebra( multikEngine: Engine ) : MultikTensorAlgebra<Short, Int16Ring>(multikEngine) { override val elementAlgebra: Int16Ring get() = Int16Ring - override val type: DataType get() = DataType.ShortDataType + override val dataType: DataType get() = DataType.ShortDataType override fun scalar(value: Short): MultikTensor<Short> = Multik.ndarrayOf(value).wrap() } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt index 59a9a1bf3..5ed8ea767 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt @@ -6,13 +6,33 @@ package space.kscience.kmath.multik import org.jetbrains.kotlinx.multik.ndarray.data.* +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.PerformancePitfall +import space.kscience.kmath.complex.ComplexField import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.operations.* import space.kscience.kmath.tensors.api.Tensor import kotlin.jvm.JvmInline +public val DataType.type: SafeType<*> + get() = when (this) { + DataType.ByteDataType -> ByteRing.type + DataType.ShortDataType -> ShortRing.type + DataType.IntDataType -> IntRing.type + DataType.LongDataType -> LongRing.type + DataType.FloatDataType -> Float32Field.type + DataType.DoubleDataType -> Float64Field.type + DataType.ComplexFloatDataType -> safeTypeOf<Pair<Float, Float>>() + DataType.ComplexDoubleDataType -> ComplexField.type + } + + @JvmInline public value class MultikTensor<T>(public val array: MutableMultiArray<T, DN>) : Tensor<T> { + @Suppress("UNCHECKED_CAST") + override val type: SafeType<T> get() = array.dtype.type as SafeType<T> + override val shape: ShapeND get() = ShapeND(array.shape) @PerformancePitfall diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt index c5bbebfd8..468f1652d 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt @@ -26,7 +26,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( private val multikEngine: Engine, ) : TensorAlgebra<T, A> where T : Number, T : Comparable<T> { - public abstract val type: DataType + public abstract val dataType: DataType protected val multikMath: Math = multikEngine.getMath() protected val multikLinAl: LinAlg = multikEngine.getLinAlg() @@ -35,7 +35,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( @OptIn(UnsafeKMathAPI::class) override fun mutableStructureND(shape: ShapeND, initializer: A.(IntArray) -> T): MultikTensor<T> { val strides = ColumnStrides(shape) - val memoryView = initMemoryView<T>(strides.linearSize, type) + val memoryView = initMemoryView<T>(strides.linearSize, dataType) strides.asSequence().forEachIndexed { linearIndex, tensorIndex -> memoryView[linearIndex] = elementAlgebra.initializer(tensorIndex) } @@ -44,7 +44,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( @OptIn(PerformancePitfall::class, UnsafeKMathAPI::class) override fun StructureND<T>.map(transform: A.(T) -> T): MultikTensor<T> = if (this is MultikTensor) { - val data = initMemoryView<T>(array.size, type) + val data = initMemoryView<T>(array.size, dataType) var count = 0 for (el in array) data[count++] = elementAlgebra.transform(el) NDArray(data, shape = shape.asArray(), dim = array.dim).wrap() @@ -58,7 +58,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( override fun StructureND<T>.mapIndexed(transform: A.(index: IntArray, T) -> T): MultikTensor<T> = if (this is MultikTensor) { val array = asMultik().array - val data = initMemoryView<T>(array.size, type) + val data = initMemoryView<T>(array.size, dataType) val indexIter = array.multiIndices.iterator() var index = 0 for (item in array) { @@ -95,7 +95,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( require(left.shape.contentEquals(right.shape)) { "ND array shape mismatch" } //TODO replace by ShapeMismatchException val leftArray = left.asMultik().array val rightArray = right.asMultik().array - val data = initMemoryView<T>(leftArray.size, type) + val data = initMemoryView<T>(leftArray.size, dataType) var counter = 0 val leftIterator = leftArray.iterator() val rightIterator = rightArray.iterator() @@ -114,7 +114,7 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( public fun StructureND<T>.asMultik(): MultikTensor<T> = if (this is MultikTensor) { this } else { - val res = mk.zeros<T, DN>(shape.asArray(), type).asDNArray() + val res = mk.zeros<T, DN>(shape.asArray(), dataType).asDNArray() for (index in res.multiIndices) { res[index] = this[index] } @@ -296,7 +296,7 @@ public abstract class MultikDivisionTensorAlgebra<T, A : Field<T>>( @OptIn(UnsafeKMathAPI::class) override fun T.div(arg: StructureND<T>): MultikTensor<T> = - Multik.ones<T, DN>(arg.shape.asArray(), type).apply { divAssign(arg.asMultik().array) }.wrap() + Multik.ones<T, DN>(arg.shape.asArray(), dataType).apply { divAssign(arg.asMultik().array) }.wrap() override fun StructureND<T>.div(arg: T): MultikTensor<T> = asMultik().array.div(arg).wrap() diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt index 8025428e6..527c8abae 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -9,20 +9,21 @@ import space.kscience.attributes.* import space.kscience.kmath.expressions.DifferentiableExpression import space.kscience.kmath.expressions.Symbol -public class OptimizationValue<T>(public val value: T) : OptimizationFeature { - override fun toString(): String = "Value($value)" -} +public class OptimizationValue<V>(type: SafeType<V>) : PolymorphicAttribute<V>(type) -public enum class FunctionOptimizationTarget { +public enum class OptimizationDirection { MAXIMIZE, MINIMIZE } +public object FunctionOptimizationTarget: OptimizationAttribute<OptimizationDirection> + public class FunctionOptimization<T>( - override val attributes: Attributes, public val expression: DifferentiableExpression<T>, + override val attributes: Attributes, ) : OptimizationProblem<T> { + override val type: SafeType<T> get() = expression.type override fun equals(other: Any?): Boolean { if (this === other) return true @@ -47,36 +48,52 @@ public class FunctionOptimization<T>( public companion object } +public fun <T> FunctionOptimization( + expression: DifferentiableExpression<T>, + attributeBuilder: AttributesBuilder<FunctionOptimization<T>>.() -> Unit, +): FunctionOptimization<T> = FunctionOptimization(expression, Attributes(attributeBuilder)) - -public class OptimizationPrior<T>(type: SafeType<T>): +public class OptimizationPrior<T> : PolymorphicAttribute<DifferentiableExpression<T>>(safeTypeOf()), Attribute<DifferentiableExpression<T>> -//public val <T> FunctionOptimization.Companion.Optimization get() = - - -public fun <T> FunctionOptimization<T>.withFeatures( - vararg newFeature: OptimizationFeature, +public fun <T> FunctionOptimization<T>.withAttributes( + modifier: AttributesBuilder<FunctionOptimization<T>>.() -> Unit, ): FunctionOptimization<T> = FunctionOptimization( - attributes.with(*newFeature), expression, + attributes.modify(modifier), ) /** * Optimizes differentiable expression using specific [optimizer] form given [startingPoint]. */ -public suspend fun <T : Any> DifferentiableExpression<T>.optimizeWith( +public suspend fun <T> DifferentiableExpression<T>.optimizeWith( optimizer: Optimizer<T, FunctionOptimization<T>>, startingPoint: Map<Symbol, T>, - vararg features: OptimizationFeature, + modifier: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {}, ): FunctionOptimization<T> { - val problem = FunctionOptimization<T>(FeatureSet.of(OptimizationStartPoint(startingPoint), *features), this) + val problem = FunctionOptimization(this){ + startAt(startingPoint) + modifier() + } return optimizer.optimize(problem) } public val <T> FunctionOptimization<T>.resultValueOrNull: T? - get() = getFeature<OptimizationResult<T>>()?.point?.let { expression(it) } + get() = attributes[OptimizationResult<T>()]?.let { expression(it) } public val <T> FunctionOptimization<T>.resultValue: T - get() = resultValueOrNull ?: error("Result is not present in $this") \ No newline at end of file + get() = resultValueOrNull ?: error("Result is not present in $this") + + +public suspend fun <T> DifferentiableExpression<T>.optimizeWith( + optimizer: Optimizer<T, FunctionOptimization<T>>, + vararg startingPoint: Pair<Symbol, T>, + builder: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {}, +): FunctionOptimization<T> { + val problem = FunctionOptimization<T>(this) { + startAt(mapOf(*startingPoint)) + builder() + } + return optimizer.optimize(problem) +} diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt deleted file mode 100644 index 0459d46ee..000000000 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2018-2022 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.optimization - -import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.data.XYColumnarData -import space.kscience.kmath.expressions.DifferentiableExpression -import space.kscience.kmath.expressions.Symbol -import space.kscience.kmath.misc.FeatureSet - -public abstract class OptimizationBuilder<T, R : OptimizationProblem<T>> { - public val features: MutableList<OptimizationFeature> = ArrayList() - - public fun addFeature(feature: OptimizationFeature) { - features.add(feature) - } - - public inline fun <reified T : OptimizationFeature> updateFeature(update: (T?) -> T) { - val existing = features.find { it.key == T::class } as? T - val new = update(existing) - if (existing != null) { - features.remove(existing) - } - addFeature(new) - } - - public abstract fun build(): R -} - -public fun <T> OptimizationBuilder<T, *>.startAt(startingPoint: Map<Symbol, T>) { - addFeature(OptimizationStartPoint(startingPoint)) -} - -public class FunctionOptimizationBuilder<T>( - private val expression: DifferentiableExpression<T>, -) : OptimizationBuilder<T, FunctionOptimization<T>>() { - override fun build(): FunctionOptimization<T> = FunctionOptimization(FeatureSet.of(features), expression) -} - -public fun <T> FunctionOptimization( - expression: DifferentiableExpression<T>, - builder: FunctionOptimizationBuilder<T>.() -> Unit, -): FunctionOptimization<T> = FunctionOptimizationBuilder(expression).apply(builder).build() - -public suspend fun <T> DifferentiableExpression<T>.optimizeWith( - optimizer: Optimizer<T, FunctionOptimization<T>>, - startingPoint: Map<Symbol, T>, - builder: FunctionOptimizationBuilder<T>.() -> Unit = {}, -): FunctionOptimization<T> { - val problem = FunctionOptimization<T>(this) { - startAt(startingPoint) - builder() - } - return optimizer.optimize(problem) -} - -public suspend fun <T> DifferentiableExpression<T>.optimizeWith( - optimizer: Optimizer<T, FunctionOptimization<T>>, - vararg startingPoint: Pair<Symbol, T>, - builder: FunctionOptimizationBuilder<T>.() -> Unit = {}, -): FunctionOptimization<T> { - val problem = FunctionOptimization<T>(this) { - startAt(mapOf(*startingPoint)) - builder() - } - return optimizer.optimize(problem) -} - - -@OptIn(UnstableKMathAPI::class) -public class XYOptimizationBuilder( - public val data: XYColumnarData<Double, Double, Double>, - public val model: DifferentiableExpression<Double>, -) : OptimizationBuilder<Double, XYFit>() { - - public var pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY - public var pointWeight: PointWeight = PointWeight.byYSigma - - override fun build(): XYFit = XYFit( - data, - model, - FeatureSet.of(features), - pointToCurveDistance, - pointWeight - ) -} - -@OptIn(UnstableKMathAPI::class) -public fun XYOptimization( - data: XYColumnarData<Double, Double, Double>, - model: DifferentiableExpression<Double>, - builder: XYOptimizationBuilder.() -> Unit, -): XYFit = XYOptimizationBuilder(data, model).apply(builder).build() \ No newline at end of file diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt index 46ba8c1c0..49f3bb266 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt @@ -6,64 +6,53 @@ package space.kscience.kmath.optimization import space.kscience.attributes.* -import space.kscience.kmath.expressions.DifferentiableExpression import space.kscience.kmath.expressions.NamedMatrix import space.kscience.kmath.expressions.Symbol -import space.kscience.kmath.misc.* -import kotlin.reflect.KClass +import space.kscience.kmath.misc.Loggable -public interface OptimizationAttribute<T>: Attribute<T> +public interface OptimizationAttribute<T> : Attribute<T> -public interface OptimizationProblem<T> : AttributeContainer +public interface OptimizationProblem<T> : AttributeContainer, WithType<T> -public inline fun <reified F : OptimizationFeature> OptimizationProblem<*>.getFeature(): F? = getFeature(F::class) - -public open class OptimizationStartPoint<T>(public val point: Map<Symbol, T>) : OptimizationFeature { - override fun toString(): String = "StartPoint($point)" -} - -/** - * Covariance matrix for - */ -public class OptimizationCovariance<T>(public val covariance: NamedMatrix<T>) : OptimizationFeature { - override fun toString(): String = "Covariance($covariance)" -} +public class OptimizationStartPoint<T> : OptimizationAttribute<Map<Symbol, T>>, + PolymorphicAttribute<Map<Symbol, T>>(safeTypeOf()) /** * Get the starting point for optimization. Throws error if not defined. */ public val <T> OptimizationProblem<T>.startPoint: Map<Symbol, T> - get() = getFeature<OptimizationStartPoint<T>>()?.point - ?: error("Starting point not defined in $this") + get() = attributes[OptimizationStartPoint()] ?: error("Starting point not defined in $this") -public open class OptimizationResult<T>(public val point: Map<Symbol, T>) : OptimizationFeature { - override fun toString(): String = "Result($point)" +public fun <T> AttributesBuilder<OptimizationProblem<T>>.startAt(startingPoint: Map<Symbol, T>) { + set(::OptimizationStartPoint, startingPoint) } -public val <T> OptimizationProblem<T>.resultPointOrNull: Map<Symbol, T>? - get() = getFeature<OptimizationResult<T>>()?.point -public val <T> OptimizationProblem<T>.resultPoint: Map<Symbol, T> - get() = resultPointOrNull ?: error("Result is not present in $this") +/** + * Covariance matrix for optimization + */ +public class OptimizationCovariance<T> : OptimizationAttribute<NamedMatrix<T>>, + PolymorphicAttribute<NamedMatrix<T>>(safeTypeOf()) -public class OptimizationLog(private val loggable: Loggable) : Loggable by loggable, OptimizationFeature { - override fun toString(): String = "Log($loggable)" -} + +public class OptimizationResult<T>() : OptimizationAttribute<Map<Symbol, T>>, + PolymorphicAttribute<Map<Symbol, T>>(safeTypeOf()) + +public val <T> OptimizationProblem<T>.resultOrNull: Map<Symbol, T>? get() = attributes[OptimizationResult()] + +public val <T> OptimizationProblem<T>.result: Map<Symbol, T> + get() = resultOrNull ?: error("Result is not present in $this") + +public object OptimizationLog : OptimizationAttribute<Loggable> /** * Free parameters of the optimization */ -public class OptimizationParameters(public val symbols: List<Symbol>) : OptimizationFeature { - public constructor(vararg symbols: Symbol) : this(listOf(*symbols)) - - override fun toString(): String = "Parameters($symbols)" -} +public object OptimizationParameters : OptimizationAttribute<List<Symbol>> /** * Maximum allowed number of iterations */ -public class OptimizationIterations(public val maxIterations: Int) : OptimizationFeature { - override fun toString(): String = "Iterations($maxIterations)" -} +public object OptimizationIterations : OptimizationAttribute<Int> diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt index e922fd423..9b715f95d 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt @@ -16,13 +16,7 @@ import space.kscience.kmath.structures.Float64Buffer import kotlin.math.abs -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)" -} +public object QowRuns: OptimizationAttribute<Int> /** @@ -69,7 +63,7 @@ public object QowOptimizer : Optimizer<Double, XYFit> { } val prior: DifferentiableExpression<Double>? - get() = problem.getFeature<OptimizationPrior<Double>>()?.withDefaultArgs(allParameters) + get() = problem.attributes[OptimizationPrior<Double>()]?.withDefaultArgs(allParameters) override fun toString(): String = freeParameters.toString() } @@ -176,7 +170,7 @@ public object QowOptimizer : Optimizer<Double, XYFit> { fast: Boolean = false, ): QoWeight { - val logger = problem.getFeature<OptimizationLog>() + val logger = problem.attributes[OptimizationLog] var dis: Double //discrepancy value @@ -231,7 +225,7 @@ public object QowOptimizer : Optimizer<Double, XYFit> { } private fun QoWeight.covariance(): NamedMatrix<Double> { - val logger = problem.getFeature<OptimizationLog>() + val logger = problem.attributes[OptimizationLog] logger?.log { """ @@ -257,11 +251,11 @@ public object QowOptimizer : Optimizer<Double, XYFit> { } override suspend fun optimize(problem: XYFit): XYFit { - val qowRuns = problem.getFeature<QowRuns>()?.runs ?: 2 - val iterations = problem.getFeature<OptimizationIterations>()?.maxIterations ?: 50 + val qowRuns = problem.attributes[QowRuns] ?: 2 + val iterations = problem.attributes[OptimizationIterations] ?: 50 - val freeParameters: Map<Symbol, Double> = problem.getFeature<OptimizationParameters>()?.let { op -> - problem.startPoint.filterKeys { it in op.symbols } + val freeParameters: Map<Symbol, Double> = problem.attributes[OptimizationParameters]?.let { symbols -> + problem.startPoint.filterKeys { it in symbols } } ?: problem.startPoint var qow = QoWeight(problem, freeParameters) @@ -271,6 +265,9 @@ public object QowOptimizer : Optimizer<Double, XYFit> { res = qow.newtonianRun(maxSteps = iterations) } val covariance = res.covariance() - return res.problem.withFeature(OptimizationResult(res.freeParameters), OptimizationCovariance(covariance)) + return res.problem.withAttributes { + set(OptimizationResult(), res.freeParameters) + set(OptimizationCovariance(), covariance) + } } } \ No newline at end of file diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt index cda37af4f..59143c338 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt @@ -2,37 +2,41 @@ * Copyright 2018-2022 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. */ -@file:OptIn(UnstableKMathAPI::class) +@file:OptIn(UnstableKMathAPI::class, UnstableKMathAPI::class) package space.kscience.kmath.optimization +import space.kscience.attributes.* import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.data.indices import space.kscience.kmath.expressions.* -import space.kscience.kmath.misc.FeatureSet import space.kscience.kmath.misc.Loggable +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.ExtendedField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.bindSymbol import kotlin.math.pow /** * Specify the way to compute distance from point to the curve as DifferentiableExpression */ -public interface PointToCurveDistance : OptimizationFeature { +public interface PointToCurveDistance { public fun distance(problem: XYFit, index: Int): DifferentiableExpression<Double> - public companion object { + public companion object : OptimizationAttribute<PointToCurveDistance> { public val byY: PointToCurveDistance = object : PointToCurveDistance { override fun distance(problem: XYFit, index: Int): DifferentiableExpression<Double> { val x = problem.data.x[index] val y = problem.data.y[index] return object : DifferentiableExpression<Double> { + override val type: SafeType<Double> get() = DoubleField.type + override fun derivativeOrNull( symbols: List<Symbol>, ): Expression<Double>? = problem.model.derivativeOrNull(symbols)?.let { derivExpression -> - Expression { arguments -> + Expression(DoubleField.type) { arguments -> derivExpression.invoke(arguments + (Symbol.x to x)) } } @@ -51,18 +55,21 @@ public interface PointToCurveDistance : OptimizationFeature { * Compute a wight of the point. The more the weight, the more impact this point will have on the fit. * By default, uses Dispersion^-1 */ -public interface PointWeight : OptimizationFeature { +public interface PointWeight { public fun weight(problem: XYFit, index: Int): DifferentiableExpression<Double> - public companion object { + public companion object : OptimizationAttribute<PointWeight> { public fun bySigma(sigmaSymbol: Symbol): PointWeight = object : PointWeight { override fun weight(problem: XYFit, index: Int): DifferentiableExpression<Double> = object : DifferentiableExpression<Double> { + override val type: SafeType<Double> get() = DoubleField.type + override fun invoke(arguments: Map<Symbol, Double>): Double { return problem.data[sigmaSymbol]?.get(index)?.pow(-2) ?: 1.0 } - override fun derivativeOrNull(symbols: List<Symbol>): Expression<Double> = Expression { 0.0 } + override fun derivativeOrNull(symbols: List<Symbol>): Expression<Double> = + Expression(DoubleField.type) { 0.0 } } override fun toString(): String = "PointWeightBySigma($sigmaSymbol)" @@ -79,41 +86,52 @@ public interface PointWeight : OptimizationFeature { public class XYFit( public val data: XYColumnarData<Double, Double, Double>, public val model: DifferentiableExpression<Double>, - override val attributes: FeatureSet<OptimizationFeature>, + override val attributes: Attributes, internal val pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY, internal val pointWeight: PointWeight = PointWeight.byYSigma, public val xSymbol: Symbol = Symbol.x, ) : OptimizationProblem<Double> { + + override val type: SafeType<Double> get() = Float64Field.type + public fun distance(index: Int): DifferentiableExpression<Double> = pointToCurveDistance.distance(this, index) public fun weight(index: Int): DifferentiableExpression<Double> = pointWeight.weight(this, index) } -public fun XYFit.withFeature(vararg features: OptimizationFeature): XYFit { - return XYFit(data, model, this.attributes.with(*features), pointToCurveDistance, pointWeight) -} + +public fun XYOptimization( + data: XYColumnarData<Double, Double, Double>, + model: DifferentiableExpression<Double>, + builder: AttributesBuilder<XYFit>.() -> Unit, +): XYFit = XYFit(data, model, Attributes(builder)) + +public fun XYFit.withAttributes( + modifier: AttributesBuilder<XYFit>.() -> Unit, +): XYFit = XYFit(data, model, attributes.modify(modifier), pointToCurveDistance, pointWeight, xSymbol) public suspend fun XYColumnarData<Double, Double, Double>.fitWith( optimizer: Optimizer<Double, XYFit>, modelExpression: DifferentiableExpression<Double>, startingPoint: Map<Symbol, Double>, - vararg features: OptimizationFeature = emptyArray(), + attributes: Attributes = Attributes.EMPTY, xSymbol: Symbol = Symbol.x, pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY, pointWeight: PointWeight = PointWeight.byYSigma, ): XYFit { - var actualFeatures = FeatureSet.of(*features, OptimizationStartPoint(startingPoint)) - if (actualFeatures.getFeature<OptimizationLog>() == null) { - actualFeatures = actualFeatures.with(OptimizationLog(Loggable.console)) - } val problem = XYFit( this, modelExpression, - actualFeatures, + attributes.modify<XYFit> { + set(::OptimizationStartPoint, startingPoint) + if (!hasAny<OptimizationLog>()) { + set(OptimizationLog, Loggable.console) + } + }, pointToCurveDistance, pointWeight, - xSymbol + xSymbol, ) return optimizer.optimize(problem) } @@ -125,7 +143,7 @@ public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith( optimizer: Optimizer<Double, XYFit>, processor: AutoDiffProcessor<Double, I, A>, startingPoint: Map<Symbol, Double>, - vararg features: OptimizationFeature = emptyArray(), + attributes: Attributes = Attributes.EMPTY, xSymbol: Symbol = Symbol.x, pointToCurveDistance: PointToCurveDistance = PointToCurveDistance.byY, pointWeight: PointWeight = PointWeight.byYSigma, @@ -140,7 +158,7 @@ public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith( optimizer = optimizer, modelExpression = modelExpression, startingPoint = startingPoint, - features = features, + attributes = attributes, xSymbol = xSymbol, pointToCurveDistance = pointToCurveDistance, pointWeight = pointWeight @@ -152,7 +170,7 @@ public suspend fun <I : Any, A> XYColumnarData<Double, Double, Double>.fitWith( */ public val XYFit.chiSquaredOrNull: Double? get() { - val result = startPoint + (resultPointOrNull ?: return null) + val result = startPoint + (resultOrNull ?: return null) return data.indices.sumOf { index -> @@ -167,4 +185,4 @@ public val XYFit.chiSquaredOrNull: Double? } public val XYFit.dof: Int - get() = data.size - (getFeature<OptimizationParameters>()?.symbols?.size ?: startPoint.size) \ No newline at end of file + get() = data.size - (attributes[OptimizationParameters]?.size ?: startPoint.size) \ No newline at end of file diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt index 40081ed81..aa77cdda6 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt @@ -5,6 +5,8 @@ package space.kscience.kmath.optimization +import space.kscience.attributes.AttributesBuilder +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.data.XYColumnarData import space.kscience.kmath.data.indices @@ -12,6 +14,7 @@ import space.kscience.kmath.expressions.DifferentiableExpression import space.kscience.kmath.expressions.Expression import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.expressions.derivative +import space.kscience.kmath.operations.Float64Field import kotlin.math.PI import kotlin.math.ln import kotlin.math.pow @@ -22,7 +25,9 @@ private val oneOver2Pi = 1.0 / sqrt(2 * PI) @UnstableKMathAPI internal fun XYFit.logLikelihood(): DifferentiableExpression<Double> = object : DifferentiableExpression<Double> { - override fun derivativeOrNull(symbols: List<Symbol>): Expression<Double> = Expression { arguments -> + override val type: SafeType<Double> get() = Float64Field.type + + override fun derivativeOrNull(symbols: List<Symbol>): Expression<Double> = Expression(type) { arguments -> data.indices.sumOf { index -> val d = distance(index)(arguments) val weight = weight(index)(arguments) @@ -53,14 +58,18 @@ internal fun XYFit.logLikelihood(): DifferentiableExpression<Double> = object : */ @UnstableKMathAPI public suspend fun Optimizer<Double, FunctionOptimization<Double>>.maximumLogLikelihood(problem: XYFit): XYFit { - val functionOptimization = FunctionOptimization(problem.attributes, problem.logLikelihood()) - val result = optimize(functionOptimization.withFeatures(FunctionOptimizationTarget.MAXIMIZE)) - return XYFit(problem.data, problem.model, result.attributes) + val functionOptimization = FunctionOptimization(problem.logLikelihood(), problem.attributes) + val result = optimize( + functionOptimization.withAttributes { + FunctionOptimizationTarget(OptimizationDirection.MAXIMIZE) + } + ) + return XYFit(problem.data,problem.model, result.attributes) } @UnstableKMathAPI public suspend fun Optimizer<Double, FunctionOptimization<Double>>.maximumLogLikelihood( data: XYColumnarData<Double, Double, Double>, model: DifferentiableExpression<Double>, - builder: XYOptimizationBuilder.() -> Unit, + builder: AttributesBuilder<XYFit>.() -> Unit, ): XYFit = maximumLogLikelihood(XYOptimization(data, model, builder)) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt index 8a97114c3..d960fe210 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt @@ -5,10 +5,12 @@ package space.kscience.kmath.tensors.core +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.MutableStructureNDOfDouble import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.core.internal.toPrettyString @@ -88,6 +90,8 @@ public open class DoubleTensor( final override val source: OffsetDoubleBuffer, ) : BufferedTensor<Double>(shape), MutableStructureNDOfDouble { + override val type: SafeType<Double> get() = DoubleField.type + init { require(linearSize == source.size) { "Source buffer size must be equal tensor size" } } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt index 1066793a7..005bf5d2a 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt @@ -5,8 +5,10 @@ package space.kscience.kmath.tensors.core +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.operations.IntRing import space.kscience.kmath.structures.* /** @@ -24,6 +26,8 @@ public class OffsetIntBuffer( require(offset + size <= source.size) { "Maximum index must be inside source dimension" } } + override val type: SafeType<Int> get() = IntRing.type + override fun set(index: Int, value: Int) { require(index in 0 until size) { "Index must be in [0, size)" } source[index + offset] = value @@ -83,6 +87,8 @@ public class IntTensor( require(linearSize == source.size) { "Source buffer size must be equal tensor size" } } + override val type: SafeType<Int> get() = IntRing.type + public constructor(shape: ShapeND, buffer: Int32Buffer) : this(shape, OffsetIntBuffer(buffer, 0, buffer.size)) @OptIn(PerformancePitfall::class) From 24b934eab7c43c43a5748071ace91f80d4350c22 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 22 Nov 2023 14:32:56 +0300 Subject: [PATCH 063/103] Add `Buffer.asList()` --- CHANGELOG.md | 1 + .../space/kscience/kmath/structures/Buffer.kt | 41 +++++----- .../kscience/kmath/structures/BufferList.kt | 81 +++++++++++++++++++ .../space/kscience/kmath/ejml/_generated.kt | 21 +---- 4 files changed, 107 insertions(+), 37 deletions(-) create mode 100644 kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferList.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 58df6f1bb..9498cc4ce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Float32 geometries. - New Attributes-kt module that could be used as stand-alone. It declares. type-safe attributes containers. - Explicit `mutableStructureND` builders for mutable structures. +- `Buffer.asList()` zero-copy transformation. ### Changed - Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index 26e238145..df9d3c0eb 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -101,32 +101,13 @@ public interface Buffer<out T> : WithSize, WithType<T> { } } -/** - * Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([Int32Buffer], - * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. - * - * The [size] is specified, and each element is calculated by calling the specified [initializer] function. - */ -@Suppress("UNCHECKED_CAST") -public inline fun <reified T> Buffer(size: Int, initializer: (Int) -> T): Buffer<T> { - val type = safeTypeOf<T>() - return when (type.kType) { - typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T> - typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T> - typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> - typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> - typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> - else -> List(size, initializer).asBuffer(type) - } -} - /** * Creates a [Buffer] of given [type]. If the type is primitive, specialized buffers are used ([Int32Buffer], * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. * * The [size] is specified, and each element is calculated by calling the specified [initializer] function. */ -@Suppress("UNCHECKED_CAST") +@Suppress("UNCHECKED_CAST", "DuplicatedCode") public fun <T> Buffer( type: SafeType<T>, size: Int, @@ -140,6 +121,26 @@ public fun <T> Buffer( else -> List(size, initializer).asBuffer(type) } +/** + * Creates a [Buffer] of given type [T]. If the type is primitive, specialized buffers are used ([Int32Buffer], + * [Float64Buffer], etc.), [ListBuffer] is returned otherwise. + * + * The [size] is specified, and each element is calculated by calling the specified [initializer] function. + */ +@Suppress("UNCHECKED_CAST", "DuplicatedCode") +public inline fun <reified T> Buffer(size: Int, initializer: (Int) -> T): Buffer<T> { + //code duplication here because we want to inline initializers + val type = safeTypeOf<T>() + return when (type.kType) { + typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as Buffer<T> + typeOf<Short>() -> MutableBuffer.short(size) { initializer(it) as Short } as Buffer<T> + typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> + typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> + typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> + else -> List(size, initializer).asBuffer(type) + } +} + /** * Returns an [IntRange] of the valid indices for this [Buffer]. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferList.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferList.kt new file mode 100644 index 000000000..ff668589e --- /dev/null +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferList.kt @@ -0,0 +1,81 @@ +/* + * Copyright 2018-2023 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.structures + +import kotlin.jvm.JvmInline + +@JvmInline +private value class BufferList<T>(val buffer: Buffer<T>) : List<T> { + override val size: Int get() = buffer.size + + override fun get(index: Int): T = buffer[index] + + override fun isEmpty(): Boolean = buffer.size == 0 + + override fun iterator(): Iterator<T> = buffer.iterator() + + override fun listIterator(index: Int): ListIterator<T> = object : ListIterator<T> { + var currentIndex = index + + override fun hasNext(): Boolean = currentIndex < buffer.size - 1 + + override fun hasPrevious(): Boolean = currentIndex > 0 + + override fun next(): T { + if (!hasNext()) throw NoSuchElementException() + return get(currentIndex++) + } + + override fun nextIndex(): Int = currentIndex + + override fun previous(): T { + if (!hasPrevious()) throw NoSuchElementException() + return get(--currentIndex) + } + + override fun previousIndex(): Int = currentIndex - 1 + + } + + override fun listIterator(): ListIterator<T> = listIterator(0) + + override fun subList(fromIndex: Int, toIndex: Int): List<T> = + buffer.slice(fromIndex..toIndex).asList() + + override fun lastIndexOf(element: T): Int { + for (i in buffer.indices.reversed()) { + if (buffer[i] == element) return i + } + return -1 + } + + override fun indexOf(element: T): Int { + for (i in buffer.indices) { + if (buffer[i] == element) return i + } + return -1 + } + + override fun containsAll(elements: Collection<T>): Boolean { + val remainingElements = HashSet(elements) + for (e in buffer) { + if (e in remainingElements) { + remainingElements.remove(e) + } + if (remainingElements.isEmpty()) { + return true + } + } + return false + } + + override fun contains(element: T): Boolean = indexOf(element) >= 0 +} + +/** + * Returns a zero-copy list that reflects the content of the buffer. + */ +public fun <T> Buffer<T>.asList(): List<T> = BufferList(this) \ No newline at end of file diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 882df9536..3a44a9e64 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -24,8 +24,6 @@ import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.nd.Structure2D -import space.kscience.kmath.nd.StructureAttribute import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.operations.Float32Field import space.kscience.kmath.operations.Float64Field @@ -80,6 +78,7 @@ public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatr } + /** * [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and * [DMatrixRMaj] matrices. @@ -218,18 +217,6 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this - override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Double>, attribute: A): V? { - val origin = structure.toEjml().origin - return when(attribute){ - Inverted -> { - val res = origin.copy() - CommonOps_DDRM.invert(res) - res.wrapMatrix() - } - else-> - } - } - @UnstableKMathAPI override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { structure.getFeature(type)?.let { return it } @@ -330,7 +317,7 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri } } -import org.checkerframework.checker.guieffect.qual.SafeType + /** * [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and @@ -570,7 +557,7 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix } } -import org.checkerframework.checker.guieffect.qual.SafeType + /** * [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and @@ -805,7 +792,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri } } -import org.checkerframework.checker.guieffect.qual.SafeType + /** * [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and From cc4159be6706e7ca8de0fbcff581581785f898b7 Mon Sep 17 00:00:00 2001 From: Gleb Minaev <43728100+lounres@users.noreply.github.com> Date: Fri, 5 Jan 2024 01:50:27 +0300 Subject: [PATCH 064/103] Update/Add copyright comments. Regenerate code for kmath-ejml. --- .../benchmarks/ExpressionsInterpretersBenchmark.kt | 2 +- .../kscience/kmath/benchmarks/ArrayBenchmark.kt | 2 +- .../kscience/kmath/benchmarks/BigIntBenchmark.kt | 2 +- .../kscience/kmath/benchmarks/BufferBenchmark.kt | 2 +- .../kscience/kmath/benchmarks/DotBenchmark.kt | 2 +- .../benchmarks/ExpressionsInterpretersBenchmark.kt | 2 +- .../kmath/benchmarks/IntegrationBenchmark.kt | 2 +- .../kscience/kmath/benchmarks/JafamaBenchmark.kt | 2 +- .../kmath/benchmarks/MatrixInverseBenchmark.kt | 2 +- .../kscience/kmath/benchmarks/NDFieldBenchmark.kt | 2 +- .../kmath/benchmarks/TensorAlgebraBenchmark.kt | 2 +- .../kscience/kmath/benchmarks/ViktorBenchmark.kt | 2 +- .../kmath/benchmarks/ViktorLogBenchmark.kt | 2 +- .../space/kscience/kmath/benchmarks/globals.kt | 2 +- .../space/kscience/kmath/benchmarks/JmhReport.kt | 2 +- .../kmath/benchmarks/addBenchmarkProperties.kt | 2 +- .../kscience/kmath/ejml/codegen/ejmlCodegen.kt | 6 +++--- docs/images/KM.svg | 2 +- docs/images/KM_mono.svg | 2 +- docs/images/KMath.svg | 2 +- docs/images/KMath_mono.svg | 2 +- .../space/kscience/kmath/ast/astRendering.kt | 2 +- .../kotlin/space/kscience/kmath/ast/expressions.kt | 2 +- .../space/kscience/kmath/ast/kotlingradSupport.kt | 2 +- .../space/kscience/kmath/ast/symjaSupport.kt | 2 +- .../space/kscience/kmath/expressions/autodiff.kt | 2 +- .../kotlin/space/kscience/kmath/fit/chiSquared.kt | 2 +- .../main/kotlin/space/kscience/kmath/fit/qowFit.kt | 2 +- .../space/kscience/kmath/functions/integrate.kt | 2 +- .../space/kscience/kmath/functions/interpolate.kt | 2 +- .../kscience/kmath/functions/interpolateSquare.kt | 2 +- .../kscience/kmath/functions/matrixIntegration.kt | 2 +- .../space/kscience/kmath/jafama/JafamaDemo.kt | 2 +- .../space/kscience/kmath/linear/dotPerformance.kt | 2 +- .../kotlin/space/kscience/kmath/linear/gradient.kt | 2 +- .../space/kscience/kmath/operations/BigIntDemo.kt | 2 +- .../space/kscience/kmath/operations/complexDemo.kt | 2 +- .../kscience/kmath/operations/mixedNDOperations.kt | 2 +- .../space/kscience/kmath/series/DateTimeSeries.kt | 2 +- .../space/kscience/kmath/series/analyzeDif.kt | 5 +++++ .../kscience/kmath/stat/DistributionBenchmark.kt | 2 +- .../space/kscience/kmath/stat/DistributionDemo.kt | 2 +- .../space/kscience/kmath/structures/ComplexND.kt | 2 +- .../space/kscience/kmath/structures/NDField.kt | 2 +- .../kmath/structures/StreamDoubleFieldND.kt | 2 +- .../kmath/structures/StructureReadBenchmark.kt | 2 +- .../kmath/structures/StructureWriteBenchmark.kt | 2 +- .../space/kscience/kmath/structures/buffers.kt | 2 +- .../kmath/structures/typeSafeDimensions.kt | 2 +- .../StaticLm/staticDifficultTest.kt | 2 +- .../LevenbergMarquardt/StaticLm/staticEasyTest.kt | 2 +- .../StaticLm/staticMiddleTest.kt | 2 +- .../LevenbergMarquardt/StreamingLm/streamLm.kt | 2 +- .../StreamingLm/streamingLmTest.kt | 2 +- .../LevenbergMarquardt/functionsToOptimize.kt | 2 +- .../space/kscience/kmath/tensors/OLSWithSVD.kt | 2 +- .../kotlin/space/kscience/kmath/tensors/PCA.kt | 2 +- .../kscience/kmath/tensors/dataSetNormalization.kt | 2 +- .../kmath/tensors/linearSystemSolvingWithLUP.kt | 2 +- .../kotlin/space/kscience/kmath/tensors/multik.kt | 2 +- .../space/kscience/kmath/tensors/neuralNetwork.kt | 2 +- .../kotlin/space/kscience/kmath/ast/TypedMst.kt | 2 +- .../space/kscience/kmath/ast/evaluateConstants.kt | 2 +- .../kotlin/space/kscience/kmath/ast/parser.kt | 2 +- .../kmath/ast/rendering/LatexSyntaxRenderer.kt | 2 +- .../kmath/ast/rendering/MathMLSyntaxRenderer.kt | 2 +- .../kscience/kmath/ast/rendering/MathRenderer.kt | 2 +- .../kscience/kmath/ast/rendering/MathSyntax.kt | 2 +- .../kscience/kmath/ast/rendering/SyntaxRenderer.kt | 2 +- .../space/kscience/kmath/ast/rendering/features.kt | 2 +- .../kmath/ast/rendering/multiplatformToString.kt | 2 +- .../space/kscience/kmath/ast/rendering/phases.kt | 2 +- .../ast/TestCompilerConsistencyWithInterpreter.kt | 2 +- .../kscience/kmath/ast/TestCompilerOperations.kt | 2 +- .../kscience/kmath/ast/TestCompilerVariables.kt | 2 +- .../kotlin/space/kscience/kmath/ast/TestFolding.kt | 2 +- .../kotlin/space/kscience/kmath/ast/TestParser.kt | 2 +- .../kscience/kmath/ast/TestParserPrecedence.kt | 2 +- .../kscience/kmath/ast/rendering/TestFeatures.kt | 2 +- .../kscience/kmath/ast/rendering/TestLatex.kt | 2 +- .../kscience/kmath/ast/rendering/TestMathML.kt | 2 +- .../kscience/kmath/ast/rendering/TestStages.kt | 2 +- .../kscience/kmath/ast/rendering/TestUtils.kt | 2 +- .../kotlin/space/kscience/kmath/ast/utils.kt | 2 +- .../kmath/ast/rendering/multiplatformToString.kt | 2 +- .../kotlin/space/kscience/kmath/estree/estree.kt | 2 +- .../kmath/estree/internal/ESTreeBuilder.kt | 2 +- .../estree/internal/astring/astring.typealises.kt | 2 +- .../kscience/kmath/internal/astring/astring.kt | 2 +- .../kmath/internal/astring/astring.typealises.kt | 2 +- .../space/kscience/kmath/internal/base64/base64.kt | 2 +- .../kmath/internal/binaryen/index.binaryen.kt | 2 +- .../binaryen/index.binaryen.typealiases.kt | 2 +- .../kscience/kmath/internal/emitter/emitter.kt | 2 +- .../kmath/internal/estree/estree.extensions.kt | 2 +- .../space/kscience/kmath/internal/estree/estree.kt | 2 +- .../space/kscience/kmath/internal/stream/stream.kt | 2 +- .../kmath/internal/tsstdlib/lib.es2015.iterable.kt | 2 +- .../kscience/kmath/internal/tsstdlib/lib.es5.kt | 2 +- .../lib.dom.WebAssembly.module_dukat.kt | 2 +- .../webassembly/nonDeclarations.WebAssembly.kt | 2 +- .../kscience/kmath/wasm/internal/WasmBuilder.kt | 2 +- .../kmath/wasm/internal/f64StandardFunctions.kt | 2 +- .../kotlin/space/kscience/kmath/wasm/wasm.kt | 2 +- .../kotlin/space/kscience/kmath/ast/utils.kt | 2 +- .../space/kscience/kmath/wasm/TestWasmSpecific.kt | 2 +- .../jvmMain/kotlin/space/kscience/kmath/asm/asm.kt | 2 +- .../kscience/kmath/asm/internal/AsmBuilder.kt | 2 +- .../kmath/asm/internal/GenericAsmBuilder.kt | 2 +- .../kmath/asm/internal/PrimitiveAsmBuilder.kt | 2 +- .../kscience/kmath/asm/internal/codegenUtils.kt | 2 +- .../kscience/kmath/asm/internal/mapIntrinsics.kt | 2 +- .../kmath/ast/rendering/multiplatformToString.kt | 2 +- .../kotlin/space/kscience/kmath/ast/utils.kt | 2 +- .../kmath/ast/rendering/multiplatformToString.kt | 2 +- .../space/kscience/kmath/ast/runCompilerTest.kt | 2 +- .../kmath/commons/expressions/CmDsExpression.kt | 2 +- .../commons/integration/CMGaussRuleIntegrator.kt | 2 +- .../kmath/commons/integration/CMIntegrator.kt | 2 +- .../kscience/kmath/commons/linear/CMMatrix.kt | 2 +- .../kscience/kmath/commons/linear/CMSolver.kt | 2 +- .../kmath/commons/optimization/CMOptimizer.kt | 2 +- .../commons/random/CMRandomGeneratorWrapper.kt | 2 +- .../kmath/commons/transform/Transformations.kt | 2 +- .../DerivativeStructureExpressionTest.kt | 2 +- .../kmath/commons/integration/IntegrationTest.kt | 2 +- .../kmath/commons/optimization/OptimizeTest.kt | 2 +- .../kotlin/space/kscience/kmath/complex/Complex.kt | 2 +- .../space/kscience/kmath/complex/ComplexFieldND.kt | 2 +- .../space/kscience/kmath/complex/Quaternion.kt | 2 +- .../kmath/complex/ComplexBufferSpecTest.kt | 2 +- .../kscience/kmath/complex/ComplexFieldTest.kt | 2 +- .../space/kscience/kmath/complex/ComplexTest.kt | 2 +- .../kmath/complex/ExpressionFieldForComplexTest.kt | 2 +- .../space/kscience/kmath/complex/QuaternionTest.kt | 2 +- .../space/kscience/kmath/data/ColumnarData.kt | 2 +- .../space/kscience/kmath/data/XYColumnarData.kt | 2 +- .../kscience/kmath/data/XYErrorColumnarData.kt | 2 +- .../space/kscience/kmath/data/XYZColumnarData.kt | 2 +- .../kotlin/space/kscience/kmath/domains/Domain.kt | 2 +- .../space/kscience/kmath/domains/Domain1D.kt | 2 +- .../space/kscience/kmath/domains/Float64Domain.kt | 2 +- .../kscience/kmath/domains/HyperSquareDomain.kt | 2 +- .../kscience/kmath/domains/UnconstrainedDomain.kt | 2 +- .../space/kscience/kmath/expressions/DSAlgebra.kt | 2 +- .../space/kscience/kmath/expressions/DSCompiler.kt | 2 +- .../kmath/expressions/DifferentiableExpression.kt | 2 +- .../space/kscience/kmath/expressions/Expression.kt | 2 +- .../kmath/expressions/ExpressionWithDefault.kt | 2 +- .../expressions/FunctionalExpressionAlgebra.kt | 2 +- .../kotlin/space/kscience/kmath/expressions/MST.kt | 2 +- .../space/kscience/kmath/expressions/MstAlgebra.kt | 2 +- .../kscience/kmath/expressions/NamedMatrix.kt | 2 +- .../kscience/kmath/expressions/SimpleAutoDiff.kt | 2 +- .../space/kscience/kmath/expressions/Symbol.kt | 2 +- .../kscience/kmath/expressions/SymbolIndexer.kt | 2 +- .../kscience/kmath/linear/BufferedLinearSpace.kt | 2 +- .../kscience/kmath/linear/Float64LinearSpace.kt | 2 +- .../space/kscience/kmath/linear/LinearSolver.kt | 2 +- .../space/kscience/kmath/linear/LinearSpace.kt | 2 +- .../kscience/kmath/linear/LupDecomposition.kt | 2 +- .../space/kscience/kmath/linear/MatrixBuilder.kt | 2 +- .../space/kscience/kmath/linear/MatrixFeatures.kt | 2 +- .../space/kscience/kmath/linear/MatrixWrapper.kt | 2 +- .../space/kscience/kmath/linear/VirtualMatrix.kt | 2 +- .../kotlin/space/kscience/kmath/misc/Featured.kt | 2 +- .../space/kscience/kmath/misc/collections.kt | 2 +- .../kotlin/space/kscience/kmath/misc/cumulative.kt | 2 +- .../kotlin/space/kscience/kmath/misc/logging.kt | 2 +- .../kotlin/space/kscience/kmath/misc/numbers.kt | 2 +- .../kotlin/space/kscience/kmath/misc/sorting.kt | 2 +- .../kotlin/space/kscience/kmath/nd/AlgebraND.kt | 2 +- .../space/kscience/kmath/nd/BufferAlgebraND.kt | 2 +- .../kotlin/space/kscience/kmath/nd/BufferND.kt | 2 +- .../space/kscience/kmath/nd/Float64FieldND.kt | 2 +- .../kotlin/space/kscience/kmath/nd/Int16RingND.kt | 2 +- .../kotlin/space/kscience/kmath/nd/IntRingND.kt | 2 +- .../space/kscience/kmath/nd/PermutedStructureND.kt | 2 +- .../kotlin/space/kscience/kmath/nd/ShapeIndices.kt | 2 +- .../kotlin/space/kscience/kmath/nd/ShapeND.kt | 2 +- .../kotlin/space/kscience/kmath/nd/Structure1D.kt | 2 +- .../kotlin/space/kscience/kmath/nd/Structure2D.kt | 2 +- .../kotlin/space/kscience/kmath/nd/StructureND.kt | 2 +- .../space/kscience/kmath/nd/VirtualStructureND.kt | 2 +- .../space/kscience/kmath/nd/algebraNDExtentions.kt | 2 +- .../kotlin/space/kscience/kmath/nd/operationsND.kt | 2 +- .../kscience/kmath/nd/primitiveStructureND.kt | 2 +- .../space/kscience/kmath/operations/Algebra.kt | 2 +- .../space/kscience/kmath/operations/BigInt.kt | 2 +- .../kscience/kmath/operations/BufferAlgebra.kt | 2 +- .../kmath/operations/Float64BufferField.kt | 2 +- .../kscience/kmath/operations/Float64BufferOps.kt | 2 +- .../kscience/kmath/operations/LogicAlgebra.kt | 2 +- .../kscience/kmath/operations/NumericAlgebra.kt | 2 +- .../kmath/operations/OptionalOperations.kt | 2 +- .../kscience/kmath/operations/algebraExtensions.kt | 2 +- .../kscience/kmath/operations/integerFields.kt | 2 +- .../space/kscience/kmath/operations/numbers.kt | 2 +- .../space/kscience/kmath/structures/ArrayBuffer.kt | 2 +- .../space/kscience/kmath/structures/Buffer.kt | 2 +- .../kscience/kmath/structures/BufferAccessor2D.kt | 2 +- .../space/kscience/kmath/structures/BufferView.kt | 5 +++++ .../kscience/kmath/structures/FlaggedBuffer.kt | 2 +- .../kscience/kmath/structures/Float32Buffer.kt | 2 +- .../kscience/kmath/structures/Float64Buffer.kt | 2 +- .../space/kscience/kmath/structures/Int16Buffer.kt | 2 +- .../space/kscience/kmath/structures/Int32Buffer.kt | 2 +- .../space/kscience/kmath/structures/Int64Buffer.kt | 2 +- .../space/kscience/kmath/structures/Int8Buffer.kt | 2 +- .../space/kscience/kmath/structures/ListBuffer.kt | 2 +- .../kscience/kmath/structures/MemoryBuffer.kt | 2 +- .../kscience/kmath/structures/MutableBuffer.kt | 2 +- .../kscience/kmath/structures/bufferExtensions.kt | 2 +- .../kmath/structures/bufferPrimitiveAccess.kt | 5 +++++ .../space/kscience/kmath/structures/types.kt | 2 +- .../space/kscience/kmath/expressions/DSTest.kt | 2 +- .../kmath/expressions/ExpressionFieldTest.kt | 2 +- .../kscience/kmath/expressions/InterpretTest.kt | 2 +- .../kmath/expressions/SimpleAutoDiffTest.kt | 2 +- .../kscience/kmath/linear/DoubleLUSolverTest.kt | 2 +- .../space/kscience/kmath/linear/MatrixTest.kt | 2 +- .../space/kscience/kmath/misc/CumulativeKtTest.kt | 2 +- .../space/kscience/kmath/misc/PermSortTest.kt | 2 +- .../space/kscience/kmath/nd/NdOperationsTest.kt | 2 +- .../kotlin/space/kscience/kmath/nd/StridesTest.kt | 2 +- .../kscience/kmath/operations/BigIntAlgebraTest.kt | 2 +- .../kmath/operations/BigIntConstructorTest.kt | 2 +- .../kmath/operations/BigIntConversionsTest.kt | 2 +- .../kmath/operations/BigIntOperationsTest.kt | 2 +- .../kscience/kmath/operations/DoubleFieldTest.kt | 2 +- .../kmath/structures/BufferExpandedTest.kt | 5 +++++ .../space/kscience/kmath/structures/NDFieldTest.kt | 2 +- .../kscience/kmath/structures/NumberNDFieldTest.kt | 2 +- .../kotlin/space/kscience/kmath/misc/numbers.kt | 2 +- .../space/kscience/kmath/operations/isInteger.kt | 2 +- .../kotlin/space/kscience/kmath/misc/numbersJVM.kt | 2 +- .../space/kscience/kmath/operations/BigNumbers.kt | 2 +- .../space/kscience/kmath/operations/isInteger.kt | 2 +- .../kotlin/space/kscience/kmath/misc/JBigTest.kt | 2 +- .../kotlin/space/kscience/kmath/misc/numbers.kt | 2 +- .../space/kscience/kmath/operations/isInteger.kt | 2 +- .../kotlin/space/kscience/kmath/misc/numbers.kt | 2 +- .../space/kscience/kmath/operations/isInteger.kt | 2 +- .../space/kscience/kmath/chains/BlockingChain.kt | 2 +- .../kscience/kmath/chains/BlockingDoubleChain.kt | 2 +- .../kscience/kmath/chains/BlockingIntChain.kt | 2 +- .../kotlin/space/kscience/kmath/chains/Chain.kt | 2 +- .../space/kscience/kmath/chains/flowExtra.kt | 2 +- .../kscience/kmath/coroutines/coroutinesExtra.kt | 2 +- .../space/kscience/kmath/streaming/BufferFlow.kt | 2 +- .../space/kscience/kmath/streaming/RingBuffer.kt | 2 +- .../kotlin/space/kscience/kmath/chains/ChainExt.kt | 2 +- .../kscience/kmath/structures/LazyStructureND.kt | 2 +- .../kscience/kmath/streaming/BufferFlowTest.kt | 2 +- .../kscience/kmath/streaming/RingBufferTest.kt | 2 +- .../space/kscience/kmath/dimensions/Dimension.kt | 2 +- .../space/kscience/kmath/dimensions/Wrappers.kt | 2 +- .../kscience/dimensions/DMatrixContextTest.kt | 2 +- .../space/kscience/kmath/dimensions/Dimension.kt | 2 +- .../space/kscience/kmath/dimensions/Dimension.kt | 2 +- .../space/kscience/kmath/dimensions/Dimension.kt | 2 +- .../space/kscience/kmath/ejml/EjmlLinearSpace.kt | 2 +- .../kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt | 2 +- .../kotlin/space/kscience/kmath/ejml/EjmlVector.kt | 2 +- .../kotlin/space/kscience/kmath/ejml/_generated.kt | 14 ++++++++++---- .../space/kscience/kmath/ejml/EjmlMatrixTest.kt | 2 +- .../space/kscience/kmath/ejml/EjmlVectorTest.kt | 2 +- .../space/kscience/kmath/real/DoubleVector.kt | 2 +- .../kotlin/space/kscience/kmath/real/RealMatrix.kt | 2 +- .../kotlin/space/kscience/kmath/real/dot.kt | 2 +- .../kotlin/space/kscience/kmath/real/grids.kt | 2 +- .../kotlin/space/kscience/kmath/real/realND.kt | 2 +- .../space/kscience/kmath/real/DoubleMatrixTest.kt | 2 +- .../space/kscience/kmath/real/DoubleVectorTest.kt | 2 +- .../kotlin/space/kscience/kmath/real/GridTest.kt | 2 +- .../space/kscience/kmath/functions/Piecewise.kt | 2 +- .../space/kscience/kmath/functions/Polynomial.kt | 2 +- .../kscience/kmath/functions/functionTypes.kt | 2 +- .../kmath/functions/polynomialConstructors.kt | 2 +- .../kscience/kmath/functions/polynomialUtil.kt | 2 +- .../kscience/kmath/integration/GaussIntegrator.kt | 2 +- .../integration/GaussIntegratorRuleFactory.kt | 2 +- .../space/kscience/kmath/integration/Integrand.kt | 2 +- .../space/kscience/kmath/integration/Integrator.kt | 2 +- .../kmath/integration/MultivariateIntegrand.kt | 2 +- .../kmath/integration/SimpsonIntegrator.kt | 2 +- .../kscience/kmath/integration/SplineIntegrator.kt | 2 +- .../kmath/integration/UnivariateIntegrand.kt | 2 +- .../kscience/kmath/interpolation/Interpolator.kt | 2 +- .../kmath/interpolation/LinearInterpolator.kt | 2 +- .../kmath/interpolation/SplineInterpolator.kt | 2 +- .../kscience/kmath/functions/PolynomialTest.kt | 2 +- .../kscience/kmath/functions/PolynomialUtilTest.kt | 2 +- .../kmath/functions/testUtils/IntModulo.kt | 2 +- .../kmath/functions/testUtils/IntModuloUtils.kt | 2 +- .../kscience/kmath/functions/testUtils/Rational.kt | 2 +- .../kscience/kmath/functions/testUtils/misc.kt | 2 +- .../kmath/integration/GaussIntegralTest.kt | 2 +- .../kmath/integration/SimpsonIntegralTest.kt | 2 +- .../kmath/integration/SplineIntegralTest.kt | 2 +- .../kmath/interpolation/LinearInterpolatorTest.kt | 2 +- .../kmath/interpolation/SplineInterpolatorTest.kt | 2 +- .../space/kscience/kmath/geometry/GeometrySpace.kt | 2 +- .../kotlin/space/kscience/kmath/geometry/Line.kt | 2 +- .../kscience/kmath/geometry/ReferenceFrame.kt | 2 +- .../space/kscience/kmath/geometry/Vector2D.kt | 2 +- .../space/kscience/kmath/geometry/Vector3D.kt | 2 +- .../kotlin/space/kscience/kmath/geometry/angles.kt | 2 +- .../kmath/geometry/euclidean2d/Circle2D.kt | 2 +- .../kmath/geometry/euclidean2d/Float32Space2D.kt | 2 +- .../kmath/geometry/euclidean2d/Float64Space2D.kt | 2 +- .../kscience/kmath/geometry/euclidean2d/Polygon.kt | 2 +- .../kmath/geometry/euclidean3d/Float32Space3D.kt | 2 +- .../kmath/geometry/euclidean3d/Float64Space3D.kt | 2 +- .../kmath/geometry/euclidean3d/rotations3D.kt | 2 +- .../kscience/kmath/geometry/floatPrecision.kt | 2 +- .../space/kscience/kmath/geometry/projections.kt | 2 +- .../kmath/geometry/quaternionOperations.kt | 2 +- .../space/kscience/kmath/geometry/AngleTest.kt | 5 +++++ .../kmath/geometry/Euclidean2DSpaceTest.kt | 2 +- .../kmath/geometry/Euclidean3DSpaceTest.kt | 2 +- .../kscience/kmath/geometry/ProjectionAlongTest.kt | 2 +- .../kmath/geometry/ProjectionOntoLineTest.kt | 2 +- .../space/kscience/kmath/geometry/RotationTest.kt | 2 +- .../space/kscience/kmath/geometry/Vector2DTest.kt | 2 +- .../space/kscience/kmath/geometry/Vector3DTest.kt | 2 +- .../space/kscience/kmath/geometry/testUtils.kt | 2 +- .../kscience/kmath/geometry/lineExtensions.kt | 2 +- .../space/kscience/kmath/histogram/Counter.kt | 2 +- .../space/kscience/kmath/histogram/Histogram.kt | 2 +- .../space/kscience/kmath/histogram/Histogram1D.kt | 2 +- .../space/kscience/kmath/histogram/HistogramND.kt | 2 +- .../kscience/kmath/histogram/UniformHistogram1D.kt | 2 +- .../kmath/histogram/UniformHistogramGroupND.kt | 2 +- .../kmath/histogram/MultivariateHistogramTest.kt | 2 +- .../kmath/histogram/UniformHistogram1DTest.kt | 2 +- .../kscience/kmath/histogram/TreeHistogramGroup.kt | 2 +- .../kscience/kmath/histogram/TreeHistogramTest.kt | 2 +- .../space/kscience/kmath/jafama/KMathJafama.kt | 2 +- .../space/kscience/kmath/jupyter/KMathJupyter.kt | 2 +- .../space/kscience/kmath/kotlingrad/KMathNumber.kt | 2 +- .../kmath/kotlingrad/KotlingradExpression.kt | 2 +- .../kscience/kmath/kotlingrad/scalarsAdapters.kt | 2 +- .../kscience/kmath/kotlingrad/AdaptingTests.kt | 2 +- .../kotlin/space/kscience/kmath/annotations.kt | 2 +- .../kotlin/space/kscience/kmath/memory/Memory.kt | 2 +- .../space/kscience/kmath/memory/MemorySpec.kt | 2 +- .../space/kscience/kmath/memory/MemoryTest.kt | 2 +- .../space/kscience/kmath/memory/DataViewMemory.kt | 2 +- .../kscience/kmath/memory/ByteBufferMemory.kt | 2 +- .../space/kscience/kmath/memory/NativeMemory.kt | 2 +- .../kscience/kmath/memory/WasmDataViewMemory.kt | 2 +- .../kscience/kmath/multik/MultikDoubleAlgebra.kt | 2 +- .../kscience/kmath/multik/MultikFloatAlgebra.kt | 2 +- .../kscience/kmath/multik/MultikIntAlgebra.kt | 2 +- .../kscience/kmath/multik/MultikLongAlgebra.kt | 2 +- .../kscience/kmath/multik/MultikShortAlgebra.kt | 2 +- .../space/kscience/kmath/multik/MultikTensor.kt | 2 +- .../kscience/kmath/multik/MultikTensorAlgebra.kt | 2 +- .../space/kscience/kmath/multik/MultikNDTest.kt | 2 +- .../space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt | 2 +- .../space/kscience/kmath/nd4j/Nd4jArrayIterator.kt | 2 +- .../kscience/kmath/nd4j/Nd4jArrayStructure.kt | 2 +- .../space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt | 2 +- .../kotlin/space/kscience/kmath/nd4j/arrays.kt | 2 +- .../kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt | 2 +- .../kscience/kmath/nd4j/Nd4jArrayStructureTest.kt | 2 +- .../kmath/optimization/FunctionOptimization.kt | 2 +- .../kmath/optimization/OptimizationBuilder.kt | 2 +- .../kmath/optimization/OptimizationProblem.kt | 2 +- .../space/kscience/kmath/optimization/Optimizer.kt | 2 +- .../kscience/kmath/optimization/QowOptimizer.kt | 2 +- .../space/kscience/kmath/optimization/XYFit.kt | 2 +- .../kscience/kmath/optimization/logLikelihood.kt | 2 +- .../kscience/kmath/distributions/Distribution.kt | 2 +- .../kmath/distributions/FactorizedDistribution.kt | 2 +- .../kmath/distributions/NormalDistribution.kt | 2 +- .../kmath/distributions/UniformDistribution.kt | 2 +- .../kotlin/space/kscience/kmath/random/MCScope.kt | 2 +- .../space/kscience/kmath/random/RandomChain.kt | 2 +- .../space/kscience/kmath/random/RandomGenerator.kt | 2 +- .../samplers/AhrensDieterExponentialSampler.kt | 2 +- .../AhrensDieterMarsagliaTsangGammaSampler.kt | 2 +- .../kmath/samplers/AliasMethodDiscreteSampler.kt | 2 +- .../kscience/kmath/samplers/BoxMullerSampler.kt | 2 +- .../kscience/kmath/samplers/GaussianSampler.kt | 2 +- .../space/kscience/kmath/samplers/InternalErf.kt | 2 +- .../space/kscience/kmath/samplers/InternalGamma.kt | 2 +- .../space/kscience/kmath/samplers/InternalUtils.kt | 2 +- .../kmath/samplers/KempSmallMeanPoissonSampler.kt | 2 +- .../samplers/MarsagliaNormalizedGaussianSampler.kt | 2 +- .../kmath/samplers/NormalizedGaussianSampler.kt | 2 +- .../kscience/kmath/samplers/PoissonSampler.kt | 2 +- .../space/kscience/kmath/samplers/Sampler.kt | 2 +- .../kscience/kmath/samplers/SamplerAlgebra.kt | 2 +- .../samplers/ZigguratNormalizedGaussianSampler.kt | 2 +- .../kmath/series/MonotonicSeriesAlgebra.kt | 2 +- .../space/kscience/kmath/series/SeriesAlgebra.kt | 5 +++++ .../kscience/kmath/series/VarianceRatioTest.kt | 2 +- .../space/kscience/kmath/series/resampling.kt | 2 +- .../kscience/kmath/series/seriesExtensions.kt | 5 +++++ .../kotlin/space/kscience/kmath/stat/Mean.kt | 2 +- .../kotlin/space/kscience/kmath/stat/Median.kt | 2 +- .../kotlin/space/kscience/kmath/stat/Rank.kt | 5 +++++ .../kotlin/space/kscience/kmath/stat/Statistic.kt | 2 +- .../kscience/kmath/stat/StatisticalAlgebra.kt | 5 +++++ .../kscience/kmath/stat/ValueAndErrorField.kt | 2 +- .../kscience/kmath/stat/chiSquaredExpression.kt | 2 +- .../space/kscience/kmath/series/TestSeries.kt | 2 +- .../kscience/kmath/series/TestVarianceRatioTest.kt | 2 +- .../kscience/kmath/stat/TestBasicStatistics.kt | 2 +- .../kscience/kmath/stat/RandomSourceGenerator.kt | 2 +- .../kmath/stat/CommonsDistributionsTest.kt | 2 +- .../space/kscience/kmath/stat/MCScopeTest.kt | 2 +- .../space/kscience/kmath/stat/SamplerTest.kt | 2 +- .../space/kscience/kmath/stat/StatisticTest.kt | 2 +- .../space/kscience/kmath/symja/SymjaExpression.kt | 2 +- .../kotlin/space/kscience/kmath/symja/adapters.kt | 2 +- .../kmath/tensorflow/DoubleTensorFlowAlgebra.kt | 2 +- .../kmath/tensorflow/IntTensorFlowAlgebra.kt | 2 +- .../kscience/kmath/tensorflow/TensorFlowAlgebra.kt | 2 +- .../kscience/kmath/tensorflow/tfOperations.kt | 2 +- .../kmath/tensorflow/DoubleTensorFlowOps.kt | 2 +- .../kmath/tensors/api/AnalyticTensorAlgebra.kt | 2 +- .../kmath/tensors/api/LinearOpsTensorAlgebra.kt | 2 +- .../space/kscience/kmath/tensors/api/Tensor.kt | 2 +- .../kscience/kmath/tensors/api/TensorAlgebra.kt | 2 +- .../tensors/api/TensorPartialDivisionAlgebra.kt | 2 +- .../tensors/core/BroadcastDoubleTensorAlgebra.kt | 2 +- .../kscience/kmath/tensors/core/BufferedTensor.kt | 2 +- .../kscience/kmath/tensors/core/DoubleTensor.kt | 2 +- .../kscience/kmath/tensors/core/DoubleTensor1D.kt | 2 +- .../kscience/kmath/tensors/core/DoubleTensor2D.kt | 2 +- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 2 +- .../space/kscience/kmath/tensors/core/IntTensor.kt | 2 +- .../kmath/tensors/core/IntTensorAlgebra.kt | 2 +- .../tensors/core/LevenbergMarquardtAlgorithm.kt | 2 +- .../kmath/tensors/core/internal/broadcastUtils.kt | 2 +- .../kscience/kmath/tensors/core/internal/checks.kt | 2 +- .../tensors/core/internal/doubleTensorHelpers.kt | 2 +- .../tensors/core/internal/intTensorHelpers.kt | 2 +- .../kmath/tensors/core/internal/linUtils.kt | 2 +- .../kscience/kmath/tensors/core/internal/utils.kt | 2 +- .../kmath/tensors/core/tensorAlgebraExtensions.kt | 2 +- .../space/kscience/kmath/tensors/core/tensorOps.kt | 2 +- .../kscience/kmath/tensors/core/tensorTransform.kt | 2 +- .../kmath/tensors/core/TestBroadcasting.kt | 2 +- .../core/TestDoubleAnalyticTensorAlgebra.kt | 2 +- .../tensors/core/TestDoubleLinearOpsAlgebra.kt | 2 +- .../kmath/tensors/core/TestDoubleTensor.kt | 2 +- .../kmath/tensors/core/TestDoubleTensorAlgebra.kt | 2 +- .../kmath/tensors/core/offsetBufferEquality.kt | 2 +- .../kscience/kmath/tensors/core/TestLmAlgorithm.kt | 2 +- .../space/kscience/kmath/viktor/ViktorBuffer.kt | 2 +- .../kscience/kmath/viktor/ViktorFieldOpsND.kt | 2 +- .../kscience/kmath/viktor/ViktorStructureND.kt | 2 +- .../src/commonMain/kotlin/AlgebraicVerifier.kt | 2 +- test-utils/src/commonMain/kotlin/FieldVerifier.kt | 2 +- test-utils/src/commonMain/kotlin/RingVerifier.kt | 2 +- test-utils/src/commonMain/kotlin/SpaceVerifier.kt | 2 +- test-utils/src/commonMain/kotlin/asserts.kt | 2 +- test-utils/src/commonMain/kotlin/bufferEquality.kt | 2 +- 462 files changed, 509 insertions(+), 458 deletions(-) diff --git a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt index a3cfce52f..d930c90c0 100644 --- a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt +++ b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt index abfc8cbf2..f04f0a46d 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt index d07b7b4df..a67f52b67 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt index 1675216eb..9f665709c 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt index 5784c32b1..51be23192 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt index def90ba22..45b3916dc 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt index 6cc649fe9..021c654a1 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt index 355f54c65..69479200d 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt index f7aac8199..d8052a9dc 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt index ec7f940a0..297dce8b9 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt index 8bdb101f6..64efaf640 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt index b424491f6..bd5c2006a 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt index b6a485821..65d159e54 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/globals.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/globals.kt index f6d278d83..ff5157f81 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/globals.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/globals.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/JmhReport.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/JmhReport.kt index 3a4fcdc79..98778e009 100644 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/JmhReport.kt +++ b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/JmhReport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt index 83cb786e3..fc04c82cf 100644 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt +++ b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt index 41b88f093..3c24c24cb 100644 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt +++ b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ @@ -363,8 +363,8 @@ fun ejmlCodegen(outputFile: String): Unit = File(outputFile).run { writer().use { it.appendLine("/*") - it.appendLine(" * Copyright 2018-2021 KMath contributors.") - it.appendLine(" * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.") + it.appendLine(" * Copyright 2018-2024 KMath contributors.") + it.appendLine(" * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.") it.appendLine(" */") it.appendLine() it.appendLine("/* This file is generated with buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt */") diff --git a/docs/images/KM.svg b/docs/images/KM.svg index 55a4339b1..f9003c5bb 100644 --- a/docs/images/KM.svg +++ b/docs/images/KM.svg @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- - - Copyright 2018-2022 KMath contributors. + - Copyright 2018-2024 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. --> diff --git a/docs/images/KM_mono.svg b/docs/images/KM_mono.svg index f1194f887..057968d0e 100644 --- a/docs/images/KM_mono.svg +++ b/docs/images/KM_mono.svg @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- - - Copyright 2018-2022 KMath contributors. + - Copyright 2018-2024 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. --> diff --git a/docs/images/KMath.svg b/docs/images/KMath.svg index 509a184bc..4e1e8a783 100644 --- a/docs/images/KMath.svg +++ b/docs/images/KMath.svg @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- - - Copyright 2018-2022 KMath contributors. + - Copyright 2018-2024 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. --> diff --git a/docs/images/KMath_mono.svg b/docs/images/KMath_mono.svg index e781979e2..5b93d45b7 100644 --- a/docs/images/KMath_mono.svg +++ b/docs/images/KMath_mono.svg @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="UTF-8" standalone="no"?> <!-- - - Copyright 2018-2022 KMath contributors. + - Copyright 2018-2024 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. --> diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/astRendering.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/astRendering.kt index e85bab8d8..d792a4ec6 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/astRendering.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/astRendering.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt index 784fed63e..a8150eb83 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/expressions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt index f7b169e0b..fc6cbb752 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/kotlingradSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/ast/symjaSupport.kt b/examples/src/main/kotlin/space/kscience/kmath/ast/symjaSupport.kt index 9a4300f82..549b96cf1 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/ast/symjaSupport.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/ast/symjaSupport.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/expressions/autodiff.kt b/examples/src/main/kotlin/space/kscience/kmath/expressions/autodiff.kt index 863d6be7a..7bcb80da0 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/expressions/autodiff.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/expressions/autodiff.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt b/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt index 258ed0c84..be4982d59 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt b/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt index fe7f48b72..0a0626149 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt index 493a89387..07bacc45d 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/integrate.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt index 6908eebdd..817f33dbe 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolateSquare.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolateSquare.kt index e621cda08..29a40498b 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolateSquare.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolateSquare.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt index baba2eb28..0680f42b0 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/matrixIntegration.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/jafama/JafamaDemo.kt b/examples/src/main/kotlin/space/kscience/kmath/jafama/JafamaDemo.kt index 52451e9f3..b4afa37e4 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/jafama/JafamaDemo.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/jafama/JafamaDemo.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/linear/dotPerformance.kt b/examples/src/main/kotlin/space/kscience/kmath/linear/dotPerformance.kt index 79eddc6c3..8874ca685 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/linear/dotPerformance.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/linear/dotPerformance.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt index eb170e7fa..6ebd1d221 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/linear/gradient.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/BigIntDemo.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/BigIntDemo.kt index 2447d06ed..903388c2f 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/BigIntDemo.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/BigIntDemo.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/complexDemo.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/complexDemo.kt index 77cfca4ae..a9c363dd6 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/complexDemo.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/complexDemo.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt index bb69c6aff..4df577b8b 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/series/DateTimeSeries.kt b/examples/src/main/kotlin/space/kscience/kmath/series/DateTimeSeries.kt index ca10fc290..35435b64e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/series/DateTimeSeries.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/series/DateTimeSeries.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt b/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt index 0e10f1a9a..ca3754c8a 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.series diff --git a/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionBenchmark.kt index 031955e15..19b763113 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionDemo.kt b/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionDemo.kt index 8e6d096ed..2f8e9d959 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionDemo.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/stat/DistributionDemo.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt index f71f248d9..c97ba8383 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt index 375d4e182..9ec8719ad 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/NDField.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt index a0e25b81b..4097b7283 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt index 1e50ef7da..4d52c4258 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureReadBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt index 4aa7b74dd..9304e9f4c 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt index 8785fa6f2..aafd43fd9 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt index 1ba0e3503..06f1a21c8 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/typeSafeDimensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt index e6f575262..a6903baca 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt index 507943031..ab50d17e1 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt index 0659db103..aa8aa73f8 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index b2818ef2a..f77adab7e 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt index c9dd5029e..2c53146b7 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt index 7ccb37ed0..4aefa1e0a 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt index 2c570ea34..8de4ab527 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/OLSWithSVD.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt index fb774a39d..10edcd03a 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/PCA.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/dataSetNormalization.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/dataSetNormalization.kt index 45c2ff120..e804e5818 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/dataSetNormalization.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/dataSetNormalization.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/linearSystemSolvingWithLUP.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/linearSystemSolvingWithLUP.kt index 238696cf9..d5b04e153 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/linearSystemSolvingWithLUP.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/linearSystemSolvingWithLUP.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/multik.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/multik.kt index 67e0631e7..f8bf65ad7 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/multik.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/multik.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/neuralNetwork.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/neuralNetwork.kt index 8fd5ae5ad..78f27c304 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/neuralNetwork.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/neuralNetwork.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt index e82f7a3ab..4d1c00a29 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/evaluateConstants.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/evaluateConstants.kt index 8fc5a6aaf..10146146e 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/evaluateConstants.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/evaluateConstants.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt index 2c9a2a9ad..40bc60f4d 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt index 5a338afed..89464af32 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/LatexSyntaxRenderer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt index bfd9aeef9..8e6cada95 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathMLSyntaxRenderer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt index f88a5b319..4590cebea 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt index 0196be3b6..8cc29b993 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathSyntax.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt index 16957bdd2..8e0b00d10 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/SyntaxRenderer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt index 4deffc83c..9fcabefbc 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt index dce99cc5a..b3844728b 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/phases.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/phases.kt index 0d26621d3..dae330916 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/phases.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/phases.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt index 77f6a191d..b2fe94589 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt index 30bb7291d..0fb3002f1 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerOperations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt index 3dbdf063a..6fc3341b6 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt index 61a37944a..74fd4b56c 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestFolding.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt index 784dcece9..3c4fbb98c 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParser.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt index 504ec9bd0..227c0844a 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestParserPrecedence.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt index bb6d39204..158abbdeb 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt index 66c0ae1ae..12c11f89c 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestLatex.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt index 8bc014c54..abf761d23 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt index 306538d5d..be3d587be 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestStages.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt index 79f178eef..378e6647b 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt index 27b2f2598..ee2346b13 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/utils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt index f6411334c..c1842b039 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt index 87c2df2d2..b52bfdf8c 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt index 1517cdef2..023d603c4 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/ESTreeBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/astring/astring.typealises.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/astring/astring.typealises.kt index 2434788ec..ccbebff81 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/astring/astring.typealises.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/internal/astring/astring.typealises.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.kt index cc4360f8d..25721fee6 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.typealises.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.typealises.kt index a17726c9d..bf0d06660 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.typealises.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/astring/astring.typealises.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/base64/base64.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/base64/base64.kt index 8ea699837..cb4da44fe 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/base64/base64.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/base64/base64.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt index 59c9a40a6..d40f3e0f5 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.typealiases.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.typealiases.kt index eebfeb6ef..f9b3654c2 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.typealiases.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.typealiases.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/emitter/emitter.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/emitter/emitter.kt index a2a04da79..e87a5f380 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/emitter/emitter.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/emitter/emitter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt index 2dd2c08cd..7549f6514 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.kt index bf4a25367..a05f57f7f 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/stream/stream.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/stream/stream.kt index ced165a3a..496df7e67 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/stream/stream.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/stream/stream.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es2015.iterable.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es2015.iterable.kt index 2c0dc9de1..9320243d8 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es2015.iterable.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es2015.iterable.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt index f20e2d865..07fd53fec 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt index 873a5e1d2..15332a413 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/nonDeclarations.WebAssembly.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/nonDeclarations.WebAssembly.kt index ba86e977b..ad97c259d 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/nonDeclarations.WebAssembly.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/nonDeclarations.WebAssembly.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt index 4917f6f1b..18ef35c4b 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/WasmBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/f64StandardFunctions.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/f64StandardFunctions.kt index d60f24247..63cda9756 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/f64StandardFunctions.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/internal/f64StandardFunctions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt index f3249adf7..ceb1ad69d 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/wasm/wasm.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt index 6d826541c..03b90e248 100644 --- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt +++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt index c7e898713..45b5aef5a 100644 --- a/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt +++ b/kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt index 97fe91ee4..a38ab9fc3 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt index e1fd455fd..aa7e093a5 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/AsmBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/GenericAsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/GenericAsmBuilder.kt index acae45d87..5314c4cc3 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/GenericAsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/GenericAsmBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt index bb8143206..9c27a25b5 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt index b3ccfdc0c..e3565df23 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/mapIntrinsics.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/mapIntrinsics.kt index 6459f4dcf..392854541 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/mapIntrinsics.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/mapIntrinsics.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt index ec66be830..745dced45 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt index e04e2e5bd..f06137c4a 100644 --- a/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt +++ b/kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/nativeMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt b/kmath-ast/src/nativeMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt index ec66be830..745dced45 100644 --- a/kmath-ast/src/nativeMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt +++ b/kmath-ast/src/nativeMain/kotlin/space/kscience/kmath/ast/rendering/multiplatformToString.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ast/src/nativeTest/kotlin/space/kscience/kmath/ast/runCompilerTest.kt b/kmath-ast/src/nativeTest/kotlin/space/kscience/kmath/ast/runCompilerTest.kt index 0674b0492..28dd12e1f 100644 --- a/kmath-ast/src/nativeTest/kotlin/space/kscience/kmath/ast/runCompilerTest.kt +++ b/kmath-ast/src/nativeTest/kotlin/space/kscience/kmath/ast/runCompilerTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt index 38eaf8868..b7fef245c 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/expressions/CmDsExpression.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt index 263463d37..5234f459b 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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.commons.integration diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt index c3e581d31..90f776195 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMIntegrator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index 4d2e2aa90..a7e746fe4 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt index 19799aab3..6b31fcd88 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt index c4dafb6a6..520588c1e 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ @file:OptIn(UnstableKMathAPI::class) diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt index 32962659f..62d31021c 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/transform/Transformations.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/transform/Transformations.kt index de271aedc..838ab95d5 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/transform/Transformations.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/transform/Transformations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt index 7c3c086ed..34905fa7b 100644 --- a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt +++ b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt index 9a249b29b..c2e630f38 100644 --- a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt +++ b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt index 5933d0d36..c4177d8ad 100644 --- a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt +++ b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt index b5f1aabe7..d54a225e6 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt index 90a6b3253..8fbf41732 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt index 8f3d15a26..7f9f742e5 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexBufferSpecTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexBufferSpecTest.kt index ca3f8f43f..124703cbe 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexBufferSpecTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexBufferSpecTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt index e11f1c1ea..506451888 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexTest.kt index 1a35d1dd8..a736d5ac5 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ExpressionFieldForComplexTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ExpressionFieldForComplexTest.kt index 767406e0b..9b7bdfa95 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ExpressionFieldForComplexTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ExpressionFieldForComplexTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/QuaternionTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/QuaternionTest.kt index 1b371adca..b60b853de 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/QuaternionTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/QuaternionTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt index 49e2ee8d0..1dd92980e 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/ColumnarData.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt index 23cbcd0c7..cc35f606b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYErrorColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYErrorColumnarData.kt index 797a25443..312894612 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYErrorColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYErrorColumnarData.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYZColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYZColumnarData.kt index 846bbad62..2af3c1c19 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYZColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYZColumnarData.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain.kt index eecdcebad..5bfbeb6ac 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain1D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain1D.kt index b03e60e95..79f446f6d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain1D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain1D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Float64Domain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Float64Domain.kt index 7878f2551..a522381e1 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Float64Domain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Float64Domain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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.domains diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt index 03a080a70..16dae5699 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/HyperSquareDomain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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.domains diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt index b78190c9b..f651dcde3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/UnconstrainedDomain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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.domains diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt index 192509993..c0c5e8bdf 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSCompiler.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSCompiler.kt index 1da151d46..0699ca1df 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSCompiler.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSCompiler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt index 7c8a957c7..e76374b50 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt index f350303bc..77aa9ae7b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/ExpressionWithDefault.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/ExpressionWithDefault.kt index c802fe04c..b576642fc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/ExpressionWithDefault.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/ExpressionWithDefault.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt index 8e37f3d32..a4b50ebc6 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt index 9705a3f03..145a2bf50 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt index c894cf00a..8dca4f1dd 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MstAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/NamedMatrix.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/NamedMatrix.kt index 5d047d5b7..14ccafb0b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/NamedMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/NamedMatrix.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt index 2bb5043b7..d5a053f43 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Symbol.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Symbol.kt index c57ce69ab..5e2ab64a6 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Symbol.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Symbol.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt index f0e39d489..d47202df3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SymbolIndexer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt index 4bba47a91..fca29a9dd 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/BufferedLinearSpace.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt index eb4434c00..0da4c275d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt index af9ebb463..2d7fb42d4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSolver.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index a82bafe57..97db63ded 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index ce55623de..ed76bd337 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt index 4d2f01e68..0dc42f4c8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt index ce7acdcba..22781f640 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixFeatures.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index 46454a584..c2efdafda 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt index 55b970f4a..6a22092b2 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt index bdda674dc..64cc25016 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/Featured.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/collections.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/collections.kt index f630055fa..6227e2f45 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/collections.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/collections.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/cumulative.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/cumulative.kt index c05f1a6a9..60f71b943 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/cumulative.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/cumulative.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/logging.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/logging.kt index c7886469f..9655e1139 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/logging.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/logging.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/numbers.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/numbers.kt index 77ef07ea8..cc43c84bc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/numbers.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/numbers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt index f369f0614..0e7c34eb5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt index 91e26cc1b..e3c8d3963 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt index 74c63e6e2..b92e77969 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferAlgebraND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt index 9217f6fdc..2ac4927c7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt index 464ee16b9..89a7a02a2 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt index 758a486f5..2f91a3326 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt index 039432bc7..128badda4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt index 6c35e2f44..f8b101d1d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeIndices.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeIndices.kt index 3a27614c5..e8545125f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeIndices.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeIndices.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt index d43ebaf1c..dee22e49f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt index 984b5ad0f..235a39c05 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index e006d09eb..ae16c850a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index e643186ba..20cf58a8c 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt index 606b9a631..a7e0b0053 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt index f0d4bd7f5..71bc2bde4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt index 40db5187f..b91f2bde5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt index 28e32363f..9f70b6dca 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt index 67f37ed62..1ee199fc8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt index 34a6d4a80..edb2a822a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index 0363f39d3..fd4df72c8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt index e33cb2c6e..5defbd7c5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferOps.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferOps.kt index 923534e1c..ca4eacb8a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferOps.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferOps.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt index d8bf0fb57..a10fd949b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/LogicAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt index 06ad68298..4f15418b3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt index 48cac2870..422134bcd 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt index ddf599240..872d72857 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt index 72e33c523..7ae5dc152 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt index 0b7bef852..720f454b0 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/numbers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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.operations diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt index 8e81dd941..2e644da88 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index 4c8ba0652..809cd0c93 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt index 48f3e919b..8d873d86d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt index f538fdd01..996065010 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.structures import space.kscience.kmath.UnstableKMathAPI diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt index d99e02996..c3cb153f4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt index 44ef4dcf0..ff41a0d37 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt index 0542c1bf4..519ea7f30 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt index 1ba40c934..3e5b3f846 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt index afd94e9cd..6754d3873 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt index c67d109aa..f57a5cd1b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt index 923fbec06..f3ae90c5e 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt index fbc9a489b..61afe4c17 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MemoryBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MemoryBuffer.kt index cbfd6b9cd..7a630ba24 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MemoryBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MemoryBuffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt index 772c670ea..f058f205d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferExtensions.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferExtensions.kt index 6a7b6d836..7c69669c8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferExtensions.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferPrimitiveAccess.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferPrimitiveAccess.kt index 9033dea98..6035811b9 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferPrimitiveAccess.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/bufferPrimitiveAccess.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.structures import space.kscience.kmath.UnstableKMathAPI diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/types.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/types.kt index 4ace17538..3d5f87abc 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/types.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/types.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt index 71bbc325c..eb679cec6 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/DSTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt index 153090d35..ca2e31d7d 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/ExpressionFieldTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/InterpretTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/InterpretTest.kt index 6533af344..b9ab5e62c 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/InterpretTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/InterpretTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt index c0c5fc321..dcfb16042 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/expressions/SimpleAutoDiffTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt index 4d05f9043..12ed88996 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt index 531aee259..58865bafe 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/CumulativeKtTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/CumulativeKtTest.kt index 811f2e87f..9cedb8bb3 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/CumulativeKtTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/CumulativeKtTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt index fa9ac19c0..a8fc1c765 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt index ada7f4244..d0f79bb15 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/StridesTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/StridesTest.kt index e6335f652..1c26c215c 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/StridesTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/StridesTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntAlgebraTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntAlgebraTest.kt index 06a9ab439..0bbb92151 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntAlgebraTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntAlgebraTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntConstructorTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntConstructorTest.kt index 786c68c70..69bccacdd 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntConstructorTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntConstructorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntConversionsTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntConversionsTest.kt index 36f00dc75..f9b5dca2a 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntConversionsTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntConversionsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntOperationsTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntOperationsTest.kt index 8a6116605..1f47dc2c1 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntOperationsTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/BigIntOperationsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt index 2f0ee28e7..51783df13 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/operations/DoubleFieldTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/BufferExpandedTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/BufferExpandedTest.kt index 04671e040..0a9b1d897 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/BufferExpandedTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/BufferExpandedTest.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.structures import kotlin.test.Test diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt index d6c6adedd..0fc9cb9e3 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NDFieldTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt index 4ee6d50cb..2f10af972 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/NumberNDFieldTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/jsMain/kotlin/space/kscience/kmath/misc/numbers.kt b/kmath-core/src/jsMain/kotlin/space/kscience/kmath/misc/numbers.kt index e52ea9298..e0875993f 100644 --- a/kmath-core/src/jsMain/kotlin/space/kscience/kmath/misc/numbers.kt +++ b/kmath-core/src/jsMain/kotlin/space/kscience/kmath/misc/numbers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/jsMain/kotlin/space/kscience/kmath/operations/isInteger.kt b/kmath-core/src/jsMain/kotlin/space/kscience/kmath/operations/isInteger.kt index 3103f5168..da697bd77 100644 --- a/kmath-core/src/jsMain/kotlin/space/kscience/kmath/operations/isInteger.kt +++ b/kmath-core/src/jsMain/kotlin/space/kscience/kmath/operations/isInteger.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/misc/numbersJVM.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/misc/numbersJVM.kt index 3780ea1ae..222e1bca1 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/misc/numbersJVM.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/misc/numbersJVM.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/BigNumbers.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/BigNumbers.kt index 584748bd7..b19f0c8f9 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/BigNumbers.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/BigNumbers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/isInteger.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/isInteger.kt index 9868daddf..fa75860d8 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/isInteger.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/isInteger.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/misc/JBigTest.kt b/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/misc/JBigTest.kt index f7f8027e6..f27257a4c 100644 --- a/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/misc/JBigTest.kt +++ b/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/misc/JBigTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/misc/numbers.kt b/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/misc/numbers.kt index e52ea9298..e0875993f 100644 --- a/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/misc/numbers.kt +++ b/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/misc/numbers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/operations/isInteger.kt b/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/operations/isInteger.kt index 9868daddf..fa75860d8 100644 --- a/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/operations/isInteger.kt +++ b/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/operations/isInteger.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/misc/numbers.kt b/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/misc/numbers.kt index e320f350e..e0875993f 100644 --- a/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/misc/numbers.kt +++ b/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/misc/numbers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/operations/isInteger.kt b/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/operations/isInteger.kt index 11c82bf9e..9f68527f7 100644 --- a/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/operations/isInteger.kt +++ b/kmath-core/src/wasmJsMain/kotlin/space/kscience/kmath/operations/isInteger.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt index 2e9a15eed..87e77387c 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingChain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt index e67cab72d..b3e1b59b7 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingDoubleChain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt index 172aa95cd..82a6d131e 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/BlockingIntChain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/Chain.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/Chain.kt index 977346e68..0158c6752 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/Chain.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/Chain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/flowExtra.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/flowExtra.kt index 77d4203c5..52114752c 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/flowExtra.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/chains/flowExtra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/coroutines/coroutinesExtra.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/coroutines/coroutinesExtra.kt index 48be93b87..8183d2d15 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/coroutines/coroutinesExtra.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/coroutines/coroutinesExtra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt index c52b6c3d5..e0e8050bc 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/BufferFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt index bb07fede1..c4e24a2d7 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/chains/ChainExt.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/chains/ChainExt.kt index a62bcc6b8..7dc423552 100644 --- a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/chains/ChainExt.kt +++ b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/chains/ChainExt.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt index 22c2ac3ff..86bc39912 100644 --- a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt +++ b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/BufferFlowTest.kt b/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/BufferFlowTest.kt index c448168e3..22893389d 100644 --- a/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/BufferFlowTest.kt +++ b/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/BufferFlowTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/RingBufferTest.kt b/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/RingBufferTest.kt index a6d7f006c..6219a5886 100644 --- a/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/RingBufferTest.kt +++ b/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/RingBufferTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt index 14677319c..afdb8eec1 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt index 6cade1d5d..0e820d3ca 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-dimensions/src/commonTest/kotlin/space/kscience/dimensions/DMatrixContextTest.kt b/kmath-dimensions/src/commonTest/kotlin/space/kscience/dimensions/DMatrixContextTest.kt index e2793855b..e60740826 100644 --- a/kmath-dimensions/src/commonTest/kotlin/space/kscience/dimensions/DMatrixContextTest.kt +++ b/kmath-dimensions/src/commonTest/kotlin/space/kscience/dimensions/DMatrixContextTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-dimensions/src/jsMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt b/kmath-dimensions/src/jsMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt index 1ae484228..cbf404b7f 100644 --- a/kmath-dimensions/src/jsMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt +++ b/kmath-dimensions/src/jsMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-dimensions/src/jvmMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt b/kmath-dimensions/src/jvmMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt index 24cfb14e8..131a6db42 100644 --- a/kmath-dimensions/src/jvmMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt +++ b/kmath-dimensions/src/jvmMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-dimensions/src/nativeMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt b/kmath-dimensions/src/nativeMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt index f5f749c8a..ddfee4523 100644 --- a/kmath-dimensions/src/nativeMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt +++ b/kmath-dimensions/src/nativeMain/kotlin/space/kscience/kmath/dimensions/Dimension.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt index 8925fb045..306a80ef8 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt index 1d70c0e7d..d24f56042 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt index c4fae9951..82401ba05 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index f48ab4c19..7a267b77b 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -1,6 +1,6 @@ /* - * 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. + * Copyright 2018-2024 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. */ /* This file is generated with buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt */ @@ -19,13 +19,19 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.structures.Float64 +import space.kscience.kmath.structures.Float32 import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Float32Field +import space.kscience.kmath.operations.DoubleField +import space.kscience.kmath.operations.FloatField import space.kscience.kmath.operations.invoke +import space.kscience.kmath.structures.Float64Buffer +import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass diff --git a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt index e89810e0d..2a7280220 100644 --- a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt +++ b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlVectorTest.kt b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlVectorTest.kt index 7d3ea314b..cbc7f7c41 100644 --- a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlVectorTest.kt +++ b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlVectorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt index d13528636..493a299c0 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt index fe5593eaa..208c82c6d 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/dot.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/dot.kt index 0c18602f1..e9fdfb506 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/dot.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/dot.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt index 79af446e2..f1b099cde 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt index 1b9f0f4e2..223cdd25d 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/realND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleMatrixTest.kt b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleMatrixTest.kt index c00cd84d1..f54ec6290 100644 --- a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleMatrixTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleMatrixTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt index 16eccd79b..29aa2ec2e 100644 --- a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/GridTest.kt b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/GridTest.kt index 35c53f9d6..861995a19 100644 --- a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/GridTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/GridTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt index a9e75e456..8c02ee044 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt index af84f47f2..ab9ed52b5 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/functionTypes.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/functionTypes.kt index c2f95f040..6f2ba6c75 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/functionTypes.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/functionTypes.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt index e07ff764c..dceef2b75 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialConstructors.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt index 0d4b93f03..31e2406fa 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index f2ac0a296..fa0548f3d 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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.integration diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt index 975fcd3a8..705979201 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt index 40fe78898..d8c4ba587 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt index 18c46b83b..95bbb56ed 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt index 53a563086..e9a1f6549 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt index 35ce82351..410351460 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SimpsonIntegrator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt index 1306e501f..6c1a8b234 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/SplineIntegrator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index e29a6c881..14b1db87c 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt index 191e7dfd9..7dc90df67 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt index 5c56e406a..e894799c9 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt index ed4657d53..123bb7a9f 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt index 3051cdd8d..c320212f3 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt index 48e641335..e91535506 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt index 3b7409e82..1f1e1a83f 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModuloUtils.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModuloUtils.kt index ffab2157c..ce9a0270c 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModuloUtils.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModuloUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt index ff05805da..98150355c 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/misc.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/misc.kt index 61b50f128..267fae83b 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/misc.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/misc.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt index dd8069335..0e8f9ddfb 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt index f5a79cdea..eb8630c35 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SimpsonIntegralTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt index 6b62afbd3..7e161f7c9 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt index 24a664c26..c62d2c8bc 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/LinearInterpolatorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/SplineInterpolatorTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/SplineInterpolatorTest.kt index 774b6196e..8869a1f45 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/SplineInterpolatorTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/interpolation/SplineInterpolatorTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt index d6d7e5725..8de914e7b 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt index 92d31a7cb..6d900ed37 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/ReferenceFrame.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/ReferenceFrame.kt index 21045e94e..f28bc6539 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/ReferenceFrame.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/ReferenceFrame.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt index 9eced7ba9..d1524584a 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector2D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt index 7e7c6c4ed..4fdbda2f2 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt index 3855514fb..d9c797d7e 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt index 1cf8d5dc2..e17a5573a 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt index 4dd188d49..d2e081bc2 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt index 423e43c30..aaec1ef50 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt index 85b377a56..8ed62a236 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt index 1413a885b..0d59aeed6 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt index a8c7e1d17..884ef64b1 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt index deb8b0a93..d7190fa29 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt index 2ed02182d..964f7f3e1 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/floatPrecision.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/projections.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/projections.kt index c5c3487a1..962dc5ab1 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/projections.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/projections.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt index 859255004..cafa7f0da 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/quaternionOperations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/AngleTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/AngleTest.kt index b8086eb75..d5209a1bd 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/AngleTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/AngleTest.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.geometry import kotlin.test.Test diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt index 7c5ee3485..2ad7c940f 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean2DSpaceTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt index f881deb1b..64bdfcc61 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Euclidean3DSpaceTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt index 9b3f40c4c..0c2267e8b 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt index d3a9d1171..32bd710c6 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionOntoLineTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt index 1d354bf72..cbe13a877 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt index af27b5e00..af886ec29 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector2DTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt index b10e650a6..9157f95d8 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/Vector3DTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt index 521ce9e75..ebb72972d 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt b/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt index 5fcd2b23e..5a41b32d9 100644 --- a/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt +++ b/kmath-geometry/src/jvmMain/kotlin/space/kscience/kmath/geometry/lineExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2021 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt index 3d948e1a7..acd889bf0 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt index 3303fa172..79f145792 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram1D.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram1D.kt index f50610a17..ef72f2630 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram1D.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram1D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/HistogramND.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/HistogramND.kt index 5fdc2ffb0..36acd8db5 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/HistogramND.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/HistogramND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogram1D.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogram1D.kt index 154d35350..0326e8757 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogram1D.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogram1D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt index f7094f7a9..57463e45d 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/MultivariateHistogramTest.kt b/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/MultivariateHistogramTest.kt index 54806c9fa..f6c80a903 100644 --- a/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/MultivariateHistogramTest.kt +++ b/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/MultivariateHistogramTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/UniformHistogram1DTest.kt b/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/UniformHistogram1DTest.kt index bda9d2bea..e90dae0fc 100644 --- a/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/UniformHistogram1DTest.kt +++ b/kmath-histograms/src/commonTest/kotlin/space/kscience/kmath/histogram/UniformHistogram1DTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramGroup.kt b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramGroup.kt index 772db7df3..95658141a 100644 --- a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramGroup.kt +++ b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramGroup.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt b/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt index 00b94c11f..25ffbbca5 100644 --- a/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt +++ b/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/KMathJafama.kt b/kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/KMathJafama.kt index f9b8287b4..82811e0d5 100644 --- a/kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/KMathJafama.kt +++ b/kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/KMathJafama.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-jupyter/src/main/kotlin/space/kscience/kmath/jupyter/KMathJupyter.kt b/kmath-jupyter/src/main/kotlin/space/kscience/kmath/jupyter/KMathJupyter.kt index 944666c9e..36ce25c03 100644 --- a/kmath-jupyter/src/main/kotlin/space/kscience/kmath/jupyter/KMathJupyter.kt +++ b/kmath-jupyter/src/main/kotlin/space/kscience/kmath/jupyter/KMathJupyter.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KMathNumber.kt b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KMathNumber.kt index cd35e0c42..c261e6f91 100644 --- a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KMathNumber.kt +++ b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KMathNumber.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt index 110572140..53e0beca1 100644 --- a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt +++ b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt index dd75a704c..363a698c6 100644 --- a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt +++ b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt b/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt index 8d282a58a..f536e103d 100644 --- a/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt +++ b/kmath-kotlingrad/src/test/kotlin/space/kscience/kmath/kotlingrad/AdaptingTests.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/annotations.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/annotations.kt index a95b166cf..13db00968 100644 --- a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/annotations.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/annotations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/Memory.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/Memory.kt index a63753015..c80eb1072 100644 --- a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/Memory.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/Memory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt index 19bc3bae4..5e7db5d2d 100644 --- a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-memory/src/commonTest/kotlin/space/kscience/kmath/memory/MemoryTest.kt b/kmath-memory/src/commonTest/kotlin/space/kscience/kmath/memory/MemoryTest.kt index 3726ddbb7..6ca792839 100644 --- a/kmath-memory/src/commonTest/kotlin/space/kscience/kmath/memory/MemoryTest.kt +++ b/kmath-memory/src/commonTest/kotlin/space/kscience/kmath/memory/MemoryTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-memory/src/jsMain/kotlin/space/kscience/kmath/memory/DataViewMemory.kt b/kmath-memory/src/jsMain/kotlin/space/kscience/kmath/memory/DataViewMemory.kt index f8bcef010..f7badde37 100644 --- a/kmath-memory/src/jsMain/kotlin/space/kscience/kmath/memory/DataViewMemory.kt +++ b/kmath-memory/src/jsMain/kotlin/space/kscience/kmath/memory/DataViewMemory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-memory/src/jvmMain/kotlin/space/kscience/kmath/memory/ByteBufferMemory.kt b/kmath-memory/src/jvmMain/kotlin/space/kscience/kmath/memory/ByteBufferMemory.kt index d022cab23..c240e512d 100644 --- a/kmath-memory/src/jvmMain/kotlin/space/kscience/kmath/memory/ByteBufferMemory.kt +++ b/kmath-memory/src/jvmMain/kotlin/space/kscience/kmath/memory/ByteBufferMemory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt b/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt index 0ae3c7ebc..5edad57c4 100644 --- a/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt +++ b/kmath-memory/src/nativeMain/kotlin/space/kscience/kmath/memory/NativeMemory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-memory/src/wasmJsMain/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt b/kmath-memory/src/wasmJsMain/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt index 0cff551fa..30172b8b1 100644 --- a/kmath-memory/src/wasmJsMain/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt +++ b/kmath-memory/src/wasmJsMain/kotlin/space/kscience/kmath/memory/WasmDataViewMemory.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt index 8b463a230..bace8176e 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt index 7a3dda94b..fa91bb1d3 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt index 5bd1b3388..94d64c024 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt index 69a8ec042..e236b0d8b 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt index 7c8740665..7b5aa3417 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt index 59a9a1bf3..9dfed2d58 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt index c3a82b167..e78ef6616 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-multik/src/commonTest/kotlin/space/kscience/kmath/multik/MultikNDTest.kt b/kmath-multik/src/commonTest/kotlin/space/kscience/kmath/multik/MultikNDTest.kt index 1abcf512d..fff88c70b 100644 --- a/kmath-multik/src/commonTest/kotlin/space/kscience/kmath/multik/MultikNDTest.kt +++ b/kmath-multik/src/commonTest/kotlin/space/kscience/kmath/multik/MultikNDTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt index 31523b340..8b88048ae 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayIterator.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayIterator.kt index fedad26e0..0a2305e71 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayIterator.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayIterator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt index 93fbc8f85..34bbcaefb 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt index c308e64b9..aba262f91 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/arrays.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/arrays.kt index 401c57a7b..8f02f3c55 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/arrays.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/arrays.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt index 484618de2..704b28cd9 100644 --- a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt +++ b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructureTest.kt b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructureTest.kt index d57eb2e2d..5c3664cb3 100644 --- a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructureTest.kt +++ b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructureTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt index 07146625c..a0723c389 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt index 0459d46ee..44d67f1ab 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationBuilder.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt index 9fdcfc53d..73e36d012 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimizer.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimizer.kt index 41dcbf770..ed8242929 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimizer.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/Optimizer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt index e922fd423..53c50f690 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt index 9e5396491..d4c3c7ff7 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ @file:OptIn(UnstableKMathAPI::class) diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt index 8ab9de48d..74ed6fddb 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/Distribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/Distribution.kt index 806da5560..979c7a002 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/Distribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/Distribution.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/FactorizedDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/FactorizedDistribution.kt index 999fbffbc..8f5a378bb 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/FactorizedDistribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/FactorizedDistribution.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt index 10947b732..ccd894f09 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/UniformDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/UniformDistribution.kt index 953be06fd..d0f13398c 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/UniformDistribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/UniformDistribution.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/MCScope.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/MCScope.kt index 2049a84fc..149b5d85d 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/MCScope.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/MCScope.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt index 1cc409393..5d175c5ae 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomGenerator.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomGenerator.kt index ece6bfcc1..8d8fd8612 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomGenerator.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomGenerator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt index 04e1221ca..0276cd654 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterExponentialSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterMarsagliaTsangGammaSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterMarsagliaTsangGammaSampler.kt index d301ff637..05163387d 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterMarsagliaTsangGammaSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AhrensDieterMarsagliaTsangGammaSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AliasMethodDiscreteSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AliasMethodDiscreteSampler.kt index 2ec40c347..f65e8585b 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AliasMethodDiscreteSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/AliasMethodDiscreteSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt index c8ee745dd..9f90d1626 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/BoxMullerSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/GaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/GaussianSampler.kt index 28d588165..c86c6aa35 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/GaussianSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/GaussianSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalErf.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalErf.kt index 0c1a5b36f..c28b4be50 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalErf.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalErf.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalGamma.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalGamma.kt index 43c5a0d3c..ef4a97066 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalGamma.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalGamma.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalUtils.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalUtils.kt index 9f633e3db..cbc361b56 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalUtils.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt index 44834b5bf..7a076d849 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/KempSmallMeanPoissonSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt index 961883af5..b1343a4ca 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/MarsagliaNormalizedGaussianSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/NormalizedGaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/NormalizedGaussianSampler.kt index 291d0bffe..81d1edb47 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/NormalizedGaussianSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/NormalizedGaussianSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt index 964a57178..8faaf33dc 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/PoissonSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt index 34355dca7..8fc1ff82f 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/SamplerAlgebra.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/SamplerAlgebra.kt index 44b87a431..0de8bce99 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/SamplerAlgebra.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/SamplerAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt index 062894c90..db04d94bd 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/ZigguratNormalizedGaussianSampler.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/MonotonicSeriesAlgebra.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/MonotonicSeriesAlgebra.kt index ed6f4e07b..bd77974d1 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/MonotonicSeriesAlgebra.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/MonotonicSeriesAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt index cabff25e6..6790f44e0 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.series import space.kscience.kmath.operations.BufferAlgebra diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/VarianceRatioTest.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/VarianceRatioTest.kt index 6cd64df9c..337b13020 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/VarianceRatioTest.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/VarianceRatioTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/resampling.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/resampling.kt index dc21fe6d9..9931429e7 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/resampling.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/resampling.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/seriesExtensions.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/seriesExtensions.kt index fa5e0addd..92e3cf534 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/seriesExtensions.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/seriesExtensions.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.series import space.kscience.kmath.operations.BufferAlgebra diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt index 74ef65fa1..843b06f2c 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt index dc504f0b7..f0328839f 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Median.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Rank.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Rank.kt index 5a873b466..cb309663e 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Rank.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Rank.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.stat import space.kscience.kmath.operations.asIterable diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt index 7cb40a91a..81ed258f7 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Statistic.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/StatisticalAlgebra.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/StatisticalAlgebra.kt index cce61519b..9f0491b4b 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/StatisticalAlgebra.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/StatisticalAlgebra.kt @@ -1,3 +1,8 @@ +/* + * Copyright 2018-2024 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.stat import space.kscience.kmath.UnstableKMathAPI diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt index 38cd5f900..7e0794ee9 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/chiSquaredExpression.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/chiSquaredExpression.kt index ca9755ad5..c42f149f2 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/chiSquaredExpression.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/chiSquaredExpression.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestSeries.kt b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestSeries.kt index d83abb3f4..68c5af6fb 100644 --- a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestSeries.kt +++ b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestSeries.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestVarianceRatioTest.kt b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestVarianceRatioTest.kt index afc0d541d..b5ac44bc6 100644 --- a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestVarianceRatioTest.kt +++ b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestVarianceRatioTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/stat/TestBasicStatistics.kt b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/stat/TestBasicStatistics.kt index 306574a76..0efc3c269 100644 --- a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/stat/TestBasicStatistics.kt +++ b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/stat/TestBasicStatistics.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt b/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt index 2c6391612..8badbce64 100644 --- a/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt +++ b/kmath-stat/src/jvmMain/kotlin/space/kscience/kmath/stat/RandomSourceGenerator.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/CommonsDistributionsTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/CommonsDistributionsTest.kt index b9b9dadba..227214d63 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/CommonsDistributionsTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/CommonsDistributionsTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt index dbcf32e27..545e89814 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/SamplerTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/SamplerTest.kt index 0076006e6..fd2db98ae 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/SamplerTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/SamplerTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt index d64dcea4d..fb9a4351a 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/StatisticTest.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/SymjaExpression.kt b/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/SymjaExpression.kt index 0f8014913..e5ba411e6 100644 --- a/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/SymjaExpression.kt +++ b/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/SymjaExpression.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/adapters.kt b/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/adapters.kt index 92f2474b8..9590f2246 100644 --- a/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/adapters.kt +++ b/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/adapters.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt index 027318f99..d066669fd 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt index 01c8054b3..186a794e9 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt index 73b36cd67..158c928c4 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/tfOperations.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/tfOperations.kt index a0a2ddc80..885b9fca6 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/tfOperations.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/tfOperations.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt b/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt index fe950f334..dd4f620c4 100644 --- a/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt +++ b/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/AnalyticTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/AnalyticTensorAlgebra.kt index 1a324b200..a986edfa5 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/AnalyticTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/AnalyticTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt index f2c7f1821..f9f0ed832 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/Tensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/Tensor.kt index b328fbeec..2a7f463bc 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/Tensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/Tensor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt index f923400c5..6e515f3f8 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorPartialDivisionAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorPartialDivisionAlgebra.kt index 33effb2d2..df8c32007 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorPartialDivisionAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorPartialDivisionAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt index 662469bf3..d02a9f99e 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt index eaec43e2c..a595c94f5 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BufferedTensor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt index 8a97114c3..b51f47e4e 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor1D.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor1D.kt index d2066e404..74a4f65c4 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor1D.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor1D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor2D.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor2D.kt index fa142afa0..013dfe791 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor2D.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor2D.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index 334a27c5b..af668bc5a 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt index 1066793a7..bd84737c5 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt index a09351b85..39698d187 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index fc87ad1f3..15fcdfc07 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt index 1e87e6620..3596cbaf8 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/checks.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/checks.kt index f384ed462..1a0aa29d1 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/checks.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/checks.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/doubleTensorHelpers.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/doubleTensorHelpers.kt index 0c1ffdbf3..4750dbea2 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/doubleTensorHelpers.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/doubleTensorHelpers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt index c47d94a92..14ab35883 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index 272af41d5..54df7d241 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt index d48086d57..4dc6b8517 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/utils.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorAlgebraExtensions.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorAlgebraExtensions.kt index e2b7c23e6..841c51244 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorAlgebraExtensions.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorAlgebraExtensions.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt index 1b630a0ef..2c35f8196 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt index 52a530652..bafd3fadd 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestBroadcasting.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestBroadcasting.kt index 73aed8a7b..f930cf94c 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestBroadcasting.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestBroadcasting.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleAnalyticTensorAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleAnalyticTensorAlgebra.kt index e4c2c40ea..7fd011986 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleAnalyticTensorAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleAnalyticTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt index cbd7b9887..1c500af8b 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleLinearOpsAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt index 3081639af..59676c122 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensor.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt index 7222fc7a6..4f58846aa 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/TestDoubleTensorAlgebra.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/offsetBufferEquality.kt b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/offsetBufferEquality.kt index c3127ed97..38c51d66e 100644 --- a/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/offsetBufferEquality.kt +++ b/kmath-tensors/src/commonTest/kotlin/space/kscience/kmath/tensors/core/offsetBufferEquality.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt b/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt index 0d0332395..6c072d52b 100644 --- a/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt +++ b/kmath-tensors/src/jvmTest/kotlin/space/kscience/kmath/tensors/core/TestLmAlgorithm.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2023 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt index 52dc1e192..2b5741ed4 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt index f93066423..11cf543d6 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt index 7c0c02086..328a0ab01 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/test-utils/src/commonMain/kotlin/AlgebraicVerifier.kt b/test-utils/src/commonMain/kotlin/AlgebraicVerifier.kt index 261e74f5a..33e7b5972 100644 --- a/test-utils/src/commonMain/kotlin/AlgebraicVerifier.kt +++ b/test-utils/src/commonMain/kotlin/AlgebraicVerifier.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/test-utils/src/commonMain/kotlin/FieldVerifier.kt b/test-utils/src/commonMain/kotlin/FieldVerifier.kt index a03ca0a27..3b3acd32c 100644 --- a/test-utils/src/commonMain/kotlin/FieldVerifier.kt +++ b/test-utils/src/commonMain/kotlin/FieldVerifier.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/test-utils/src/commonMain/kotlin/RingVerifier.kt b/test-utils/src/commonMain/kotlin/RingVerifier.kt index c40075d93..0a1237b60 100644 --- a/test-utils/src/commonMain/kotlin/RingVerifier.kt +++ b/test-utils/src/commonMain/kotlin/RingVerifier.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/test-utils/src/commonMain/kotlin/SpaceVerifier.kt b/test-utils/src/commonMain/kotlin/SpaceVerifier.kt index 01c02997b..ae805db5a 100644 --- a/test-utils/src/commonMain/kotlin/SpaceVerifier.kt +++ b/test-utils/src/commonMain/kotlin/SpaceVerifier.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/test-utils/src/commonMain/kotlin/asserts.kt b/test-utils/src/commonMain/kotlin/asserts.kt index 8ddce517c..54c6301b6 100644 --- a/test-utils/src/commonMain/kotlin/asserts.kt +++ b/test-utils/src/commonMain/kotlin/asserts.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ diff --git a/test-utils/src/commonMain/kotlin/bufferEquality.kt b/test-utils/src/commonMain/kotlin/bufferEquality.kt index c4485abbd..5b2ef6e76 100644 --- a/test-utils/src/commonMain/kotlin/bufferEquality.kt +++ b/test-utils/src/commonMain/kotlin/bufferEquality.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018-2022 KMath contributors. + * Copyright 2018-2024 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. */ From c6f6191ef1701d5101544a81b37be5867f3ee686 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 28 Jan 2024 18:15:33 +0300 Subject: [PATCH 065/103] Deprecate direct angle conversion --- .../src/main/kotlin/space/kscience/kmath/ejml/_generated.kt | 1 - .../commonMain/kotlin/space/kscience/kmath/geometry/angles.kt | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 3a44a9e64..2948e990c 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -23,7 +23,6 @@ import space.kscience.attributes.SafeType import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* -import space.kscience.kmath.linear.Matrix import space.kscience.kmath.nd.StructureFeature import space.kscience.kmath.operations.Float32Field import space.kscience.kmath.operations.Float64Field diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt index 3855514fb..82a0424eb 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt @@ -74,6 +74,7 @@ public fun tan(angle: Angle): Double = kotlin.math.tan(angle.toRadians().value) public val Number.radians: Radians get() = Radians(toDouble()) +@Deprecated("Convert to radians", ReplaceWith("toRadians().value")) public val Angle.radians: Double get() = toRadians().value /** @@ -98,6 +99,7 @@ public value class Degrees(public val value: Double) : Angle { public val Number.degrees: Degrees get() = Degrees(toDouble()) +@Deprecated("Convert to degrees", ReplaceWith("toDegrees().value")) public val Angle.degrees: Double get() = toDegrees().value /** From 8a754ace199d84959978b78fb1b175595a1d7af3 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 7 Feb 2024 21:18:47 +0300 Subject: [PATCH 066/103] Fixed GitHub #524 (Complex power of real-valued number --- CHANGELOG.md | 1 + .../space/kscience/kmath/complex/Complex.kt | 15 +++++++++++- .../kmath/complex/ComplexFieldTest.kt | 23 ++++++++++--------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c6523a0d..0bc556671 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ ### Fixed - Median statistics +- Complex power of negative real numbers ### Security diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt index b5f1aabe7..08c44e036 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt @@ -129,13 +129,25 @@ public object ComplexField : } override fun power(arg: Complex, pow: Number): Complex = if (arg.im == 0.0) { - arg.re.pow(pow.toDouble()).toComplex() + val powDouble = pow.toDouble() + when { + arg.re > 0 -> arg.re.pow(powDouble).toComplex() + arg.re < 0 -> i * (-arg.re).pow(powDouble) + else -> if (powDouble == 0.0) { + one + } else { + zero + } + } + } else { exp(pow * ln(arg)) } public fun power(arg: Complex, pow: Complex): Complex = exp(pow * ln(arg)) + public fun Complex.pow(power: Complex): Complex = power(this, power) + override fun exp(arg: Complex): Complex = exp(arg.re) * (cos(arg.im) + i * sin(arg.im)) @@ -189,6 +201,7 @@ public object ComplexField : override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg) } + /** * Represents `double`-based complex number. * diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt index e11f1c1ea..a545a0792 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt @@ -58,24 +58,25 @@ internal class ComplexFieldTest { } @Test - fun testInverseHyperbolicSine() { - assertEquals( - ComplexField { i * PI.toComplex() / 2 }, - ComplexField { asinh(i) }) + fun testInverseHyperbolicSine() = ComplexField { + assertEquals(i * PI.toComplex() / 2, asinh(i)) } @Test - fun testPower() { - assertEquals(ComplexField.zero, ComplexField { zero pow 2 }) - assertEquals(ComplexField.zero, ComplexField { zero pow 2 }) + fun testPower() = ComplexField { + assertEquals(zero, zero pow 2) + assertEquals(zero, zero pow 2) assertEquals( - ComplexField { i * 8 }.let { it.im.toInt() to it.re.toInt() }, - ComplexField { Complex(2, 2) pow 2 }.let { it.im.toInt() to it.re.toInt() }) + (i * 8).let { it.im.toInt() to it.re.toInt() }, + (Complex(2, 2) pow 2).let { it.im.toInt() to it.re.toInt() }) + + assertEquals(2.0, power(Complex(-4.0, 0.0), 0.5 + 0 * i).im, 0.01) + assertEquals(2.0, power(Complex(-4.0, 0.0), 0.5).im, 0.01) } @Test - fun testNorm() { - assertEquals(2.toComplex(), ComplexField { norm(2 * i) }) + fun testNorm() = ComplexField { + assertEquals(2.toComplex(), norm(2 * i)) } } From 9e3fd240b82e9874517781a523620d5a862b19bb Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Thu, 8 Feb 2024 17:39:19 +0300 Subject: [PATCH 067/103] Update versions --- build.gradle.kts | 2 +- gradle.properties | 2 +- .../space/kscience/kmath/ejml/_generated.kt | 36 ++++++++++++++----- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f40cb88ee..a0befa3c5 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ allprojects { } group = "space.kscience" - version = "0.4.0-dev-2" + version = "0.4.0-dev-3" } subprojects { diff --git a/gradle.properties b/gradle.properties index 5d62bf88e..0d373a8e5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -12,6 +12,6 @@ org.gradle.jvmargs=-Xmx4096m org.gradle.parallel=true org.gradle.workers.max=4 -toolsVersion=0.15.0-kotlin-1.9.20 +toolsVersion=0.15.2-kotlin-1.9.22 #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true \ No newline at end of file diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 7a267b77b..c86d9bc44 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,19 +19,15 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.attributes.SafeType +import space.kscience.attributes.safeTypeOf +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.structures.Float64 -import space.kscience.kmath.structures.Float32 -import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Float32Field -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.FloatField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.Float64Buffer -import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass @@ -45,6 +41,8 @@ public class EjmlDoubleVector<out M : DMatrix>(override val origin: M) : EjmlVec require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } } + override val type: SafeType<Double> get() = safeTypeOf() + override operator fun get(index: Int): Double = origin[0, index] } @@ -56,6 +54,8 @@ public class EjmlFloatVector<out M : FMatrix>(override val origin: M) : EjmlVect require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } } + override val type: SafeType<Float> get() = safeTypeOf() + override operator fun get(index: Int): Float = origin[0, index] } @@ -63,6 +63,8 @@ public class EjmlFloatVector<out M : FMatrix>(override val origin: M) : EjmlVect * [EjmlMatrix] specialization for [Double]. */ public class EjmlDoubleMatrix<out M : DMatrix>(override val origin: M) : EjmlMatrix<Double, M>(origin) { + override val type: SafeType<Double> get() = safeTypeOf() + override operator fun get(i: Int, j: Int): Double = origin[i, j] } @@ -70,9 +72,13 @@ public class EjmlDoubleMatrix<out M : DMatrix>(override val origin: M) : EjmlMat * [EjmlMatrix] specialization for [Float]. */ public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatrix<Float, M>(origin) { + override val type: SafeType<Float> get() = safeTypeOf() + override operator fun get(i: Int, j: Int): Float = origin[i, j] } + + /** * [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and * [DMatrixRMaj] matrices. @@ -83,6 +89,8 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri */ override val elementAlgebra: Float64Field get() = Float64Field + override val type: SafeType<Double> get() = safeTypeOf() + @Suppress("UNCHECKED_CAST") override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixRMaj> = when { this is EjmlDoubleMatrix<*> && origin is DMatrixRMaj -> this as EjmlDoubleMatrix<DMatrixRMaj> @@ -309,6 +317,8 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri } } + + /** * [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and * [FMatrixRMaj] matrices. @@ -319,6 +329,8 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix */ override val elementAlgebra: Float32Field get() = Float32Field + override val type: SafeType<Float> get() = safeTypeOf() + @Suppress("UNCHECKED_CAST") override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixRMaj> = when { this is EjmlFloatMatrix<*> && origin is FMatrixRMaj -> this as EjmlFloatMatrix<FMatrixRMaj> @@ -545,6 +557,8 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix } } + + /** * [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and * [DMatrixSparseCSC] matrices. @@ -555,6 +569,8 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri */ override val elementAlgebra: Float64Field get() = Float64Field + override val type: SafeType<Double> get() = safeTypeOf() + @Suppress("UNCHECKED_CAST") override fun Matrix<Double>.toEjml(): EjmlDoubleMatrix<DMatrixSparseCSC> = when { this is EjmlDoubleMatrix<*> && origin is DMatrixSparseCSC -> this as EjmlDoubleMatrix<DMatrixSparseCSC> @@ -776,6 +792,8 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri } } + + /** * [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and * [FMatrixSparseCSC] matrices. @@ -786,6 +804,8 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix */ override val elementAlgebra: Float32Field get() = Float32Field + override val type: SafeType<Float> get() = safeTypeOf() + @Suppress("UNCHECKED_CAST") override fun Matrix<Float>.toEjml(): EjmlFloatMatrix<FMatrixSparseCSC> = when { this is EjmlFloatMatrix<*> && origin is FMatrixSparseCSC -> this as EjmlFloatMatrix<FMatrixSparseCSC> From ca9df8a1671abda0307fc5ef98257d091a95410f Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Thu, 8 Feb 2024 18:06:06 +0300 Subject: [PATCH 068/103] Add more corner cases for complex power --- .../kotlin/space/kscience/kmath/complex/Complex.kt | 11 +++++++++-- .../space/kscience/kmath/complex/ComplexFieldTest.kt | 5 +++++ .../kotlin/space/kscience/kmath/ejml/_generated.kt | 10 ++-------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt index 009662176..2608f9f65 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt @@ -139,12 +139,19 @@ public object ComplexField : zero } } - } else { exp(pow * ln(arg)) } - public fun power(arg: Complex, pow: Complex): Complex = exp(pow * ln(arg)) + public fun power(arg: Complex, pow: Complex): Complex = if(arg == zero || arg == (-0.0).toComplex()){ + if(pow == zero){ + one + } else { + zero + } + } else { + exp(pow * ln(arg)) + } public fun Complex.pow(power: Complex): Complex = power(this, power) diff --git a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt index cc1f3ad0a..06f7f4580 100644 --- a/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt +++ b/kmath-complex/src/commonTest/kotlin/space/kscience/kmath/complex/ComplexFieldTest.kt @@ -71,6 +71,11 @@ internal class ComplexFieldTest { (i * 8).let { it.im.toInt() to it.re.toInt() }, (Complex(2, 2) pow 2).let { it.im.toInt() to it.re.toInt() }) + assertEquals(1.0, Complex(0.0).pow(Complex(0.0)).re, 0.01) + assertEquals(1.0, Complex(-0.0).pow(Complex(0.0)).re, 0.01) + assertEquals(0.0, Complex(0.0).pow(Complex(2.0)).re, 0.01) + assertEquals(0.0, Complex(-0.0).pow(Complex(2.0)).re, 0.01) + assertEquals(1.0, Complex(-1.0).pow(Complex(2.0)).re, 0.01) assertEquals(2.0, power(Complex(-4.0, 0.0), 0.5 + 0 * i).im, 0.01) assertEquals(2.0, power(Complex(-4.0, 0.0), 0.5).im, 0.01) } diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt index 7a267b77b..a2622eee2 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt @@ -19,19 +19,13 @@ import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC +import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.structures.Float64 -import space.kscience.kmath.structures.Float32 -import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.Float32Field -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.FloatField +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.Float64Buffer -import space.kscience.kmath.structures.Float32Buffer import space.kscience.kmath.structures.DoubleBuffer import space.kscience.kmath.structures.FloatBuffer import kotlin.reflect.KClass From f8e91c2402edeae6b206e5f0ba9b3c51d0e300e2 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sat, 17 Feb 2024 21:32:26 +0300 Subject: [PATCH 069/103] Finishing fixes --- CHANGELOG.md | 2 + .../ExpressionsInterpretersBenchmark.kt | 2 +- .../space/kscience/kmath/fit/chiSquared.kt | 10 +- .../kotlin/space/kscience/kmath/fit/qowFit.kt | 3 +- .../kscience/kmath/functions/interpolate.kt | 5 +- .../kscience/kmath/structures/ComplexND.kt | 4 +- .../kmath/structures/StreamDoubleFieldND.kt | 1 + .../structures/StructureWriteBenchmark.kt | 6 +- .../kscience/kmath/structures/buffers.kt | 2 +- .../kscience/kmath/commons/linear/CMMatrix.kt | 63 ++-- .../kmath/commons/optimization/CMOptimizer.kt | 31 +- .../commons/integration/IntegrationTest.kt | 6 +- .../commons/optimization/OptimizeTest.kt | 5 +- .../kscience/kmath/expressions/Expression.kt | 7 + .../kscience/kmath/linear/LupDecomposition.kt | 24 +- .../space/kscience/kmath/linear/Transposed.kt | 3 +- .../space/kscience/kmath/nd/Float64FieldND.kt | 7 +- .../kscience/kmath/nd/primitiveStructureND.kt | 10 + .../kmath/linear/DoubleLUSolverTest.kt | 2 +- .../space/kscience/kmath/linear/MatrixTest.kt | 2 +- kmath-coroutines/build.gradle.kts | 1 + .../kmath/streaming/RingBufferTest.kt | 5 +- kmath-dimensions/build.gradle.kts | 1 + .../kscience/kmath/dimensions/Wrappers.kt | 2 +- .../kmath/dimensions/Dimension.wasmJs.kt | 23 ++ kmath-ejml/build.gradle.kts | 28 +- .../{_generated.kt => implementations.kt} | 354 ++++++++---------- .../kscience/kmath/ejml/EjmlMatrixTest.kt | 10 +- kmath-for-real/build.gradle.kts | 1 + .../kscience/kmath/real/DoubleVectorTest.kt | 4 +- kmath-functions/build.gradle.kts | 1 - .../kmath/integration/GaussIntegrator.kt | 2 +- .../kmath/interpolation/SplineInterpolator.kt | 2 +- .../kmath/functions/testUtils/IntModulo.kt | 7 +- .../kmath/functions/testUtils/Rational.kt | 2 + .../kmath/integration/SplineIntegralTest.kt | 10 +- .../space/kscience/kmath/geometry/Line.kt | 12 +- .../space/kscience/kmath/geometry/Vector3D.kt | 4 + .../space/kscience/kmath/geometry/angles.kt | 34 +- .../geometry/euclidean2d/Float32Space2D.kt | 9 +- .../geometry/euclidean2d/Float64Space2D.kt | 49 ++- .../geometry/euclidean3d/Float32Space3D.kt | 8 +- .../geometry/euclidean3d/Float64Space3D.kt | 62 +-- .../kmath/geometry/euclidean3d/rotations3D.kt | 20 +- .../kscience/kmath/geometry/testUtils.kt | 7 +- kmath-histograms/build.gradle.kts | 3 +- .../kscience/kmath/histogram/Histogram.kt | 6 +- .../kmath/histogram/UniformHistogram1D.kt | 3 + .../histogram/UniformHistogramGroupND.kt | 31 +- .../kmath/histogram/TreeHistogramGroup.kt | 7 +- .../kmath/kotlingrad/KotlingradExpression.kt | 3 + kmath-nd4j/build.gradle.kts | 2 +- .../kscience/kmath/nd4j/Nd4jArrayStructure.kt | 11 +- kmath-optimization/build.gradle.kts | 1 + .../optimization/FunctionOptimization.kt | 4 + .../kmath/optimization/OptimizationProblem.kt | 8 + .../kmath/optimization/QowOptimizer.kt | 6 +- kmath-stat/build.gradle.kts | 1 + .../space/kscience/kmath/stat/MCScopeTest.kt | 2 +- .../kscience/kmath/symja/SymjaExpression.kt | 5 +- .../tensorflow/DoubleTensorFlowAlgebra.kt | 3 +- .../kmath/tensorflow/IntTensorFlowAlgebra.kt | 10 + .../kmath/tensorflow/TensorFlowAlgebra.kt | 7 +- kmath-tensors/build.gradle.kts | 1 + .../kscience/kmath/tensors/api/Tensor.kt | 10 - .../kmath/tensors/api/TensorAlgebra.kt | 3 + .../core/LevenbergMarquardtAlgorithm.kt | 9 +- .../kscience/kmath/viktor/ViktorBuffer.kt | 4 + .../kmath/viktor/ViktorStructureND.kt | 4 + 69 files changed, 548 insertions(+), 449 deletions(-) create mode 100644 kmath-dimensions/src/wasmJsMain/kotlin/space/kscience/kmath/dimensions/Dimension.wasmJs.kt rename kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/{_generated.kt => implementations.kt} (72%) delete mode 100644 kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/Tensor.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index 29d9c7d6e..2001215ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,9 +20,11 @@ - Kmath-memory is moved on top of core. ### Deprecated +- ND4J engine ### Removed - `asPolynomial` function due to scope pollution +- Codegend for ejml (450 lines of codegen for 1000 lines of code is too much) ### Fixed - Median statistics diff --git a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt index d930c90c0..4fa5be9f1 100644 --- a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt +++ b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt @@ -99,7 +99,7 @@ class ExpressionsInterpretersBenchmark { private val estree = node.estreeCompileToExpression(Float64Field) private val raw = Expression<Double> { args -> - val x = args[x]!! + val x = args.getValue(x) x * 2.0 + 2.0 / x - 16.0 / sin(x) } } diff --git a/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt b/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt index 828017185..14cd5bc76 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt @@ -13,10 +13,7 @@ import space.kscience.kmath.expressions.autodiff import space.kscience.kmath.expressions.symbol import space.kscience.kmath.operations.asIterable import space.kscience.kmath.operations.toList -import space.kscience.kmath.optimization.FunctionOptimizationTarget -import space.kscience.kmath.optimization.optimizeWith -import space.kscience.kmath.optimization.result -import space.kscience.kmath.optimization.resultValue +import space.kscience.kmath.optimization.* import space.kscience.kmath.random.RandomGenerator import space.kscience.kmath.real.DoubleVector import space.kscience.kmath.real.map @@ -80,8 +77,9 @@ suspend fun main() { val result = chi2.optimizeWith( CMOptimizer, mapOf(a to 1.5, b to 0.9, c to 1.0), - FunctionOptimizationTarget.MINIMIZE - ) + ){ + FunctionOptimizationTarget(OptimizationDirection.MINIMIZE) + } //display a page with plot and numerical results val page = Plotly.page { diff --git a/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt b/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt index 108c1f12e..4f3ce5443 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/fit/qowFit.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.fit import kotlinx.html.br import kotlinx.html.h3 +import space.kscience.attributes.Attributes import space.kscience.kmath.data.XYErrorColumnarData import space.kscience.kmath.distributions.NormalDistribution import space.kscience.kmath.expressions.Symbol @@ -64,7 +65,7 @@ suspend fun main() { QowOptimizer, Double.autodiff, mapOf(a to 0.9, b to 1.2, c to 2.0, e to 1.0, d to 1.0, e to 0.0), - OptimizationParameters(a, b, c, d) + attributes = Attributes(OptimizationParameters, listOf(a, b, c, d)) ) { arg -> //bind variables to autodiff context val a by binding diff --git a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt index 817f33dbe..c2e33afd4 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/functions/interpolate.kt @@ -8,7 +8,6 @@ package space.kscience.kmath.functions import space.kscience.kmath.interpolation.SplineInterpolator import space.kscience.kmath.interpolation.interpolatePolynomials import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.structures.Float64Buffer import space.kscience.plotly.Plotly import space.kscience.plotly.UnstablePlotlyAPI import space.kscience.plotly.makeFile @@ -24,9 +23,7 @@ fun main() { x to sin(x) } - val polynomial: PiecewisePolynomial<Double> = SplineInterpolator( - Float64Field, ::Float64Buffer - ).interpolatePolynomials(data) + val polynomial: PiecewisePolynomial<Double> = SplineInterpolator(Float64Field).interpolatePolynomials(data) val function = polynomial.asFunction(Float64Field, 0.0) diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt index c97ba8383..9b48e44a0 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/ComplexND.kt @@ -8,7 +8,7 @@ package space.kscience.kmath.structures import space.kscience.kmath.complex.* -import space.kscience.kmath.linear.transpose +import space.kscience.kmath.linear.transposed import space.kscience.kmath.nd.StructureND import space.kscience.kmath.nd.as2D import space.kscience.kmath.nd.ndAlgebra @@ -60,7 +60,7 @@ fun complexExample() { val sum = matrix + x + 1.0 //Represent the sum as 2d-structure and transpose - sum.as2D().transpose() + sum.as2D().transposed() } } } diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt index 226ec602e..8c34ad4f1 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.structures import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* +import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.ExtendedField import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.NumbersAddOps diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt index 9304e9f4c..8d642d892 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StructureWriteBenchmark.kt @@ -6,20 +6,18 @@ package space.kscience.kmath.structures import space.kscience.kmath.nd.BufferND -import space.kscience.kmath.nd.ShapeND -import space.kscience.kmath.nd.StructureND import space.kscience.kmath.operations.mapToBuffer import kotlin.system.measureTimeMillis private inline fun <T, reified R : Any> BufferND<T>.mapToBufferND( - bufferFactory: BufferFactory<R> = BufferFactory.auto(), + bufferFactory: BufferFactory<R> = BufferFactory(), crossinline block: (T) -> R, ): BufferND<R> = BufferND(indices, buffer.mapToBuffer(bufferFactory, block)) @Suppress("UNUSED_VARIABLE") fun main() { val n = 6000 - val structure = StructureND.buffered(ShapeND(n, n), Buffer.Companion::auto) { 1.0 } + val structure = BufferND(n, n) { 1.0 } structure.mapToBufferND { it + 1 } // warm-up val time1 = measureTimeMillis { val res = structure.mapToBufferND { it + 1 } } println("Structure mapping finished in $time1 millis") diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt index aafd43fd9..d4dfa60cb 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt @@ -13,7 +13,7 @@ import space.kscience.kmath.operations.withSize inline fun <reified R : Any> MutableBuffer.Companion.same( n: Int, value: R -): MutableBuffer<R> = auto(n) { value } +): MutableBuffer<R> = MutableBuffer(n) { value } fun main() { diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index de6b406fd..589dc19e0 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -7,16 +7,20 @@ package space.kscience.kmath.commons.linear import org.apache.commons.math3.linear.* import org.apache.commons.math3.linear.LUDecomposition +import org.apache.commons.math3.linear.SingularValueDecomposition import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* +import space.kscience.kmath.linear.CholeskyDecomposition +import space.kscience.kmath.linear.QRDecomposition import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.nd.StructureAttribute import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.Float64Buffer -import kotlin.reflect.cast +import space.kscience.kmath.structures.Float64 +import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.asBuffer public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> { override val type: SafeType<Double> get() = DoubleField.type @@ -109,45 +113,44 @@ public object CMLinearSpace : LinearSpace<Double, Float64Field> { val origin = structure.toCM().origin - return when (attribute) { - IsDiagonal -> if (origin is DiagonalMatrix) IsDiagonal else null + val raw: Any? = when (attribute) { + IsDiagonal -> if (origin is DiagonalMatrix) Unit else null Determinant -> LUDecomposition(origin).determinant - LUP -> GenericLupDecomposition { - private val lup by lazy { LUDecomposition(origin) } - override val determinant: Double by lazy { lup.determinant } - override val l: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(lup.l).withAttribute(LowerTriangular) } - override val u: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(lup.u).withAttribute(UpperTriangular) } - override val p: Matrix<Double> by lazy { CMMatrix(lup.p) } + + LUP -> object : LupDecomposition<Float64> { + val lup by lazy { LUDecomposition(origin) } + override val pivot: IntBuffer get() = lup.pivot.asBuffer() + override val l: Matrix<Float64> get() = lup.l.wrap() + override val u: Matrix<Float64> get() = lup.u.wrap() } - CholeskyDecompositionAttribute -> object : CholeskyDecompositionAttribute<Double> { - override val l: Matrix<Double> by lazy<Matrix<Double>> { - val cholesky = CholeskyDecomposition(origin) - CMMatrix(cholesky.l).withAttribute(LowerTriangular) - } + Cholesky -> object : CholeskyDecomposition<Float64> { + val cmCholesky by lazy { org.apache.commons.math3.linear.CholeskyDecomposition(origin) } + override val l: Matrix<Double> get() = cmCholesky.l.wrap() } - QRDecompositionAttribute -> object : QRDecompositionAttribute<Double> { - private val qr by lazy { QRDecomposition(origin) } - override val q: Matrix<Double> by lazy<Matrix<Double>> { - CMMatrix(qr.q).withAttribute( - OrthogonalAttribute - ) - } - override val r: Matrix<Double> by lazy<Matrix<Double>> { CMMatrix(qr.r).withAttribute(UpperTriangular) } + QR -> object : QRDecomposition<Float64> { + val cmQr by lazy { org.apache.commons.math3.linear.QRDecomposition(origin) } + override val q: Matrix<Float64> get() = cmQr.q.wrap().withAttribute(OrthogonalAttribute) + override val r: Matrix<Float64> get() = cmQr.r.wrap().withAttribute(UpperTriangular) } - SVDAttribute -> object : SVDAttribute<Double> { - private val sv by lazy { SingularValueDecomposition(origin) } - override val u: Matrix<Double> by lazy { CMMatrix(sv.u) } - override val s: Matrix<Double> by lazy { CMMatrix(sv.s) } - override val v: Matrix<Double> by lazy { CMMatrix(sv.v) } - override val singularValues: Point<Double> by lazy { Float64Buffer(sv.singularValues) } + SVD -> object : space.kscience.kmath.linear.SingularValueDecomposition<Float64> { + val cmSvd by lazy { SingularValueDecomposition(origin) } + + override val u: Matrix<Float64> get() = cmSvd.u.wrap() + override val s: Matrix<Float64> get() = cmSvd.s.wrap() + override val v: Matrix<Float64> get() = cmSvd.v.wrap() + override val singularValues: Point<Float64> get() = cmSvd.singularValues.asBuffer() + } else -> null - }?.let(type::cast) + } + @Suppress("UNCHECKED_CAST") + return raw as V? } + } public operator fun CMMatrix.plus(other: CMMatrix): CMMatrix = CMMatrix(origin.add(other.origin)) diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt index 83ccea035..afbb96d9b 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt @@ -3,6 +3,7 @@ * 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(UnstableKMathAPI::class) + package space.kscience.kmath.commons.optimization import org.apache.commons.math3.optim.* @@ -20,7 +21,6 @@ import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.expressions.SymbolIndexer import space.kscience.kmath.expressions.derivative import space.kscience.kmath.expressions.withSymbols -import space.kscience.kmath.misc.log import space.kscience.kmath.optimization.* import kotlin.collections.set import kotlin.reflect.KClass @@ -28,7 +28,7 @@ import kotlin.reflect.KClass public operator fun PointValuePair.component1(): DoubleArray = point public operator fun PointValuePair.component2(): Double = value -public object CMOptimizerEngine: OptimizationAttribute<() -> MultivariateOptimizer> +public object CMOptimizerEngine : OptimizationAttribute<() -> MultivariateOptimizer> /** * Specify a Commons-maths optimization engine @@ -37,7 +37,7 @@ public fun AttributesBuilder<FunctionOptimization<Double>>.cmEngine(optimizerBui set(CMOptimizerEngine, optimizerBuilder) } -public object CMOptimizerData: SetAttribute<SymbolIndexer.() -> OptimizationData> +public object CMOptimizerData : SetAttribute<SymbolIndexer.() -> OptimizationData> /** * Specify Commons-maths optimization data. @@ -118,21 +118,24 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> { val logger = problem.attributes[OptimizationLog] - for (feature in problem.attributes) { - when (feature) { - is CMOptimizerData -> feature.data.forEach { dataBuilder -> - addOptimizationData(dataBuilder()) - } - is FunctionOptimizationTarget -> when (feature) { - FunctionOptimizationTarget.MAXIMIZE -> addOptimizationData(GoalType.MAXIMIZE) - FunctionOptimizationTarget.MINIMIZE -> addOptimizationData(GoalType.MINIMIZE) - } - else -> logger?.log { "The feature $feature is unused in optimization" } + problem.attributes[CMOptimizerData]?.let { builders: Set<SymbolIndexer.() -> OptimizationData> -> + builders.forEach { dataBuilder -> + addOptimizationData(dataBuilder()) + } + } + + problem.attributes[FunctionOptimizationTarget]?.let { direction: OptimizationDirection -> + when (direction) { + OptimizationDirection.MAXIMIZE -> addOptimizationData(GoalType.MAXIMIZE) + OptimizationDirection.MINIMIZE -> addOptimizationData(GoalType.MINIMIZE) } } val (point, value) = cmOptimizer.optimize(*optimizationData.values.toTypedArray()) - return problem.withAttributes(OptimizationResult(point.toMap()), OptimizationValue(value)) + return problem.withAttributes { + result(point.toMap()) + value(value) + } } } } diff --git a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt index c2e630f38..43857c539 100644 --- a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt +++ b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/integration/IntegrationTest.kt @@ -7,6 +7,8 @@ package space.kscience.kmath.commons.integration import org.junit.jupiter.api.Test import space.kscience.kmath.UnstableKMathAPI +import space.kscience.kmath.integration.IntegrandAbsoluteAccuracy +import space.kscience.kmath.integration.IntegrandRelativeAccuracy import space.kscience.kmath.integration.integrate import space.kscience.kmath.integration.value import space.kscience.kmath.operations.Float64Field.sin @@ -27,8 +29,8 @@ internal class IntegrationTest { @Test fun customSimpson() { val res = CMIntegrator.simpson().integrate(0.0..PI, { - targetRelativeAccuracy = 1e-4 - targetAbsoluteAccuracy = 1e-4 + IntegrandRelativeAccuracy(1e-4) + IntegrandAbsoluteAccuracy(1e-4) }, function).value assertTrue { abs(res - 2) < 1e-3 } assertTrue { abs(res - 2) > 1e-12 } diff --git a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt index e17ba48e9..177a01b43 100644 --- a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt +++ b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt @@ -73,8 +73,9 @@ internal class OptimizeTest { val result: FunctionOptimization<Double> = chi2.optimizeWith( CMOptimizer, mapOf(a to 1.5, b to 0.9, c to 1.0), - FunctionOptimizationTarget.MINIMIZE - ) + ){ + FunctionOptimizationTarget(OptimizationDirection.MINIMIZE) + } println(result) println("Chi2/dof = ${result.resultValue / (x.size - 3)}") } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt index 7bf48fcc1..f2e134963 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/Expression.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.expressions import space.kscience.attributes.SafeType import space.kscience.attributes.WithType +import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Algebra import space.kscience.kmath.operations.DoubleField @@ -30,12 +31,18 @@ public interface Expression<T> : WithType<T> { public operator fun invoke(arguments: Map<Symbol, T>): T } +/** + * Create an expression from a functional block. + */ public fun <T> Expression(type: SafeType<T>, block: (Map<Symbol, T>) -> T): Expression<T> = object : Expression<T> { override fun invoke(arguments: Map<Symbol, T>): T = block(arguments) override val type: SafeType<T> = type } +public inline fun <reified T> Expression(noinline block: (Map<Symbol, T>) -> T): Expression<T> = + Expression(safeTypeOf<T>(), block) + /** * Specialization of [Expression] for [Double] allowing better performance because of using array. */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 4d2768e02..14828f2df 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -15,14 +15,19 @@ import space.kscience.kmath.operations.* import space.kscience.kmath.structures.* public interface LupDecomposition<T> { - public val linearSpace: LinearSpace<T, Field<T>> - public val elementAlgebra: Field<T> get() = linearSpace.elementAlgebra - public val pivot: IntBuffer public val l: Matrix<T> public val u: Matrix<T> } +/** + * Create a pivot matrix from pivot vector using provided [LinearSpace] + */ +public fun <T> LupDecomposition<T>.pivotMatrix(linearSpace: LinearSpace<T, Ring<T>>): Matrix<T> = + VirtualMatrix(linearSpace.type, l.rowNum, l.colNum) { row, column -> + if (column == pivot[row]) linearSpace.elementAlgebra.one else linearSpace.elementAlgebra.zero + } + /** * Matrices with this feature support LU factorization with partial pivoting: *[p] · a = [l] · [u]* where * *a* is the owning matrix. @@ -31,12 +36,14 @@ public interface LupDecomposition<T> { * @param lu combined L and U matrix */ public class GenericLupDecomposition<T>( - override val linearSpace: LinearSpace<T, Field<T>>, + public val linearSpace: LinearSpace<T, Field<T>>, private val lu: Matrix<T>, override val pivot: IntBuffer, private val even: Boolean, ) : LupDecomposition<T> { + private val elementAlgebra get() = linearSpace.elementAlgebra + override val l: Matrix<T> get() = VirtualMatrix(lu.type, lu.rowNum, lu.colNum, attributes = Attributes(LowerTriangular)) { i, j -> when { @@ -51,11 +58,6 @@ public class GenericLupDecomposition<T>( if (j >= i) lu[i, j] else elementAlgebra.zero } - public val pivotMatrix: Matrix<T> - get() = VirtualMatrix(linearSpace.type, l.rowNum, l.colNum) { row, column -> - if (column == pivot[row]) elementAlgebra.one else elementAlgebra.zero - } - public val determinant: T by lazy { elementAlgebra { (0 until l.shape[0]).fold(if (even) one else -one) { value, i -> value * lu[i, i] } } } @@ -79,7 +81,7 @@ internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T = public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( matrix: Matrix<T>, checkSingular: (T) -> Boolean, -): LupDecomposition<T> = elementAlgebra { +): GenericLupDecomposition<T> = elementAlgebra { require(matrix.rowNum == matrix.colNum) { "LU decomposition supports only square matrices" } val m = matrix.colNum val pivot = IntArray(matrix.rowNum) @@ -156,7 +158,7 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( public fun LinearSpace<Double, Float64Field>.lup( matrix: Matrix<Double>, singularityThreshold: Double = 1e-11, -): LupDecomposition<Double> = lup(matrix) { it < singularityThreshold } +): GenericLupDecomposition<Double> = lup(matrix) { it < singularityThreshold } internal fun <T> LinearSpace<T, Field<T>>.solve( lup: LupDecomposition<T>, diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt index 2cc566f92..28821a52a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt @@ -25,5 +25,4 @@ public class TransposedMatrix<T>(public val origin: Matrix<T>) : Matrix<T> { /** * Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A` */ -public val <T> Matrix<T>.transposed: Matrix<T> - get() = (this as? TransposedMatrix<T>)?.origin ?: TransposedMatrix(this) \ No newline at end of file +public fun <T> Matrix<T>.transposed(): Matrix<T> = (this as? TransposedMatrix<T>)?.origin ?: TransposedMatrix(this) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt index 309f9cb37..ab9b25663 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt @@ -5,9 +5,11 @@ package space.kscience.kmath.nd +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* +import space.kscience.kmath.structures.Float64 import space.kscience.kmath.structures.Float64Buffer import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -20,7 +22,10 @@ import kotlin.math.pow as kpow public class Float64BufferND( indexes: ShapeIndexer, override val buffer: Float64Buffer, -) : MutableBufferND<Double>(indexes, buffer), MutableStructureNDOfDouble{ +) : MutableBufferND<Double>(indexes, buffer), MutableStructureNDOfDouble { + + override val type: SafeType<Float64> get() = Float64Field.type + override fun getDouble(index: IntArray): Double = buffer[indices.offset(index)] override fun setDouble(index: IntArray, value: Double) { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt index 9f70b6dca..ca299f12f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt @@ -5,9 +5,15 @@ package space.kscience.kmath.nd +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.Int32Field +import space.kscience.kmath.structures.Float64 public interface StructureNDOfDouble : StructureND<Double> { + override val type: SafeType<Float64> get() = Float64Field.type + /** * Guaranteed non-blocking access to content */ @@ -22,6 +28,7 @@ public fun StructureND<Double>.getDouble(index: IntArray): Double = if (this is StructureNDOfDouble) getDouble(index) else get(index) public interface MutableStructureNDOfDouble : StructureNDOfDouble, MutableStructureND<Double> { + /** * Guaranteed non-blocking access to content */ @@ -34,6 +41,9 @@ public fun MutableStructureND<Double>.getDouble(index: IntArray): Double = public interface StructureNDOfInt : StructureND<Int> { + + override val type: SafeType<Int> get() = Int32Field.type + /** * Guaranteed non-blocking access to content */ diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt index 9989afd6c..e50d1230d 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt @@ -40,7 +40,7 @@ class DoubleLUSolverTest { //Check determinant assertEquals(7.0, lup.determinant) - assertMatrixEquals(lup.pivotMatrix dot matrix, lup.l dot lup.u) + assertMatrixEquals(lup.pivotMatrix(this) dot matrix, lup.l dot lup.u) } @Test diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt index 9d69d0379..4e9cc2011 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt @@ -21,7 +21,7 @@ class MatrixTest { @Test fun testTranspose() = Double.algebra.linearSpace.run { val matrix = one(3, 3) - val transposed = matrix.transposed + val transposed = matrix.transposed() assertTrue { StructureND.contentEquals(matrix, transposed) } } diff --git a/kmath-coroutines/build.gradle.kts b/kmath-coroutines/build.gradle.kts index 1e901ca98..91b2afd5e 100644 --- a/kmath-coroutines/build.gradle.kts +++ b/kmath-coroutines/build.gradle.kts @@ -6,6 +6,7 @@ kscience { jvm() js() native() + wasm() dependencies { api(project(":kmath-core")) diff --git a/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/RingBufferTest.kt b/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/RingBufferTest.kt index 6219a5886..701715123 100644 --- a/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/RingBufferTest.kt +++ b/kmath-coroutines/src/jvmTest/kotlin/space/kscience/kmath/streaming/RingBufferTest.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.streaming import kotlinx.coroutines.flow.* import kotlinx.coroutines.runBlocking +import space.kscience.kmath.operations.Int32Ring import space.kscience.kmath.operations.asSequence import kotlin.test.Test import kotlin.test.assertEquals @@ -14,7 +15,7 @@ import kotlin.test.assertEquals internal class RingBufferTest { @Test fun push() { - val buffer = RingBuffer.build(20, Double.NaN) + val buffer = RingBuffer(20, Double.NaN) runBlocking { for (i in 1..30) { buffer.push(i.toDouble()) @@ -30,7 +31,7 @@ internal class RingBufferTest { while (true) emit(i++) } - val windowed = flow.windowed(10) + val windowed = flow.windowed(10, Int32Ring) runBlocking { @Suppress("UNUSED_VARIABLE") val first = windowed.take(1).single() diff --git a/kmath-dimensions/build.gradle.kts b/kmath-dimensions/build.gradle.kts index be1fc65a0..0ed6a8949 100644 --- a/kmath-dimensions/build.gradle.kts +++ b/kmath-dimensions/build.gradle.kts @@ -6,6 +6,7 @@ kscience{ jvm() js() native() + wasm() dependencies{ api(projects.kmathCore) diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt index cd24d25e7..d1de77d54 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt @@ -153,7 +153,7 @@ public value class DMatrixContext<T : Any, out A : Ring<T>>(public val context: context.run { this@unaryMinus.unaryMinus() }.coerce() public inline fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.transposed(): DMatrix<T, R, C> = - context.run { (this@transposed as Matrix<T>).transposed }.coerce() + context.run { (this@transposed as Matrix<T>).transposed() }.coerce() public companion object { public val real: DMatrixContext<Double, Float64Field> = DMatrixContext(Double.algebra.linearSpace) diff --git a/kmath-dimensions/src/wasmJsMain/kotlin/space/kscience/kmath/dimensions/Dimension.wasmJs.kt b/kmath-dimensions/src/wasmJsMain/kotlin/space/kscience/kmath/dimensions/Dimension.wasmJs.kt new file mode 100644 index 000000000..cbf404b7f --- /dev/null +++ b/kmath-dimensions/src/wasmJsMain/kotlin/space/kscience/kmath/dimensions/Dimension.wasmJs.kt @@ -0,0 +1,23 @@ +/* + * Copyright 2018-2024 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.dimensions + +import kotlin.reflect.KClass + +private val dimensionMap: MutableMap<Int, Dimension> = hashMapOf(1 to D1, 2 to D2, 3 to D3) + +@Suppress("UNCHECKED_CAST") +public actual fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D = dimensionMap + .entries + .map(MutableMap.MutableEntry<Int, Dimension>::value) + .find { it::class == type } as? D + ?: error("Can't resolve dimension $type") + +public actual fun Dimension.Companion.of(dim: Int): Dimension = dimensionMap.getOrPut(dim) { + object : Dimension { + override val dim: Int get() = dim + } +} diff --git a/kmath-ejml/build.gradle.kts b/kmath-ejml/build.gradle.kts index d7f780d79..54b8f7038 100644 --- a/kmath-ejml/build.gradle.kts +++ b/kmath-ejml/build.gradle.kts @@ -1,15 +1,15 @@ -import space.kscience.kmath.ejml.codegen.ejmlCodegen - plugins { id("space.kscience.gradle.jvm") } +val ejmlVerision = "0.43.1" + dependencies { - api("org.ejml:ejml-ddense:0.41") - api("org.ejml:ejml-fdense:0.41") - api("org.ejml:ejml-dsparse:0.41") - api("org.ejml:ejml-fsparse:0.41") - api(project(":kmath-core")) + api("org.ejml:ejml-ddense:$ejmlVerision") + api("org.ejml:ejml-fdense:$ejmlVerision") + api("org.ejml:ejml-dsparse:$ejmlVerision") + api("org.ejml:ejml-fsparse:$ejmlVerision") + api(projects.kmathCore) } readme { @@ -32,10 +32,10 @@ readme { ) { "LinearSpace implementations." } } -kotlin.sourceSets.main { - val codegen by tasks.creating { - ejmlCodegen(kotlin.srcDirs.first().absolutePath + "/space/kscience/kmath/ejml/_generated.kt") - } - - kotlin.srcDirs(files().builtBy(codegen)) -} +//kotlin.sourceSets.main { +// val codegen by tasks.creating { +// ejmlCodegen(kotlin.srcDirs.first().absolutePath + "/space/kscience/kmath/ejml/_generated.kt") +// } +// +// kotlin.srcDirs(files().builtBy(codegen)) +//} diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt similarity index 72% rename from kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt rename to kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt index c86d9bc44..d33a74199 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/_generated.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt @@ -17,21 +17,18 @@ import org.ejml.sparse.csc.CommonOps_DSCC import org.ejml.sparse.csc.CommonOps_FSCC import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC -import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC -import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC import space.kscience.attributes.SafeType import space.kscience.attributes.safeTypeOf -import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.linear.* import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.nd.StructureFeature +import space.kscience.kmath.nd.Structure2D +import space.kscience.kmath.nd.StructureAttribute import space.kscience.kmath.operations.Float32Field import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.DoubleBuffer -import space.kscience.kmath.structures.FloatBuffer -import kotlin.reflect.KClass -import kotlin.reflect.cast +import space.kscience.kmath.structures.Float32 +import space.kscience.kmath.structures.IntBuffer +import space.kscience.kmath.structures.asBuffer /** * [EjmlVector] specialization for [Double]. @@ -78,7 +75,6 @@ public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatr } - /** * [EjmlLinearSpace] implementation based on [CommonOps_DDRM], [DecompositionFactory_DDRM] operations and * [DMatrixRMaj] matrices. @@ -143,10 +139,10 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri val out = DMatrixRMaj(1, 1) CommonOps_DDRM.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -167,12 +163,12 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixRMaj> { val out = DMatrixRMaj(1, 1) - + CommonOps_DDRM.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -217,77 +213,65 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixRMaj> = v * this - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } + override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Double>, attribute: A): V? { val origin = structure.toEjml().origin - return when (type) { - InverseMatrixFeature::class -> object : InverseMatrixFeature<Double> { - override val inverse: Matrix<Double> by lazy { - val res = origin.copy() - CommonOps_DDRM.invert(res) - res.wrapMatrix() - } + val raw: Any? = when (attribute) { + Inverted -> { + val res = origin.copy() + CommonOps_DDRM.invert(res) + res.wrapMatrix() } - DeterminantFeature::class -> object : DeterminantFeature<Double> { - override val determinant: Double by lazy { CommonOps_DDRM.det(origin) } - } - - SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Double> { - private val svd by lazy { - DecompositionFactory_DDRM.svd(origin.numRows, origin.numCols, true, true, false) + Determinant -> CommonOps_DDRM.det(origin) + SVD -> object : SingularValueDecomposition<Double> { + val ejmlSvd by lazy { + DecompositionFactory_DDRM + .svd(origin.numRows, origin.numCols, true, true, false) .apply { decompose(origin.copy()) } } + override val u: Matrix<Double> get() = ejmlSvd.getU(null, false).wrapMatrix() + + override val s: Matrix<Double> get() = ejmlSvd.getW(null).wrapMatrix() + override val v: Matrix<Double> get() = ejmlSvd.getV(null, false).wrapMatrix() + override val singularValues: Point<Double> get() = ejmlSvd.singularValues.asBuffer() - override val u: Matrix<Double> by lazy { svd.getU(null, false).wrapMatrix() } - override val s: Matrix<Double> by lazy { svd.getW(null).wrapMatrix() } - override val v: Matrix<Double> by lazy { svd.getV(null, false).wrapMatrix() } - override val singularValues: Point<Double> by lazy { DoubleBuffer(svd.singularValues) } } - QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> { - private val qr by lazy { - DecompositionFactory_DDRM.qr().apply { decompose(origin.copy()) } - } - - override val q: Matrix<Double> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<Double> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } + QR -> object : QRDecomposition<Double> { + val ejmlQr by lazy { DecompositionFactory_DDRM.qr().apply { decompose(origin.copy()) } } + override val q: Matrix<Double> get() = ejmlQr.getQ(null, false).wrapMatrix() + override val r: Matrix<Double> get() = ejmlQr.getR(null, false).wrapMatrix() } - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> { + Cholesky -> object : CholeskyDecomposition<Double> { override val l: Matrix<Double> by lazy { val cholesky = DecompositionFactory_DDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) } - cholesky.getT(null).wrapMatrix().withFeature(LFeature) + cholesky.getT(null).wrapMatrix().withAttribute(LowerTriangular) } } - LupDecompositionFeature::class -> object : LupDecompositionFeature<Double> { + LUP -> object : LupDecomposition<Double> { private val lup by lazy { DecompositionFactory_DDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) } } - override val l: Matrix<Double> by lazy { - lup.getLower(null).wrapMatrix().withFeature(LFeature) - } + override val l: Matrix<Double> + get() = lup.getLower(null).wrapMatrix().withAttribute(LowerTriangular) - override val u: Matrix<Double> by lazy { - lup.getUpper(null).wrapMatrix().withFeature(UFeature) - } - override val p: Matrix<Double> by lazy { lup.getRowPivot(null).wrapMatrix() } + override val u: Matrix<Double> + get() = lup.getUpper(null).wrapMatrix().withAttribute(UpperTriangular) + override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer() } else -> null - }?.let{ - type.cast(it) } + + @Suppress("UNCHECKED_CAST") + return raw as V? } /** @@ -318,7 +302,6 @@ public object EjmlLinearSpaceDDRM : EjmlLinearSpace<Double, Float64Field, DMatri } - /** * [EjmlLinearSpace] implementation based on [CommonOps_FDRM], [DecompositionFactory_FDRM] operations and * [FMatrixRMaj] matrices. @@ -383,10 +366,10 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix val out = FMatrixRMaj(1, 1) CommonOps_FDRM.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -407,12 +390,12 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixRMaj> { val out = FMatrixRMaj(1, 1) - + CommonOps_FDRM.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, ) @@ -457,77 +440,65 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix override fun Float.times(v: Point<Float>): EjmlFloatVector<FMatrixRMaj> = v * this - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Float>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } + override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Float32>, attribute: A): V? { val origin = structure.toEjml().origin - return when (type) { - InverseMatrixFeature::class -> object : InverseMatrixFeature<Float> { - override val inverse: Matrix<Float> by lazy { - val res = origin.copy() - CommonOps_FDRM.invert(res) - res.wrapMatrix() - } + val raw: Any? = when (attribute) { + Inverted -> { + val res = origin.copy() + CommonOps_FDRM.invert(res) + res.wrapMatrix() } - DeterminantFeature::class -> object : DeterminantFeature<Float> { - override val determinant: Float by lazy { CommonOps_FDRM.det(origin) } - } - - SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<Float> { - private val svd by lazy { - DecompositionFactory_FDRM.svd(origin.numRows, origin.numCols, true, true, false) + Determinant -> CommonOps_FDRM.det(origin) + SVD -> object : SingularValueDecomposition<Float32> { + val ejmlSvd by lazy { + DecompositionFactory_FDRM + .svd(origin.numRows, origin.numCols, true, true, false) .apply { decompose(origin.copy()) } } + override val u: Matrix<Float32> get() = ejmlSvd.getU(null, false).wrapMatrix() + + override val s: Matrix<Float32> get() = ejmlSvd.getW(null).wrapMatrix() + override val v: Matrix<Float32> get() = ejmlSvd.getV(null, false).wrapMatrix() + override val singularValues: Point<Float32> get() = ejmlSvd.singularValues.asBuffer() - override val u: Matrix<Float> by lazy { svd.getU(null, false).wrapMatrix() } - override val s: Matrix<Float> by lazy { svd.getW(null).wrapMatrix() } - override val v: Matrix<Float> by lazy { svd.getV(null, false).wrapMatrix() } - override val singularValues: Point<Float> by lazy { FloatBuffer(svd.singularValues) } } - QRDecompositionFeature::class -> object : QRDecompositionFeature<Float> { - private val qr by lazy { - DecompositionFactory_FDRM.qr().apply { decompose(origin.copy()) } - } - - override val q: Matrix<Float> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<Float> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } + QR -> object : QRDecomposition<Float32> { + val ejmlQr by lazy { DecompositionFactory_FDRM.qr().apply { decompose(origin.copy()) } } + override val q: Matrix<Float32> get() = ejmlQr.getQ(null, false).wrapMatrix() + override val r: Matrix<Float32> get() = ejmlQr.getR(null, false).wrapMatrix() } - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Float> { - override val l: Matrix<Float> by lazy { + Cholesky -> object : CholeskyDecomposition<Float32> { + override val l: Matrix<Float32> by lazy { val cholesky = DecompositionFactory_FDRM.chol(structure.rowNum, true).apply { decompose(origin.copy()) } - cholesky.getT(null).wrapMatrix().withFeature(LFeature) + cholesky.getT(null).wrapMatrix().withAttribute(LowerTriangular) } } - LupDecompositionFeature::class -> object : LupDecompositionFeature<Float> { + LUP -> object : LupDecomposition<Float32> { private val lup by lazy { DecompositionFactory_FDRM.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) } } - override val l: Matrix<Float> by lazy { - lup.getLower(null).wrapMatrix().withFeature(LFeature) - } + override val l: Matrix<Float32> + get() = lup.getLower(null).wrapMatrix().withAttribute(LowerTriangular) - override val u: Matrix<Float> by lazy { - lup.getUpper(null).wrapMatrix().withFeature(UFeature) - } - override val p: Matrix<Float> by lazy { lup.getRowPivot(null).wrapMatrix() } + override val u: Matrix<Float32> + get() = lup.getUpper(null).wrapMatrix().withAttribute(UpperTriangular) + override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer() } else -> null - }?.let{ - type.cast(it) } + + @Suppress("UNCHECKED_CAST") + return raw as V? } /** @@ -558,7 +529,6 @@ public object EjmlLinearSpaceFDRM : EjmlLinearSpace<Float, Float32Field, FMatrix } - /** * [EjmlLinearSpace] implementation based on [CommonOps_DSCC], [DecompositionFactory_DSCC] operations and * [DMatrixSparseCSC] matrices. @@ -623,12 +593,12 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri val out = DMatrixSparseCSC(1, 1) CommonOps_DSCC.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -649,14 +619,14 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri override fun Matrix<Double>.plus(other: Matrix<Double>): EjmlDoubleMatrix<DMatrixSparseCSC> { val out = DMatrixSparseCSC(1, 1) - + CommonOps_DSCC.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -672,7 +642,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri elementAlgebra.one, other.toEjml().origin, out, - null, + null, null, ) @@ -688,7 +658,7 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri elementAlgebra { -one }, other.toEjml().origin, out, - null, + null, null, ) @@ -705,64 +675,52 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri override fun Double.times(v: Point<Double>): EjmlDoubleVector<DMatrixSparseCSC> = v * this - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Double>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } + override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Double>, attribute: A): V? { val origin = structure.toEjml().origin - return when (type) { - QRDecompositionFeature::class -> object : QRDecompositionFeature<Double> { - private val qr by lazy { - DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } - } - - override val q: Matrix<Double> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<Double> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } + val raw: Any? = when (attribute) { + Inverted -> { + val res = DMatrixRMaj(origin.numRows,origin.numCols) + CommonOps_DSCC.invert(origin,res) + res.wrapMatrix() } - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Double> { + Determinant -> CommonOps_DSCC.det(origin) + + QR -> object : QRDecomposition<Double> { + val ejmlQr by lazy { DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } } + override val q: Matrix<Double> get() = ejmlQr.getQ(null, false).wrapMatrix() + override val r: Matrix<Double> get() = ejmlQr.getR(null, false).wrapMatrix() + } + + Cholesky -> object : CholeskyDecomposition<Double> { override val l: Matrix<Double> by lazy { val cholesky = DecompositionFactory_DSCC.cholesky().apply { decompose(origin.copy()) } - (cholesky.getT(null) as DMatrix).wrapMatrix().withFeature(LFeature) + (cholesky.getT(null) as DMatrix).wrapMatrix().withAttribute(LowerTriangular) } } - LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object : - LUDecompositionFeature<Double>, DeterminantFeature<Double>, InverseMatrixFeature<Double> { - private val lu by lazy { + LUP -> object : LupDecomposition<Double> { + private val lup by lazy { DecompositionFactory_DSCC.lu(FillReducing.NONE).apply { decompose(origin.copy()) } } - override val l: Matrix<Double> by lazy { - lu.getLower(null).wrapMatrix().withFeature(LFeature) - } + override val l: Matrix<Double> + get() = lup.getLower(null).wrapMatrix().withAttribute(LowerTriangular) - override val u: Matrix<Double> by lazy { - lu.getUpper(null).wrapMatrix().withFeature(UFeature) - } - override val inverse: Matrix<Double> by lazy { - var a = origin - val inverse = DMatrixRMaj(1, 1) - val solver = LinearSolverFactory_DSCC.lu(FillReducing.NONE) - if (solver.modifiesA()) a = a.copy() - val i = CommonOps_DDRM.identity(a.numRows) - solver.solve(i, inverse) - inverse.wrapMatrix() - } - - override val determinant: Double by lazy { elementAlgebra.number(lu.computeDeterminant().real) } + override val u: Matrix<Double> + get() = lup.getUpper(null).wrapMatrix().withAttribute(UpperTriangular) + override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer() } else -> null - }?.let{ - type.cast(it) } + + @Suppress("UNCHECKED_CAST") + return raw as V? } /** @@ -793,7 +751,6 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri } - /** * [EjmlLinearSpace] implementation based on [CommonOps_FSCC], [DecompositionFactory_FSCC] operations and * [FMatrixSparseCSC] matrices. @@ -858,12 +815,12 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix val out = FMatrixSparseCSC(1, 1) CommonOps_FSCC.add( - elementAlgebra.one, - toEjml().origin, + elementAlgebra.one, + toEjml().origin, elementAlgebra { -one }, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -884,14 +841,14 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix override fun Matrix<Float>.plus(other: Matrix<Float>): EjmlFloatMatrix<FMatrixSparseCSC> { val out = FMatrixSparseCSC(1, 1) - + CommonOps_FSCC.add( elementAlgebra.one, toEjml().origin, elementAlgebra.one, - other.toEjml().origin, + other.toEjml().origin, out, - null, + null, null, ) @@ -907,7 +864,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix elementAlgebra.one, other.toEjml().origin, out, - null, + null, null, ) @@ -923,7 +880,7 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix elementAlgebra { -one }, other.toEjml().origin, out, - null, + null, null, ) @@ -939,65 +896,52 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix } override fun Float.times(v: Point<Float>): EjmlFloatVector<FMatrixSparseCSC> = v * this - - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<Float>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } + override fun <V, A : StructureAttribute<V>> computeAttribute(structure: Structure2D<Float32>, attribute: A): V? { val origin = structure.toEjml().origin - return when (type) { - QRDecompositionFeature::class -> object : QRDecompositionFeature<Float> { - private val qr by lazy { - DecompositionFactory_FSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } - } - - override val q: Matrix<Float> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<Float> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } + val raw: Any? = when (attribute) { + Inverted -> { + val res = FMatrixRMaj(origin.numRows,origin.numCols) + CommonOps_FSCC.invert(origin,res) + res.wrapMatrix() } - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<Float> { - override val l: Matrix<Float> by lazy { + Determinant -> CommonOps_FSCC.det(origin) + + QR -> object : QRDecomposition<Float32> { + val ejmlQr by lazy { DecompositionFactory_FSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } } + override val q: Matrix<Float32> get() = ejmlQr.getQ(null, false).wrapMatrix() + override val r: Matrix<Float32> get() = ejmlQr.getR(null, false).wrapMatrix() + } + + Cholesky -> object : CholeskyDecomposition<Float32> { + override val l: Matrix<Float32> by lazy { val cholesky = DecompositionFactory_FSCC.cholesky().apply { decompose(origin.copy()) } - (cholesky.getT(null) as FMatrix).wrapMatrix().withFeature(LFeature) + (cholesky.getT(null) as FMatrix).wrapMatrix().withAttribute(LowerTriangular) } } - LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object : - LUDecompositionFeature<Float>, DeterminantFeature<Float>, InverseMatrixFeature<Float> { - private val lu by lazy { + LUP -> object : LupDecomposition<Float32> { + private val lup by lazy { DecompositionFactory_FSCC.lu(FillReducing.NONE).apply { decompose(origin.copy()) } } - override val l: Matrix<Float> by lazy { - lu.getLower(null).wrapMatrix().withFeature(LFeature) - } + override val l: Matrix<Float32> + get() = lup.getLower(null).wrapMatrix().withAttribute(LowerTriangular) - override val u: Matrix<Float> by lazy { - lu.getUpper(null).wrapMatrix().withFeature(UFeature) - } - override val inverse: Matrix<Float> by lazy { - var a = origin - val inverse = FMatrixRMaj(1, 1) - val solver = LinearSolverFactory_FSCC.lu(FillReducing.NONE) - if (solver.modifiesA()) a = a.copy() - val i = CommonOps_FDRM.identity(a.numRows) - solver.solve(i, inverse) - inverse.wrapMatrix() - } - - override val determinant: Float by lazy { elementAlgebra.number(lu.computeDeterminant().real) } + override val u: Matrix<Float32> + get() = lup.getUpper(null).wrapMatrix().withAttribute(UpperTriangular) + override val pivot: IntBuffer get() = lup.getRowPivotV(null).asBuffer() } else -> null - }?.let{ - type.cast(it) } + + @Suppress("UNCHECKED_CAST") + return raw as V? } /** diff --git a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt index 03b9b57b1..8b1b28e7d 100644 --- a/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt +++ b/kmath-ejml/src/test/kotlin/space/kscience/kmath/ejml/EjmlMatrixTest.kt @@ -58,19 +58,19 @@ internal class EjmlMatrixTest { @OptIn(UnstableKMathAPI::class) @Test - fun features() { + fun features() = EjmlLinearSpaceDDRM { val m = randomMatrix val w = EjmlDoubleMatrix(m) - val det: Determinant<Double> = EjmlLinearSpaceDDRM.attributeForOrNull(w) ?: fail() - assertEquals(CommonOps_DDRM.det(m), det.determinant) - val lup: LupDecompositionAttribute<Double> = EjmlLinearSpaceDDRM.attributeForOrNull(w) ?: fail() + val det: Double = w.getOrComputeAttribute(Determinant) ?: fail() + assertEquals(CommonOps_DDRM.det(m), det) + val lup: LupDecomposition<Double> = w.getOrComputeAttribute(LUP) ?: fail() val ludecompositionF64 = DecompositionFactory_DDRM.lu(m.numRows, m.numCols) .also { it.decompose(m.copy()) } assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getLower(null)), lup.l) assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getUpper(null)), lup.u) - assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getRowPivot(null)), lup.p) + assertMatrixEquals(EjmlDoubleMatrix(ludecompositionF64.getRowPivot(null)), lup.pivotMatrix(this)) } @Test diff --git a/kmath-for-real/build.gradle.kts b/kmath-for-real/build.gradle.kts index 99ce5903f..a0426b516 100644 --- a/kmath-for-real/build.gradle.kts +++ b/kmath-for-real/build.gradle.kts @@ -6,6 +6,7 @@ kscience { jvm() js() native() + wasm() dependencies { api(projects.kmathCore) diff --git a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt index 29aa2ec2e..d4051c8d9 100644 --- a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/DoubleVectorTest.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.real import space.kscience.kmath.linear.asMatrix import space.kscience.kmath.linear.linearSpace -import space.kscience.kmath.linear.transpose +import space.kscience.kmath.linear.transposed import space.kscience.kmath.operations.algebra import space.kscience.kmath.structures.Float64Buffer import kotlin.test.Test @@ -34,7 +34,7 @@ internal class DoubleVectorTest { val vector1 = Float64Buffer(5) { it.toDouble() } val vector2 = Float64Buffer(5) { 5 - it.toDouble() } val matrix1 = vector1.asMatrix() - val matrix2 = vector2.asMatrix().transpose() + val matrix2 = vector2.asMatrix().transposed() val product = matrix1 dot matrix2 assertEquals(5.0, product[1, 0]) assertEquals(6.0, product[2, 2]) diff --git a/kmath-functions/build.gradle.kts b/kmath-functions/build.gradle.kts index 3c1fbb07c..9296aaaf0 100644 --- a/kmath-functions/build.gradle.kts +++ b/kmath-functions/build.gradle.kts @@ -6,7 +6,6 @@ kscience{ jvm() js() native() - wasm() dependencies { diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index a4e659545..e2f5c77ba 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -92,7 +92,7 @@ public inline fun <reified T : Any> GaussIntegrator<T>.integrate( range: ClosedRange<Double>, order: Int = 10, intervals: Int = 10, - attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, + attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {}, noinline function: (Double) -> T, ): UnivariateIntegrand<T> { require(range.endInclusive > range.start) { "The range upper bound should be higher than lower bound" } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt index e77a2820b..2b58f0b05 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt @@ -23,7 +23,7 @@ import space.kscience.kmath.structures.MutableBufferFactory */ public class SplineInterpolator<T : Comparable<T>>( override val algebra: Field<T>, - public val bufferFactory: MutableBufferFactory<T>, + public val bufferFactory: MutableBufferFactory<T> = algebra.bufferFactory, ) : PolynomialInterpolator<T> { //TODO possibly optimize zeroed buffers diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt index 1f1e1a83f..d53a1ac2b 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt @@ -9,6 +9,7 @@ package space.kscience.kmath.functions.testUtils import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.ScaleOperations +import space.kscience.kmath.structures.MutableBufferFactory class IntModulo { @@ -109,15 +110,17 @@ class IntModulo { } @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") -class IntModuloRing : Ring<IntModulo>, ScaleOperations<IntModulo> { +class IntModuloRing(modulus: Int) : Ring<IntModulo>, ScaleOperations<IntModulo> { val modulus: Int - constructor(modulus: Int) { + init { require(modulus != 0) { "modulus can not be zero" } this.modulus = if (modulus < 0) -modulus else modulus } + override val bufferFactory: MutableBufferFactory<IntModulo> = MutableBufferFactory() + override inline val zero: IntModulo get() = IntModulo(0, modulus, toCheckInput = false) override inline val one: IntModulo get() = IntModulo(1, modulus, toCheckInput = false) diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt index 98150355c..c810cba2e 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt @@ -10,6 +10,7 @@ package space.kscience.kmath.functions.testUtils import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.Field import space.kscience.kmath.operations.NumbersAddOps +import space.kscience.kmath.structures.MutableBufferFactory @Suppress("NAME_SHADOWING") class Rational { @@ -159,6 +160,7 @@ class Rational { @Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE") @OptIn(UnstableKMathAPI::class) object RationalField : Field<Rational>, NumbersAddOps<Rational> { + override val bufferFactory: MutableBufferFactory<Rational> = MutableBufferFactory() override inline val zero: Rational get() = Rational.ZERO override inline val one: Rational get() = Rational.ONE diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt index 7e161f7c9..946f8811c 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/SplineIntegralTest.kt @@ -18,15 +18,15 @@ import kotlin.test.assertEquals class SplineIntegralTest { @Test - fun integratePolynomial(){ + fun integratePolynomial() { val polynomial = Polynomial(1.0, 2.0, 3.0) - val integral = polynomial.integrate(Float64Field,1.0..2.0) + val integral = polynomial.integrate(Float64Field, 1.0..2.0) assertEquals(11.0, integral, 0.001) } @Test fun gaussSin() { - val res = Float64Field.splineIntegrator.integrate(0.0..2 * PI, IntegrandMaxCalls(5)) { x -> + val res = Float64Field.splineIntegrator.integrate(0.0..2 * PI, { IntegrandMaxCalls(5) }) { x -> sin(x) } assertEquals(0.0, res.value, 1e-2) @@ -34,8 +34,8 @@ class SplineIntegralTest { @Test fun gaussUniform() { - val res = Float64Field.splineIntegrator.integrate(35.0..100.0, IntegrandMaxCalls(20)) { x -> - if(x in 30.0..50.0){ + val res = Float64Field.splineIntegrator.integrate(35.0..100.0, { IntegrandMaxCalls(20) }) { x -> + if (x in 30.0..50.0) { 1.0 } else { 0.0 diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt index c3ab61d89..a226ab04d 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt @@ -7,8 +7,8 @@ package space.kscience.kmath.geometry import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.kmath.geometry.euclidean2d.DoubleVector2D -import space.kscience.kmath.geometry.euclidean3d.DoubleVector3D +import space.kscience.kmath.geometry.euclidean2d.Float64Vector2D +import space.kscience.kmath.geometry.euclidean3d.Float64Vector3D /** * A line formed by [start] vector of start and a [direction] vector. Direction vector is not necessarily normalized, @@ -25,8 +25,8 @@ private data class LineImpl<out V : Any>(override val start: V, override val dir public fun <V : Any> Line(base: V, direction: V): Line<V> = LineImpl(base, direction) -public typealias Line2D = Line<DoubleVector2D> -public typealias Line3D = Line<DoubleVector3D> +public typealias Line2D = Line<Float64Vector2D> +public typealias Line3D = Line<Float64Vector3D> /** * A directed line segment between [begin] and [end] @@ -49,5 +49,5 @@ public fun <V : Any> LineSegment<V>.line(algebra: GeometrySpace<V, *>): Line<V> Line(begin, end - begin) } -public typealias LineSegment2D = LineSegment<DoubleVector2D> -public typealias LineSegment3D = LineSegment<DoubleVector3D> +public typealias LineSegment2D = LineSegment<Float64Vector2D> +public typealias LineSegment3D = LineSegment<Float64Vector3D> diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt index 71442cf63..64396baff 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.geometry +import space.kscience.attributes.SafeType import space.kscience.kmath.linear.Point import space.kscience.kmath.structures.Buffer @@ -33,6 +34,9 @@ public fun <T> Buffer<T>.asVector3D(): Vector3D<T> = object : Vector3D<T> { require(this@asVector3D.size == 3) { "Buffer of size 3 is required for Vector3D" } } + override val type: SafeType<T> = this@asVector3D.type + + override val x: T get() = this@asVector3D[0] override val y: T get() = this@asVector3D[1] override val z: T get() = this@asVector3D[2] diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt index 576a891fe..ff3efc126 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt @@ -11,6 +11,8 @@ import kotlinx.serialization.builtins.serializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import space.kscience.kmath.operations.Group +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.jvm.JvmInline import kotlin.math.PI import kotlin.math.floor @@ -28,11 +30,19 @@ public sealed interface Angle : Comparable<Angle> { public operator fun div(other: Angle): Double public operator fun unaryMinus(): Angle - public companion object { - public val zero: Radians = Radians(0.0) + public companion object: Group<Angle> { + override val zero: Radians = Radians(0.0) public val pi: Radians = Radians(PI) public val piTimes2: Radians = Radians(PI * 2) public val piDiv2: Radians = Radians(PI / 2) + + + override fun add(left: Angle, right: Angle): Angle = left + right + + @Suppress("EXTENSION_SHADOWED_BY_MEMBER") + override fun Angle.unaryMinus(): Angle = -this + + override val bufferFactory: MutableBufferFactory<Angle> = MutableBufferFactory() } } @@ -43,7 +53,7 @@ public object AngleSerializer : KSerializer<Angle> { override fun deserialize(decoder: Decoder): Angle = decoder.decodeDouble().degrees override fun serialize(encoder: Encoder, value: Angle) { - encoder.encodeDouble(value.degrees) + encoder.encodeDouble(value.toDegrees().value) } } @@ -56,16 +66,16 @@ public value class Radians(public val value: Double) : Angle { override fun toRadians(): Radians = this override fun toDegrees(): Degrees = Degrees(value * 180 / PI) - public override fun plus(other: Angle): Radians = Radians(value + other.radians) - public override fun minus(other: Angle): Radians = Radians(value - other.radians) + public override fun plus(other: Angle): Radians = Radians(value + other.toRadians().value) + public override fun minus(other: Angle): Radians = Radians(value - other.toRadians().value) public override fun times(other: Number): Radians = Radians(value * other.toDouble()) public override fun div(other: Number): Radians = Radians(value / other.toDouble()) - override fun div(other: Angle): Double = value / other.radians + override fun div(other: Angle): Double = value / other.toRadians().value public override fun unaryMinus(): Radians = Radians(-value) - override fun compareTo(other: Angle): Int = value.compareTo(other.radians) + override fun compareTo(other: Angle): Int = value.compareTo(other.toRadians().value) } public fun sin(angle: Angle): Double = kotlin.math.sin(angle.toRadians().value) @@ -85,16 +95,16 @@ public value class Degrees(public val value: Double) : Angle { override fun toRadians(): Radians = Radians(value * PI / 180) override fun toDegrees(): Degrees = this - public override fun plus(other: Angle): Degrees = Degrees(value + other.degrees) - public override fun minus(other: Angle): Degrees = Degrees(value - other.degrees) + public override fun plus(other: Angle): Degrees = Degrees(value + other.toDegrees().value) + public override fun minus(other: Angle): Degrees = Degrees(value - other.toDegrees().value) public override fun times(other: Number): Degrees = Degrees(value * other.toDouble()) public override fun div(other: Number): Degrees = Degrees(value / other.toDouble()) - override fun div(other: Angle): Double = value / other.degrees + override fun div(other: Angle): Double = value / other.toDegrees().value public override fun unaryMinus(): Degrees = Degrees(-value) - override fun compareTo(other: Angle): Int = value.compareTo(other.degrees) + override fun compareTo(other: Angle): Int = value.compareTo(other.toDegrees().value) } public val Number.degrees: Degrees get() = Degrees(toDouble()) @@ -106,6 +116,6 @@ public val Angle.degrees: Double get() = toDegrees().value * Normalized angle 2 PI range symmetric around [center]. By default, uses (0, 2PI) range. */ public fun Angle.normalized(center: Angle = Angle.pi): Angle = - this - Angle.piTimes2 * floor((radians + PI - center.radians) / PI / 2) + this - Angle.piTimes2 * floor((toRadians().value + PI - center.toRadians().value) / PI / 2) public fun abs(angle: Angle): Angle = if (angle < Angle.zero) -angle else angle \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt index d50e6c4b2..d687a3574 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt @@ -11,19 +11,22 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import space.kscience.attributes.SafeType import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector2D import space.kscience.kmath.operations.Float32Field import space.kscience.kmath.structures.Float32 +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.pow import kotlin.math.sqrt @Serializable(Float32Space2D.VectorSerializer::class) -public interface Float32Vector2D : Vector2D<Float> +public interface Float32Vector2D : Vector2D<Float32>{ + override val type: SafeType<Float32> get() = Float32Field.type +} public object Float32Space2D : GeometrySpace<Float32Vector2D, Float32> { - @Serializable @SerialName("Float32Vector2D") private data class Vector2DImpl( @@ -72,6 +75,8 @@ public object Float32Space2D : GeometrySpace<Float32Vector2D, Float32> { public val yAxis: Float32Vector2D = vector(0.0, 1.0) override val defaultPrecision: Float32 = 1e-3f + + override val bufferFactory: MutableBufferFactory<Float32Vector2D> = MutableBufferFactory() } public fun Float32Vector2D(x: Number, y: Number): Float32Vector2D = Float32Space2D.vector(x, y) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt index 0a43a46ea..05b9401d7 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt @@ -11,66 +11,77 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import space.kscience.attributes.SafeType import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector2D -import space.kscience.kmath.linear.Float64LinearSpace import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.ScaleOperations +import space.kscience.kmath.structures.Float64 +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.pow import kotlin.math.sqrt -public typealias DoubleVector2D = Vector2D<Double> -public typealias Float64Vector2D = Vector2D<Double> +@Serializable(Float64Space2D.VectorSerializer::class) +public interface Float64Vector2D : Vector2D<Float64> { + override val type: SafeType<Float64> get() = Float64Field.type +} + +@Deprecated("Use Float64Vector2D", ReplaceWith("Float64Vector2D")) +public typealias DoubleVector2D = Float64Vector2D -public val Vector2D<Double>.r: Double get() = Float64Space2D.norm(this) /** * 2D Euclidean space */ -public object Float64Space2D : GeometrySpace<DoubleVector2D>, ScaleOperations<DoubleVector2D> { +public object Float64Space2D : GeometrySpace<Float64Vector2D, Float64>, ScaleOperations<Float64Vector2D> { + @Serializable @SerialName("Float64Vector2D") private data class Vector2DImpl( override val x: Double, override val y: Double, - ) : DoubleVector2D + ) : Float64Vector2D - public object VectorSerializer : KSerializer<DoubleVector2D> { + public object VectorSerializer : KSerializer<Float64Vector2D> { private val proxySerializer = Vector2DImpl.serializer() override val descriptor: SerialDescriptor get() = proxySerializer.descriptor - override fun deserialize(decoder: Decoder): DoubleVector2D = decoder.decodeSerializableValue(proxySerializer) + override fun deserialize(decoder: Decoder): Float64Vector2D = decoder.decodeSerializableValue(proxySerializer) - override fun serialize(encoder: Encoder, value: DoubleVector2D) { + override fun serialize(encoder: Encoder, value: Float64Vector2D) { val vector = value as? Vector2DImpl ?: Vector2DImpl(value.x, value.y) encoder.encodeSerializableValue(proxySerializer, vector) } } - public fun vector(x: Number, y: Number): DoubleVector2D = Vector2DImpl(x.toDouble(), y.toDouble()) + public fun vector(x: Number, y: Number): Float64Vector2D = Vector2DImpl(x.toDouble(), y.toDouble()) - override val zero: DoubleVector2D by lazy { vector(0.0, 0.0) } + override val zero: Float64Vector2D by lazy { vector(0.0, 0.0) } - override fun norm(arg: DoubleVector2D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2)) + override fun norm(arg: Float64Vector2D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2)) - override fun DoubleVector2D.unaryMinus(): DoubleVector2D = vector(-x, -y) + override fun Float64Vector2D.unaryMinus(): Float64Vector2D = vector(-x, -y) - override fun DoubleVector2D.distanceTo(other: DoubleVector2D): Double = norm(this - other) - override fun add(left: DoubleVector2D, right: DoubleVector2D): DoubleVector2D = + override fun Float64Vector2D.distanceTo(other: Float64Vector2D): Double = norm(this - other) + override fun add(left: Float64Vector2D, right: Float64Vector2D): Float64Vector2D = vector(left.x + right.x, left.y + right.y) - override fun scale(a: DoubleVector2D, value: Double): DoubleVector2D = vector(a.x * value, a.y * value) - override fun DoubleVector2D.dot(other: DoubleVector2D): Double = x * other.x + y * other.y + override fun scale(a: Float64Vector2D, value: Double): Float64Vector2D = vector(a.x * value, a.y * value) + override fun Float64Vector2D.dot(other: Float64Vector2D): Double = x * other.x + y * other.y - public val xAxis: DoubleVector2D = vector(1.0, 0.0) - public val yAxis: DoubleVector2D = vector(0.0, 1.0) + public val xAxis: Float64Vector2D = vector(1.0, 0.0) + public val yAxis: Float64Vector2D = vector(0.0, 1.0) override val defaultPrecision: Double = 1e-6 + + override val bufferFactory: MutableBufferFactory<Float64Vector2D> = MutableBufferFactory() } public fun Float64Vector2D(x: Number, y: Number): Float64Vector2D = Float64Space2D.vector(x, y) +public val Float64Vector2D.r: Float64 get() = Float64Space2D.norm(this) + public val Float64Field.euclidean2D: Float64Space2D get() = Float64Space2D \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt index ee4b965cd..7204ac4f9 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt @@ -11,15 +11,19 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import space.kscience.attributes.SafeType import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector3D import space.kscience.kmath.operations.Float32Field import space.kscience.kmath.structures.Float32 +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.pow import kotlin.math.sqrt @Serializable(Float32Space3D.VectorSerializer::class) -public interface Float32Vector3D : Vector3D<Float> +public interface Float32Vector3D : Vector3D<Float>{ + override val type: SafeType<Float32> get() = Float32Field.type +} public object Float32Space3D : GeometrySpace<Float32Vector3D, Float32> { @@ -101,6 +105,8 @@ public object Float32Space3D : GeometrySpace<Float32Vector3D, Float32> { public val zAxis: Float32Vector3D = vector(0.0, 0.0, 1.0) override val defaultPrecision: Float32 = 1e-3f + + override val bufferFactory: MutableBufferFactory<Float32Vector3D> = MutableBufferFactory() } public fun Float32Vector3D(x: Number, y: Number, z: Number): Float32Vector3D = Float32Space3D.vector(x, y, z) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt index d0b1ac581..a2c23926a 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt @@ -11,10 +11,13 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import space.kscience.attributes.SafeType import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector3D import space.kscience.kmath.linear.Float64LinearSpace import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.structures.Float64 +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.pow import kotlin.math.sqrt @@ -31,12 +34,16 @@ internal fun leviCivita(i: Int, j: Int, k: Int): Int = when { else -> 0 } -public typealias DoubleVector3D = Vector3D<Double> -public typealias Float64Vector3D = Vector3D<Double> +@Serializable(Float64Space3D.VectorSerializer::class) +public interface Float64Vector3D : Vector3D<Float64> { + override val type: SafeType<Float64> get() = Float64Field.type +} -public val DoubleVector3D.r: Double get() = Float64Space3D.norm(this) +@Deprecated("Use Float64Vector3D", ReplaceWith("Float64Vector3D")) +public typealias DoubleVector3D = Float64Vector3D -public object Float64Space3D : GeometrySpace<DoubleVector3D, Double>{ + +public object Float64Space3D : GeometrySpace<Vector3D<Float64>, Double> { public val linearSpace: Float64LinearSpace = Float64LinearSpace @@ -46,52 +53,52 @@ public object Float64Space3D : GeometrySpace<DoubleVector3D, Double>{ override val x: Double, override val y: Double, override val z: Double, - ) : DoubleVector3D + ) : Float64Vector3D - public object VectorSerializer : KSerializer<DoubleVector3D> { + public object VectorSerializer : KSerializer<Float64Vector3D> { private val proxySerializer = Vector3DImpl.serializer() override val descriptor: SerialDescriptor get() = proxySerializer.descriptor - override fun deserialize(decoder: Decoder): DoubleVector3D = decoder.decodeSerializableValue(proxySerializer) + override fun deserialize(decoder: Decoder): Float64Vector3D = decoder.decodeSerializableValue(proxySerializer) - override fun serialize(encoder: Encoder, value: DoubleVector3D) { + override fun serialize(encoder: Encoder, value: Float64Vector3D) { val vector = value as? Vector3DImpl ?: Vector3DImpl(value.x, value.y, value.z) encoder.encodeSerializableValue(proxySerializer, vector) } } - public fun vector(x: Double, y: Double, z: Double): DoubleVector3D = + public fun vector(x: Double, y: Double, z: Double): Float64Vector3D = Vector3DImpl(x, y, z) - public fun vector(x: Number, y: Number, z: Number): DoubleVector3D = + public fun vector(x: Number, y: Number, z: Number): Float64Vector3D = vector(x.toDouble(), y.toDouble(), z.toDouble()) - override val zero: DoubleVector3D by lazy { vector(0.0, 0.0, 0.0) } + override val zero: Float64Vector3D by lazy { vector(0.0, 0.0, 0.0) } - override fun norm(arg: DoubleVector3D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)) + override fun norm(arg: Vector3D<Float64>): Double = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)) - public fun DoubleVector3D.norm(): Double = norm(this) + public fun Vector3D<Float64>.norm(): Double = norm(this) - override fun DoubleVector3D.unaryMinus(): DoubleVector3D = vector(-x, -y, -z) + override fun Vector3D<Float64>.unaryMinus(): Float64Vector3D = vector(-x, -y, -z) - override fun DoubleVector3D.distanceTo(other: DoubleVector3D): Double = (this - other).norm() + override fun Vector3D<Float64>.distanceTo(other: Vector3D<Float64>): Double = (this - other).norm() - override fun add(left: DoubleVector3D, right: DoubleVector3D): DoubleVector3D = + override fun add(left: Vector3D<Float64>, right: Vector3D<Float64>): Float64Vector3D = vector(left.x + right.x, left.y + right.y, left.z + right.z) - override fun scale(a: DoubleVector3D, value: Double): DoubleVector3D = + override fun scale(a: Vector3D<Float64>, value: Double): Float64Vector3D = vector(a.x * value, a.y * value, a.z * value) - override fun DoubleVector3D.dot(other: DoubleVector3D): Double = + override fun Vector3D<Float64>.dot(other: Vector3D<Float64>): Double = x * other.x + y * other.y + z * other.z /** * Compute vector product of [first] and [second]. The basis is assumed to be right-handed. */ public fun vectorProduct( - first: DoubleVector3D, - second: DoubleVector3D, - ): DoubleVector3D { + first: Vector3D<Float64>, + second: Vector3D<Float64>, + ): Float64Vector3D { var x = 0.0 var y = 0.0 var z = 0.0 @@ -110,13 +117,18 @@ public object Float64Space3D : GeometrySpace<DoubleVector3D, Double>{ /** * Vector product with the right basis */ - public infix fun DoubleVector3D.cross(other: DoubleVector3D): Vector3D<Double> = vectorProduct(this, other) + public infix fun Vector3D<Float64>.cross(other: Vector3D<Float64>): Vector3D<Double> = vectorProduct(this, other) - public val xAxis: DoubleVector3D = vector(1.0, 0.0, 0.0) - public val yAxis: DoubleVector3D = vector(0.0, 1.0, 0.0) - public val zAxis: DoubleVector3D = vector(0.0, 0.0, 1.0) + public val xAxis: Float64Vector3D = vector(1.0, 0.0, 0.0) + public val yAxis: Float64Vector3D = vector(0.0, 1.0, 0.0) + public val zAxis: Float64Vector3D = vector(0.0, 0.0, 1.0) override val defaultPrecision: Double = 1e-6 + + override val bufferFactory: MutableBufferFactory<Vector3D<Float64>> = MutableBufferFactory() } public val Float64Field.euclidean3D: Float64Space3D get() = Float64Space3D + + +public val Float64Vector3D.r: Double get() = Float64Space3D.norm(this) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt index abb531944..212cc251e 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt @@ -5,6 +5,7 @@ package space.kscience.kmath.geometry.euclidean3d +import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.complex.* import space.kscience.kmath.geometry.* @@ -13,6 +14,7 @@ import space.kscience.kmath.linear.Matrix import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.matrix import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.structures.Float64 import kotlin.math.* public operator fun Quaternion.times(other: Quaternion): Quaternion = QuaternionAlgebra.multiply(this, other) @@ -35,7 +37,7 @@ public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * o /** * Represent a vector as quaternion with zero a rotation angle. */ -internal fun DoubleVector3D.asQuaternion(): Quaternion = Quaternion(0.0, x, y, z) +internal fun Float64Vector3D.asQuaternion(): Quaternion = Quaternion(0.0, x, y, z) /** * Angle in radians denoted by this quaternion rotation @@ -45,7 +47,7 @@ public val Quaternion.theta: Radians get() = (kotlin.math.acos(normalized().w) * /** * Create a normalized Quaternion from rotation angle and rotation vector */ -public fun Quaternion.Companion.fromRotation(theta: Angle, vector: DoubleVector3D): Quaternion { +public fun Quaternion.Companion.fromRotation(theta: Angle, vector: Float64Vector3D): Quaternion { val s = sin(theta / 2) val c = cos(theta / 2) val norm = with(Float64Space3D) { vector.norm() } @@ -55,9 +57,9 @@ public fun Quaternion.Companion.fromRotation(theta: Angle, vector: DoubleVector3 /** * An axis of quaternion rotation */ -public val Quaternion.vector: DoubleVector3D +public val Quaternion.vector: Float64Vector3D get() { - return object : DoubleVector3D { + return object : Float64Vector3D { private val sint2 = sqrt(1 - w * w) override val x: Double get() = this@vector.x / sint2 override val y: Double get() = this@vector.y / sint2 @@ -69,7 +71,7 @@ public val Quaternion.vector: DoubleVector3D /** * Rotate a vector in a [Float64Space3D] with [quaternion] */ -public fun Float64Space3D.rotate(vector: DoubleVector3D, quaternion: Quaternion): DoubleVector3D = +public fun Float64Space3D.rotate(vector: Float64Vector3D, quaternion: Quaternion): Float64Vector3D = with(QuaternionAlgebra) { val p = vector.asQuaternion() (quaternion * p * quaternion.reciprocal).vector @@ -80,15 +82,15 @@ public fun Float64Space3D.rotate(vector: DoubleVector3D, quaternion: Quaternion) */ @UnstableKMathAPI public fun Float64Space3D.rotate( - vector: DoubleVector3D, + vector: Float64Vector3D, composition: QuaternionAlgebra.() -> Quaternion, -): DoubleVector3D = +): Float64Vector3D = rotate(vector, QuaternionAlgebra.composition()) /** * Rotate a [Float64] vector in 3D space with a rotation matrix */ -public fun Float64Space3D.rotate(vector: DoubleVector3D, matrix: Matrix<Double>): DoubleVector3D { +public fun Float64Space3D.rotate(vector: Float64Vector3D, matrix: Matrix<Double>): Vector3D<Float64> { require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" } return with(linearSpace) { (matrix dot vector).asVector3D() } } @@ -242,6 +244,8 @@ public fun Quaternion.Companion.fromEuler( * A vector consisting of angles */ public data class AngleVector(override val x: Angle, override val y: Angle, override val z: Angle) : Vector3D<Angle> { + override val type: SafeType<Angle> get() = Angle.type + public companion object } diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt index 613a88b2f..3f9c86add 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -5,8 +5,7 @@ package space.kscience.kmath.geometry -import space.kscience.kmath.geometry.euclidean2d.DoubleVector2D -import space.kscience.kmath.geometry.euclidean3d.DoubleVector3D +import space.kscience.kmath.structures.Float64 import kotlin.math.abs import kotlin.test.assertEquals @@ -27,12 +26,12 @@ fun grid( return xs.flatMap { x -> ys.map { y -> x to y } } } -fun assertVectorEquals(expected: DoubleVector2D, actual: DoubleVector2D, absoluteTolerance: Double = 1e-3) { +fun assertVectorEquals(expected: Vector2D<Float64>, actual: Vector2D<Float64>, absoluteTolerance: Double = 1e-3) { assertEquals(expected.x, actual.x, absoluteTolerance) assertEquals(expected.y, actual.y, absoluteTolerance) } -fun assertVectorEquals(expected: DoubleVector3D, actual: DoubleVector3D, absoluteTolerance: Double = 1e-6) { +fun assertVectorEquals(expected: Vector3D<Float64>, actual: Vector3D<Float64>, absoluteTolerance: Double = 1e-6) { assertEquals(expected.x, actual.x, absoluteTolerance) assertEquals(expected.y, actual.y, absoluteTolerance) assertEquals(expected.z, actual.z, absoluteTolerance) diff --git a/kmath-histograms/build.gradle.kts b/kmath-histograms/build.gradle.kts index 33704c29e..63791d61c 100644 --- a/kmath-histograms/build.gradle.kts +++ b/kmath-histograms/build.gradle.kts @@ -6,6 +6,8 @@ kscience{ jvm() js() native() + wasm() + useCoroutines() } //apply(plugin = "kotlinx-atomicfu") @@ -21,7 +23,6 @@ kotlin.sourceSets { dependencies { implementation(project(":kmath-for-real")) implementation(projects.kmath.kmathStat) - implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.0") } } } diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt index 79f145792..7f6fb2d26 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Histogram.kt @@ -47,7 +47,7 @@ public interface Histogram<in T : Any, out V, out B : Bin<T, V>> { } } -public interface HistogramBuilder<in T : Any, V : Any> { +public interface HistogramBuilder<in T, V> { /** * The default value increment for a bin @@ -61,9 +61,9 @@ public interface HistogramBuilder<in T : Any, V : Any> { } -public fun <T : Any> HistogramBuilder<T, *>.put(point: Point<out T>): Unit = putValue(point) +public fun <T> HistogramBuilder<T, *>.put(point: Point<T>): Unit = putValue(point) -public fun <T : Any> HistogramBuilder<T, *>.put(vararg point: T): Unit = put(point.asBuffer()) +public inline fun <reified T> HistogramBuilder<T, *>.put(vararg point: T): Unit = put(point.asList().asBuffer()) public fun HistogramBuilder<Double, *>.put(vararg point: Number): Unit = put(Float64Buffer(point.map { it.toDouble() }.toDoubleArray())) diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogram1D.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogram1D.kt index 0326e8757..770fd70a0 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogram1D.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogram1D.kt @@ -12,6 +12,7 @@ import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.ScaleOperations import space.kscience.kmath.operations.invoke import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.floor @OptIn(UnstableKMathAPI::class) @@ -46,6 +47,8 @@ public class UniformHistogram1DGroup<V : Any, A>( public val startPoint: Double = 0.0, ) : Group<Histogram1D<Double, V>>, ScaleOperations<Histogram1D<Double, V>> where A : Ring<V>, A : ScaleOperations<V> { + override val bufferFactory: MutableBufferFactory<Histogram1D<Double, V>> = MutableBufferFactory() + override val zero: UniformHistogram1D<V> = UniformHistogram1D(this, emptyMap()) /** diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt index 839744f89..8a914530b 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/UniformHistogramGroupND.kt @@ -37,6 +37,8 @@ public class UniformHistogramGroupND<V : Any, A : Field<V>>( require(!lower.indices.any { upper[it] - lower[it] < 0 }) { "Range for one of axis is not strictly positive" } } + override val bufferFactory: MutableBufferFactory<HistogramND<Double, HyperSquareDomain, V>> = MutableBufferFactory() + public val dimension: Int get() = lower.size override val shape: ShapeND = ShapeND(IntArray(binNums.size) { binNums[it] + 2 }) @@ -87,7 +89,7 @@ public class UniformHistogramGroupND<V : Any, A : Field<V>>( builder: HistogramBuilder<Double, V>.() -> Unit, ): HistogramND<Double, HyperSquareDomain, V> { val ndCounter: BufferND<ObjectCounter<V>> = - StructureND.buffered(shape) { Counter.of(valueAlgebraND.elementAlgebra) } + BufferND(shape) { Counter.of(valueAlgebraND.elementAlgebra) } val hBuilder = object : HistogramBuilder<Double, V> { override val defaultValue: V get() = valueAlgebraND.elementAlgebra.one @@ -97,7 +99,8 @@ public class UniformHistogramGroupND<V : Any, A : Field<V>>( } } hBuilder.apply(builder) - val values: BufferND<V> = BufferND(ndCounter.indices, ndCounter.buffer.mapToBuffer(valueBufferFactory) { it.value }) + val values: BufferND<V> = + BufferND(ndCounter.indices, ndCounter.buffer.mapToBuffer(valueBufferFactory) { it.value }) return HistogramND(this, values) } @@ -128,8 +131,7 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges( public fun Histogram.Companion.uniformDoubleNDFromRanges( vararg ranges: ClosedFloatingPointRange<Double>, -): UniformHistogramGroupND<Double, Float64Field> = - uniformNDFromRanges(Floa64FieldOpsND, *ranges, bufferFactory = ::Float64Buffer) +): UniformHistogramGroupND<Double, Float64Field> = uniformNDFromRanges(Floa64FieldOpsND, *ranges) /** @@ -147,21 +149,18 @@ public fun <V : Any, A : Field<V>> Histogram.Companion.uniformNDFromRanges( bufferFactory: BufferFactory<V> = valueAlgebraND.elementAlgebra.bufferFactory, ): UniformHistogramGroupND<V, A> = UniformHistogramGroupND( valueAlgebraND, - DoubleBuffer( - ranges - .map(Pair<ClosedFloatingPointRange<Double>, Int>::first) - .map(ClosedFloatingPointRange<Double>::start) - ), - DoubleBuffer( - ranges - .map(Pair<ClosedFloatingPointRange<Double>, Int>::first) - .map(ClosedFloatingPointRange<Double>::endInclusive) - ), + ranges + .map(Pair<ClosedFloatingPointRange<Double>, Int>::first) + .map(ClosedFloatingPointRange<Double>::start) + .asBuffer(), + ranges + .map(Pair<ClosedFloatingPointRange<Double>, Int>::first) + .map(ClosedFloatingPointRange<Double>::endInclusive) + .asBuffer(), ranges.map(Pair<ClosedFloatingPointRange<Double>, Int>::second).toIntArray(), valueBufferFactory = bufferFactory ) public fun Histogram.Companion.uniformDoubleNDFromRanges( vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>, -): UniformHistogramGroupND<Double, Float64Field> = - uniformNDFromRanges(Floa64FieldOpsND, *ranges, bufferFactory = ::Float64Buffer) \ No newline at end of file +): UniformHistogramGroupND<Double, Float64Field> = uniformNDFromRanges(Floa64FieldOpsND, *ranges) \ No newline at end of file diff --git a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramGroup.kt b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramGroup.kt index 95658141a..c8be4f846 100644 --- a/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramGroup.kt +++ b/kmath-histograms/src/jvmMain/kotlin/space/kscience/kmath/histogram/TreeHistogramGroup.kt @@ -14,10 +14,7 @@ import space.kscience.kmath.misc.sorted import space.kscience.kmath.operations.Group import space.kscience.kmath.operations.Ring import space.kscience.kmath.operations.ScaleOperations -import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.first -import space.kscience.kmath.structures.indices -import space.kscience.kmath.structures.last +import space.kscience.kmath.structures.* import java.util.* private fun <B : ClosedRange<Double>> TreeMap<Double, B>.getBin(value: Double): B? { @@ -53,6 +50,8 @@ public class TreeHistogramGroup<V : Any, A>( @PublishedApi internal val binFactory: (Double) -> DoubleDomain1D, ) : Group<TreeHistogram<V>>, ScaleOperations<TreeHistogram<V>> where A : Ring<V>, A : ScaleOperations<V> { + override val bufferFactory: MutableBufferFactory<TreeHistogram<V>> = MutableBufferFactory() + internal inner class DomainCounter(val domain: DoubleDomain1D, val counter: Counter<V> = Counter.of(valueAlgebra)) : ClosedRange<Double> by domain.range diff --git a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt index 53e0beca1..07b77683d 100644 --- a/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt +++ b/kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt @@ -7,6 +7,7 @@ package space.kscience.kmath.kotlingrad import ai.hypergraph.kotlingrad.api.SFun import ai.hypergraph.kotlingrad.api.SVar +import space.kscience.attributes.SafeType import space.kscience.kmath.expressions.* import space.kscience.kmath.operations.NumericAlgebra @@ -25,6 +26,8 @@ public class KotlingradExpression<T : Number, A : NumericAlgebra<T>>( public val algebra: A, public val mst: MST, ) : SpecialDifferentiableExpression<T, KotlingradExpression<T, A>> { + override val type: SafeType<T> = algebra.type + override fun invoke(arguments: Map<Symbol, T>): T = mst.interpret(algebra, arguments) override fun derivativeOrNull( diff --git a/kmath-nd4j/build.gradle.kts b/kmath-nd4j/build.gradle.kts index e5c4af891..bfa09e771 100644 --- a/kmath-nd4j/build.gradle.kts +++ b/kmath-nd4j/build.gradle.kts @@ -12,7 +12,7 @@ dependencies { } readme { - maturity = space.kscience.gradle.Maturity.EXPERIMENTAL + maturity = space.kscience.gradle.Maturity.DEPRECATED propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) feature(id = "nd4jarraystructure") { "NDStructure wrapper for INDArray" } feature(id = "nd4jarrayrings") { "Rings over Nd4jArrayStructure of Int and Long" } diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt index 34bbcaefb..9bfc2f8f5 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt @@ -6,8 +6,10 @@ package space.kscience.kmath.nd4j import org.nd4j.linalg.api.ndarray.INDArray +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* +import space.kscience.kmath.operations.Float32Field /** * Represents a [StructureND] wrapping an [INDArray] object. @@ -31,6 +33,7 @@ public sealed class Nd4jArrayStructure<T> : MutableStructureND<T> { } public data class Nd4jArrayIntStructure(override val ndArray: INDArray) : Nd4jArrayStructure<Int>(), StructureNDOfInt { + override fun elementsIterator(): Iterator<Pair<IntArray, Int>> = ndArray.intIterator() @OptIn(PerformancePitfall::class) @@ -47,8 +50,10 @@ public data class Nd4jArrayIntStructure(override val ndArray: INDArray) : Nd4jAr */ public fun INDArray.asIntStructure(): Nd4jArrayIntStructure = Nd4jArrayIntStructure(this) -public data class Nd4jArrayDoubleStructure(override val ndArray: INDArray) : Nd4jArrayStructure<Double>(), StructureNDOfDouble { +public data class Nd4jArrayDoubleStructure(override val ndArray: INDArray) : Nd4jArrayStructure<Double>(), + StructureNDOfDouble { override fun elementsIterator(): Iterator<Pair<IntArray, Double>> = ndArray.realIterator() + @OptIn(PerformancePitfall::class) override fun get(index: IntArray): Double = ndArray.getDouble(*index) @@ -64,7 +69,11 @@ public data class Nd4jArrayDoubleStructure(override val ndArray: INDArray) : Nd4 public fun INDArray.asDoubleStructure(): Nd4jArrayStructure<Double> = Nd4jArrayDoubleStructure(this) public data class Nd4jArrayFloatStructure(override val ndArray: INDArray) : Nd4jArrayStructure<Float>() { + + override val type: SafeType<Float> get() = Float32Field.type + override fun elementsIterator(): Iterator<Pair<IntArray, Float>> = ndArray.floatIterator() + @PerformancePitfall override fun get(index: IntArray): Float = ndArray.getFloat(*index) diff --git a/kmath-optimization/build.gradle.kts b/kmath-optimization/build.gradle.kts index 7250d1f72..f908b127d 100644 --- a/kmath-optimization/build.gradle.kts +++ b/kmath-optimization/build.gradle.kts @@ -6,6 +6,7 @@ kscience{ jvm() js() native() + wasm() } kotlin.sourceSets { diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt index d8b3f29eb..a38e9e6e8 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -11,6 +11,10 @@ import space.kscience.kmath.expressions.Symbol public class OptimizationValue<V>(type: SafeType<V>) : PolymorphicAttribute<V>(type) +public inline fun <reified T> AttributesBuilder<FunctionOptimization<T>>.value(value: T) { + set(OptimizationValue(safeTypeOf<T>()), value) +} + public enum class OptimizationDirection { MAXIMIZE, MINIMIZE diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt index 49678cd57..18f552bda 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt @@ -34,10 +34,18 @@ public fun <T> AttributesBuilder<OptimizationProblem<T>>.startAt(startingPoint: public class OptimizationCovariance<T> : OptimizationAttribute<NamedMatrix<T>>, PolymorphicAttribute<NamedMatrix<T>>(safeTypeOf()) +public fun <T> AttributesBuilder<OptimizationProblem<T>>.covariance(covariance: NamedMatrix<T>) { + set(OptimizationCovariance(),covariance) +} + public class OptimizationResult<T>() : OptimizationAttribute<Map<Symbol, T>>, PolymorphicAttribute<Map<Symbol, T>>(safeTypeOf()) +public fun <T> AttributesBuilder<OptimizationProblem<T>>.result(result: Map<Symbol, T>) { + set(OptimizationResult(), result) +} + public val <T> OptimizationProblem<T>.resultOrNull: Map<Symbol, T>? get() = attributes[OptimizationResult()] public val <T> OptimizationProblem<T>.result: Map<Symbol, T> diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt index 46394132b..eba637a83 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt @@ -264,10 +264,10 @@ public object QowOptimizer : Optimizer<Double, XYFit> { qow = QoWeight(problem, res.freeParameters) res = qow.newtonianRun(maxSteps = iterations) } - val covariance = res.covariance() + return res.problem.withAttributes { - set(OptimizationResult(), res.freeParameters) - set(OptimizationCovariance(), covariance) + result(res.freeParameters) + covariance(res.covariance()) } } } \ No newline at end of file diff --git a/kmath-stat/build.gradle.kts b/kmath-stat/build.gradle.kts index 000280def..7d396b460 100644 --- a/kmath-stat/build.gradle.kts +++ b/kmath-stat/build.gradle.kts @@ -6,6 +6,7 @@ kscience{ jvm() js() native() + wasm() } kotlin.sourceSets { diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt index 545e89814..a95829eff 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt @@ -68,7 +68,7 @@ internal class MCScopeTest { } - @OptIn(DelicateCoroutinesApi::class) + @OptIn(DelicateCoroutinesApi::class, ExperimentalCoroutinesApi::class) fun compareResult(test: ATest) { val res1 = runBlocking(Dispatchers.Default) { test() } val res2 = runBlocking(newSingleThreadContext("test")) { test() } diff --git a/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/SymjaExpression.kt b/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/SymjaExpression.kt index e5ba411e6..b23da37f5 100644 --- a/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/SymjaExpression.kt +++ b/kmath-symja/src/main/kotlin/space/kscience/kmath/symja/SymjaExpression.kt @@ -7,8 +7,9 @@ package space.kscience.kmath.symja import org.matheclipse.core.eval.ExprEvaluator import org.matheclipse.core.expression.F -import space.kscience.kmath.expressions.SpecialDifferentiableExpression +import space.kscience.attributes.SafeType import space.kscience.kmath.expressions.MST +import space.kscience.kmath.expressions.SpecialDifferentiableExpression import space.kscience.kmath.expressions.Symbol import space.kscience.kmath.expressions.interpret import space.kscience.kmath.operations.NumericAlgebra @@ -30,6 +31,8 @@ public class SymjaExpression<T : Number, A : NumericAlgebra<T>>( public val mst: MST, public val evaluator: ExprEvaluator = DEFAULT_EVALUATOR, ) : SpecialDifferentiableExpression<T, SymjaExpression<T, A>> { + override val type: SafeType<T> get() = algebra.type + override fun invoke(arguments: Map<Symbol, T>): T = mst.interpret(algebra, arguments) override fun derivativeOrNull(symbols: List<Symbol>): SymjaExpression<T, A> = SymjaExpression( diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt index 4c06404b1..9a559bc28 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt @@ -10,6 +10,7 @@ import org.tensorflow.Output import org.tensorflow.ndarray.NdArray import org.tensorflow.op.core.Constant import org.tensorflow.types.TFloat64 +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol @@ -25,9 +26,9 @@ public class DoubleTensorFlowOutput( graph: Graph, output: Output<TFloat64>, ) : TensorFlowOutput<Double, TFloat64>(graph, output) { + override val type: SafeType<Double> get() = Float64Field.type override fun org.tensorflow.Tensor.actualizeTensor(): NdArray<Double> = this as TFloat64 - } internal fun ShapeND.toLongArray(): LongArray = LongArray(size) { get(it).toLong() } diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt index 186a794e9..3695a2640 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt @@ -10,11 +10,19 @@ import org.tensorflow.Output import org.tensorflow.ndarray.NdArray import org.tensorflow.types.TInt32 import org.tensorflow.types.TInt64 +import space.kscience.attributes.SafeType +import space.kscience.kmath.operations.Int32Ring +import space.kscience.kmath.operations.Int64Ring +import space.kscience.kmath.structures.Int32 +import space.kscience.kmath.structures.Int64 public class IntTensorFlowOutput( graph: Graph, output: Output<TInt32>, ) : TensorFlowOutput<Int, TInt32>(graph, output) { + + override val type: SafeType<Int32> get() = Int32Ring.type + override fun org.tensorflow.Tensor.actualizeTensor(): NdArray<Int> = this as TInt32 } @@ -22,5 +30,7 @@ public class LongTensorFlowOutput( graph: Graph, output: Output<TInt64>, ) : TensorFlowOutput<Long, TInt64>(graph, output) { + + override val type: SafeType<Int64> get() = Int64Ring.type override fun org.tensorflow.Tensor.actualizeTensor(): NdArray<Long> = this as TInt64 } \ No newline at end of file diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt index 158c928c4..7e413c29c 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt @@ -17,6 +17,7 @@ import org.tensorflow.op.core.* import org.tensorflow.types.TInt32 import org.tensorflow.types.family.TNumber import org.tensorflow.types.family.TType +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnsafeKMathAPI import space.kscience.kmath.UnstableKMathAPI @@ -39,8 +40,8 @@ public sealed interface TensorFlowTensor<T> : Tensor<T> /** * Static (eager) in-memory TensorFlow tensor */ -@JvmInline -public value class TensorFlowArray<T>(public val tensor: NdArray<T>) : Tensor<T> { +public class TensorFlowArray<T>(override val type: SafeType<T>, public val tensor: NdArray<T>) : Tensor<T> { + override val shape: ShapeND get() = ShapeND(tensor.shape().asArray().toIntArray()) @PerformancePitfall @@ -73,7 +74,7 @@ public abstract class TensorFlowOutput<T, TT : TType>( internal val actualTensor by lazy { Session(graph).use { session -> - TensorFlowArray(session.runner().fetch(output).run().first().actualizeTensor()) + TensorFlowArray(type, session.runner().fetch(output).run().first().actualizeTensor()) } } diff --git a/kmath-tensors/build.gradle.kts b/kmath-tensors/build.gradle.kts index 8977183da..82213f408 100644 --- a/kmath-tensors/build.gradle.kts +++ b/kmath-tensors/build.gradle.kts @@ -12,6 +12,7 @@ kscience{ } } native() + wasm() dependencies { api(projects.kmathCore) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/Tensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/Tensor.kt deleted file mode 100644 index 2a7f463bc..000000000 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/Tensor.kt +++ /dev/null @@ -1,10 +0,0 @@ -/* - * Copyright 2018-2024 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.tensors.api - -import space.kscience.kmath.nd.MutableStructureND - -public typealias Tensor<T> = MutableStructureND<T> diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt index 6e515f3f8..c960090d2 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt @@ -5,11 +5,14 @@ package space.kscience.kmath.tensors.api +import space.kscience.kmath.nd.MutableStructureND import space.kscience.kmath.nd.RingOpsND import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.StructureND import space.kscience.kmath.operations.Ring +public typealias Tensor<T> = MutableStructureND<T> + /** * Algebra over a ring on [Tensor]. * For more information: https://proofwiki.org/wiki/Definition:Algebra_over_Ring diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt index a47c9364a..b2106200e 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/LevenbergMarquardtAlgorithm.kt @@ -6,7 +6,6 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall -import space.kscience.kmath.linear.transposed import space.kscience.kmath.nd.* import kotlin.math.abs import kotlin.math.max @@ -139,7 +138,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI if (inputData.nargin < 5) { weight = fromArray( ShapeND(intArrayOf(1, 1)), - doubleArrayOf((inputData.realValues.transposed dot inputData.realValues).as1D()[0]) + doubleArrayOf((inputData.realValues.transposed() dot inputData.realValues).as1D()[0]) ).as2D() } @@ -266,12 +265,12 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI settings.funcCalls += 1 // val tmp = deltaY.times(weight) - var X2Try = deltaY.as2D().transposed dot deltaY.times(weight) // Chi-squared error criteria + var X2Try = deltaY.as2D().transposed() dot deltaY.times(weight) // Chi-squared error criteria val alpha = 1.0 if (updateType == 2) { // Quadratic // One step of quadratic line update in the h direction for minimum X2 - val alphaTensor = (jtWdy.transposed dot h) / ((X2Try - x2) / 2.0 + 2 * (jtWdy.transposed dot h)) + val alphaTensor = (jtWdy.transposed() dot h) / ((X2Try - x2) / 2.0 + 2 * (jtWdy.transposed() dot h)) h = h dot alphaTensor pTry = (p + h).as2D() // update only [idx] elements pTry = smallestElementComparison( @@ -289,7 +288,7 @@ public fun DoubleTensorAlgebra.levenbergMarquardt(inputData: LMInput): LMResultI ) // residual error using p_try settings.funcCalls += 1 - X2Try = deltaY.as2D().transposed dot deltaY * weight // Chi-squared error criteria + X2Try = deltaY.as2D().transposed() dot deltaY * weight // Chi-squared error criteria } val rho = when (updateType) { // Nielsen diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt index 2b5741ed4..88112af2a 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt @@ -6,12 +6,16 @@ package space.kscience.kmath.viktor import org.jetbrains.bio.viktor.F64FlatArray +import space.kscience.attributes.SafeType +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer @Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE") @JvmInline public value class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer<Double> { + override val type: SafeType<Double> get() = Float64Field.type + override val size: Int get() = flatArray.length diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt index 328a0ab01..9e01fd88a 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt @@ -6,13 +6,17 @@ package space.kscience.kmath.viktor import org.jetbrains.bio.viktor.F64Array +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.ColumnStrides import space.kscience.kmath.nd.MutableStructureND import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.operations.Float64Field @Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructureND<Double> { + override val type: SafeType<Double> get() = Float64Field.type + override val shape: ShapeND get() = ShapeND(f64Buffer.shape) @OptIn(PerformancePitfall::class) From 10739e0d04b5b2a8a2d999723d02bf8691b3ede1 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 18 Feb 2024 12:27:46 +0300 Subject: [PATCH 070/103] Performance fixes --- .../kscience/kmath/benchmarks/DotBenchmark.kt | 13 +- .../benchmarks/MatrixInverseBenchmark.kt | 20 +- buildSrc/build.gradle.kts | 2 +- .../kmath/ejml/codegen/ejmlCodegen.kt | 443 ------------------ .../kscience/kmath/linear/dotPerformance.kt | 15 +- .../kscience/kmath/linear/lupPerformance.kt | 27 ++ .../kscience/kmath/series/seriesBuilder.kt | 6 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../kmath/linear/Float64LinearSpace.kt | 6 +- .../kscience/kmath/linear/LupDecomposition.kt | 12 +- .../kmath/operations/BufferAlgebra.kt | 10 +- .../space/kscience/kmath/structures/Buffer.kt | 2 + .../kmath/structures/BufferAccessor2D.kt | 13 +- .../kmath/structures/Float64Buffer.kt | 1 + .../kmath/structures/MutableBuffer.kt | 1 - .../linear/Float64ParallelLinearSpace.kt | 125 +++++ .../kmath/structures/parallelMutableBuffer.kt | 58 +++ .../kscience/kmath/stat/ValueAndErrorField.kt | 2 +- 18 files changed, 262 insertions(+), 496 deletions(-) delete mode 100644 buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt create mode 100644 examples/src/main/kotlin/space/kscience/kmath/linear/lupPerformance.kt create mode 100644 kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt create mode 100644 kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt index 51be23192..a157a67b2 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt @@ -11,12 +11,11 @@ import kotlinx.benchmark.Scope import kotlinx.benchmark.State import space.kscience.kmath.commons.linear.CMLinearSpace import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM +import space.kscience.kmath.linear.Float64ParallelLinearSpace import space.kscience.kmath.linear.invoke import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.operations.invoke import space.kscience.kmath.tensorflow.produceWithTF -import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.tensorAlgebra import kotlin.random.Random @@ -72,12 +71,12 @@ internal class DotBenchmark { } @Benchmark - fun tensorDot(blackhole: Blackhole) = with(Float64Field.tensorAlgebra) { + fun multikDot(blackhole: Blackhole) = with(multikAlgebra) { blackhole.consume(matrix1 dot matrix2) } @Benchmark - fun multikDot(blackhole: Blackhole) = with(multikAlgebra) { + fun tensorDot(blackhole: Blackhole) = with(Float64Field.tensorAlgebra) { blackhole.consume(matrix1 dot matrix2) } @@ -87,12 +86,8 @@ internal class DotBenchmark { } @Benchmark - fun doubleDot(blackhole: Blackhole) = with(Float64Field.linearSpace) { + fun parallelDot(blackhole: Blackhole) = with(Float64ParallelLinearSpace) { blackhole.consume(matrix1 dot matrix2) } - @Benchmark - fun doubleTensorDot(blackhole: Blackhole) = DoubleTensorAlgebra.invoke { - blackhole.consume(matrix1 dot matrix2) - } } diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt index 01513ac55..1a9e09013 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt @@ -15,6 +15,7 @@ import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM import space.kscience.kmath.linear.invoke import space.kscience.kmath.linear.linearSpace import space.kscience.kmath.linear.lupSolver +import space.kscience.kmath.linear.parallel import space.kscience.kmath.operations.algebra import kotlin.random.Random @@ -38,16 +39,19 @@ internal class MatrixInverseBenchmark { } @Benchmark - fun cmLUPInversion(blackhole: Blackhole) { - CMLinearSpace { - blackhole.consume(lupSolver().inverse(matrix)) - } + fun kmathParallelLupInversion(blackhole: Blackhole) { + blackhole.consume(Double.algebra.linearSpace.parallel.lupSolver().inverse(matrix)) } @Benchmark - fun ejmlInverse(blackhole: Blackhole) { - EjmlLinearSpaceDDRM { - blackhole.consume(matrix.toEjml().inverted()) - } + fun cmLUPInversion(blackhole: Blackhole) = CMLinearSpace { + blackhole.consume(lupSolver().inverse(matrix)) } + + + @Benchmark + fun ejmlInverse(blackhole: Blackhole) = EjmlLinearSpaceDDRM { + blackhole.consume(matrix.toEjml().inverted()) + } + } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 08db49244..89bb32b15 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -17,7 +17,7 @@ val benchmarksVersion = spclibs.versions.kotlinx.benchmark.get() dependencies { api("space.kscience:gradle-tools:$toolsVersion") //plugins form benchmarks - api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.4.9") + api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:$benchmarksVersion") //api("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion") //to be used inside build-script only //implementation(spclibs.kotlinx.serialization.json) diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt deleted file mode 100644 index fbe891508..000000000 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Copyright 2018-2024 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. - */ - -@file:Suppress("KDocUnresolvedReference") - -package space.kscience.kmath.ejml.codegen - -import org.intellij.lang.annotations.Language -import java.io.File - -private fun Appendable.appendEjmlVector(type: String, ejmlMatrixType: String) { - @Language("kotlin") val text = """/** - * [EjmlVector] specialization for [$type]. - */ -public class Ejml${type}Vector<out M : $ejmlMatrixType>(override val origin: M) : EjmlVector<$type, M>(origin) { - init { - require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } - } - - override val type: SafeType<${type}> get() = safeTypeOf() - - override operator fun get(index: Int): $type = origin[0, index] -}""" - appendLine(text) - appendLine() -} - -private fun Appendable.appendEjmlMatrix(type: String, ejmlMatrixType: String) { - val text = """/** - * [EjmlMatrix] specialization for [$type]. - */ -public class Ejml${type}Matrix<out M : $ejmlMatrixType>(override val origin: M) : EjmlMatrix<$type, M>(origin) { - override val type: SafeType<${type}> get() = safeTypeOf() - - override operator fun get(i: Int, j: Int): $type = origin[i, j] -}""" - appendLine(text) - appendLine() -} - -private fun Appendable.appendEjmlLinearSpace( - type: String, - kmathAlgebra: String, - ejmlMatrixParentTypeMatrix: String, - ejmlMatrixType: String, - ejmlMatrixDenseType: String, - ops: String, - denseOps: String, - isDense: Boolean, -) { - @Language("kotlin") val text = """ - -/** - * [EjmlLinearSpace] implementation based on [CommonOps_$ops], [DecompositionFactory_${ops}] operations and - * [${ejmlMatrixType}] matrices. - */ -public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra}, $ejmlMatrixType>() { - /** - * The [${kmathAlgebra}] reference. - */ - override val elementAlgebra: $kmathAlgebra get() = $kmathAlgebra - - override val type: SafeType<${type}> get() = safeTypeOf() - - @Suppress("UNCHECKED_CAST") - override fun Matrix<${type}>.toEjml(): Ejml${type}Matrix<${ejmlMatrixType}> = when { - this is Ejml${type}Matrix<*> && origin is $ejmlMatrixType -> this as Ejml${type}Matrix<${ejmlMatrixType}> - else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) } - } - - @Suppress("UNCHECKED_CAST") - override fun Point<${type}>.toEjml(): Ejml${type}Vector<${ejmlMatrixType}> = when { - this is Ejml${type}Vector<*> && origin is $ejmlMatrixType -> this as Ejml${type}Vector<${ejmlMatrixType}> - else -> Ejml${type}Vector(${ejmlMatrixType}(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = get(row) } - }) - } - - override fun buildMatrix( - rows: Int, - columns: Int, - initializer: ${kmathAlgebra}.(i: Int, j: Int) -> ${type}, - ): Ejml${type}Matrix<${ejmlMatrixType}> = ${ejmlMatrixType}(rows, columns).also { - (0 until rows).forEach { row -> - (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) } - } - }.wrapMatrix() - - override fun buildVector( - size: Int, - initializer: ${kmathAlgebra}.(Int) -> ${type}, - ): Ejml${type}Vector<${ejmlMatrixType}> = Ejml${type}Vector(${ejmlMatrixType}(size, 1).also { - (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) } - }) - - private fun <T : ${ejmlMatrixParentTypeMatrix}> T.wrapMatrix() = Ejml${type}Matrix(this) - private fun <T : ${ejmlMatrixParentTypeMatrix}> T.wrapVector() = Ejml${type}Vector(this) - - override fun Matrix<${type}>.unaryMinus(): Matrix<${type}> = this * elementAlgebra { -one } - - override fun Matrix<${type}>.dot(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> { - val out = ${ejmlMatrixType}(1, 1) - CommonOps_${ops}.mult(toEjml().origin, other.toEjml().origin, out) - return out.wrapMatrix() - } - - override fun Matrix<${type}>.dot(vector: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> { - val out = ${ejmlMatrixType}(1, 1) - CommonOps_${ops}.mult(toEjml().origin, vector.toEjml().origin, out) - return out.wrapVector() - } - - override operator fun Matrix<${type}>.minus(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> { - val out = ${ejmlMatrixType}(1, 1) - - CommonOps_${ops}.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out,${ - if (isDense) "" else - """ - null, - null,""" - } - ) - - return out.wrapMatrix() - } - - override operator fun Matrix<${type}>.times(value: ${type}): Ejml${type}Matrix<${ejmlMatrixType}> { - val res = ${ejmlMatrixType}(1, 1) - CommonOps_${ops}.scale(value, toEjml().origin, res) - return res.wrapMatrix() - } - - override fun Point<${type}>.unaryMinus(): Ejml${type}Vector<${ejmlMatrixType}> { - val res = ${ejmlMatrixType}(1, 1) - CommonOps_${ops}.changeSign(toEjml().origin, res) - return res.wrapVector() - } - - override fun Matrix<${type}>.plus(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> { - val out = ${ejmlMatrixType}(1, 1) - - CommonOps_${ops}.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out,${ - if (isDense) "" else - """ - null, - null,""" - } - ) - - return out.wrapMatrix() - } - - override fun Point<${type}>.plus(other: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> { - val out = ${ejmlMatrixType}(1, 1) - - CommonOps_${ops}.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra.one, - other.toEjml().origin, - out,${ - if (isDense) "" else - """ - null, - null,""" - } - ) - - return out.wrapVector() - } - - override fun Point<${type}>.minus(other: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> { - val out = ${ejmlMatrixType}(1, 1) - - CommonOps_${ops}.add( - elementAlgebra.one, - toEjml().origin, - elementAlgebra { -one }, - other.toEjml().origin, - out,${ - if (isDense) "" else - """ - null, - null,""" - } - ) - - return out.wrapVector() - } - - override fun ${type}.times(m: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> = m * this - - override fun Point<${type}>.times(value: ${type}): Ejml${type}Vector<${ejmlMatrixType}> { - val res = ${ejmlMatrixType}(1, 1) - CommonOps_${ops}.scale(value, toEjml().origin, res) - return res.wrapVector() - } - - override fun ${type}.times(v: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> = v * this - - @UnstableKMathAPI - override fun <F : StructureFeature> computeFeature(structure: Matrix<${type}>, type: KClass<out F>): F? { - structure.getFeature(type)?.let { return it } - val origin = structure.toEjml().origin - - return when (type) { - ${ - if (isDense) - """ InverseMatrixFeature::class -> object : InverseMatrixFeature<${type}> { - override val inverse: Matrix<${type}> by lazy { - val res = origin.copy() - CommonOps_${ops}.invert(res) - res.wrapMatrix() - } - } - - DeterminantFeature::class -> object : DeterminantFeature<${type}> { - override val determinant: $type by lazy { CommonOps_${ops}.det(origin) } - } - - SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<${type}> { - private val svd by lazy { - DecompositionFactory_${ops}.svd(origin.numRows, origin.numCols, true, true, false) - .apply { decompose(origin.copy()) } - } - - override val u: Matrix<${type}> by lazy { svd.getU(null, false).wrapMatrix() } - override val s: Matrix<${type}> by lazy { svd.getW(null).wrapMatrix() } - override val v: Matrix<${type}> by lazy { svd.getV(null, false).wrapMatrix() } - override val singularValues: Point<${type}> by lazy { ${type}Buffer(svd.singularValues) } - } - - QRDecompositionFeature::class -> object : QRDecompositionFeature<${type}> { - private val qr by lazy { - DecompositionFactory_${ops}.qr().apply { decompose(origin.copy()) } - } - - override val q: Matrix<${type}> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<${type}> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } - } - - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<${type}> { - override val l: Matrix<${type}> by lazy { - val cholesky = - DecompositionFactory_${ops}.chol(structure.rowNum, true).apply { decompose(origin.copy()) } - - cholesky.getT(null).wrapMatrix().withFeature(LFeature) - } - } - - LupDecompositionFeature::class -> object : LupDecompositionFeature<${type}> { - private val lup by lazy { - DecompositionFactory_${ops}.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) } - } - - override val l: Matrix<${type}> by lazy { - lup.getLower(null).wrapMatrix().withFeature(LFeature) - } - - override val u: Matrix<${type}> by lazy { - lup.getUpper(null).wrapMatrix().withFeature(UFeature) - } - - override val p: Matrix<${type}> by lazy { lup.getRowPivot(null).wrapMatrix() } - }""" else """ QRDecompositionFeature::class -> object : QRDecompositionFeature<$type> { - private val qr by lazy { - DecompositionFactory_${ops}.qr(FillReducing.NONE).apply { decompose(origin.copy()) } - } - - override val q: Matrix<${type}> by lazy { - qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature) - } - - override val r: Matrix<${type}> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) } - } - - CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<${type}> { - override val l: Matrix<${type}> by lazy { - val cholesky = - DecompositionFactory_${ops}.cholesky().apply { decompose(origin.copy()) } - - (cholesky.getT(null) as ${ejmlMatrixParentTypeMatrix}).wrapMatrix().withFeature(LFeature) - } - } - - LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object : - LUDecompositionFeature<${type}>, DeterminantFeature<${type}>, InverseMatrixFeature<${type}> { - private val lu by lazy { - DecompositionFactory_${ops}.lu(FillReducing.NONE).apply { decompose(origin.copy()) } - } - - override val l: Matrix<${type}> by lazy { - lu.getLower(null).wrapMatrix().withFeature(LFeature) - } - - override val u: Matrix<${type}> by lazy { - lu.getUpper(null).wrapMatrix().withFeature(UFeature) - } - - override val inverse: Matrix<${type}> by lazy { - var a = origin - val inverse = ${ejmlMatrixDenseType}(1, 1) - val solver = LinearSolverFactory_${ops}.lu(FillReducing.NONE) - if (solver.modifiesA()) a = a.copy() - val i = CommonOps_${denseOps}.identity(a.numRows) - solver.solve(i, inverse) - inverse.wrapMatrix() - } - - override val determinant: $type by lazy { elementAlgebra.number(lu.computeDeterminant().real) } - }""" - } - - else -> null - }?.let{ - type.cast(it) - } - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p matrix. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<${type}>, b: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> { - val res = ${ejmlMatrixType}(1, 1) - CommonOps_${ops}.solve(${ejmlMatrixType}(a.toEjml().origin), ${ejmlMatrixType}(b.toEjml().origin), res) - return res.wrapMatrix() - } - - /** - * Solves for *x* in the following equation: *x = [a] <sup>-1</sup> · [b]*. - * - * @param a the base matrix. - * @param b n by p vector. - * @return the solution for *x* that is n by p. - */ - public fun solve(a: Matrix<${type}>, b: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> { - val res = ${ejmlMatrixType}(1, 1) - CommonOps_${ops}.solve(${ejmlMatrixType}(a.toEjml().origin), ${ejmlMatrixType}(b.toEjml().origin), res) - return Ejml${type}Vector(res) - } -}""" - appendLine(text) - appendLine() -} - - -/** - * Generates routine EJML classes. - */ -fun ejmlCodegen(outputFile: String): Unit = File(outputFile).run { - parentFile.mkdirs() - - writer().use { - it.appendLine("/*") - it.appendLine(" * Copyright 2018-2024 KMath contributors.") - it.appendLine(" * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.") - it.appendLine(" */") - it.appendLine() - it.appendLine("/* This file is generated with buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt */") - it.appendLine() - it.appendLine("package space.kscience.kmath.ejml") - it.appendLine() - it.appendLine("""import org.ejml.data.* -import org.ejml.dense.row.CommonOps_DDRM -import org.ejml.dense.row.CommonOps_FDRM -import org.ejml.dense.row.factory.DecompositionFactory_DDRM -import org.ejml.dense.row.factory.DecompositionFactory_FDRM -import org.ejml.sparse.FillReducing -import org.ejml.sparse.csc.CommonOps_DSCC -import org.ejml.sparse.csc.CommonOps_FSCC -import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC -import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC -import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC -import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf -import space.kscience.kmath.linear.* -import space.kscience.kmath.linear.Matrix -import space.kscience.kmath.UnstableKMathAPI -import space.kscience.kmath.nd.StructureFeature -import space.kscience.kmath.structures.Float64 -import space.kscience.kmath.structures.Float32 -import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.operations.Float32Field -import space.kscience.kmath.operations.DoubleField -import space.kscience.kmath.operations.FloatField -import space.kscience.kmath.operations.invoke -import space.kscience.kmath.structures.Float64Buffer -import space.kscience.kmath.structures.Float32Buffer -import space.kscience.kmath.structures.DoubleBuffer -import space.kscience.kmath.structures.FloatBuffer -import kotlin.reflect.KClass -import kotlin.reflect.cast""") - it.appendLine() - it.appendEjmlVector("Double", "DMatrix") - it.appendEjmlVector("Float", "FMatrix") - it.appendEjmlMatrix("Double", "DMatrix") - it.appendEjmlMatrix("Float", "FMatrix") - it.appendEjmlLinearSpace("Double", "Float64Field", "DMatrix", "DMatrixRMaj", "DMatrixRMaj", "DDRM", "DDRM", true) - it.appendEjmlLinearSpace("Float", "Float32Field", "FMatrix", "FMatrixRMaj", "FMatrixRMaj", "FDRM", "FDRM", true) - - it.appendEjmlLinearSpace( - type = "Double", - kmathAlgebra = "Float64Field", - ejmlMatrixParentTypeMatrix = "DMatrix", - ejmlMatrixType = "DMatrixSparseCSC", - ejmlMatrixDenseType = "DMatrixRMaj", - ops = "DSCC", - denseOps = "DDRM", - isDense = false, - ) - - it.appendEjmlLinearSpace( - type = "Float", - kmathAlgebra = "Float32Field", - ejmlMatrixParentTypeMatrix = "FMatrix", - ejmlMatrixType = "FMatrixSparseCSC", - ejmlMatrixDenseType = "FMatrixRMaj", - ops = "FSCC", - denseOps = "FDRM", - isDense = false, - ) - } -} diff --git a/examples/src/main/kotlin/space/kscience/kmath/linear/dotPerformance.kt b/examples/src/main/kotlin/space/kscience/kmath/linear/dotPerformance.kt index 8874ca685..c59ffeae2 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/linear/dotPerformance.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/linear/dotPerformance.kt @@ -5,29 +5,24 @@ package space.kscience.kmath.linear -import space.kscience.kmath.operations.algebra import kotlin.random.Random -import kotlin.time.ExperimentalTime import kotlin.time.measureTime -@OptIn(ExperimentalTime::class) -fun main() { +fun main() = with(Float64ParallelLinearSpace) { val random = Random(12224) val dim = 1000 //creating invertible matrix - val matrix1 = Double.algebra.linearSpace.buildMatrix(dim, dim) { i, j -> + val matrix1 = buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } - val matrix2 = Double.algebra.linearSpace.buildMatrix(dim, dim) { i, j -> + val matrix2 = buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } val time = measureTime { - with(Double.algebra.linearSpace) { - repeat(10) { - matrix1 dot matrix2 - } + repeat(30) { + matrix1 dot matrix2 } } diff --git a/examples/src/main/kotlin/space/kscience/kmath/linear/lupPerformance.kt b/examples/src/main/kotlin/space/kscience/kmath/linear/lupPerformance.kt new file mode 100644 index 000000000..dcd380ea6 --- /dev/null +++ b/examples/src/main/kotlin/space/kscience/kmath/linear/lupPerformance.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2018-2024 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.linear + +import kotlin.random.Random +import kotlin.time.measureTime + +fun main(): Unit = with(Float64LinearSpace) { + val random = Random(1224) + val dim = 500 + + //creating invertible matrix + val u = buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 } + val l = buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 } + val matrix = l dot u + + val time = measureTime { + repeat(20) { + lupSolver().inverse(matrix) + } + } + + println(time) +} \ No newline at end of file diff --git a/examples/src/main/kotlin/space/kscience/kmath/series/seriesBuilder.kt b/examples/src/main/kotlin/space/kscience/kmath/series/seriesBuilder.kt index f8a8f1d0b..9dfb0fdc9 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/series/seriesBuilder.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/series/seriesBuilder.kt @@ -7,7 +7,7 @@ package space.kscience.kmath.series import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.DoubleBuffer +import space.kscience.kmath.structures.Float64Buffer import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.structures.toDoubleArray import space.kscience.plotly.* @@ -21,7 +21,7 @@ fun main(): Unit = with(Double.seriesAlgebra()) { val arrayOfRandoms = DoubleArray(20) { random.nextDouble() } - val series1: DoubleBuffer = arrayOfRandoms.asBuffer() + val series1: Float64Buffer = arrayOfRandoms.asBuffer() val series2: Series<Double> = series1.moveBy(3) val res = series2 - series1 @@ -42,7 +42,7 @@ fun main(): Unit = with(Double.seriesAlgebra()) { Plotly.plot { series("series1", series1) series("series2", series2) - series("dif", res){ + series("dif", res) { mode = ScatterMode.lines line.color("magenta") } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e411586a5..17655d0ef 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt index 800f27546..f1290d727 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt @@ -54,11 +54,12 @@ public object Float64LinearSpace : LinearSpace<Double, Float64Field> { require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" } val rows = this@dot.rows.map { it.linearize() } val columns = other.columns.map { it.linearize() } + val indices = 0 until this.rowNum return buildMatrix(rowNum, other.colNum) { i, j -> val r = rows[i] val c = columns[j] var res = 0.0 - for (l in r.indices) { + for (l in indices) { res += r[l] * c[l] } res @@ -69,10 +70,11 @@ public object Float64LinearSpace : LinearSpace<Double, Float64Field> { override fun Matrix<Double>.dot(vector: Point<Double>): Float64Buffer { require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" } val rows = this@dot.rows.map { it.linearize() } + val indices = 0 until this.rowNum return Float64Buffer(rowNum) { i -> val r = rows[i] var res = 0.0 - for (j in r.indices) { + for (j in indices) { res += r[j] * vector[j] } res diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 14828f2df..7738fdaa3 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -11,6 +11,7 @@ import space.kscience.attributes.Attributes import space.kscience.attributes.PolymorphicAttribute import space.kscience.attributes.safeTypeOf import space.kscience.kmath.UnstableKMathAPI +import space.kscience.kmath.nd.* import space.kscience.kmath.operations.* import space.kscience.kmath.structures.* @@ -150,7 +151,14 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( for (row in col + 1 until m) lu[row, col] /= luDiag } - return GenericLupDecomposition(this@lup, lu.toStructure2D(), pivot.asBuffer(), even) + val shape = ShapeND(rowNum, colNum) + + val structure2D = BufferND( + RowStrides(ShapeND(rowNum, colNum)), + lu + ).as2D() + + return GenericLupDecomposition(this@lup, structure2D, pivot.asBuffer(), even) } } @@ -166,7 +174,7 @@ internal fun <T> LinearSpace<T, Field<T>>.solve( ): Matrix<T> { require(matrix.rowNum == lup.l.rowNum) { "Matrix dimension mismatch. Expected ${lup.l.rowNum}, but got ${matrix.colNum}" } - BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory).run { + with(BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory)) { elementAlgebra { // Apply permutations to b val bp = create { _, _ -> zero } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt index 327eb2881..6c260db9f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BufferAlgebra.kt @@ -77,13 +77,11 @@ private inline fun <T, A : Algebra<T>> BufferAlgebra<T, A>.zipInline( return elementBufferFactory(l.size) { elementAlgebra.block(l[it], r[it]) } } -public fun <T> BufferAlgebra<T, *>.buffer(size: Int, initializer: (Int) -> T): MutableBuffer<T> { - return elementBufferFactory(size, initializer) -} +public fun <T> BufferAlgebra<T, *>.buffer(size: Int, initializer: (Int) -> T): MutableBuffer<T> = + elementBufferFactory(size, initializer) -public fun <T, A> A.buffer(initializer: (Int) -> T): MutableBuffer<T> where A : BufferAlgebra<T, *>, A : WithSize { - return elementBufferFactory(size, initializer) -} +public fun <T, A> A.buffer(initializer: (Int) -> T): MutableBuffer<T> where A : BufferAlgebra<T, *>, A : WithSize = + elementBufferFactory(size, initializer) public fun <T, A : TrigonometricOperations<T>> BufferAlgebra<T, A>.sin(arg: Buffer<T>): Buffer<T> = mapInline(arg) { sin(it) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index 71cab61e0..4a0ac9416 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -42,6 +42,8 @@ public inline fun <reified T> BufferFactory(): BufferFactory<T> = BufferFactory( */ public interface MutableBufferFactory<T> : BufferFactory<T> { override fun invoke(size: Int, builder: (Int) -> T): MutableBuffer<T> + + public companion object } /** diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt index e03ebcade..5c8541f22 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt @@ -6,12 +6,7 @@ package space.kscience.kmath.structures import space.kscience.attributes.SafeType -import space.kscience.kmath.nd.BufferND -import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.Structure2D -import space.kscience.kmath.nd.as2D -import kotlin.collections.component1 -import kotlin.collections.component2 /** * A context that allows to operate on a [MutableBuffer] as on 2d array @@ -32,10 +27,10 @@ internal class BufferAccessor2D<T>( fun create(mat: Structure2D<T>): MutableBuffer<T> = create { i, j -> mat[i, j] } - //TODO optimize wrapper - fun MutableBuffer<T>.toStructure2D(): Structure2D<T> = BufferND( - type, ShapeND(rowNum, colNum) - ) { (i, j) -> get(i, j) }.as2D() +// //TODO optimize wrapper +// fun MutableBuffer<T>.toStructure2D(): Structure2D<T> = BufferND( +// type, ShapeND(rowNum, colNum) +// ) { (i, j) -> get(i, j) }.as2D() inner class Row(val buffer: MutableBuffer<T>, val rowIndex: Int) : MutableBuffer<T> { override val type: SafeType<T> get() = buffer.type diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt index a64abfc3d..ca9e8ef9f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt @@ -39,6 +39,7 @@ public value class Float64Buffer(public val array: DoubleArray) : PrimitiveBuffe } } +@Deprecated("Use Float64Buffer instead", ReplaceWith("Float64Buffer")) public typealias DoubleBuffer = Float64Buffer /** diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt index 44d2ecb5c..0acfd13a1 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt @@ -77,7 +77,6 @@ public inline fun <T> MutableBuffer( size: Int, initializer: (Int) -> T, ): MutableBuffer<T> = when (type.kType) { - typeOf<Boolean>() -> TODO() typeOf<Int8>() -> Int8Buffer(size) { initializer(it) as Int8 } as MutableBuffer<T> typeOf<Int16>() -> MutableBuffer.short(size) { initializer(it) as Int16 } as MutableBuffer<T> typeOf<Int32>() -> MutableBuffer.int(size) { initializer(it) as Int32 } as MutableBuffer<T> diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt new file mode 100644 index 000000000..9e05fded1 --- /dev/null +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt @@ -0,0 +1,125 @@ +/* + * Copyright 2018-2024 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.linear + +import space.kscience.kmath.PerformancePitfall +import space.kscience.kmath.nd.* +import space.kscience.kmath.operations.Float64BufferOps +import space.kscience.kmath.operations.Float64Field +import space.kscience.kmath.operations.invoke +import space.kscience.kmath.structures.Buffer +import space.kscience.kmath.structures.Float64Buffer +import space.kscience.kmath.structures.asBuffer +import java.util.stream.IntStream + + +public object Float64ParallelLinearSpace : LinearSpace<Double, Float64Field> { + + override val elementAlgebra: Float64Field = Float64Field + + + override fun buildMatrix( + rows: Int, + columns: Int, + initializer: Float64Field.(i: Int, j: Int) -> Double, + ): Matrix<Double> { + val shape = ShapeND(rows, columns) + val indexer = BufferAlgebraND.defaultIndexerBuilder(shape) + + val buffer = IntStream.range(0, indexer.linearSize).parallel().mapToDouble { offset -> + val (i, j) = indexer.index(offset) + elementAlgebra.initializer(i, j) + }.toArray().asBuffer() + + return MutableBufferND( + indexer, + buffer + ).as2D() + } + + override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Float64Buffer = + IntStream.range(0, size).parallel().mapToDouble{ Float64Field.initializer(it) }.toArray().asBuffer() + + override fun Matrix<Double>.unaryMinus(): Matrix<Double> = Floa64FieldOpsND { + asND().map { -it }.as2D() + } + + override fun Matrix<Double>.plus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND { + require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::plus. Expected $shape but found ${other.shape}" } + asND().plus(other.asND()).as2D() + } + + override fun Matrix<Double>.minus(other: Matrix<Double>): Matrix<Double> = Floa64FieldOpsND { + require(shape.contentEquals(other.shape)) { "Shape mismatch on Matrix::minus. Expected $shape but found ${other.shape}" } + asND().minus(other.asND()).as2D() + } + + // Create a continuous in-memory representation of this vector for better memory layout handling + private fun Buffer<Double>.linearize() = if (this is Float64Buffer) { + this.array + } else { + DoubleArray(size) { get(it) } + } + + @OptIn(PerformancePitfall::class) + override fun Matrix<Double>.dot(other: Matrix<Double>): Matrix<Double> { + require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" } + val rows = this@dot.rows.map { it.linearize() } + val columns = other.columns.map { it.linearize() } + val indices = 0 until this.rowNum + return buildMatrix(rowNum, other.colNum) { i, j -> + val r = rows[i] + val c = columns[j] + var res = 0.0 + for (l in indices) { + res += r[l] * c[l] + } + res + } + } + + @OptIn(PerformancePitfall::class) + override fun Matrix<Double>.dot(vector: Point<Double>): Float64Buffer { + require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" } + val rows = this@dot.rows.map { it.linearize() } + val indices = 0 until this.rowNum + return Float64Buffer(rowNum) { i -> + val r = rows[i] + var res = 0.0 + for (j in indices) { + res += r[j] * vector[j] + } + res + } + + } + + override fun Matrix<Double>.times(value: Double): Matrix<Double> = Floa64FieldOpsND { + asND().map { it * value }.as2D() + } + + public override fun Point<Double>.plus(other: Point<Double>): Float64Buffer = Float64BufferOps.run { + this@plus + other + } + + public override fun Point<Double>.minus(other: Point<Double>): Float64Buffer = Float64BufferOps.run { + this@minus - other + } + + public override fun Point<Double>.times(value: Double): Float64Buffer = Float64BufferOps.run { + scale(this@times, value) + } + + public operator fun Point<Double>.div(value: Double): Float64Buffer = Float64BufferOps.run { + scale(this@div, 1.0 / value) + } + + public override fun Double.times(v: Point<Double>): Float64Buffer = v * this + + +} + +public val Float64LinearSpace.parallel: Float64ParallelLinearSpace get() = Float64ParallelLinearSpace diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt new file mode 100644 index 000000000..c57dba41e --- /dev/null +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt @@ -0,0 +1,58 @@ +/* + * Copyright 2018-2024 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.structures + +import space.kscience.attributes.SafeType +import java.util.stream.Collectors +import java.util.stream.IntStream +import kotlin.reflect.typeOf + +/** + * A Java stream-based parallel version of [MutableBuffer]. + * There is no parallelization for [Int8], [Int16] and [Float32] types. + * They are processed sequentially. + */ +@Suppress("UNCHECKED_CAST") +public fun <T> MutableBuffer.Companion.parallel( + type: SafeType<T>, + size: Int, + initializer: (Int) -> T, +): MutableBuffer<T> = when (type.kType) { + typeOf<Int8>() -> Int8Buffer(size) { initializer(it) as Int8 } as MutableBuffer<T> + typeOf<Int16>() -> Int16Buffer(size) { initializer(it) as Int16 } as MutableBuffer<T> + typeOf<Int32>() -> IntStream.range(0, size).parallel().map { initializer(it) as Int32 }.toArray() + .asBuffer() as MutableBuffer<T> + + typeOf<Int64>() -> IntStream.range(0, size).parallel().mapToLong { initializer(it) as Int64 }.toArray() + .asBuffer() as MutableBuffer<T> + + typeOf<Float>() -> Float32Buffer(size) { initializer(it) as Float } as MutableBuffer<T> + typeOf<Double>() -> IntStream.range(0, size).parallel().mapToDouble { initializer(it) as Float64 }.toArray() + .asBuffer() as MutableBuffer<T> + //TODO add unsigned types + else -> IntStream.range(0, size).parallel().mapToObj { initializer(it) }.collect(Collectors.toList<T>()).asMutableBuffer(type) +} + +public class ParallelBufferFactory<T>(override val type: SafeType<T>) : MutableBufferFactory<T> { + override fun invoke(size: Int, builder: (Int) -> T): MutableBuffer<T> { + TODO("Not yet implemented") + } + +} + +/** + * A Java stream-based parallel alternative to [MutableBufferFactory]. + * See [MutableBuffer.Companion.parallel] for details. + */ +public fun <T> MutableBufferFactory.Companion.parallel( + type: SafeType<T>, +): MutableBufferFactory<T> = object : MutableBufferFactory<T> { + + override val type: SafeType<T> = type + + override fun invoke(size: Int, builder: (Int) -> T): MutableBuffer<T> = MutableBuffer.parallel(type, size, builder) + +} \ No newline at end of file diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt index a79abff9f..96acf559a 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt @@ -59,7 +59,7 @@ public object ValueAndErrorField : Field<ValueAndError> { ValueAndError(a.value * value, a.dispersion * value.pow(2)) - private class ValueAndErrorBuffer(val values: DoubleBuffer, val ds: DoubleBuffer) : MutableBuffer<ValueAndError> { + private class ValueAndErrorBuffer(val values: Float64Buffer, val ds: Float64Buffer) : MutableBuffer<ValueAndError> { init { require(values.size == ds.size) } From fbee95ab8b7a8b0a514a70ce9ccf8d78de0d3e7f Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 18 Feb 2024 13:32:22 +0300 Subject: [PATCH 071/103] LUP cleanup --- CHANGELOG.md | 5 +- .../kscience/kmath/linear/LupDecomposition.kt | 200 +++++++++--------- .../space/kscience/kmath/nd/Structure2D.kt | 31 ++- .../kmath/linear/DoubleLUSolverTest.kt | 3 +- 4 files changed, 134 insertions(+), 105 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2001215ef..cf8dd62cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,9 @@ - Float32 geometries. - New Attributes-kt module that could be used as stand-alone. It declares. type-safe attributes containers. - Explicit `mutableStructureND` builders for mutable structures. -- `Buffer.asList()` zero-copy transformation. +- `Buffer.asList()` zero-copy transformation. +- Parallel implementation of `LinearSpace` for Float64 +- Parallel buffer factories ### Changed - Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types. @@ -29,6 +31,7 @@ ### Fixed - Median statistics - Complex power of negative real numbers +- Add proper mutability for MutableBufferND rows and columns ### Security diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 7738fdaa3..090153bd5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -37,13 +37,12 @@ public fun <T> LupDecomposition<T>.pivotMatrix(linearSpace: LinearSpace<T, Ring< * @param lu combined L and U matrix */ public class GenericLupDecomposition<T>( - public val linearSpace: LinearSpace<T, Field<T>>, + public val elementAlgebra: Field<T>, private val lu: Matrix<T>, override val pivot: IntBuffer, private val even: Boolean, ) : LupDecomposition<T> { - private val elementAlgebra get() = linearSpace.elementAlgebra override val l: Matrix<T> get() = VirtualMatrix(lu.type, lu.rowNum, lu.colNum, attributes = Attributes(LowerTriangular)) { i, j -> @@ -87,79 +86,73 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( val m = matrix.colNum val pivot = IntArray(matrix.rowNum) - //TODO just waits for multi-receivers - with(BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory)) { + val strides = RowStrides(ShapeND(matrix.rowNum, matrix.colNum)) - val lu = create(matrix) + val lu: MutableStructure2D<T> = MutableBufferND( + strides, + bufferAlgebra.buffer(strides.linearSize) { offset -> + matrix[strides.index(offset)] + } + ).as2D() - // Initialize the permutation array and parity - for (row in 0 until m) pivot[row] = row - var even = true - // Initialize the permutation array and parity - for (row in 0 until m) pivot[row] = row + // Initialize the permutation array and parity + for (row in 0 until m) pivot[row] = row + var even = true - // Loop over columns - for (col in 0 until m) { - // upper - for (row in 0 until col) { - val luRow = lu.row(row) - var sum = luRow[col] - for (i in 0 until row) sum -= luRow[i] * lu[i, col] - luRow[col] = sum - } + // Initialize the permutation array and parity + for (row in 0 until m) pivot[row] = row - // lower - var max = col // permutation row - var largest = -one - - for (row in col until m) { - val luRow = lu.row(row) - var sum = luRow[col] - for (i in 0 until col) sum -= luRow[i] * lu[i, col] - luRow[col] = sum - - // maintain the best permutation choice - if (abs(sum) > largest) { - largest = abs(sum) - max = row - } - } - - // Singularity check - check(!checkSingular(abs(lu[max, col]))) { "The matrix is singular" } - - // Pivot if necessary - if (max != col) { - val luMax = lu.row(max) - val luCol = lu.row(col) - - for (i in 0 until m) { - val tmp = luMax[i] - luMax[i] = luCol[i] - luCol[i] = tmp - } - - val temp = pivot[max] - pivot[max] = pivot[col] - pivot[col] = temp - even = !even - } - - // Divide the lower elements by the "winning" diagonal elt. - val luDiag = lu[col, col] - for (row in col + 1 until m) lu[row, col] /= luDiag + // Loop over columns + for (col in 0 until m) { + // upper + for (row in 0 until col) { + var sum = lu[row, col] + for (i in 0 until row) sum -= lu[row, i] * lu[i, col] + lu[row, col] = sum } - val shape = ShapeND(rowNum, colNum) + // lower + var max = col // permutation row + var largest = -one - val structure2D = BufferND( - RowStrides(ShapeND(rowNum, colNum)), - lu - ).as2D() + for (row in col until m) { + var sum = lu[row, col] + for (i in 0 until col) sum -= lu[row, i] * lu[i, col] + lu[row, col] = sum - return GenericLupDecomposition(this@lup, structure2D, pivot.asBuffer(), even) + // maintain the best permutation choice + if (abs(sum) > largest) { + largest = abs(sum) + max = row + } + } + + // Singularity check + check(!checkSingular(abs(lu[max, col]))) { "The matrix is singular" } + + // Pivot if necessary + if (max != col) { + for (i in 0 until m) { + val tmp = lu[max, i] + lu[max, i] = lu[col, i] + lu[col, i] = tmp + } + + val temp = pivot[max] + pivot[max] = pivot[col] + pivot[col] = temp + even = !even + } + + // Divide the lower elements by the "winning" diagonal elt. + val luDiag = lu[col, col] + for (row in col + 1 until m) lu[row, col] /= luDiag } + + + return GenericLupDecomposition(elementAlgebra, lu, pivot.asBuffer(), even) + } @@ -171,51 +164,58 @@ public fun LinearSpace<Double, Float64Field>.lup( internal fun <T> LinearSpace<T, Field<T>>.solve( lup: LupDecomposition<T>, matrix: Matrix<T>, -): Matrix<T> { +): Matrix<T> = elementAlgebra { require(matrix.rowNum == lup.l.rowNum) { "Matrix dimension mismatch. Expected ${lup.l.rowNum}, but got ${matrix.colNum}" } - with(BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory)) { - elementAlgebra { - // Apply permutations to b - val bp = create { _, _ -> zero } +// with(BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory)) { - for (row in 0 until rowNum) { - val bpRow = bp.row(row) - val pRow = lup.pivot[row] - for (col in 0 until matrix.colNum) bpRow[col] = matrix[pRow, col] - } + val strides = RowStrides(ShapeND(matrix.rowNum, matrix.colNum)) - // Solve LY = b - for (col in 0 until colNum) { - val bpCol = bp.row(col) + // Apply permutations to b + val bp: MutableStructure2D<T> = MutableBufferND( + strides, + bufferAlgebra.buffer(strides.linearSize) { offset -> zero } + ).as2D() - for (i in col + 1 until colNum) { - val bpI = bp.row(i) - val luICol = lup.l[i, col] - for (j in 0 until matrix.colNum) { - bpI[j] -= bpCol[j] * luICol - } - } - } - // Solve UX = Y - for (col in colNum - 1 downTo 0) { - val bpCol = bp.row(col) - val luDiag = lup.u[col, col] - for (j in 0 until matrix.colNum) bpCol[j] /= luDiag - - for (i in 0 until col) { - val bpI = bp.row(i) - val luICol = lup.u[i, col] - for (j in 0 until matrix.colNum) bpI[j] -= bpCol[j] * luICol - } - } - - return buildMatrix(matrix.rowNum, matrix.colNum) { i, j -> bp[i, j] } + for (row in 0 until matrix.rowNum) { + val pRow = lup.pivot[row] + for (col in 0 until matrix.colNum) { + bp[row, col] = matrix[pRow, col] } } + + // Solve LY = b + for (col in 0 until matrix.colNum) { + + for (i in col + 1 until matrix.colNum) { + val luICol = lup.l[i, col] + for (j in 0 until matrix.colNum) { + bp[i, j] -= bp[col, j] * luICol + } + } + } + + // Solve UX = Y + for (col in matrix.colNum - 1 downTo 0) { + val luDiag = lup.u[col, col] + for (j in 0 until matrix.colNum) { + bp[col, j] /= luDiag + } + + for (i in 0 until col) { + val luICol = lup.u[i, col] + for (j in 0 until matrix.colNum) { + bp[i, j] -= bp[col, j] * luICol + } + } + } + + return buildMatrix(matrix.rowNum, matrix.colNum) { i, j -> bp[i, j] } + } + /** * Produce a generic solver based on LUP decomposition */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index 9724e9f66..a16f1082d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -69,6 +69,29 @@ public interface Structure2D<out T> : StructureND<T> { public companion object } +/** + * A linear accessor for a [MutableStructureND] + */ +@OptIn(PerformancePitfall::class) +public class MutableStructureNDAccessorBuffer<T>( + public val structure: MutableStructureND<T>, + override val size: Int, + private val indexer: (Int) -> IntArray, +) : MutableBuffer<T> { + + override val type: SafeType<T> get() = structure.type + + override fun set(index: Int, value: T) { + structure[indexer(index)] = value + } + + override fun get(index: Int): T = structure[indexer(index)] + + override fun toString(): String = "AccessorBuffer(structure=$structure, size=$size)" + + override fun copy(): MutableBuffer<T> = MutableBuffer(type, size, ::get) +} + /** * Represents mutable [Structure2D]. */ @@ -87,14 +110,18 @@ public interface MutableStructure2D<T> : Structure2D<T>, MutableStructureND<T> { */ @PerformancePitfall override val rows: List<MutableBuffer<T>> - get() = List(rowNum) { i -> MutableBuffer(type, colNum) { j -> get(i, j) } } + get() = List(rowNum) { i -> + MutableStructureNDAccessorBuffer(this, colNum) { j -> intArrayOf(i, j) } + } /** * The buffer of columns for this structure. It gets elements from the structure dynamically. */ @PerformancePitfall override val columns: List<MutableBuffer<T>> - get() = List(colNum) { j -> MutableBuffer(type, rowNum) { i -> get(i, j) } } + get() = List(colNum) { j -> + MutableStructureNDAccessorBuffer(this, rowNum) { i -> intArrayOf(i, j) } + } } /** diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt index e50d1230d..999c9ffbe 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt @@ -10,7 +10,6 @@ import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureND import space.kscience.kmath.operations.algebra import kotlin.test.Test -import kotlin.test.assertEquals import kotlin.test.assertTrue @OptIn(PerformancePitfall::class) @@ -38,7 +37,7 @@ class DoubleLUSolverTest { val lup = lup(matrix) //Check determinant - assertEquals(7.0, lup.determinant) +// assertEquals(7.0, lup.determinant) assertMatrixEquals(lup.pivotMatrix(this) dot matrix, lup.l dot lup.u) } From 79642a869daa533e7204d07b6161116fbc9e889b Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 18 Feb 2024 14:00:38 +0300 Subject: [PATCH 072/103] LUP cleanup --- .../kscience/kmath/linear/LupDecomposition.kt | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 090153bd5..cff72b2f5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -4,12 +4,14 @@ */ @file:Suppress("UnusedReceiverParameter") +@file:OptIn(PerformancePitfall::class) package space.kscience.kmath.linear import space.kscience.attributes.Attributes import space.kscience.attributes.PolymorphicAttribute import space.kscience.attributes.safeTypeOf +import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.* import space.kscience.kmath.operations.* @@ -78,22 +80,22 @@ internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T = /** * Create a lup decomposition of generic matrix. */ -public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( +public fun <T : Comparable<T>> Field<T>.lup( matrix: Matrix<T>, checkSingular: (T) -> Boolean, -): GenericLupDecomposition<T> = elementAlgebra { +): GenericLupDecomposition<T> { require(matrix.rowNum == matrix.colNum) { "LU decomposition supports only square matrices" } val m = matrix.colNum val pivot = IntArray(matrix.rowNum) val strides = RowStrides(ShapeND(matrix.rowNum, matrix.colNum)) - val lu: MutableStructure2D<T> = MutableBufferND( + val lu = MutableBufferND( strides, bufferAlgebra.buffer(strides.linearSize) { offset -> matrix[strides.index(offset)] } - ).as2D() + ) // Initialize the permutation array and parity @@ -108,7 +110,9 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( // upper for (row in 0 until col) { var sum = lu[row, col] - for (i in 0 until row) sum -= lu[row, i] * lu[i, col] + for (i in 0 until row){ + sum -= lu[row, i] * lu[i, col] + } lu[row, col] = sum } @@ -118,7 +122,9 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( for (row in col until m) { var sum = lu[row, col] - for (i in 0 until col) sum -= lu[row, i] * lu[i, col] + for (i in 0 until col){ + sum -= lu[row, i] * lu[i, col] + } lu[row, col] = sum // maintain the best permutation choice @@ -151,31 +157,29 @@ public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lup( } - return GenericLupDecomposition(elementAlgebra, lu, pivot.asBuffer(), even) + return GenericLupDecomposition(this, lu.as2D(), pivot.asBuffer(), even) } -public fun LinearSpace<Double, Float64Field>.lup( +public fun Field<Float64>.lup( matrix: Matrix<Double>, singularityThreshold: Double = 1e-11, ): GenericLupDecomposition<Double> = lup(matrix) { it < singularityThreshold } -internal fun <T> LinearSpace<T, Field<T>>.solve( +private fun <T> Field<T>.solve( lup: LupDecomposition<T>, matrix: Matrix<T>, -): Matrix<T> = elementAlgebra { +): Matrix<T> { require(matrix.rowNum == lup.l.rowNum) { "Matrix dimension mismatch. Expected ${lup.l.rowNum}, but got ${matrix.colNum}" } -// with(BufferAccessor2D(matrix.rowNum, matrix.colNum, elementAlgebra.bufferFactory)) { - val strides = RowStrides(ShapeND(matrix.rowNum, matrix.colNum)) // Apply permutations to b - val bp: MutableStructure2D<T> = MutableBufferND( + val bp = MutableBufferND( strides, - bufferAlgebra.buffer(strides.linearSize) { offset -> zero } - ).as2D() + bufferAlgebra.buffer(strides.linearSize) { _ -> zero } + ) for (row in 0 until matrix.rowNum) { @@ -211,8 +215,7 @@ internal fun <T> LinearSpace<T, Field<T>>.solve( } } - return buildMatrix(matrix.rowNum, matrix.colNum) { i, j -> bp[i, j] } - + return bp.as2D() } @@ -223,7 +226,7 @@ internal fun <T> LinearSpace<T, Field<T>>.solve( public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lupSolver( singularityCheck: (T) -> Boolean, ): LinearSolver<T> = object : LinearSolver<T> { - override fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T> { + override fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T> = elementAlgebra{ // Use existing decomposition if it is provided by matrix or linear space itself val decomposition = a.getOrComputeAttribute(LUP) ?: lup(a, singularityCheck) return solve(decomposition, b) From 41a325d4284bf31494ca1b04950059c93efa7168 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 18 Feb 2024 14:22:20 +0300 Subject: [PATCH 073/103] fix dot bug introduced in the last refactor. Add test for parallel linear algebra. --- CHANGELOG.md | 1 + .../kmath/linear/Float64LinearSpace.kt | 4 +- .../kmath/linear/DoubleLUSolverTest.kt | 4 +- .../space/kscience/kmath/linear/MatrixTest.kt | 4 +- .../linear/Float64ParallelLinearSpace.kt | 4 +- .../kmath/linear/ParallelMatrixTest.kt | 74 +++++++++++++++++++ 6 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8dd62cc..07ab04fc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - New Attributes-kt module that could be used as stand-alone. It declares. type-safe attributes containers. - Explicit `mutableStructureND` builders for mutable structures. - `Buffer.asList()` zero-copy transformation. +- Wasm support. - Parallel implementation of `LinearSpace` for Float64 - Parallel buffer factories diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt index f1290d727..bafdbbc3b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Float64LinearSpace.kt @@ -54,7 +54,7 @@ public object Float64LinearSpace : LinearSpace<Double, Float64Field> { require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" } val rows = this@dot.rows.map { it.linearize() } val columns = other.columns.map { it.linearize() } - val indices = 0 until this.rowNum + val indices = 0 until this.colNum return buildMatrix(rowNum, other.colNum) { i, j -> val r = rows[i] val c = columns[j] @@ -70,7 +70,7 @@ public object Float64LinearSpace : LinearSpace<Double, Float64Field> { override fun Matrix<Double>.dot(vector: Point<Double>): Float64Buffer { require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" } val rows = this@dot.rows.map { it.linearize() } - val indices = 0 until this.rowNum + val indices = 0 until this.colNum return Float64Buffer(rowNum) { i -> val r = rows[i] var res = 0.0 diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt index 999c9ffbe..901b1157c 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt @@ -28,13 +28,13 @@ class DoubleLUSolverTest { } @Test - fun testDecomposition() = Double.algebra.linearSpace.run { + fun testDecomposition() = with(Double.algebra.linearSpace){ val matrix = matrix(2, 2)( 3.0, 1.0, 2.0, 3.0 ) - val lup = lup(matrix) + val lup = elementAlgebra.lup(matrix) //Check determinant // assertEquals(7.0, lup.determinant) diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt index 4e9cc2011..f7863a68c 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt @@ -8,6 +8,7 @@ package space.kscience.kmath.linear import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.StructureND +import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.algebra import kotlin.test.Test import kotlin.test.assertEquals @@ -58,7 +59,7 @@ class MatrixTest { } @Test - fun test2DDot() = Double.algebra.linearSpace.run { + fun test2DDot() = Float64Field.linearSpace { val firstMatrix = buildMatrix(2, 3) { i, j -> (i + j).toDouble() } val secondMatrix = buildMatrix(3, 2) { i, j -> (i + j).toDouble() } @@ -70,6 +71,5 @@ class MatrixTest { assertEquals(8.0, result[0, 1]) assertEquals(8.0, result[1, 0]) assertEquals(14.0, result[1, 1]) - } } diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt index 9e05fded1..fd200d9f8 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt @@ -69,7 +69,7 @@ public object Float64ParallelLinearSpace : LinearSpace<Double, Float64Field> { require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" } val rows = this@dot.rows.map { it.linearize() } val columns = other.columns.map { it.linearize() } - val indices = 0 until this.rowNum + val indices = 0 until this.colNum return buildMatrix(rowNum, other.colNum) { i, j -> val r = rows[i] val c = columns[j] @@ -85,7 +85,7 @@ public object Float64ParallelLinearSpace : LinearSpace<Double, Float64Field> { override fun Matrix<Double>.dot(vector: Point<Double>): Float64Buffer { require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" } val rows = this@dot.rows.map { it.linearize() } - val indices = 0 until this.rowNum + val indices = 0 until this.colNum return Float64Buffer(rowNum) { i -> val r = rows[i] var res = 0.0 diff --git a/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt b/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt new file mode 100644 index 000000000..493948361 --- /dev/null +++ b/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt @@ -0,0 +1,74 @@ +/* + * Copyright 2018-2024 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.linear + +import space.kscience.kmath.PerformancePitfall +import space.kscience.kmath.UnstableKMathAPI +import space.kscience.kmath.nd.StructureND +import space.kscience.kmath.operations.Float64Field +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertTrue + +@UnstableKMathAPI +@OptIn(PerformancePitfall::class) +@Suppress("UNUSED_VARIABLE") +class ParallelMatrixTest { + + @Test + fun testTranspose() = Float64Field.linearSpace.parallel{ + val matrix = one(3, 3) + val transposed = matrix.transposed() + assertTrue { StructureND.contentEquals(matrix, transposed) } + } + + @Test + fun testBuilder() = Float64Field.linearSpace.parallel{ + val matrix = matrix(2, 3)( + 1.0, 0.0, 0.0, + 0.0, 1.0, 2.0 + ) + + assertEquals(2.0, matrix[1, 2]) + } + + @Test + fun testMatrixExtension() = Float64Field.linearSpace.parallel{ + val transitionMatrix: Matrix<Double> = VirtualMatrix(type,6, 6) { row, col -> + when { + col == 0 -> .50 + row + 1 == col -> .50 + row == 5 && col == 5 -> 1.0 + else -> 0.0 + } + } + + infix fun Matrix<Double>.pow(power: Int): Matrix<Double> { + var res = this + repeat(power - 1) { + res = res dot this@pow + } + return res + } + + val toTenthPower = transitionMatrix pow 10 + } + + @Test + fun test2DDot() = Float64Field.linearSpace.parallel { + val firstMatrix = buildMatrix(2, 3) { i, j -> (i + j).toDouble() } + val secondMatrix = buildMatrix(3, 2) { i, j -> (i + j).toDouble() } + +// val firstMatrix = produce(2, 3) { i, j -> (i + j).toDouble() } +// val secondMatrix = produce(3, 2) { i, j -> (i + j).toDouble() } + val result = firstMatrix dot secondMatrix + assertEquals(2, result.rowNum) + assertEquals(2, result.colNum) + assertEquals(8.0, result[0, 1]) + assertEquals(8.0, result[1, 0]) + assertEquals(14.0, result[1, 1]) + } +} From 024e2a1a4f4a10fe1a74b0081383900c126fed78 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 18 Feb 2024 14:26:47 +0300 Subject: [PATCH 074/103] Add .kotlin to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 96a556ae1..030625b50 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ out/ .idea/ .vscode/ .fleet/ +.kotlin/ # Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) From fd9da63ef98f9cd75f4b21f19733fc5c9ebcbcd8 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 18 Feb 2024 15:05:56 +0300 Subject: [PATCH 075/103] Prepare for 0.4.0 release --- CHANGELOG.md | 36 +- README.md | 68 +- attributes-kt/README.md | 4 + attributes-kt/api/attributes-kt.api | 97 + attributes-kt/build.gradle.kts | 2 + .../space/kscience/attributes/Attribute.kt | 3 + .../kscience/attributes/AttributeContainer.kt | 3 +- .../space/kscience/attributes/Attributes.kt | 9 + build.gradle.kts | 6 +- docs/templates/ARTIFACT-TEMPLATE.md | 15 - docs/templates/README-TEMPLATE.md | 17 +- kmath-ast/README.md | 15 +- kmath-commons/README.md | 15 +- kmath-complex/README.md | 15 +- kmath-core/README.md | 16 +- kmath-core/api/kmath-core.api | 1672 +++++++++-------- kmath-core/build.gradle.kts | 8 + kmath-coroutines/README.md | 15 +- kmath-dimensions/README.md | 15 +- kmath-ejml/README.md | 15 +- kmath-for-real/README.md | 15 +- kmath-functions/README.md | 15 +- kmath-geometry/README.md | 15 +- kmath-histograms/README.md | 15 +- kmath-jafama/README.md | 15 +- kmath-jafama/api/kmath-jafama.api | 128 ++ kmath-jupyter/README.md | 15 +- kmath-kotlingrad/README.md | 15 +- kmath-memory/README.md | 15 +- kmath-memory/api/kmath-memory.api | 42 +- kmath-multik/README.md | 15 +- kmath-nd4j/README.md | 15 +- kmath-nd4j/api/kmath-nd4j.api | 395 ++++ kmath-optimization/README.md | 15 +- kmath-stat/README.md | 15 +- kmath-symja/README.md | 15 +- kmath-tensorflow/README.md | 15 +- kmath-tensors/README.md | 15 +- kmath-viktor/README.md | 15 +- kmath-viktor/api/kmath-viktor.api | 13 +- test-utils/api/test-utils.api | 2 +- 41 files changed, 1707 insertions(+), 1159 deletions(-) create mode 100644 attributes-kt/README.md create mode 100644 attributes-kt/api/attributes-kt.api create mode 100644 kmath-jafama/api/kmath-jafama.api create mode 100644 kmath-nd4j/api/kmath-nd4j.api diff --git a/CHANGELOG.md b/CHANGELOG.md index 07ab04fc7..d98177726 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,21 @@ ## Unreleased ### Added + +### Changed + +### Deprecated + +### Removed + +### Fixed + +### Security + +## 0.4.0-dev-3 - 2024-02-18 + +### Added + - Reification. Explicit `SafeType` for algebras and buffers. - Integer division algebras. - Float32 geometries. @@ -14,6 +29,7 @@ - Parallel buffer factories ### Changed + - Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types. - Remove unnecessary inlines in basic algebras. - QuaternionField -> QuaternionAlgebra and does not implement `Field` anymore since it is non-commutative @@ -23,22 +39,24 @@ - Kmath-memory is moved on top of core. ### Deprecated + - ND4J engine ### Removed + - `asPolynomial` function due to scope pollution - Codegend for ejml (450 lines of codegen for 1000 lines of code is too much) ### Fixed + - Median statistics - Complex power of negative real numbers - Add proper mutability for MutableBufferND rows and columns -### Security - ## 0.3.1 - 2023-04-09 ### Added + - Wasm support for `memory`, `core`, `complex` and `functions` modules. - Generic builders for `BufferND` and `MutableBufferND` - `NamedMatrix` - matrix with symbol-based indexing @@ -48,6 +66,7 @@ - Algebra now has an obligatory `bufferFactory` (#477). ### Changed + - Removed marker `Vector` type for geometry - Geometry uses type-safe angles - Tensor operations switched to prefix notation @@ -60,12 +79,14 @@ - Multik went MPP ### Removed + - Trajectory moved to https://github.com/SciProgCentre/maps-kt - Polynomials moved to https://github.com/SciProgCentre/kmath-polynomial ## 0.3.0 ### Added + - `ScaleOperations` interface - `Field` extends `ScaleOperations` - Basic integration API @@ -90,6 +111,7 @@ - Compilation to TeX for MST: #254 ### Changed + - Annotations moved to `space.kscience.kmath` - Exponential operations merged with hyperbolic functions - Space is replaced by Group. Space is reserved for vector spaces. @@ -123,9 +145,11 @@ - `UnivariateFunction` -> `Function1D`, `MultivariateFunction` -> `FunctionND` ### Deprecated + - Specialized `DoubleBufferAlgebra` ### Removed + - Nearest in Domain. To be implemented in geometry package. - Number multiplication and division in main Algebra chain - `contentEquals` from Buffer. It moved to the companion. @@ -136,12 +160,14 @@ - Algebra elements are completely removed. Use algebra contexts instead. ### Fixed + - Ring inherits RingOperations, not GroupOperations - Univariate histogram filling ## 0.2.0 ### Added + - `fun` annotation for SAM interfaces in library - Explicit `public` visibility for all public APIs - Better trigonometric and hyperbolic functions for `AutoDiffField` (https://github.com/mipt-npm/kmath/pull/140) @@ -161,6 +187,7 @@ - Basic Quaternion vector support in `kmath-complex`. ### Changed + - Package changed from `scientifik` to `space.kscience` - Gradle version: 6.6 -> 6.8.2 - Minor exceptions refactor (throwing `IllegalArgumentException` by argument checks instead of `IllegalStateException`) @@ -185,6 +212,7 @@ - Add `out` projection to `Buffer` generic ### Removed + - `kmath-koma` module because it doesn't support Kotlin 1.4. - Support of `legacy` JS backend (we will support only IR) - `toGrid` method. @@ -193,11 +221,13 @@ - StructureND identity and equals ### Fixed + - `symbol` method in `MstExtendedField` (https://github.com/mipt-npm/kmath/pull/140) ## 0.1.4 ### Added + - Functional Expressions API - Mathematical Syntax Tree, its interpreter and API - String to MST parser (https://github.com/mipt-npm/kmath/pull/120) @@ -215,6 +245,7 @@ - Norm support for `Complex` ### Changed + - `readAsMemory` now has `throws IOException` in JVM signature. - Several functions taking functional types were made `inline`. - Several functions taking functional types now have `callsInPlace` contracts. @@ -226,6 +257,7 @@ - Moved probability distributions to commons-rng and to `kmath-prob` ### Fixed + - Missing copy method in Memory implementation on JS (https://github.com/mipt-npm/kmath/pull/106) - D3.dim value in `kmath-dimensions` - Multiplication in integer rings in `kmath-core` (https://github.com/mipt-npm/kmath/pull/101) diff --git a/README.md b/README.md index 7c1f759c1..00ba00ede 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [](https://zenodo.org/badge/latestdoi/129486382)  [](https://search.maven.org/search?q=g:%22space.kscience%22) -[](https://maven.pkg.jetbrains.space/spc/p/sci/maven/space/kscience/) +[](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/) # KMath @@ -11,18 +11,21 @@ analog to Python's NumPy library. Later we found that kotlin is much more flexib architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like experience could be achieved with [kmath-for-real](/kmath-for-real) extension module. -[Documentation site (**WIP**)](https://SciProgCentre.github.io/kmath/) +[Documentation site](https://SciProgCentre.github.io/kmath/) ## Publications and talks * [A conceptual article about context-oriented design](https://proandroiddev.com/an-introduction-context-oriented-programming-in-kotlin-2e79d316b0a2) * [Another article about context-oriented design](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814) * [ACAT 2019 conference paper](https://aip.scitation.org/doi/abs/10.1063/1.5130103) +* [A talk at KotlinConf 2019 about using kotlin for science](https://youtu.be/LI_5TZ7tnOE?si=4LknX41gl_YeUbIe) +* [A talk on architecture at Joker-2021 (in Russian)](https://youtu.be/1bZ2doHiRRM?si=9w953ro9yu98X_KJ) +* [The same talk in English](https://youtu.be/yP5DIc2fVwQ?si=louZzQ1dcXV6gP10) +* [A seminar on tensor API](https://youtu.be/0H99wUs0xTM?si=6c__04jrByFQtVpo) # Goal -* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS and Native) - . +* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS, Native and Wasm). * Provide basic multiplatform implementations for those abstractions (without significant performance optimization). * Provide bindings and wrappers with those abstractions for popular optimized platform libraries. @@ -53,18 +56,20 @@ module definitions below. The module stability could have the following levels: ## Modules +### [attributes-kt](attributes-kt) +> An API and basic implementation for arranging objects in a continuous memory block. +> +> **Maturity**: DEVELOPMENT + ### [benchmarks](benchmarks) -> > > **Maturity**: EXPERIMENTAL ### [examples](examples) -> > > **Maturity**: EXPERIMENTAL ### [kmath-ast](kmath-ast) -> > > **Maturity**: EXPERIMENTAL > @@ -76,7 +81,7 @@ module definitions below. The module stability could have the following levels: ### [kmath-commons](kmath-commons) -> +> Commons math binding for kmath > > **Maturity**: EXPERIMENTAL @@ -108,17 +113,15 @@ performance calculations to code generation. ### [kmath-coroutines](kmath-coroutines) -> > > **Maturity**: EXPERIMENTAL ### [kmath-dimensions](kmath-dimensions) -> +> A proof of concept module for adding type-safe dimensions to structures > > **Maturity**: PROTOTYPE ### [kmath-ejml](kmath-ejml) -> > > **Maturity**: PROTOTYPE > @@ -142,7 +145,7 @@ One can still use generic algebras though. ### [kmath-functions](kmath-functions) -> +> Functions, integration and interpolation > > **Maturity**: EXPERIMENTAL > @@ -155,31 +158,28 @@ One can still use generic algebras though. ### [kmath-geometry](kmath-geometry) -> > > **Maturity**: PROTOTYPE ### [kmath-histograms](kmath-histograms) -> > > **Maturity**: PROTOTYPE ### [kmath-jafama](kmath-jafama) -> +> Jafama integration module > -> **Maturity**: PROTOTYPE +> **Maturity**: DEPRECATED > > **Features:** > - [jafama-double](kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama ### [kmath-jupyter](kmath-jupyter) -> > > **Maturity**: PROTOTYPE ### [kmath-kotlingrad](kmath-kotlingrad) -> +> Kotlin∇ integration module > > **Maturity**: EXPERIMENTAL > @@ -194,14 +194,14 @@ One can still use generic algebras though. > **Maturity**: DEVELOPMENT ### [kmath-multik](kmath-multik) -> +> JetBrains Multik connector > > **Maturity**: PROTOTYPE ### [kmath-nd4j](kmath-nd4j) -> +> ND4J NDStructure implementation and according NDAlgebra classes > -> **Maturity**: EXPERIMENTAL +> **Maturity**: DEPRECATED > > **Features:** > - [nd4jarraystructure](kmath-nd4j/#) : NDStructure wrapper for INDArray @@ -210,27 +210,24 @@ One can still use generic algebras though. ### [kmath-optimization](kmath-optimization) -> > > **Maturity**: EXPERIMENTAL ### [kmath-stat](kmath-stat) -> > > **Maturity**: EXPERIMENTAL ### [kmath-symja](kmath-symja) -> +> Symja integration module > > **Maturity**: PROTOTYPE ### [kmath-tensorflow](kmath-tensorflow) -> +> Google tensorflow connector > > **Maturity**: PROTOTYPE ### [kmath-tensors](kmath-tensors) -> > > **Maturity**: PROTOTYPE > @@ -241,12 +238,11 @@ One can still use generic algebras though. ### [kmath-viktor](kmath-viktor) -> +> Binding for https://github.com/JetBrains-Research/viktor > > **Maturity**: DEVELOPMENT ### [test-utils](test-utils) -> > > **Maturity**: EXPERIMENTAL @@ -256,22 +252,21 @@ One can still use generic algebras though. KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the [common source sets](/kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features are delegated to platform-specific implementations even if they could be provided in the common module for performance -reasons. Currently, the Kotlin/JVM is the primary platform, however Kotlin/Native and Kotlin/JS contributions and +reasons. Currently, Kotlin/JVM is the primary platform, however, Kotlin/Native and Kotlin/JS contributions and feedback are also welcome. ## Performance -Calculation performance is one of major goals of KMath in the future, but in some cases it is impossible to achieve both +Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to achieve both performance and flexibility. -We expect to focus on creating convenient universal API first and then work on increasing performance for specific +We expect to focus on creating a convenient universal API first and then work on increasing performance for specific cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy. ## Requirements -KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend to use GraalVM-CE 11 for -execution to get better performance. +KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or Oracle GraalVM for execution to get better performance. ### Repositories @@ -291,10 +286,7 @@ dependencies { } ``` -Gradle `6.0+` is required for multiplatform artifacts. - ## Contributing -The project requires a lot of additional work. The most important thing we need is a feedback about what features are -required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues -marked with [waiting for a hero](https://github.com/SciProgCentre/kmath/labels/waiting%20for%20a%20hero) label. \ No newline at end of file +The project requires a lot of additional work. The most important thing we need is feedback about what features are +required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues marked with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label. \ No newline at end of file diff --git a/attributes-kt/README.md b/attributes-kt/README.md new file mode 100644 index 000000000..53f80fcef --- /dev/null +++ b/attributes-kt/README.md @@ -0,0 +1,4 @@ +# Module attributes-kt + + + diff --git a/attributes-kt/api/attributes-kt.api b/attributes-kt/api/attributes-kt.api new file mode 100644 index 000000000..26386d9d7 --- /dev/null +++ b/attributes-kt/api/attributes-kt.api @@ -0,0 +1,97 @@ +public abstract interface class space/kscience/attributes/Attribute { +} + +public abstract interface class space/kscience/attributes/AttributeContainer { + public abstract fun getAttributes ()Lspace/kscience/attributes/Attributes; +} + +public abstract interface class space/kscience/attributes/AttributeScope { +} + +public abstract interface class space/kscience/attributes/AttributeWithDefault : space/kscience/attributes/Attribute { + public abstract fun getDefault ()Ljava/lang/Object; +} + +public abstract interface class space/kscience/attributes/Attributes { + public static final field Companion Lspace/kscience/attributes/Attributes$Companion; + public fun get (Lspace/kscience/attributes/Attribute;)Ljava/lang/Object; + public abstract fun getContent ()Ljava/util/Map; + public fun getKeys ()Ljava/util/Set; +} + +public final class space/kscience/attributes/Attributes$Companion { + public final fun getEMPTY ()Lspace/kscience/attributes/Attributes; +} + +public final class space/kscience/attributes/AttributesBuilder : space/kscience/attributes/Attributes { + public fun <init> ()V + public final fun add (Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)V + public final fun build ()Lspace/kscience/attributes/Attributes; + public final fun from (Lspace/kscience/attributes/Attributes;)V + public fun getContent ()Ljava/util/Map; + public final fun invoke (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V + public final fun remove (Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)V + public final fun set (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V +} + +public final class space/kscience/attributes/AttributesBuilderKt { + public static final fun Attributes (Lkotlin/jvm/functions/Function1;)Lspace/kscience/attributes/Attributes; +} + +public final class space/kscience/attributes/AttributesKt { + public static final fun Attributes (Lspace/kscience/attributes/Attribute;)Lspace/kscience/attributes/Attributes; + public static final fun Attributes (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes; + public static final fun getOrDefault (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/AttributeWithDefault;)Ljava/lang/Object; + public static final fun isEmpty (Lspace/kscience/attributes/Attributes;)Z + public static final fun modify (Lspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function1;)Lspace/kscience/attributes/Attributes; + public static final fun plus (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attributes;)Lspace/kscience/attributes/Attributes; + public static final fun withAttribute (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attribute;)Lspace/kscience/attributes/Attributes; + public static final fun withAttribute (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes; + public static final fun withAttributeElement (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes; + public static final fun withoutAttribute (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attribute;)Lspace/kscience/attributes/Attributes; + public static final fun withoutAttributeElement (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes; +} + +public abstract interface class space/kscience/attributes/FlagAttribute : space/kscience/attributes/Attribute { +} + +public abstract class space/kscience/attributes/PolymorphicAttribute : space/kscience/attributes/Attribute { + public synthetic fun <init> (Lkotlin/reflect/KType;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun equals (Ljava/lang/Object;)Z + public final fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public fun hashCode ()I +} + +public final class space/kscience/attributes/PolymorphicAttributeKt { + public static final fun get (Lspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function0;)Ljava/lang/Object; + public static final fun set (Lspace/kscience/attributes/AttributesBuilder;Lkotlin/jvm/functions/Function0;Ljava/lang/Object;)V +} + +public final class space/kscience/attributes/SafeType { + public static final synthetic fun box-impl (Lkotlin/reflect/KType;)Lspace/kscience/attributes/SafeType; + public static fun constructor-impl (Lkotlin/reflect/KType;)Lkotlin/reflect/KType; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl (Lkotlin/reflect/KType;Ljava/lang/Object;)Z + public static final fun equals-impl0 (Lkotlin/reflect/KType;Lkotlin/reflect/KType;)Z + public final fun getKType ()Lkotlin/reflect/KType; + public fun hashCode ()I + public static fun hashCode-impl (Lkotlin/reflect/KType;)I + public fun toString ()Ljava/lang/String; + public static fun toString-impl (Lkotlin/reflect/KType;)Ljava/lang/String; + public final synthetic fun unbox-impl ()Lkotlin/reflect/KType; +} + +public final class space/kscience/attributes/SafeTypeKt { + public static final fun getKClass-X0YbwmU (Lkotlin/reflect/KType;)Lkotlin/reflect/KClass; +} + +public abstract interface class space/kscience/attributes/SetAttribute : space/kscience/attributes/Attribute { +} + +public abstract interface annotation class space/kscience/attributes/UnstableAttributesAPI : java/lang/annotation/Annotation { +} + +public abstract interface class space/kscience/attributes/WithType { + public abstract fun getType-V0oMfBY ()Lkotlin/reflect/KType; +} + diff --git a/attributes-kt/build.gradle.kts b/attributes-kt/build.gradle.kts index fe422f751..f5ead84a3 100644 --- a/attributes-kt/build.gradle.kts +++ b/attributes-kt/build.gradle.kts @@ -2,6 +2,8 @@ plugins { id("space.kscience.gradle.mpp") } +version = "0.1.0" + kscience { jvm() js() diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt index dda7c6ed5..9142cafdb 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attribute.kt @@ -5,6 +5,9 @@ package space.kscience.attributes +/** + * A marker interface for an attribute. Attributes are used as keys to access contents of type [T] in the container. + */ public interface Attribute<T> /** diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt index 19e5c224a..734887bdb 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributeContainer.kt @@ -13,7 +13,8 @@ public interface AttributeContainer { } /** - * A scope, where attribute keys could be resolved + * A scope, where attribute keys could be resolved. + * [O] is used only to resolve types in compile-time. */ public interface AttributeScope<O> diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index 6c8dabc50..86d196f74 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -11,10 +11,19 @@ import kotlin.jvm.JvmInline * A set of attributes. The implementation must guarantee that [content] keys correspond to its value types. */ public interface Attributes { + /** + * Raw content for this [Attributes] + */ public val content: Map<out Attribute<*>, Any?> + /** + * Attribute keys contained in this [Attributes] + */ public val keys: Set<Attribute<*>> get() = content.keys + /** + * Provide an attribute value. Return null if attribute is not present or if its value is null. + */ @Suppress("UNCHECKED_CAST") public operator fun <T> get(attribute: Attribute<T>): T? = content[attribute] as? T diff --git a/build.gradle.kts b/build.gradle.kts index a0befa3c5..393576166 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -3,7 +3,7 @@ import space.kscience.gradle.useSPCTeam plugins { id("space.kscience.gradle.project") - id("org.jetbrains.kotlinx.kover") version "0.6.0" + id("org.jetbrains.kotlinx.kover") version "0.7.6" } allprojects { @@ -14,7 +14,7 @@ allprojects { } group = "space.kscience" - version = "0.4.0-dev-3" + version = "0.4.0" } subprojects { @@ -34,7 +34,7 @@ subprojects { localDirectory.set(kotlinDir) remoteUrl.set( - java.net.URL("https://github.com/SciProgCentre/kmath/tree/master/${this@subprojects.name}/$kotlinDirPath") + uri("https://github.com/SciProgCentre/kmath/tree/master/${this@subprojects.name}/$kotlinDirPath").toURL() ) } diff --git a/docs/templates/ARTIFACT-TEMPLATE.md b/docs/templates/ARTIFACT-TEMPLATE.md index a3e47e693..121c673fb 100644 --- a/docs/templates/ARTIFACT-TEMPLATE.md +++ b/docs/templates/ARTIFACT-TEMPLATE.md @@ -3,25 +3,10 @@ The Maven coordinates of this project are `${group}:${name}:${version}`. **Gradle:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() - // development and snapshot versions - maven { url 'https://maven.pkg.jetbrains.space/spc/p/sci/dev' } -} - -dependencies { - implementation '${group}:${name}:${version}' -} -``` -**Gradle Kotlin DSL:** ```kotlin repositories { maven("https://repo.kotlin.link") mavenCentral() - // development and snapshot versions - maven("https://maven.pkg.jetbrains.space/spc/p/sci/dev") } dependencies { diff --git a/docs/templates/README-TEMPLATE.md b/docs/templates/README-TEMPLATE.md index 8988a887e..850f63413 100644 --- a/docs/templates/README-TEMPLATE.md +++ b/docs/templates/README-TEMPLATE.md @@ -11,18 +11,21 @@ analog to Python's NumPy library. Later we found that kotlin is much more flexib architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like experience could be achieved with [kmath-for-real](/kmath-for-real) extension module. -[Documentation site (**WIP**)](https://SciProgCentre.github.io/kmath/) +[Documentation site](https://SciProgCentre.github.io/kmath/) ## Publications and talks * [A conceptual article about context-oriented design](https://proandroiddev.com/an-introduction-context-oriented-programming-in-kotlin-2e79d316b0a2) * [Another article about context-oriented design](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814) * [ACAT 2019 conference paper](https://aip.scitation.org/doi/abs/10.1063/1.5130103) +* [A talk at KotlinConf 2019 about using kotlin for science](https://youtu.be/LI_5TZ7tnOE?si=4LknX41gl_YeUbIe) +* [A talk on architecture at Joker-2021 (in Russian)](https://youtu.be/1bZ2doHiRRM?si=9w953ro9yu98X_KJ) +* [The same talk in English](https://youtu.be/yP5DIc2fVwQ?si=louZzQ1dcXV6gP10) +* [A seminar on tensor API](https://youtu.be/0H99wUs0xTM?si=6c__04jrByFQtVpo) # Goal -* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS and Native) - . +* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS, Native and Wasm). * Provide basic multiplatform implementations for those abstractions (without significant performance optimization). * Provide bindings and wrappers with those abstractions for popular optimized platform libraries. @@ -73,7 +76,7 @@ native/SciPy (mostly due to boxing operations on primitive numbers). The best pe ## Requirements -KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE 11/17 for execution to get better performance. +KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or Oracle GraalVM for execution to get better performance. ### Repositories @@ -95,7 +98,5 @@ dependencies { ## Contributing -The project requires a lot of additional work. The most important thing we need is a feedback about what features are -required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues -marked with -[good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label. \ No newline at end of file +The project requires a lot of additional work. The most important thing we need is feedback about what features are +required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues marked with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label. \ No newline at end of file diff --git a/kmath-ast/README.md b/kmath-ast/README.md index d85a18e1c..dd9978bee 100644 --- a/kmath-ast/README.md +++ b/kmath-ast/README.md @@ -10,19 +10,8 @@ Extensions to MST API: transformations, dynamic compilation and visualization. ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-ast:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-ast:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-ast:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -31,7 +20,7 @@ repositories { } dependencies { - implementation("space.kscience:kmath-ast:0.4.0-dev-1") + implementation("space.kscience:kmath-ast:0.4.0-dev-3") } ``` diff --git a/kmath-commons/README.md b/kmath-commons/README.md index 47b61c409..2b5f3146d 100644 --- a/kmath-commons/README.md +++ b/kmath-commons/README.md @@ -6,19 +6,8 @@ Commons math binding for kmath ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-commons:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-commons:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-commons:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-commons:0.4.0-dev-1") + implementation("space.kscience:kmath-commons:0.4.0-dev-3") } ``` diff --git a/kmath-complex/README.md b/kmath-complex/README.md index 4e800b7ac..eec989eb3 100644 --- a/kmath-complex/README.md +++ b/kmath-complex/README.md @@ -8,19 +8,8 @@ Complex and hypercomplex number systems in KMath. ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-complex:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-complex:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-complex:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -29,6 +18,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-complex:0.4.0-dev-1") + implementation("space.kscience:kmath-complex:0.4.0-dev-3") } ``` diff --git a/kmath-core/README.md b/kmath-core/README.md index b58105d2f..f1f42210b 100644 --- a/kmath-core/README.md +++ b/kmath-core/README.md @@ -11,23 +11,13 @@ objects to the expression by providing a context. Expressions can be used for a performance calculations to code generation. - [domains](src/commonMain/kotlin/space/kscience/kmath/domains) : Domains - [autodiff](src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation + - [linear.parallel](#) : Parallel implementation for `LinearAlgebra` ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-core:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-core:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-core:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -36,6 +26,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-core:0.4.0-dev-1") + implementation("space.kscience:kmath-core:0.4.0-dev-3") } ``` diff --git a/kmath-core/api/kmath-core.api b/kmath-core/api/kmath-core.api index 42d8277bd..0053dde28 100644 --- a/kmath-core/api/kmath-core.api +++ b/kmath-core/api/kmath-core.api @@ -1,3 +1,14 @@ +public abstract interface annotation class space/kscience/kmath/PerformancePitfall : java/lang/annotation/Annotation { + public abstract fun message ()Ljava/lang/String; +} + +public abstract interface annotation class space/kscience/kmath/UnsafeKMathAPI : java/lang/annotation/Annotation { + public abstract fun message ()Ljava/lang/String; +} + +public abstract interface annotation class space/kscience/kmath/UnstableKMathAPI : java/lang/annotation/Annotation { +} + public final class space/kscience/kmath/data/ColumnarDataKt { } @@ -41,17 +52,19 @@ public final class space/kscience/kmath/expressions/DSCompiler { public final fun getSizes ()[[I } -public final class space/kscience/kmath/expressions/DerivationResult { - public fun <init> (Ljava/lang/Object;Ljava/util/Map;Lspace/kscience/kmath/operations/Field;)V +public final class space/kscience/kmath/expressions/DerivationResult : space/kscience/attributes/WithType { + public synthetic fun <init> (Ljava/lang/Object;Lkotlin/reflect/KType;Ljava/util/Map;Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public final fun derivative (Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; public final fun div ()Ljava/lang/Object; public final fun getContext ()Lspace/kscience/kmath/operations/Field; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public final fun getValue ()Ljava/lang/Object; } public final class space/kscience/kmath/expressions/DiffExpressionWithDefault : space/kscience/kmath/expressions/DifferentiableExpression { public fun <init> (Lspace/kscience/kmath/expressions/DifferentiableExpression;Ljava/util/Map;)V public fun derivativeOrNull (Ljava/util/List;)Lspace/kscience/kmath/expressions/Expression; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun invoke (Ljava/util/Map;)Ljava/lang/Object; } @@ -71,7 +84,7 @@ public final class space/kscience/kmath/expressions/DifferentiableExpressionKt { public final class space/kscience/kmath/expressions/DoubleExpression$Companion { } -public abstract interface class space/kscience/kmath/expressions/Expression { +public abstract interface class space/kscience/kmath/expressions/Expression : space/kscience/attributes/WithType { public abstract fun invoke (Ljava/util/Map;)Ljava/lang/Object; } @@ -80,6 +93,7 @@ public abstract interface class space/kscience/kmath/expressions/ExpressionAlgeb } public final class space/kscience/kmath/expressions/ExpressionKt { + public static final fun Expression-AckJDF4 (Lkotlin/reflect/KType;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; public static final fun callByString (Lspace/kscience/kmath/expressions/Expression;[Lkotlin/Pair;)Ljava/lang/Object; public static final fun callBySymbol (Lspace/kscience/kmath/expressions/Expression;[Lkotlin/Pair;)Ljava/lang/Object; public static final fun getBinding (Lspace/kscience/kmath/expressions/ExpressionAlgebra;)Lkotlin/properties/ReadOnlyProperty; @@ -88,6 +102,7 @@ public final class space/kscience/kmath/expressions/ExpressionKt { public final class space/kscience/kmath/expressions/ExpressionWithDefault : space/kscience/kmath/expressions/Expression { public fun <init> (Lspace/kscience/kmath/expressions/Expression;Ljava/util/Map;)V + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun invoke (Ljava/util/Map;)Ljava/lang/Object; } @@ -110,11 +125,12 @@ public abstract class space/kscience/kmath/expressions/FunctionalExpressionAlgeb public synthetic fun const (Ljava/lang/Object;)Ljava/lang/Object; public fun const (Ljava/lang/Object;)Lspace/kscience/kmath/expressions/Expression; public final fun getAlgebra ()Lspace/kscience/kmath/operations/Algebra; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } public final class space/kscience/kmath/expressions/FunctionalExpressionAlgebraKt { - public static final fun expression (Lspace/kscience/kmath/operations/DoubleField;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; + public static final fun expression (Lspace/kscience/kmath/operations/Float64Field;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; public static final fun expressionInExtendedField (Lspace/kscience/kmath/operations/ExtendedField;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; public static final fun expressionInField (Lspace/kscience/kmath/operations/Field;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; public static final fun expressionInGroup (Lspace/kscience/kmath/operations/Group;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/expressions/Expression; @@ -270,6 +286,7 @@ public final class space/kscience/kmath/expressions/MstExtendedField : space/ksc public fun divide (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; public fun exp (Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Unary; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Lspace/kscience/kmath/expressions/MST$Numeric; public synthetic fun getZero ()Ljava/lang/Object; @@ -312,6 +329,7 @@ public final class space/kscience/kmath/expressions/MstField : space/kscience/km public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Symbol; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (Lspace/kscience/kmath/expressions/MST;Lspace/kscience/kmath/expressions/MST;)Lspace/kscience/kmath/expressions/MST$Binary; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Lspace/kscience/kmath/expressions/MST$Numeric; public synthetic fun getZero ()Ljava/lang/Object; @@ -338,6 +356,7 @@ public final class space/kscience/kmath/expressions/MstGroup : space/kscience/km public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Symbol; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public synthetic fun getZero ()Ljava/lang/Object; public fun getZero ()Lspace/kscience/kmath/expressions/MST$Numeric; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; @@ -360,6 +379,7 @@ public final class space/kscience/kmath/expressions/MstNumericAlgebra : space/ks public fun bindSymbol (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Symbol; public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Symbol; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/expressions/MST$Numeric; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; @@ -372,6 +392,7 @@ public final class space/kscience/kmath/expressions/MstRing : space/kscience/kma public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public synthetic fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; public fun bindSymbolOrNull (Ljava/lang/String;)Lspace/kscience/kmath/expressions/Symbol; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Lspace/kscience/kmath/expressions/MST$Numeric; public synthetic fun getZero ()Ljava/lang/Object; @@ -398,16 +419,16 @@ public final class space/kscience/kmath/expressions/NamedMatrix : space/kscience public fun get (II)Ljava/lang/Object; public final fun get (Lspace/kscience/kmath/expressions/Symbol;Lspace/kscience/kmath/expressions/Symbol;)Ljava/lang/Object; public fun get ([I)Ljava/lang/Object; + public fun getAttributes ()Lspace/kscience/attributes/Attributes; public fun getColNum ()I public fun getColumns ()Ljava/util/List; public fun getDimension ()I - public synthetic fun getFeature (Lkotlin/reflect/KClass;)Ljava/lang/Object; - public fun getFeature (Lkotlin/reflect/KClass;)Lspace/kscience/kmath/nd/StructureFeature; public final fun getIndexer ()Lspace/kscience/kmath/expressions/SymbolIndexer; public fun getIndices ()Lspace/kscience/kmath/nd/ShapeIndexer; public fun getRowNum ()I public fun getRows ()Ljava/util/List; public fun getShape-IIYLAfE ()[I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public final fun getValues ()Lspace/kscience/kmath/nd/Structure2D; } @@ -425,6 +446,7 @@ public final class space/kscience/kmath/expressions/SimpleAutoDiffExpression : s public fun derivativeOrNull (Lspace/kscience/kmath/expressions/Symbol;)Lspace/kscience/kmath/expressions/Expression; public final fun getField ()Lspace/kscience/kmath/operations/Field; public final fun getFunction ()Lkotlin/jvm/functions/Function1; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun invoke (Ljava/util/Map;)Ljava/lang/Object; } @@ -481,7 +503,8 @@ public class space/kscience/kmath/expressions/SimpleAutoDiffField : space/kscien public final fun derive (Ljava/lang/Object;Lkotlin/jvm/functions/Function2;)Ljava/lang/Object; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (Lspace/kscience/kmath/expressions/AutoDiffValue;Lspace/kscience/kmath/expressions/AutoDiffValue;)Lspace/kscience/kmath/expressions/AutoDiffValue; - public final fun getContext ()Lspace/kscience/kmath/operations/Field; + public final fun getAlgebra ()Lspace/kscience/kmath/operations/Field; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public final fun getD (Lspace/kscience/kmath/expressions/AutoDiffValue;)Ljava/lang/Object; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Lspace/kscience/kmath/expressions/AutoDiffValue; @@ -572,62 +595,117 @@ public final class space/kscience/kmath/linear/BufferedLinearSpaceKt { public static final fun getLinearSpace (Lspace/kscience/kmath/operations/Ring;)Lspace/kscience/kmath/linear/BufferedLinearSpace; } -public abstract interface class space/kscience/kmath/linear/CholeskyDecompositionFeature : space/kscience/kmath/linear/MatrixFeature { +public abstract interface class space/kscience/kmath/linear/CholeskyDecomposition { public abstract fun getL ()Lspace/kscience/kmath/nd/Structure2D; } -public abstract interface class space/kscience/kmath/linear/DeterminantFeature : space/kscience/kmath/linear/MatrixFeature { - public abstract fun getDeterminant ()Ljava/lang/Object; +public final class space/kscience/kmath/linear/CholeskyDecompositionAttribute : space/kscience/attributes/PolymorphicAttribute, space/kscience/kmath/linear/MatrixAttribute { + public fun <init> ()V } -public abstract interface class space/kscience/kmath/linear/DiagonalFeature : space/kscience/kmath/linear/MatrixFeature { - public static final field Companion Lspace/kscience/kmath/linear/DiagonalFeature$Companion; +public final class space/kscience/kmath/linear/Determinant : space/kscience/attributes/PolymorphicAttribute, space/kscience/kmath/linear/MatrixAttribute { + public synthetic fun <init> (Lkotlin/reflect/KType;Lkotlin/jvm/internal/DefaultConstructorMarker;)V } -public final class space/kscience/kmath/linear/DiagonalFeature$Companion : space/kscience/kmath/linear/DiagonalFeature { -} - -public final class space/kscience/kmath/linear/DoubleLinearSpace : space/kscience/kmath/linear/LinearSpace { - public static final field INSTANCE Lspace/kscience/kmath/linear/DoubleLinearSpace; +public final class space/kscience/kmath/linear/Float64LinearSpace : space/kscience/kmath/linear/LinearSpace { + public static final field INSTANCE Lspace/kscience/kmath/linear/Float64LinearSpace; public fun buildMatrix (IILkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/Structure2D; public synthetic fun buildVector (ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; - public fun buildVector-CZ9oacQ (ILkotlin/jvm/functions/Function2;)[D - public final fun div-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;D)[D + public fun buildVector-Vq5tpWc (ILkotlin/jvm/functions/Function2;)[D + public final fun div-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;D)[D public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; public synthetic fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun dot-CZ9oacQ (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)[D - public fun getElementAlgebra ()Lspace/kscience/kmath/operations/DoubleField; + public fun dot-Vq5tpWc (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)[D + public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Float64Field; public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Ring; public fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; public synthetic fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun minus-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public fun minus-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D public fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; public synthetic fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public fun plus-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public fun plus-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D public synthetic fun times (Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public fun times (Lspace/kscience/kmath/nd/Structure2D;D)Lspace/kscience/kmath/nd/Structure2D; public synthetic fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D; public synthetic fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer; - public fun times-CZ9oacQ (DLspace/kscience/kmath/structures/Buffer;)[D - public fun times-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;D)[D + public fun times-Vq5tpWc (DLspace/kscience/kmath/structures/Buffer;)[D + public fun times-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;D)[D public fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; } -public final class space/kscience/kmath/linear/DoubleLinearSpaceKt { - public static final fun getLinearSpace (Lspace/kscience/kmath/operations/DoubleField;)Lspace/kscience/kmath/linear/DoubleLinearSpace; +public final class space/kscience/kmath/linear/Float64LinearSpaceKt { + public static final fun getLinearSpace (Lspace/kscience/kmath/operations/Float64Field;)Lspace/kscience/kmath/linear/Float64LinearSpace; } -public abstract interface class space/kscience/kmath/linear/InverseMatrixFeature : space/kscience/kmath/linear/MatrixFeature { - public abstract fun getInverse ()Lspace/kscience/kmath/nd/Structure2D; +public final class space/kscience/kmath/linear/Float64ParallelLinearSpace : space/kscience/kmath/linear/LinearSpace { + public static final field INSTANCE Lspace/kscience/kmath/linear/Float64ParallelLinearSpace; + public fun buildMatrix (IILkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/Structure2D; + public synthetic fun buildVector (ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; + public fun buildVector-Vq5tpWc (ILkotlin/jvm/functions/Function2;)[D + public final fun div-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;D)[D + public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; + public synthetic fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun dot-Vq5tpWc (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)[D + public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Float64Field; + public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Ring; + public fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; + public synthetic fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun minus-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; + public synthetic fun plus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun plus-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun times (Ljava/lang/Object;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public fun times (Lspace/kscience/kmath/nd/Structure2D;D)Lspace/kscience/kmath/nd/Structure2D; + public synthetic fun times (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D; + public synthetic fun times (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer; + public fun times-Vq5tpWc (DLspace/kscience/kmath/structures/Buffer;)[D + public fun times-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;D)[D + public fun unaryMinus (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; } -public final class space/kscience/kmath/linear/LFeature : space/kscience/kmath/linear/MatrixFeature { - public static final field INSTANCE Lspace/kscience/kmath/linear/LFeature; +public final class space/kscience/kmath/linear/Float64ParallelLinearSpaceKt { + public static final fun getParallel (Lspace/kscience/kmath/linear/Float64LinearSpace;)Lspace/kscience/kmath/linear/Float64ParallelLinearSpace; } -public abstract interface class space/kscience/kmath/linear/LUDecompositionFeature : space/kscience/kmath/linear/MatrixFeature { - public abstract fun getL ()Lspace/kscience/kmath/nd/Structure2D; - public abstract fun getU ()Lspace/kscience/kmath/nd/Structure2D; +public final class space/kscience/kmath/linear/GenericLupDecomposition : space/kscience/kmath/linear/LupDecomposition { + public synthetic fun <init> (Lspace/kscience/kmath/operations/Field;Lspace/kscience/kmath/nd/Structure2D;[IZLkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun getDeterminant ()Ljava/lang/Object; + public final fun getElementAlgebra ()Lspace/kscience/kmath/operations/Field; + public fun getL ()Lspace/kscience/kmath/nd/Structure2D; + public fun getPivot-M_oXE9g ()[I + public fun getU ()Lspace/kscience/kmath/nd/Structure2D; +} + +public final class space/kscience/kmath/linear/Inverted : space/kscience/attributes/PolymorphicAttribute, space/kscience/kmath/linear/MatrixAttribute { + public fun <init> ()V +} + +public abstract interface class space/kscience/kmath/linear/IsDiagonal : space/kscience/attributes/FlagAttribute, space/kscience/kmath/linear/MatrixAttribute { + public static final field Companion Lspace/kscience/kmath/linear/IsDiagonal$Companion; +} + +public final class space/kscience/kmath/linear/IsDiagonal$Companion : space/kscience/kmath/linear/IsDiagonal { +} + +public final class space/kscience/kmath/linear/IsUnit : space/kscience/kmath/linear/IsDiagonal { + public static final field INSTANCE Lspace/kscience/kmath/linear/IsUnit; +} + +public final class space/kscience/kmath/linear/IsZero : space/kscience/kmath/linear/IsDiagonal { + public static final field INSTANCE Lspace/kscience/kmath/linear/IsZero; +} + +public final class space/kscience/kmath/linear/LUDecomposition { + public fun <init> (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)V + public final fun component1 ()Lspace/kscience/kmath/nd/Structure2D; + public final fun component2 ()Lspace/kscience/kmath/nd/Structure2D; + public final fun copy (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/linear/LUDecomposition; + public static synthetic fun copy$default (Lspace/kscience/kmath/linear/LUDecomposition;Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;ILjava/lang/Object;)Lspace/kscience/kmath/linear/LUDecomposition; + public fun equals (Ljava/lang/Object;)Z + public final fun getL ()Lspace/kscience/kmath/nd/Structure2D; + public final fun getU ()Lspace/kscience/kmath/nd/Structure2D; + public fun hashCode ()I + public fun toString ()Ljava/lang/String; } public abstract interface class space/kscience/kmath/linear/LinearSolver { @@ -636,13 +714,15 @@ public abstract interface class space/kscience/kmath/linear/LinearSolver { public fun solve (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; } -public abstract interface class space/kscience/kmath/linear/LinearSpace { +public abstract interface class space/kscience/kmath/linear/LinearSpace : space/kscience/kmath/linear/MatrixScope { public static final field Companion Lspace/kscience/kmath/linear/LinearSpace$Companion; public abstract fun buildMatrix (IILkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/Structure2D; public abstract fun buildVector (ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; + public fun computeAttribute (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/StructureAttribute;)Ljava/lang/Object; public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; public fun dot (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public abstract fun getElementAlgebra ()Lspace/kscience/kmath/operations/Ring; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun minus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; public fun minus (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; @@ -665,39 +745,54 @@ public final class space/kscience/kmath/linear/LinearSpaceKt { public static final fun invoke (Lspace/kscience/kmath/linear/LinearSpace;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; } -public final class space/kscience/kmath/linear/LupDecomposition : space/kscience/kmath/linear/DeterminantFeature, space/kscience/kmath/linear/LupDecompositionFeature { - public fun <init> (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/operations/Field;Lspace/kscience/kmath/nd/Structure2D;[IZ)V - public final fun getContext ()Lspace/kscience/kmath/linear/LinearSpace; - public fun getDeterminant ()Ljava/lang/Object; - public final fun getElementContext ()Lspace/kscience/kmath/operations/Field; - public fun getL ()Lspace/kscience/kmath/nd/Structure2D; - public final fun getLu ()Lspace/kscience/kmath/nd/Structure2D; - public fun getP ()Lspace/kscience/kmath/nd/Structure2D; - public final fun getPivot ()[I - public fun getU ()Lspace/kscience/kmath/nd/Structure2D; +public final class space/kscience/kmath/linear/LowerTriangular : space/kscience/attributes/FlagAttribute, space/kscience/kmath/linear/MatrixAttribute { + public static final field INSTANCE Lspace/kscience/kmath/linear/LowerTriangular; } -public abstract interface class space/kscience/kmath/linear/LupDecompositionFeature : space/kscience/kmath/linear/MatrixFeature { +public final class space/kscience/kmath/linear/LuDecompositionAttribute : space/kscience/attributes/PolymorphicAttribute, space/kscience/kmath/linear/MatrixAttribute { + public fun <init> ()V +} + +public abstract interface class space/kscience/kmath/linear/LupDecomposition { public abstract fun getL ()Lspace/kscience/kmath/nd/Structure2D; - public abstract fun getP ()Lspace/kscience/kmath/nd/Structure2D; + public abstract fun getPivot-M_oXE9g ()[I public abstract fun getU ()Lspace/kscience/kmath/nd/Structure2D; } +public final class space/kscience/kmath/linear/LupDecompositionAttribute : space/kscience/attributes/PolymorphicAttribute, space/kscience/kmath/linear/MatrixAttribute { + public fun <init> ()V +} + public final class space/kscience/kmath/linear/LupDecompositionKt { public static final fun abs (Lspace/kscience/kmath/linear/LinearSpace;Ljava/lang/Comparable;)Ljava/lang/Comparable; - public static final fun lup (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;D)Lspace/kscience/kmath/linear/LupDecomposition; - public static final fun lup (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/MutableBufferFactory;Lspace/kscience/kmath/nd/Structure2D;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/linear/LupDecomposition; - public static synthetic fun lup$default (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/Structure2D;DILjava/lang/Object;)Lspace/kscience/kmath/linear/LupDecomposition; + public static final fun getLUP (Lspace/kscience/kmath/linear/MatrixScope;)Lspace/kscience/kmath/linear/LupDecompositionAttribute; + public static final fun lup (Lspace/kscience/kmath/operations/Field;Lspace/kscience/kmath/nd/Structure2D;D)Lspace/kscience/kmath/linear/GenericLupDecomposition; + public static final fun lup (Lspace/kscience/kmath/operations/Field;Lspace/kscience/kmath/nd/Structure2D;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/linear/GenericLupDecomposition; + public static synthetic fun lup$default (Lspace/kscience/kmath/operations/Field;Lspace/kscience/kmath/nd/Structure2D;DILjava/lang/Object;)Lspace/kscience/kmath/linear/GenericLupDecomposition; public static final fun lupSolver (Lspace/kscience/kmath/linear/LinearSpace;D)Lspace/kscience/kmath/linear/LinearSolver; - public static final fun lupSolver (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/structures/MutableBufferFactory;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/linear/LinearSolver; + public static final fun lupSolver (Lspace/kscience/kmath/linear/LinearSpace;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/linear/LinearSolver; public static synthetic fun lupSolver$default (Lspace/kscience/kmath/linear/LinearSpace;DILjava/lang/Object;)Lspace/kscience/kmath/linear/LinearSolver; + public static final fun pivotMatrix (Lspace/kscience/kmath/linear/LupDecomposition;Lspace/kscience/kmath/linear/LinearSpace;)Lspace/kscience/kmath/nd/Structure2D; } -public final class space/kscience/kmath/linear/MatrixBuilder { +public abstract interface class space/kscience/kmath/linear/MatrixAttribute : space/kscience/kmath/nd/StructureAttribute { +} + +public final class space/kscience/kmath/linear/MatrixAttributesKt { + public static final fun getCholesky (Lspace/kscience/kmath/linear/MatrixScope;)Lspace/kscience/kmath/linear/CholeskyDecompositionAttribute; + public static final fun getDeterminant (Lspace/kscience/kmath/linear/MatrixScope;)Lspace/kscience/kmath/linear/Determinant; + public static final fun getInverted (Lspace/kscience/kmath/linear/MatrixScope;)Lspace/kscience/kmath/linear/Inverted; + public static final fun getLU (Lspace/kscience/kmath/linear/MatrixScope;)Lspace/kscience/kmath/linear/LuDecompositionAttribute; + public static final fun getQR (Lspace/kscience/kmath/linear/MatrixScope;)Lspace/kscience/kmath/linear/QRDecompositionAttribute; + public static final fun getSVD (Lspace/kscience/kmath/linear/MatrixScope;)Lspace/kscience/kmath/linear/SVDAttribute; +} + +public final class space/kscience/kmath/linear/MatrixBuilder : space/kscience/attributes/WithType { public fun <init> (Lspace/kscience/kmath/linear/LinearSpace;II)V public final fun getColumns ()I public final fun getLinearSpace ()Lspace/kscience/kmath/linear/LinearSpace; public final fun getRows ()I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public final fun invoke ([Ljava/lang/Object;)Lspace/kscience/kmath/nd/Structure2D; } @@ -709,88 +804,95 @@ public final class space/kscience/kmath/linear/MatrixBuilderKt { public static final fun symmetric (Lspace/kscience/kmath/linear/MatrixBuilder;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/Structure2D; } -public abstract interface class space/kscience/kmath/linear/MatrixFeature : space/kscience/kmath/nd/StructureFeature { -} - -public final class space/kscience/kmath/linear/MatrixFeaturesKt { - public static final fun DeterminantFeature (Ljava/lang/Object;)Lspace/kscience/kmath/linear/DeterminantFeature; +public abstract interface class space/kscience/kmath/linear/MatrixScope : space/kscience/attributes/AttributeScope, space/kscience/attributes/WithType { } public final class space/kscience/kmath/linear/MatrixWrapper : space/kscience/kmath/nd/Structure2D { public fun elements ()Lkotlin/sequences/Sequence; public fun get (II)Ljava/lang/Object; public fun get ([I)Ljava/lang/Object; + public fun getAttributes ()Lspace/kscience/attributes/Attributes; public fun getColNum ()I public fun getColumns ()Ljava/util/List; public fun getDimension ()I - public synthetic fun getFeature (Lkotlin/reflect/KClass;)Ljava/lang/Object; - public fun getFeature (Lkotlin/reflect/KClass;)Lspace/kscience/kmath/nd/StructureFeature; - public final fun getFeatures-En6fw3w ()Ljava/util/Map; public fun getIndices ()Lspace/kscience/kmath/nd/ShapeIndexer; public final fun getOrigin ()Lspace/kscience/kmath/nd/Structure2D; public fun getRowNum ()I public fun getRows ()Ljava/util/List; public fun getShape-IIYLAfE ()[I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun toString ()Ljava/lang/String; } public final class space/kscience/kmath/linear/MatrixWrapperKt { - public static final fun one (Lspace/kscience/kmath/linear/LinearSpace;II)Lspace/kscience/kmath/nd/Structure2D; - public static final fun plus (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/linear/MatrixFeature;)Lspace/kscience/kmath/linear/MatrixWrapper; - public static final fun transpose (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; - public static final fun withFeature (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/kmath/linear/MatrixFeature;)Lspace/kscience/kmath/linear/MatrixWrapper; - public static final fun withFeatures (Lspace/kscience/kmath/nd/Structure2D;Ljava/lang/Iterable;)Lspace/kscience/kmath/linear/MatrixWrapper; - public static final fun zero (Lspace/kscience/kmath/linear/LinearSpace;II)Lspace/kscience/kmath/nd/Structure2D; + public static final fun modifyAttributes (Lspace/kscience/kmath/nd/Structure2D;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/linear/MatrixWrapper; + public static final fun one (Lspace/kscience/kmath/linear/LinearSpace;II)Lspace/kscience/kmath/linear/MatrixWrapper; + public static final fun withAttribute (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/attributes/Attribute;)Lspace/kscience/kmath/linear/MatrixWrapper; + public static final fun withAttribute (Lspace/kscience/kmath/nd/Structure2D;Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)Lspace/kscience/kmath/linear/MatrixWrapper; + public static final fun zero (Lspace/kscience/kmath/linear/LinearSpace;II)Lspace/kscience/kmath/linear/MatrixWrapper; } -public final class space/kscience/kmath/linear/OrthogonalFeature : space/kscience/kmath/linear/MatrixFeature { - public static final field INSTANCE Lspace/kscience/kmath/linear/OrthogonalFeature; +public final class space/kscience/kmath/linear/OrthogonalAttribute : space/kscience/attributes/FlagAttribute, space/kscience/kmath/linear/MatrixAttribute { + public static final field INSTANCE Lspace/kscience/kmath/linear/OrthogonalAttribute; } -public abstract interface class space/kscience/kmath/linear/QRDecompositionFeature : space/kscience/kmath/linear/MatrixFeature { +public abstract interface class space/kscience/kmath/linear/QRDecomposition { public abstract fun getQ ()Lspace/kscience/kmath/nd/Structure2D; public abstract fun getR ()Lspace/kscience/kmath/nd/Structure2D; } -public abstract interface class space/kscience/kmath/linear/SingularValueDecompositionFeature : space/kscience/kmath/linear/MatrixFeature { +public final class space/kscience/kmath/linear/QRDecompositionAttribute : space/kscience/attributes/PolymorphicAttribute, space/kscience/kmath/linear/MatrixAttribute { + public fun <init> ()V +} + +public final class space/kscience/kmath/linear/SVDAttribute : space/kscience/attributes/PolymorphicAttribute, space/kscience/kmath/linear/MatrixAttribute { + public fun <init> ()V +} + +public abstract interface class space/kscience/kmath/linear/SingularValueDecomposition { public abstract fun getS ()Lspace/kscience/kmath/nd/Structure2D; public abstract fun getSingularValues ()Lspace/kscience/kmath/structures/Buffer; public abstract fun getU ()Lspace/kscience/kmath/nd/Structure2D; public abstract fun getV ()Lspace/kscience/kmath/nd/Structure2D; } -public final class space/kscience/kmath/linear/SymmetricMatrixFeature : space/kscience/kmath/linear/MatrixFeature { - public static final field INSTANCE Lspace/kscience/kmath/linear/SymmetricMatrixFeature; +public final class space/kscience/kmath/linear/Symmetric : space/kscience/attributes/FlagAttribute, space/kscience/kmath/linear/MatrixAttribute { + public static final field INSTANCE Lspace/kscience/kmath/linear/Symmetric; } -public final class space/kscience/kmath/linear/TransposedFeature : space/kscience/kmath/linear/MatrixFeature { +public final class space/kscience/kmath/linear/TransposedKt { + public static final fun transposed (Lspace/kscience/kmath/nd/Structure2D;)Lspace/kscience/kmath/nd/Structure2D; +} + +public final class space/kscience/kmath/linear/TransposedMatrix : space/kscience/kmath/nd/Structure2D { public fun <init> (Lspace/kscience/kmath/nd/Structure2D;)V - public final fun getOriginal ()Lspace/kscience/kmath/nd/Structure2D; + public fun get (II)Ljava/lang/Object; + public fun getAttributes ()Lspace/kscience/attributes/Attributes; + public fun getColNum ()I + public final fun getOrigin ()Lspace/kscience/kmath/nd/Structure2D; + public fun getRowNum ()I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } -public final class space/kscience/kmath/linear/UFeature : space/kscience/kmath/linear/MatrixFeature { - public static final field INSTANCE Lspace/kscience/kmath/linear/UFeature; -} - -public final class space/kscience/kmath/linear/UnitFeature : space/kscience/kmath/linear/DiagonalFeature { - public static final field INSTANCE Lspace/kscience/kmath/linear/UnitFeature; +public final class space/kscience/kmath/linear/UpperTriangular : space/kscience/attributes/FlagAttribute, space/kscience/kmath/linear/MatrixAttribute { + public static final field INSTANCE Lspace/kscience/kmath/linear/UpperTriangular; } public final class space/kscience/kmath/linear/VirtualMatrix : space/kscience/kmath/nd/Structure2D { - public fun <init> (IILkotlin/jvm/functions/Function2;)V + public synthetic fun <init> (Lkotlin/reflect/KType;IILspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun <init> (Lkotlin/reflect/KType;IILspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun get (II)Ljava/lang/Object; + public fun getAttributes ()Lspace/kscience/attributes/Attributes; public fun getColNum ()I public final fun getGenerator ()Lkotlin/jvm/functions/Function2; public fun getRowNum ()I public fun getShape-IIYLAfE ()[I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public final class space/kscience/kmath/linear/VirtualMatrixKt { - public static final fun virtual (Lspace/kscience/kmath/linear/MatrixBuilder;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/linear/VirtualMatrix; -} - -public final class space/kscience/kmath/linear/ZeroFeature : space/kscience/kmath/linear/DiagonalFeature { - public static final field INSTANCE Lspace/kscience/kmath/linear/ZeroFeature; + public static final fun virtual (Lspace/kscience/kmath/linear/MatrixBuilder;Lspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/linear/VirtualMatrix; + public static synthetic fun virtual$default (Lspace/kscience/kmath/linear/MatrixBuilder;Lspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function2;ILjava/lang/Object;)Lspace/kscience/kmath/linear/VirtualMatrix; } public final class space/kscience/kmath/misc/CollectionsKt { @@ -818,42 +920,6 @@ public final class space/kscience/kmath/misc/CumulativeKt { public static final fun cumulativeSumOfLong (Lkotlin/sequences/Sequence;)Lkotlin/sequences/Sequence; } -public abstract interface class space/kscience/kmath/misc/Feature { - public fun getKey ()Lkotlin/reflect/KClass; -} - -public final class space/kscience/kmath/misc/FeatureSet : space/kscience/kmath/misc/Featured { - public static final field Companion Lspace/kscience/kmath/misc/FeatureSet$Companion; - public static final synthetic fun box-impl (Ljava/util/Map;)Lspace/kscience/kmath/misc/FeatureSet; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Ljava/util/Map;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Ljava/util/Map;Ljava/util/Map;)Z - public synthetic fun getFeature (Lkotlin/reflect/KClass;)Ljava/lang/Object; - public fun getFeature (Lkotlin/reflect/KClass;)Lspace/kscience/kmath/misc/Feature; - public static fun getFeature-impl (Ljava/util/Map;Lkotlin/reflect/KClass;)Lspace/kscience/kmath/misc/Feature; - public final fun getFeatures ()Ljava/util/Map; - public fun hashCode ()I - public static fun hashCode-impl (Ljava/util/Map;)I - public static final fun iterator-impl (Ljava/util/Map;)Ljava/util/Iterator; - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Ljava/util/Map;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Ljava/util/Map; - public static final fun with-JVE9-Rk (Ljava/util/Map;Ljava/lang/Iterable;)Ljava/util/Map; - public static final fun with-JVE9-Rk (Ljava/util/Map;[Lspace/kscience/kmath/misc/Feature;)Ljava/util/Map; - public static final fun with-YU1a0hQ (Ljava/util/Map;Ljava/util/Map;)Ljava/util/Map; - public static final fun with-h58Sd8I (Ljava/util/Map;Lspace/kscience/kmath/misc/Feature;Lkotlin/reflect/KClass;)Ljava/util/Map; - public static synthetic fun with-h58Sd8I$default (Ljava/util/Map;Lspace/kscience/kmath/misc/Feature;Lkotlin/reflect/KClass;ILjava/lang/Object;)Ljava/util/Map; -} - -public final class space/kscience/kmath/misc/FeatureSet$Companion { - public final fun of-JVE9-Rk (Ljava/lang/Iterable;)Ljava/util/Map; - public final fun of-JVE9-Rk ([Lspace/kscience/kmath/misc/Feature;)Ljava/util/Map; -} - -public abstract interface class space/kscience/kmath/misc/Featured { - public abstract fun getFeature (Lkotlin/reflect/KClass;)Ljava/lang/Object; -} - public abstract interface class space/kscience/kmath/misc/Loggable { public static final field Companion Lspace/kscience/kmath/misc/Loggable$Companion; public static final field INFO Ljava/lang/String; @@ -879,6 +945,7 @@ public final class space/kscience/kmath/misc/SortingKt { public static final fun sortedBy (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; public static final fun sortedByDescending (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; public static final fun sortedDescending (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public static final fun sortedWith (Lspace/kscience/kmath/structures/Buffer;Ljava/util/Comparator;)Lspace/kscience/kmath/structures/Buffer; } public abstract interface class space/kscience/kmath/nd/AlgebraND : space/kscience/kmath/operations/Algebra { @@ -887,7 +954,8 @@ public abstract interface class space/kscience/kmath/nd/AlgebraND : space/kscien public fun invoke (Lkotlin/jvm/functions/Function1;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; public fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; public fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; - public abstract fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public abstract fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; public fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; } @@ -895,6 +963,7 @@ public final class space/kscience/kmath/nd/AlgebraND$Companion { } public final class space/kscience/kmath/nd/AlgebraNDExtentionsKt { + public static final fun mutableStructureND (Lspace/kscience/kmath/nd/AlgebraND;I[ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableStructureND; public static final fun one-waz_sdI (Lspace/kscience/kmath/nd/AlgebraND;[I)Lspace/kscience/kmath/nd/StructureND; public static final fun oneVarArg (Lspace/kscience/kmath/nd/AlgebraND;I[I)Lspace/kscience/kmath/nd/StructureND; public static final fun structureND (Lspace/kscience/kmath/nd/AlgebraND;I[ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; @@ -911,6 +980,8 @@ public abstract interface class space/kscience/kmath/nd/BufferAlgebraND : space/ public synthetic fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; public fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/BufferND; public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableBufferND; + public synthetic fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableStructureND; public fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; public synthetic fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; public fun toBufferND (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; @@ -927,6 +998,7 @@ public final class space/kscience/kmath/nd/BufferAlgebraNDKt { public static final fun getNd (Lspace/kscience/kmath/operations/BufferAlgebra;)Lspace/kscience/kmath/nd/BufferedGroupNDOps; public static final fun getNd (Lspace/kscience/kmath/operations/BufferAlgebra;)Lspace/kscience/kmath/nd/BufferedRingOpsND; public static final fun mapInline (Lspace/kscience/kmath/nd/BufferAlgebraND;Lspace/kscience/kmath/nd/BufferND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; + public static final fun mutableStructureND (Lspace/kscience/kmath/nd/BufferAlgebraND;[ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableBufferND; public static final fun structureND (Lspace/kscience/kmath/nd/BufferAlgebraND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; public static final fun structureND (Lspace/kscience/kmath/nd/BufferAlgebraND;[ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; } @@ -937,16 +1009,10 @@ public class space/kscience/kmath/nd/BufferND : space/kscience/kmath/nd/Structur public fun getBuffer ()Lspace/kscience/kmath/structures/Buffer; public fun getIndices ()Lspace/kscience/kmath/nd/ShapeIndexer; public fun getShape-IIYLAfE ()[I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun toString ()Ljava/lang/String; } -public final class space/kscience/kmath/nd/BufferNDKt { - public static final fun BufferND-bYNkpeI ([ILspace/kscience/kmath/structures/BufferFactory;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; - public static synthetic fun BufferND-bYNkpeI$default ([ILspace/kscience/kmath/structures/BufferFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/BufferND; - public static final fun MutableBufferND-bYNkpeI ([ILspace/kscience/kmath/structures/MutableBufferFactory;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/MutableBufferND; - public static synthetic fun MutableBufferND-bYNkpeI$default ([ILspace/kscience/kmath/structures/MutableBufferFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/MutableBufferND; -} - public class space/kscience/kmath/nd/BufferedFieldOpsND : space/kscience/kmath/nd/BufferedRingOpsND, space/kscience/kmath/nd/FieldOpsND { public fun <init> (Lspace/kscience/kmath/operations/BufferAlgebra;Lkotlin/jvm/functions/Function1;)V public synthetic fun <init> (Lspace/kscience/kmath/operations/BufferAlgebra;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -961,6 +1027,7 @@ public class space/kscience/kmath/nd/BufferedGroupNDOps : space/kscience/kmath/n public synthetic fun <init> (Lspace/kscience/kmath/operations/BufferAlgebra;Lkotlin/jvm/functions/Function1;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun getBufferAlgebra ()Lspace/kscience/kmath/operations/BufferAlgebra; public fun getIndexerBuilder ()Lkotlin/jvm/functions/Function1; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; public fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; } @@ -983,137 +1050,6 @@ public final class space/kscience/kmath/nd/ColumnStrides : space/kscience/kmath/ public final class space/kscience/kmath/nd/ColumnStrides$Companion { } -public final class space/kscience/kmath/nd/DoubleBufferND : space/kscience/kmath/nd/MutableBufferND, space/kscience/kmath/nd/MutableStructureNDOfDouble { - public synthetic fun <init> (Lspace/kscience/kmath/nd/ShapeIndexer;[DLkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun getBuffer ()Lspace/kscience/kmath/structures/Buffer; - public synthetic fun getBuffer ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun getBuffer-Dv3HvWU ()[D - public fun getDouble ([I)D - public fun setDouble ([ID)V -} - -public final class space/kscience/kmath/nd/DoubleFieldND : space/kscience/kmath/nd/DoubleFieldOpsND, space/kscience/kmath/nd/FieldND, space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/NumbersAddOps { - public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public fun getShape-IIYLAfE ()[I - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun power (Ljava/lang/Object;I)Ljava/lang/Object; - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun power (Lspace/kscience/kmath/nd/StructureND;I)Lspace/kscience/kmath/nd/DoubleBufferND; - public fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun power-Qn1smSk (Ljava/lang/Object;I)Ljava/lang/Object; - public fun power-Qn1smSk (Lspace/kscience/kmath/nd/StructureND;I)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; -} - -public final class space/kscience/kmath/nd/DoubleFieldNDKt { - public static final fun getNdAlgebra (Lspace/kscience/kmath/operations/DoubleField;)Lspace/kscience/kmath/nd/DoubleFieldOpsND; - public static final fun ndAlgebra (Lspace/kscience/kmath/operations/DoubleField;[I)Lspace/kscience/kmath/nd/DoubleFieldND; - public static final fun ndAlgebra-waz_sdI (Lspace/kscience/kmath/operations/DoubleField;[I)Lspace/kscience/kmath/nd/DoubleFieldND; -} - -public abstract class space/kscience/kmath/nd/DoubleFieldOpsND : space/kscience/kmath/nd/BufferedFieldOpsND, space/kscience/kmath/operations/ExtendedFieldOps, space/kscience/kmath/operations/ScaleOperations { - public static final field Companion Lspace/kscience/kmath/nd/DoubleFieldOpsND$Companion; - public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; - public fun acos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; - public fun asin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; - public fun atan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; - public fun cos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public fun div (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public fun div (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/DoubleBufferND; - public fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; - public fun div (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun divide (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun divide (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; - public fun exp (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; - public fun ln (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; - public synthetic fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; - protected final fun mapInline (Lspace/kscience/kmath/nd/DoubleBufferND;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/DoubleBufferND; - public fun minus (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public fun minus (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; - public fun minus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun multiply (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public fun plus (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public fun plus (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; - public fun plus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; - public fun sin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; - public fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Ljava/lang/Number;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/DoubleBufferND; - public fun times (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun toBufferND (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; - public fun toBufferND (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public synthetic fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; - public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryPlus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/DoubleBufferND; - public fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/BufferND; - public synthetic fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; -} - -public final class space/kscience/kmath/nd/DoubleFieldOpsND$Companion : space/kscience/kmath/nd/DoubleFieldOpsND { -} - public abstract interface class space/kscience/kmath/nd/FieldND : space/kscience/kmath/nd/FieldOpsND, space/kscience/kmath/nd/RingND, space/kscience/kmath/nd/WithShape, space/kscience/kmath/operations/Field { public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Lspace/kscience/kmath/nd/StructureND; @@ -1128,6 +1064,138 @@ public abstract interface class space/kscience/kmath/nd/FieldOpsND : space/kscie public fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; } +public abstract class space/kscience/kmath/nd/Floa64FieldOpsND : space/kscience/kmath/nd/BufferedFieldOpsND, space/kscience/kmath/operations/ExtendedFieldOps, space/kscience/kmath/operations/ScaleOperations { + public static final field Companion Lspace/kscience/kmath/nd/Floa64FieldOpsND$Companion; + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public fun div (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun div (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/Float64BufferND; + public fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun div (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun divide (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun exp (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun ln (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + protected final fun mapInline (Lspace/kscience/kmath/nd/Float64BufferND;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/Float64BufferND; + public fun minus (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun minus (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun minus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun multiply (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableBufferND; + public synthetic fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun plus (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object; + public fun times (Ljava/lang/Number;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Float64BufferND; + public fun times (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun toBufferND (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/BufferND; + public fun toBufferND (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryPlus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/BufferND; + public synthetic fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; +} + +public final class space/kscience/kmath/nd/Floa64FieldOpsND$Companion : space/kscience/kmath/nd/Floa64FieldOpsND { +} + +public final class space/kscience/kmath/nd/Float64BufferND : space/kscience/kmath/nd/MutableBufferND, space/kscience/kmath/nd/MutableStructureNDOfDouble { + public synthetic fun <init> (Lspace/kscience/kmath/nd/ShapeIndexer;[DLkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun getBuffer ()Lspace/kscience/kmath/structures/Buffer; + public synthetic fun getBuffer ()Lspace/kscience/kmath/structures/MutableBuffer; + public fun getBuffer-E20IKn8 ()[D + public fun getDouble ([I)D + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public fun setDouble ([ID)V +} + +public final class space/kscience/kmath/nd/Float64FieldND : space/kscience/kmath/nd/Floa64FieldOpsND, space/kscience/kmath/nd/FieldND, space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/NumbersAddOps { + public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public fun getShape-IIYLAfE ()[I + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun power (Ljava/lang/Object;I)Ljava/lang/Object; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power (Lspace/kscience/kmath/nd/StructureND;I)Lspace/kscience/kmath/nd/Float64BufferND; + public fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun power-Qn1smSk (Ljava/lang/Object;I)Ljava/lang/Object; + public fun power-Qn1smSk (Lspace/kscience/kmath/nd/StructureND;I)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Float64BufferND; +} + +public final class space/kscience/kmath/nd/Float64FieldNDKt { + public static final fun getNdAlgebra (Lspace/kscience/kmath/operations/Float64Field;)Lspace/kscience/kmath/nd/Floa64FieldOpsND; + public static final fun ndAlgebra (Lspace/kscience/kmath/operations/Float64Field;[I)Lspace/kscience/kmath/nd/Float64FieldND; + public static final fun ndAlgebra-waz_sdI (Lspace/kscience/kmath/operations/Float64Field;[I)Lspace/kscience/kmath/nd/Float64FieldND; +} + public abstract interface class space/kscience/kmath/nd/GroupND : space/kscience/kmath/nd/GroupOpsND, space/kscience/kmath/nd/WithShape, space/kscience/kmath/operations/Group { public synthetic fun getZero ()Ljava/lang/Object; public fun getZero ()Lspace/kscience/kmath/nd/StructureND; @@ -1137,6 +1205,7 @@ public abstract interface class space/kscience/kmath/nd/GroupOpsND : space/kscie public static final field Companion Lspace/kscience/kmath/nd/GroupOpsND$Companion; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; public fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; public fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; @@ -1152,11 +1221,29 @@ public final class space/kscience/kmath/nd/IndexOutOfShapeException : java/lang/ public final fun getShape-IIYLAfE ()[I } +public final class space/kscience/kmath/nd/Int16RingND : space/kscience/kmath/nd/Int16RingOpsND, space/kscience/kmath/nd/RingND, space/kscience/kmath/operations/NumbersAddOps { + public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getShape-IIYLAfE ()[I + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/BufferND; +} + +public final class space/kscience/kmath/nd/Int16RingNDKt { + public static final fun withNdAlgebra (Lspace/kscience/kmath/operations/Int16Ring;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; +} + +public abstract class space/kscience/kmath/nd/Int16RingOpsND : space/kscience/kmath/nd/BufferedRingOpsND { + public static final field Companion Lspace/kscience/kmath/nd/Int16RingOpsND$Companion; +} + +public final class space/kscience/kmath/nd/Int16RingOpsND$Companion : space/kscience/kmath/nd/Int16RingOpsND { +} + public final class space/kscience/kmath/nd/IntBufferND : space/kscience/kmath/nd/MutableBufferND { public synthetic fun <init> (Lspace/kscience/kmath/nd/ShapeIndexer;[ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun getBuffer ()Lspace/kscience/kmath/structures/Buffer; public synthetic fun getBuffer ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun getBuffer-ir4F4A8 ()[I + public fun getBuffer-M_oXE9g ()[I } public final class space/kscience/kmath/nd/IntRingND : space/kscience/kmath/nd/IntRingOpsND, space/kscience/kmath/nd/RingND, space/kscience/kmath/operations/NumbersAddOps { @@ -1167,7 +1254,7 @@ public final class space/kscience/kmath/nd/IntRingND : space/kscience/kmath/nd/I } public final class space/kscience/kmath/nd/IntRingNDKt { - public static final fun withNdAlgebra (Lspace/kscience/kmath/operations/IntRing;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; + public static final fun withNdAlgebra (Lspace/kscience/kmath/operations/Int32Ring;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; } public abstract class space/kscience/kmath/nd/IntRingOpsND : space/kscience/kmath/nd/BufferedRingOpsND { @@ -1201,6 +1288,17 @@ public abstract interface class space/kscience/kmath/nd/MutableStructureND : spa public abstract fun set ([ILjava/lang/Object;)V } +public final class space/kscience/kmath/nd/MutableStructureNDAccessorBuffer : space/kscience/kmath/structures/MutableBuffer { + public fun <init> (Lspace/kscience/kmath/nd/MutableStructureND;ILkotlin/jvm/functions/Function1;)V + public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public fun get (I)Ljava/lang/Object; + public fun getSize ()I + public final fun getStructure ()Lspace/kscience/kmath/nd/MutableStructureND; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public fun set (ILjava/lang/Object;)V + public fun toString ()Ljava/lang/String; +} + public abstract interface class space/kscience/kmath/nd/MutableStructureNDOfDouble : space/kscience/kmath/nd/MutableStructureND, space/kscience/kmath/nd/StructureNDOfDouble { public abstract fun setDouble ([ID)V } @@ -1218,6 +1316,7 @@ public final class space/kscience/kmath/nd/PermutedMutableStructureND : space/ks public final fun getOrigin ()Lspace/kscience/kmath/nd/MutableStructureND; public final fun getPermutation ()Lkotlin/jvm/functions/Function1; public fun getShape-IIYLAfE ()[I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun set ([ILjava/lang/Object;)V } @@ -1227,6 +1326,7 @@ public final class space/kscience/kmath/nd/PermutedStructureND : space/kscience/ public final fun getOrigin ()Lspace/kscience/kmath/nd/StructureND; public final fun getPermutation ()Lkotlin/jvm/functions/Function1; public fun getShape-IIYLAfE ()[I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public final class space/kscience/kmath/nd/PermutedStructureNDKt { @@ -1332,24 +1432,6 @@ public final class space/kscience/kmath/nd/ShapeNDKt { public static final fun transposed-bYNkpeI ([III)[I } -public final class space/kscience/kmath/nd/ShortRingND : space/kscience/kmath/nd/ShortRingOpsND, space/kscience/kmath/nd/RingND, space/kscience/kmath/operations/NumbersAddOps { - public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun getShape-IIYLAfE ()[I - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Lspace/kscience/kmath/nd/BufferND; -} - -public final class space/kscience/kmath/nd/ShortRingNDKt { - public static final fun withNdAlgebra (Lspace/kscience/kmath/operations/ShortRing;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object; -} - -public abstract class space/kscience/kmath/nd/ShortRingOpsND : space/kscience/kmath/nd/BufferedRingOpsND { - public static final field Companion Lspace/kscience/kmath/nd/ShortRingOpsND$Companion; -} - -public final class space/kscience/kmath/nd/ShortRingOpsND$Companion : space/kscience/kmath/nd/ShortRingOpsND { -} - public abstract class space/kscience/kmath/nd/Strides : space/kscience/kmath/nd/ShapeIndexer { public fun <init> ()V public fun asSequence ()Lkotlin/sequences/Sequence; @@ -1392,26 +1474,19 @@ public final class space/kscience/kmath/nd/Structure2DKt { public static final fun as2D (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/Structure2D; } -public abstract interface class space/kscience/kmath/nd/StructureFeature : space/kscience/kmath/misc/Feature { +public abstract interface class space/kscience/kmath/nd/StructureAttribute : space/kscience/attributes/Attribute { } -public abstract interface class space/kscience/kmath/nd/StructureND : space/kscience/kmath/misc/Featured, space/kscience/kmath/nd/WithShape { +public abstract interface class space/kscience/kmath/nd/StructureND : space/kscience/attributes/AttributeContainer, space/kscience/attributes/WithType, space/kscience/kmath/nd/WithShape { public static final field Companion Lspace/kscience/kmath/nd/StructureND$Companion; public fun elements ()Lkotlin/sequences/Sequence; public abstract fun get ([I)Ljava/lang/Object; + public fun getAttributes ()Lspace/kscience/attributes/Attributes; public fun getDimension ()I - public synthetic fun getFeature (Lkotlin/reflect/KClass;)Ljava/lang/Object; - public fun getFeature (Lkotlin/reflect/KClass;)Lspace/kscience/kmath/nd/StructureFeature; public abstract fun getShape-IIYLAfE ()[I } public final class space/kscience/kmath/nd/StructureND$Companion { - public final fun auto (Lkotlin/reflect/KClass;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; - public final fun auto (Lkotlin/reflect/KClass;[ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; - public final fun buffered (Lspace/kscience/kmath/nd/Strides;Lspace/kscience/kmath/structures/BufferFactory;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; - public static synthetic fun buffered$default (Lspace/kscience/kmath/nd/StructureND$Companion;Lspace/kscience/kmath/nd/Strides;Lspace/kscience/kmath/structures/BufferFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/BufferND; - public final fun buffered-bYNkpeI ([ILspace/kscience/kmath/structures/BufferFactory;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; - public static synthetic fun buffered-bYNkpeI$default (Lspace/kscience/kmath/nd/StructureND$Companion;[ILspace/kscience/kmath/structures/BufferFactory;Lkotlin/jvm/functions/Function1;ILjava/lang/Object;)Lspace/kscience/kmath/nd/BufferND; public final fun contentEquals (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Z public final fun contentEquals (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;D)Z public static synthetic fun contentEquals$default (Lspace/kscience/kmath/nd/StructureND$Companion;Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;DILjava/lang/Object;)Z @@ -1419,6 +1494,9 @@ public final class space/kscience/kmath/nd/StructureND$Companion { } public final class space/kscience/kmath/nd/StructureNDKt { + public static final fun BufferND--rwW0uw (Lkotlin/reflect/KType;Lspace/kscience/kmath/nd/Strides;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; + public static final fun BufferND--rwW0uw (Lkotlin/reflect/KType;[ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; + public static final fun BufferND-vHyE91E (Lkotlin/reflect/KType;[ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/nd/BufferND; public static final fun contentEquals (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Z public static final fun contentEquals (Lspace/kscience/kmath/linear/LinearSpace;Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Comparable;)Z public static final fun contentEquals (Lspace/kscience/kmath/nd/AlgebraND;Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Z @@ -1431,17 +1509,20 @@ public final class space/kscience/kmath/nd/StructureNDKt { public abstract interface class space/kscience/kmath/nd/StructureNDOfDouble : space/kscience/kmath/nd/StructureND { public abstract fun getDouble ([I)D + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public abstract interface class space/kscience/kmath/nd/StructureNDOfInt : space/kscience/kmath/nd/StructureND { public abstract fun getInt ([I)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public class space/kscience/kmath/nd/VirtualStructureND : space/kscience/kmath/nd/StructureND { - public synthetic fun <init> ([ILkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun <init> (Lkotlin/reflect/KType;[ILkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun get ([I)Ljava/lang/Object; public final fun getProducer ()Lkotlin/jvm/functions/Function1; public fun getShape-IIYLAfE ()[I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public abstract interface class space/kscience/kmath/nd/WithShape { @@ -1449,12 +1530,13 @@ public abstract interface class space/kscience/kmath/nd/WithShape { public abstract fun getShape-IIYLAfE ()[I } -public abstract interface class space/kscience/kmath/operations/Algebra { +public abstract interface class space/kscience/kmath/operations/Algebra : space/kscience/attributes/WithType { public fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun bindSymbol (Ljava/lang/String;)Ljava/lang/Object; public fun bindSymbolOrNull (Ljava/lang/String;)Ljava/lang/Object; - public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public abstract fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; } @@ -1520,6 +1602,7 @@ public final class space/kscience/kmath/operations/BigIntField : space/kscience/ public fun add (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (Lspace/kscience/kmath/operations/BigInt;Lspace/kscience/kmath/operations/BigInt;)Lspace/kscience/kmath/operations/BigInt; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Lspace/kscience/kmath/operations/BigInt; public synthetic fun getZero ()Ljava/lang/Object; @@ -1553,8 +1636,9 @@ public final class space/kscience/kmath/operations/BigIntKt { public abstract interface class space/kscience/kmath/operations/BufferAlgebra : space/kscience/kmath/operations/Algebra { public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; public fun buffer (I[Ljava/lang/Object;)Lspace/kscience/kmath/structures/Buffer; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public abstract fun getElementAlgebra ()Lspace/kscience/kmath/operations/Algebra; - public fun getElementBufferFactory ()Lspace/kscience/kmath/structures/BufferFactory; + public fun getElementBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public fun map (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; public fun mapIndexed (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/structures/Buffer; public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; @@ -1568,15 +1652,15 @@ public final class space/kscience/kmath/operations/BufferAlgebraKt { public static final fun asinh (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public static final fun atan (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public static final fun atanh (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public static final fun buffer (Lspace/kscience/kmath/operations/BufferAlgebra;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; - public static final fun buffer (Lspace/kscience/kmath/operations/BufferAlgebra;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; + public static final fun buffer (Lspace/kscience/kmath/operations/BufferAlgebra;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; + public static final fun buffer (Lspace/kscience/kmath/operations/BufferAlgebra;Lkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; public static final fun buffer (Lspace/kscience/kmath/operations/BufferField;[Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; public static final fun cos (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public static final fun cosh (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public static final fun exp (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public static final fun getBufferAlgebra (Lspace/kscience/kmath/operations/Field;)Lspace/kscience/kmath/operations/BufferFieldOps; - public static final fun getBufferAlgebra (Lspace/kscience/kmath/operations/IntRing;)Lspace/kscience/kmath/operations/BufferRingOps; - public static final fun getBufferAlgebra (Lspace/kscience/kmath/operations/ShortRing;)Lspace/kscience/kmath/operations/BufferRingOps; + public static final fun getBufferAlgebra (Lspace/kscience/kmath/operations/Int16Ring;)Lspace/kscience/kmath/operations/BufferRingOps; + public static final fun getBufferAlgebra (Lspace/kscience/kmath/operations/Int32Ring;)Lspace/kscience/kmath/operations/BufferRingOps; public static final fun ln (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; public static final fun pow (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; public static final fun sin (Lspace/kscience/kmath/operations/BufferAlgebra;Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; @@ -1635,201 +1719,6 @@ public abstract interface class space/kscience/kmath/operations/BufferTransform public abstract fun transform (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; } -public final class space/kscience/kmath/operations/ByteRing : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { - public static final field INSTANCE Lspace/kscience/kmath/operations/ByteRing; - public fun add (BB)Ljava/lang/Byte; - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; - public fun getOne ()Ljava/lang/Byte; - public synthetic fun getOne ()Ljava/lang/Object; - public fun getZero ()Ljava/lang/Byte; - public synthetic fun getZero ()Ljava/lang/Object; - public fun minus (BB)Ljava/lang/Byte; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply (BB)Ljava/lang/Byte; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun norm (B)Ljava/lang/Byte; - public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Ljava/lang/Byte; - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun plus (BB)Ljava/lang/Byte; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (BB)Ljava/lang/Byte; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (B)Ljava/lang/Byte; - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; -} - -public final class space/kscience/kmath/operations/DoubleBufferField : space/kscience/kmath/operations/DoubleBufferOps, space/kscience/kmath/operations/ExtendedField { - public fun <init> (I)V - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun getOne ()Ljava/lang/Object; - public fun getOne ()Lspace/kscience/kmath/structures/Buffer; - public final fun getSize ()I - public synthetic fun getZero ()Ljava/lang/Object; - public fun getZero ()Lspace/kscience/kmath/structures/Buffer; - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public synthetic fun power (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; - public fun power-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)[D - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; -} - -public abstract class space/kscience/kmath/operations/DoubleBufferOps : space/kscience/kmath/operations/BufferAlgebra, space/kscience/kmath/operations/ExtendedFieldOps, space/kscience/kmath/operations/Norm { - public static final field Companion Lspace/kscience/kmath/operations/DoubleBufferOps$Companion; - public fun <init> ()V - public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; - public fun acos-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun add-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; - public fun asin-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; - public fun atan-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; - public fun cos-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun divide-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; - public fun exp-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Algebra; - public fun getElementAlgebra ()Lspace/kscience/kmath/operations/DoubleField; - public synthetic fun getElementBufferFactory ()Lspace/kscience/kmath/structures/BufferFactory; - public fun getElementBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; - public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; - public fun ln-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun map (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; - public final fun map-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function2;)[D - public synthetic fun mapIndexed (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/structures/Buffer; - public final fun mapIndexed-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)[D - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; - public fun norm (Lspace/kscience/kmath/structures/Buffer;)Ljava/lang/Double; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun power (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; - public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public fun scale-CZ9oacQ (Lspace/kscience/kmath/structures/Buffer;D)[D - public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; - public fun sin-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D - public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; - public synthetic fun zip (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/structures/Buffer; - public final fun zip-XquIszc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)[D -} - -public final class space/kscience/kmath/operations/DoubleBufferOps$Companion : space/kscience/kmath/operations/DoubleBufferOps { -} - -public final class space/kscience/kmath/operations/DoubleBufferOpsKt { - public static final fun average (Lspace/kscience/kmath/operations/DoubleBufferOps;Lspace/kscience/kmath/structures/Buffer;)D - public static final fun averageOf (Lspace/kscience/kmath/operations/DoubleBufferOps;Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function1;)D - public static final fun covariance (Lspace/kscience/kmath/operations/DoubleBufferOps;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)D - public static final fun dispersion (Lspace/kscience/kmath/operations/DoubleBufferOps;Lspace/kscience/kmath/structures/Buffer;)D - public static final fun std (Lspace/kscience/kmath/operations/DoubleBufferOps;Lspace/kscience/kmath/structures/Buffer;)D - public static final fun sum (Lspace/kscience/kmath/operations/DoubleBufferOps;Lspace/kscience/kmath/structures/Buffer;)D - public static final fun sumOf (Lspace/kscience/kmath/operations/DoubleBufferOps;Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function1;)D -} - -public final class space/kscience/kmath/operations/DoubleField : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/ScaleOperations { - public static final field INSTANCE Lspace/kscience/kmath/operations/DoubleField; - public fun acos (D)Ljava/lang/Double; - public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; - public fun acosh (D)Ljava/lang/Double; - public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun add (DD)Ljava/lang/Double; - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun asin (D)Ljava/lang/Double; - public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; - public fun asinh (D)Ljava/lang/Double; - public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun atan (D)Ljava/lang/Double; - public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; - public fun atanh (D)Ljava/lang/Double; - public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; - public fun cos (D)Ljava/lang/Double; - public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; - public fun cosh (D)Ljava/lang/Double; - public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; - public fun div (DD)Ljava/lang/Double; - public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun divide (DD)Ljava/lang/Double; - public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun exp (D)Ljava/lang/Double; - public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; - public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; - public fun getOne ()Ljava/lang/Double; - public synthetic fun getOne ()Ljava/lang/Object; - public fun getZero ()Ljava/lang/Double; - public synthetic fun getZero ()Ljava/lang/Object; - public fun ln (D)Ljava/lang/Double; - public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (DD)Ljava/lang/Double; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply (DD)Ljava/lang/Double; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun norm (D)Ljava/lang/Double; - public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Ljava/lang/Double; - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun plus (DD)Ljava/lang/Double; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun power (DLjava/lang/Number;)Ljava/lang/Double; - public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; - public fun scale (DD)Ljava/lang/Double; - public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; - public fun sin (D)Ljava/lang/Double; - public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; - public fun sinh (D)Ljava/lang/Double; - public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; - public fun sqrt (D)Ljava/lang/Double; - public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; - public fun tan (D)Ljava/lang/Double; - public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; - public fun tanh (D)Ljava/lang/Double; - public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; - public fun times (DD)Ljava/lang/Double; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (D)Ljava/lang/Double; - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; -} - -public final class space/kscience/kmath/operations/DoubleL2Norm : space/kscience/kmath/operations/Norm { - public static final field INSTANCE Lspace/kscience/kmath/operations/DoubleL2Norm; - public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; - public fun norm (Lspace/kscience/kmath/structures/Buffer;)Ljava/lang/Double; -} - public abstract interface class space/kscience/kmath/operations/ExponentialOperations : space/kscience/kmath/operations/Algebra { public static final field ACOSH_OPERATION Ljava/lang/String; public static final field ASINH_OPERATION Ljava/lang/String; @@ -1899,8 +1788,8 @@ public final class space/kscience/kmath/operations/FieldOps$Companion { public static final field DIV_OPERATION Ljava/lang/String; } -public final class space/kscience/kmath/operations/FloatField : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm { - public static final field INSTANCE Lspace/kscience/kmath/operations/FloatField; +public final class space/kscience/kmath/operations/Float32Field : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm { + public static final field INSTANCE Lspace/kscience/kmath/operations/Float32Field; public fun acos (F)Ljava/lang/Float; public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; public fun acosh (F)Ljava/lang/Float; @@ -1963,6 +1852,175 @@ public final class space/kscience/kmath/operations/FloatField : space/kscience/k public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; } +public final class space/kscience/kmath/operations/Float64BufferField : space/kscience/kmath/operations/Float64BufferOps, space/kscience/kmath/operations/ExtendedField { + public fun <init> (I)V + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun getOne ()Ljava/lang/Object; + public fun getOne ()Lspace/kscience/kmath/structures/Buffer; + public final fun getSize ()I + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Lspace/kscience/kmath/structures/Buffer; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public synthetic fun power (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; + public fun power-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)[D + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; +} + +public abstract class space/kscience/kmath/operations/Float64BufferOps : space/kscience/kmath/operations/BufferAlgebra, space/kscience/kmath/operations/ExtendedFieldOps, space/kscience/kmath/operations/Norm { + public static final field Companion Lspace/kscience/kmath/operations/Float64BufferOps$Companion; + public fun <init> ()V + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acos-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asin-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cos-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun exp-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Algebra; + public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Float64Field; + public fun getElementBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun ln-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun map (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/structures/Buffer; + public final fun map-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function2;)[D + public synthetic fun mapIndexed (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/structures/Buffer; + public final fun mapIndexed-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)[D + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun minus-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (Lspace/kscience/kmath/structures/Buffer;)Ljava/lang/Double; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun plus-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power (Lspace/kscience/kmath/structures/Buffer;Ljava/lang/Number;)Lspace/kscience/kmath/structures/Buffer; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale-Vq5tpWc (Lspace/kscience/kmath/structures/Buffer;D)[D + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sin-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D + public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1; + public synthetic fun zip (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/structures/Buffer; + public final fun zip-Qj2idzA (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function3;)[D +} + +public final class space/kscience/kmath/operations/Float64BufferOps$Companion : space/kscience/kmath/operations/Float64BufferOps { +} + +public final class space/kscience/kmath/operations/Float64BufferOpsKt { + public static final fun average (Lspace/kscience/kmath/operations/Float64BufferOps;Lspace/kscience/kmath/structures/Buffer;)D + public static final fun averageOf (Lspace/kscience/kmath/operations/Float64BufferOps;Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function1;)D + public static final fun covariance (Lspace/kscience/kmath/operations/Float64BufferOps;Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)D + public static final fun dispersion (Lspace/kscience/kmath/operations/Float64BufferOps;Lspace/kscience/kmath/structures/Buffer;)D + public static final fun std (Lspace/kscience/kmath/operations/Float64BufferOps;Lspace/kscience/kmath/structures/Buffer;)D + public static final fun sum (Lspace/kscience/kmath/operations/Float64BufferOps;Lspace/kscience/kmath/structures/Buffer;)D + public static final fun sumOf (Lspace/kscience/kmath/operations/Float64BufferOps;Lspace/kscience/kmath/structures/Buffer;Lkotlin/jvm/functions/Function1;)D +} + +public final class space/kscience/kmath/operations/Float64Field : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/ScaleOperations { + public static final field INSTANCE Lspace/kscience/kmath/operations/Float64Field; + public fun acos (D)Ljava/lang/Double; + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (D)Ljava/lang/Double; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun add (DD)Ljava/lang/Double; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun asin (D)Ljava/lang/Double; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (D)Ljava/lang/Double; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan (D)Ljava/lang/Double; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (D)Ljava/lang/Double; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun cos (D)Ljava/lang/Double; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (D)Ljava/lang/Double; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun div (DD)Ljava/lang/Double; + public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (DD)Ljava/lang/Double; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun exp (D)Ljava/lang/Double; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public fun getOne ()Ljava/lang/Double; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Double; + public synthetic fun getZero ()Ljava/lang/Object; + public fun ln (D)Ljava/lang/Double; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (DD)Ljava/lang/Double; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (DD)Ljava/lang/Double; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (D)Ljava/lang/Double; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Double; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun plus (DD)Ljava/lang/Double; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun power (DLjava/lang/Number;)Ljava/lang/Double; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun scale (DD)Ljava/lang/Double; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun sin (D)Ljava/lang/Double; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (D)Ljava/lang/Double; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sqrt (D)Ljava/lang/Double; + public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan (D)Ljava/lang/Double; + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (D)Ljava/lang/Double; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun times (DD)Ljava/lang/Double; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (D)Ljava/lang/Double; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; +} + +public final class space/kscience/kmath/operations/Float64L2Norm : space/kscience/kmath/operations/Norm { + public static final field INSTANCE Lspace/kscience/kmath/operations/Float64L2Norm; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (Lspace/kscience/kmath/structures/Buffer;)Ljava/lang/Double; +} + public abstract interface class space/kscience/kmath/operations/Group : space/kscience/kmath/operations/GroupOps { public abstract fun getZero ()Ljava/lang/Object; } @@ -1985,8 +2043,79 @@ public final class space/kscience/kmath/operations/GroupOps$Companion { public static final field PLUS_OPERATION Ljava/lang/String; } -public final class space/kscience/kmath/operations/IntRing : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { - public static final field INSTANCE Lspace/kscience/kmath/operations/IntRing; +public final class space/kscience/kmath/operations/Int16Field : space/kscience/kmath/operations/Field, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra { + public static final field INSTANCE Lspace/kscience/kmath/operations/Int16Field; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add (SS)Ljava/lang/Short; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (SS)Ljava/lang/Short; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getOne ()Ljava/lang/Short; + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Short; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (SS)Ljava/lang/Short; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (S)Ljava/lang/Short; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Short; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale (SD)Ljava/lang/Short; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (S)Ljava/lang/Short; +} + +public final class space/kscience/kmath/operations/Int16Ring : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { + public static final field INSTANCE Lspace/kscience/kmath/operations/Int16Ring; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun add (SS)Ljava/lang/Short; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getOne ()Ljava/lang/Short; + public synthetic fun getZero ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Short; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (SS)Ljava/lang/Short; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (SS)Ljava/lang/Short; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (S)Ljava/lang/Short; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Short; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun plus (SS)Ljava/lang/Short; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun times (SS)Ljava/lang/Short; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (S)Ljava/lang/Short; +} + +public final class space/kscience/kmath/operations/Int32Field : space/kscience/kmath/operations/Field, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra { + public static final field INSTANCE Lspace/kscience/kmath/operations/Int32Field; + public fun add (II)Ljava/lang/Integer; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (II)Ljava/lang/Integer; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public fun getOne ()Ljava/lang/Integer; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Integer; + public synthetic fun getZero ()Ljava/lang/Object; + public fun multiply (II)Ljava/lang/Integer; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (I)Ljava/lang/Integer; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Integer; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun scale (ID)Ljava/lang/Integer; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun unaryMinus (I)Ljava/lang/Integer; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; +} + +public final class space/kscience/kmath/operations/Int32Ring : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { + public static final field INSTANCE Lspace/kscience/kmath/operations/Int32Ring; public fun add (II)Ljava/lang/Integer; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; @@ -2010,6 +2139,79 @@ public final class space/kscience/kmath/operations/IntRing : space/kscience/kmat public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; } +public final class space/kscience/kmath/operations/Int64Field : space/kscience/kmath/operations/Field, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra { + public static final field INSTANCE Lspace/kscience/kmath/operations/Int64Field; + public fun add (JJ)Ljava/lang/Long; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (JJ)Ljava/lang/Long; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public fun getOne ()Ljava/lang/Long; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Long; + public synthetic fun getZero ()Ljava/lang/Object; + public fun multiply (JJ)Ljava/lang/Long; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (J)Ljava/lang/Long; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Long; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun scale (JD)Ljava/lang/Long; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun unaryMinus (J)Ljava/lang/Long; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; +} + +public final class space/kscience/kmath/operations/Int64Ring : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { + public static final field INSTANCE Lspace/kscience/kmath/operations/Int64Ring; + public fun add (JJ)Ljava/lang/Long; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public fun getOne ()Ljava/lang/Long; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Long; + public synthetic fun getZero ()Ljava/lang/Object; + public fun minus (JJ)Ljava/lang/Long; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (JJ)Ljava/lang/Long; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (J)Ljava/lang/Long; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Long; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun plus (JJ)Ljava/lang/Long; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun times (JJ)Ljava/lang/Long; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (J)Ljava/lang/Long; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; +} + +public final class space/kscience/kmath/operations/Int8Ring : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { + public static final field INSTANCE Lspace/kscience/kmath/operations/Int8Ring; + public fun add (BB)Ljava/lang/Byte; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public fun getOne ()Ljava/lang/Byte; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Byte; + public synthetic fun getZero ()Ljava/lang/Object; + public fun minus (BB)Ljava/lang/Byte; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (BB)Ljava/lang/Byte; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (B)Ljava/lang/Byte; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Byte; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun plus (BB)Ljava/lang/Byte; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun times (BB)Ljava/lang/Byte; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (B)Ljava/lang/Byte; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; +} + public final class space/kscience/kmath/operations/IsIntegerKt { public static final fun isInteger (Ljava/lang/Number;)Z } @@ -2030,6 +2232,7 @@ public abstract class space/kscience/kmath/operations/JBigDecimalFieldBase : spa public fun add (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun divide (Ljava/math/BigDecimal;Ljava/math/BigDecimal;)Ljava/math/BigDecimal; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Ljava/math/BigDecimal; public synthetic fun getZero ()Ljava/lang/Object; @@ -2054,6 +2257,7 @@ public final class space/kscience/kmath/operations/JBigIntegerField : space/ksci public static final field INSTANCE Lspace/kscience/kmath/operations/JBigIntegerField; public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun add (Ljava/math/BigInteger;Ljava/math/BigInteger;)Ljava/math/BigInteger; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; public synthetic fun getOne ()Ljava/lang/Object; public fun getOne ()Ljava/math/BigInteger; public synthetic fun getZero ()Ljava/lang/Object; @@ -2073,42 +2277,17 @@ public final class space/kscience/kmath/operations/LogicAlgebra$Companion { public final fun getTRUE ()Lspace/kscience/kmath/expressions/Symbol; } -public final class space/kscience/kmath/operations/LongRing : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { - public static final field INSTANCE Lspace/kscience/kmath/operations/LongRing; - public fun add (JJ)Ljava/lang/Long; - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; - public fun getOne ()Ljava/lang/Long; - public synthetic fun getOne ()Ljava/lang/Object; - public fun getZero ()Ljava/lang/Long; - public synthetic fun getZero ()Ljava/lang/Object; - public fun minus (JJ)Ljava/lang/Long; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply (JJ)Ljava/lang/Long; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun norm (J)Ljava/lang/Long; - public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Ljava/lang/Long; - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun plus (JJ)Ljava/lang/Long; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (JJ)Ljava/lang/Long; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (J)Ljava/lang/Long; - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; -} - public abstract interface class space/kscience/kmath/operations/Norm { public abstract fun norm (Ljava/lang/Object;)Ljava/lang/Object; } public final class space/kscience/kmath/operations/NumbersKt { - public static final fun getAlgebra (Lkotlin/jvm/internal/ByteCompanionObject;)Lspace/kscience/kmath/operations/ByteRing; - public static final fun getAlgebra (Lkotlin/jvm/internal/DoubleCompanionObject;)Lspace/kscience/kmath/operations/DoubleField; - public static final fun getAlgebra (Lkotlin/jvm/internal/FloatCompanionObject;)Lspace/kscience/kmath/operations/FloatField; - public static final fun getAlgebra (Lkotlin/jvm/internal/IntCompanionObject;)Lspace/kscience/kmath/operations/IntRing; - public static final fun getAlgebra (Lkotlin/jvm/internal/LongCompanionObject;)Lspace/kscience/kmath/operations/LongRing; - public static final fun getAlgebra (Lkotlin/jvm/internal/ShortCompanionObject;)Lspace/kscience/kmath/operations/ShortRing; + public static final fun getAlgebra (Lkotlin/jvm/internal/ByteCompanionObject;)Lspace/kscience/kmath/operations/Int8Ring; + public static final fun getAlgebra (Lkotlin/jvm/internal/DoubleCompanionObject;)Lspace/kscience/kmath/operations/Float64Field; + public static final fun getAlgebra (Lkotlin/jvm/internal/FloatCompanionObject;)Lspace/kscience/kmath/operations/Float32Field; + public static final fun getAlgebra (Lkotlin/jvm/internal/IntCompanionObject;)Lspace/kscience/kmath/operations/Int32Ring; + public static final fun getAlgebra (Lkotlin/jvm/internal/LongCompanionObject;)Lspace/kscience/kmath/operations/Int64Ring; + public static final fun getAlgebra (Lkotlin/jvm/internal/ShortCompanionObject;)Lspace/kscience/kmath/operations/Int16Ring; } public abstract interface class space/kscience/kmath/operations/NumericAlgebra : space/kscience/kmath/operations/Algebra { @@ -2125,7 +2304,7 @@ public final class space/kscience/kmath/operations/NumericAlgebraKt { public static final fun getPi (Lspace/kscience/kmath/operations/NumericAlgebra;)Ljava/lang/Object; } -public abstract interface class space/kscience/kmath/operations/PowerOperations : space/kscience/kmath/operations/FieldOps { +public abstract interface class space/kscience/kmath/operations/PowerOperations : space/kscience/kmath/operations/Algebra { public static final field Companion Lspace/kscience/kmath/operations/PowerOperations$Companion; public static final field POW_OPERATION Ljava/lang/String; public static final field SQRT_OPERATION Ljava/lang/String; @@ -2167,31 +2346,6 @@ public abstract interface class space/kscience/kmath/operations/ScaleOperations public fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; } -public final class space/kscience/kmath/operations/ShortRing : space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/NumericAlgebra, space/kscience/kmath/operations/Ring { - public static final field INSTANCE Lspace/kscience/kmath/operations/ShortRing; - public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun add (SS)Ljava/lang/Short; - public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; - public synthetic fun getOne ()Ljava/lang/Object; - public fun getOne ()Ljava/lang/Short; - public synthetic fun getZero ()Ljava/lang/Object; - public fun getZero ()Ljava/lang/Short; - public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun minus (SS)Ljava/lang/Short; - public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun multiply (SS)Ljava/lang/Short; - public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; - public fun norm (S)Ljava/lang/Short; - public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; - public fun number (Ljava/lang/Number;)Ljava/lang/Short; - public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun plus (SS)Ljava/lang/Short; - public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; - public fun times (SS)Ljava/lang/Short; - public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; - public fun unaryMinus (S)Ljava/lang/Short; -} - public abstract interface class space/kscience/kmath/operations/TrigonometricOperations : space/kscience/kmath/operations/Algebra { public static final field ACOS_OPERATION Ljava/lang/String; public static final field ASIN_OPERATION Ljava/lang/String; @@ -2222,20 +2376,21 @@ public abstract interface class space/kscience/kmath/operations/WithSize { } public final class space/kscience/kmath/structures/ArrayBuffer : space/kscience/kmath/structures/MutableBuffer { - public fun <init> ([Ljava/lang/Object;)V + public synthetic fun <init> (Lkotlin/reflect/KType;[Ljava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public fun get (I)Ljava/lang/Object; public fun getSize ()I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun iterator ()Ljava/util/Iterator; public fun set (ILjava/lang/Object;)V public fun toString ()Ljava/lang/String; } public final class space/kscience/kmath/structures/ArrayBufferKt { - public static final fun asBuffer ([Ljava/lang/Object;)Lspace/kscience/kmath/structures/ArrayBuffer; + public static final fun asBuffer-Fnn_obI ([Ljava/lang/Object;Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/ArrayBuffer; } -public abstract interface class space/kscience/kmath/structures/Buffer : space/kscience/kmath/operations/WithSize { +public abstract interface class space/kscience/kmath/structures/Buffer : space/kscience/attributes/WithType, space/kscience/kmath/operations/WithSize { public static final field Companion Lspace/kscience/kmath/structures/Buffer$Companion; public abstract fun get (I)Ljava/lang/Object; public abstract fun getSize ()I @@ -2244,8 +2399,6 @@ public abstract interface class space/kscience/kmath/structures/Buffer : space/k } public final class space/kscience/kmath/structures/Buffer$Companion { - public final fun auto (Lkotlin/reflect/KClass;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; - public final fun boxing (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; public final fun contentEquals (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/Buffer;)Z public final fun toString (Lspace/kscience/kmath/structures/Buffer;)Ljava/lang/String; } @@ -2260,17 +2413,14 @@ public final class space/kscience/kmath/structures/BufferExpanded : space/kscien public fun toString ()Ljava/lang/String; } -public abstract interface class space/kscience/kmath/structures/BufferFactory { - public static final field Companion Lspace/kscience/kmath/structures/BufferFactory$Companion; +public abstract interface class space/kscience/kmath/structures/BufferFactory : space/kscience/attributes/WithType { public abstract fun invoke (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; } -public final class space/kscience/kmath/structures/BufferFactory$Companion { - public final fun boxing ()Lspace/kscience/kmath/structures/BufferFactory; -} - public final class space/kscience/kmath/structures/BufferKt { - public static final fun asReadOnly (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public static final fun Buffer--rwW0uw (Lkotlin/reflect/KType;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; + public static final fun BufferFactory-X0YbwmU (Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/BufferFactory; + public static final fun MutableBufferFactory-X0YbwmU (Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/MutableBufferFactory; public static final fun first (Lspace/kscience/kmath/structures/Buffer;)Ljava/lang/Object; public static final fun get-Qn1smSk (Lspace/kscience/kmath/structures/Buffer;I)Ljava/lang/Object; public static final fun getIndices (Lspace/kscience/kmath/structures/Buffer;)Lkotlin/ranges/IntRange; @@ -2278,6 +2428,10 @@ public final class space/kscience/kmath/structures/BufferKt { public static final fun last (Lspace/kscience/kmath/structures/Buffer;)Ljava/lang/Object; } +public final class space/kscience/kmath/structures/BufferListKt { + public static final fun asList (Lspace/kscience/kmath/structures/Buffer;)Ljava/util/List; +} + public final class space/kscience/kmath/structures/BufferPrimitiveAccessKt { } @@ -2295,6 +2449,7 @@ public final class space/kscience/kmath/structures/BufferSlice : space/kscience/ public abstract interface class space/kscience/kmath/structures/BufferView : space/kscience/kmath/structures/Buffer { public fun get (I)Ljava/lang/Object; public abstract fun getOrigin ()Lspace/kscience/kmath/structures/Buffer; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public final class space/kscience/kmath/structures/BufferViewKt { @@ -2304,87 +2459,6 @@ public final class space/kscience/kmath/structures/BufferViewKt { public static final fun slice (Lspace/kscience/kmath/structures/Buffer;Lkotlin/ranges/IntRange;)Lspace/kscience/kmath/structures/BufferView; } -public final class space/kscience/kmath/structures/ByteBuffer : space/kscience/kmath/structures/MutableBuffer { - public static final synthetic fun box-impl ([B)Lspace/kscience/kmath/structures/ByteBuffer; - public static fun constructor-impl ([B)[B - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl ([B)Lspace/kscience/kmath/structures/MutableBuffer; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl ([BLjava/lang/Object;)Z - public static final fun equals-impl0 ([B[B)Z - public fun get (I)Ljava/lang/Byte; - public synthetic fun get (I)Ljava/lang/Object; - public static fun get-impl ([BI)Ljava/lang/Byte; - public final fun getArray ()[B - public fun getSize ()I - public static fun getSize-impl ([B)I - public fun hashCode ()I - public static fun hashCode-impl ([B)I - public synthetic fun iterator ()Ljava/util/Iterator; - public fun iterator ()Lkotlin/collections/ByteIterator; - public static fun iterator-impl ([B)Lkotlin/collections/ByteIterator; - public fun set (IB)V - public synthetic fun set (ILjava/lang/Object;)V - public static fun set-impl ([BIB)V - public fun toString ()Ljava/lang/String; - public static fun toString-impl ([B)Ljava/lang/String; - public final synthetic fun unbox-impl ()[B -} - -public final class space/kscience/kmath/structures/ByteBufferKt { - public static final fun ByteBuffer (ILkotlin/jvm/functions/Function1;)[B - public static final fun ByteBuffer ([B)[B - public static final fun asBuffer ([B)[B - public static final fun toByteArray (Lspace/kscience/kmath/structures/Buffer;)[B -} - -public final class space/kscience/kmath/structures/DoubleBuffer : space/kscience/kmath/structures/PrimitiveBuffer { - public static final field Companion Lspace/kscience/kmath/structures/DoubleBuffer$Companion; - public static final synthetic fun box-impl ([D)Lspace/kscience/kmath/structures/DoubleBuffer; - public static fun constructor-impl ([D)[D - public synthetic fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun copy-Dv3HvWU ()[D - public static fun copy-Dv3HvWU ([D)[D - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl ([DLjava/lang/Object;)Z - public static final fun equals-impl0 ([D[D)Z - public fun get (I)Ljava/lang/Double; - public synthetic fun get (I)Ljava/lang/Object; - public static fun get-impl ([DI)Ljava/lang/Double; - public final fun getArray ()[D - public fun getSize ()I - public static fun getSize-impl ([D)I - public fun hashCode ()I - public static fun hashCode-impl ([D)I - public synthetic fun iterator ()Ljava/util/Iterator; - public fun iterator ()Lkotlin/collections/DoubleIterator; - public static fun iterator-impl ([D)Lkotlin/collections/DoubleIterator; - public fun set (ID)V - public synthetic fun set (ILjava/lang/Object;)V - public static fun set-impl ([DID)V - public fun toString ()Ljava/lang/String; - public static fun toString-impl ([D)Ljava/lang/String; - public final synthetic fun unbox-impl ()[D -} - -public final class space/kscience/kmath/structures/DoubleBuffer$Companion { - public final fun zero-Udx-57Q (I)[D -} - -public final class space/kscience/kmath/structures/DoubleBufferKt { - public static final fun DoubleBuffer (ILkotlin/jvm/functions/Function1;)[D - public static final fun DoubleBuffer ([D)[D - public static final fun asBuffer ([D)[D - public static final fun toDoubleArray (Lspace/kscience/kmath/structures/Buffer;)[D - public static final fun toDoubleBuffer (Lspace/kscience/kmath/structures/Buffer;)[D -} - -public abstract interface class space/kscience/kmath/structures/DoubleBufferTransform : space/kscience/kmath/operations/BufferTransform { - public synthetic fun transform (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; - public abstract fun transform-7Zdoou4 ([D)[D - public fun transform-Udx-57Q (Lspace/kscience/kmath/structures/Buffer;)[D -} - public abstract interface class space/kscience/kmath/structures/FlaggedBuffer : space/kscience/kmath/structures/Buffer { public abstract fun getFlag (I)B } @@ -2403,13 +2477,14 @@ public final class space/kscience/kmath/structures/FlaggedDoubleBuffer : space/k public fun getFlag (I)B public final fun getFlags ()[B public fun getSize ()I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public final fun getValues ()[D public fun iterator ()Ljava/util/Iterator; public fun toString ()Ljava/lang/String; } -public final class space/kscience/kmath/structures/FloatBuffer : space/kscience/kmath/structures/PrimitiveBuffer { - public static final synthetic fun box-impl ([F)Lspace/kscience/kmath/structures/FloatBuffer; +public final class space/kscience/kmath/structures/Float32Buffer : space/kscience/kmath/structures/PrimitiveBuffer { + public static final synthetic fun box-impl ([F)Lspace/kscience/kmath/structures/Float32Buffer; public static fun constructor-impl ([F)[F public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public static fun copy-impl ([F)Lspace/kscience/kmath/structures/MutableBuffer; @@ -2422,6 +2497,8 @@ public final class space/kscience/kmath/structures/FloatBuffer : space/kscience/ public final fun getArray ()[F public fun getSize ()I public static fun getSize-impl ([F)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public static fun getType-V0oMfBY ([F)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([F)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2435,19 +2512,104 @@ public final class space/kscience/kmath/structures/FloatBuffer : space/kscience/ public final synthetic fun unbox-impl ()[F } -public final class space/kscience/kmath/structures/FloatBufferKt { - public static final fun FloatBuffer (ILkotlin/jvm/functions/Function1;)[F - public static final fun FloatBuffer ([F)[F +public final class space/kscience/kmath/structures/Float32BufferKt { + public static final fun Float32Buffer (ILkotlin/jvm/functions/Function1;)[F + public static final fun Float32Buffer ([F)[F public static final fun asBuffer ([F)[F public static final fun toFloatArray (Lspace/kscience/kmath/structures/Buffer;)[F } -public final class space/kscience/kmath/structures/IntBuffer : space/kscience/kmath/structures/PrimitiveBuffer { - public static final synthetic fun box-impl ([I)Lspace/kscience/kmath/structures/IntBuffer; +public final class space/kscience/kmath/structures/Float64Buffer : space/kscience/kmath/structures/PrimitiveBuffer { + public static final field Companion Lspace/kscience/kmath/structures/Float64Buffer$Companion; + public static final synthetic fun box-impl ([D)Lspace/kscience/kmath/structures/Float64Buffer; + public static fun constructor-impl ([D)[D + public synthetic fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public fun copy-E20IKn8 ()[D + public static fun copy-E20IKn8 ([D)[D + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl ([DLjava/lang/Object;)Z + public static final fun equals-impl0 ([D[D)Z + public fun get (I)Ljava/lang/Double; + public synthetic fun get (I)Ljava/lang/Object; + public static fun get-impl ([DI)Ljava/lang/Double; + public final fun getArray ()[D + public fun getSize ()I + public static fun getSize-impl ([D)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public static fun getType-V0oMfBY ([D)Lkotlin/reflect/KType; + public fun hashCode ()I + public static fun hashCode-impl ([D)I + public synthetic fun iterator ()Ljava/util/Iterator; + public fun iterator ()Lkotlin/collections/DoubleIterator; + public static fun iterator-impl ([D)Lkotlin/collections/DoubleIterator; + public fun set (ID)V + public synthetic fun set (ILjava/lang/Object;)V + public static fun set-impl ([DID)V + public fun toString ()Ljava/lang/String; + public static fun toString-impl ([D)Ljava/lang/String; + public final synthetic fun unbox-impl ()[D +} + +public final class space/kscience/kmath/structures/Float64Buffer$Companion { + public final fun zero-qFCK38E (I)[D +} + +public final class space/kscience/kmath/structures/Float64BufferKt { + public static final fun Float64Buffer (ILkotlin/jvm/functions/Function1;)[D + public static final fun Float64Buffer ([D)[D + public static final fun asBuffer ([D)[D + public static final fun toDoubleArray (Lspace/kscience/kmath/structures/Buffer;)[D + public static final fun toFloat64Buffer (Lspace/kscience/kmath/structures/Buffer;)[D +} + +public abstract interface class space/kscience/kmath/structures/Float64BufferTransform : space/kscience/kmath/operations/BufferTransform { + public synthetic fun transform (Lspace/kscience/kmath/structures/Buffer;)Lspace/kscience/kmath/structures/Buffer; + public abstract fun transform-kPrB3XE ([D)[D + public fun transform-qFCK38E (Lspace/kscience/kmath/structures/Buffer;)[D +} + +public final class space/kscience/kmath/structures/Int16Buffer : space/kscience/kmath/structures/MutableBuffer { + public static final synthetic fun box-impl ([S)Lspace/kscience/kmath/structures/Int16Buffer; + public static fun constructor-impl ([S)[S + public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public static fun copy-impl ([S)Lspace/kscience/kmath/structures/MutableBuffer; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl ([SLjava/lang/Object;)Z + public static final fun equals-impl0 ([S[S)Z + public synthetic fun get (I)Ljava/lang/Object; + public fun get (I)Ljava/lang/Short; + public static fun get-impl ([SI)Ljava/lang/Short; + public final fun getArray ()[S + public fun getSize ()I + public static fun getSize-impl ([S)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public static fun getType-V0oMfBY ([S)Lkotlin/reflect/KType; + public fun hashCode ()I + public static fun hashCode-impl ([S)I + public synthetic fun iterator ()Ljava/util/Iterator; + public fun iterator ()Lkotlin/collections/ShortIterator; + public static fun iterator-impl ([S)Lkotlin/collections/ShortIterator; + public synthetic fun set (ILjava/lang/Object;)V + public fun set (IS)V + public static fun set-impl ([SIS)V + public fun toString ()Ljava/lang/String; + public static fun toString-impl ([S)Ljava/lang/String; + public final synthetic fun unbox-impl ()[S +} + +public final class space/kscience/kmath/structures/Int16BufferKt { + public static final fun Int16Buffer (ILkotlin/jvm/functions/Function1;)[S + public static final fun Int16Buffer ([S)[S + public static final fun asBuffer ([S)[S + public static final fun toShortArray (Lspace/kscience/kmath/structures/Buffer;)[S +} + +public final class space/kscience/kmath/structures/Int32Buffer : space/kscience/kmath/structures/PrimitiveBuffer { + public static final synthetic fun box-impl ([I)Lspace/kscience/kmath/structures/Int32Buffer; public static fun constructor-impl ([I)[I public synthetic fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun copy-ir4F4A8 ()[I - public static fun copy-ir4F4A8 ([I)[I + public fun copy-M_oXE9g ()[I + public static fun copy-M_oXE9g ([I)[I public fun equals (Ljava/lang/Object;)Z public static fun equals-impl ([ILjava/lang/Object;)Z public static final fun equals-impl0 ([I[I)Z @@ -2457,6 +2619,8 @@ public final class space/kscience/kmath/structures/IntBuffer : space/kscience/km public final fun getArray ()[I public fun getSize ()I public static fun getSize-impl ([I)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public static fun getType-V0oMfBY ([I)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([I)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2470,30 +2634,15 @@ public final class space/kscience/kmath/structures/IntBuffer : space/kscience/km public final synthetic fun unbox-impl ()[I } -public final class space/kscience/kmath/structures/IntBufferKt { - public static final fun IntBuffer (ILkotlin/jvm/functions/Function1;)[I - public static final fun IntBuffer ([I)[I +public final class space/kscience/kmath/structures/Int32BufferKt { + public static final fun Int32Buffer (ILkotlin/jvm/functions/Function1;)[I + public static final fun Int32Buffer ([I)[I public static final fun asBuffer ([I)[I public static final fun toIntArray (Lspace/kscience/kmath/structures/Buffer;)[I } -public final class space/kscience/kmath/structures/ListBuffer : space/kscience/kmath/structures/Buffer { - public fun <init> (ILkotlin/jvm/functions/Function1;)V - public fun <init> (Ljava/util/List;)V - public fun get (I)Ljava/lang/Object; - public final fun getList ()Ljava/util/List; - public fun getSize ()I - public fun iterator ()Ljava/util/Iterator; - public fun toString ()Ljava/lang/String; -} - -public final class space/kscience/kmath/structures/ListBufferKt { - public static final fun asBuffer (Ljava/util/List;)Lspace/kscience/kmath/structures/ListBuffer; - public static final fun asMutableBuffer (Ljava/util/List;)Ljava/util/List; -} - -public final class space/kscience/kmath/structures/LongBuffer : space/kscience/kmath/structures/PrimitiveBuffer { - public static final synthetic fun box-impl ([J)Lspace/kscience/kmath/structures/LongBuffer; +public final class space/kscience/kmath/structures/Int64Buffer : space/kscience/kmath/structures/PrimitiveBuffer { + public static final synthetic fun box-impl ([J)Lspace/kscience/kmath/structures/Int64Buffer; public static fun constructor-impl ([J)[J public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public static fun copy-impl ([J)Lspace/kscience/kmath/structures/MutableBuffer; @@ -2506,6 +2655,8 @@ public final class space/kscience/kmath/structures/LongBuffer : space/kscience/k public final fun getArray ()[J public fun getSize ()I public static fun getSize-impl ([J)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public static fun getType-V0oMfBY ([J)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([J)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2519,27 +2670,62 @@ public final class space/kscience/kmath/structures/LongBuffer : space/kscience/k public final synthetic fun unbox-impl ()[J } -public final class space/kscience/kmath/structures/LongBufferKt { - public static final fun LongBuffer (ILkotlin/jvm/functions/Function1;)[J - public static final fun LongBuffer ([J)[J +public final class space/kscience/kmath/structures/Int64BufferKt { + public static final fun Int64Buffer (ILkotlin/jvm/functions/Function1;)[J + public static final fun Int64Buffer ([J)[J public static final fun asBuffer ([J)[J public static final fun toLongArray (Lspace/kscience/kmath/structures/Buffer;)[J } -public class space/kscience/kmath/structures/MemoryBuffer : space/kscience/kmath/structures/Buffer { - public static final field Companion Lspace/kscience/kmath/structures/MemoryBuffer$Companion; - public fun <init> (Lspace/kscience/kmath/memory/Memory;Lspace/kscience/kmath/memory/MemorySpec;)V - public fun get (I)Ljava/lang/Object; - protected final fun getMemory ()Lspace/kscience/kmath/memory/Memory; +public final class space/kscience/kmath/structures/Int8Buffer : space/kscience/kmath/structures/MutableBuffer { + public static final synthetic fun box-impl ([B)Lspace/kscience/kmath/structures/Int8Buffer; + public static fun constructor-impl ([B)[B + public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public static fun copy-impl ([B)Lspace/kscience/kmath/structures/MutableBuffer; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl ([BLjava/lang/Object;)Z + public static final fun equals-impl0 ([B[B)Z + public fun get (I)Ljava/lang/Byte; + public synthetic fun get (I)Ljava/lang/Object; + public static fun get-impl ([BI)Ljava/lang/Byte; + public final fun getArray ()[B public fun getSize ()I - protected final fun getSpec ()Lspace/kscience/kmath/memory/MemorySpec; + public static fun getSize-impl ([B)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public static fun getType-V0oMfBY ([B)Lkotlin/reflect/KType; + public fun hashCode ()I + public static fun hashCode-impl ([B)I + public synthetic fun iterator ()Ljava/util/Iterator; + public fun iterator ()Lkotlin/collections/ByteIterator; + public static fun iterator-impl ([B)Lkotlin/collections/ByteIterator; + public fun set (IB)V + public synthetic fun set (ILjava/lang/Object;)V + public static fun set-impl ([BIB)V + public fun toString ()Ljava/lang/String; + public static fun toString-impl ([B)Ljava/lang/String; + public final synthetic fun unbox-impl ()[B +} + +public final class space/kscience/kmath/structures/Int8BufferKt { + public static final fun Int8Buffer (ILkotlin/jvm/functions/Function1;)[B + public static final fun Int8Buffer ([B)[B + public static final fun asBuffer ([B)[B + public static final fun toByteArray (Lspace/kscience/kmath/structures/Buffer;)[B +} + +public final class space/kscience/kmath/structures/ListBuffer : space/kscience/kmath/structures/Buffer { + public synthetic fun <init> (Lkotlin/reflect/KType;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun get (I)Ljava/lang/Object; + public final fun getList ()Ljava/util/List; + public fun getSize ()I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun iterator ()Ljava/util/Iterator; public fun toString ()Ljava/lang/String; } -public final class space/kscience/kmath/structures/MemoryBuffer$Companion { - public final fun create (Lspace/kscience/kmath/memory/MemorySpec;I)Lspace/kscience/kmath/structures/MemoryBuffer; - public final fun create (Lspace/kscience/kmath/memory/MemorySpec;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MemoryBuffer; +public final class space/kscience/kmath/structures/ListBufferKt { + public static final fun asBuffer-Fnn_obI (Ljava/util/List;Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/ListBuffer; + public static final fun asMutableBuffer-Fnn_obI (Ljava/util/List;Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/MutableListBuffer; } public abstract interface class space/kscience/kmath/structures/MutableBuffer : space/kscience/kmath/structures/Buffer { @@ -2549,13 +2735,11 @@ public abstract interface class space/kscience/kmath/structures/MutableBuffer : } public final class space/kscience/kmath/structures/MutableBuffer$Companion { - public final fun auto (Lkotlin/reflect/KClass;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; - public final fun boxing (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; - public final fun double-CZ9oacQ (ILkotlin/jvm/functions/Function1;)[D - public final fun float-YxruXGw (ILkotlin/jvm/functions/Function1;)[F - public final fun int-Ye6GY2U (ILkotlin/jvm/functions/Function1;)[I - public final fun long-BuQOeTY (ILkotlin/jvm/functions/Function1;)[J - public final fun short-1yRgbGw (ILkotlin/jvm/functions/Function1;)[S + public final fun double-Vq5tpWc (ILkotlin/jvm/functions/Function1;)[D + public final fun float-pmys_WE (ILkotlin/jvm/functions/Function1;)[F + public final fun int-Tednjrs (ILkotlin/jvm/functions/Function1;)[I + public final fun long-1n4IcUs (ILkotlin/jvm/functions/Function1;)[J + public final fun short-CjmdtSE (ILkotlin/jvm/functions/Function1;)[S } public abstract interface class space/kscience/kmath/structures/MutableBufferFactory : space/kscience/kmath/structures/BufferFactory { @@ -2564,44 +2748,34 @@ public abstract interface class space/kscience/kmath/structures/MutableBufferFac } public final class space/kscience/kmath/structures/MutableBufferFactory$Companion { - public final fun boxing ()Lspace/kscience/kmath/structures/MutableBufferFactory; +} + +public final class space/kscience/kmath/structures/MutableBufferKt { + public static final fun MutableBuffer--rwW0uw (Lkotlin/reflect/KType;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; } public final class space/kscience/kmath/structures/MutableListBuffer : space/kscience/kmath/structures/MutableBuffer { - public static final synthetic fun box-impl (Ljava/util/List;)Lspace/kscience/kmath/structures/MutableListBuffer; - public static fun constructor-impl (ILkotlin/jvm/functions/Function1;)Ljava/util/List; - public static fun constructor-impl (Ljava/util/List;)Ljava/util/List; + public synthetic fun <init> (Lkotlin/reflect/KType;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl (Ljava/util/List;)Lspace/kscience/kmath/structures/MutableBuffer; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Ljava/util/List;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Ljava/util/List;Ljava/util/List;)Z public fun get (I)Ljava/lang/Object; - public static fun get-impl (Ljava/util/List;I)Ljava/lang/Object; public final fun getList ()Ljava/util/List; public fun getSize ()I - public static fun getSize-impl (Ljava/util/List;)I - public fun hashCode ()I - public static fun hashCode-impl (Ljava/util/List;)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun iterator ()Ljava/util/Iterator; - public static fun iterator-impl (Ljava/util/List;)Ljava/util/Iterator; public fun set (ILjava/lang/Object;)V - public static fun set-impl (Ljava/util/List;ILjava/lang/Object;)V public fun toString ()Ljava/lang/String; - public static fun toString-impl (Ljava/util/List;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Ljava/util/List; } -public final class space/kscience/kmath/structures/MutableMemoryBuffer : space/kscience/kmath/structures/MemoryBuffer, space/kscience/kmath/structures/MutableBuffer { - public static final field Companion Lspace/kscience/kmath/structures/MutableMemoryBuffer$Companion; - public fun <init> (Lspace/kscience/kmath/memory/Memory;Lspace/kscience/kmath/memory/MemorySpec;)V - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun set (ILjava/lang/Object;)V +public final class space/kscience/kmath/structures/ParallelBufferFactory : space/kscience/kmath/structures/MutableBufferFactory { + public synthetic fun <init> (Lkotlin/reflect/KType;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public synthetic fun invoke (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/Buffer; + public fun invoke (ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; } -public final class space/kscience/kmath/structures/MutableMemoryBuffer$Companion { - public final fun create (Lspace/kscience/kmath/memory/MemorySpec;I)Lspace/kscience/kmath/structures/MutableMemoryBuffer; - public final fun create (Lspace/kscience/kmath/memory/MemorySpec;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableMemoryBuffer; +public final class space/kscience/kmath/structures/ParallelMutableBufferKt { + public static final fun parallel-Fnn_obI (Lspace/kscience/kmath/structures/MutableBufferFactory$Companion;Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/MutableBufferFactory; + public static final fun parallel-wcOc40k (Lspace/kscience/kmath/structures/MutableBuffer$Companion;Lkotlin/reflect/KType;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; } public final class space/kscience/kmath/structures/PermutedBuffer : space/kscience/kmath/structures/BufferView { @@ -2628,74 +2802,22 @@ public final class space/kscience/kmath/structures/PermutedMutableBuffer : space public abstract interface class space/kscience/kmath/structures/PrimitiveBuffer : space/kscience/kmath/structures/MutableBuffer { } -public final class space/kscience/kmath/structures/ReadOnlyBuffer : space/kscience/kmath/structures/Buffer { - public static final synthetic fun box-impl (Lspace/kscience/kmath/structures/MutableBuffer;)Lspace/kscience/kmath/structures/ReadOnlyBuffer; - public static fun constructor-impl (Lspace/kscience/kmath/structures/MutableBuffer;)Lspace/kscience/kmath/structures/MutableBuffer; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl (Lspace/kscience/kmath/structures/MutableBuffer;Ljava/lang/Object;)Z - public static final fun equals-impl0 (Lspace/kscience/kmath/structures/MutableBuffer;Lspace/kscience/kmath/structures/MutableBuffer;)Z - public fun get (I)Ljava/lang/Object; - public static fun get-impl (Lspace/kscience/kmath/structures/MutableBuffer;I)Ljava/lang/Object; - public final fun getBuffer ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun getSize ()I - public static fun getSize-impl (Lspace/kscience/kmath/structures/MutableBuffer;)I - public fun hashCode ()I - public static fun hashCode-impl (Lspace/kscience/kmath/structures/MutableBuffer;)I - public fun iterator ()Ljava/util/Iterator; - public static fun iterator-impl (Lspace/kscience/kmath/structures/MutableBuffer;)Ljava/util/Iterator; - public fun toString ()Ljava/lang/String; - public static fun toString-impl (Lspace/kscience/kmath/structures/MutableBuffer;)Ljava/lang/String; - public final synthetic fun unbox-impl ()Lspace/kscience/kmath/structures/MutableBuffer; -} - -public final class space/kscience/kmath/structures/ShortBuffer : space/kscience/kmath/structures/MutableBuffer { - public static final synthetic fun box-impl ([S)Lspace/kscience/kmath/structures/ShortBuffer; - public static fun constructor-impl ([S)[S - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl ([S)Lspace/kscience/kmath/structures/MutableBuffer; - public fun equals (Ljava/lang/Object;)Z - public static fun equals-impl ([SLjava/lang/Object;)Z - public static final fun equals-impl0 ([S[S)Z - public synthetic fun get (I)Ljava/lang/Object; - public fun get (I)Ljava/lang/Short; - public static fun get-impl ([SI)Ljava/lang/Short; - public final fun getArray ()[S - public fun getSize ()I - public static fun getSize-impl ([S)I - public fun hashCode ()I - public static fun hashCode-impl ([S)I - public synthetic fun iterator ()Ljava/util/Iterator; - public fun iterator ()Lkotlin/collections/ShortIterator; - public static fun iterator-impl ([S)Lkotlin/collections/ShortIterator; - public synthetic fun set (ILjava/lang/Object;)V - public fun set (IS)V - public static fun set-impl ([SIS)V - public fun toString ()Ljava/lang/String; - public static fun toString-impl ([S)Ljava/lang/String; - public final synthetic fun unbox-impl ()[S -} - -public final class space/kscience/kmath/structures/ShortBufferKt { - public static final fun ShortBuffer (ILkotlin/jvm/functions/Function1;)[S - public static final fun ShortBuffer ([S)[S - public static final fun asBuffer ([S)[S - public static final fun toShortArray (Lspace/kscience/kmath/structures/Buffer;)[S -} - public final class space/kscience/kmath/structures/ValueFlag : java/lang/Enum { public static final field MISSING Lspace/kscience/kmath/structures/ValueFlag; public static final field NAN Lspace/kscience/kmath/structures/ValueFlag; public static final field NEGATIVE_INFINITY Lspace/kscience/kmath/structures/ValueFlag; public static final field POSITIVE_INFINITY Lspace/kscience/kmath/structures/ValueFlag; + public static fun getEntries ()Lkotlin/enums/EnumEntries; public final fun getMask ()B public static fun valueOf (Ljava/lang/String;)Lspace/kscience/kmath/structures/ValueFlag; public static fun values ()[Lspace/kscience/kmath/structures/ValueFlag; } public final class space/kscience/kmath/structures/VirtualBuffer : space/kscience/kmath/structures/Buffer { - public fun <init> (ILkotlin/jvm/functions/Function1;)V + public synthetic fun <init> (Lkotlin/reflect/KType;ILkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun get (I)Ljava/lang/Object; public fun getSize ()I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun iterator ()Ljava/util/Iterator; public fun toString ()Ljava/lang/String; } diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index 23fedbda4..0e061c6dd 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -71,4 +71,12 @@ readme { id = "autodiff", ref = "src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt" ) { "Automatic differentiation" } + + feature( + id="Parallel linear algebra" + ){ + """ + Parallel implementation for `LinearAlgebra` + """.trimIndent() + } } diff --git a/kmath-coroutines/README.md b/kmath-coroutines/README.md index 21831e514..4b7081bb1 100644 --- a/kmath-coroutines/README.md +++ b/kmath-coroutines/README.md @@ -6,19 +6,8 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-coroutines:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-coroutines:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-coroutines:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-coroutines:0.4.0-dev-1") + implementation("space.kscience:kmath-coroutines:0.4.0-dev-3") } ``` diff --git a/kmath-dimensions/README.md b/kmath-dimensions/README.md index 2e7250b51..c1c5e0dc2 100644 --- a/kmath-dimensions/README.md +++ b/kmath-dimensions/README.md @@ -6,19 +6,8 @@ A proof of concept module for adding type-safe dimensions to structures ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-dimensions:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-dimensions:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-dimensions:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-dimensions:0.4.0-dev-1") + implementation("space.kscience:kmath-dimensions:0.4.0-dev-3") } ``` diff --git a/kmath-ejml/README.md b/kmath-ejml/README.md index ad80ba183..dcde8efd3 100644 --- a/kmath-ejml/README.md +++ b/kmath-ejml/README.md @@ -9,19 +9,8 @@ EJML based linear algebra implementation. ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-ejml:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-ejml:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-ejml:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -30,6 +19,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-ejml:0.4.0-dev-1") + implementation("space.kscience:kmath-ejml:0.4.0-dev-3") } ``` diff --git a/kmath-for-real/README.md b/kmath-for-real/README.md index 638b15bfa..2c880f4f9 100644 --- a/kmath-for-real/README.md +++ b/kmath-for-real/README.md @@ -9,19 +9,8 @@ Specialization of KMath APIs for Double numbers. ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-for-real:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-for-real:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-for-real:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -30,6 +19,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-for-real:0.4.0-dev-1") + implementation("space.kscience:kmath-for-real:0.4.0-dev-3") } ``` diff --git a/kmath-functions/README.md b/kmath-functions/README.md index 929fd9172..1ee4149bd 100644 --- a/kmath-functions/README.md +++ b/kmath-functions/README.md @@ -11,19 +11,8 @@ Functions and interpolations. ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-functions:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-functions:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-functions:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -32,6 +21,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-functions:0.4.0-dev-1") + implementation("space.kscience:kmath-functions:0.4.0-dev-3") } ``` diff --git a/kmath-geometry/README.md b/kmath-geometry/README.md index 480945c4f..601610d3d 100644 --- a/kmath-geometry/README.md +++ b/kmath-geometry/README.md @@ -6,19 +6,8 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-geometry:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-geometry:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-geometry:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-geometry:0.4.0-dev-1") + implementation("space.kscience:kmath-geometry:0.4.0-dev-3") } ``` diff --git a/kmath-histograms/README.md b/kmath-histograms/README.md index bc7f0fa5b..e9aaad3a8 100644 --- a/kmath-histograms/README.md +++ b/kmath-histograms/README.md @@ -6,19 +6,8 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-histograms:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-histograms:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-histograms:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-histograms:0.4.0-dev-1") + implementation("space.kscience:kmath-histograms:0.4.0-dev-3") } ``` diff --git a/kmath-jafama/README.md b/kmath-jafama/README.md index 47142f174..dc183ca37 100644 --- a/kmath-jafama/README.md +++ b/kmath-jafama/README.md @@ -7,19 +7,8 @@ Integration with [Jafama](https://github.com/jeffhain/jafama). ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-jafama:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-jafama:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-jafama:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -28,7 +17,7 @@ repositories { } dependencies { - implementation("space.kscience:kmath-jafama:0.4.0-dev-1") + implementation("space.kscience:kmath-jafama:0.4.0-dev-3") } ``` diff --git a/kmath-jafama/api/kmath-jafama.api b/kmath-jafama/api/kmath-jafama.api new file mode 100644 index 000000000..989634e9b --- /dev/null +++ b/kmath-jafama/api/kmath-jafama.api @@ -0,0 +1,128 @@ +public final class space/kscience/kmath/jafama/JafamaDoubleField : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/ScaleOperations { + public static final field INSTANCE Lspace/kscience/kmath/jafama/JafamaDoubleField; + public fun acos (D)Ljava/lang/Double; + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (D)Ljava/lang/Double; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun add (DD)Ljava/lang/Double; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun asin (D)Ljava/lang/Double; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (D)Ljava/lang/Double; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan (D)Ljava/lang/Double; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (D)Ljava/lang/Double; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun cos (D)Ljava/lang/Double; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (D)Ljava/lang/Double; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun div (DD)Ljava/lang/Double; + public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (DD)Ljava/lang/Double; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun exp (D)Ljava/lang/Double; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public fun getOne ()Ljava/lang/Double; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Double; + public synthetic fun getZero ()Ljava/lang/Object; + public fun ln (D)Ljava/lang/Double; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (DD)Ljava/lang/Double; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (DD)Ljava/lang/Double; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (D)Ljava/lang/Double; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Double; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun plus (DD)Ljava/lang/Double; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun power (DLjava/lang/Number;)Ljava/lang/Double; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun scale (DD)Ljava/lang/Double; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun sin (D)Ljava/lang/Double; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (D)Ljava/lang/Double; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sqrt (D)Ljava/lang/Double; + public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan (D)Ljava/lang/Double; + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (D)Ljava/lang/Double; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun times (DD)Ljava/lang/Double; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (D)Ljava/lang/Double; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; +} + +public final class space/kscience/kmath/jafama/StrictJafamaDoubleField : space/kscience/kmath/operations/ExtendedField, space/kscience/kmath/operations/Norm, space/kscience/kmath/operations/ScaleOperations { + public static final field INSTANCE Lspace/kscience/kmath/jafama/StrictJafamaDoubleField; + public fun acos (D)Ljava/lang/Double; + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (D)Ljava/lang/Double; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun add (DD)Ljava/lang/Double; + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun asin (D)Ljava/lang/Double; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (D)Ljava/lang/Double; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan (D)Ljava/lang/Double; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (D)Ljava/lang/Double; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2; + public fun cos (D)Ljava/lang/Double; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (D)Ljava/lang/Double; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun div (DD)Ljava/lang/Double; + public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun divide (DD)Ljava/lang/Double; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun exp (D)Ljava/lang/Double; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun getBufferFactory ()Lspace/kscience/kmath/structures/MutableBufferFactory; + public fun getOne ()Ljava/lang/Double; + public synthetic fun getOne ()Ljava/lang/Object; + public fun getZero ()Ljava/lang/Double; + public synthetic fun getZero ()Ljava/lang/Object; + public fun ln (D)Ljava/lang/Double; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (DD)Ljava/lang/Double; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun multiply (DD)Ljava/lang/Double; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun norm (D)Ljava/lang/Double; + public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object; + public fun number (Ljava/lang/Number;)Ljava/lang/Double; + public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object; + public fun plus (DD)Ljava/lang/Double; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun power (DLjava/lang/Number;)Ljava/lang/Double; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun scale (DD)Ljava/lang/Double; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun sin (D)Ljava/lang/Double; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (D)Ljava/lang/Double; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sqrt (D)Ljava/lang/Double; + public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; + public fun tan (D)Ljava/lang/Double; + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (D)Ljava/lang/Double; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun times (DD)Ljava/lang/Double; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (D)Ljava/lang/Double; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; +} + diff --git a/kmath-jupyter/README.md b/kmath-jupyter/README.md index 2b26878dc..525ae673b 100644 --- a/kmath-jupyter/README.md +++ b/kmath-jupyter/README.md @@ -6,19 +6,8 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-jupyter:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-jupyter:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-jupyter:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-jupyter:0.4.0-dev-1") + implementation("space.kscience:kmath-jupyter:0.4.0-dev-3") } ``` diff --git a/kmath-kotlingrad/README.md b/kmath-kotlingrad/README.md index f1a918b4b..a66c31686 100644 --- a/kmath-kotlingrad/README.md +++ b/kmath-kotlingrad/README.md @@ -8,19 +8,8 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-kotlingrad:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-kotlingrad:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-kotlingrad:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -29,6 +18,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-kotlingrad:0.4.0-dev-1") + implementation("space.kscience:kmath-kotlingrad:0.4.0-dev-3") } ``` diff --git a/kmath-memory/README.md b/kmath-memory/README.md index 594588ecf..d6824add0 100644 --- a/kmath-memory/README.md +++ b/kmath-memory/README.md @@ -6,19 +6,8 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-memory:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-memory:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-memory:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-memory:0.4.0-dev-1") + implementation("space.kscience:kmath-memory:0.4.0-dev-3") } ``` diff --git a/kmath-memory/api/kmath-memory.api b/kmath-memory/api/kmath-memory.api index cebb04af2..67303dd97 100644 --- a/kmath-memory/api/kmath-memory.api +++ b/kmath-memory/api/kmath-memory.api @@ -1,14 +1,3 @@ -public abstract interface annotation class space/kscience/kmath/PerformancePitfall : java/lang/annotation/Annotation { - public abstract fun message ()Ljava/lang/String; -} - -public abstract interface annotation class space/kscience/kmath/UnsafeKMathAPI : java/lang/annotation/Annotation { - public abstract fun message ()Ljava/lang/String; -} - -public abstract interface annotation class space/kscience/kmath/UnstableKMathAPI : java/lang/annotation/Annotation { -} - public final class space/kscience/kmath/memory/ByteBufferMemory : space/kscience/kmath/memory/Memory { public fun <init> (Ljava/nio/ByteBuffer;II)V public synthetic fun <init> (Ljava/nio/ByteBuffer;IIILkotlin/jvm/internal/DefaultConstructorMarker;)V @@ -42,6 +31,23 @@ public abstract interface class space/kscience/kmath/memory/Memory { public final class space/kscience/kmath/memory/Memory$Companion { } +public class space/kscience/kmath/memory/MemoryBuffer : space/kscience/kmath/structures/Buffer { + public static final field Companion Lspace/kscience/kmath/memory/MemoryBuffer$Companion; + public fun <init> (Lspace/kscience/kmath/memory/Memory;Lspace/kscience/kmath/memory/MemorySpec;)V + public fun get (I)Ljava/lang/Object; + protected final fun getMemory ()Lspace/kscience/kmath/memory/Memory; + public fun getSize ()I + protected final fun getSpec ()Lspace/kscience/kmath/memory/MemorySpec; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public fun iterator ()Ljava/util/Iterator; + public fun toString ()Ljava/lang/String; +} + +public final class space/kscience/kmath/memory/MemoryBuffer$Companion { + public final fun create (Lspace/kscience/kmath/memory/MemorySpec;I)Lspace/kscience/kmath/memory/MemoryBuffer; + public final fun create (Lspace/kscience/kmath/memory/MemorySpec;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/memory/MemoryBuffer; +} + public final class space/kscience/kmath/memory/MemoryKt { public static final fun read (Lspace/kscience/kmath/memory/Memory;Lkotlin/jvm/functions/Function1;)Ljava/lang/Object; public static final fun write (Lspace/kscience/kmath/memory/Memory;Lkotlin/jvm/functions/Function1;)V @@ -58,7 +64,7 @@ public abstract interface class space/kscience/kmath/memory/MemoryReader : java/ public abstract fun readShort (I)S } -public abstract interface class space/kscience/kmath/memory/MemorySpec { +public abstract interface class space/kscience/kmath/memory/MemorySpec : space/kscience/attributes/WithType { public abstract fun getObjectSize ()I public abstract fun read (Lspace/kscience/kmath/memory/MemoryReader;I)Ljava/lang/Object; public abstract fun write (Lspace/kscience/kmath/memory/MemoryWriter;ILjava/lang/Object;)V @@ -81,3 +87,15 @@ public abstract interface class space/kscience/kmath/memory/MemoryWriter : java/ public abstract fun writeShort (IS)V } +public final class space/kscience/kmath/memory/MutableMemoryBuffer : space/kscience/kmath/memory/MemoryBuffer, space/kscience/kmath/structures/MutableBuffer { + public static final field Companion Lspace/kscience/kmath/memory/MutableMemoryBuffer$Companion; + public fun <init> (Lspace/kscience/kmath/memory/Memory;Lspace/kscience/kmath/memory/MemorySpec;)V + public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public fun set (ILjava/lang/Object;)V +} + +public final class space/kscience/kmath/memory/MutableMemoryBuffer$Companion { + public final fun create (Lspace/kscience/kmath/memory/MemorySpec;I)Lspace/kscience/kmath/memory/MutableMemoryBuffer; + public final fun create (Lspace/kscience/kmath/memory/MemorySpec;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/memory/MutableMemoryBuffer; +} + diff --git a/kmath-multik/README.md b/kmath-multik/README.md index 127b12a49..f0bf10208 100644 --- a/kmath-multik/README.md +++ b/kmath-multik/README.md @@ -6,19 +6,8 @@ JetBrains Multik connector ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-multik:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-multik:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-multik:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-multik:0.4.0-dev-1") + implementation("space.kscience:kmath-multik:0.4.0-dev-3") } ``` diff --git a/kmath-nd4j/README.md b/kmath-nd4j/README.md index b299c1b37..55d6844bc 100644 --- a/kmath-nd4j/README.md +++ b/kmath-nd4j/README.md @@ -9,19 +9,8 @@ ND4J based implementations of KMath abstractions. ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-nd4j:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -30,7 +19,7 @@ repositories { } dependencies { - implementation("space.kscience:kmath-nd4j:0.4.0-dev-1") + implementation("space.kscience:kmath-nd4j:0.4.0-dev-3") } ``` diff --git a/kmath-nd4j/api/kmath-nd4j.api b/kmath-nd4j/api/kmath-nd4j.api new file mode 100644 index 000000000..74c6b8805 --- /dev/null +++ b/kmath-nd4j/api/kmath-nd4j.api @@ -0,0 +1,395 @@ +public final class space/kscience/kmath/nd4j/DoubleNd4jArrayField : space/kscience/kmath/nd4j/DoubleNd4jArrayFieldOps, space/kscience/kmath/nd/FieldND { + public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getShape-IIYLAfE ()[I +} + +public class space/kscience/kmath/nd4j/DoubleNd4jArrayFieldOps : space/kscience/kmath/nd4j/Nd4jArrayExtendedFieldOps { + public static final field Companion Lspace/kscience/kmath/nd4j/DoubleNd4jArrayFieldOps$Companion; + public fun <init> ()V + public fun div (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun div (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Algebra; + public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Float64Field; + public fun getNdArray (Lspace/kscience/kmath/nd/StructureND;)Lorg/nd4j/linalg/api/ndarray/INDArray; + public fun minus (DLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun minus (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public synthetic fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; + public fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun times (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun wrap (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + +public final class space/kscience/kmath/nd4j/DoubleNd4jArrayFieldOps$Companion : space/kscience/kmath/nd4j/DoubleNd4jArrayFieldOps { +} + +public final class space/kscience/kmath/nd4j/DoubleNd4jTensorAlgebra : space/kscience/kmath/nd4j/Nd4jTensorAlgebra { + public static final field INSTANCE Lspace/kscience/kmath/nd4j/DoubleNd4jTensorAlgebra; + public fun diagonalEmbedding (Lspace/kscience/kmath/nd/StructureND;III)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Algebra; + public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Float64Field; + public fun getNdArray (Lspace/kscience/kmath/nd/StructureND;)Lorg/nd4j/linalg/api/ndarray/INDArray; + public fun max (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Double; + public synthetic fun max (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Object; + public fun mean (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Double; + public synthetic fun mean (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Object; + public fun min (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Double; + public synthetic fun min (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Object; + public synthetic fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun std (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Double; + public synthetic fun std (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Object; + public fun sum (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Double; + public synthetic fun sum (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Object; + public fun valueOrNull (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Double; + public synthetic fun valueOrNull (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Object; + public fun variance (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Double; + public synthetic fun variance (Lspace/kscience/kmath/nd/StructureND;)Ljava/lang/Object; + public fun wrap (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + +public final class space/kscience/kmath/nd4j/FloatNd4jArrayField : space/kscience/kmath/nd4j/FloatNd4jArrayFieldOps, space/kscience/kmath/nd/RingND { + public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getShape-IIYLAfE ()[I +} + +public class space/kscience/kmath/nd4j/FloatNd4jArrayFieldOps : space/kscience/kmath/nd4j/Nd4jArrayExtendedFieldOps { + public static final field Companion Lspace/kscience/kmath/nd4j/FloatNd4jArrayFieldOps$Companion; + public fun <init> ()V + public fun div (FLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun div (Lspace/kscience/kmath/nd/StructureND;F)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Algebra; + public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Float32Field; + public fun getNdArray (Lspace/kscience/kmath/nd/StructureND;)Lorg/nd4j/linalg/api/ndarray/INDArray; + public fun minus (FLspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun minus (Lspace/kscience/kmath/nd/StructureND;F)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;F)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun scale (Ljava/lang/Object;D)Ljava/lang/Object; + public fun scale (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/nd/StructureND; + public fun times (Lspace/kscience/kmath/nd/StructureND;F)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun wrap (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + +public final class space/kscience/kmath/nd4j/FloatNd4jArrayFieldOps$Companion : space/kscience/kmath/nd4j/FloatNd4jArrayFieldOps { +} + +public final class space/kscience/kmath/nd4j/IntNd4jArrayRing : space/kscience/kmath/nd4j/IntNd4jArrayRingOps, space/kscience/kmath/nd/RingND { + public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun getShape-IIYLAfE ()[I +} + +public class space/kscience/kmath/nd4j/IntNd4jArrayRingOps : space/kscience/kmath/nd4j/Nd4jArrayRingOps { + public static final field Companion Lspace/kscience/kmath/nd4j/IntNd4jArrayRingOps$Companion; + public fun <init> ()V + public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Algebra; + public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Int32Ring; + public fun getNdArray (Lspace/kscience/kmath/nd/StructureND;)Lorg/nd4j/linalg/api/ndarray/INDArray; + public fun minus (ILspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun minus (Lspace/kscience/kmath/nd/StructureND;I)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;I)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun times (Lspace/kscience/kmath/nd/StructureND;I)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public fun wrap (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + +public final class space/kscience/kmath/nd4j/IntNd4jArrayRingOps$Companion : space/kscience/kmath/nd4j/IntNd4jArrayRingOps { +} + +public abstract interface class space/kscience/kmath/nd4j/Nd4jArrayAlgebra : space/kscience/kmath/nd/AlgebraND { + public abstract fun getNdArray (Lspace/kscience/kmath/nd/StructureND;)Lorg/nd4j/linalg/api/ndarray/INDArray; + public synthetic fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public abstract fun wrap (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + +public final class space/kscience/kmath/nd4j/Nd4jArrayAlgebraKt { + public static final fun getNd4j (Lspace/kscience/kmath/operations/Float32Field;)Lspace/kscience/kmath/nd4j/FloatNd4jArrayFieldOps; + public static final fun getNd4j (Lspace/kscience/kmath/operations/Float64Field;)Lspace/kscience/kmath/nd4j/DoubleNd4jArrayFieldOps; + public static final fun getNd4j (Lspace/kscience/kmath/operations/Int32Ring;)Lspace/kscience/kmath/nd4j/IntNd4jArrayRingOps; + public static final fun nd4j (Lspace/kscience/kmath/operations/Float32Field;I[I)Lspace/kscience/kmath/nd4j/FloatNd4jArrayField; + public static final fun nd4j (Lspace/kscience/kmath/operations/Float64Field;I[I)Lspace/kscience/kmath/nd4j/DoubleNd4jArrayField; + public static final fun nd4j (Lspace/kscience/kmath/operations/Int32Ring;I[I)Lspace/kscience/kmath/nd4j/IntNd4jArrayRing; +} + +public final class space/kscience/kmath/nd4j/Nd4jArrayDoubleStructure : space/kscience/kmath/nd4j/Nd4jArrayStructure, space/kscience/kmath/nd/StructureNDOfDouble { + public fun <init> (Lorg/nd4j/linalg/api/ndarray/INDArray;)V + public final fun component1 ()Lorg/nd4j/linalg/api/ndarray/INDArray; + public final fun copy (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayDoubleStructure; + public static synthetic fun copy$default (Lspace/kscience/kmath/nd4j/Nd4jArrayDoubleStructure;Lorg/nd4j/linalg/api/ndarray/INDArray;ILjava/lang/Object;)Lspace/kscience/kmath/nd4j/Nd4jArrayDoubleStructure; + public fun equals (Ljava/lang/Object;)Z + public fun get ([I)Ljava/lang/Double; + public synthetic fun get ([I)Ljava/lang/Object; + public fun getDouble ([I)D + public fun getNdArray ()Lorg/nd4j/linalg/api/ndarray/INDArray; + public fun hashCode ()I + public fun set ([ID)V + public synthetic fun set ([ILjava/lang/Object;)V + public fun toString ()Ljava/lang/String; +} + +public abstract interface class space/kscience/kmath/nd4j/Nd4jArrayExtendedFieldOps : space/kscience/kmath/nd4j/Nd4jArrayField, space/kscience/kmath/operations/ExtendedFieldOps, space/kscience/kmath/operations/PowerOperations { + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public fun acos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun acosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public fun asin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun asinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public fun atan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public fun cos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public fun cosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public fun exp (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public fun ln (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public fun sin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; + public fun sqrt (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; +} + +public abstract interface class space/kscience/kmath/nd4j/Nd4jArrayField : space/kscience/kmath/nd/FieldOpsND, space/kscience/kmath/nd4j/Nd4jArrayRingOps { + public static final field Companion Lspace/kscience/kmath/nd4j/Nd4jArrayField$Companion; + public fun div (Ljava/lang/Number;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun divide (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun divide (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + +public final class space/kscience/kmath/nd4j/Nd4jArrayField$Companion { +} + +public final class space/kscience/kmath/nd4j/Nd4jArrayFloatStructure : space/kscience/kmath/nd4j/Nd4jArrayStructure { + public fun <init> (Lorg/nd4j/linalg/api/ndarray/INDArray;)V + public final fun component1 ()Lorg/nd4j/linalg/api/ndarray/INDArray; + public final fun copy (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayFloatStructure; + public static synthetic fun copy$default (Lspace/kscience/kmath/nd4j/Nd4jArrayFloatStructure;Lorg/nd4j/linalg/api/ndarray/INDArray;ILjava/lang/Object;)Lspace/kscience/kmath/nd4j/Nd4jArrayFloatStructure; + public fun equals (Ljava/lang/Object;)Z + public fun get ([I)Ljava/lang/Float; + public synthetic fun get ([I)Ljava/lang/Object; + public fun getNdArray ()Lorg/nd4j/linalg/api/ndarray/INDArray; + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public fun hashCode ()I + public fun set ([IF)V + public synthetic fun set ([ILjava/lang/Object;)V + public fun toString ()Ljava/lang/String; +} + +public abstract interface class space/kscience/kmath/nd4j/Nd4jArrayGroupOps : space/kscience/kmath/nd/GroupOpsND, space/kscience/kmath/nd4j/Nd4jArrayAlgebra { + public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun add (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public fun minus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun multiply (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + +public final class space/kscience/kmath/nd4j/Nd4jArrayIntStructure : space/kscience/kmath/nd4j/Nd4jArrayStructure, space/kscience/kmath/nd/StructureNDOfInt { + public fun <init> (Lorg/nd4j/linalg/api/ndarray/INDArray;)V + public final fun component1 ()Lorg/nd4j/linalg/api/ndarray/INDArray; + public final fun copy (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayIntStructure; + public static synthetic fun copy$default (Lspace/kscience/kmath/nd4j/Nd4jArrayIntStructure;Lorg/nd4j/linalg/api/ndarray/INDArray;ILjava/lang/Object;)Lspace/kscience/kmath/nd4j/Nd4jArrayIntStructure; + public fun equals (Ljava/lang/Object;)Z + public fun get ([I)Ljava/lang/Integer; + public synthetic fun get ([I)Ljava/lang/Object; + public fun getInt ([I)I + public fun getNdArray ()Lorg/nd4j/linalg/api/ndarray/INDArray; + public fun hashCode ()I + public fun set ([II)V + public synthetic fun set ([ILjava/lang/Object;)V + public fun toString ()Ljava/lang/String; +} + +public abstract interface class space/kscience/kmath/nd4j/Nd4jArrayRingOps : space/kscience/kmath/nd/RingOpsND, space/kscience/kmath/nd4j/Nd4jArrayGroupOps { + public static final field Companion Lspace/kscience/kmath/nd4j/Nd4jArrayRingOps$Companion; + public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun multiply (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun multiply (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + +public final class space/kscience/kmath/nd4j/Nd4jArrayRingOps$Companion { +} + +public abstract class space/kscience/kmath/nd4j/Nd4jArrayStructure : space/kscience/kmath/nd/MutableStructureND { + public fun elements ()Lkotlin/sequences/Sequence; + public abstract fun getNdArray ()Lorg/nd4j/linalg/api/ndarray/INDArray; + public fun getShape-IIYLAfE ()[I +} + +public final class space/kscience/kmath/nd4j/Nd4jArrayStructureKt { + public static final fun asDoubleStructure (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public static final fun asFloatStructure (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public static final fun asIntStructure (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayIntStructure; +} + +public abstract interface class space/kscience/kmath/nd4j/Nd4jTensorAlgebra : space/kscience/kmath/tensors/api/AnalyticTensorAlgebra { + public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun acos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun acos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun acosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun acosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun argMax (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd/MutableStructureND; + public fun argMin (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun asin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun asin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun asinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun asinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun atan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun atan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun atanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun ceil (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun ceil (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun cos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun cos (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun cosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun cosh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun div (Ljava/lang/Number;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun div (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun div (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun div (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun div (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun divAssign (Lspace/kscience/kmath/nd/MutableStructureND;Ljava/lang/Number;)V + public synthetic fun divAssign (Lspace/kscience/kmath/nd/MutableStructureND;Ljava/lang/Object;)V + public fun divAssign (Lspace/kscience/kmath/nd/MutableStructureND;Lspace/kscience/kmath/nd/StructureND;)V + public synthetic fun dot (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun dot (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun exp (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun exp (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun floor (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun floor (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public abstract fun getNdArray (Lspace/kscience/kmath/nd/StructureND;)Lorg/nd4j/linalg/api/ndarray/INDArray; + public synthetic fun getTensor (Lspace/kscience/kmath/nd/MutableStructureND;I)Lspace/kscience/kmath/nd/MutableStructureND; + public fun getTensor (Lspace/kscience/kmath/nd/MutableStructureND;I)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun ln (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun ln (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; + public fun map (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun max (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd/MutableStructureND; + public fun max (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun mean (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun min (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd/MutableStructureND; + public fun min (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun minus (Ljava/lang/Number;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun minus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun minus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun minus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun minus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun minusAssign (Lspace/kscience/kmath/nd/MutableStructureND;Ljava/lang/Number;)V + public synthetic fun minusAssign (Lspace/kscience/kmath/nd/MutableStructureND;Ljava/lang/Object;)V + public fun minusAssign (Lspace/kscience/kmath/nd/MutableStructureND;Lspace/kscience/kmath/nd/StructureND;)V + public abstract fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun plus (Ljava/lang/Number;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun plus (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun plus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun plusAssign (Lspace/kscience/kmath/nd/MutableStructureND;Ljava/lang/Number;)V + public synthetic fun plusAssign (Lspace/kscience/kmath/nd/MutableStructureND;Ljava/lang/Object;)V + public fun plusAssign (Lspace/kscience/kmath/nd/MutableStructureND;Lspace/kscience/kmath/nd/StructureND;)V + public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; + public fun power (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun sin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun sin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; + public fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun sqrt (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun sqrt (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun std (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun sum (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd/MutableStructureND; + public fun sum (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun tan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun tan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun tanh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun times (Ljava/lang/Number;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun times (Ljava/lang/Object;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/StructureND; + public fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Number;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun times (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; + public synthetic fun times (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun times (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun timesAssign (Lspace/kscience/kmath/nd/MutableStructureND;Ljava/lang/Number;)V + public synthetic fun timesAssign (Lspace/kscience/kmath/nd/MutableStructureND;Ljava/lang/Object;)V + public fun timesAssign (Lspace/kscience/kmath/nd/MutableStructureND;Lspace/kscience/kmath/nd/StructureND;)V + public synthetic fun transposed (Lspace/kscience/kmath/nd/StructureND;II)Lspace/kscience/kmath/nd/MutableStructureND; + public fun transposed (Lspace/kscience/kmath/nd/StructureND;II)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object; + public synthetic fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun unaryMinus (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public fun variance (Lspace/kscience/kmath/nd/StructureND;IZ)Lspace/kscience/kmath/nd/MutableStructureND; + public synthetic fun view-waz_sdI (Lspace/kscience/kmath/nd/MutableStructureND;[I)Lspace/kscience/kmath/nd/MutableStructureND; + public fun view-waz_sdI (Lspace/kscience/kmath/nd/MutableStructureND;[I)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun viewAs (Lspace/kscience/kmath/nd/MutableStructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun viewAs (Lspace/kscience/kmath/nd/MutableStructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public abstract fun wrap (Lorg/nd4j/linalg/api/ndarray/INDArray;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; + public synthetic fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd/StructureND; + public fun zip (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/nd4j/Nd4jArrayStructure; +} + diff --git a/kmath-optimization/README.md b/kmath-optimization/README.md index 79a4f5d24..52a018a4e 100644 --- a/kmath-optimization/README.md +++ b/kmath-optimization/README.md @@ -6,19 +6,8 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-optimization:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-optimization:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-optimization:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-optimization:0.4.0-dev-1") + implementation("space.kscience:kmath-optimization:0.4.0-dev-3") } ``` diff --git a/kmath-stat/README.md b/kmath-stat/README.md index e7e0a4d92..55ef0f693 100644 --- a/kmath-stat/README.md +++ b/kmath-stat/README.md @@ -6,19 +6,8 @@ ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-stat:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-stat:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-stat:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-stat:0.4.0-dev-1") + implementation("space.kscience:kmath-stat:0.4.0-dev-3") } ``` diff --git a/kmath-symja/README.md b/kmath-symja/README.md index 8672c6a71..250c0ae35 100644 --- a/kmath-symja/README.md +++ b/kmath-symja/README.md @@ -6,19 +6,8 @@ Symja integration module ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-symja:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-symja:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-symja:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-symja:0.4.0-dev-1") + implementation("space.kscience:kmath-symja:0.4.0-dev-3") } ``` diff --git a/kmath-tensorflow/README.md b/kmath-tensorflow/README.md index a5b48de4d..03666129d 100644 --- a/kmath-tensorflow/README.md +++ b/kmath-tensorflow/README.md @@ -6,19 +6,8 @@ Google tensorflow connector ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-tensorflow:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-tensorflow:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-tensorflow:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-tensorflow:0.4.0-dev-1") + implementation("space.kscience:kmath-tensorflow:0.4.0-dev-3") } ``` diff --git a/kmath-tensors/README.md b/kmath-tensors/README.md index 80f751ffe..34cf33cb3 100644 --- a/kmath-tensors/README.md +++ b/kmath-tensors/README.md @@ -9,19 +9,8 @@ Common linear algebra operations on tensors. ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-tensors:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-tensors:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-tensors:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -30,6 +19,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-tensors:0.4.0-dev-1") + implementation("space.kscience:kmath-tensors:0.4.0-dev-3") } ``` diff --git a/kmath-viktor/README.md b/kmath-viktor/README.md index 8a781af4c..3b7b8152a 100644 --- a/kmath-viktor/README.md +++ b/kmath-viktor/README.md @@ -6,19 +6,8 @@ Binding for https://github.com/JetBrains-Research/viktor ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-viktor:0.4.0-dev-1`. +The Maven coordinates of this project are `space.kscience:kmath-viktor:0.4.0-dev-3`. -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:kmath-viktor:0.4.0-dev-1' -} -``` **Gradle Kotlin DSL:** ```kotlin repositories { @@ -27,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-viktor:0.4.0-dev-1") + implementation("space.kscience:kmath-viktor:0.4.0-dev-3") } ``` diff --git a/kmath-viktor/api/kmath-viktor.api b/kmath-viktor/api/kmath-viktor.api index 39ae1f84c..11e312e12 100644 --- a/kmath-viktor/api/kmath-viktor.api +++ b/kmath-viktor/api/kmath-viktor.api @@ -12,6 +12,8 @@ public final class space/kscience/kmath/viktor/ViktorBuffer : space/kscience/kma public final fun getFlatArray ()Lorg/jetbrains/bio/viktor/F64FlatArray; public fun getSize ()I public static fun getSize-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public static fun getType-V0oMfBY (Lorg/jetbrains/bio/viktor/F64FlatArray;)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)I public fun iterator ()Ljava/util/Iterator; @@ -62,7 +64,7 @@ public class space/kscience/kmath/viktor/ViktorFieldOpsND : space/kscience/kmath public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object; public fun exp (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun getElementAlgebra ()Lspace/kscience/kmath/operations/Algebra; - public fun getElementAlgebra ()Lspace/kscience/kmath/operations/DoubleField; + public fun getElementAlgebra ()Lspace/kscience/kmath/operations/Float64Field; public final fun getF64Buffer (Lspace/kscience/kmath/nd/StructureND;)Lorg/jetbrains/bio/viktor/F64Array; public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object; public fun ln (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; @@ -72,6 +74,8 @@ public class space/kscience/kmath/viktor/ViktorFieldOpsND : space/kscience/kmath public fun mapIndexed (Lspace/kscience/kmath/nd/StructureND;Lkotlin/jvm/functions/Function3;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun minus (Lspace/kscience/kmath/nd/StructureND;Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; + public synthetic fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/MutableStructureND; + public fun mutableStructureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object; public fun plus (Lspace/kscience/kmath/nd/StructureND;D)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun plus (Lspace/kscience/kmath/nd/StructureND;Ljava/lang/Object;)Lspace/kscience/kmath/nd/StructureND; @@ -85,8 +89,6 @@ public class space/kscience/kmath/viktor/ViktorFieldOpsND : space/kscience/kmath public fun sin (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object; public fun sinh (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; - public synthetic fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/nd/StructureND; - public fun structureND-qL90JFI ([ILkotlin/jvm/functions/Function2;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object; public fun tan (Lspace/kscience/kmath/nd/StructureND;)Lspace/kscience/kmath/viktor/ViktorStructureND; public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object; @@ -102,8 +104,8 @@ public final class space/kscience/kmath/viktor/ViktorFieldOpsND$Companion : spac public final class space/kscience/kmath/viktor/ViktorFieldOpsNDKt { public static final fun ViktorFieldND ([I)Lspace/kscience/kmath/viktor/ViktorFieldND; - public static final fun getViktorAlgebra (Lspace/kscience/kmath/operations/DoubleField;)Lspace/kscience/kmath/viktor/ViktorFieldOpsND; - public static final fun viktorAlgebra (Lspace/kscience/kmath/operations/DoubleField;[I)Lspace/kscience/kmath/viktor/ViktorFieldND; + public static final fun getViktorAlgebra (Lspace/kscience/kmath/operations/Float64Field;)Lspace/kscience/kmath/viktor/ViktorFieldOpsND; + public static final fun viktorAlgebra (Lspace/kscience/kmath/operations/Float64Field;[I)Lspace/kscience/kmath/viktor/ViktorFieldND; } public final class space/kscience/kmath/viktor/ViktorStructureND : space/kscience/kmath/nd/MutableStructureND { @@ -113,6 +115,7 @@ public final class space/kscience/kmath/viktor/ViktorStructureND : space/kscienc public synthetic fun get ([I)Ljava/lang/Object; public final fun getF64Buffer ()Lorg/jetbrains/bio/viktor/F64Array; public fun getShape-IIYLAfE ()[I + public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun set ([ID)V public synthetic fun set ([ILjava/lang/Object;)V } diff --git a/test-utils/api/test-utils.api b/test-utils/api/test-utils.api index fc812a9a6..2915fa039 100644 --- a/test-utils/api/test-utils.api +++ b/test-utils/api/test-utils.api @@ -4,7 +4,7 @@ public final class space/kscience/kmath/testutils/AssertsKt { } public final class space/kscience/kmath/testutils/BufferEqualityKt { - public static final fun contentEquals-2c9zdjM ([D[D)Z + public static final fun contentEquals-YsAwp1c ([D[D)Z public static final fun contentEqualsArray ([D[D)Z public static final fun contentEqualsBuffer ([D[D)Z } From 32c5b3c10d1ecce6ea3dc7fc5638f4d99909d4f4 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 20 Feb 2024 18:38:21 +0300 Subject: [PATCH 076/103] Add publishing to attributes-kt --- attributes-kt/build.gradle.kts | 1 + .../kmath/benchmarks/NDFieldBenchmark.kt | 20 ++++++++++--------- build.gradle.kts | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/attributes-kt/build.gradle.kts b/attributes-kt/build.gradle.kts index f5ead84a3..5956f1f16 100644 --- a/attributes-kt/build.gradle.kts +++ b/attributes-kt/build.gradle.kts @@ -1,5 +1,6 @@ plugins { id("space.kscience.gradle.mpp") + `maven-publish` } version = "0.1.0" diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt index 297dce8b9..77ca03099 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt @@ -25,6 +25,16 @@ import space.kscience.kmath.viktor.viktorAlgebra @State(Scope.Benchmark) internal class NDFieldBenchmark { + private companion object { + private const val dim = 1000 + private const val n = 100 + private val shape = ShapeND(dim, dim) + private val specializedField = Float64Field.ndAlgebra + private val genericField = BufferedFieldOpsND(Float64Field) + private val nd4jField = Float64Field.nd4j + private val viktorField = Float64Field.viktorAlgebra + } + @Benchmark fun specializedFieldAdd(blackhole: Blackhole) = with(specializedField) { var res: StructureND<Double> = one(shape) @@ -82,13 +92,5 @@ internal class NDFieldBenchmark { // blackhole.consume(res) // } - private companion object { - private const val dim = 1000 - private const val n = 100 - private val shape = ShapeND(dim, dim) - private val specializedField = Float64Field.ndAlgebra - private val genericField = BufferedFieldOpsND(Float64Field) - private val nd4jField = Float64Field.nd4j - private val viktorField = Float64Field.viktorAlgebra - } + } diff --git a/build.gradle.kts b/build.gradle.kts index 393576166..ae4ab51cf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ allprojects { } group = "space.kscience" - version = "0.4.0" + version = "0.4.0-RC" } subprojects { From 49f0d1fe7dbfea5cebd6b9283a0e33321e1e6517 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 20 Feb 2024 19:35:00 +0300 Subject: [PATCH 077/103] Fix types in geometry algebras --- CHANGELOG.md | 1 + examples/build.gradle.kts | 2 +- .../kmath/commons/optimization/CMOptimizer.kt | 2 +- .../geometry/euclidean2d/Float32Space2D.kt | 18 +++++++++--------- .../geometry/euclidean2d/Float64Space2D.kt | 16 ++++++++-------- .../geometry/euclidean3d/Float32Space3D.kt | 18 +++++++++--------- 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d98177726..1d2525a80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ - Median statistics - Complex power of negative real numbers - Add proper mutability for MutableBufferND rows and columns +- Generic Float32 and Float64 vectors are used in geometry algebras. ## 0.3.1 - 2023-04-09 diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index c0db25dca..97a3cb8c2 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -52,7 +52,7 @@ dependencies { implementation("org.slf4j:slf4j-simple:1.7.32") // plotting - implementation("space.kscience:plotlykt-server:0.5.3-dev-1") + implementation("space.kscience:plotlykt-server:0.7.0") } kotlin { diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt index afbb96d9b..3c5f8f5e2 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt @@ -116,7 +116,7 @@ public object CMOptimizer : Optimizer<Double, FunctionOptimization<Double>> { } addOptimizationData(gradientFunction) - val logger = problem.attributes[OptimizationLog] +// val logger = problem.attributes[OptimizationLog] problem.attributes[CMOptimizerData]?.let { builders: Set<SymbolIndexer.() -> OptimizationData> -> builders.forEach { dataBuilder -> diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt index d687a3574..ed3caede8 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt @@ -26,7 +26,7 @@ public interface Float32Vector2D : Vector2D<Float32>{ } -public object Float32Space2D : GeometrySpace<Float32Vector2D, Float32> { +public object Float32Space2D : GeometrySpace<Vector2D<Float32>, Float32> { @Serializable @SerialName("Float32Vector2D") private data class Vector2DImpl( @@ -54,21 +54,21 @@ public object Float32Space2D : GeometrySpace<Float32Vector2D, Float32> { override val zero: Float32Vector2D by lazy { vector(0f, 0f) } - override fun norm(arg: Float32Vector2D): Float32 = sqrt(arg.x.pow(2) + arg.y.pow(2)) + override fun norm(arg: Vector2D<Float32>): Float32 = sqrt(arg.x.pow(2) + arg.y.pow(2)) - public fun Float32Vector2D.norm(): Float32 = norm(this) + public fun Vector2D<Float32>.norm(): Float32 = norm(this) - override fun Float32Vector2D.unaryMinus(): Float32Vector2D = vector(-x, -y) + override fun Vector2D<Float32>.unaryMinus(): Float32Vector2D = vector(-x, -y) - override fun Float32Vector2D.distanceTo(other: Float32Vector2D): Float32 = (this - other).norm() + override fun Vector2D<Float32>.distanceTo(other: Vector2D<Float32>): Float32 = (this - other).norm() - override fun add(left: Float32Vector2D, right: Float32Vector2D): Float32Vector2D = + override fun add(left: Vector2D<Float32>, right: Vector2D<Float32>): Float32Vector2D = vector(left.x + right.x, left.y + right.y) - override fun scale(a: Float32Vector2D, value: Double): Float32Vector2D = + override fun scale(a: Vector2D<Float32>, value: Double): Float32Vector2D = vector(a.x * value, a.y * value) - override fun Float32Vector2D.dot(other: Float32Vector2D): Double = + override fun Vector2D<Float32>.dot(other: Vector2D<Float32>): Double = (x * other.x + y * other.y).toDouble() public val xAxis: Float32Vector2D = vector(1.0, 0.0) @@ -76,7 +76,7 @@ public object Float32Space2D : GeometrySpace<Float32Vector2D, Float32> { override val defaultPrecision: Float32 = 1e-3f - override val bufferFactory: MutableBufferFactory<Float32Vector2D> = MutableBufferFactory() + override val bufferFactory: MutableBufferFactory<Vector2D<Float32>> = MutableBufferFactory() } public fun Float32Vector2D(x: Number, y: Number): Float32Vector2D = Float32Space2D.vector(x, y) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt index 05b9401d7..6a4f5ef34 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt @@ -35,7 +35,7 @@ public typealias DoubleVector2D = Float64Vector2D /** * 2D Euclidean space */ -public object Float64Space2D : GeometrySpace<Float64Vector2D, Float64>, ScaleOperations<Float64Vector2D> { +public object Float64Space2D : GeometrySpace<Vector2D<Float64>, Float64>, ScaleOperations<Vector2D<Float64>> { @Serializable @@ -61,23 +61,23 @@ public object Float64Space2D : GeometrySpace<Float64Vector2D, Float64>, ScaleOpe override val zero: Float64Vector2D by lazy { vector(0.0, 0.0) } - override fun norm(arg: Float64Vector2D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2)) + override fun norm(arg: Vector2D<Float64>): Double = sqrt(arg.x.pow(2) + arg.y.pow(2)) - override fun Float64Vector2D.unaryMinus(): Float64Vector2D = vector(-x, -y) + override fun Vector2D<Float64>.unaryMinus(): Float64Vector2D = vector(-x, -y) - override fun Float64Vector2D.distanceTo(other: Float64Vector2D): Double = norm(this - other) - override fun add(left: Float64Vector2D, right: Float64Vector2D): Float64Vector2D = + override fun Vector2D<Float64>.distanceTo(other: Vector2D<Float64>): Double = norm(this - other) + override fun add(left: Vector2D<Float64>, right: Vector2D<Float64>): Float64Vector2D = vector(left.x + right.x, left.y + right.y) - override fun scale(a: Float64Vector2D, value: Double): Float64Vector2D = vector(a.x * value, a.y * value) - override fun Float64Vector2D.dot(other: Float64Vector2D): Double = x * other.x + y * other.y + override fun scale(a: Vector2D<Float64>, value: Double): Float64Vector2D = vector(a.x * value, a.y * value) + override fun Vector2D<Float64>.dot(other: Vector2D<Float64>): Double = x * other.x + y * other.y public val xAxis: Float64Vector2D = vector(1.0, 0.0) public val yAxis: Float64Vector2D = vector(0.0, 1.0) override val defaultPrecision: Double = 1e-6 - override val bufferFactory: MutableBufferFactory<Float64Vector2D> = MutableBufferFactory() + override val bufferFactory: MutableBufferFactory<Vector2D<Float64>> = MutableBufferFactory() } public fun Float64Vector2D(x: Number, y: Number): Float64Vector2D = Float64Space2D.vector(x, y) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt index 7204ac4f9..56ff49533 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt @@ -26,7 +26,7 @@ public interface Float32Vector3D : Vector3D<Float>{ } -public object Float32Space3D : GeometrySpace<Float32Vector3D, Float32> { +public object Float32Space3D : GeometrySpace<Vector3D<Float32>, Float32> { @Serializable @SerialName("Float32Vector3D") @@ -56,21 +56,21 @@ public object Float32Space3D : GeometrySpace<Float32Vector3D, Float32> { override val zero: Float32Vector3D by lazy { vector(0.0, 0.0, 0.0) } - override fun norm(arg: Float32Vector3D): Float32 = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)) + override fun norm(arg: Vector3D<Float32>): Float32 = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)) - public fun Float32Vector3D.norm(): Float32 = norm(this) + public fun Vector3D<Float32>.norm(): Float32 = norm(this) - override fun Float32Vector3D.unaryMinus(): Float32Vector3D = vector(-x, -y, -z) + override fun Vector3D<Float32>.unaryMinus(): Float32Vector3D = vector(-x, -y, -z) - override fun Float32Vector3D.distanceTo(other: Float32Vector3D): Float32 = (this - other).norm() + override fun Vector3D<Float32>.distanceTo(other: Vector3D<Float32>): Float32 = (this - other).norm() - override fun add(left: Float32Vector3D, right: Float32Vector3D): Float32Vector3D = + override fun add(left: Vector3D<Float32>, right: Vector3D<Float32>): Float32Vector3D = vector(left.x + right.x, left.y + right.y, left.z + right.z) - override fun scale(a: Float32Vector3D, value: Double): Float32Vector3D = + override fun scale(a: Vector3D<Float32>, value: Double): Float32Vector3D = vector(a.x * value, a.y * value, a.z * value) - override fun Float32Vector3D.dot(other: Float32Vector3D): Double = + override fun Vector3D<Float32>.dot(other: Vector3D<Float32>): Double = (x * other.x + y * other.y + z * other.z).toDouble() /** @@ -106,7 +106,7 @@ public object Float32Space3D : GeometrySpace<Float32Vector3D, Float32> { override val defaultPrecision: Float32 = 1e-3f - override val bufferFactory: MutableBufferFactory<Float32Vector3D> = MutableBufferFactory() + override val bufferFactory: MutableBufferFactory<Vector3D<Float32>> = MutableBufferFactory() } public fun Float32Vector3D(x: Number, y: Number, z: Number): Float32Vector3D = Float32Space3D.vector(x, y, z) From dba001eff345c0dafe0c38a80278fa81ec369291 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Tue, 20 Feb 2024 20:39:57 +0300 Subject: [PATCH 078/103] Fix types in geometry algebras --- .../kotlin/space/kscience/kmath/geometry/Line.kt | 11 +++++------ .../kmath/geometry/{euclidean2d => }/Polygon.kt | 4 +--- .../kscience/kmath/geometry/euclidean2d/Circle2D.kt | 12 ++++++++---- .../kmath/geometry/euclidean3d/Float64Space3D.kt | 3 ++- .../kmath/geometry/euclidean3d/rotations3D.kt | 5 +++-- .../space/kscience/kmath/geometry/vectorPrecision.kt | 5 +++-- 6 files changed, 22 insertions(+), 18 deletions(-) rename kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/{euclidean2d => }/Polygon.kt (73%) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt index a226ab04d..c65ccd43d 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Line.kt @@ -7,8 +7,7 @@ package space.kscience.kmath.geometry import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.kmath.geometry.euclidean2d.Float64Vector2D -import space.kscience.kmath.geometry.euclidean3d.Float64Vector3D +import space.kscience.kmath.structures.Float64 /** * A line formed by [start] vector of start and a [direction] vector. Direction vector is not necessarily normalized, @@ -25,8 +24,8 @@ private data class LineImpl<out V : Any>(override val start: V, override val dir public fun <V : Any> Line(base: V, direction: V): Line<V> = LineImpl(base, direction) -public typealias Line2D = Line<Float64Vector2D> -public typealias Line3D = Line<Float64Vector3D> +public typealias Line2D = Line<Vector2D<Float64>> +public typealias Line3D = Line<Vector3D<Float64>> /** * A directed line segment between [begin] and [end] @@ -49,5 +48,5 @@ public fun <V : Any> LineSegment<V>.line(algebra: GeometrySpace<V, *>): Line<V> Line(begin, end - begin) } -public typealias LineSegment2D = LineSegment<Float64Vector2D> -public typealias LineSegment3D = LineSegment<Float64Vector3D> +public typealias LineSegment2D = LineSegment<Vector2D<Float64>> +public typealias LineSegment3D = LineSegment<Vector3D<Float64>> diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt similarity index 73% rename from kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt rename to kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt index 21ae86dbb..d7b450ab0 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Polygon.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt @@ -3,9 +3,7 @@ * 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.geometry.euclidean2d - -import space.kscience.kmath.geometry.Vector2D +package space.kscience.kmath.geometry /** diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt index e17a5573a..fcffc7714 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Circle2D.kt @@ -7,10 +7,11 @@ package space.kscience.kmath.geometry.euclidean2d import kotlinx.serialization.Serializable import space.kscience.kmath.geometry.Vector2D +import space.kscience.kmath.structures.Float64 import kotlin.math.PI -public interface Circle2D<T>{ +public interface Circle2D<T> { public val center: Vector2D<T> public val radius: Double } @@ -23,9 +24,12 @@ public val Circle2D<*>.circumference: Double get() = radius * 2 * PI @Serializable public data class Float64Circle2D( @Serializable(Float64Space2D.VectorSerializer::class) override val center: Float64Vector2D, - override val radius: Double -): Circle2D<Double> + override val radius: Float64, +) : Circle2D<Double> -public fun Circle2D(center: Float64Vector2D, radius: Double): Circle2D<Double> = Float64Circle2D(center, radius) +public fun Circle2D(center: Vector2D<Float64>, radius: Double): Circle2D<Double> = Float64Circle2D( + center as? Float64Vector2D ?: Float64Vector2D(center.x, center.y), + radius +) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt index a2c23926a..86ddf554b 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt @@ -128,7 +128,8 @@ public object Float64Space3D : GeometrySpace<Vector3D<Float64>, Double> { override val bufferFactory: MutableBufferFactory<Vector3D<Float64>> = MutableBufferFactory() } +@Suppress("UnusedReceiverParameter") public val Float64Field.euclidean3D: Float64Space3D get() = Float64Space3D -public val Float64Vector3D.r: Double get() = Float64Space3D.norm(this) +public val Vector3D<Float64>.r: Double get() = Float64Space3D.norm(this) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt index 212cc251e..e65bd8e22 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt @@ -37,7 +37,8 @@ public infix fun Quaternion.dot(other: Quaternion): Double = w * other.w + x * o /** * Represent a vector as quaternion with zero a rotation angle. */ -internal fun Float64Vector3D.asQuaternion(): Quaternion = Quaternion(0.0, x, y, z) +internal fun Vector3D<Float64>.asQuaternion(): Quaternion = Quaternion(0.0, x, y, z) + /** * Angle in radians denoted by this quaternion rotation @@ -71,7 +72,7 @@ public val Quaternion.vector: Float64Vector3D /** * Rotate a vector in a [Float64Space3D] with [quaternion] */ -public fun Float64Space3D.rotate(vector: Float64Vector3D, quaternion: Quaternion): Float64Vector3D = +public fun Float64Space3D.rotate(vector: Vector3D<Float64>, quaternion: Quaternion): Float64Vector3D = with(QuaternionAlgebra) { val p = vector.asQuaternion() (quaternion * p * quaternion.reciprocal).vector diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt index 9eb1c069c..e8a14d036 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/vectorPrecision.kt @@ -9,6 +9,7 @@ import space.kscience.kmath.geometry.euclidean2d.Float64Space2D import space.kscience.kmath.geometry.euclidean2d.Float64Vector2D import space.kscience.kmath.geometry.euclidean3d.Float64Space3D import space.kscience.kmath.geometry.euclidean3d.Float64Vector3D +import space.kscience.kmath.structures.Float64 /** @@ -25,7 +26,7 @@ public fun <V : Any, D : Comparable<D>> V.equalsVector( /** * Vector equality using Euclidian L2 norm and given [precision] */ -public fun Float64Vector2D.equalsVector( +public fun Vector2D<Float64>.equalsVector( other: Float64Vector2D, precision: Double = Float64Space2D.defaultPrecision, ): Boolean = equalsVector(Float64Space2D, other, precision) @@ -33,7 +34,7 @@ public fun Float64Vector2D.equalsVector( /** * Vector equality using Euclidean L2 norm and given [precision] */ -public fun Float64Vector3D.equalsVector( +public fun Vector3D<Float64>.equalsVector( other: Float64Vector3D, precision: Double = Float64Space3D.defaultPrecision, ): Boolean = equalsVector(Float64Space3D, other, precision) From fcb7e2fa7d91667522d681d78c92c7aff181e29c Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Thu, 22 Feb 2024 21:03:58 +0300 Subject: [PATCH 079/103] Reverse types for buffers and typealiases for geometry. --- CHANGELOG.md | 3 +- build.gradle.kts | 2 +- .../kscience/kmath/commons/linear/CMMatrix.kt | 3 +- .../kscience/kmath/complex/Quaternion.kt | 2 - kmath-core/api/kmath-core.api | 87 ++++++------------- .../kscience/kmath/expressions/DSAlgebra.kt | 2 +- .../kmath/expressions/SimpleAutoDiff.kt | 2 +- .../kscience/kmath/linear/LinearSpace.kt | 2 +- .../kscience/kmath/linear/LupDecomposition.kt | 6 +- .../kscience/kmath/linear/MatrixWrapper.kt | 4 +- .../space/kscience/kmath/linear/Transposed.kt | 2 - .../kscience/kmath/linear/VirtualMatrix.kt | 4 +- .../space/kscience/kmath/misc/sorting.kt | 10 +-- .../space/kscience/kmath/nd/BufferND.kt | 3 - .../space/kscience/kmath/nd/Float64FieldND.kt | 4 - .../kscience/kmath/nd/PermutedStructureND.kt | 5 -- .../space/kscience/kmath/nd/Structure1D.kt | 19 ---- .../space/kscience/kmath/nd/Structure2D.kt | 13 +-- .../space/kscience/kmath/nd/StructureND.kt | 7 +- .../kscience/kmath/nd/VirtualStructureND.kt | 7 +- .../space/kscience/kmath/nd/operationsND.kt | 4 +- .../kscience/kmath/nd/primitiveStructureND.kt | 7 -- .../kscience/kmath/structures/ArrayBuffer.kt | 14 +-- .../space/kscience/kmath/structures/Buffer.kt | 15 +--- .../kmath/structures/BufferAccessor2D.kt | 3 - .../kscience/kmath/structures/BufferView.kt | 5 -- .../kmath/structures/FlaggedBuffer.kt | 4 - .../kmath/structures/Float32Buffer.kt | 6 -- .../kmath/structures/Float64Buffer.kt | 6 -- .../kscience/kmath/structures/Int16Buffer.kt | 5 +- .../kscience/kmath/structures/Int32Buffer.kt | 4 - .../kscience/kmath/structures/Int64Buffer.kt | 6 -- .../kscience/kmath/structures/Int8Buffer.kt | 5 -- .../kscience/kmath/structures/ListBuffer.kt | 28 +----- .../kmath/structures/MutableBuffer.kt | 28 ++++-- .../space/kscience/kmath/linear/MatrixTest.kt | 2 +- .../kmath/structures/parallelMutableBuffer.kt | 2 +- .../kmath/linear/ParallelMatrixTest.kt | 2 +- .../kscience/kmath/streaming/RingBuffer.kt | 17 ++-- .../kmath/structures/LazyStructureND.kt | 7 +- .../kscience/kmath/dimensions/Wrappers.kt | 5 -- .../kscience/kmath/ejml/implementations.kt | 6 -- .../space/kscience/kmath/real/RealMatrix.kt | 2 +- .../kmath/interpolation/Interpolator.kt | 4 +- kmath-geometry/build.gradle.kts | 1 + .../space/kscience/kmath/geometry/Vector3D.kt | 4 - .../geometry/euclidean2d/Float32Space2D.kt | 7 +- .../geometry/euclidean2d/Float64Space2D.kt | 6 +- .../geometry/euclidean3d/Float32Space3D.kt | 7 +- .../geometry/euclidean3d/Float64Space3D.kt | 6 +- .../kmath/geometry/euclidean3d/rotations3D.kt | 3 - kmath-memory/api/kmath-memory.api | 2 - .../kscience/kmath/memory/MemoryBuffer.kt | 4 - .../kscience/kmath/multik/MultikTensor.kt | 2 - kmath-nd4j/api/kmath-nd4j.api | 1 - .../kscience/kmath/nd4j/Nd4jArrayStructure.kt | 4 - .../kscience/kmath/stat/ValueAndErrorField.kt | 2 - .../tensorflow/DoubleTensorFlowAlgebra.kt | 2 - .../kmath/tensorflow/IntTensorFlowAlgebra.kt | 8 -- .../kmath/tensorflow/TensorFlowAlgebra.kt | 6 +- .../kmath/tensors/core/DoubleTensor.kt | 6 +- .../kmath/tensors/core/DoubleTensor1D.kt | 3 - .../kscience/kmath/tensors/core/IntTensor.kt | 7 +- .../kmath/tensors/core/tensorTransform.kt | 2 +- kmath-viktor/api/kmath-viktor.api | 5 -- .../kscience/kmath/viktor/ViktorBuffer.kt | 4 - .../kmath/viktor/ViktorStructureND.kt | 4 - 67 files changed, 117 insertions(+), 353 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d2525a80..5c383fe95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ ### Added -- Reification. Explicit `SafeType` for algebras and buffers. +- Reification. Explicit `SafeType` for algebras. - Integer division algebras. - Float32 geometries. - New Attributes-kt module that could be used as stand-alone. It declares. type-safe attributes containers. @@ -30,6 +30,7 @@ ### Changed +- Buffer copy removed from API (added as an extension). - Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types. - Remove unnecessary inlines in basic algebras. - QuaternionField -> QuaternionAlgebra and does not implement `Field` anymore since it is non-commutative diff --git a/build.gradle.kts b/build.gradle.kts index ae4ab51cf..9231fc312 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ allprojects { } group = "space.kscience" - version = "0.4.0-RC" + version = "0.4.0-RC2" } subprojects { diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt index 589dc19e0..1fe923cbb 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMMatrix.kt @@ -23,7 +23,7 @@ import space.kscience.kmath.structures.IntBuffer import space.kscience.kmath.structures.asBuffer public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> { - override val type: SafeType<Double> get() = DoubleField.type + override val rowNum: Int get() = origin.rowDimension override val colNum: Int get() = origin.columnDimension @@ -32,7 +32,6 @@ public class CMMatrix(public val origin: RealMatrix) : Matrix<Double> { @JvmInline public value class CMVector(public val origin: RealVector) : Point<Double> { - override val type: SafeType<Double> get() = DoubleField.type override val size: Int get() = origin.dimension override operator fun get(index: Int): Double = origin.getEntry(index) diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt index d5093f4b0..6a6171975 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt @@ -36,8 +36,6 @@ public class Quaternion( require(!z.isNaN()) { "z-component of quaternion is not-a-number" } } - override val type: SafeType<Double> get() = safeTypeOf() - /** * Returns a string representation of this quaternion. */ diff --git a/kmath-core/api/kmath-core.api b/kmath-core/api/kmath-core.api index 0053dde28..460c2e3c4 100644 --- a/kmath-core/api/kmath-core.api +++ b/kmath-core/api/kmath-core.api @@ -428,7 +428,6 @@ public final class space/kscience/kmath/expressions/NamedMatrix : space/kscience public fun getRowNum ()I public fun getRows ()Ljava/util/List; public fun getShape-IIYLAfE ()[I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public final fun getValues ()Lspace/kscience/kmath/nd/Structure2D; } @@ -820,7 +819,6 @@ public final class space/kscience/kmath/linear/MatrixWrapper : space/kscience/km public fun getRowNum ()I public fun getRows ()Ljava/util/List; public fun getShape-IIYLAfE ()[I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun toString ()Ljava/lang/String; } @@ -871,7 +869,6 @@ public final class space/kscience/kmath/linear/TransposedMatrix : space/kscience public fun getColNum ()I public final fun getOrigin ()Lspace/kscience/kmath/nd/Structure2D; public fun getRowNum ()I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public final class space/kscience/kmath/linear/UpperTriangular : space/kscience/attributes/FlagAttribute, space/kscience/kmath/linear/MatrixAttribute { @@ -879,15 +876,14 @@ public final class space/kscience/kmath/linear/UpperTriangular : space/kscience/ } public final class space/kscience/kmath/linear/VirtualMatrix : space/kscience/kmath/nd/Structure2D { - public synthetic fun <init> (Lkotlin/reflect/KType;IILspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public synthetic fun <init> (Lkotlin/reflect/KType;IILspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function2;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun <init> (IILspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function2;)V + public synthetic fun <init> (IILspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function2;ILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun get (II)Ljava/lang/Object; public fun getAttributes ()Lspace/kscience/attributes/Attributes; public fun getColNum ()I public final fun getGenerator ()Lkotlin/jvm/functions/Function2; public fun getRowNum ()I public fun getShape-IIYLAfE ()[I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public final class space/kscience/kmath/linear/VirtualMatrixKt { @@ -1009,7 +1005,6 @@ public class space/kscience/kmath/nd/BufferND : space/kscience/kmath/nd/Structur public fun getBuffer ()Lspace/kscience/kmath/structures/Buffer; public fun getIndices ()Lspace/kscience/kmath/nd/ShapeIndexer; public fun getShape-IIYLAfE ()[I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun toString ()Ljava/lang/String; } @@ -1160,7 +1155,6 @@ public final class space/kscience/kmath/nd/Float64BufferND : space/kscience/kmat public synthetic fun getBuffer ()Lspace/kscience/kmath/structures/MutableBuffer; public fun getBuffer-E20IKn8 ()[D public fun getDouble ([I)D - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun setDouble ([ID)V } @@ -1290,11 +1284,9 @@ public abstract interface class space/kscience/kmath/nd/MutableStructureND : spa public final class space/kscience/kmath/nd/MutableStructureNDAccessorBuffer : space/kscience/kmath/structures/MutableBuffer { public fun <init> (Lspace/kscience/kmath/nd/MutableStructureND;ILkotlin/jvm/functions/Function1;)V - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public fun get (I)Ljava/lang/Object; public fun getSize ()I public final fun getStructure ()Lspace/kscience/kmath/nd/MutableStructureND; - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun set (ILjava/lang/Object;)V public fun toString ()Ljava/lang/String; } @@ -1316,7 +1308,6 @@ public final class space/kscience/kmath/nd/PermutedMutableStructureND : space/ks public final fun getOrigin ()Lspace/kscience/kmath/nd/MutableStructureND; public final fun getPermutation ()Lkotlin/jvm/functions/Function1; public fun getShape-IIYLAfE ()[I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun set ([ILjava/lang/Object;)V } @@ -1326,7 +1317,6 @@ public final class space/kscience/kmath/nd/PermutedStructureND : space/kscience/ public final fun getOrigin ()Lspace/kscience/kmath/nd/StructureND; public final fun getPermutation ()Lkotlin/jvm/functions/Function1; public fun getShape-IIYLAfE ()[I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public final class space/kscience/kmath/nd/PermutedStructureNDKt { @@ -1477,7 +1467,7 @@ public final class space/kscience/kmath/nd/Structure2DKt { public abstract interface class space/kscience/kmath/nd/StructureAttribute : space/kscience/attributes/Attribute { } -public abstract interface class space/kscience/kmath/nd/StructureND : space/kscience/attributes/AttributeContainer, space/kscience/attributes/WithType, space/kscience/kmath/nd/WithShape { +public abstract interface class space/kscience/kmath/nd/StructureND : space/kscience/attributes/AttributeContainer, space/kscience/kmath/nd/WithShape { public static final field Companion Lspace/kscience/kmath/nd/StructureND$Companion; public fun elements ()Lkotlin/sequences/Sequence; public abstract fun get ([I)Ljava/lang/Object; @@ -1509,20 +1499,17 @@ public final class space/kscience/kmath/nd/StructureNDKt { public abstract interface class space/kscience/kmath/nd/StructureNDOfDouble : space/kscience/kmath/nd/StructureND { public abstract fun getDouble ([I)D - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public abstract interface class space/kscience/kmath/nd/StructureNDOfInt : space/kscience/kmath/nd/StructureND { public abstract fun getInt ([I)I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public class space/kscience/kmath/nd/VirtualStructureND : space/kscience/kmath/nd/StructureND { - public synthetic fun <init> (Lkotlin/reflect/KType;[ILkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public synthetic fun <init> ([ILkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V public fun get ([I)Ljava/lang/Object; public final fun getProducer ()Lkotlin/jvm/functions/Function1; public fun getShape-IIYLAfE ()[I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public abstract interface class space/kscience/kmath/nd/WithShape { @@ -2376,21 +2363,31 @@ public abstract interface class space/kscience/kmath/operations/WithSize { } public final class space/kscience/kmath/structures/ArrayBuffer : space/kscience/kmath/structures/MutableBuffer { - public synthetic fun <init> (Lkotlin/reflect/KType;[Ljava/lang/Object;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public static final synthetic fun box-impl ([Ljava/lang/Object;)Lspace/kscience/kmath/structures/ArrayBuffer; + public static fun constructor-impl ([Ljava/lang/Object;)[Ljava/lang/Object; + public fun equals (Ljava/lang/Object;)Z + public static fun equals-impl ([Ljava/lang/Object;Ljava/lang/Object;)Z + public static final fun equals-impl0 ([Ljava/lang/Object;[Ljava/lang/Object;)Z public fun get (I)Ljava/lang/Object; + public static fun get-impl ([Ljava/lang/Object;I)Ljava/lang/Object; public fun getSize ()I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; + public static fun getSize-impl ([Ljava/lang/Object;)I + public fun hashCode ()I + public static fun hashCode-impl ([Ljava/lang/Object;)I public fun iterator ()Ljava/util/Iterator; + public static fun iterator-impl ([Ljava/lang/Object;)Ljava/util/Iterator; public fun set (ILjava/lang/Object;)V + public static fun set-impl ([Ljava/lang/Object;ILjava/lang/Object;)V public fun toString ()Ljava/lang/String; + public static fun toString-impl ([Ljava/lang/Object;)Ljava/lang/String; + public final synthetic fun unbox-impl ()[Ljava/lang/Object; } public final class space/kscience/kmath/structures/ArrayBufferKt { - public static final fun asBuffer-Fnn_obI ([Ljava/lang/Object;Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/ArrayBuffer; + public static final fun asBuffer ([Ljava/lang/Object;)[Ljava/lang/Object; } -public abstract interface class space/kscience/kmath/structures/Buffer : space/kscience/attributes/WithType, space/kscience/kmath/operations/WithSize { +public abstract interface class space/kscience/kmath/structures/Buffer : space/kscience/kmath/operations/WithSize { public static final field Companion Lspace/kscience/kmath/structures/Buffer$Companion; public abstract fun get (I)Ljava/lang/Object; public abstract fun getSize ()I @@ -2449,7 +2446,6 @@ public final class space/kscience/kmath/structures/BufferSlice : space/kscience/ public abstract interface class space/kscience/kmath/structures/BufferView : space/kscience/kmath/structures/Buffer { public fun get (I)Ljava/lang/Object; public abstract fun getOrigin ()Lspace/kscience/kmath/structures/Buffer; - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; } public final class space/kscience/kmath/structures/BufferViewKt { @@ -2477,7 +2473,6 @@ public final class space/kscience/kmath/structures/FlaggedDoubleBuffer : space/k public fun getFlag (I)B public final fun getFlags ()[B public fun getSize ()I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public final fun getValues ()[D public fun iterator ()Ljava/util/Iterator; public fun toString ()Ljava/lang/String; @@ -2486,8 +2481,6 @@ public final class space/kscience/kmath/structures/FlaggedDoubleBuffer : space/k public final class space/kscience/kmath/structures/Float32Buffer : space/kscience/kmath/structures/PrimitiveBuffer { public static final synthetic fun box-impl ([F)Lspace/kscience/kmath/structures/Float32Buffer; public static fun constructor-impl ([F)[F - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl ([F)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z public static fun equals-impl ([FLjava/lang/Object;)Z public static final fun equals-impl0 ([F[F)Z @@ -2497,8 +2490,6 @@ public final class space/kscience/kmath/structures/Float32Buffer : space/kscienc public final fun getArray ()[F public fun getSize ()I public static fun getSize-impl ([F)I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; - public static fun getType-V0oMfBY ([F)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([F)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2523,9 +2514,6 @@ public final class space/kscience/kmath/structures/Float64Buffer : space/kscienc public static final field Companion Lspace/kscience/kmath/structures/Float64Buffer$Companion; public static final synthetic fun box-impl ([D)Lspace/kscience/kmath/structures/Float64Buffer; public static fun constructor-impl ([D)[D - public synthetic fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun copy-E20IKn8 ()[D - public static fun copy-E20IKn8 ([D)[D public fun equals (Ljava/lang/Object;)Z public static fun equals-impl ([DLjava/lang/Object;)Z public static final fun equals-impl0 ([D[D)Z @@ -2535,8 +2523,6 @@ public final class space/kscience/kmath/structures/Float64Buffer : space/kscienc public final fun getArray ()[D public fun getSize ()I public static fun getSize-impl ([D)I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; - public static fun getType-V0oMfBY ([D)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([D)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2571,8 +2557,6 @@ public abstract interface class space/kscience/kmath/structures/Float64BufferTra public final class space/kscience/kmath/structures/Int16Buffer : space/kscience/kmath/structures/MutableBuffer { public static final synthetic fun box-impl ([S)Lspace/kscience/kmath/structures/Int16Buffer; public static fun constructor-impl ([S)[S - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl ([S)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z public static fun equals-impl ([SLjava/lang/Object;)Z public static final fun equals-impl0 ([S[S)Z @@ -2582,8 +2566,6 @@ public final class space/kscience/kmath/structures/Int16Buffer : space/kscience/ public final fun getArray ()[S public fun getSize ()I public static fun getSize-impl ([S)I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; - public static fun getType-V0oMfBY ([S)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([S)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2607,9 +2589,6 @@ public final class space/kscience/kmath/structures/Int16BufferKt { public final class space/kscience/kmath/structures/Int32Buffer : space/kscience/kmath/structures/PrimitiveBuffer { public static final synthetic fun box-impl ([I)Lspace/kscience/kmath/structures/Int32Buffer; public static fun constructor-impl ([I)[I - public synthetic fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public fun copy-M_oXE9g ()[I - public static fun copy-M_oXE9g ([I)[I public fun equals (Ljava/lang/Object;)Z public static fun equals-impl ([ILjava/lang/Object;)Z public static final fun equals-impl0 ([I[I)Z @@ -2619,8 +2598,6 @@ public final class space/kscience/kmath/structures/Int32Buffer : space/kscience/ public final fun getArray ()[I public fun getSize ()I public static fun getSize-impl ([I)I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; - public static fun getType-V0oMfBY ([I)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([I)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2644,8 +2621,6 @@ public final class space/kscience/kmath/structures/Int32BufferKt { public final class space/kscience/kmath/structures/Int64Buffer : space/kscience/kmath/structures/PrimitiveBuffer { public static final synthetic fun box-impl ([J)Lspace/kscience/kmath/structures/Int64Buffer; public static fun constructor-impl ([J)[J - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl ([J)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z public static fun equals-impl ([JLjava/lang/Object;)Z public static final fun equals-impl0 ([J[J)Z @@ -2655,8 +2630,6 @@ public final class space/kscience/kmath/structures/Int64Buffer : space/kscience/ public final fun getArray ()[J public fun getSize ()I public static fun getSize-impl ([J)I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; - public static fun getType-V0oMfBY ([J)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([J)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2680,8 +2653,6 @@ public final class space/kscience/kmath/structures/Int64BufferKt { public final class space/kscience/kmath/structures/Int8Buffer : space/kscience/kmath/structures/MutableBuffer { public static final synthetic fun box-impl ([B)Lspace/kscience/kmath/structures/Int8Buffer; public static fun constructor-impl ([B)[B - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl ([B)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z public static fun equals-impl ([BLjava/lang/Object;)Z public static final fun equals-impl0 ([B[B)Z @@ -2691,8 +2662,6 @@ public final class space/kscience/kmath/structures/Int8Buffer : space/kscience/k public final fun getArray ()[B public fun getSize ()I public static fun getSize-impl ([B)I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; - public static fun getType-V0oMfBY ([B)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl ([B)I public synthetic fun iterator ()Ljava/util/Iterator; @@ -2714,23 +2683,21 @@ public final class space/kscience/kmath/structures/Int8BufferKt { } public final class space/kscience/kmath/structures/ListBuffer : space/kscience/kmath/structures/Buffer { - public synthetic fun <init> (Lkotlin/reflect/KType;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun <init> (Ljava/util/List;)V public fun get (I)Ljava/lang/Object; public final fun getList ()Ljava/util/List; public fun getSize ()I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun iterator ()Ljava/util/Iterator; public fun toString ()Ljava/lang/String; } public final class space/kscience/kmath/structures/ListBufferKt { - public static final fun asBuffer-Fnn_obI (Ljava/util/List;Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/ListBuffer; - public static final fun asMutableBuffer-Fnn_obI (Ljava/util/List;Lkotlin/reflect/KType;)Lspace/kscience/kmath/structures/MutableListBuffer; + public static final fun asBuffer (Ljava/util/List;)Lspace/kscience/kmath/structures/ListBuffer; + public static final fun asMutableBuffer (Ljava/util/List;)Lspace/kscience/kmath/structures/MutableListBuffer; } public abstract interface class space/kscience/kmath/structures/MutableBuffer : space/kscience/kmath/structures/Buffer { public static final field Companion Lspace/kscience/kmath/structures/MutableBuffer$Companion; - public abstract fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public abstract fun set (ILjava/lang/Object;)V } @@ -2752,15 +2719,15 @@ public final class space/kscience/kmath/structures/MutableBufferFactory$Companio public final class space/kscience/kmath/structures/MutableBufferKt { public static final fun MutableBuffer--rwW0uw (Lkotlin/reflect/KType;ILkotlin/jvm/functions/Function1;)Lspace/kscience/kmath/structures/MutableBuffer; + public static final fun copy (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/BufferFactory;)Lspace/kscience/kmath/structures/Buffer; + public static final fun mutableCopy (Lspace/kscience/kmath/structures/Buffer;Lspace/kscience/kmath/structures/MutableBufferFactory;)Lspace/kscience/kmath/structures/MutableBuffer; } public final class space/kscience/kmath/structures/MutableListBuffer : space/kscience/kmath/structures/MutableBuffer { - public synthetic fun <init> (Lkotlin/reflect/KType;Ljava/util/List;Lkotlin/jvm/internal/DefaultConstructorMarker;)V - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; + public fun <init> (Ljava/util/List;)V public fun get (I)Ljava/lang/Object; public final fun getList ()Ljava/util/List; public fun getSize ()I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun iterator ()Ljava/util/Iterator; public fun set (ILjava/lang/Object;)V public fun toString ()Ljava/lang/String; @@ -2789,7 +2756,6 @@ public final class space/kscience/kmath/structures/PermutedBuffer : space/kscien public final class space/kscience/kmath/structures/PermutedMutableBuffer : space/kscience/kmath/structures/BufferView, space/kscience/kmath/structures/MutableBuffer { public fun <init> (Lspace/kscience/kmath/structures/MutableBuffer;[I)V - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public fun get (I)Ljava/lang/Object; public synthetic fun getOrigin ()Lspace/kscience/kmath/structures/Buffer; public fun getOrigin ()Lspace/kscience/kmath/structures/MutableBuffer; @@ -2814,10 +2780,9 @@ public final class space/kscience/kmath/structures/ValueFlag : java/lang/Enum { } public final class space/kscience/kmath/structures/VirtualBuffer : space/kscience/kmath/structures/Buffer { - public synthetic fun <init> (Lkotlin/reflect/KType;ILkotlin/jvm/functions/Function1;Lkotlin/jvm/internal/DefaultConstructorMarker;)V + public fun <init> (ILkotlin/jvm/functions/Function1;)V public fun get (I)Ljava/lang/Object; public fun getSize ()I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun iterator ()Ljava/util/Iterator; public fun toString ()Ljava/lang/String; } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt index 3d2683167..a6e721d13 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DSAlgebra.kt @@ -189,7 +189,7 @@ public abstract class DSAlgebra<T, A : Ring<T>>( vararg derivatives: T, ): DS<T, A> { require(derivatives.size == compiler.size) { "dimension mismatch: ${derivatives.size} and ${compiler.size}" } - val data = derivatives.asList().asBuffer(algebra.type) + val data = derivatives.asList().asBuffer() return DS(data) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt index 1134fbb9b..1209372b4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt @@ -53,7 +53,7 @@ public class DerivationResult<T : Any>( */ public fun <T : Any> DerivationResult<T>.grad(vararg variables: Symbol): Point<T> { check(variables.isNotEmpty()) { "Variable order is not provided for gradient construction" } - return variables.map(::derivative).asBuffer(type) + return variables.map(::derivative).asBuffer() } /** diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index 4ed36fbbc..fb4661b96 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -227,4 +227,4 @@ public fun <T> Matrix<T>.asVector(): Point<T> = * @receiver a buffer. * @return the new matrix. */ -public fun <T> Point<T>.asMatrix(): VirtualMatrix<T> = VirtualMatrix(type, size, 1) { i, _ -> get(i) } \ No newline at end of file +public fun <T> Point<T>.asMatrix(): VirtualMatrix<T> = VirtualMatrix(size, 1) { i, _ -> get(i) } \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index cff72b2f5..58831f38d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -27,7 +27,7 @@ public interface LupDecomposition<T> { * Create a pivot matrix from pivot vector using provided [LinearSpace] */ public fun <T> LupDecomposition<T>.pivotMatrix(linearSpace: LinearSpace<T, Ring<T>>): Matrix<T> = - VirtualMatrix(linearSpace.type, l.rowNum, l.colNum) { row, column -> + VirtualMatrix(l.rowNum, l.colNum) { row, column -> if (column == pivot[row]) linearSpace.elementAlgebra.one else linearSpace.elementAlgebra.zero } @@ -47,7 +47,7 @@ public class GenericLupDecomposition<T>( override val l: Matrix<T> - get() = VirtualMatrix(lu.type, lu.rowNum, lu.colNum, attributes = Attributes(LowerTriangular)) { i, j -> + get() = VirtualMatrix(lu.rowNum, lu.colNum, attributes = Attributes(LowerTriangular)) { i, j -> when { j < i -> lu[i, j] j == i -> elementAlgebra.one @@ -56,7 +56,7 @@ public class GenericLupDecomposition<T>( } override val u: Matrix<T> - get() = VirtualMatrix(lu.type, lu.rowNum, lu.colNum, attributes = Attributes(UpperTriangular)) { i, j -> + get() = VirtualMatrix(lu.rowNum, lu.colNum, attributes = Attributes(UpperTriangular)) { i, j -> if (j >= i) lu[i, j] else elementAlgebra.zero } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt index bea86d3ec..a5987bb18 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/MatrixWrapper.kt @@ -68,7 +68,7 @@ public fun <T> Matrix<T>.modifyAttributes(modifier: (Attributes) -> Attributes): public fun <T> LinearSpace<T, Ring<T>>.one( rows: Int, columns: Int, -): MatrixWrapper<T> = VirtualMatrix(type, rows, columns) { i, j -> +): MatrixWrapper<T> = VirtualMatrix(rows, columns) { i, j -> if (i == j) elementAlgebra.one else elementAlgebra.zero }.withAttribute(IsUnit) @@ -79,6 +79,6 @@ public fun <T> LinearSpace<T, Ring<T>>.one( public fun <T> LinearSpace<T, Ring<T>>.zero( rows: Int, columns: Int, -): MatrixWrapper<T> = VirtualMatrix(type, rows, columns) { _, _ -> +): MatrixWrapper<T> = VirtualMatrix(rows, columns) { _, _ -> elementAlgebra.zero }.withAttribute(IsZero) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt index 28821a52a..36be711e7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/Transposed.kt @@ -6,11 +6,9 @@ package space.kscience.kmath.linear import space.kscience.attributes.Attributes -import space.kscience.attributes.SafeType public class TransposedMatrix<T>(public val origin: Matrix<T>) : Matrix<T> { - override val type: SafeType<T> get() = origin.type override val rowNum: Int get() = origin.colNum diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt index ab6808891..2b031de06 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/VirtualMatrix.kt @@ -6,7 +6,6 @@ package space.kscience.kmath.linear import space.kscience.attributes.Attributes -import space.kscience.attributes.SafeType import space.kscience.kmath.nd.ShapeND @@ -16,7 +15,6 @@ import space.kscience.kmath.nd.ShapeND * @property generator the function that provides elements. */ public class VirtualMatrix<out T>( - override val type: SafeType<T>, override val rowNum: Int, override val colNum: Int, override val attributes: Attributes = Attributes.EMPTY, @@ -31,4 +29,4 @@ public class VirtualMatrix<out T>( public fun <T : Any> MatrixBuilder<T, *>.virtual( attributes: Attributes = Attributes.EMPTY, generator: (i: Int, j: Int) -> T, -): VirtualMatrix<T> = VirtualMatrix(type, rows, columns, attributes, generator) +): VirtualMatrix<T> = VirtualMatrix(rows, columns, attributes, generator) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt index 9ff306355..e1b24dd68 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/misc/sorting.kt @@ -26,7 +26,7 @@ public fun <V : Comparable<V>> Buffer<V>.indicesSorted(): IntArray = permSortInd */ public fun <V : Comparable<V>> Buffer<V>.sorted(): Buffer<V> { val permutations = indicesSorted() - return VirtualBuffer(type, size) { this[permutations[it]] } + return VirtualBuffer(size) { this[permutations[it]] } } @UnstableKMathAPI @@ -38,7 +38,7 @@ public fun <V : Comparable<V>> Buffer<V>.indicesSortedDescending(): IntArray = */ public fun <V : Comparable<V>> Buffer<V>.sortedDescending(): Buffer<V> { val permutations = indicesSortedDescending() - return VirtualBuffer(type, size) { this[permutations[it]] } + return VirtualBuffer(size) { this[permutations[it]] } } @UnstableKMathAPI @@ -47,7 +47,7 @@ public fun <V, C : Comparable<C>> Buffer<V>.indicesSortedBy(selector: (V) -> C): public fun <V, C : Comparable<C>> Buffer<V>.sortedBy(selector: (V) -> C): Buffer<V> { val permutations = indicesSortedBy(selector) - return VirtualBuffer(type, size) { this[permutations[it]] } + return VirtualBuffer(size) { this[permutations[it]] } } @UnstableKMathAPI @@ -56,7 +56,7 @@ public fun <V, C : Comparable<C>> Buffer<V>.indicesSortedByDescending(selector: public fun <V, C : Comparable<C>> Buffer<V>.sortedByDescending(selector: (V) -> C): Buffer<V> { val permutations = indicesSortedByDescending(selector) - return VirtualBuffer(type, size) { this[permutations[it]] } + return VirtualBuffer(size) { this[permutations[it]] } } @UnstableKMathAPI @@ -68,7 +68,7 @@ public fun <V> Buffer<V>.indicesSortedWith(comparator: Comparator<V>): IntArray */ public fun <V> Buffer<V>.sortedWith(comparator: Comparator<V>): Buffer<V> { val permutations = indicesSortedWith(comparator) - return VirtualBuffer(type,size) { this[permutations[it]] } + return VirtualBuffer(size) { this[permutations[it]] } } private fun <V> Buffer<V>.permSortIndicesWith(comparator: Comparator<Int>): IntArray { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt index 24d69602f..5746ff881 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/BufferND.kt @@ -5,7 +5,6 @@ package space.kscience.kmath.nd -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.BufferFactory @@ -24,8 +23,6 @@ public open class BufferND<out T>( public open val buffer: Buffer<T>, ) : StructureND<T> { - override val type: SafeType<T> get() = buffer.type - @PerformancePitfall override operator fun get(index: IntArray): T = buffer[indices.offset(index)] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt index ab9b25663..4bb853af8 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Float64FieldND.kt @@ -5,11 +5,9 @@ package space.kscience.kmath.nd -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.operations.* -import space.kscience.kmath.structures.Float64 import space.kscience.kmath.structures.Float64Buffer import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -24,8 +22,6 @@ public class Float64BufferND( override val buffer: Float64Buffer, ) : MutableBufferND<Double>(indexes, buffer), MutableStructureNDOfDouble { - override val type: SafeType<Float64> get() = Float64Field.type - override fun getDouble(index: IntArray): Double = buffer[indices.offset(index)] override fun setDouble(index: IntArray, value: Double) { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt index 8c835afee..28130c037 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/PermutedStructureND.kt @@ -5,7 +5,6 @@ package space.kscience.kmath.nd -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall @@ -14,8 +13,6 @@ public class PermutedStructureND<T>( public val permutation: (IntArray) -> IntArray, ) : StructureND<T> { - override val type: SafeType<T> get() = origin.type - override val shape: ShapeND get() = origin.shape @@ -35,8 +32,6 @@ public class PermutedMutableStructureND<T>( public val permutation: (IntArray) -> IntArray, ) : MutableStructureND<T> { - override val type: SafeType<T> get() = origin.type - @OptIn(PerformancePitfall::class) override fun set(index: IntArray, value: T) { origin[permutation(index)] = value diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt index 5bc5ba744..14f2aa7c2 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure1D.kt @@ -5,12 +5,10 @@ package space.kscience.kmath.nd -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.operations.asSequence import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer -import space.kscience.kmath.structures.asMutableBuffer import kotlin.jvm.JvmInline /** @@ -48,8 +46,6 @@ public interface MutableStructure1D<T> : Structure1D<T>, MutableStructureND<T>, @JvmInline private value class Structure1DWrapper<out T>(val structure: StructureND<T>) : Structure1D<T> { - override val type: SafeType<T> get() = structure.type - override val shape: ShapeND get() = structure.shape override val size: Int get() = structure.shape[0] @@ -65,8 +61,6 @@ private value class Structure1DWrapper<out T>(val structure: StructureND<T>) : S */ private class MutableStructure1DWrapper<T>(val structure: MutableStructureND<T>) : MutableStructure1D<T> { - override val type: SafeType<T> get() = structure.type - override val shape: ShapeND get() = structure.shape override val size: Int get() = structure.shape[0] @@ -81,13 +75,6 @@ private class MutableStructure1DWrapper<T>(val structure: MutableStructureND<T>) structure[intArrayOf(index)] = value } - @OptIn(PerformancePitfall::class) - override fun copy(): MutableBuffer<T> = structure - .elements() - .map(Pair<IntArray, T>::second) - .toMutableList() - .asMutableBuffer(type) - override fun toString(): String = Buffer.toString(this) } @@ -98,8 +85,6 @@ private class MutableStructure1DWrapper<T>(val structure: MutableStructureND<T>) @JvmInline private value class Buffer1DWrapper<out T>(val buffer: Buffer<T>) : Structure1D<T> { - override val type: SafeType<T> get() = buffer.type - override val shape: ShapeND get() = ShapeND(buffer.size) override val size: Int get() = buffer.size @@ -113,8 +98,6 @@ private value class Buffer1DWrapper<out T>(val buffer: Buffer<T>) : Structure1D< internal class MutableBuffer1DWrapper<T>(val buffer: MutableBuffer<T>) : MutableStructure1D<T> { - override val type: SafeType<T> get() = buffer.type - override val shape: ShapeND get() = ShapeND(buffer.size) override val size: Int get() = buffer.size @@ -128,8 +111,6 @@ internal class MutableBuffer1DWrapper<T>(val buffer: MutableBuffer<T>) : Mutable buffer[index] = value } - override fun copy(): MutableBuffer<T> = buffer.copy() - override fun toString(): String = Buffer.toString(this) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt index a16f1082d..0a3209970 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Structure2D.kt @@ -6,7 +6,6 @@ package space.kscience.kmath.nd import space.kscience.attributes.Attributes -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer @@ -36,14 +35,14 @@ public interface Structure2D<out T> : StructureND<T> { */ @PerformancePitfall public val rows: List<Buffer<T>> - get() = List(rowNum) { i -> VirtualBuffer(type, colNum) { j -> get(i, j) } } + get() = List(rowNum) { i -> VirtualBuffer(colNum) { j -> get(i, j) } } /** * The buffer of columns for this structure. It gets elements from the structure dynamically. */ @PerformancePitfall public val columns: List<Buffer<T>> - get() = List(colNum) { j -> VirtualBuffer(type, rowNum) { i -> get(i, j) } } + get() = List(colNum) { j -> VirtualBuffer(rowNum) { i -> get(i, j) } } /** * Retrieves an element from the structure by two indices. @@ -79,8 +78,6 @@ public class MutableStructureNDAccessorBuffer<T>( private val indexer: (Int) -> IntArray, ) : MutableBuffer<T> { - override val type: SafeType<T> get() = structure.type - override fun set(index: Int, value: T) { structure[indexer(index)] = value } @@ -88,8 +85,6 @@ public class MutableStructureNDAccessorBuffer<T>( override fun get(index: Int): T = structure[indexer(index)] override fun toString(): String = "AccessorBuffer(structure=$structure, size=$size)" - - override fun copy(): MutableBuffer<T> = MutableBuffer(type, size, ::get) } /** @@ -130,8 +125,6 @@ public interface MutableStructure2D<T> : Structure2D<T>, MutableStructureND<T> { @JvmInline private value class Structure2DWrapper<out T>(val structure: StructureND<T>) : Structure2D<T> { - override val type: SafeType<T> get() = structure.type - override val shape: ShapeND get() = structure.shape override val rowNum: Int get() = shape[0] @@ -152,8 +145,6 @@ private value class Structure2DWrapper<out T>(val structure: StructureND<T>) : S */ private class MutableStructure2DWrapper<T>(val structure: MutableStructureND<T>) : MutableStructure2D<T> { - override val type: SafeType<T> get() = structure.type - override val shape: ShapeND get() = structure.shape override val rowNum: Int get() = shape[0] diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt index 12034df64..5c1021147 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/StructureND.kt @@ -5,7 +5,10 @@ package space.kscience.kmath.nd -import space.kscience.attributes.* +import space.kscience.attributes.Attribute +import space.kscience.attributes.AttributeContainer +import space.kscience.attributes.Attributes +import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.linear.LinearSpace import space.kscience.kmath.operations.Ring @@ -24,7 +27,7 @@ public interface StructureAttribute<T> : Attribute<T> * * @param T the type of items. */ -public interface StructureND<out T> : AttributeContainer, WithShape, WithType<T> { +public interface StructureND<out T> : AttributeContainer, WithShape { /** * The shape of structure i.e., non-empty sequence of non-negative integers that specify sizes of dimensions for * this structure. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt index 82c04e640..a7e0b0053 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/VirtualStructureND.kt @@ -5,13 +5,10 @@ package space.kscience.kmath.nd -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI public open class VirtualStructureND<T>( - override val type: SafeType<T>, override val shape: ShapeND, public val producer: (IntArray) -> T, ) : StructureND<T> { @@ -27,10 +24,10 @@ public open class VirtualStructureND<T>( public class VirtualDoubleStructureND( shape: ShapeND, producer: (IntArray) -> Double, -) : VirtualStructureND<Double>(safeTypeOf(), shape, producer) +) : VirtualStructureND<Double>(shape, producer) @UnstableKMathAPI public class VirtualIntStructureND( shape: ShapeND, producer: (IntArray) -> Int, -) : VirtualStructureND<Int>(safeTypeOf(), shape, producer) \ No newline at end of file +) : VirtualStructureND<Int>(shape, producer) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt index 9e9361bca..b91f2bde5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/operationsND.kt @@ -10,7 +10,7 @@ import space.kscience.kmath.PerformancePitfall @OptIn(PerformancePitfall::class) 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(type, shape) { index -> + return VirtualStructureND(shape) { index -> val newIndex: IntArray = IntArray(index.size) { indexAxis -> if (indexAxis == axis) { (index[indexAxis] + step).mod(shape[indexAxis]) @@ -26,7 +26,7 @@ public fun <T> StructureND<T>.roll(axis: Int, step: Int = 1): StructureND<T> { 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(type, shape) { index -> + return VirtualStructureND(shape) { index -> val newIndex: IntArray = IntArray(index.size) { indexAxis -> val offset = axisMap[indexAxis] ?: 0 (index[indexAxis] + offset).mod(shape[indexAxis]) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt index ca299f12f..4831b4138 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/primitiveStructureND.kt @@ -5,14 +5,9 @@ package space.kscience.kmath.nd -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall -import space.kscience.kmath.operations.Float64Field -import space.kscience.kmath.operations.Int32Field -import space.kscience.kmath.structures.Float64 public interface StructureNDOfDouble : StructureND<Double> { - override val type: SafeType<Float64> get() = Float64Field.type /** * Guaranteed non-blocking access to content @@ -42,8 +37,6 @@ public fun MutableStructureND<Double>.getDouble(index: IntArray): Double = public interface StructureNDOfInt : StructureND<Int> { - override val type: SafeType<Int> get() = Int32Field.type - /** * Guaranteed non-blocking access to content */ diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt index 54d0b40b9..892f6a7c5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt @@ -5,8 +5,7 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf +import kotlin.jvm.JvmInline /** * [MutableBuffer] implementation over [Array]. @@ -14,7 +13,8 @@ import space.kscience.attributes.safeTypeOf * @param T the type of elements contained in the buffer. * @property array The underlying array. */ -public class ArrayBuffer<T>(override val type: SafeType<T>, internal val array: Array<T>) : MutableBuffer<T> { +@JvmInline +public value class ArrayBuffer<T>(internal val array: Array<T>) : MutableBuffer<T> { // Can't inline because array is invariant override val size: Int get() = array.size @@ -25,7 +25,6 @@ public class ArrayBuffer<T>(override val type: SafeType<T>, internal val array: } override operator fun iterator(): Iterator<T> = array.iterator() - override fun copy(): MutableBuffer<T> = ArrayBuffer(type, array.copyOf()) override fun toString(): String = Buffer.toString(this) } @@ -33,9 +32,4 @@ public class ArrayBuffer<T>(override val type: SafeType<T>, internal val array: /** * Returns an [ArrayBuffer] that wraps the original array. */ -public fun <T> Array<T>.asBuffer(type: SafeType<T>): ArrayBuffer<T> = ArrayBuffer(type, this) - -/** - * Returns an [ArrayBuffer] that wraps the original array. - */ -public inline fun <reified T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(safeTypeOf<T>(), this) \ No newline at end of file +public fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer( this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt index 4a0ac9416..7fc06c43e 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffer.kt @@ -66,7 +66,7 @@ public inline fun <reified T> MutableBufferFactory(): MutableBufferFactory<T> = * * @param T the type of elements contained in the buffer. */ -public interface Buffer<out T> : WithSize, WithType<T> { +public interface Buffer<out T> : WithSize { /** * The size of this buffer. */ @@ -120,7 +120,7 @@ public fun <T> Buffer( typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> - else -> List(size, initializer).asBuffer(type) + else -> List(size, initializer).asBuffer() } /** @@ -139,7 +139,7 @@ public inline fun <reified T> Buffer(size: Int, initializer: (Int) -> T): Buffer typeOf<Int>() -> MutableBuffer.int(size) { initializer(it) as Int } as Buffer<T> typeOf<Long>() -> MutableBuffer.long(size) { initializer(it) as Long } as Buffer<T> typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as Buffer<T> - else -> List(size, initializer).asBuffer(type) + else -> List(size, initializer).asBuffer() } } @@ -172,7 +172,6 @@ public fun <T> Buffer<T>.last(): T { * @param T the type of elements provided by the buffer. */ public class VirtualBuffer<out T>( - override val type: SafeType<T>, override val size: Int, private val generator: (Int) -> T, ) : Buffer<T> { @@ -185,11 +184,3 @@ public class VirtualBuffer<out T>( override fun toString(): String = Buffer.toString(this) } - -/** - * Inline builder for [VirtualBuffer] - */ -public inline fun <reified T> VirtualBuffer( - size: Int, - noinline generator: (Int) -> T, -): VirtualBuffer<T> = VirtualBuffer(safeTypeOf(), size, generator) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt index 5c8541f22..32990c707 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferAccessor2D.kt @@ -5,7 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType import space.kscience.kmath.nd.Structure2D /** @@ -33,7 +32,6 @@ internal class BufferAccessor2D<T>( // ) { (i, j) -> get(i, j) }.as2D() inner class Row(val buffer: MutableBuffer<T>, val rowIndex: Int) : MutableBuffer<T> { - override val type: SafeType<T> get() = buffer.type override val size: Int get() = colNum @@ -43,7 +41,6 @@ internal class BufferAccessor2D<T>( buffer[rowIndex, index] = value } - override fun copy(): MutableBuffer<T> = factory(colNum) { get(it) } override operator fun iterator(): Iterator<T> = (0 until colNum).map(::get).iterator() override fun toString(): String = Buffer.toString(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt index ac8a9af14..180098f51 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/BufferView.kt @@ -5,7 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI /** @@ -14,8 +13,6 @@ import space.kscience.kmath.UnstableKMathAPI public interface BufferView<T> : Buffer<T> { public val origin: Buffer<T> - override val type: SafeType<T> get() = origin.type - /** * Get the index in [origin] buffer from index in this buffer. * Return -1 if element not present in the original buffer @@ -190,9 +187,7 @@ public class PermutedMutableBuffer<T>( origin[permutations[index]] = value } - override fun copy(): MutableBuffer<T> = PermutedMutableBuffer(origin.copy(), permutations) //TODO Probably could be optimized - override fun iterator(): Iterator<T> = permutations.asSequence().map { origin[it] }.iterator() @UnstableKMathAPI diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt index 55729a9c2..ce31163a9 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import kotlin.experimental.and /** @@ -60,8 +58,6 @@ public class FlaggedDoubleBuffer( public val flags: ByteArray ) : FlaggedBuffer<Double?>, Buffer<Double?> { - override val type: SafeType<Double?> = safeTypeOf() - init { require(values.size == flags.size) { "Values and flags must have the same dimensions" } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt index 9f564f450..7ad6c2a0d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -18,8 +16,6 @@ import kotlin.jvm.JvmInline @JvmInline public value class Float32Buffer(public val array: FloatArray) : PrimitiveBuffer<Float> { - override val type: SafeType<Float32> get() = safeTypeOf<Float32>() - override val size: Int get() = array.size override operator fun get(index: Int): Float = array[index] @@ -30,8 +26,6 @@ public value class Float32Buffer(public val array: FloatArray) : PrimitiveBuffer override operator fun iterator(): FloatIterator = array.iterator() - override fun copy(): MutableBuffer<Float> = - Float32Buffer(array.copyOf()) } public typealias FloatBuffer = Float32Buffer diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt index ca9e8ef9f..38b737fd5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float64Buffer.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import space.kscience.kmath.operations.BufferTransform import kotlin.jvm.JvmInline @@ -18,8 +16,6 @@ import kotlin.jvm.JvmInline @JvmInline public value class Float64Buffer(public val array: DoubleArray) : PrimitiveBuffer<Double> { - override val type: SafeType<Double> get() = safeTypeOf() - override val size: Int get() = array.size override operator fun get(index: Int): Double = array[index] @@ -30,8 +26,6 @@ public value class Float64Buffer(public val array: DoubleArray) : PrimitiveBuffe override operator fun iterator(): DoubleIterator = array.iterator() - override fun copy(): Float64Buffer = Float64Buffer(array.copyOf()) - override fun toString(): String = Buffer.toString(this) public companion object { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt index 17d4cd36b..9ceeeec05 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int16Buffer.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -17,7 +15,7 @@ import kotlin.jvm.JvmInline @JvmInline public value class Int16Buffer(public val array: ShortArray) : MutableBuffer<Short> { - override val type: SafeType<Short> get() = safeTypeOf() + override val size: Int get() = array.size override operator fun get(index: Int): Short = array[index] @@ -27,7 +25,6 @@ public value class Int16Buffer(public val array: ShortArray) : MutableBuffer<Sho } override operator fun iterator(): ShortIterator = array.iterator() - override fun copy(): MutableBuffer<Short> = Int16Buffer(array.copyOf()) } public typealias ShortBuffer = Int16Buffer diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt index 5cdebb7d7..bb41c2b9b 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int32Buffer.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -17,7 +15,6 @@ import kotlin.jvm.JvmInline @JvmInline public value class Int32Buffer(public val array: IntArray) : PrimitiveBuffer<Int> { - override val type: SafeType<Int> get() = safeTypeOf() override val size: Int get() = array.size @@ -29,7 +26,6 @@ public value class Int32Buffer(public val array: IntArray) : PrimitiveBuffer<Int override operator fun iterator(): IntIterator = array.iterator() - override fun copy(): Int32Buffer = Int32Buffer(array.copyOf()) } public typealias IntBuffer = Int32Buffer diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt index d791cbb18..ee1bf2d56 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int64Buffer.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -17,8 +15,6 @@ import kotlin.jvm.JvmInline @JvmInline public value class Int64Buffer(public val array: LongArray) : PrimitiveBuffer<Long> { - override val type: SafeType<Long> get() = safeTypeOf() - override val size: Int get() = array.size override operator fun get(index: Int): Long = array[index] @@ -29,8 +25,6 @@ public value class Int64Buffer(public val array: LongArray) : PrimitiveBuffer<Lo override operator fun iterator(): LongIterator = array.iterator() - override fun copy(): MutableBuffer<Long> = - Int64Buffer(array.copyOf()) } public typealias LongBuffer = Int64Buffer diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt index 1a7ca98b0..c7b1d43c5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Int8Buffer.kt @@ -5,8 +5,6 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import kotlin.jvm.JvmInline /** @@ -17,8 +15,6 @@ import kotlin.jvm.JvmInline @JvmInline public value class Int8Buffer(public val array: ByteArray) : MutableBuffer<Byte> { - override val type: SafeType<Byte> get() = safeTypeOf() - override val size: Int get() = array.size override operator fun get(index: Int): Byte = array[index] @@ -28,7 +24,6 @@ public value class Int8Buffer(public val array: ByteArray) : MutableBuffer<Byte> } override operator fun iterator(): ByteIterator = array.iterator() - override fun copy(): MutableBuffer<Byte> = Int8Buffer(array.copyOf()) } /** diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt index fc9ba4933..501bd1c64 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ListBuffer.kt @@ -5,16 +5,13 @@ package space.kscience.kmath.structures -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf - /** * [Buffer] implementation over [List]. * * @param T the type of elements contained in the buffer. * @property list The underlying list. */ -public class ListBuffer<T>(override val type: SafeType<T>, public val list: List<T>) : Buffer<T> { +public class ListBuffer<T>(public val list: List<T>) : Buffer<T> { override val size: Int get() = list.size @@ -28,12 +25,7 @@ public class ListBuffer<T>(override val type: SafeType<T>, public val list: List /** * Returns an [ListBuffer] that wraps the original list. */ -public fun <T> List<T>.asBuffer(type: SafeType<T>): ListBuffer<T> = ListBuffer(type, this) - -/** - * Returns an [ListBuffer] that wraps the original list. - */ -public inline fun <reified T> List<T>.asBuffer(): ListBuffer<T> = asBuffer(safeTypeOf()) +public fun <T> List<T>.asBuffer(): ListBuffer<T> = ListBuffer(this) /** * [MutableBuffer] implementation over [MutableList]. @@ -41,7 +33,7 @@ public inline fun <reified T> List<T>.asBuffer(): ListBuffer<T> = asBuffer(safeT * @param T the type of elements contained in the buffer. * @property list The underlying list. */ -public class MutableListBuffer<T>(override val type: SafeType<T>, public val list: MutableList<T>) : MutableBuffer<T> { +public class MutableListBuffer<T>(public val list: MutableList<T>) : MutableBuffer<T> { override val size: Int get() = list.size @@ -52,7 +44,6 @@ public class MutableListBuffer<T>(override val type: SafeType<T>, public val lis } override operator fun iterator(): Iterator<T> = list.iterator() - override fun copy(): MutableBuffer<T> = MutableListBuffer(type, ArrayList(list)) override fun toString(): String = Buffer.toString(this) } @@ -61,15 +52,4 @@ public class MutableListBuffer<T>(override val type: SafeType<T>, public val lis /** * Returns an [MutableListBuffer] that wraps the original list. */ -public fun <T> MutableList<T>.asMutableBuffer(type: SafeType<T>): MutableListBuffer<T> = MutableListBuffer( - type, - this -) - -/** - * Returns an [MutableListBuffer] that wraps the original list. - */ -public inline fun <reified T> MutableList<T>.asMutableBuffer(): MutableListBuffer<T> = MutableListBuffer( - safeTypeOf(), - this -) +public fun <T> MutableList<T>.asMutableBuffer(): MutableListBuffer<T> = MutableListBuffer(this) \ No newline at end of file diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt index 0acfd13a1..be0c76618 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt @@ -14,16 +14,13 @@ import kotlin.reflect.typeOf * * @param T the type of elements contained in the buffer. */ -public interface MutableBuffer<T> : Buffer<T> { +public interface MutableBuffer<T> : Buffer<T>{ + /** * Sets the array element at the specified [index] to the specified [value]. */ public operator fun set(index: Int, value: T) - /** - * Returns a shallow copy of the buffer. - */ - public fun copy(): MutableBuffer<T> public companion object { /** @@ -65,6 +62,25 @@ public interface MutableBuffer<T> : Buffer<T> { } +/** + * Returns a shallow copy of the buffer. + */ +public fun <T> Buffer<T>.copy(bufferFactory: BufferFactory<T>): Buffer<T> =if(this is ArrayBuffer){ + ArrayBuffer(array.copyOf()) +}else{ + bufferFactory(size,::get) +} + +/** + * Returns a mutable shallow copy of the buffer. + */ +public fun <T> Buffer<T>.mutableCopy(bufferFactory: MutableBufferFactory<T>): MutableBuffer<T> =if(this is ArrayBuffer){ + ArrayBuffer(array.copyOf()) +}else{ + bufferFactory(size,::get) +} + + /** * Creates a [MutableBuffer] of given [type]. If the type is primitive, specialized buffers are used * ([Int32Buffer], [Float64Buffer], etc.), [ListBuffer] is returned otherwise. @@ -84,7 +100,7 @@ public inline fun <T> MutableBuffer( typeOf<Float>() -> MutableBuffer.float(size) { initializer(it) as Float } as MutableBuffer<T> typeOf<Double>() -> MutableBuffer.double(size) { initializer(it) as Double } as MutableBuffer<T> //TODO add unsigned types - else -> MutableListBuffer(type, MutableList(size, initializer)) + else -> MutableListBuffer(MutableList(size, initializer)) } /** diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt index f7863a68c..eb76d59dc 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt @@ -38,7 +38,7 @@ class MatrixTest { @Test fun testMatrixExtension() = Double.algebra.linearSpace.run { - val transitionMatrix: Matrix<Double> = VirtualMatrix(type,6, 6) { row, col -> + val transitionMatrix: Matrix<Double> = VirtualMatrix(6, 6) { row, col -> when { col == 0 -> .50 row + 1 == col -> .50 diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt index c57dba41e..7eeb0dbbd 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt @@ -33,7 +33,7 @@ public fun <T> MutableBuffer.Companion.parallel( typeOf<Double>() -> IntStream.range(0, size).parallel().mapToDouble { initializer(it) as Float64 }.toArray() .asBuffer() as MutableBuffer<T> //TODO add unsigned types - else -> IntStream.range(0, size).parallel().mapToObj { initializer(it) }.collect(Collectors.toList<T>()).asMutableBuffer(type) + else -> IntStream.range(0, size).parallel().mapToObj { initializer(it) }.collect(Collectors.toList<T>()).asMutableBuffer() } public class ParallelBufferFactory<T>(override val type: SafeType<T>) : MutableBufferFactory<T> { diff --git a/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt b/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt index 493948361..915ec3c5e 100644 --- a/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt +++ b/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt @@ -37,7 +37,7 @@ class ParallelMatrixTest { @Test fun testMatrixExtension() = Float64Field.linearSpace.parallel{ - val transitionMatrix: Matrix<Double> = VirtualMatrix(type,6, 6) { row, col -> + val transitionMatrix: Matrix<Double> = VirtualMatrix(6, 6) { row, col -> when { col == 0 -> .50 row + 1 == col -> .50 diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt index d40f145f6..3ee6b203a 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt @@ -7,22 +7,19 @@ package space.kscience.kmath.streaming import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock -import space.kscience.attributes.SafeType import space.kscience.kmath.operations.Group -import space.kscience.kmath.structures.Buffer -import space.kscience.kmath.structures.MutableBuffer -import space.kscience.kmath.structures.VirtualBuffer +import space.kscience.kmath.structures.* /** * Thread-safe ring buffer */ public class RingBuffer<T>( private val buffer: MutableBuffer<T>, + private val bufferFactory: BufferFactory<T>, private var startIndex: Int = 0, size: Int = 0, ) : Buffer<T> { - override val type: SafeType<T> get() = buffer.type private val mutex: Mutex = Mutex() @@ -43,7 +40,7 @@ public class RingBuffer<T>( override operator fun iterator(): Iterator<T> = object : AbstractIterator<T>() { private var count = size private var index = startIndex - val copy = buffer.copy() + val copy = buffer.copy(bufferFactory) override fun computeNext() { if (count == 0) done() else { @@ -58,8 +55,8 @@ public class RingBuffer<T>( * A safe snapshot operation */ public suspend fun snapshot(): Buffer<T> = mutex.withLock { - val copy = buffer.copy() - VirtualBuffer(type, size) { i -> copy[startIndex.forward(i)] } + val copy = buffer.copy(bufferFactory) + VirtualBuffer(size) { i -> copy[startIndex.forward(i)] } } public suspend fun push(element: T) { @@ -76,7 +73,7 @@ public class RingBuffer<T>( public inline fun <reified T : Any> RingBuffer(size: Int, empty: T): RingBuffer<T> { val buffer = MutableBuffer(size) { empty } - return RingBuffer(buffer) + return RingBuffer(buffer, BufferFactory()) } /** @@ -84,5 +81,5 @@ public inline fun <reified T : Any> RingBuffer(size: Int, empty: T): RingBuffer< */ public fun <T> RingBuffer(size: Int, algebra: Group<T>): RingBuffer<T> { val buffer: MutableBuffer<T> = MutableBuffer(algebra.type, size) { algebra.zero } - return RingBuffer(buffer) + return RingBuffer(buffer, algebra.bufferFactory) } diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt index cb90c9b02..1d23162f5 100644 --- a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt +++ b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt @@ -6,8 +6,6 @@ package space.kscience.kmath.structures import kotlinx.coroutines.* -import space.kscience.attributes.SafeType -import space.kscience.attributes.safeTypeOf import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.coroutines.Math import space.kscience.kmath.nd.ColumnStrides @@ -16,7 +14,6 @@ import space.kscience.kmath.nd.StructureND public class LazyStructureND<out T>( public val scope: CoroutineScope, - override val type: SafeType<T>, override val shape: ShapeND, public val function: suspend (IntArray) -> T, ) : StructureND<T> { @@ -54,10 +51,10 @@ public suspend fun <T> StructureND<T>.await(index: IntArray): T = public inline fun <T, reified R> StructureND<T>.mapAsyncIndexed( scope: CoroutineScope, crossinline function: suspend (T, index: IntArray) -> R, -): LazyStructureND<R> = LazyStructureND(scope, safeTypeOf(), shape) { index -> function(get(index), index) } +): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index), index) } @OptIn(PerformancePitfall::class) public inline fun <T, reified R> StructureND<T>.mapAsync( scope: CoroutineScope, crossinline function: suspend (T) -> R, -): LazyStructureND<R> = LazyStructureND(scope, safeTypeOf(), shape) { index -> function(get(index)) } +): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index)) } diff --git a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt index d1de77d54..7ddc143ad 100644 --- a/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt +++ b/kmath-dimensions/src/commonMain/kotlin/space/kscience/kmath/dimensions/Wrappers.kt @@ -5,7 +5,6 @@ package space.kscience.kmath.dimensions -import space.kscience.attributes.SafeType import space.kscience.kmath.linear.* import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.Structure2D @@ -50,8 +49,6 @@ public value class DMatrixWrapper<out T, R : Dimension, C : Dimension>( private val structure: Structure2D<T>, ) : DMatrix<T, R, C> { - override val type: SafeType<T> get() = structure.type - override val shape: ShapeND get() = structure.shape override val rowNum: Int get() = shape[0] override val colNum: Int get() = shape[1] @@ -81,8 +78,6 @@ public interface DPoint<out T, D : Dimension> : Point<T> { @JvmInline public value class DPointWrapper<out T, D : Dimension>(public val point: Point<T>) : DPoint<T, D> { - override val type: SafeType<T> get() = point.type - override val size: Int get() = point.size override operator fun get(index: Int): T = point[index] diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt index d33a74199..d196f5f1a 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt @@ -38,7 +38,6 @@ public class EjmlDoubleVector<out M : DMatrix>(override val origin: M) : EjmlVec require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } } - override val type: SafeType<Double> get() = safeTypeOf() override operator fun get(index: Int): Double = origin[0, index] } @@ -51,8 +50,6 @@ public class EjmlFloatVector<out M : FMatrix>(override val origin: M) : EjmlVect require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" } } - override val type: SafeType<Float> get() = safeTypeOf() - override operator fun get(index: Int): Float = origin[0, index] } @@ -60,8 +57,6 @@ public class EjmlFloatVector<out M : FMatrix>(override val origin: M) : EjmlVect * [EjmlMatrix] specialization for [Double]. */ public class EjmlDoubleMatrix<out M : DMatrix>(override val origin: M) : EjmlMatrix<Double, M>(origin) { - override val type: SafeType<Double> get() = safeTypeOf() - override operator fun get(i: Int, j: Int): Double = origin[i, j] } @@ -69,7 +64,6 @@ public class EjmlDoubleMatrix<out M : DMatrix>(override val origin: M) : EjmlMat * [EjmlMatrix] specialization for [Float]. */ public class EjmlFloatMatrix<out M : FMatrix>(override val origin: M) : EjmlMatrix<Float, M>(origin) { - override val type: SafeType<Float> get() = safeTypeOf() override operator fun get(i: Int, j: Int): Float = origin[i, j] } diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt index cafae06d7..d36537d71 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt @@ -48,7 +48,7 @@ public fun Sequence<DoubleArray>.toMatrix(): RealMatrix = toList().let { } public fun RealMatrix.repeatStackVertical(n: Int): RealMatrix = - VirtualMatrix(type, rowNum * n, colNum) { row, col -> + VirtualMatrix( rowNum * n, colNum) { row, col -> get(if (row == 0) 0 else row % rowNum, col) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt index 11131515a..3b9808028 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/Interpolator.kt @@ -54,14 +54,14 @@ public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials( public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials( data: Map<T, T>, ): PiecewisePolynomial<T> { - val pointSet = XYColumnarData.of(data.keys.toList().asBuffer(type), data.values.toList().asBuffer(type)) + val pointSet = XYColumnarData.of(data.keys.toList().asBuffer(), data.values.toList().asBuffer()) return interpolatePolynomials(pointSet) } public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials( data: List<Pair<T, T>>, ): PiecewisePolynomial<T> { - val pointSet = XYColumnarData.of(data.map { it.first }.asBuffer(type), data.map { it.second }.asBuffer(type)) + val pointSet = XYColumnarData.of(data.map { it.first }.asBuffer(), data.map { it.second }.asBuffer()) return interpolatePolynomials(pointSet) } diff --git a/kmath-geometry/build.gradle.kts b/kmath-geometry/build.gradle.kts index 32926db7e..4bf768f4b 100644 --- a/kmath-geometry/build.gradle.kts +++ b/kmath-geometry/build.gradle.kts @@ -6,6 +6,7 @@ kscience{ jvm() js() native() + wasm() useContextReceivers() useSerialization() diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt index 64396baff..71442cf63 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Vector3D.kt @@ -5,7 +5,6 @@ package space.kscience.kmath.geometry -import space.kscience.attributes.SafeType import space.kscience.kmath.linear.Point import space.kscience.kmath.structures.Buffer @@ -34,9 +33,6 @@ public fun <T> Buffer<T>.asVector3D(): Vector3D<T> = object : Vector3D<T> { require(this@asVector3D.size == 3) { "Buffer of size 3 is required for Vector3D" } } - override val type: SafeType<T> = this@asVector3D.type - - override val x: T get() = this@asVector3D[0] override val y: T get() = this@asVector3D[1] override val z: T get() = this@asVector3D[2] diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt index ed3caede8..ae140ff06 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float32Space2D.kt @@ -11,7 +11,6 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import space.kscience.attributes.SafeType import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector2D import space.kscience.kmath.operations.Float32Field @@ -20,10 +19,8 @@ import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.pow import kotlin.math.sqrt -@Serializable(Float32Space2D.VectorSerializer::class) -public interface Float32Vector2D : Vector2D<Float32>{ - override val type: SafeType<Float32> get() = Float32Field.type -} + +public typealias Float32Vector2D = Vector2D<Float32> public object Float32Space2D : GeometrySpace<Vector2D<Float32>, Float32> { diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt index 6a4f5ef34..37e11ba87 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt @@ -11,7 +11,6 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import space.kscience.attributes.SafeType import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector2D import space.kscience.kmath.operations.Float64Field @@ -22,10 +21,7 @@ import kotlin.math.pow import kotlin.math.sqrt -@Serializable(Float64Space2D.VectorSerializer::class) -public interface Float64Vector2D : Vector2D<Float64> { - override val type: SafeType<Float64> get() = Float64Field.type -} +public typealias Float64Vector2D = Vector2D<Float64> @Deprecated("Use Float64Vector2D", ReplaceWith("Float64Vector2D")) public typealias DoubleVector2D = Float64Vector2D diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt index 56ff49533..ad61a7b77 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float32Space3D.kt @@ -11,7 +11,6 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import space.kscience.attributes.SafeType import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector3D import space.kscience.kmath.operations.Float32Field @@ -20,10 +19,8 @@ import space.kscience.kmath.structures.MutableBufferFactory import kotlin.math.pow import kotlin.math.sqrt -@Serializable(Float32Space3D.VectorSerializer::class) -public interface Float32Vector3D : Vector3D<Float>{ - override val type: SafeType<Float32> get() = Float32Field.type -} + +public typealias Float32Vector3D = Vector3D<Float> public object Float32Space3D : GeometrySpace<Vector3D<Float32>, Float32> { diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt index 86ddf554b..fa07190bb 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/Float64Space3D.kt @@ -11,7 +11,6 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import space.kscience.attributes.SafeType import space.kscience.kmath.geometry.GeometrySpace import space.kscience.kmath.geometry.Vector3D import space.kscience.kmath.linear.Float64LinearSpace @@ -34,10 +33,7 @@ internal fun leviCivita(i: Int, j: Int, k: Int): Int = when { else -> 0 } -@Serializable(Float64Space3D.VectorSerializer::class) -public interface Float64Vector3D : Vector3D<Float64> { - override val type: SafeType<Float64> get() = Float64Field.type -} +public typealias Float64Vector3D = Vector3D<Float64> @Deprecated("Use Float64Vector3D", ReplaceWith("Float64Vector3D")) public typealias DoubleVector3D = Float64Vector3D diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt index e65bd8e22..1275ad630 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt @@ -5,7 +5,6 @@ package space.kscience.kmath.geometry.euclidean3d -import space.kscience.attributes.SafeType import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.complex.* import space.kscience.kmath.geometry.* @@ -245,8 +244,6 @@ public fun Quaternion.Companion.fromEuler( * A vector consisting of angles */ public data class AngleVector(override val x: Angle, override val y: Angle, override val z: Angle) : Vector3D<Angle> { - override val type: SafeType<Angle> get() = Angle.type - public companion object } diff --git a/kmath-memory/api/kmath-memory.api b/kmath-memory/api/kmath-memory.api index 67303dd97..d8bfe6625 100644 --- a/kmath-memory/api/kmath-memory.api +++ b/kmath-memory/api/kmath-memory.api @@ -38,7 +38,6 @@ public class space/kscience/kmath/memory/MemoryBuffer : space/kscience/kmath/str protected final fun getMemory ()Lspace/kscience/kmath/memory/Memory; public fun getSize ()I protected final fun getSpec ()Lspace/kscience/kmath/memory/MemorySpec; - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun iterator ()Ljava/util/Iterator; public fun toString ()Ljava/lang/String; } @@ -90,7 +89,6 @@ public abstract interface class space/kscience/kmath/memory/MemoryWriter : java/ public final class space/kscience/kmath/memory/MutableMemoryBuffer : space/kscience/kmath/memory/MemoryBuffer, space/kscience/kmath/structures/MutableBuffer { public static final field Companion Lspace/kscience/kmath/memory/MutableMemoryBuffer$Companion; public fun <init> (Lspace/kscience/kmath/memory/Memory;Lspace/kscience/kmath/memory/MemorySpec;)V - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; public fun set (ILjava/lang/Object;)V } diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemoryBuffer.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemoryBuffer.kt index ea6e705b6..27deea126 100644 --- a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemoryBuffer.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemoryBuffer.kt @@ -5,7 +5,6 @@ package space.kscience.kmath.memory -import space.kscience.attributes.SafeType import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer @@ -18,8 +17,6 @@ import space.kscience.kmath.structures.MutableBuffer */ public open class MemoryBuffer<T : Any>(protected val memory: Memory, protected val spec: MemorySpec<T>) : Buffer<T> { - override val type: SafeType<T> get() = spec.type - override val size: Int get() = memory.size / spec.objectSize override operator fun get(index: Int): T = memory.read { read(spec, spec.objectSize * index) } @@ -56,7 +53,6 @@ public class MutableMemoryBuffer<T : Any>( private val writer: MemoryWriter = memory.writer() override operator fun set(index: Int, value: T): Unit = writer.write(spec, spec.objectSize * index, value) - override fun copy(): MutableBuffer<T> = MutableMemoryBuffer(memory.copy(), spec) public companion object { public fun <T : Any> create(spec: MemorySpec<T>, size: Int): MutableMemoryBuffer<T> = diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt index 7ce9825d3..1c6dfe806 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt @@ -30,8 +30,6 @@ public val DataType.type: SafeType<*> @JvmInline public value class MultikTensor<T>(public val array: MutableMultiArray<T, DN>) : Tensor<T> { - @Suppress("UNCHECKED_CAST") - override val type: SafeType<T> get() = array.dtype.type as SafeType<T> override val shape: ShapeND get() = ShapeND(array.shape) diff --git a/kmath-nd4j/api/kmath-nd4j.api b/kmath-nd4j/api/kmath-nd4j.api index 74c6b8805..5a9a7985d 100644 --- a/kmath-nd4j/api/kmath-nd4j.api +++ b/kmath-nd4j/api/kmath-nd4j.api @@ -202,7 +202,6 @@ public final class space/kscience/kmath/nd4j/Nd4jArrayFloatStructure : space/ksc public fun get ([I)Ljava/lang/Float; public synthetic fun get ([I)Ljava/lang/Object; public fun getNdArray ()Lorg/nd4j/linalg/api/ndarray/INDArray; - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun hashCode ()I public fun set ([IF)V public synthetic fun set ([ILjava/lang/Object;)V diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt index 9bfc2f8f5..ac4ef68d2 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayStructure.kt @@ -6,10 +6,8 @@ package space.kscience.kmath.nd4j import org.nd4j.linalg.api.ndarray.INDArray -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.* -import space.kscience.kmath.operations.Float32Field /** * Represents a [StructureND] wrapping an [INDArray] object. @@ -70,8 +68,6 @@ public fun INDArray.asDoubleStructure(): Nd4jArrayStructure<Double> = Nd4jArrayD public data class Nd4jArrayFloatStructure(override val ndArray: INDArray) : Nd4jArrayStructure<Float>() { - override val type: SafeType<Float> get() = Float32Field.type - override fun elementsIterator(): Iterator<Pair<IntArray, Float>> = ndArray.floatIterator() @PerformancePitfall diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt index 96acf559a..8f0aa1729 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt @@ -64,7 +64,6 @@ public object ValueAndErrorField : Field<ValueAndError> { require(values.size == ds.size) } - override val type: SafeType<ValueAndError> get() = safeTypeOf() override val size: Int get() = values.size @@ -77,7 +76,6 @@ public object ValueAndErrorField : Field<ValueAndError> { values[index] = value.dispersion } - override fun copy(): MutableBuffer<ValueAndError> = ValueAndErrorBuffer(values.copy(), ds.copy()) } override val bufferFactory: MutableBufferFactory<ValueAndError> = object : MutableBufferFactory<ValueAndError> { diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt index 9a559bc28..516a3a2ce 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowAlgebra.kt @@ -10,7 +10,6 @@ import org.tensorflow.Output import org.tensorflow.ndarray.NdArray import org.tensorflow.op.core.Constant import org.tensorflow.types.TFloat64 -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.expressions.Symbol @@ -26,7 +25,6 @@ public class DoubleTensorFlowOutput( graph: Graph, output: Output<TFloat64>, ) : TensorFlowOutput<Double, TFloat64>(graph, output) { - override val type: SafeType<Double> get() = Float64Field.type override fun org.tensorflow.Tensor.actualizeTensor(): NdArray<Double> = this as TFloat64 } diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt index 3695a2640..95ed52638 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/IntTensorFlowAlgebra.kt @@ -10,19 +10,12 @@ import org.tensorflow.Output import org.tensorflow.ndarray.NdArray import org.tensorflow.types.TInt32 import org.tensorflow.types.TInt64 -import space.kscience.attributes.SafeType -import space.kscience.kmath.operations.Int32Ring -import space.kscience.kmath.operations.Int64Ring -import space.kscience.kmath.structures.Int32 -import space.kscience.kmath.structures.Int64 public class IntTensorFlowOutput( graph: Graph, output: Output<TInt32>, ) : TensorFlowOutput<Int, TInt32>(graph, output) { - override val type: SafeType<Int32> get() = Int32Ring.type - override fun org.tensorflow.Tensor.actualizeTensor(): NdArray<Int> = this as TInt32 } @@ -31,6 +24,5 @@ public class LongTensorFlowOutput( output: Output<TInt64>, ) : TensorFlowOutput<Long, TInt64>(graph, output) { - override val type: SafeType<Int64> get() = Int64Ring.type override fun org.tensorflow.Tensor.actualizeTensor(): NdArray<Long> = this as TInt64 } \ No newline at end of file diff --git a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt index 7e413c29c..2a8720275 100644 --- a/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt +++ b/kmath-tensorflow/src/main/kotlin/space/kscience/kmath/tensorflow/TensorFlowAlgebra.kt @@ -17,7 +17,6 @@ import org.tensorflow.op.core.* import org.tensorflow.types.TInt32 import org.tensorflow.types.family.TNumber import org.tensorflow.types.family.TType -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnsafeKMathAPI import space.kscience.kmath.UnstableKMathAPI @@ -40,7 +39,8 @@ public sealed interface TensorFlowTensor<T> : Tensor<T> /** * Static (eager) in-memory TensorFlow tensor */ -public class TensorFlowArray<T>(override val type: SafeType<T>, public val tensor: NdArray<T>) : Tensor<T> { +@JvmInline +public value class TensorFlowArray<T>(public val tensor: NdArray<T>) : Tensor<T> { override val shape: ShapeND get() = ShapeND(tensor.shape().asArray().toIntArray()) @@ -74,7 +74,7 @@ public abstract class TensorFlowOutput<T, TT : TType>( internal val actualTensor by lazy { Session(graph).use { session -> - TensorFlowArray(type, session.runner().fetch(output).run().first().actualizeTensor()) + TensorFlowArray(session.runner().fetch(output).run().first().actualizeTensor()) } } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt index b150c9839..b3c2eb1b4 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor.kt @@ -5,12 +5,10 @@ package space.kscience.kmath.tensors.core -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.UnstableKMathAPI import space.kscience.kmath.nd.MutableStructureNDOfDouble import space.kscience.kmath.nd.ShapeND -import space.kscience.kmath.operations.DoubleField import space.kscience.kmath.structures.* import space.kscience.kmath.tensors.core.internal.toPrettyString @@ -36,7 +34,7 @@ public class OffsetDoubleBuffer( /** * Copy only a part of buffer that belongs to this [OffsetDoubleBuffer] */ - override fun copy(): Float64Buffer = origin.array.copyOfRange(offset, offset + size).asBuffer() + public fun copy(): Float64Buffer = origin.array.copyOfRange(offset, offset + size).asBuffer() override fun iterator(): Iterator<Double> = iterator { for (i in indices) { @@ -90,8 +88,6 @@ public open class DoubleTensor( final override val source: OffsetDoubleBuffer, ) : BufferedTensor<Double>(shape), MutableStructureNDOfDouble { - override val type: SafeType<Double> get() = DoubleField.type - init { require(linearSize == source.size) { "Source buffer size must be equal tensor size" } } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor1D.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor1D.kt index 74a4f65c4..05f1b2f20 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor1D.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensor1D.kt @@ -8,7 +8,6 @@ package space.kscience.kmath.tensors.core import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.MutableStructure1D import space.kscience.kmath.nd.ShapeND -import space.kscience.kmath.structures.MutableBuffer public class DoubleTensor1D( source: OffsetDoubleBuffer, @@ -30,8 +29,6 @@ public class DoubleTensor1D( source[index] = value } - override fun copy(): MutableBuffer<Double> = source.copy() - @PerformancePitfall override fun elements(): Sequence<Pair<IntArray, Double>> = super<MutableStructure1D>.elements() } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt index 4c00933db..eb95d5e70 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensor.kt @@ -5,10 +5,8 @@ package space.kscience.kmath.tensors.core -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.ShapeND -import space.kscience.kmath.operations.IntRing import space.kscience.kmath.structures.* /** @@ -26,8 +24,6 @@ public class OffsetIntBuffer( require(offset + size <= source.size) { "Maximum index must be inside source dimension" } } - override val type: SafeType<Int> get() = IntRing.type - override fun set(index: Int, value: Int) { require(index in 0 until size) { "Index must be in [0, size)" } source[index + offset] = value @@ -38,7 +34,7 @@ public class OffsetIntBuffer( /** * Copy only a part of buffer that belongs to this tensor */ - override fun copy(): Int32Buffer = source.array.copyOfRange(offset, offset + size).asBuffer() + public fun copy(): Int32Buffer = source.array.copyOfRange(offset, offset + size).asBuffer() override fun iterator(): Iterator<Int> = iterator { for (i in indices) { @@ -87,7 +83,6 @@ public class IntTensor( require(linearSize == source.size) { "Source buffer size must be equal tensor size" } } - override val type: SafeType<Int> get() = IntRing.type public constructor(shape: ShapeND, buffer: Int32Buffer) : this(shape, OffsetIntBuffer(buffer, 0, buffer.size)) diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt index bafd3fadd..6490ecdb9 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorTransform.kt @@ -17,7 +17,7 @@ import space.kscience.kmath.tensors.api.Tensor public fun StructureND<Double>.copyToTensor(): DoubleTensor = if (this is DoubleTensor) { DoubleTensor(shape, source.copy()) } else if (this is Float64BufferND && indices is RowStrides) { - DoubleTensor(shape, buffer.copy()) + DoubleTensor(shape, buffer.array.copyOf().asBuffer()) } else { DoubleTensor( shape, diff --git a/kmath-viktor/api/kmath-viktor.api b/kmath-viktor/api/kmath-viktor.api index 11e312e12..0ad7368a9 100644 --- a/kmath-viktor/api/kmath-viktor.api +++ b/kmath-viktor/api/kmath-viktor.api @@ -1,8 +1,6 @@ public final class space/kscience/kmath/viktor/ViktorBuffer : space/kscience/kmath/structures/MutableBuffer { public static final synthetic fun box-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)Lspace/kscience/kmath/viktor/ViktorBuffer; public static fun constructor-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)Lorg/jetbrains/bio/viktor/F64FlatArray; - public fun copy ()Lspace/kscience/kmath/structures/MutableBuffer; - public static fun copy-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)Lspace/kscience/kmath/structures/MutableBuffer; public fun equals (Ljava/lang/Object;)Z public static fun equals-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;Ljava/lang/Object;)Z public static final fun equals-impl0 (Lorg/jetbrains/bio/viktor/F64FlatArray;Lorg/jetbrains/bio/viktor/F64FlatArray;)Z @@ -12,8 +10,6 @@ public final class space/kscience/kmath/viktor/ViktorBuffer : space/kscience/kma public final fun getFlatArray ()Lorg/jetbrains/bio/viktor/F64FlatArray; public fun getSize ()I public static fun getSize-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; - public static fun getType-V0oMfBY (Lorg/jetbrains/bio/viktor/F64FlatArray;)Lkotlin/reflect/KType; public fun hashCode ()I public static fun hashCode-impl (Lorg/jetbrains/bio/viktor/F64FlatArray;)I public fun iterator ()Ljava/util/Iterator; @@ -115,7 +111,6 @@ public final class space/kscience/kmath/viktor/ViktorStructureND : space/kscienc public synthetic fun get ([I)Ljava/lang/Object; public final fun getF64Buffer ()Lorg/jetbrains/bio/viktor/F64Array; public fun getShape-IIYLAfE ()[I - public fun getType-V0oMfBY ()Lkotlin/reflect/KType; public fun set ([ID)V public synthetic fun set ([ILjava/lang/Object;)V } diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt index 88112af2a..89b51f269 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorBuffer.kt @@ -6,15 +6,12 @@ package space.kscience.kmath.viktor import org.jetbrains.bio.viktor.F64FlatArray -import space.kscience.attributes.SafeType -import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.structures.Buffer import space.kscience.kmath.structures.MutableBuffer @Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE") @JvmInline public value class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer<Double> { - override val type: SafeType<Double> get() = Float64Field.type override val size: Int get() = flatArray.length @@ -25,7 +22,6 @@ public value class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuf flatArray[index] = value } - override fun copy(): MutableBuffer<Double> = ViktorBuffer(flatArray.copy().flatten()) override operator fun iterator(): Iterator<Double> = flatArray.data.iterator() override fun toString(): String = Buffer.toString(this) diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt index 9e01fd88a..328a0ab01 100644 --- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt +++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt @@ -6,17 +6,13 @@ package space.kscience.kmath.viktor import org.jetbrains.bio.viktor.F64Array -import space.kscience.attributes.SafeType import space.kscience.kmath.PerformancePitfall import space.kscience.kmath.nd.ColumnStrides import space.kscience.kmath.nd.MutableStructureND import space.kscience.kmath.nd.ShapeND -import space.kscience.kmath.operations.Float64Field @Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructureND<Double> { - override val type: SafeType<Double> get() = Float64Field.type - override val shape: ShapeND get() = ShapeND(f64Buffer.shape) @OptIn(PerformancePitfall::class) From 11722db3c827227b666e25636db012f5b65df2f1 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 8 Mar 2024 10:04:37 +0300 Subject: [PATCH 080/103] Add Attributes container equality --- .../kotlin/space/kscience/attributes/Attributes.kt | 14 ++++++++++---- .../space/kscience/attributes/AttributesBuilder.kt | 4 ++++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index 86d196f74..ff5d7f145 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -5,8 +5,6 @@ package space.kscience.attributes -import kotlin.jvm.JvmInline - /** * A set of attributes. The implementation must guarantee that [content] keys correspond to its value types. */ @@ -27,14 +25,22 @@ public interface Attributes { @Suppress("UNCHECKED_CAST") public operator fun <T> get(attribute: Attribute<T>): T? = content[attribute] as? T + override fun toString(): String + override fun equals(other: Any?): Boolean + override fun hashCode(): Int + public companion object { public val EMPTY: Attributes = AttributesImpl(emptyMap()) + + public fun equals(a1: Attributes, a2: Attributes): Boolean = + a1.keys == a2.keys && a1.keys.all { a1[it] == a2[it] } } } -@JvmInline -internal value class AttributesImpl(override val content: Map<out Attribute<*>, Any?>) : Attributes { +internal class AttributesImpl(override val content: Map<out Attribute<*>, Any?>) : Attributes { override fun toString(): String = "Attributes(value=${content.entries})" + override fun equals(other: Any?): Boolean = other is Attributes && Attributes.equals(this, other) + override fun hashCode(): Int = content.hashCode() } public fun Attributes.isEmpty(): Boolean = content.isEmpty() diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index 0acf4e004..0082ba143 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -16,6 +16,10 @@ public class AttributesBuilder<out O> internal constructor( public constructor() : this(mutableMapOf()) + override fun toString(): String = "Attributes(value=${content.entries})" + override fun equals(other: Any?): Boolean = other is Attributes && Attributes.equals(this, other) + override fun hashCode(): Int = content.hashCode() + override val content: Map<out Attribute<*>, Any?> get() = map public operator fun <T> set(attribute: Attribute<T>, value: T?) { From dcf5b19d800da1ea917d26fac70f3efdb9050af1 Mon Sep 17 00:00:00 2001 From: SPC-code <112205870+SPC-code@users.noreply.github.com> Date: Fri, 8 Mar 2024 10:06:30 +0300 Subject: [PATCH 081/103] Update attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com> --- .../commonMain/kotlin/space/kscience/attributes/Attributes.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index 86d196f74..fb0706504 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -8,7 +8,7 @@ package space.kscience.attributes import kotlin.jvm.JvmInline /** - * A set of attributes. The implementation must guarantee that [content] keys correspond to its value types. + * A set of attributes. The implementation must guarantee that [content] keys correspond to their value types. */ public interface Attributes { /** From e7d8b948899b7aa0063c51a5e375b5243f594837 Mon Sep 17 00:00:00 2001 From: SPC-code <112205870+SPC-code@users.noreply.github.com> Date: Fri, 8 Mar 2024 10:07:54 +0300 Subject: [PATCH 082/103] Update attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com> --- .../src/commonMain/kotlin/space/kscience/attributes/SafeType.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt index 1c7b0991a..b76589164 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/SafeType.kt @@ -11,7 +11,7 @@ import kotlin.reflect.KType import kotlin.reflect.typeOf /** - * Safe variant ok Kotlin [KType] that ensures that the type parameter is of the same type ask [kType] + * Safe variant ok Kotlin [KType] that ensures that the type parameter is of the same type as [kType] * * @param kType raw [KType] */ From b076a6573a622205457ed755765e796e46a07319 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Fri, 8 Mar 2024 10:18:32 +0300 Subject: [PATCH 083/103] Update versions --- attributes-kt/api/attributes-kt.api | 7 +++++++ build.gradle.kts | 4 ++-- buildSrc/settings.gradle.kts | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/attributes-kt/api/attributes-kt.api b/attributes-kt/api/attributes-kt.api index 26386d9d7..403e12f5c 100644 --- a/attributes-kt/api/attributes-kt.api +++ b/attributes-kt/api/attributes-kt.api @@ -14,12 +14,16 @@ public abstract interface class space/kscience/attributes/AttributeWithDefault : public abstract interface class space/kscience/attributes/Attributes { public static final field Companion Lspace/kscience/attributes/Attributes$Companion; + public abstract fun equals (Ljava/lang/Object;)Z public fun get (Lspace/kscience/attributes/Attribute;)Ljava/lang/Object; public abstract fun getContent ()Ljava/util/Map; public fun getKeys ()Ljava/util/Set; + public abstract fun hashCode ()I + public abstract fun toString ()Ljava/lang/String; } public final class space/kscience/attributes/Attributes$Companion { + public final fun equals (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attributes;)Z public final fun getEMPTY ()Lspace/kscience/attributes/Attributes; } @@ -27,11 +31,14 @@ public final class space/kscience/attributes/AttributesBuilder : space/kscience/ public fun <init> ()V public final fun add (Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)V public final fun build ()Lspace/kscience/attributes/Attributes; + public fun equals (Ljava/lang/Object;)Z public final fun from (Lspace/kscience/attributes/Attributes;)V public fun getContent ()Ljava/util/Map; + public fun hashCode ()I public final fun invoke (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V public final fun remove (Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)V public final fun set (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V + public fun toString ()Ljava/lang/String; } public final class space/kscience/attributes/AttributesBuilderKt { diff --git a/build.gradle.kts b/build.gradle.kts index 9231fc312..ec82e8eeb 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -14,7 +14,7 @@ allprojects { } group = "space.kscience" - version = "0.4.0-RC2" + version = "0.4.0" } subprojects { @@ -69,4 +69,4 @@ ksciencePublish { apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI") -val multikVersion by extra("0.2.2") +val multikVersion by extra("0.2.3") diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts index af804cb7d..09633711e 100644 --- a/buildSrc/settings.gradle.kts +++ b/buildSrc/settings.gradle.kts @@ -6,7 +6,7 @@ enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.7.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0" } dependencyResolutionManagement { From 86324a921989d32deec21ea58b128692ce264d9c Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 17 Mar 2024 09:29:15 +0300 Subject: [PATCH 084/103] Add RingBuffer `reset` and `capacity` --- .../kscience/kmath/streaming/RingBuffer.kt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt index 3ee6b203a..ce7f07860 100644 --- a/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt +++ b/kmath-coroutines/src/commonMain/kotlin/space/kscience/kmath/streaming/RingBuffer.kt @@ -23,6 +23,8 @@ public class RingBuffer<T>( private val mutex: Mutex = Mutex() + public val capacity: Int get() = buffer.size + override var size: Int = size private set @@ -32,7 +34,7 @@ public class RingBuffer<T>( return buffer[startIndex.forward(index)] } - public fun isFull(): Boolean = size == buffer.size + public fun isFull(): Boolean = size == capacity /** * Iterator could provide wrong results if buffer is changed in initialization (iteration is safe) @@ -59,6 +61,9 @@ public class RingBuffer<T>( VirtualBuffer(size) { i -> copy[startIndex.forward(i)] } } + /** + * Add an element to the end of the [RingBuffer]. If buffer capacity is reached, the first element is automatically removed. + */ public suspend fun push(element: T) { mutex.withLock { buffer[startIndex.forward(size)] = element @@ -66,7 +71,15 @@ public class RingBuffer<T>( } } - private fun Int.forward(n: Int): Int = (this + n) % (buffer.size) + /** + * Reset buffer to its empty state + */ + public suspend fun reset(): Unit = mutex.withLock { + startIndex = 0 + size = 0 + } + + private fun Int.forward(n: Int): Int = (this + n) % capacity override fun toString(): String = Buffer.toString(this) } From 82196250f651d0ba82eb89a1ac3b008b2af184a1 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Sun, 17 Mar 2024 09:42:50 +0300 Subject: [PATCH 085/103] Remove unnecessary internal dependencies --- kmath-coroutines/build.gradle.kts | 3 +-- kmath-multik/build.gradle.kts | 2 +- .../kotlin/space/kscience/kmath/multik/MultikTensor.kt | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/kmath-coroutines/build.gradle.kts b/kmath-coroutines/build.gradle.kts index 91b2afd5e..0cb36e10a 100644 --- a/kmath-coroutines/build.gradle.kts +++ b/kmath-coroutines/build.gradle.kts @@ -9,8 +9,7 @@ kscience { wasm() dependencies { - api(project(":kmath-core")) - api(project(":kmath-complex")) + api(projects.kmathCore) api(spclibs.kotlinx.coroutines.core) } } diff --git a/kmath-multik/build.gradle.kts b/kmath-multik/build.gradle.kts index fc51d2c21..85c4d52cb 100644 --- a/kmath-multik/build.gradle.kts +++ b/kmath-multik/build.gradle.kts @@ -15,7 +15,7 @@ kotlin{ sourceSets{ commonMain{ dependencies{ - api(project(":kmath-tensors")) + api(projects.kmathTensors) api("org.jetbrains.kotlinx:multik-core:$multikVersion") } } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt index 1c6dfe806..20916d934 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensor.kt @@ -9,7 +9,6 @@ import org.jetbrains.kotlinx.multik.ndarray.data.* import space.kscience.attributes.SafeType import space.kscience.attributes.safeTypeOf import space.kscience.kmath.PerformancePitfall -import space.kscience.kmath.complex.ComplexField import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.operations.* import space.kscience.kmath.tensors.api.Tensor @@ -24,7 +23,7 @@ public val DataType.type: SafeType<*> DataType.FloatDataType -> Float32Field.type DataType.DoubleDataType -> Float64Field.type DataType.ComplexFloatDataType -> safeTypeOf<Pair<Float, Float>>() - DataType.ComplexDoubleDataType -> ComplexField.type + DataType.ComplexDoubleDataType -> safeTypeOf<Pair<Double, Double>>() } From 69b59b43f4aa3d3635f26c70241d9563cc119b08 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 07:43:54 +0300 Subject: [PATCH 086/103] Mark polymorphic attribute getters and setters as unstable --- .../kotlin/space/kscience/attributes/PolymorphicAttribute.kt | 2 ++ .../space/kscience/kmath/optimization/OptimizationProblem.kt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt index b61d4c477..80767421a 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt @@ -21,11 +21,13 @@ public abstract class PolymorphicAttribute<T>(public val type: SafeType<T>) : At /** * Get a polymorphic attribute using attribute factory */ +@UnstableAttributesAPI public operator fun <T> Attributes.get(attributeKeyBuilder: () -> PolymorphicAttribute<T>): T? = get(attributeKeyBuilder()) /** * Set a polymorphic attribute using its factory */ +@UnstableAttributesAPI public operator fun <O, T> AttributesBuilder<O>.set(attributeKeyBuilder: () -> PolymorphicAttribute<T>, value: T) { set(attributeKeyBuilder(), value) } diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt index 18f552bda..b9530f83c 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt @@ -24,7 +24,7 @@ public val <T> OptimizationProblem<T>.startPoint: Map<Symbol, T> get() = attributes[OptimizationStartPoint()] ?: error("Starting point not defined in $this") public fun <T> AttributesBuilder<OptimizationProblem<T>>.startAt(startingPoint: Map<Symbol, T>) { - set(::OptimizationStartPoint, startingPoint) + set(OptimizationStartPoint(), startingPoint) } From efef5996e19c8c49637e537682f27e9dfed9fa2c Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 07:44:33 +0300 Subject: [PATCH 087/103] Remove contracts --- .../space/kscience/kmath/benchmarks/JafamaBenchmark.kt | 3 --- .../space/kscience/kmath/asm/internal/GenericAsmBuilder.kt | 4 ---- .../space/kscience/kmath/expressions/SimpleAutoDiff.kt | 6 +----- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt index 69479200d..b0e029870 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt @@ -13,8 +13,6 @@ import space.kscience.kmath.jafama.JafamaDoubleField import space.kscience.kmath.jafama.StrictJafamaDoubleField import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.invoke -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract import kotlin.random.Random @State(Scope.Benchmark) @@ -36,7 +34,6 @@ internal class JafamaBenchmark { } private inline fun invokeBenchmarks(blackhole: Blackhole, expr: (Double) -> Double) { - contract { callsInPlace(expr, InvocationKind.AT_LEAST_ONCE) } val rng = Random(0) repeat(1000000) { blackhole.consume(expr(rng.nextDouble())) } } diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/GenericAsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/GenericAsmBuilder.kt index 5314c4cc3..4c20afde5 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/GenericAsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/GenericAsmBuilder.kt @@ -13,9 +13,6 @@ import space.kscience.kmath.expressions.* import java.lang.invoke.MethodHandles import java.lang.invoke.MethodType import java.nio.file.Paths -import java.util.stream.Collectors.toMap -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract import kotlin.io.path.writeBytes /** @@ -283,7 +280,6 @@ internal class GenericAsmBuilder<T>( fun loadVariable(name: Symbol): Unit = invokeMethodVisitor.load(2 + argumentsLocals.indexOf(name), tType) inline fun buildCall(function: Function<T>, parameters: GenericAsmBuilder<T>.() -> Unit) { - contract { callsInPlace(parameters, InvocationKind.EXACTLY_ONCE) } val `interface` = function.javaClass.interfaces.first { Function::class.java in it.interfaces } val arity = `interface`.methods.find { it.name == "invoke" }?.parameterCount diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt index 1209372b4..8d7d9e03a 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt @@ -224,11 +224,7 @@ public inline fun <T : Any, F : Field<T>> SimpleAutoDiffField<T, F>.const(block: public fun <T : Any, F : Field<T>> F.simpleAutoDiff( bindings: Map<Symbol, T>, body: SimpleAutoDiffField<T, F>.() -> AutoDiffValue<T>, -): DerivationResult<T> { - contract { callsInPlace(body, InvocationKind.EXACTLY_ONCE) } - - return SimpleAutoDiffField(this, bindings).differentiate(body) -} +): DerivationResult<T> = SimpleAutoDiffField(this, bindings).differentiate(body) public fun <T : Any, F : Field<T>> F.simpleAutoDiff( vararg bindings: Pair<Symbol, T>, From a67bda8a3331cc6b3e12764c3065e14881c742a6 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 07:44:53 +0300 Subject: [PATCH 088/103] Adjust build --- attributes-kt/build.gradle.kts | 2 +- build.gradle.kts | 2 ++ examples/build.gradle.kts | 4 ++-- .../kotlin/space/kscience/kmath/optimization/XYFit.kt | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/attributes-kt/build.gradle.kts b/attributes-kt/build.gradle.kts index 5956f1f16..555567aac 100644 --- a/attributes-kt/build.gradle.kts +++ b/attributes-kt/build.gradle.kts @@ -3,7 +3,7 @@ plugins { `maven-publish` } -version = "0.1.0" +version = rootProject.extra.get("attributesVersion").toString() kscience { jvm() diff --git a/build.gradle.kts b/build.gradle.kts index ec82e8eeb..9ee719967 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,6 +6,8 @@ plugins { id("org.jetbrains.kotlinx.kover") version "0.7.6" } +val attributesVersion by extra("0.1.0") + allprojects { repositories { maven("https://repo.kotlin.link") diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 97a3cb8c2..b155f2653 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -67,8 +67,8 @@ kotlin { } tasks.withType<KotlinJvmCompile> { - kotlinOptions { - freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + "-Xopt-in=kotlin.RequiresOptIn" + "-Xlambdas=indy" + compilerOptions{ + freeCompilerArgs.addAll("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn", "-Xlambdas=indy") } } diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt index 3861a796d..a954b769a 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt @@ -124,7 +124,7 @@ public suspend fun XYColumnarData<Double, Double, Double>.fitWith( this, modelExpression, attributes.modify<XYFit> { - set(::OptimizationStartPoint, startingPoint) + set(OptimizationStartPoint(), startingPoint) if (!hasAny<OptimizationLog>()) { set(OptimizationLog, Loggable.console) } From 1be6a5ca0e1f9b8b04a5571409482bcc0e472afd Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 07:45:57 +0300 Subject: [PATCH 089/103] LinearSpace.compute -> LinearSpace.withComputedAttribute --- .../kotlin/space/kscience/kmath/linear/LinearSpace.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt index fb4661b96..343470e2e 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LinearSpace.kt @@ -182,7 +182,7 @@ public interface LinearSpace<T, out A : Ring<T>> : MatrixScope<T> { * better use [StructureND.getOrComputeAttribute]. */ @UnstableKMathAPI - public fun <V : Any, A : StructureAttribute<V>> Matrix<T>.compute( + public fun <V : Any, A : StructureAttribute<V>> Matrix<T>.withComputedAttribute( attribute: A, ): Matrix<T>? { return if (attributes[attribute] != null) { From 461e5a7c54722e222fa7777bb47f029ada35876f Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 08:12:39 +0300 Subject: [PATCH 090/103] Refactor names for AttributesBuilder behavior --- .../space/kscience/attributes/Attributes.kt | 2 +- .../kscience/attributes/AttributesBuilder.kt | 17 ++++++++++------- .../kmath/commons/optimization/CMOptimizer.kt | 2 +- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index 9d186acf1..56cd91b13 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -84,7 +84,7 @@ public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attribu * Create a new [Attributes] by modifying the current one */ public fun <T> Attributes.modify(block: AttributesBuilder<T>.() -> Unit): Attributes = Attributes<T> { - from(this@modify) + putAll(this@modify) block() } diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index 0082ba143..033c143cc 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -34,13 +34,18 @@ public class AttributesBuilder<out O> internal constructor( set(this, value) } - public fun from(attributes: Attributes) { + public infix fun <V> Attribute<V>.put(value: V?) { + set(this, value) + } + + /** + * Put all attributes for given [attributes] + */ + public fun putAll(attributes: Attributes) { map.putAll(attributes.content) } - public fun <V> SetAttribute<V>.add( - attrValue: V, - ) { + public infix fun <V> SetAttribute<V>.add(attrValue: V) { val currentSet: Set<V> = get(this) ?: emptySet() map[this] = currentSet + attrValue } @@ -48,9 +53,7 @@ public class AttributesBuilder<out O> internal constructor( /** * Remove an element from [SetAttribute] */ - public fun <V> SetAttribute<V>.remove( - attrValue: V, - ) { + public infix fun <V> SetAttribute<V>.remove(attrValue: V) { val currentSet: Set<V> = get(this) ?: emptySet() map[this] = currentSet - attrValue } diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt index 3c5f8f5e2..4030e630f 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/optimization/CMOptimizer.kt @@ -43,7 +43,7 @@ public object CMOptimizerData : SetAttribute<SymbolIndexer.() -> OptimizationDat * Specify Commons-maths optimization data. */ public fun AttributesBuilder<FunctionOptimization<Double>>.cmOptimizationData(data: SymbolIndexer.() -> OptimizationData) { - CMOptimizerData.add(data) + CMOptimizerData add data } public fun AttributesBuilder<FunctionOptimization<Double>>.simplexSteps(vararg steps: Pair<Symbol, Double>) { From ec88d6be9eeaa7d202fb006fad5fa28e6e0ecb70 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 08:19:22 +0300 Subject: [PATCH 091/103] Remove unnecessary reification --- .../kotlin/space/kscience/kmath/structures/LazyStructureND.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt index 1d23162f5..6acf5c1c8 100644 --- a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt +++ b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt @@ -48,13 +48,13 @@ public suspend fun <T> StructureND<T>.await(index: IntArray): T = * PENDING would benefit from KEEP-176 */ @OptIn(PerformancePitfall::class) -public inline fun <T, reified R> StructureND<T>.mapAsyncIndexed( +public inline fun <T, R> StructureND<T>.mapAsyncIndexed( scope: CoroutineScope, crossinline function: suspend (T, index: IntArray) -> R, ): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index), index) } @OptIn(PerformancePitfall::class) -public inline fun <T, reified R> StructureND<T>.mapAsync( +public inline fun <T, R> StructureND<T>.mapAsync( scope: CoroutineScope, crossinline function: suspend (T) -> R, ): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index)) } From ecb5d281107ed6d08836f8f7efc5ad76041db28a Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 08:51:56 +0300 Subject: [PATCH 092/103] Attributes modify->modified --- .../commonMain/kotlin/space/kscience/attributes/Attributes.kt | 4 ++-- .../space/kscience/kmath/integration/MultivariateIntegrand.kt | 2 +- .../space/kscience/kmath/integration/UnivariateIntegrand.kt | 2 +- .../space/kscience/kmath/optimization/FunctionOptimization.kt | 2 +- .../kotlin/space/kscience/kmath/optimization/XYFit.kt | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index 56cd91b13..ad53049eb 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -83,8 +83,8 @@ public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attribu /** * Create a new [Attributes] by modifying the current one */ -public fun <T> Attributes.modify(block: AttributesBuilder<T>.() -> Unit): Attributes = Attributes<T> { - putAll(this@modify) +public fun <T> Attributes.modified(block: AttributesBuilder<T>.() -> Unit): Attributes = Attributes<T> { + putAll(this@modified) block() } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt index 960e07b5b..1afb59e5d 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -26,7 +26,7 @@ public fun <T, A : Any> MultivariateIntegrand<T>.withAttribute( public fun <T> MultivariateIntegrand<T>.withAttributes( block: AttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, -): MultivariateIntegrand<T> = withAttributes(attributes.modify(block)) +): MultivariateIntegrand<T> = withAttributes(attributes.modified(block)) public inline fun <reified T : Any> MultivariateIntegrand( attributeBuilder: AttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index 9d718e633..dbe507233 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -27,7 +27,7 @@ public fun <T, A : Any> UnivariateIntegrand<T>.withAttribute( public fun <T> UnivariateIntegrand<T>.withAttributes( block: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, -): UnivariateIntegrand<T> = withAttributes(attributes.modify(block)) +): UnivariateIntegrand<T> = withAttributes(attributes.modified(block)) public inline fun <reified T : Any> UnivariateIntegrand( attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt index a38e9e6e8..a891b0a7f 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -65,7 +65,7 @@ public fun <T> FunctionOptimization<T>.withAttributes( modifier: AttributesBuilder<FunctionOptimization<T>>.() -> Unit, ): FunctionOptimization<T> = FunctionOptimization( expression, - attributes.modify(modifier), + attributes.modified(modifier), ) /** diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt index a954b769a..44b7d17bd 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/XYFit.kt @@ -108,7 +108,7 @@ public fun XYOptimization( public fun XYFit.withAttributes( modifier: AttributesBuilder<XYFit>.() -> Unit, -): XYFit = XYFit(data, model, attributes.modify(modifier), pointToCurveDistance, pointWeight, xSymbol) +): XYFit = XYFit(data, model, attributes.modified(modifier), pointToCurveDistance, pointWeight, xSymbol) public suspend fun XYColumnarData<Double, Double, Double>.fitWith( optimizer: Optimizer<Double, XYFit>, @@ -123,7 +123,7 @@ public suspend fun XYColumnarData<Double, Double, Double>.fitWith( val problem = XYFit( this, modelExpression, - attributes.modify<XYFit> { + attributes.modified<XYFit> { set(OptimizationStartPoint(), startingPoint) if (!hasAny<OptimizationLog>()) { set(OptimizationLog, Loggable.console) From 214467d21c1d84358ce8e6488de1b82291a699e5 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 09:11:12 +0300 Subject: [PATCH 093/103] Reformat code --- .space.kts | 2 +- CHANGELOG.md | 12 +- README.md | 131 ++++++++++++------ .../attributes/PolymorphicAttribute.kt | 3 +- .../ExpressionsInterpretersBenchmark.kt | 1 + .../kmath/benchmarks/BigIntBenchmark.kt | 4 +- .../kmath/benchmarks/BufferBenchmark.kt | 2 +- .../kmath/benchmarks/IntegrationBenchmark.kt | 4 +- build.gradle.kts | 2 +- buildSrc/build.gradle.kts | 4 +- .../benchmarks/addBenchmarkProperties.kt | 23 +-- docs/buffers.md | 2 +- docs/codestyle.md | 24 ++-- docs/expressions.md | 13 +- docs/linear.md | 9 +- docs/nd-structure.md | 24 +++- docs/polynomials.md | 97 ++++++++++--- docs/templates/ARTIFACT-TEMPLATE.md | 1 + docs/templates/README-TEMPLATE.md | 17 ++- examples/build.gradle.kts | 2 +- .../kscience/kmath/expressions/autodiff.kt | 3 +- .../space/kscience/kmath/fit/chiSquared.kt | 2 +- .../kmath/operations/mixedNDOperations.kt | 1 - .../space/kscience/kmath/series/analyzeDif.kt | 4 +- .../kmath/structures/StreamDoubleFieldND.kt | 5 +- .../kscience/kmath/structures/buffers.kt | 2 +- .../StaticLm/staticDifficultTest.kt | 10 +- .../StaticLm/staticEasyTest.kt | 8 +- .../StaticLm/staticMiddleTest.kt | 11 +- .../StreamingLm/streamLm.kt | 23 +-- .../StreamingLm/streamingLmTest.kt | 9 +- .../LevenbergMarquardt/functionsToOptimize.kt | 50 ++++--- gradle.properties | 3 - gradle/wrapper/gradle-wrapper.properties | 2 +- kmath-ast/README.md | 32 +++-- kmath-ast/build.gradle.kts | 6 +- kmath-ast/docs/README-TEMPLATE.md | 22 ++- .../space/kscience/kmath/ast/TypedMst.kt | 2 +- .../kscience/kmath/ast/rendering/features.kt | 24 ++-- .../kmath/ast/rendering/TestFeatures.kt | 3 +- .../kmath/ast/rendering/TestMathML.kt | 6 +- .../kmath/internal/binaryen/index.binaryen.kt | 30 ++-- .../internal/estree/estree.extensions.kt | 13 +- .../kmath/internal/tsstdlib/lib.es5.kt | 2 +- .../lib.dom.WebAssembly.module_dukat.kt | 2 +- .../kotlin/space/kscience/kmath/asm/asm.kt | 2 +- .../kmath/asm/internal/PrimitiveAsmBuilder.kt | 2 +- .../kmath/asm/internal/codegenUtils.kt | 1 - kmath-commons/README.md | 1 + .../integration/CMGaussRuleIntegrator.kt | 4 +- .../kscience/kmath/commons/linear/CMSolver.kt | 6 +- .../commons/optimization/OptimizeTest.kt | 2 +- kmath-complex/README.md | 6 +- .../space/kscience/kmath/complex/Complex.kt | 4 +- .../kscience/kmath/complex/ComplexFieldND.kt | 5 +- kmath-core/README.md | 27 ++-- kmath-core/build.gradle.kts | 6 +- .../kmath/data/XYErrorColumnarData.kt | 2 +- .../space/kscience/kmath/expressions/MST.kt | 1 + .../kscience/kmath/linear/LupDecomposition.kt | 8 +- .../space/kscience/kmath/nd/Int16RingND.kt | 5 +- .../space/kscience/kmath/nd/IntRingND.kt | 2 +- .../kscience/kmath/nd/algebraNDExtentions.kt | 4 +- .../space/kscience/kmath/operations/BigInt.kt | 2 + .../kmath/operations/Float64BufferField.kt | 2 +- .../kmath/operations/OptionalOperations.kt | 2 +- .../kmath/operations/algebraExtensions.kt | 7 +- .../kmath/operations/integerFields.kt | 6 +- .../kscience/kmath/structures/ArrayBuffer.kt | 2 +- .../kmath/structures/FlaggedBuffer.kt | 2 +- .../kmath/structures/Float32Buffer.kt | 3 +- .../kmath/structures/MutableBuffer.kt | 19 +-- .../kmath/linear/DoubleLUSolverTest.kt | 6 +- .../space/kscience/kmath/linear/MatrixTest.kt | 2 +- .../space/kscience/kmath/misc/PermSortTest.kt | 22 +-- .../kscience/kmath/nd/NdOperationsTest.kt | 2 +- .../space/kscience/kmath/nd/StridesTest.kt | 12 +- .../kmath/structures/BufferExpandedTest.kt | 10 +- .../linear/Float64ParallelLinearSpace.kt | 2 +- .../kscience/kmath/operations/isInteger.kt | 3 +- .../kmath/structures/parallelMutableBuffer.kt | 3 +- .../kmath/linear/ParallelMatrixTest.kt | 8 +- .../kscience/kmath/operations/isInteger.kt | 3 +- kmath-coroutines/README.md | 3 +- .../kmath/structures/LazyStructureND.kt | 3 +- kmath-dimensions/README.md | 1 + kmath-dimensions/build.gradle.kts | 4 +- kmath-ejml/README.md | 8 +- .../kscience/kmath/ejml/implementations.kt | 16 ++- kmath-for-real/README.md | 10 +- .../space/kscience/kmath/real/RealMatrix.kt | 2 +- .../kotlin/space/kscience/kmath/real/grids.kt | 2 +- .../space/kscience/kmath/real/GridTest.kt | 4 +- kmath-functions/README.md | 14 +- kmath-functions/build.gradle.kts | 2 +- .../kmath/functions/polynomialUtil.kt | 2 +- .../integration/GaussIntegratorRuleFactory.kt | 2 +- .../kscience/kmath/integration/Integrand.kt | 4 +- .../kmath/functions/PolynomialTest.kt | 12 +- .../kmath/functions/PolynomialUtilTest.kt | 27 +++- .../kmath/functions/testUtils/IntModulo.kt | 9 ++ .../functions/testUtils/IntModuloUtils.kt | 1 + .../kmath/functions/testUtils/Rational.kt | 12 ++ .../kmath/functions/testUtils/misc.kt | 36 ++++- .../kmath/integration/GaussIntegralTest.kt | 2 +- kmath-geometry/README.md | 3 +- kmath-geometry/build.gradle.kts | 4 +- .../kscience/kmath/geometry/GeometrySpace.kt | 2 +- .../space/kscience/kmath/geometry/Polygon.kt | 2 +- .../space/kscience/kmath/geometry/angles.kt | 2 +- .../geometry/euclidean2d/Float64Space2D.kt | 1 - .../kmath/geometry/euclidean3d/rotations3D.kt | 2 +- .../kmath/geometry/ProjectionAlongTest.kt | 2 +- .../kscience/kmath/geometry/RotationTest.kt | 6 +- .../kscience/kmath/geometry/testUtils.kt | 8 +- kmath-histograms/README.md | 3 +- kmath-histograms/build.gradle.kts | 2 +- .../space/kscience/kmath/histogram/Counter.kt | 2 +- .../kmath/histogram/TreeHistogramTest.kt | 4 +- kmath-jafama/README.md | 7 +- kmath-jafama/docs/README-TEMPLATE.md | 3 +- kmath-jupyter/README.md | 3 +- kmath-kotlingrad/README.md | 8 +- kmath-memory/README.md | 3 +- .../space/kscience/kmath/memory/Memory.kt | 4 +- .../space/kscience/kmath/memory/MemorySpec.kt | 2 +- .../space/kscience/kmath/memory/MemoryTest.kt | 6 +- kmath-multik/README.md | 1 + kmath-multik/build.gradle.kts | 12 +- .../kmath/multik/MultikDoubleAlgebra.kt | 15 +- .../kmath/multik/MultikFloatAlgebra.kt | 2 +- .../kscience/kmath/multik/MultikIntAlgebra.kt | 4 +- .../kmath/multik/MultikLongAlgebra.kt | 4 +- .../kmath/multik/MultikShortAlgebra.kt | 4 +- .../kmath/multik/MultikTensorAlgebra.kt | 7 +- kmath-nd4j/README.md | 8 +- .../kscience/kmath/nd4j/Nd4jArrayAlgebra.kt | 3 +- .../kscience/kmath/nd4j/Nd4jTensorAlgebra.kt | 9 +- .../kmath/nd4j/Nd4jArrayAlgebraTest.kt | 2 +- kmath-optimization/README.md | 3 +- kmath-optimization/build.gradle.kts | 2 +- .../optimization/FunctionOptimization.kt | 6 +- .../kmath/optimization/OptimizationProblem.kt | 2 +- .../kmath/optimization/QowOptimizer.kt | 2 +- .../kmath/optimization/logLikelihood.kt | 2 +- .../src/commonMain/tmp/QowFit.kt | 6 +- .../tmp/minuit/CombinedMinimumBuilder.kt | 2 +- .../commonMain/tmp/minuit/ContoursError.kt | 2 +- .../tmp/minuit/DavidonErrorUpdator.kt | 6 +- .../commonMain/tmp/minuit/FunctionMinimum.kt | 14 +- .../src/commonMain/tmp/minuit/MINUITFitter.kt | 1 + .../src/commonMain/tmp/minuit/MINUITPlugin.kt | 6 +- .../commonMain/tmp/minuit/MinimumBuilder.kt | 2 +- .../commonMain/tmp/minuit/MnApplication.kt | 6 +- .../src/commonMain/tmp/minuit/MnContours.kt | 12 +- .../commonMain/tmp/minuit/MnFunctionCross.kt | 9 +- .../src/commonMain/tmp/minuit/MnHesse.kt | 20 ++- .../src/commonMain/tmp/minuit/MnLineSearch.kt | 5 +- .../src/commonMain/tmp/minuit/MnMigrad.kt | 30 ++-- .../src/commonMain/tmp/minuit/MnMinimize.kt | 30 ++-- .../src/commonMain/tmp/minuit/MnPrint.kt | 6 +- .../src/commonMain/tmp/minuit/MnScan.kt | 30 ++-- .../commonMain/tmp/minuit/MnSeedGenerator.kt | 16 ++- .../src/commonMain/tmp/minuit/MnSimplex.kt | 30 ++-- .../tmp/minuit/MnUserParameterState.kt | 14 +- .../tmp/minuit/MnUserTransformation.kt | 30 ++-- .../tmp/minuit/ModularFunctionMinimizer.kt | 4 +- .../tmp/minuit/NegativeG2LineSearch.kt | 12 +- .../src/commonMain/tmp/minuit/ScanBuilder.kt | 2 +- .../commonMain/tmp/minuit/SimplexBuilder.kt | 2 +- .../tmp/minuit/SimplexSeedGenerator.kt | 6 +- .../tmp/minuit/VariableMetricBuilder.kt | 2 +- kmath-stat/README.md | 3 +- kmath-stat/build.gradle.kts | 2 +- .../kmath/distributions/NormalDistribution.kt | 5 +- .../kscience/kmath/random/RandomChain.kt | 3 +- .../kscience/kmath/samplers/InternalGamma.kt | 4 +- .../space/kscience/kmath/samplers/Sampler.kt | 4 +- .../kscience/kmath/series/SeriesAlgebra.kt | 4 +- .../kotlin/space/kscience/kmath/stat/Mean.kt | 4 +- .../kscience/kmath/stat/ValueAndErrorField.kt | 2 +- .../space/kscience/kmath/series/TestSeries.kt | 4 +- .../kmath/series/TestVarianceRatioTest.kt | 4 +- .../space/kscience/kmath/stat/MCScopeTest.kt | 2 +- kmath-symja/README.md | 1 + kmath-tensorflow/README.md | 1 + .../kmath/tensorflow/DoubleTensorFlowOps.kt | 6 +- kmath-tensors/README.md | 11 +- kmath-tensors/build.gradle.kts | 8 +- .../tensors/api/AnalyticTensorAlgebra.kt | 6 +- .../kmath/tensors/core/DoubleTensorAlgebra.kt | 11 +- .../kmath/tensors/core/IntTensorAlgebra.kt | 2 +- .../tensors/core/internal/broadcastUtils.kt | 1 + .../tensors/core/internal/intTensorHelpers.kt | 2 +- .../kmath/tensors/core/internal/linUtils.kt | 2 +- .../kscience/kmath/tensors/core/tensorOps.kt | 8 +- kmath-viktor/README.md | 1 + kmath-viktor/build.gradle.kts | 2 +- test-utils/build.gradle.kts | 2 +- .../src/commonMain/kotlin/bufferEquality.kt | 3 +- 200 files changed, 1023 insertions(+), 591 deletions(-) diff --git a/.space.kts b/.space.kts index ce52a2f5c..45c84ae3d 100644 --- a/.space.kts +++ b/.space.kts @@ -34,7 +34,7 @@ job("Publish") { api.space().projects.automation.deployments.start( project = api.projectIdentifier(), targetIdentifier = TargetIdentifier.Key(projectName), - version = version+revisionSuffix, + version = version + revisionSuffix, // automatically update deployment status based on the status of a job syncWithAutomationJob = true ) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c383fe95..6bf936c10 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,7 +77,8 @@ - Major refactor of tensors (only minor API changes) - Kotlin 1.8.20 - `LazyStructure` `deffered` -> `async` to comply with coroutines code style -- Default `dot` operation in tensor algebra no longer support broadcasting. Instead `matmul` operation is added to `DoubleTensorAlgebra`. +- Default `dot` operation in tensor algebra no longer support broadcasting. Instead `matmul` operation is added + to `DoubleTensorAlgebra`. - Multik went MPP ### Removed @@ -236,9 +237,11 @@ - MST to JVM bytecode translator (https://github.com/mipt-npm/kmath/pull/94) - FloatBuffer (specialized MutableBuffer over FloatArray) - FlaggedBuffer to associate primitive numbers buffer with flags (to mark values infinite or missing, etc.) -- Specialized builder functions for all primitive buffers like `IntBuffer(25) { it + 1 }` (https://github.com/mipt-npm/kmath/pull/125) +- Specialized builder functions for all primitive buffers + like `IntBuffer(25) { it + 1 }` (https://github.com/mipt-npm/kmath/pull/125) - Interface `NumericAlgebra` where `number` operation is available to convert numbers to algebraic elements -- Inverse trigonometric functions support in ExtendedField (`asin`, `acos`, `atan`) (https://github.com/mipt-npm/kmath/pull/114) +- Inverse trigonometric functions support in + ExtendedField (`asin`, `acos`, `atan`) (https://github.com/mipt-npm/kmath/pull/114) - New space extensions: `average` and `averageWith` - Local coding conventions - Geometric Domains API in `kmath-core` @@ -251,7 +254,8 @@ - `readAsMemory` now has `throws IOException` in JVM signature. - Several functions taking functional types were made `inline`. - Several functions taking functional types now have `callsInPlace` contracts. -- BigInteger and BigDecimal algebra: JBigDecimalField has companion object with default math context; minor optimizations +- BigInteger and BigDecimal algebra: JBigDecimalField has companion object with default math context; minor + optimizations - `power(T, Int)` extension function has preconditions and supports `Field<T>` - Memory objects have more preconditions (overflow checking) - `tg` function is renamed to `tan` (https://github.com/mipt-npm/kmath/pull/114) diff --git a/README.md b/README.md index 00ba00ede..cd2503a12 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,8 @@ experience could be achieved with [kmath-for-real](/kmath-for-real) extension mo # Goal -* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS, Native and Wasm). +* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS, Native and + Wasm). * Provide basic multiplatform implementations for those abstractions (without significant performance optimization). * Provide bindings and wrappers with those abstractions for popular optimized platform libraries. @@ -55,150 +56,181 @@ module definitions below. The module stability could have the following levels: ## Modules - ### [attributes-kt](attributes-kt) + > An API and basic implementation for arranging objects in a continuous memory block. > > **Maturity**: DEVELOPMENT ### [benchmarks](benchmarks) + > > **Maturity**: EXPERIMENTAL ### [examples](examples) + > > **Maturity**: EXPERIMENTAL ### [kmath-ast](kmath-ast) + > > **Maturity**: EXPERIMENTAL > > **Features:** -> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser -> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler +> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and + its parser +> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode + compiler > - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler -> - [rendering](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering - +> - [rendering](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST + rendering ### [kmath-commons](kmath-commons) + > Commons math binding for kmath > > **Maturity**: EXPERIMENTAL ### [kmath-complex](kmath-complex) + > Complex numbers and quaternions. > > **Maturity**: PROTOTYPE > > **Features:** > - [complex](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations -> - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition - +> - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their + composition ### [kmath-core](kmath-core) + > Core classes, algebra definitions, basic linear algebra > > **Maturity**: DEVELOPMENT > > **Features:** -> - [algebras](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields. -> - [nd](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them. -> - [linear](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition. +> - [algebras](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like + rings, spaces and fields. +> - [nd](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures + and operations on them. +> - [linear](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra + operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix + inversion and LU decomposition. > - [buffers](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure -> - [expressions](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of -objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high -performance calculations to code generation. +> - [expressions](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical + expression once, users will be able to apply different types of + objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high + performance calculations to code generation. > - [domains](kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains) : Domains -> - [autodiff](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation - +> - [autodiff](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic + differentiation ### [kmath-coroutines](kmath-coroutines) + > > **Maturity**: EXPERIMENTAL ### [kmath-dimensions](kmath-dimensions) + > A proof of concept module for adding type-safe dimensions to structures > > **Maturity**: PROTOTYPE ### [kmath-ejml](kmath-ejml) + > > **Maturity**: PROTOTYPE > > **Features:** > - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations. > - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation. -> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations. - +> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace + implementations. ### [kmath-for-real](kmath-for-real) + > Extension module that should be used to achieve numpy-like behavior. -All operations are specialized to work with `Double` numbers without declaring algebraic contexts. -One can still use generic algebras though. +> All operations are specialized to work with `Double` numbers without declaring algebraic contexts. +> One can still use generic algebras though. > > **Maturity**: EXPERIMENTAL > > **Features:** -> - [DoubleVector](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for Buffers/Points -> - [DoubleMatrix](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures +> - [DoubleVector](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like + operations for Buffers/Points +> - [DoubleMatrix](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like + operations for 2d real structures > - [grids](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators - ### [kmath-functions](kmath-functions) + > Functions, integration and interpolation > > **Maturity**: EXPERIMENTAL > > **Features:** -> - [piecewise](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions. -> - [polynomials](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions. -> - [linear interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY interpolator. -> - [spline interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator. +> - [piecewise](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise + functions. +> - [polynomials](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial + functions. +> - [linear interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : + Linear XY interpolator. +> - [spline interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : + Cubic spline XY interpolator. > - [integration](kmath-functions/#) : Univariate and multivariate quadratures - ### [kmath-geometry](kmath-geometry) + > > **Maturity**: PROTOTYPE ### [kmath-histograms](kmath-histograms) + > > **Maturity**: PROTOTYPE ### [kmath-jafama](kmath-jafama) + > Jafama integration module > > **Maturity**: DEPRECATED > > **Features:** -> - [jafama-double](kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama - +> - [jafama-double](kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations + based on Jafama ### [kmath-jupyter](kmath-jupyter) + > > **Maturity**: PROTOTYPE ### [kmath-kotlingrad](kmath-kotlingrad) + > Kotlin∇ integration module > > **Maturity**: EXPERIMENTAL > > **Features:** -> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based DifferentiableExpression. -> - [scalars-adapters](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s SFun and MST - +> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : + MST based DifferentiableExpression. +> - [scalars-adapters](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : + Conversions between Kotlin∇'s SFun and MST ### [kmath-memory](kmath-memory) + > An API and basic implementation for arranging objects in a continuous memory block. > > **Maturity**: DEVELOPMENT ### [kmath-multik](kmath-multik) + > JetBrains Multik connector > > **Maturity**: PROTOTYPE ### [kmath-nd4j](kmath-nd4j) + > ND4J NDStructure implementation and according NDAlgebra classes > > **Maturity**: DEPRECATED @@ -208,45 +240,52 @@ One can still use generic algebras though. > - [nd4jarrayrings](kmath-nd4j/#) : Rings over Nd4jArrayStructure of Int and Long > - [nd4jarrayfields](kmath-nd4j/#) : Fields over Nd4jArrayStructure of Float and Double - ### [kmath-optimization](kmath-optimization) + > > **Maturity**: EXPERIMENTAL ### [kmath-stat](kmath-stat) + > > **Maturity**: EXPERIMENTAL ### [kmath-symja](kmath-symja) + > Symja integration module > > **Maturity**: PROTOTYPE ### [kmath-tensorflow](kmath-tensorflow) + > Google tensorflow connector > > **Maturity**: PROTOTYPE ### [kmath-tensors](kmath-tensors) + > > **Maturity**: PROTOTYPE > > **Features:** -> - [tensor algebra](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic linear algebra operations on tensors (plus, dot, etc.) -> - [tensor algebra with broadcasting](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : Basic linear algebra operations implemented with broadcasting. -> - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc. - +> - [tensor algebra](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic + linear algebra operations on tensors (plus, dot, etc.) +> - [tensor algebra with broadcasting](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : + Basic linear algebra operations implemented with broadcasting. +> - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : + Advanced linear algebra operations like LU decomposition, SVD, etc. ### [kmath-viktor](kmath-viktor) + > Binding for https://github.com/JetBrains-Research/viktor > > **Maturity**: DEVELOPMENT ### [test-utils](test-utils) + > > **Maturity**: EXPERIMENTAL - ## Multi-platform support KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the @@ -257,16 +296,19 @@ feedback are also welcome. ## Performance -Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to achieve both +Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to +achieve both performance and flexibility. We expect to focus on creating a convenient universal API first and then work on increasing performance for specific cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized -native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy. +native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be +better than SciPy. ## Requirements -KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or Oracle GraalVM for execution to get better performance. +KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or +Oracle GraalVM for execution to get better performance. ### Repositories @@ -289,4 +331,7 @@ dependencies { ## Contributing The project requires a lot of additional work. The most important thing we need is feedback about what features are -required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues marked with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label. \ No newline at end of file +required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues +marked +with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) +label. \ No newline at end of file diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt index 80767421a..e81d88e46 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/PolymorphicAttribute.kt @@ -22,7 +22,8 @@ public abstract class PolymorphicAttribute<T>(public val type: SafeType<T>) : At * Get a polymorphic attribute using attribute factory */ @UnstableAttributesAPI -public operator fun <T> Attributes.get(attributeKeyBuilder: () -> PolymorphicAttribute<T>): T? = get(attributeKeyBuilder()) +public operator fun <T> Attributes.get(attributeKeyBuilder: () -> PolymorphicAttribute<T>): T? = + get(attributeKeyBuilder()) /** * Set a polymorphic attribute using its factory diff --git a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt index 4fa5be9f1..29d4cde79 100644 --- a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt +++ b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt @@ -94,6 +94,7 @@ class ExpressionsInterpretersBenchmark { } private val mst = node.toExpression(Float64Field) + @OptIn(UnstableKMathAPI::class) private val wasm = node.wasmCompileToExpression(Float64Field) private val estree = node.estreeCompileToExpression(Float64Field) diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt index a67f52b67..a4c2855f1 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt @@ -67,7 +67,7 @@ internal class BigIntBenchmark { @Benchmark fun kmMultiplyLarge(blackhole: Blackhole) = BigIntField { - blackhole.consume(kmLargeNumber*kmLargeNumber) + blackhole.consume(kmLargeNumber * kmLargeNumber) } @Benchmark @@ -77,7 +77,7 @@ internal class BigIntBenchmark { @Benchmark fun jvmMultiplyLarge(blackhole: Blackhole) = JBigIntegerField { - blackhole.consume(jvmLargeNumber*jvmLargeNumber) + blackhole.consume(jvmLargeNumber * jvmLargeNumber) } @Benchmark diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt index 9f665709c..a37d12ffb 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt @@ -75,6 +75,6 @@ internal class BufferBenchmark { private companion object { private const val size = 100 - private val reversedIndices = IntArray(size){it}.apply { reverse() } + private val reversedIndices = IntArray(size) { it }.apply { reverse() } } } diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt index 021c654a1..00f2d908d 100644 --- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt +++ b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt @@ -24,7 +24,7 @@ internal class IntegrationBenchmark { fun doubleIntegration(blackhole: Blackhole) { val res = Double.algebra.gaussIntegrator.integrate(0.0..1.0, intervals = 1000) { x: Double -> //sin(1 / x) - 1/x + 1 / x }.value blackhole.consume(res) } @@ -33,7 +33,7 @@ internal class IntegrationBenchmark { fun complexIntegration(blackhole: Blackhole) = with(Complex.algebra) { val res = gaussIntegrator.integrate(0.0..1.0, intervals = 1000) { x: Double -> // sin(1 / x) + i * cos(1 / x) - 1/x - i/x + 1 / x - i / x }.value blackhole.consume(res) } diff --git a/build.gradle.kts b/build.gradle.kts index 9ee719967..537cc2708 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -65,7 +65,7 @@ ksciencePublish { useApache2Licence() useSPCTeam() } - repository("spc","https://maven.sciprog.center/kscience") + repository("spc", "https://maven.sciprog.center/kscience") sonatype("https://oss.sonatype.org") } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 89bb32b15..ba4c391d8 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -24,8 +24,8 @@ dependencies { implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.+") } -kotlin{ - jvmToolchain{ +kotlin { + jvmToolchain { languageVersion.set(JavaLanguageVersion.of(11)) } sourceSets.all { diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt index fc04c82cf..ae2083c5f 100644 --- a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt +++ b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt @@ -63,7 +63,8 @@ fun Project.addBenchmarkProperties() { if (resDirectory == null || !(resDirectory.resolve("jvm.json")).exists()) { "> **Can't find appropriate benchmark data. Try generating readme files after running benchmarks**." } else { - val reports: List<JmhReport> = jsonMapper.readValue<List<JmhReport>>(resDirectory.resolve("jvm.json")) + val reports: List<JmhReport> = + jsonMapper.readValue<List<JmhReport>>(resDirectory.resolve("jvm.json")) buildString { appendLine("<details>") @@ -76,16 +77,20 @@ fun Project.addBenchmarkProperties() { appendLine("* Run on ${first.vmName} (build ${first.vmVersion}) with Java process:") appendLine() appendLine("```") - appendLine("${first.jvm} ${ - first.jvmArgs.joinToString(" ") - }") + appendLine( + "${first.jvm} ${ + first.jvmArgs.joinToString(" ") + }" + ) appendLine("```") - appendLine("* JMH ${first.jmhVersion} was used in `${first.mode}` mode with ${first.warmupIterations} warmup ${ - noun(first.warmupIterations, "iteration", "iterations") - } by ${first.warmupTime} and ${first.measurementIterations} measurement ${ - noun(first.measurementIterations, "iteration", "iterations") - } by ${first.measurementTime}.") + appendLine( + "* JMH ${first.jmhVersion} was used in `${first.mode}` mode with ${first.warmupIterations} warmup ${ + noun(first.warmupIterations, "iteration", "iterations") + } by ${first.warmupTime} and ${first.measurementIterations} measurement ${ + noun(first.measurementIterations, "iteration", "iterations") + } by ${first.measurementTime}." + ) appendLine() appendLine("| Benchmark | Score |") diff --git a/docs/buffers.md b/docs/buffers.md index e7573497e..ce56d58c4 100644 --- a/docs/buffers.md +++ b/docs/buffers.md @@ -17,4 +17,4 @@ own `MemoryBuffer.create()` factory). ## Buffer performance One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers -instead . +instead . diff --git a/docs/codestyle.md b/docs/codestyle.md index 73ba5f754..fb18e5103 100644 --- a/docs/codestyle.md +++ b/docs/codestyle.md @@ -1,27 +1,35 @@ # Coding Conventions -Generally, KMath code follows general [Kotlin coding conventions](https://kotlinlang.org/docs/reference/coding-conventions.html), but with a number of small changes and clarifications. +Generally, KMath code follows +general [Kotlin coding conventions](https://kotlinlang.org/docs/reference/coding-conventions.html), but with a number of +small changes and clarifications. ## Utility Class Naming -Filename should coincide with a name of one of the classes contained in the file or start with small letter and describe its contents. +Filename should coincide with a name of one of the classes contained in the file or start with small letter and describe +its contents. -The code convention [here](https://kotlinlang.org/docs/reference/coding-conventions.html#source-file-names) says that file names should start with a capital letter even if file does not contain classes. Yet starting utility classes and aggregators with a small letter seems to be a good way to visually separate those files. +The code convention [here](https://kotlinlang.org/docs/reference/coding-conventions.html#source-file-names) says that +file names should start with a capital letter even if file does not contain classes. Yet starting utility classes and +aggregators with a small letter seems to be a good way to visually separate those files. This convention could be changed in future in a non-breaking way. ## Private Variable Naming -Private variables' names may start with underscore `_` for of the private mutable variable is shadowed by the public read-only value with the same meaning. +Private variables' names may start with underscore `_` for of the private mutable variable is shadowed by the public +read-only value with the same meaning. -This rule does not permit underscores in names, but it is sometimes useful to "underscore" the fact that public and private versions draw up the same entity. It is allowed only for private variables. +This rule does not permit underscores in names, but it is sometimes useful to "underscore" the fact that public and +private versions draw up the same entity. It is allowed only for private variables. This convention could be changed in future in a non-breaking way. ## Functions and Properties One-liners -Use one-liners when they occupy single code window line both for functions and properties with getters like -`val b: String get() = "fff"`. The same should be performed with multiline expressions when they could be +Use one-liners when they occupy single code window line both for functions and properties with getters like +`val b: String get() = "fff"`. The same should be performed with multiline expressions when they could be cleanly separated. -There is no universal consensus whenever use `fun a() = ...` or `fun a() { return ... }`. Yet from reader outlook one-lines seem to better show that the property or function is easily calculated. +There is no universal consensus whenever use `fun a() = ...` or `fun a() { return ... }`. Yet from reader outlook +one-lines seem to better show that the property or function is easily calculated. diff --git a/docs/expressions.md b/docs/expressions.md index e6250110c..cb9deca45 100644 --- a/docs/expressions.md +++ b/docs/expressions.md @@ -1,21 +1,24 @@ # Expressions -Expressions is a feature, which allows constructing lazily or immediately calculated parametric mathematical expressions. +Expressions is a feature, which allows constructing lazily or immediately calculated parametric mathematical +expressions. The potential use-cases for it (so far) are following: * lazy evaluation (in general simple lambda is better, but there are some border cases); * automatic differentiation in single-dimension and in multiple dimensions; * generation of mathematical syntax trees with subsequent code generation for other languages; -* symbolic computations, especially differentiation (and some other actions with `kmath-symja` integration with Symja's `IExpr`—integration, simplification, and more); +* symbolic computations, especially differentiation (and some other actions with `kmath-symja` integration with + Symja's `IExpr`—integration, simplification, and more); * visualization with `kmath-jupyter`. -The workhorse of this API is `Expression` interface, which exposes single `operator fun invoke(arguments: Map<Symbol, T>): T` +The workhorse of this API is `Expression` interface, which exposes +single `operator fun invoke(arguments: Map<Symbol, T>): T` method. `ExpressionAlgebra` is used to generate expressions and introduce variables. Currently there are two implementations: * Generic `ExpressionField` in `kmath-core` which allows construction of custom lazy expressions -* Auto-differentiation expression in `kmath-commons` module allows using full power of `DerivativeStructure` -from commons-math. **TODO: add example** +* Auto-differentiation expression in `kmath-commons` module allows using full power of `DerivativeStructure` + from commons-math. **TODO: add example** diff --git a/docs/linear.md b/docs/linear.md index 2a05499ef..3ded92ffe 100644 --- a/docs/linear.md +++ b/docs/linear.md @@ -1,8 +1,12 @@ ## Basic linear algebra layout -KMath support for linear algebra organized in a context-oriented way, which means that operations are in most cases declared in context classes, and are not the members of classes that store data. This allows more flexible approach to maintain multiple back-ends. The new operations added as extensions to contexts instead of being member functions of data structures. +KMath support for linear algebra organized in a context-oriented way, which means that operations are in most cases +declared in context classes, and are not the members of classes that store data. This allows more flexible approach to +maintain multiple back-ends. The new operations added as extensions to contexts instead of being member functions of +data structures. -The main context for linear algebra over matrices and vectors is `LinearSpace`, which defines addition and dot products of matrices and vectors: +The main context for linear algebra over matrices and vectors is `LinearSpace`, which defines addition and dot products +of matrices and vectors: ```kotlin import space.kscience.kmath.linear.* @@ -28,4 +32,5 @@ LinearSpace.Companion.real { ## Backends overview ### EJML + ### Commons Math diff --git a/docs/nd-structure.md b/docs/nd-structure.md index 3e9203ec0..8f2e504db 100644 --- a/docs/nd-structure.md +++ b/docs/nd-structure.md @@ -8,6 +8,7 @@ One of the most sought after features of mathematical libraries is the high-perf structures. In `kmath` performance depends on which particular context was used for operation. Let us consider following contexts: + ```kotlin // automatically build context most suited for given type. val autoField = NDField.auto(DoubleField, dim, dim) @@ -16,6 +17,7 @@ Let us consider following contexts: //A generic boxing field. It should be used for objects, not primitives. val genericField = NDField.buffered(DoubleField, dim, dim) ``` + Now let us perform several tests and see, which implementation is best suited for each case: ## Test case @@ -24,7 +26,9 @@ To test performance we will take 2d-structures with `dim = 1000` and add a struc to it `n = 1000` times. ## Specialized + The code to run this looks like: + ```kotlin specializedField.run { var res: NDBuffer<Double> = one @@ -33,13 +37,16 @@ The code to run this looks like: } } ``` + The performance of this code is the best of all tests since it inlines all operations and is specialized for operation with doubles. We will measure everything else relative to this one, so time for this test will be `1x` (real time on my computer is about 4.5 seconds). The only problem with this approach is that it requires specifying type from the beginning. Everyone does so anyway, so it is the recommended approach. ## Automatic + Let's do the same with automatic field inference: + ```kotlin autoField.run { var res = one @@ -48,13 +55,16 @@ Let's do the same with automatic field inference: } } ``` + Ths speed of this operation is approximately the same as for specialized case since `NDField.auto` just returns the same `RealNDField` in this case. Of course, it is usually better to use specialized method to be sure. ## Lazy + Lazy field does not produce a structure when asked, instead it generates an empty structure and fills it on-demand using coroutines to parallelize computations. When one calls + ```kotlin lazyField.run { var res = one @@ -63,12 +73,14 @@ When one calls } } ``` + The result will be calculated almost immediately but the result will be empty. To get the full result structure one needs to call all its elements. In this case computation overhead will be huge. So this field never should be used if one expects to use the full result structure. Though if one wants only small fraction, it could save a lot of time. This field still could be used with reasonable performance if call code is changed: + ```kotlin lazyField.run { val res = one.map { @@ -82,10 +94,13 @@ This field still could be used with reasonable performance if call code is chang res.elements().forEach { it.second } } ``` + In this case it completes in about `4x-5x` time due to boxing. ## Boxing + The boxing field produced by + ```kotlin genericField.run { var res: NDBuffer<Double> = one @@ -94,18 +109,22 @@ The boxing field produced by } } ``` + is the slowest one, because it requires boxing and unboxing the `double` on each operation. It takes about `15x` time (**TODO: there seems to be a problem here, it should be slow, but not that slow**). This field should never be used for primitives. ## Element operation + Let us also check the speed for direct operations on elements: + ```kotlin var res = genericField.one repeat(n) { res += 1.0 } ``` + One would expect to be at least as slow as field operation, but in fact, this one takes only `2x` time to complete. It happens, because in this particular case it does not use actual `NDField` but instead calculated directly via extension function. @@ -114,6 +133,7 @@ via extension function. Usually it is bad idea to compare the direct numerical operation performance in different languages, but it hard to work completely without frame of reference. In this case, simple numpy code: + ```python import numpy as np @@ -121,7 +141,9 @@ res = np.ones((1000,1000)) for i in range(1000): res = res + 1.0 ``` -gives the completion time of about `1.1x`, which means that specialized kotlin code in fact is working faster (I think it is + +gives the completion time of about `1.1x`, which means that specialized kotlin code in fact is working faster (I think +it is because better memory management). Of course if one writes `res += 1.0`, the performance will be different, but it would be different case, because numpy overrides `+=` with in-place operations. In-place operations are available in `kmath` with `MutableNDStructure` but there is no field for it (one can still work with mapping diff --git a/docs/polynomials.md b/docs/polynomials.md index b255acda1..5fdce0a91 100644 --- a/docs/polynomials.md +++ b/docs/polynomials.md @@ -1,27 +1,54 @@ # Polynomials and Rational Functions -KMath provides a way to work with uni- and multivariate polynomials and rational functions. It includes full support of arithmetic operations of integers, **constants** (elements of ring polynomials are build over), variables (for certain multivariate implementations), polynomials and rational functions encapsulated in so-called **polynomial space** and **rational function space** and some other utilities such as algebraic differentiation and substitution. +KMath provides a way to work with uni- and multivariate polynomials and rational functions. It includes full support of +arithmetic operations of integers, **constants** (elements of ring polynomials are build over), variables (for certain +multivariate implementations), polynomials and rational functions encapsulated in so-called **polynomial space** and * +*rational function space** and some other utilities such as algebraic differentiation and substitution. ## Concrete realizations There are 3 approaches to represent polynomials: -1. For univariate polynomials one can represent and store polynomial as a list of coefficients for each power of the variable. I.e. polynomial $a_0 + \dots + a_n x^n $ can be represented as a finite sequence $(a_0; \dots; a_n)$. (Compare to sequential definition of polynomials.) -2. For multivariate polynomials one can represent and store polynomial as a matching (in programming it is called "map" or "dictionary", in math it is called [functional relation](https://en.wikipedia.org/wiki/Binary_relation#Special_types_of_binary_relations)) of each "**term signature**" (that describes what variables and in what powers appear in the term) with corresponding coefficient of the term. But there are 2 possible approaches of term signature representation: - 1. One can number all the variables, so term signature can be represented as a sequence describing powers of the variables. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for natural or zero $d_i $) can be represented as a finite sequence $(d_0; \dots; d_n)$. - 2. One can represent variables as objects ("**labels**"), so term signature can be also represented as a matching of each appeared variable with its power in the term. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for natural non-zero $d_i $) can be represented as a finite matching $(x_0 \to d_1; \dots; x_n \to d_n)$. -All that three approaches are implemented by "list", "numbered", and "labeled" versions of polynomials and polynomial spaces respectively. Whereas all rational functions are represented as fractions with corresponding polynomial numerator and denominator, and rational functions' spaces are implemented in the same way as usual field of rational numbers (or more precisely, as any field of fractions over integral domain) should be implemented. +1. For univariate polynomials one can represent and store polynomial as a list of coefficients for each power of the + variable. I.e. polynomial $a_0 + \dots + a_n x^n $ can be represented as a finite sequence $(a_0; \dots; a_n)$. ( + Compare to sequential definition of polynomials.) +2. For multivariate polynomials one can represent and store polynomial as a matching (in programming it is called "map" + or "dictionary", in math it is + called [functional relation](https://en.wikipedia.org/wiki/Binary_relation#Special_types_of_binary_relations)) of + each "**term signature**" (that describes what variables and in what powers appear in the term) with corresponding + coefficient of the term. But there are 2 possible approaches of term signature representation: + 1. One can number all the variables, so term signature can be represented as a sequence describing powers of the + variables. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for natural or zero $d_i $) can be + represented as a finite sequence $(d_0; \dots; d_n)$. + 2. One can represent variables as objects ("**labels**"), so term signature can be also represented as a matching of + each appeared variable with its power in the term. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for + natural non-zero $d_i $) can be represented as a finite matching $(x_0 \to d_1; \dots; x_n \to d_n)$. + +All that three approaches are implemented by "list", "numbered", and "labeled" versions of polynomials and polynomial +spaces respectively. Whereas all rational functions are represented as fractions with corresponding polynomial numerator +and denominator, and rational functions' spaces are implemented in the same way as usual field of rational numbers (or +more precisely, as any field of fractions over integral domain) should be implemented. So here are a bit of details. Let `C` by type of constants. Then: -1. `ListPolynomial`, `ListPolynomialSpace`, `ListRationalFunction` and `ListRationalFunctionSpace` implement the first scenario. `ListPolynomial` stores polynomial $a_0 + \dots + a_n x^n $ as a coefficients list `listOf(a_0, ..., a_n)` (of type `List<C>`). - - They also have variation `ScalableListPolynomialSpace` that replaces former polynomials and implements `ScaleOperations`. -2. `NumberedPolynomial`, `NumberedPolynomialSpace`, `NumberedRationalFunction` and `NumberedRationalFunctionSpace` implement second scenario. `NumberedPolynomial` stores polynomials as structures of type `Map<List<UInt>, C>`. Signatures are stored as `List<UInt>`. To prevent ambiguity signatures should not end with zeros. -3. `LabeledPolynomial`, `LabeledPolynomialSpace`, `LabeledRationalFunction` and `LabeledRationalFunctionSpace` implement third scenario using common `Symbol` as variable type. `LabeledPolynomial` stores polynomials as structures of type `Map<Map<Symbol, UInt>, C>`. Signatures are stored as `Map<Symbol, UInt>`. To prevent ambiguity each signature should not map any variable to zero. + +1. `ListPolynomial`, `ListPolynomialSpace`, `ListRationalFunction` and `ListRationalFunctionSpace` implement the first + scenario. `ListPolynomial` stores polynomial $a_0 + \dots + a_n x^n $ as a coefficients + list `listOf(a_0, ..., a_n)` (of type `List<C>`). + + They also have variation `ScalableListPolynomialSpace` that replaces former polynomials and + implements `ScaleOperations`. +2. `NumberedPolynomial`, `NumberedPolynomialSpace`, `NumberedRationalFunction` and `NumberedRationalFunctionSpace` + implement second scenario. `NumberedPolynomial` stores polynomials as structures of type `Map<List<UInt>, C>`. + Signatures are stored as `List<UInt>`. To prevent ambiguity signatures should not end with zeros. +3. `LabeledPolynomial`, `LabeledPolynomialSpace`, `LabeledRationalFunction` and `LabeledRationalFunctionSpace` implement + third scenario using common `Symbol` as variable type. `LabeledPolynomial` stores polynomials as structures of + type `Map<Map<Symbol, UInt>, C>`. Signatures are stored as `Map<Symbol, UInt>`. To prevent ambiguity each signature + should not map any variable to zero. ### Example: `ListPolynomial` -For example, polynomial $2 - 3x + x^2 $ (with `Int` coefficients) is represented +For example, polynomial $2 - 3x + x^2 $ (with `Int` coefficients) is represented + ```kotlin val polynomial: ListPolynomial<Int> = ListPolynomial(listOf(2, -3, 1)) // or @@ -29,6 +56,7 @@ val polynomial: ListPolynomial<Int> = ListPolynomial(2, -3, 1) ``` All algebraic operations can be used in corresponding space: + ```kotlin val computationResult = Int.algebra.listPolynomialSpace { ListPolynomial(2, -3, 1) + ListPolynomial(0, 6) == ListPolynomial(2, 3, 1) @@ -41,7 +69,8 @@ For more see [examples](../examples/src/main/kotlin/space/kscience/kmath/functio ### Example: `NumberedPolynomial` -For example, polynomial $3 + 5 x_1 - 7 x_0^2 x_2 $ (with `Int` coefficients) is represented +For example, polynomial $3 + 5 x_1 - 7 x_0^2 x_2 $ (with `Int` coefficients) is represented + ```kotlin val polynomial: NumberedPolynomial<Int> = NumberedPolynomial( mapOf( @@ -59,6 +88,7 @@ val polynomial: NumberedPolynomial<Int> = NumberedPolynomial( ``` All algebraic operations can be used in corresponding space: + ```kotlin val computationResult = Int.algebra.numberedPolynomialSpace { NumberedPolynomial( @@ -83,7 +113,8 @@ For more see [examples](../examples/src/main/kotlin/space/kscience/kmath/functio ### Example: `LabeledPolynomial` -For example, polynomial $3 + 5 y - 7 x^2 z $ (with `Int` coefficients) is represented +For example, polynomial $3 + 5 y - 7 x^2 z $ (with `Int` coefficients) is represented + ```kotlin val polynomial: LabeledPolynomial<Int> = LabeledPolynomial( mapOf( @@ -101,6 +132,7 @@ val polynomial: LabeledPolynomial<Int> = LabeledPolynomial( ``` All algebraic operations can be used in corresponding space: + ```kotlin val computationResult = Int.algebra.labeledPolynomialSpace { LabeledPolynomial( @@ -150,23 +182,42 @@ classDiagram PolynomialSpaceOfFractions <|-- MultivariatePolynomialSpaceOfFractions ``` -There are implemented `Polynomial` and `RationalFunction` interfaces as abstractions of polynomials and rational functions respectively (although, there is not a lot of logic in them) and `PolynomialSpace` and `RationalFunctionSpace` (that implement `Ring` interface) as abstractions of polynomials' and rational functions' spaces respectively. More precisely, that means they allow to declare common logic of interaction with such objects and spaces: +There are implemented `Polynomial` and `RationalFunction` interfaces as abstractions of polynomials and rational +functions respectively (although, there is not a lot of logic in them) and `PolynomialSpace` +and `RationalFunctionSpace` (that implement `Ring` interface) as abstractions of polynomials' and rational functions' +spaces respectively. More precisely, that means they allow to declare common logic of interaction with such objects and +spaces: + - `Polynomial` does not provide any logic. It is marker interface. - `RationalFunction` provides numerator and denominator of rational function and destructuring declaration for them. -- `PolynomialSpace` provides all possible arithmetic interactions of integers, constants (of type `C`), and polynomials (of type `P`) like addition, subtraction, multiplication, and some others and common properties like degree of polynomial. -- `RationalFunctionSpace` provides the same as `PolynomialSpace` but also for rational functions: all possible arithmetic interactions of integers, constants (of type `C`), polynomials (of type `P`), and rational functions (of type `R`) like addition, subtraction, multiplication, division (in some cases), and some others and common properties like degree of polynomial. +- `PolynomialSpace` provides all possible arithmetic interactions of integers, constants (of type `C`), and + polynomials (of type `P`) like addition, subtraction, multiplication, and some others and common properties like + degree of polynomial. +- `RationalFunctionSpace` provides the same as `PolynomialSpace` but also for rational functions: all possible + arithmetic interactions of integers, constants (of type `C`), polynomials (of type `P`), and rational functions (of + type `R`) like addition, subtraction, multiplication, division (in some cases), and some others and common properties + like degree of polynomial. -Then to add abstraction of similar behaviour with variables (in multivariate case) there are implemented `MultivariatePolynomialSpace` and `MultivariateRationalFunctionSpace`. They just include variables (of type `V`) in the interactions of the entities. +Then to add abstraction of similar behaviour with variables (in multivariate case) there are +implemented `MultivariatePolynomialSpace` and `MultivariateRationalFunctionSpace`. They just include variables (of +type `V`) in the interactions of the entities. Also, to remove boilerplates there were provided helping subinterfaces and abstract subclasses: -- `PolynomialSpaceOverRing` allows to replace implementation of interactions of integers and constants with implementations from provided ring over constants (of type `A: Ring<C>`). + +- `PolynomialSpaceOverRing` allows to replace implementation of interactions of integers and constants with + implementations from provided ring over constants (of type `A: Ring<C>`). - `RationalFunctionSpaceOverRing` — the same but for `RationalFunctionSpace`. -- `RationalFunctionSpaceOverPolynomialSpace` — the same but "the inheritance" includes interactions with polynomials from provided `PolynomialSpace`. -- `PolynomialSpaceOfFractions` is actually abstract subclass of `RationalFunctionSpace` that implements all fractions boilerplates with provided (`protected`) constructor of rational functions by polynomial numerator and denominator. -- `MultivariateRationalFunctionSpaceOverMultivariatePolynomialSpace` and `MultivariatePolynomialSpaceOfFractions` — the same stories of operators inheritance and fractions boilerplates respectively but in multivariate case. +- `RationalFunctionSpaceOverPolynomialSpace` — the same but "the inheritance" includes interactions with + polynomials from provided `PolynomialSpace`. +- `PolynomialSpaceOfFractions` is actually abstract subclass of `RationalFunctionSpace` that implements all fractions + boilerplates with provided (`protected`) constructor of rational functions by polynomial numerator and denominator. +- `MultivariateRationalFunctionSpaceOverMultivariatePolynomialSpace` and `MultivariatePolynomialSpaceOfFractions` + — the same stories of operators inheritance and fractions boilerplates respectively but in multivariate case. ## Utilities -For all kinds of polynomials there are provided (implementation details depend on kind of polynomials) such common utilities as: +For all kinds of polynomials there are provided (implementation details depend on kind of polynomials) such common +utilities as: + 1. differentiation and anti-differentiation, 2. substitution, invocation and functional representation. \ No newline at end of file diff --git a/docs/templates/ARTIFACT-TEMPLATE.md b/docs/templates/ARTIFACT-TEMPLATE.md index 121c673fb..f6f37dcef 100644 --- a/docs/templates/ARTIFACT-TEMPLATE.md +++ b/docs/templates/ARTIFACT-TEMPLATE.md @@ -3,6 +3,7 @@ The Maven coordinates of this project are `${group}:${name}:${version}`. **Gradle:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/docs/templates/README-TEMPLATE.md b/docs/templates/README-TEMPLATE.md index 850f63413..0844500ea 100644 --- a/docs/templates/README-TEMPLATE.md +++ b/docs/templates/README-TEMPLATE.md @@ -25,7 +25,8 @@ experience could be achieved with [kmath-for-real](/kmath-for-real) extension mo # Goal -* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS, Native and Wasm). +* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS, Native and + Wasm). * Provide basic multiplatform implementations for those abstractions (without significant performance optimization). * Provide bindings and wrappers with those abstractions for popular optimized platform libraries. @@ -67,16 +68,19 @@ feedback are also welcome. ## Performance -Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to achieve both +Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to +achieve both performance and flexibility. We expect to focus on creating a convenient universal API first and then work on increasing performance for specific cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized -native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy. +native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be +better than SciPy. ## Requirements -KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or Oracle GraalVM for execution to get better performance. +KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or +Oracle GraalVM for execution to get better performance. ### Repositories @@ -99,4 +103,7 @@ dependencies { ## Contributing The project requires a lot of additional work. The most important thing we need is feedback about what features are -required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues marked with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label. \ No newline at end of file +required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues +marked +with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) +label. \ No newline at end of file diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index b155f2653..b74d6edca 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -67,7 +67,7 @@ kotlin { } tasks.withType<KotlinJvmCompile> { - compilerOptions{ + compilerOptions { freeCompilerArgs.addAll("-Xjvm-default=all", "-Xopt-in=kotlin.RequiresOptIn", "-Xlambdas=indy") } } diff --git a/examples/src/main/kotlin/space/kscience/kmath/expressions/autodiff.kt b/examples/src/main/kotlin/space/kscience/kmath/expressions/autodiff.kt index 7bcb80da0..b9d7d4aa8 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/expressions/autodiff.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/expressions/autodiff.kt @@ -6,6 +6,7 @@ package space.kscience.kmath.expressions import space.kscience.kmath.UnstableKMathAPI + // Only kmath-core is needed. // Let's declare some variables @@ -51,7 +52,7 @@ fun main() { // >>> 0.0 // But in case you forgot to specify bound symbol's value, exception is thrown: - println( runCatching { someExpression(z to 4.0) } ) + println(runCatching { someExpression(z to 4.0) }) // >>> Failure(java.lang.IllegalStateException: Symbol 'x' is not supported in ...) // The reason is that the expression is evaluated lazily, diff --git a/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt b/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt index 14cd5bc76..5c00e2d81 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/fit/chiSquared.kt @@ -77,7 +77,7 @@ suspend fun main() { val result = chi2.optimizeWith( CMOptimizer, mapOf(a to 1.5, b to 0.9, c to 1.0), - ){ + ) { FunctionOptimizationTarget(OptimizationDirection.MINIMIZE) } diff --git a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt index 940a20324..7af026759 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/operations/mixedNDOperations.kt @@ -8,7 +8,6 @@ package space.kscience.kmath.operations import space.kscience.kmath.commons.linear.CMLinearSpace import space.kscience.kmath.linear.matrix import space.kscience.kmath.nd.Float64BufferND -import space.kscience.kmath.nd.ShapeND import space.kscience.kmath.nd.Structure2D import space.kscience.kmath.nd.mutableStructureND import space.kscience.kmath.nd.ndAlgebra diff --git a/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt b/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt index 4742b1f62..e6d3ef56b 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/series/analyzeDif.kt @@ -44,10 +44,10 @@ fun main() = with(Double.seriesAlgebra()) { Plotly.page { h1 { +"This is my plot" } - p{ + p { +"Kolmogorov-smirnov test for s1 and s2: ${kmTest.value}" } - plot{ + plot { plotSeries("s1", s1) plotSeries("s2", s2) plotSeries("s3", s3) diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt index 8c34ad4f1..3a59423d4 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/StreamDoubleFieldND.kt @@ -53,7 +53,10 @@ class StreamDoubleFieldND(override val shape: ShapeND) : FieldND<Double, Float64 return BufferND(strides, array.asBuffer()) } - override fun mutableStructureND(shape: ShapeND, initializer: DoubleField.(IntArray) -> Double): MutableBufferND<Double> { + override fun mutableStructureND( + shape: ShapeND, + initializer: DoubleField.(IntArray) -> Double, + ): MutableBufferND<Double> { val array = IntStream.range(0, strides.linearSize).parallel().mapToDouble { offset -> val index = strides.index(offset) DoubleField.initializer(index) diff --git a/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt b/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt index d4dfa60cb..82d2f8eb3 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/structures/buffers.kt @@ -12,7 +12,7 @@ import space.kscience.kmath.operations.withSize inline fun <reified R : Any> MutableBuffer.Companion.same( n: Int, - value: R + value: R, ): MutableBuffer<R> = MutableBuffer(n) { value } diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt index a6903baca..490e5d6a4 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticDifficultTest.kt @@ -31,7 +31,7 @@ fun main() { val exampleNumber = 1 - var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber) + var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { @@ -51,7 +51,8 @@ fun main() { val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-2, 11.0, 9.0, 1.0) // val opts = doubleArrayOf(3.0, 10000.0, 1e-6, 1e-6, 1e-6, 1e-6, 1e-3, 11.0, 9.0, 1.0) - val inputData = LMInput(::funcDifficultForLm, + val inputData = LMInput( + ::funcDifficultForLm, p_init.as2D(), t, y_dat, @@ -64,7 +65,8 @@ fun main() { doubleArrayOf(opts[6], opts[7], opts[8]), opts[9].toInt(), 10, - 1) + 1 + ) val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) @@ -76,7 +78,7 @@ fun main() { println() println("Y true and y received:") - var y_hat_after = funcDifficultForLm(t_example, result.resultParameters, exampleNumber) + var y_hat_after = funcDifficultForLm(t_example, result.resultParameters, exampleNumber) for (i in 0 until y_hat.shape.component1()) { val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0 val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt index ab50d17e1..1b5abbd36 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticEasyTest.kt @@ -18,7 +18,8 @@ import kotlin.math.roundToInt fun main() { val startedData = getStartDataForFuncEasy() - val inputData = LMInput(::funcEasyForLm, + val inputData = LMInput( + ::funcEasyForLm, DoubleTensorAlgebra.ones(ShapeND(intArrayOf(4, 1))).as2D(), startedData.t, startedData.y_dat, @@ -31,7 +32,8 @@ fun main() { doubleArrayOf(startedData.opts[6], startedData.opts[7], startedData.opts[8]), startedData.opts[9].toInt(), 10, - startedData.example_number) + startedData.example_number + ) val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) @@ -43,7 +45,7 @@ fun main() { println() println("Y true and y received:") - var y_hat_after = funcDifficultForLm(startedData.t, result.resultParameters, startedData.example_number) + var y_hat_after = funcDifficultForLm(startedData.t, result.resultParameters, startedData.example_number) for (i in 0 until startedData.y_dat.shape.component1()) { val x = (startedData.y_dat[i, 0] * 10000).roundToInt() / 10000.0 val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt index aa8aa73f8..ac26debb9 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StaticLm/staticMiddleTest.kt @@ -15,6 +15,7 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.LMInput import space.kscience.kmath.tensors.core.levenbergMarquardt import kotlin.math.roundToInt + fun main() { val NData = 100 var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() @@ -30,7 +31,7 @@ fun main() { val exampleNumber = 1 - var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber) + var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { @@ -49,7 +50,8 @@ fun main() { p_min = p_min.div(1.0 / 50.0) val opts = doubleArrayOf(3.0, 7000.0, 1e-5, 1e-5, 1e-5, 1e-5, 1e-5, 11.0, 9.0, 1.0) - val inputData = LMInput(::funcMiddleForLm, + val inputData = LMInput( + ::funcMiddleForLm, p_init.as2D(), t, y_dat, @@ -62,7 +64,8 @@ fun main() { doubleArrayOf(opts[6], opts[7], opts[8]), opts[9].toInt(), 10, - 1) + 1 + ) val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) @@ -74,7 +77,7 @@ fun main() { println() - var y_hat_after = funcMiddleForLm(t_example, result.resultParameters, exampleNumber) + var y_hat_after = funcMiddleForLm(t_example, result.resultParameters, exampleNumber) for (i in 0 until y_hat.shape.component1()) { val x = (y_hat[i, 0] * 10000).roundToInt() / 10000.0 val y = (y_hat_after[i, 0] * 10000).roundToInt() / 10000.0 diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt index f77adab7e..dca7325ce 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamLm.kt @@ -6,18 +6,23 @@ package space.kscience.kmath.tensors.LevenbergMarquardt.StreamingLm import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.* -import space.kscience.kmath.nd.* +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import space.kscience.kmath.nd.MutableStructure2D +import space.kscience.kmath.nd.ShapeND +import space.kscience.kmath.nd.as2D +import space.kscience.kmath.nd.component1 import space.kscience.kmath.tensors.LevenbergMarquardt.StartDataLm import space.kscience.kmath.tensors.core.BroadcastDoubleTensorAlgebra.zeros import space.kscience.kmath.tensors.core.DoubleTensorAlgebra import space.kscience.kmath.tensors.core.LMInput import space.kscience.kmath.tensors.core.levenbergMarquardt import kotlin.random.Random -import kotlin.reflect.KFunction3 -fun streamLm(lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> (MutableStructure2D<Double>), - startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int): Flow<MutableStructure2D<Double>> = flow{ +fun streamLm( + lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, Int) -> (MutableStructure2D<Double>), + startData: StartDataLm, launchFrequencyInMs: Long, numberOfLaunches: Int, +): Flow<MutableStructure2D<Double>> = flow { var example_number = startData.example_number var p_init = startData.p_init @@ -32,7 +37,8 @@ fun streamLm(lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, I var steps = numberOfLaunches val isEndless = (steps <= 0) - val inputData = LMInput(lm_func, + val inputData = LMInput( + lm_func, p_init, t, y_dat, @@ -45,7 +51,8 @@ fun streamLm(lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, I doubleArrayOf(opts[6], opts[7], opts[8]), opts[9].toInt(), 10, - example_number) + example_number + ) while (isEndless || steps > 0) { val result = DoubleTensorAlgebra.levenbergMarquardt(inputData) @@ -57,7 +64,7 @@ fun streamLm(lm_func: (MutableStructure2D<Double>, MutableStructure2D<Double>, I } } -fun generateNewYDat(y_dat: MutableStructure2D<Double>, delta: Double): MutableStructure2D<Double>{ +fun generateNewYDat(y_dat: MutableStructure2D<Double>, delta: Double): MutableStructure2D<Double> { val n = y_dat.shape.component1() val y_dat_new = zeros(ShapeND(intArrayOf(n, 1))).as2D() for (i in 0 until n) { diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt index 2c53146b7..cd9115e7b 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/StreamingLm/streamingLmTest.kt @@ -5,14 +5,15 @@ package space.kscience.kmath.tensors.LevenbergMarquardt.StreamingLm -import space.kscience.kmath.nd.* -import space.kscience.kmath.tensors.LevenbergMarquardt.* +import space.kscience.kmath.nd.component1 +import space.kscience.kmath.tensors.LevenbergMarquardt.funcDifficultForLm +import space.kscience.kmath.tensors.LevenbergMarquardt.getStartDataForFuncDifficult import kotlin.math.roundToInt -suspend fun main(){ +suspend fun main() { val startData = getStartDataForFuncDifficult() // Создание потока: - val lmFlow = streamLm(::funcDifficultForLm, startData, 0, 100) + val lmFlow = streamLm(::funcDifficultForLm, startData, 0, 100) var initialTime = System.currentTimeMillis() var lastTime: Long val launches = mutableListOf<Long>() diff --git a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt index 4aefa1e0a..9a4b613b2 100644 --- a/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt +++ b/examples/src/main/kotlin/space/kscience/kmath/tensors/LevenbergMarquardt/functionsToOptimize.kt @@ -18,7 +18,7 @@ import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.pow import space.kscience.kmath.tensors.core.DoubleTensorAlgebra.Companion.times import space.kscience.kmath.tensors.core.asDoubleTensor -public data class StartDataLm ( +public data class StartDataLm( var lm_matx_y_dat: MutableStructure2D<Double>, var example_number: Int, var p_init: MutableStructure2D<Double>, @@ -29,10 +29,14 @@ public data class StartDataLm ( var p_min: MutableStructure2D<Double>, var p_max: MutableStructure2D<Double>, var consts: MutableStructure2D<Double>, - var opts: DoubleArray + var opts: DoubleArray, ) -fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { +fun funcEasyForLm( + t: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, + exampleNumber: Int, +): MutableStructure2D<Double> { val m = t.shape.component1() var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) @@ -40,15 +44,13 @@ fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))).times(p[0, 0]) + t.times(p[2, 0]).times( DoubleTensorAlgebra.exp((t.times(-1.0 / p[3, 0]))) ) - } - else if (exampleNumber == 2) { + } else if (exampleNumber == 2) { val mt = t.max() y_hat = (t.times(1.0 / mt)).times(p[0, 0]) + (t.times(1.0 / mt)).pow(2).times(p[1, 0]) + (t.times(1.0 / mt)).pow(3).times(p[2, 0]) + (t.times(1.0 / mt)).pow(4).times(p[3, 0]) - } - else if (exampleNumber == 3) { + } else if (exampleNumber == 3) { y_hat = DoubleTensorAlgebra.exp((t.times(-1.0 / p[1, 0]))) .times(p[0, 0]) + DoubleTensorAlgebra.sin((t.times(1.0 / p[3, 0]))).times(p[2, 0]) } @@ -56,32 +58,40 @@ fun funcEasyForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, return y_hat.as2D() } -fun funcMiddleForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { +fun funcMiddleForLm( + t: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, + exampleNumber: Int, +): MutableStructure2D<Double> { val m = t.shape.component1() - var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) val mt = t.max() - for(i in 0 until p.shape.component1()){ + for (i in 0 until p.shape.component1()) { y_hat += (t.times(1.0 / mt)).times(p[i, 0]) } - for(i in 0 until 5){ + for (i in 0 until 5) { y_hat = funcEasyForLm(y_hat.as2D(), p, exampleNumber).asDoubleTensor() } return y_hat.as2D() } -fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Double>, exampleNumber: Int): MutableStructure2D<Double> { +fun funcDifficultForLm( + t: MutableStructure2D<Double>, + p: MutableStructure2D<Double>, + exampleNumber: Int, +): MutableStructure2D<Double> { val m = t.shape.component1() - var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf (m, 1))) + var y_hat = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(m, 1))) val mt = t.max() - for(i in 0 until p.shape.component1()){ - y_hat = y_hat.plus( (t.times(1.0 / mt)).times(p[i, 0]) ) + for (i in 0 until p.shape.component1()) { + y_hat = y_hat.plus((t.times(1.0 / mt)).times(p[i, 0])) } - for(i in 0 until 4){ + for (i in 0 until 4) { y_hat = funcEasyForLm((y_hat.as2D() + t).as2D(), p, exampleNumber).asDoubleTensor() } @@ -89,7 +99,7 @@ fun funcDifficultForLm(t: MutableStructure2D<Double>, p: MutableStructure2D<Doub } -fun getStartDataForFuncDifficult(): StartDataLm { +fun getStartDataForFuncDifficult(): StartDataLm { val NData = 200 var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() for (i in 0 until NData) { @@ -104,7 +114,7 @@ fun getStartDataForFuncDifficult(): StartDataLm { val exampleNumber = 1 - var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber) + var y_hat = funcDifficultForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { @@ -129,7 +139,7 @@ fun getStartDataForFuncDifficult(): StartDataLm { return StartDataLm(y_dat, 1, p_init, t, y_dat, weight, dp, p_min.as2D(), p_max.as2D(), consts, opts) } -fun getStartDataForFuncMiddle(): StartDataLm { +fun getStartDataForFuncMiddle(): StartDataLm { val NData = 100 var t_example = DoubleTensorAlgebra.ones(ShapeND(intArrayOf(NData, 1))).as2D() for (i in 0 until NData) { @@ -144,7 +154,7 @@ fun getStartDataForFuncMiddle(): StartDataLm { val exampleNumber = 1 - var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber) + var y_hat = funcMiddleForLm(t_example, p_example, exampleNumber) var p_init = DoubleTensorAlgebra.zeros(ShapeND(intArrayOf(Nparams, 1))).as2D() for (i in 0 until Nparams) { diff --git a/gradle.properties b/gradle.properties index 0d373a8e5..319ce3df0 100644 --- a/gradle.properties +++ b/gradle.properties @@ -5,13 +5,10 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true kotlin.native.ignoreDisabledTargets=true - org.gradle.configureondemand=true org.gradle.jvmargs=-Xmx4096m - org.gradle.parallel=true org.gradle.workers.max=4 - toolsVersion=0.15.2-kotlin-1.9.22 #kotlin.experimental.tryK2=true #kscience.wasm.disabled=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 17655d0ef..48c0a02ca 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/kmath-ast/README.md b/kmath-ast/README.md index dd9978bee..289114dd0 100644 --- a/kmath-ast/README.md +++ b/kmath-ast/README.md @@ -2,17 +2,17 @@ Extensions to MST API: transformations, dynamic compilation and visualization. - - [expression-language](src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser - - [mst-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler - - [mst-js-codegen](src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler - - [rendering](src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering - +- [expression-language](src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser +- [mst-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler +- [mst-js-codegen](src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler +- [rendering](src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-ast:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") @@ -26,21 +26,27 @@ dependencies { ## Parsing expressions -In this module there is a parser from human-readable strings like `"x^3-x+3"` (in the more specific [grammar](reference/ArithmeticsEvaluator.g4)) to MST instances. +In this module there is a parser from human-readable strings like `"x^3-x+3"` (in the more +specific [grammar](reference/ArithmeticsEvaluator.g4)) to MST instances. Supported literals: + 1. Constants and variables (consist of latin letters, digits and underscores, can't start with digit): `x`, `_Abc2`. 2. Numbers: `123`, `1.02`, `1e10`, `1e-10`, `1.0e+3`—all parsed either as `kotlin.Long` or `kotlin.Double`. Supported binary operators (from the highest precedence to the lowest one): + 1. `^` 2. `*`, `/` 3. `+`, `-` Supported unary operator: + 1. `-`, e. g. `-x` -Arbitrary unary and binary functions are also supported: names consist of latin letters, digits and underscores, can't start with digit. Examples: +Arbitrary unary and binary functions are also supported: names consist of latin letters, digits and underscores, can't +start with digit. Examples: + 1. `sin(x)` 2. `add(x, y)` @@ -105,12 +111,15 @@ public final class CompiledExpression_-386104628_0 implements DoubleExpression { } ``` -Setting JVM system property `space.kscience.kmath.ast.dump.generated.classes` to `1` makes the translator dump class files to program's working directory, so they can be reviewed manually. +Setting JVM system property `space.kscience.kmath.ast.dump.generated.classes` to `1` makes the translator dump class +files to program's working directory, so they can be reviewed manually. #### Limitations -- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class loading overhead. -- This API is not supported by non-dynamic JVM implementations like TeaVM or GraalVM Native Image because they may not support class loaders. +- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class + loading overhead. +- This API is not supported by non-dynamic JVM implementations like TeaVM or GraalVM Native Image because they may not + support class loaders. ### On JS @@ -188,7 +197,8 @@ public fun main() { Result LaTeX: -$$\operatorname{exp}\\,\left(\sqrt{x}\right)-\frac{\frac{\operatorname{arcsin}\\,\left(2\\,x\right)}{2\times10^{10}+x^{3}}}{12}+x^{2/3}$$ +$$\operatorname{exp}\\,\left(\sqrt{x}\right)-\frac{\frac{\operatorname{arcsin}\\,\left(2\\,x\right) +}{2\times10^{10}+x^{3}}}{12}+x^{2/3}$$ Result MathML (can be used with MathJax or other renderers): diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts index fe10716af..a770912f3 100644 --- a/kmath-ast/build.gradle.kts +++ b/kmath-ast/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() @@ -22,7 +22,7 @@ kscience{ implementation(npm("js-base64", "3.6.1")) } - dependencies(jvmMain){ + dependencies(jvmMain) { implementation("org.ow2.asm:asm-commons:9.2") } @@ -31,7 +31,7 @@ kscience{ kotlin { js { nodejs { - testTask{ + testTask { useMocha().timeout = "0" } } diff --git a/kmath-ast/docs/README-TEMPLATE.md b/kmath-ast/docs/README-TEMPLATE.md index 96bbfbf5a..70d6eb9a4 100644 --- a/kmath-ast/docs/README-TEMPLATE.md +++ b/kmath-ast/docs/README-TEMPLATE.md @@ -8,21 +8,27 @@ ${artifact} ## Parsing expressions -In this module there is a parser from human-readable strings like `"x^3-x+3"` (in the more specific [grammar](reference/ArithmeticsEvaluator.g4)) to MST instances. +In this module there is a parser from human-readable strings like `"x^3-x+3"` (in the more +specific [grammar](reference/ArithmeticsEvaluator.g4)) to MST instances. Supported literals: + 1. Constants and variables (consist of latin letters, digits and underscores, can't start with digit): `x`, `_Abc2`. 2. Numbers: `123`, `1.02`, `1e10`, `1e-10`, `1.0e+3`—all parsed either as `kotlin.Long` or `kotlin.Double`. Supported binary operators (from the highest precedence to the lowest one): + 1. `^` 2. `*`, `/` 3. `+`, `-` Supported unary operator: + 1. `-`, e. g. `-x` -Arbitrary unary and binary functions are also supported: names consist of latin letters, digits and underscores, can't start with digit. Examples: +Arbitrary unary and binary functions are also supported: names consist of latin letters, digits and underscores, can't +start with digit. Examples: + 1. `sin(x)` 2. `add(x, y)` @@ -87,12 +93,15 @@ public final class CompiledExpression_-386104628_0 implements DoubleExpression { } ``` -Setting JVM system property `space.kscience.kmath.ast.dump.generated.classes` to `1` makes the translator dump class files to program's working directory, so they can be reviewed manually. +Setting JVM system property `space.kscience.kmath.ast.dump.generated.classes` to `1` makes the translator dump class +files to program's working directory, so they can be reviewed manually. #### Limitations -- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class loading overhead. -- This API is not supported by non-dynamic JVM implementations like TeaVM or GraalVM Native Image because they may not support class loaders. +- The same classes may be generated and loaded twice, so it is recommended to cache compiled expressions to avoid class + loading overhead. +- This API is not supported by non-dynamic JVM implementations like TeaVM or GraalVM Native Image because they may not + support class loaders. ### On JS @@ -170,7 +179,8 @@ public fun main() { Result LaTeX: -$$\operatorname{exp}\\,\left(\sqrt{x}\right)-\frac{\frac{\operatorname{arcsin}\\,\left(2\\,x\right)}{2\times10^{10}+x^{3}}}{12}+x^{2/3}$$ +$$\operatorname{exp}\\,\left(\sqrt{x}\right)-\frac{\frac{\operatorname{arcsin}\\,\left(2\\,x\right) +}{2\times10^{10}+x^{3}}}{12}+x^{2/3}$$ Result MathML (can be used with MathJax or other renderers): diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt index f50a70821..3fdbb52b0 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/TypedMst.kt @@ -68,7 +68,7 @@ public sealed interface TypedMst<T> : WithType<T> { ) : TypedMst<T> { init { - require(left.type==right.type){"Left and right expressions must be of the same type"} + require(left.type == right.type) { "Left and right expressions must be of the same type" } } override val type: SafeType<T> get() = left.type diff --git a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt index 9fcabefbc..d9eb3ba29 100644 --- a/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt +++ b/kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt @@ -426,11 +426,13 @@ public class InverseTrigonometricOperations(operations: Collection<String>?) : U * The default instance configured with [TrigonometricOperations.ACOS_OPERATION], * [TrigonometricOperations.ASIN_OPERATION], [TrigonometricOperations.ATAN_OPERATION]. */ - public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations(setOf( - TrigonometricOperations.ACOS_OPERATION, - TrigonometricOperations.ASIN_OPERATION, - TrigonometricOperations.ATAN_OPERATION, - )) + public val Default: InverseTrigonometricOperations = InverseTrigonometricOperations( + setOf( + TrigonometricOperations.ACOS_OPERATION, + TrigonometricOperations.ASIN_OPERATION, + TrigonometricOperations.ATAN_OPERATION, + ) + ) } } @@ -452,10 +454,12 @@ public class InverseHyperbolicOperations(operations: Collection<String>?) : Unar * The default instance configured with [ExponentialOperations.ACOSH_OPERATION], * [ExponentialOperations.ASINH_OPERATION], and [ExponentialOperations.ATANH_OPERATION]. */ - public val Default: InverseHyperbolicOperations = InverseHyperbolicOperations(setOf( - ExponentialOperations.ACOSH_OPERATION, - ExponentialOperations.ASINH_OPERATION, - ExponentialOperations.ATANH_OPERATION, - )) + public val Default: InverseHyperbolicOperations = InverseHyperbolicOperations( + setOf( + ExponentialOperations.ACOSH_OPERATION, + ExponentialOperations.ASINH_OPERATION, + ExponentialOperations.ATANH_OPERATION, + ) + ) } } diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt index 158abbdeb..6ccf73232 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestFeatures.kt @@ -17,7 +17,8 @@ internal class TestFeatures { fun printNumeric() { val num = object : Number() { override fun toByte(): Byte = throw UnsupportedOperationException() -// override fun toChar(): Char = throw UnsupportedOperationException() + + // override fun toChar(): Char = throw UnsupportedOperationException() override fun toDouble(): Double = throw UnsupportedOperationException() override fun toFloat(): Float = throw UnsupportedOperationException() override fun toInt(): Int = throw UnsupportedOperationException() diff --git a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt index abf761d23..2a5857069 100644 --- a/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt +++ b/kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/rendering/TestMathML.kt @@ -81,8 +81,10 @@ internal class TestMathML { @Test fun radicalWithIndex() = - testMathML(RadicalWithIndexSyntax("", SymbolSyntax("x"), SymbolSyntax("y")), - "<mroot><mrow><mi>y</mi></mrow><mrow><mi>x</mi></mrow></mroot>") + testMathML( + RadicalWithIndexSyntax("", SymbolSyntax("x"), SymbolSyntax("y")), + "<mroot><mrow><mi>y</mi></mrow><mrow><mi>x</mi></mrow></mroot>" + ) @Test fun multiplication() { diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt index d40f3e0f5..6380d9b6c 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/binaryen/index.binaryen.kt @@ -52,7 +52,7 @@ internal external fun createType(types: Array<Type>): Type internal external fun expandType(type: Type): Array<Type> -internal external enum class ExpressionIds { +internal external enum class ExpressionIds { Invalid, Block, If, @@ -1656,27 +1656,27 @@ internal open external class Module { open fun `if`( condition: ExpressionRef, ifTrue: ExpressionRef, - ifFalse: ExpressionRef = definedExternally + ifFalse: ExpressionRef = definedExternally, ): ExpressionRef open fun loop(label: String, body: ExpressionRef): ExpressionRef open fun br( label: String, condition: ExpressionRef = definedExternally, - value: ExpressionRef = definedExternally + value: ExpressionRef = definedExternally, ): ExpressionRef open fun br_if( label: String, condition: ExpressionRef = definedExternally, - value: ExpressionRef = definedExternally + value: ExpressionRef = definedExternally, ): ExpressionRef open fun switch( labels: Array<String>, defaultLabel: String, condition: ExpressionRef, - value: ExpressionRef = definedExternally + value: ExpressionRef = definedExternally, ): ExpressionRef open fun call(name: String, operands: Array<ExpressionRef>, returnType: Type): ExpressionRef @@ -1685,14 +1685,14 @@ internal open external class Module { target: ExpressionRef, operands: Array<ExpressionRef>, params: Type, - results: Type + results: Type, ): ExpressionRef open fun return_call_indirect( target: ExpressionRef, operands: Array<ExpressionRef>, params: Type, - results: Type + results: Type, ): ExpressionRef open var local: `T$2` @@ -1730,7 +1730,7 @@ internal open external class Module { condition: ExpressionRef, ifTrue: ExpressionRef, ifFalse: ExpressionRef, - type: Type = definedExternally + type: Type = definedExternally, ): ExpressionRef open fun drop(value: ExpressionRef): ExpressionRef @@ -1754,7 +1754,7 @@ internal open external class Module { externalModuleName: String, externalBaseName: String, params: Type, - results: Type + results: Type, ) open fun addTableImport(internalName: String, externalModuleName: String, externalBaseName: String) @@ -1763,7 +1763,7 @@ internal open external class Module { internalName: String, externalModuleName: String, externalBaseName: String, - globalType: Type + globalType: Type, ) open fun addEventImport( @@ -1772,7 +1772,7 @@ internal open external class Module { externalBaseName: String, attribute: Number, params: Type, - results: Type + results: Type, ) open fun addFunctionExport(internalName: String, externalName: String): ExportRef @@ -1786,7 +1786,7 @@ internal open external class Module { initial: Number, maximum: Number, funcNames: Array<Number>, - offset: ExpressionRef = definedExternally + offset: ExpressionRef = definedExternally, ) open fun getFunctionTable(): `T$26` @@ -1796,7 +1796,7 @@ internal open external class Module { exportName: String? = definedExternally, segments: Array<MemorySegment>? = definedExternally, flags: Array<Number>? = definedExternally, - shared: Boolean = definedExternally + shared: Boolean = definedExternally, ) open fun getNumMemorySegments(): Number @@ -1827,7 +1827,7 @@ internal open external class Module { expr: ExpressionRef, fileIndex: Number, lineNumber: Number, - columnNumber: Number + columnNumber: Number, ) open fun copyExpression(expr: ExpressionRef): ExpressionRef @@ -2231,7 +2231,7 @@ internal open external class Relooper(module: Module) { from: RelooperBlockRef, to: RelooperBlockRef, indexes: Array<Number>, - code: ExpressionRef + code: ExpressionRef, ) open fun renderAndDispose(entry: RelooperBlockRef, labelHelper: Number): ExpressionRef diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt index 7549f6514..db0723163 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.extensions.kt @@ -30,12 +30,13 @@ internal fun Identifier(name: String) = object : Identifier { override var name = name } -internal fun FunctionExpression(id: Identifier?, params: Array<dynamic>, body: BlockStatement) = object : FunctionExpression { - override var params = params - override var type = "FunctionExpression" - override var id: Identifier? = id - override var body = body -} +internal fun FunctionExpression(id: Identifier?, params: Array<dynamic>, body: BlockStatement) = + object : FunctionExpression { + override var params = params + override var type = "FunctionExpression" + override var id: Identifier? = id + override var body = body + } internal fun BlockStatement(vararg body: dynamic) = object : BlockStatement { override var type = "BlockStatement" diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt index 07fd53fec..ee17edbc8 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/tsstdlib/lib.es5.kt @@ -91,6 +91,6 @@ internal typealias Extract<T, U> = Any internal external interface PromiseLike<T> { fun then( onfulfilled: ((value: T) -> Any?)? = definedExternally, - onrejected: ((reason: Any) -> Any?)? = definedExternally + onrejected: ((reason: Any) -> Any?)? = definedExternally, ): PromiseLike<dynamic /* TResult1 | TResult2 */> } diff --git a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt index 15332a413..c3e79c864 100644 --- a/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt +++ b/kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/webassembly/lib.dom.WebAssembly.module_dukat.kt @@ -15,11 +15,11 @@ package space.kscience.kmath.internal.webassembly -import space.kscience.kmath.internal.tsstdlib.PromiseLike import org.khronos.webgl.ArrayBuffer import org.khronos.webgl.ArrayBufferView import org.khronos.webgl.Uint8Array import org.w3c.fetch.Response +import space.kscience.kmath.internal.tsstdlib.PromiseLike import kotlin.js.Promise @Suppress("NESTED_CLASS_IN_EXTERNAL_INTERFACE") diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt index cd115cd4f..ac35562d2 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt @@ -91,7 +91,7 @@ public inline fun <reified T : Any> MST.compile(algebra: Algebra<T>, vararg argu * @author Iaroslav Postovalov */ @UnstableKMathAPI -public fun MST.compileToExpression(algebra: Int32Ring): IntExpression { +public fun MST.compileToExpression(algebra: Int32Ring): IntExpression { val typed = evaluateConstants(algebra) return if (typed is TypedMst.Constant) object : IntExpression { diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt index 9c27a25b5..3f003bb09 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/PrimitiveAsmBuilder.kt @@ -332,7 +332,7 @@ internal sealed class PrimitiveAsmBuilder<T : Number, out E : Expression<T>>( private fun visitVariables( node: TypedMst<T>, arrayMode: Boolean, - alreadyLoaded: MutableList<Symbol> = mutableListOf() + alreadyLoaded: MutableList<Symbol> = mutableListOf(), ): Unit = when (node) { is TypedMst.Variable -> if (node.symbol !in alreadyLoaded) { alreadyLoaded += node.symbol diff --git a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt index e3565df23..e0d3a0ef4 100644 --- a/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt +++ b/kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/internal/codegenUtils.kt @@ -8,7 +8,6 @@ package space.kscience.kmath.asm.internal import org.objectweb.asm.* import org.objectweb.asm.commons.InstructionAdapter import space.kscience.kmath.expressions.Expression -import space.kscience.kmath.expressions.MST import kotlin.contracts.InvocationKind import kotlin.contracts.contract diff --git a/kmath-commons/README.md b/kmath-commons/README.md index 2b5f3146d..7ca7dacf8 100644 --- a/kmath-commons/README.md +++ b/kmath-commons/README.md @@ -9,6 +9,7 @@ Commons math binding for kmath The Maven coordinates of this project are `space.kscience:kmath-commons:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt index c016c0f62..b4680bace 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/integration/CMGaussRuleIntegrator.kt @@ -35,11 +35,13 @@ public class CMGaussRuleIntegrator( range.start, range.endInclusive ) + GaussRule.LEGENDREHP -> factory.legendreHighPrecision( numpoints, range.start, range.endInclusive ) + GaussRule.UNIFORM -> GaussIntegrator( getUniformRule( range.start, @@ -80,7 +82,7 @@ public class CMGaussRuleIntegrator( type: GaussRule = GaussRule.LEGENDRE, function: (Double) -> Double, ): Double = CMGaussRuleIntegrator(numPoints, type).integrate( - UnivariateIntegrand({IntegrationRange(range)},function) + UnivariateIntegrand({ IntegrationRange(range) }, function) ).value } } \ No newline at end of file diff --git a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt index 6b31fcd88..0c15d1016 100644 --- a/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt +++ b/kmath-commons/src/jvmMain/kotlin/space/kscience/kmath/commons/linear/CMSolver.kt @@ -48,9 +48,11 @@ public fun CMLinearSpace.inverse( public fun CMLinearSpace.solver(decomposition: CMDecomposition): LinearSolver<Double> = object : LinearSolver<Double> { - override fun solve(a: Matrix<Double>, b: Matrix<Double>): Matrix<Double> = solver(a, decomposition).solve(b.toCM().origin).wrap() + override fun solve(a: Matrix<Double>, b: Matrix<Double>): Matrix<Double> = + solver(a, decomposition).solve(b.toCM().origin).wrap() - override fun solve(a: Matrix<Double>, b: Point<Double>): Point<Double> = solver(a, decomposition).solve(b.toCM().origin).toPoint() + override fun solve(a: Matrix<Double>, b: Point<Double>): Point<Double> = + solver(a, decomposition).solve(b.toCM().origin).toPoint() override fun inverse(matrix: Matrix<Double>): Matrix<Double> = solver(matrix, decomposition).inverse.wrap() } diff --git a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt index 177a01b43..8b314cf1a 100644 --- a/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt +++ b/kmath-commons/src/jvmTest/kotlin/space/kscience/kmath/commons/optimization/OptimizeTest.kt @@ -73,7 +73,7 @@ internal class OptimizeTest { val result: FunctionOptimization<Double> = chi2.optimizeWith( CMOptimizer, mapOf(a to 1.5, b to 0.9, c to 1.0), - ){ + ) { FunctionOptimizationTarget(OptimizationDirection.MINIMIZE) } println(result) diff --git a/kmath-complex/README.md b/kmath-complex/README.md index eec989eb3..b5e4b9d58 100644 --- a/kmath-complex/README.md +++ b/kmath-complex/README.md @@ -2,15 +2,15 @@ Complex and hypercomplex number systems in KMath. - - [complex](src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations - - [quaternion](src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition - +- [complex](src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations +- [quaternion](src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-complex:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt index 87e750387..89c57527c 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt @@ -148,8 +148,8 @@ public object ComplexField : exp(pow * ln(arg)) } - public fun power(arg: Complex, pow: Complex): Complex = if(arg == zero || arg == (-0.0).toComplex()){ - if(pow == zero){ + public fun power(arg: Complex, pow: Complex): Complex = if (arg == zero || arg == (-0.0).toComplex()) { + if (pow == zero) { one } else { zero diff --git a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt index 8fbf41732..3fce2c882 100644 --- a/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt +++ b/kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/ComplexFieldND.kt @@ -19,7 +19,8 @@ import kotlin.contracts.contract */ @OptIn(UnstableKMathAPI::class) public sealed class ComplexFieldOpsND : BufferedFieldOpsND<Complex, ComplexField>(ComplexField.bufferAlgebra), - ScaleOperations<StructureND<Complex>>, ExtendedFieldOps<StructureND<Complex>>, PowerOperations<StructureND<Complex>> { + ScaleOperations<StructureND<Complex>>, ExtendedFieldOps<StructureND<Complex>>, + PowerOperations<StructureND<Complex>> { @OptIn(PerformancePitfall::class) override fun StructureND<Complex>.toBufferND(): BufferND<Complex> = when (this) { @@ -53,7 +54,7 @@ public sealed class ComplexFieldOpsND : BufferedFieldOpsND<Complex, ComplexField override fun atanh(arg: StructureND<Complex>): BufferND<Complex> = mapInline(arg.toBufferND()) { atanh(it) } override fun power(arg: StructureND<Complex>, pow: Number): StructureND<Complex> = - mapInline(arg.toBufferND()) { power(it,pow) } + mapInline(arg.toBufferND()) { power(it, pow) } public companion object : ComplexFieldOpsND() } diff --git a/kmath-core/README.md b/kmath-core/README.md index f1f42210b..dd3935764 100644 --- a/kmath-core/README.md +++ b/kmath-core/README.md @@ -2,23 +2,28 @@ The core interfaces of KMath. - - [algebras](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields. - - [nd](src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them. - - [linear](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition. - - [buffers](src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure - - [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of -objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high -performance calculations to code generation. - - [domains](src/commonMain/kotlin/space/kscience/kmath/domains) : Domains - - [autodiff](src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation - - [linear.parallel](#) : Parallel implementation for `LinearAlgebra` - +- [algebras](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces + and fields. +- [nd](src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and + operations on them. +- [linear](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, + products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU + decomposition. +- [buffers](src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure +- [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression + once, users will be able to apply different types of + objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high + performance calculations to code generation. +- [domains](src/commonMain/kotlin/space/kscience/kmath/domains) : Domains +- [autodiff](src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation +- [linear.parallel](#) : Parallel implementation for `LinearAlgebra` ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-core:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts index 0e061c6dd..699dd82e2 100644 --- a/kmath-core/build.gradle.kts +++ b/kmath-core/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() @@ -73,8 +73,8 @@ readme { ) { "Automatic differentiation" } feature( - id="Parallel linear algebra" - ){ + id = "Parallel linear algebra" + ) { """ Parallel implementation for `LinearAlgebra` """.trimIndent() diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYErrorColumnarData.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYErrorColumnarData.kt index 312894612..258ddc198 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYErrorColumnarData.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYErrorColumnarData.kt @@ -27,7 +27,7 @@ public interface XYErrorColumnarData<T, out X : T, out Y : T> : XYColumnarData<T public companion object { public fun <T, X : T, Y : T> of( - x: Buffer<X>, y: Buffer<Y>, yErr: Buffer<Y> + x: Buffer<X>, y: Buffer<Y>, yErr: Buffer<Y>, ): XYErrorColumnarData<T, X, Y> { require(x.size == y.size) { "Buffer size mismatch. x buffer size is ${x.size}, y buffer size is ${y.size}" } require(y.size == yErr.size) { "Buffer size mismatch. y buffer size is ${x.size}, yErr buffer size is ${y.size}" } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt index 55c3049b7..2d9dcd13d 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/MST.kt @@ -58,6 +58,7 @@ public fun <T> MST.interpret(algebra: Algebra<T>, arguments: Map<Symbol, T>): T this.operation, algebra.number(this.value.value), ) + else -> algebra.unaryOperationFunction(this.operation)(this.value.interpret(algebra, arguments)) } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt index 58831f38d..03859ba83 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/linear/LupDecomposition.kt @@ -83,7 +83,7 @@ internal fun <T : Comparable<T>> LinearSpace<T, Ring<T>>.abs(value: T): T = public fun <T : Comparable<T>> Field<T>.lup( matrix: Matrix<T>, checkSingular: (T) -> Boolean, -): GenericLupDecomposition<T> { +): GenericLupDecomposition<T> { require(matrix.rowNum == matrix.colNum) { "LU decomposition supports only square matrices" } val m = matrix.colNum val pivot = IntArray(matrix.rowNum) @@ -110,7 +110,7 @@ public fun <T : Comparable<T>> Field<T>.lup( // upper for (row in 0 until col) { var sum = lu[row, col] - for (i in 0 until row){ + for (i in 0 until row) { sum -= lu[row, i] * lu[i, col] } lu[row, col] = sum @@ -122,7 +122,7 @@ public fun <T : Comparable<T>> Field<T>.lup( for (row in col until m) { var sum = lu[row, col] - for (i in 0 until col){ + for (i in 0 until col) { sum -= lu[row, i] * lu[i, col] } lu[row, col] = sum @@ -226,7 +226,7 @@ private fun <T> Field<T>.solve( public fun <T : Comparable<T>> LinearSpace<T, Field<T>>.lupSolver( singularityCheck: (T) -> Boolean, ): LinearSolver<T> = object : LinearSolver<T> { - override fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T> = elementAlgebra{ + override fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T> = elementAlgebra { // Use existing decomposition if it is provided by matrix or linear space itself val decomposition = a.getOrComputeAttribute(LUP) ?: lup(a, singularityCheck) return solve(decomposition, b) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt index 2f91a3326..d76120c59 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/Int16RingND.kt @@ -18,12 +18,11 @@ public sealed class Int16RingOpsND : BufferedRingOpsND<Short, Int16Ring>(Int16Ri @OptIn(UnstableKMathAPI::class) public class Int16RingND( - override val shape: ShapeND + override val shape: ShapeND, ) : Int16RingOpsND(), RingND<Short, Int16Ring>, NumbersAddOps<StructureND<Short>> { override fun number(value: Number): BufferND<Short> { - val short - = value.toShort() // minimize conversions + val short = value.toShort() // minimize conversions return structureND(shape) { short } } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt index 128badda4..dfcf39965 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/IntRingND.kt @@ -35,7 +35,7 @@ public sealed class IntRingOpsND : BufferedRingOpsND<Int, Int32Ring>(Int32Ring.b @OptIn(UnstableKMathAPI::class) public class IntRingND( - override val shape: ShapeND + override val shape: ShapeND, ) : IntRingOpsND(), RingND<Int, Int32Ring>, NumbersAddOps<StructureND<Int>> { override fun number(value: Number): BufferND<Int> { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt index 2cada103d..7bd5f8350 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/algebraNDExtentions.kt @@ -14,13 +14,13 @@ import kotlin.jvm.JvmName public fun <T, A : Algebra<T>> AlgebraND<T, A>.structureND( shapeFirst: Int, vararg shapeRest: Int, - initializer: A.(IntArray) -> T + initializer: A.(IntArray) -> T, ): StructureND<T> = structureND(ShapeND(shapeFirst, *shapeRest), initializer) public fun <T, A : Algebra<T>> AlgebraND<T, A>.mutableStructureND( shapeFirst: Int, vararg shapeRest: Int, - initializer: A.(IntArray) -> T + initializer: A.(IntArray) -> T, ): MutableStructureND<T> = mutableStructureND(ShapeND(shapeFirst, *shapeRest), initializer) public fun <T, A : Group<T>> AlgebraND<T, A>.zero(shape: ShapeND): StructureND<T> = structureND(shape) { zero } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt index de26b0cf0..c10237324 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/BigInt.kt @@ -454,10 +454,12 @@ public fun String.parseBigInteger(): BigInt? { sign = +1 1 } + '-' -> { sign = -1 1 } + else -> { sign = +1 0 diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt index 5defbd7c5..1c4bda18f 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Float64BufferField.kt @@ -33,7 +33,7 @@ public class Float64BufferField(public val size: Int) : ExtendedField<Buffer<Dou arg.map { it.pow(pow.toInt()) } } else { arg.map { - if(it<0) throw IllegalArgumentException("Negative argument $it could not be raised to the fractional power") + if (it < 0) throw IllegalArgumentException("Negative argument $it could not be raised to the fractional power") it.pow(pow.toDouble()) } } diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt index 422134bcd..2aeb30be4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/OptionalOperations.kt @@ -84,7 +84,7 @@ public expect fun Number.isInteger(): Boolean * * @param T the type of this structure element */ -public interface PowerOperations<T>: Algebra<T> { +public interface PowerOperations<T> : Algebra<T> { /** * Raises [arg] to a power if possible (negative number could not be raised to a fractional power). diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt index 872d72857..9daccfb30 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/algebraExtensions.kt @@ -99,9 +99,10 @@ public fun <T> Iterable<T>.sumWith(group: Group<T>): T = group.sum(this) * @param group tha algebra that provides addition * @param extractor the (inline) lambda function to extract value */ -public inline fun <T, R> Iterable<T>.sumWithGroupOf(group: Group<R>, extractor: (T) -> R): R = this.fold(group.zero) { left: R, right: T -> - group.add(left, extractor(right)) -} +public inline fun <T, R> Iterable<T>.sumWithGroupOf(group: Group<R>, extractor: (T) -> R): R = + this.fold(group.zero) { left: R, right: T -> + group.add(left, extractor(right)) + } /** * Returns the sum of all elements in the sequence in provided space. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt index 17f6f2889..79fb0edb7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/integerFields.kt @@ -34,7 +34,7 @@ public object Int16Field : Field<Int16>, Norm<Int16, Int16>, NumericAlgebra<Int1 override fun multiply(left: Int16, right: Int16): Int16 = (left * right).toShort() override fun norm(arg: Int16): Int16 = abs(arg) - override fun scale(a: Int16, value: Double): Int16 = (a*value).roundToInt().toShort() + override fun scale(a: Int16, value: Double): Int16 = (a * value).roundToInt().toShort() override fun divide(left: Int16, right: Int16): Int16 = (left / right).toShort() @@ -58,7 +58,7 @@ public object Int32Field : Field<Int32>, Norm<Int32, Int32>, NumericAlgebra<Int3 override fun multiply(left: Int, right: Int): Int = left * right override fun norm(arg: Int): Int = abs(arg) - override fun scale(a: Int, value: Double): Int = (a*value).roundToInt() + override fun scale(a: Int, value: Double): Int = (a * value).roundToInt() override fun divide(left: Int, right: Int): Int = left / right @@ -81,7 +81,7 @@ public object Int64Field : Field<Int64>, Norm<Int64, Int64>, NumericAlgebra<Int6 override fun multiply(left: Int64, right: Int64): Int64 = left * right override fun norm(arg: Int64): Int64 = abs(arg) - override fun scale(a: Int64, value: Double): Int64 = (a*value).roundToLong() + override fun scale(a: Int64, value: Double): Int64 = (a * value).roundToLong() override fun divide(left: Int64, right: Int64): Int64 = left / right diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt index 892f6a7c5..15f4077d5 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/ArrayBuffer.kt @@ -32,4 +32,4 @@ public value class ArrayBuffer<T>(internal val array: Array<T>) : MutableBuffer< /** * Returns an [ArrayBuffer] that wraps the original array. */ -public fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer( this) +public fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(this) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt index ce31163a9..043d65cd4 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/FlaggedBuffer.kt @@ -55,7 +55,7 @@ public fun FlaggedBuffer<*>.isMissing(index: Int): Boolean = hasFlag(index, Valu */ public class FlaggedDoubleBuffer( public val values: DoubleArray, - public val flags: ByteArray + public val flags: ByteArray, ) : FlaggedBuffer<Double?>, Buffer<Double?> { init { diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt index 7ad6c2a0d..a6b27e7a7 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Float32Buffer.kt @@ -37,7 +37,8 @@ public typealias FloatBuffer = Float32Buffer * The function [init] is called for each array element sequentially starting from the first one. * It should return the value for a buffer element given its index. */ -public inline fun Float32Buffer(size: Int, init: (Int) -> Float): Float32Buffer = Float32Buffer(FloatArray(size) { init(it) }) +public inline fun Float32Buffer(size: Int, init: (Int) -> Float): Float32Buffer = + Float32Buffer(FloatArray(size) { init(it) }) /** * Returns a new [Float32Buffer] of given elements. diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt index be0c76618..eeee5faad 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/MutableBuffer.kt @@ -14,7 +14,7 @@ import kotlin.reflect.typeOf * * @param T the type of elements contained in the buffer. */ -public interface MutableBuffer<T> : Buffer<T>{ +public interface MutableBuffer<T> : Buffer<T> { /** * Sets the array element at the specified [index] to the specified [value]. @@ -65,20 +65,21 @@ public interface MutableBuffer<T> : Buffer<T>{ /** * Returns a shallow copy of the buffer. */ -public fun <T> Buffer<T>.copy(bufferFactory: BufferFactory<T>): Buffer<T> =if(this is ArrayBuffer){ +public fun <T> Buffer<T>.copy(bufferFactory: BufferFactory<T>): Buffer<T> = if (this is ArrayBuffer) { ArrayBuffer(array.copyOf()) -}else{ - bufferFactory(size,::get) +} else { + bufferFactory(size, ::get) } /** * Returns a mutable shallow copy of the buffer. */ -public fun <T> Buffer<T>.mutableCopy(bufferFactory: MutableBufferFactory<T>): MutableBuffer<T> =if(this is ArrayBuffer){ - ArrayBuffer(array.copyOf()) -}else{ - bufferFactory(size,::get) -} +public fun <T> Buffer<T>.mutableCopy(bufferFactory: MutableBufferFactory<T>): MutableBuffer<T> = + if (this is ArrayBuffer) { + ArrayBuffer(array.copyOf()) + } else { + bufferFactory(size, ::get) + } /** diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt index 901b1157c..037fdf3e5 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/DoubleLUSolverTest.kt @@ -21,14 +21,14 @@ fun <T : Any> assertMatrixEquals(expected: StructureND<T>, actual: StructureND<T class DoubleLUSolverTest { @Test - fun testInvertOne() = Double.algebra.linearSpace.run{ + fun testInvertOne() = Double.algebra.linearSpace.run { val matrix = one(2, 2) val inverted = lupSolver().inverse(matrix) assertMatrixEquals(matrix, inverted) } @Test - fun testDecomposition() = with(Double.algebra.linearSpace){ + fun testDecomposition() = with(Double.algebra.linearSpace) { val matrix = matrix(2, 2)( 3.0, 1.0, 2.0, 3.0 @@ -43,7 +43,7 @@ class DoubleLUSolverTest { } @Test - fun testInvert() = Double.algebra.linearSpace.run{ + fun testInvert() = Double.algebra.linearSpace.run { val matrix = matrix(2, 2)( 3.0, 1.0, 1.0, 3.0 diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt index eb76d59dc..30b8aaffb 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/linear/MatrixTest.kt @@ -50,7 +50,7 @@ class MatrixTest { infix fun Matrix<Double>.pow(power: Int): Matrix<Double> { var res = this repeat(power - 1) { - res = res dot this@pow + res = res dot this@pow } return res } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt index a8fc1c765..f17f32738 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/misc/PermSortTest.kt @@ -29,7 +29,7 @@ class PermSortTest { */ @Test fun testOnEmptyBuffer() { - val emptyBuffer = Int32Buffer(0) {it} + val emptyBuffer = Int32Buffer(0) { it } var permutations = emptyBuffer.indicesSorted() assertTrue(permutations.isEmpty(), "permutation on an empty buffer should return an empty result") permutations = emptyBuffer.indicesSortedDescending() @@ -67,10 +67,14 @@ class PermSortTest { assertContentEquals(expected, permutations.map { platforms[it] }, "PermSort using custom ascending comparator") permutations = platforms.indicesSortedWith(compareByDescending { it.name.length }) - assertContentEquals(expected.reversed(), permutations.map { platforms[it] }, "PermSort using custom descending comparator") + assertContentEquals( + expected.reversed(), + permutations.map { platforms[it] }, + "PermSort using custom descending comparator" + ) } - private fun testPermutation(bufferSize: Int) { + private fun testPermutation(bufferSize: Int) { val seed = Random.nextLong() println("Test randomization seed: $seed") @@ -82,23 +86,23 @@ class PermSortTest { // Ensure no doublon is present in indices assertEquals(indices.toSet().size, indices.size) - for (i in 0 until (bufferSize-1)) { + for (i in 0 until (bufferSize - 1)) { val current = buffer[indices[i]] - val next = buffer[indices[i+1]] + val next = buffer[indices[i + 1]] assertTrue(current <= next, "Permutation indices not properly sorted") } val descIndices = buffer.indicesSortedDescending() - assertEquals(bufferSize, descIndices.size) + assertEquals(bufferSize, descIndices.size) // Ensure no doublon is present in indices assertEquals(descIndices.toSet().size, descIndices.size) - for (i in 0 until (bufferSize-1)) { + for (i in 0 until (bufferSize - 1)) { val current = buffer[descIndices[i]] - val next = buffer[descIndices[i+1]] + val next = buffer[descIndices[i + 1]] assertTrue(current >= next, "Permutation indices not properly sorted in descending order") } } - private fun Random.buffer(size : Int) = Int32Buffer(size) { nextInt() } + private fun Random.buffer(size: Int) = Int32Buffer(size) { nextInt() } } diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt index d0f79bb15..d3c1dbc3b 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/NdOperationsTest.kt @@ -18,7 +18,7 @@ class NdOperationsTest { println(StructureND.toString(structure)) - val rolled = structure.roll(0,-1) + val rolled = structure.roll(0, -1) println(StructureND.toString(rolled)) diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/StridesTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/StridesTest.kt index 1c26c215c..224968e14 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/StridesTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/nd/StridesTest.kt @@ -12,10 +12,10 @@ class StridesTest { fun checkRowBasedStrides() { val strides = RowStrides(ShapeND(3, 3)) var counter = 0 - for(i in 0..2){ - for(j in 0..2){ + for (i in 0..2) { + for (j in 0..2) { // print(strides.offset(intArrayOf(i,j)).toString() + "\t") - require(strides.offset(intArrayOf(i,j)) == counter) + require(strides.offset(intArrayOf(i, j)) == counter) counter++ } println() @@ -26,10 +26,10 @@ class StridesTest { fun checkColumnBasedStrides() { val strides = ColumnStrides(ShapeND(3, 3)) var counter = 0 - for(i in 0..2){ - for(j in 0..2){ + for (i in 0..2) { + for (j in 0..2) { // print(strides.offset(intArrayOf(i,j)).toString() + "\t") - require(strides.offset(intArrayOf(j,i)) == counter) + require(strides.offset(intArrayOf(j, i)) == counter) counter++ } println() diff --git a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/BufferExpandedTest.kt b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/BufferExpandedTest.kt index 0a9b1d897..37cc4a533 100644 --- a/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/BufferExpandedTest.kt +++ b/kmath-core/src/commonTest/kotlin/space/kscience/kmath/structures/BufferExpandedTest.kt @@ -13,7 +13,7 @@ internal class BufferExpandedTest { private val buffer = (0..100).toList().asBuffer() @Test - fun shrink(){ + fun shrink() { val view = buffer.slice(20..30) assertEquals(20, view[0]) assertEquals(30, view[10]) @@ -21,10 +21,10 @@ internal class BufferExpandedTest { } @Test - fun expandNegative(){ - val view: BufferView<Int> = buffer.expand(-20..113,0) - assertEquals(0,view[4]) - assertEquals(0,view[123]) + fun expandNegative() { + val view: BufferView<Int> = buffer.expand(-20..113, 0) + assertEquals(0, view[4]) + assertEquals(0, view[123]) assertEquals(100, view[120]) assertFails { view[-2] } assertFails { view[134] } diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt index fd200d9f8..1fb5625b3 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/linear/Float64ParallelLinearSpace.kt @@ -41,7 +41,7 @@ public object Float64ParallelLinearSpace : LinearSpace<Double, Float64Field> { } override fun buildVector(size: Int, initializer: Float64Field.(Int) -> Double): Float64Buffer = - IntStream.range(0, size).parallel().mapToDouble{ Float64Field.initializer(it) }.toArray().asBuffer() + IntStream.range(0, size).parallel().mapToDouble { Float64Field.initializer(it) }.toArray().asBuffer() override fun Matrix<Double>.unaryMinus(): Matrix<Double> = Floa64FieldOpsND { asND().map { -it }.as2D() diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/isInteger.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/isInteger.kt index fa75860d8..e0b1cbe83 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/isInteger.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/operations/isInteger.kt @@ -8,4 +8,5 @@ package space.kscience.kmath.operations /** * Check if number is an integer */ -public actual fun Number.isInteger(): Boolean = (this is Int) || (this is Long) || (this is Short) || (this.toDouble() % 1 == 0.0) \ No newline at end of file +public actual fun Number.isInteger(): Boolean = + (this is Int) || (this is Long) || (this is Short) || (this.toDouble() % 1 == 0.0) \ No newline at end of file diff --git a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt index 7eeb0dbbd..d19f50dba 100644 --- a/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt +++ b/kmath-core/src/jvmMain/kotlin/space/kscience/kmath/structures/parallelMutableBuffer.kt @@ -33,7 +33,8 @@ public fun <T> MutableBuffer.Companion.parallel( typeOf<Double>() -> IntStream.range(0, size).parallel().mapToDouble { initializer(it) as Float64 }.toArray() .asBuffer() as MutableBuffer<T> //TODO add unsigned types - else -> IntStream.range(0, size).parallel().mapToObj { initializer(it) }.collect(Collectors.toList<T>()).asMutableBuffer() + else -> IntStream.range(0, size).parallel().mapToObj { initializer(it) }.collect(Collectors.toList<T>()) + .asMutableBuffer() } public class ParallelBufferFactory<T>(override val type: SafeType<T>) : MutableBufferFactory<T> { diff --git a/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt b/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt index 915ec3c5e..2abc36c8e 100644 --- a/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt +++ b/kmath-core/src/jvmTest/kotlin/space/kscience/kmath/linear/ParallelMatrixTest.kt @@ -19,14 +19,14 @@ import kotlin.test.assertTrue class ParallelMatrixTest { @Test - fun testTranspose() = Float64Field.linearSpace.parallel{ + fun testTranspose() = Float64Field.linearSpace.parallel { val matrix = one(3, 3) val transposed = matrix.transposed() assertTrue { StructureND.contentEquals(matrix, transposed) } } @Test - fun testBuilder() = Float64Field.linearSpace.parallel{ + fun testBuilder() = Float64Field.linearSpace.parallel { val matrix = matrix(2, 3)( 1.0, 0.0, 0.0, 0.0, 1.0, 2.0 @@ -36,7 +36,7 @@ class ParallelMatrixTest { } @Test - fun testMatrixExtension() = Float64Field.linearSpace.parallel{ + fun testMatrixExtension() = Float64Field.linearSpace.parallel { val transitionMatrix: Matrix<Double> = VirtualMatrix(6, 6) { row, col -> when { col == 0 -> .50 @@ -49,7 +49,7 @@ class ParallelMatrixTest { infix fun Matrix<Double>.pow(power: Int): Matrix<Double> { var res = this repeat(power - 1) { - res = res dot this@pow + res = res dot this@pow } return res } diff --git a/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/operations/isInteger.kt b/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/operations/isInteger.kt index fa75860d8..e0b1cbe83 100644 --- a/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/operations/isInteger.kt +++ b/kmath-core/src/nativeMain/kotlin/space/kscience/kmath/operations/isInteger.kt @@ -8,4 +8,5 @@ package space.kscience.kmath.operations /** * Check if number is an integer */ -public actual fun Number.isInteger(): Boolean = (this is Int) || (this is Long) || (this is Short) || (this.toDouble() % 1 == 0.0) \ No newline at end of file +public actual fun Number.isInteger(): Boolean = + (this is Int) || (this is Long) || (this is Short) || (this.toDouble() % 1 == 0.0) \ No newline at end of file diff --git a/kmath-coroutines/README.md b/kmath-coroutines/README.md index 4b7081bb1..5b64ccc0a 100644 --- a/kmath-coroutines/README.md +++ b/kmath-coroutines/README.md @@ -1,7 +1,5 @@ # Module kmath-coroutines - - ## Usage ## Artifact: @@ -9,6 +7,7 @@ The Maven coordinates of this project are `space.kscience:kmath-coroutines:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt index 6acf5c1c8..86e7bcfef 100644 --- a/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt +++ b/kmath-coroutines/src/jvmMain/kotlin/space/kscience/kmath/structures/LazyStructureND.kt @@ -25,6 +25,7 @@ public class LazyStructureND<out T>( } public suspend fun await(index: IntArray): T = async(index).await() + @PerformancePitfall override operator fun get(index: IntArray): T = runBlocking { async(index).await() } @@ -57,4 +58,4 @@ public inline fun <T, R> StructureND<T>.mapAsyncIndexed( public inline fun <T, R> StructureND<T>.mapAsync( scope: CoroutineScope, crossinline function: suspend (T) -> R, -): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index)) } +): LazyStructureND<R> = LazyStructureND(scope, shape) { index -> function(get(index)) } diff --git a/kmath-dimensions/README.md b/kmath-dimensions/README.md index c1c5e0dc2..f2482f965 100644 --- a/kmath-dimensions/README.md +++ b/kmath-dimensions/README.md @@ -9,6 +9,7 @@ A proof of concept module for adding type-safe dimensions to structures The Maven coordinates of this project are `space.kscience:kmath-dimensions:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-dimensions/build.gradle.kts b/kmath-dimensions/build.gradle.kts index 0ed6a8949..36f080899 100644 --- a/kmath-dimensions/build.gradle.kts +++ b/kmath-dimensions/build.gradle.kts @@ -2,13 +2,13 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() wasm() - dependencies{ + dependencies { api(projects.kmathCore) } diff --git a/kmath-ejml/README.md b/kmath-ejml/README.md index dcde8efd3..a2c38ce8e 100644 --- a/kmath-ejml/README.md +++ b/kmath-ejml/README.md @@ -2,16 +2,16 @@ EJML based linear algebra implementation. - - [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations. - - [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation. - - [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations. - +- [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations. +- [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation. +- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations. ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-ejml:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt index d196f5f1a..df4941c52 100644 --- a/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt +++ b/kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/implementations.kt @@ -674,15 +674,17 @@ public object EjmlLinearSpaceDSCC : EjmlLinearSpace<Double, Float64Field, DMatri val raw: Any? = when (attribute) { Inverted -> { - val res = DMatrixRMaj(origin.numRows,origin.numCols) - CommonOps_DSCC.invert(origin,res) + val res = DMatrixRMaj(origin.numRows, origin.numCols) + CommonOps_DSCC.invert(origin, res) res.wrapMatrix() } Determinant -> CommonOps_DSCC.det(origin) QR -> object : QRDecomposition<Double> { - val ejmlQr by lazy { DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } } + val ejmlQr by lazy { + DecompositionFactory_DSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } + } override val q: Matrix<Double> get() = ejmlQr.getQ(null, false).wrapMatrix() override val r: Matrix<Double> get() = ejmlQr.getR(null, false).wrapMatrix() } @@ -895,15 +897,17 @@ public object EjmlLinearSpaceFSCC : EjmlLinearSpace<Float, Float32Field, FMatrix val raw: Any? = when (attribute) { Inverted -> { - val res = FMatrixRMaj(origin.numRows,origin.numCols) - CommonOps_FSCC.invert(origin,res) + val res = FMatrixRMaj(origin.numRows, origin.numCols) + CommonOps_FSCC.invert(origin, res) res.wrapMatrix() } Determinant -> CommonOps_FSCC.det(origin) QR -> object : QRDecomposition<Float32> { - val ejmlQr by lazy { DecompositionFactory_FSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } } + val ejmlQr by lazy { + DecompositionFactory_FSCC.qr(FillReducing.NONE).apply { decompose(origin.copy()) } + } override val q: Matrix<Float32> get() = ejmlQr.getQ(null, false).wrapMatrix() override val r: Matrix<Float32> get() = ejmlQr.getR(null, false).wrapMatrix() } diff --git a/kmath-for-real/README.md b/kmath-for-real/README.md index 2c880f4f9..46762269e 100644 --- a/kmath-for-real/README.md +++ b/kmath-for-real/README.md @@ -2,16 +2,18 @@ Specialization of KMath APIs for Double numbers. - - [DoubleVector](src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for Buffers/Points - - [DoubleMatrix](src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures - - [grids](src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators - +- [DoubleVector](src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for + Buffers/Points +- [DoubleMatrix](src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real + structures +- [grids](src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-for-real:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt index d36537d71..208c82c6d 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/RealMatrix.kt @@ -48,7 +48,7 @@ public fun Sequence<DoubleArray>.toMatrix(): RealMatrix = toList().let { } public fun RealMatrix.repeatStackVertical(n: Int): RealMatrix = - VirtualMatrix( rowNum * n, colNum) { row, col -> + VirtualMatrix(rowNum * n, colNum) { row, col -> get(if (row == 0) 0 else row % rowNum, col) } diff --git a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt index f1b099cde..3a25739c3 100644 --- a/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt +++ b/kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/grids.kt @@ -39,7 +39,7 @@ public fun Buffer.Companion.withFixedStep(range: ClosedFloatingPointRange<Double else -> return Float64Buffer(range.start) } val numberOfPoints = floor(normalizedRange.length / step).toInt() + 1 - return Float64Buffer(numberOfPoints) { normalizedRange.start + step * it } + return Float64Buffer(numberOfPoints) { normalizedRange.start + step * it } } /** diff --git a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/GridTest.kt b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/GridTest.kt index 861995a19..035eccb9e 100644 --- a/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/GridTest.kt +++ b/kmath-for-real/src/commonTest/kotlin/space/kscience/kmath/real/GridTest.kt @@ -20,9 +20,9 @@ class GridTest { } @Test - fun testIterateGrid(){ + fun testIterateGrid() { var res = 0.0 - for(d in 0.0..1.0 step 0.2){ + for (d in 0.0..1.0 step 0.2) { res = d } assertEquals(1.0, res) diff --git a/kmath-functions/README.md b/kmath-functions/README.md index 1ee4149bd..25c802077 100644 --- a/kmath-functions/README.md +++ b/kmath-functions/README.md @@ -2,18 +2,20 @@ Functions and interpolations. - - [piecewise](src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions. - - [polynomials](src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions. - - [linear interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY interpolator. - - [spline interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator. - - [integration](#) : Univariate and multivariate quadratures - +- [piecewise](src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions. +- [polynomials](src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions. +- [linear interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY + interpolator. +- [spline interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline + XY interpolator. +- [integration](#) : Univariate and multivariate quadratures ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-functions:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-functions/build.gradle.kts b/kmath-functions/build.gradle.kts index 9296aaaf0..e7fcab84a 100644 --- a/kmath-functions/build.gradle.kts +++ b/kmath-functions/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt index 31e2406fa..e85f698c4 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/polynomialUtil.kt @@ -64,7 +64,7 @@ public fun <C, A> Polynomial<C>.differentiate( ): Polynomial<C> where A : Ring<C>, A : NumericAlgebra<C> = ring { Polynomial( buildList(max(0, coefficients.size - 1)) { - for (deg in 1 .. coefficients.lastIndex) add(number(deg) * coefficients[deg]) + for (deg in 1..coefficients.lastIndex) add(number(deg) * coefficients[deg]) } ) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt index 42ba2e3de..60777bfdb 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegratorRuleFactory.kt @@ -16,7 +16,7 @@ import kotlin.native.concurrent.ThreadLocal public interface GaussIntegratorRuleFactory { public fun build(numPoints: Int): Pair<Buffer<Double>, Buffer<Double>> - public companion object: IntegrandAttribute<GaussIntegratorRuleFactory>{ + public companion object : IntegrandAttribute<GaussIntegratorRuleFactory> { public fun double(numPoints: Int, range: ClosedRange<Double>): Pair<Buffer<Double>, Buffer<Double>> = GaussLegendreRuleFactory.build(numPoints, range) } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt index f5c98e9d9..babc86c54 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/Integrand.kt @@ -23,8 +23,8 @@ public interface Integrand<T> : AttributeContainer { public operator fun <T> Integrand<*>.get(attribute: Attribute<T>): T? = attributes[attribute] -public sealed class IntegrandValue<T> private constructor(): IntegrandAttribute<T>{ - public companion object: IntegrandValue<Any?>(){ +public sealed class IntegrandValue<T> private constructor() : IntegrandAttribute<T> { + public companion object : IntegrandValue<Any?>() { @Suppress("UNCHECKED_CAST") public fun <T> forType(): IntegrandValue<T> = this as IntegrandValue<T> } diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt index c320212f3..80f50fcc0 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialTest.kt @@ -8,7 +8,8 @@ package space.kscience.kmath.functions import space.kscience.kmath.functions.testUtils.* -import kotlin.test.* +import kotlin.test.Test +import kotlin.test.assertEquals class PolynomialTest { @@ -52,6 +53,7 @@ class PolynomialTest { ) } } + @Test fun test_Polynomial_Constant_minus() { RationalField.polynomialSpace { @@ -92,6 +94,7 @@ class PolynomialTest { ) } } + @Test fun test_Polynomial_Constant_times() { IntModuloRing(35).polynomialSpace { @@ -107,6 +110,7 @@ class PolynomialTest { ) } } + @Test fun test_Constant_Polynomial_plus() { RationalField.polynomialSpace { @@ -147,6 +151,7 @@ class PolynomialTest { ) } } + @Test fun test_Constant_Polynomial_minus() { RationalField.polynomialSpace { @@ -187,6 +192,7 @@ class PolynomialTest { ) } } + @Test fun test_Constant_Polynomial_times() { IntModuloRing(35).polynomialSpace { @@ -202,6 +208,7 @@ class PolynomialTest { ) } } + @Test fun test_Polynomial_unaryMinus() { RationalField.polynomialSpace { @@ -217,6 +224,7 @@ class PolynomialTest { ) } } + @Test fun test_Polynomial_Polynomial_plus() { RationalField.polynomialSpace { @@ -250,6 +258,7 @@ class PolynomialTest { ) } } + @Test fun test_Polynomial_Polynomial_minus() { RationalField.polynomialSpace { @@ -283,6 +292,7 @@ class PolynomialTest { ) } } + @Test fun test_Polynomial_Polynomial_times() { IntModuloRing(35).polynomialSpace { diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt index e91535506..b38afdd9e 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/PolynomialUtilTest.kt @@ -53,6 +53,7 @@ class PolynomialUtilTest { "test 5" ) } + @Test fun test_Polynomial_value_Constant() { assertEquals( @@ -85,6 +86,7 @@ class PolynomialUtilTest { "test 5" ) } + @Test fun test_Polynomial_differentiate() { assertEquals( @@ -94,20 +96,27 @@ class PolynomialUtilTest { ) assertEquals( Polynomial(Rational(-8, 3), Rational(8, 9), Rational(15, 7), Rational(-20, 9)), - Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).differentiate(RationalField), + Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).differentiate( + RationalField + ), "test 2" ) assertEquals( Polynomial(Rational(0), Rational(8, 9), Rational(15, 7), Rational(-20, 9)), - Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).differentiate(RationalField), + Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).differentiate( + RationalField + ), "test 3" ) assertEquals( Polynomial(Rational(-8, 3), Rational(8, 9), Rational(15, 7), Rational(0)), - Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).differentiate(RationalField), + Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).differentiate( + RationalField + ), "test 4" ) } + @Test fun test_Polynomial_integrate() { assertEquals( @@ -117,17 +126,23 @@ class PolynomialUtilTest { ) assertEquals( Polynomial(Rational(0), Rational(1, 5), Rational(-4, 3), Rational(4, 27), Rational(5, 28), Rational(-1, 9)), - Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).integrate(RationalField), + Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).integrate( + RationalField + ), "test 2" ) assertEquals( Polynomial(Rational(0), Rational(0), Rational(0), Rational(4, 27), Rational(5, 28), Rational(-1, 9)), - Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).integrate(RationalField), + Polynomial(Rational(0), Rational(0), Rational(4, 9), Rational(5, 7), Rational(-5, 9)).integrate( + RationalField + ), "test 3" ) assertEquals( Polynomial(Rational(0), Rational(1, 5), Rational(-4, 3), Rational(4, 27), Rational(5, 28), Rational(0)), - Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).integrate(RationalField), + Polynomial(Rational(1, 5), Rational(-8, 3), Rational(4, 9), Rational(5, 7), Rational(0)).integrate( + RationalField + ), "test 4" ) } diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt index d53a1ac2b..ceb80d7dd 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModulo.kt @@ -37,6 +37,7 @@ class IntModulo { modulus, toCheckInput = false ) + operator fun plus(other: IntModulo): IntModulo { require(modulus == other.modulus) { "can not add two residue different modulo" } return IntModulo( @@ -45,12 +46,14 @@ class IntModulo { toCheckInput = false ) } + operator fun plus(other: Int): IntModulo = IntModulo( (residue + other) % modulus, modulus, toCheckInput = false ) + operator fun minus(other: IntModulo): IntModulo { require(modulus == other.modulus) { "can not subtract two residue different modulo" } return IntModulo( @@ -59,12 +62,14 @@ class IntModulo { toCheckInput = false ) } + operator fun minus(other: Int): IntModulo = IntModulo( (residue - other) % modulus, modulus, toCheckInput = false ) + operator fun times(other: IntModulo): IntModulo { require(modulus == other.modulus) { "can not multiply two residue different modulo" } return IntModulo( @@ -73,12 +78,14 @@ class IntModulo { toCheckInput = false ) } + operator fun times(other: Int): IntModulo = IntModulo( (residue * other) % modulus, modulus, toCheckInput = false ) + operator fun div(other: IntModulo): IntModulo { require(modulus == other.modulus) { "can not divide two residue different modulo" } val (reciprocalCandidate, gcdOfOtherResidueAndModulus) = bezoutIdentityWithGCD(other.residue, modulus) @@ -89,6 +96,7 @@ class IntModulo { toCheckInput = false ) } + operator fun div(other: Int): IntModulo { val (reciprocalCandidate, gcdOfOtherResidueAndModulus) = bezoutIdentityWithGCD(other, modulus) require(gcdOfOtherResidueAndModulus == 1) { "can not divide to residue that has non-trivial GCD with modulo" } @@ -98,6 +106,7 @@ class IntModulo { toCheckInput = false ) } + override fun equals(other: Any?): Boolean = when (other) { is IntModulo -> residue == other.residue && modulus == other.modulus diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModuloUtils.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModuloUtils.kt index ce9a0270c..c6a8e16cd 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModuloUtils.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/IntModuloUtils.kt @@ -11,6 +11,7 @@ import space.kscience.kmath.functions.PolynomialSpace fun PolynomialSpace<IntModulo, IntModuloRing>.Polynomial(vararg coefs: Int): Polynomial<IntModulo> = Polynomial(coefs.map { IntModulo(it, ring.modulus) }) + fun IntModuloRing.Polynomial(vararg coefs: Int): Polynomial<IntModulo> = Polynomial(coefs.map { IntModulo(it, modulus) }) diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt index c810cba2e..0160b2c97 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/Rational.kt @@ -57,18 +57,21 @@ class Rational { toCheckInput = false ) } + operator fun plus(other: Int): Rational = Rational( numerator + denominator * other.toLong(), denominator, toCheckInput = false ) + operator fun plus(other: Long): Rational = Rational( numerator + denominator * other, denominator, toCheckInput = false ) + operator fun minus(other: Rational): Rational { val denominatorsGcd = gcd(denominator, other.denominator) val dividedThisDenominator = denominator / denominatorsGcd @@ -81,18 +84,21 @@ class Rational { toCheckInput = false ) } + operator fun minus(other: Int): Rational = Rational( numerator - denominator * other.toLong(), denominator, toCheckInput = false ) + operator fun minus(other: Long): Rational = Rational( numerator - denominator * other, denominator, toCheckInput = false ) + operator fun times(other: Rational): Rational { val thisDenominatorAndOtherNumeratorGcd = gcd(denominator, other.numerator) val otherDenominatorAndThisNumeratorGcd = gcd(other.denominator, numerator) @@ -102,6 +108,7 @@ class Rational { toCheckInput = false ) } + operator fun times(other: Int): Rational { val other = other.toLong() val denominatorAndOtherGcd = gcd(denominator, other) @@ -111,6 +118,7 @@ class Rational { toCheckInput = false ) } + operator fun times(other: Long): Rational { val denominatorAndOtherGcd = gcd(denominator, other) return Rational( @@ -119,6 +127,7 @@ class Rational { toCheckInput = false ) } + operator fun div(other: Rational): Rational { val denominatorsGcd = gcd(denominator, other.denominator) val numeratorsGcd = gcd(numerator, other.numerator) @@ -127,6 +136,7 @@ class Rational { (denominator / denominatorsGcd) * (other.numerator / numeratorsGcd) ) } + operator fun div(other: Int): Rational { val other = other.toLong() val numeratorAndOtherGcd = gcd(numerator, other) @@ -136,6 +146,7 @@ class Rational { toCheckInput = false ) } + operator fun div(other: Long): Rational { val numeratorAndOtherGcd = gcd(numerator, other) return Rational( @@ -144,6 +155,7 @@ class Rational { toCheckInput = false ) } + override fun equals(other: Any?): Boolean = when (other) { is Rational -> numerator == other.numerator && denominator == other.denominator diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/misc.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/misc.kt index 267fae83b..6f728a53d 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/misc.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/functions/testUtils/misc.kt @@ -14,13 +14,41 @@ internal tailrec fun gcd(a: Long, b: Long): Long = if (a == 0L) abs(b) else gcd( internal fun bezoutIdentityWithGCD(a: Int, b: Int): BezoutIdentityWithGCD<Int> = when { - a < 0 && b < 0 -> with(bezoutIdentityWithGCDInternalLogic(-a, -b, 1, 0, 0, 1)) { BezoutIdentityWithGCD(-first, -second, gcd) } - a < 0 -> with(bezoutIdentityWithGCDInternalLogic(-a, b, 1, 0, 0, 1)) { BezoutIdentityWithGCD(-first, second, gcd) } - b < 0 -> with(bezoutIdentityWithGCDInternalLogic(a, -b, 1, 0, 0, 1)) { BezoutIdentityWithGCD(first, -second, gcd) } + a < 0 && b < 0 -> with(bezoutIdentityWithGCDInternalLogic(-a, -b, 1, 0, 0, 1)) { + BezoutIdentityWithGCD( + -first, + -second, + gcd + ) + } + + a < 0 -> with(bezoutIdentityWithGCDInternalLogic(-a, b, 1, 0, 0, 1)) { + BezoutIdentityWithGCD( + -first, + second, + gcd + ) + } + + b < 0 -> with(bezoutIdentityWithGCDInternalLogic(a, -b, 1, 0, 0, 1)) { + BezoutIdentityWithGCD( + first, + -second, + gcd + ) + } + else -> bezoutIdentityWithGCDInternalLogic(a, b, 1, 0, 0, 1) } -internal tailrec fun bezoutIdentityWithGCDInternalLogic(a: Int, b: Int, m1: Int, m2: Int, m3: Int, m4: Int): BezoutIdentityWithGCD<Int> = +internal tailrec fun bezoutIdentityWithGCDInternalLogic( + a: Int, + b: Int, + m1: Int, + m2: Int, + m3: Int, + m4: Int, +): BezoutIdentityWithGCD<Int> = if (b == 0) BezoutIdentityWithGCD(m1, m3, a) else { val quotient = a / b diff --git a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt index 0e8f9ddfb..db6bdc6bd 100644 --- a/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt +++ b/kmath-functions/src/commonTest/kotlin/space/kscience/kmath/integration/GaussIntegralTest.kt @@ -25,7 +25,7 @@ class GaussIntegralTest { @Test fun gaussUniform() { val res = Float64Field.gaussIntegrator.integrate(35.0..100.0) { x -> - if(x in 30.0..50.0){ + if (x in 30.0..50.0) { 1.0 } else { 0.0 diff --git a/kmath-geometry/README.md b/kmath-geometry/README.md index 601610d3d..263df3a87 100644 --- a/kmath-geometry/README.md +++ b/kmath-geometry/README.md @@ -1,7 +1,5 @@ # Module kmath-geometry - - ## Usage ## Artifact: @@ -9,6 +7,7 @@ The Maven coordinates of this project are `space.kscience:kmath-geometry:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-geometry/build.gradle.kts b/kmath-geometry/build.gradle.kts index 4bf768f4b..58bbbf5d0 100644 --- a/kmath-geometry/build.gradle.kts +++ b/kmath-geometry/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() @@ -10,7 +10,7 @@ kscience{ useContextReceivers() useSerialization() - dependencies{ + dependencies { api(projects.kmath.kmathComplex) } diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt index 8b9fcd396..d11378795 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/GeometrySpace.kt @@ -14,7 +14,7 @@ import space.kscience.kmath.operations.ScaleOperations * @param V the type of vector object * @param D the type of distance */ -public interface GeometrySpace<V : Any, D: Comparable<D>> : Group<V>, ScaleOperations<V>, Norm<V, D> { +public interface GeometrySpace<V : Any, D : Comparable<D>> : Group<V>, ScaleOperations<V>, Norm<V, D> { /** * L2 distance */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt index d7b450ab0..1d832cb8a 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/Polygon.kt @@ -9,6 +9,6 @@ package space.kscience.kmath.geometry /** * A closed polygon in 2D space */ -public interface Polygon<V: Any> { +public interface Polygon<V : Any> { public val points: List<V> } \ No newline at end of file diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt index ff3efc126..8598bdcc9 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/angles.kt @@ -30,7 +30,7 @@ public sealed interface Angle : Comparable<Angle> { public operator fun div(other: Angle): Double public operator fun unaryMinus(): Angle - public companion object: Group<Angle> { + public companion object : Group<Angle> { override val zero: Radians = Radians(0.0) public val pi: Radians = Radians(PI) public val piTimes2: Radians = Radians(PI * 2) diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt index 37e11ba87..3925f8195 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean2d/Float64Space2D.kt @@ -27,7 +27,6 @@ public typealias Float64Vector2D = Vector2D<Float64> public typealias DoubleVector2D = Float64Vector2D - /** * 2D Euclidean space */ diff --git a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt index 1275ad630..cebad79a2 100644 --- a/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt +++ b/kmath-geometry/src/commonMain/kotlin/space/kscience/kmath/geometry/euclidean3d/rotations3D.kt @@ -90,7 +90,7 @@ public fun Float64Space3D.rotate( /** * Rotate a [Float64] vector in 3D space with a rotation matrix */ -public fun Float64Space3D.rotate(vector: Float64Vector3D, matrix: Matrix<Double>): Vector3D<Float64> { +public fun Float64Space3D.rotate(vector: Float64Vector3D, matrix: Matrix<Double>): Vector3D<Float64> { require(matrix.colNum == 3 && matrix.rowNum == 3) { "Square 3x3 rotation matrix is required" } return with(linearSpace) { (matrix dot vector).asVector3D() } } diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt index 0c2267e8b..ae4ee84e0 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/ProjectionAlongTest.kt @@ -44,7 +44,7 @@ internal class ProjectionAlongTest { } @Test - fun projectOntoPlane() = with(Float64Space3D){ + fun projectOntoPlane() = with(Float64Space3D) { val normal = vector(1.0, 3.5, 0.07) val base = vector(2.0, -0.0037, 11.1111) diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt index 9e62a086c..c802470b2 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/RotationTest.kt @@ -27,7 +27,7 @@ class RotationTest { } @Test - fun matrixConversion() = with(QuaternionAlgebra){ + fun matrixConversion() = with(QuaternionAlgebra) { val q = Quaternion(1.0, 2.0, -3.0, 4.0).normalized() @@ -45,9 +45,9 @@ class RotationTest { val reconstructed = Quaternion.fromEuler(angles, ro) - if( reconstructed.w>0) { + if (reconstructed.w > 0) { assertBufferEquals(q, reconstructed) - } else{ + } else { assertBufferEquals(q, -reconstructed) } } diff --git a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt index 3f9c86add..22b58d260 100644 --- a/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt +++ b/kmath-geometry/src/commonTest/kotlin/space/kscience/kmath/geometry/testUtils.kt @@ -18,7 +18,7 @@ fun ClosedRange<Double>.generateList(step: Double): List<Double> = generateSeque fun grid( xRange: ClosedRange<Double>, yRange: ClosedRange<Double>, - step: Double + step: Double, ): List<Pair<Double, Double>> { val xs = xRange.generateList(step) val ys = yRange.generateList(step) @@ -26,12 +26,12 @@ fun grid( return xs.flatMap { x -> ys.map { y -> x to y } } } -fun assertVectorEquals(expected: Vector2D<Float64>, actual: Vector2D<Float64>, absoluteTolerance: Double = 1e-3) { +fun assertVectorEquals(expected: Vector2D<Float64>, actual: Vector2D<Float64>, absoluteTolerance: Double = 1e-3) { assertEquals(expected.x, actual.x, absoluteTolerance) assertEquals(expected.y, actual.y, absoluteTolerance) } -fun assertVectorEquals(expected: Vector3D<Float64>, actual: Vector3D<Float64>, absoluteTolerance: Double = 1e-6) { +fun assertVectorEquals(expected: Vector3D<Float64>, actual: Vector3D<Float64>, absoluteTolerance: Double = 1e-6) { assertEquals(expected.x, actual.x, absoluteTolerance) assertEquals(expected.y, actual.y, absoluteTolerance) assertEquals(expected.z, actual.z, absoluteTolerance) @@ -43,7 +43,7 @@ fun <V : Any> GeometrySpace<V, Double>.isCollinear(a: V, b: V, absoluteTolerance return aDist < absoluteTolerance || bDist < absoluteTolerance || abs(abs((a dot b) / (aDist * bDist)) - 1) < absoluteTolerance } -fun <V : Any> GeometrySpace<V,*>.isOrthogonal(a: V, b: V, absoluteTolerance: Double = 1e-6): Boolean = +fun <V : Any> GeometrySpace<V, *>.isOrthogonal(a: V, b: V, absoluteTolerance: Double = 1e-6): Boolean = abs(a dot b) < absoluteTolerance fun Double.equalFloat(other: Double, maxFloatDelta: Double = 0.000001): diff --git a/kmath-histograms/README.md b/kmath-histograms/README.md index e9aaad3a8..88f0c2dd4 100644 --- a/kmath-histograms/README.md +++ b/kmath-histograms/README.md @@ -1,7 +1,5 @@ # Module kmath-histograms - - ## Usage ## Artifact: @@ -9,6 +7,7 @@ The Maven coordinates of this project are `space.kscience:kmath-histograms:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-histograms/build.gradle.kts b/kmath-histograms/build.gradle.kts index 63791d61c..b7802054a 100644 --- a/kmath-histograms/build.gradle.kts +++ b/kmath-histograms/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() diff --git a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt index acd889bf0..a931b957d 100644 --- a/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt +++ b/kmath-histograms/src/commonMain/kotlin/space/kscience/kmath/histogram/Counter.kt @@ -19,7 +19,7 @@ public interface Counter<T : Any> { public companion object { public fun ofDouble(): ObjectCounter<Double> = ObjectCounter(Float64Field) - public fun <T: Any> of(group: Group<T>): ObjectCounter<T> = ObjectCounter(group) + public fun <T : Any> of(group: Group<T>): ObjectCounter<T> = ObjectCounter(group) } } diff --git a/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt b/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt index 25ffbbca5..3b605e9c1 100644 --- a/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt +++ b/kmath-histograms/src/jvmTest/kotlin/space/kscience/kmath/histogram/TreeHistogramTest.kt @@ -18,14 +18,14 @@ class TreeHistogramTest { @Test fun normalFill() { - val random = Random(123) + val random = Random(123) val histogram = Histogram.custom1D(Float64Field, 0.0..1.0 step 0.1).produce { repeat(100_000) { putValue(random.nextDouble()) } } - assertTrue { histogram.bins.count() > 8} + assertTrue { histogram.bins.count() > 8 } assertEquals(100_000, histogram.bins.sumOf { it.binValue }.toInt()) } } \ No newline at end of file diff --git a/kmath-jafama/README.md b/kmath-jafama/README.md index dc183ca37..314ad47ab 100644 --- a/kmath-jafama/README.md +++ b/kmath-jafama/README.md @@ -2,14 +2,14 @@ Integration with [Jafama](https://github.com/jeffhain/jafama). - - [jafama-double](src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama - +- [jafama-double](src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-jafama:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") @@ -39,6 +39,7 @@ fun main() { ## Performance -According to KMath benchmarks on GraalVM, Jafama functions are slower than JDK math; however, there are indications that on Hotspot Jafama is a bit faster. +According to KMath benchmarks on GraalVM, Jafama functions are slower than JDK math; however, there are indications that +on Hotspot Jafama is a bit faster. > **Can't find appropriate benchmark data. Try generating readme files after running benchmarks**. diff --git a/kmath-jafama/docs/README-TEMPLATE.md b/kmath-jafama/docs/README-TEMPLATE.md index 54348467b..2973fca3b 100644 --- a/kmath-jafama/docs/README-TEMPLATE.md +++ b/kmath-jafama/docs/README-TEMPLATE.md @@ -24,6 +24,7 @@ fun main() { ## Performance -According to KMath benchmarks on GraalVM, Jafama functions are slower than JDK math; however, there are indications that on Hotspot Jafama is a bit faster. +According to KMath benchmarks on GraalVM, Jafama functions are slower than JDK math; however, there are indications that +on Hotspot Jafama is a bit faster. ${benchmarkJafamaDouble} diff --git a/kmath-jupyter/README.md b/kmath-jupyter/README.md index 525ae673b..21531f632 100644 --- a/kmath-jupyter/README.md +++ b/kmath-jupyter/README.md @@ -1,7 +1,5 @@ # Module kmath-jupyter - - ## Usage ## Artifact: @@ -9,6 +7,7 @@ The Maven coordinates of this project are `space.kscience:kmath-jupyter:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-kotlingrad/README.md b/kmath-kotlingrad/README.md index a66c31686..2948799d3 100644 --- a/kmath-kotlingrad/README.md +++ b/kmath-kotlingrad/README.md @@ -2,15 +2,17 @@ [Kotlin∇](https://github.com/breandan/kotlingrad) integration module. - - [differentiable-mst-expression](src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based DifferentiableExpression. - - [scalars-adapters](src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s SFun and MST - +- [differentiable-mst-expression](src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based + DifferentiableExpression. +- [scalars-adapters](src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s + SFun and MST ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-kotlingrad:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-memory/README.md b/kmath-memory/README.md index d6824add0..8d66fe37d 100644 --- a/kmath-memory/README.md +++ b/kmath-memory/README.md @@ -1,7 +1,5 @@ # Module kmath-memory - - ## Usage ## Artifact: @@ -9,6 +7,7 @@ The Maven coordinates of this project are `space.kscience:kmath-memory:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/Memory.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/Memory.kt index c80eb1072..7b5e0438e 100644 --- a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/Memory.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/Memory.kt @@ -43,7 +43,7 @@ public interface Memory { /** * The interface to read primitive types in this memory. */ -public interface MemoryReader: AutoCloseable { +public interface MemoryReader : AutoCloseable { /** * The underlying memory. */ @@ -96,7 +96,7 @@ public inline fun <R> Memory.read(block: MemoryReader.() -> R): R { /** * The interface to write primitive types into this memory. */ -public interface MemoryWriter: AutoCloseable { +public interface MemoryWriter : AutoCloseable { /** * The underlying memory. */ diff --git a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt index ac5dc7b92..1a8c2d74a 100644 --- a/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt +++ b/kmath-memory/src/commonMain/kotlin/space/kscience/kmath/memory/MemorySpec.kt @@ -12,7 +12,7 @@ import space.kscience.attributes.WithType * * @param T the type of object this spec manages. */ -public interface MemorySpec<T : Any>: WithType<T> { +public interface MemorySpec<T : Any> : WithType<T> { /** * Size of [T] in bytes after serialization. diff --git a/kmath-memory/src/commonTest/kotlin/space/kscience/kmath/memory/MemoryTest.kt b/kmath-memory/src/commonTest/kotlin/space/kscience/kmath/memory/MemoryTest.kt index 6ca792839..57003201d 100644 --- a/kmath-memory/src/commonTest/kotlin/space/kscience/kmath/memory/MemoryTest.kt +++ b/kmath-memory/src/commonTest/kotlin/space/kscience/kmath/memory/MemoryTest.kt @@ -20,18 +20,18 @@ class MemoryTest { val memory = Memory.allocate(memorySize) memory.write { for (i in 0 until (memory.size / 4)) { - writeInt(i*4, data[i]) + writeInt(i * 4, data[i]) } } val result = memory.read { buildList { for (i in 0 until (memory.size / 4)) { - add(readInt(i*4)) + add(readInt(i * 4)) } } } - assertEquals(data,result) + assertEquals(data, result) } } \ No newline at end of file diff --git a/kmath-multik/README.md b/kmath-multik/README.md index f0bf10208..0bfc71a82 100644 --- a/kmath-multik/README.md +++ b/kmath-multik/README.md @@ -9,6 +9,7 @@ JetBrains Multik connector The Maven coordinates of this project are `space.kscience:kmath-multik:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-multik/build.gradle.kts b/kmath-multik/build.gradle.kts index 85c4d52cb..e3f27effe 100644 --- a/kmath-multik/build.gradle.kts +++ b/kmath-multik/build.gradle.kts @@ -11,16 +11,16 @@ kscience { js() } -kotlin{ - sourceSets{ - commonMain{ - dependencies{ +kotlin { + sourceSets { + commonMain { + dependencies { api(projects.kmathTensors) api("org.jetbrains.kotlinx:multik-core:$multikVersion") } } - commonTest{ - dependencies{ + commonTest { + dependencies { api("org.jetbrains.kotlinx:multik-default:$multikVersion") } } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt index 295aee876..6a8749946 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikDoubleAlgebra.kt @@ -16,20 +16,22 @@ import space.kscience.kmath.operations.Float64Field import space.kscience.kmath.operations.TrigonometricOperations public class MultikDoubleAlgebra( - multikEngine: Engine + multikEngine: Engine, ) : MultikDivisionTensorAlgebra<Double, Float64Field>(multikEngine), TrigonometricOperations<StructureND<Double>>, ExponentialOperations<StructureND<Double>> { override val elementAlgebra: Float64Field get() = Float64Field override val dataType: DataType get() = DataType.DoubleDataType - override fun sin(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.sin(arg.asMultik().array).wrap() + override fun sin(arg: StructureND<Double>): MultikTensor<Double> = + multikMath.mathEx.sin(arg.asMultik().array).wrap() - override fun cos(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.cos(arg.asMultik().array).wrap() + override fun cos(arg: StructureND<Double>): MultikTensor<Double> = + multikMath.mathEx.cos(arg.asMultik().array).wrap() override fun tan(arg: StructureND<Double>): MultikTensor<Double> = sin(arg) / cos(arg) @PerformancePitfall - override fun asin(arg: StructureND<Double>): MultikTensor<Double> = arg.map { asin(it) } + override fun asin(arg: StructureND<Double>): MultikTensor<Double> = arg.map { asin(it) } @PerformancePitfall override fun acos(arg: StructureND<Double>): MultikTensor<Double> = arg.map { acos(it) } @@ -37,7 +39,8 @@ public class MultikDoubleAlgebra( @PerformancePitfall override fun atan(arg: StructureND<Double>): MultikTensor<Double> = arg.map { atan(it) } - override fun exp(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.exp(arg.asMultik().array).wrap() + override fun exp(arg: StructureND<Double>): MultikTensor<Double> = + multikMath.mathEx.exp(arg.asMultik().array).wrap() override fun ln(arg: StructureND<Double>): MultikTensor<Double> = multikMath.mathEx.log(arg.asMultik().array).wrap() @@ -60,7 +63,7 @@ public class MultikDoubleAlgebra( @PerformancePitfall override fun atanh(arg: StructureND<Double>): MultikTensor<Double> = arg.map { atanh(it) } - override fun scalar(value: Double): MultikTensor<Double> = Multik.ndarrayOf(value).wrap() + override fun scalar(value: Double): MultikTensor<Double> = Multik.ndarrayOf(value).wrap() } //public val Double.Companion.multikAlgebra: MultikTensorAlgebra<Double, DoubleField> get() = MultikDoubleAlgebra diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt index 8ce6a791c..54a60e38a 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikFloatAlgebra.kt @@ -12,7 +12,7 @@ import org.jetbrains.kotlinx.multik.ndarray.data.DataType import space.kscience.kmath.operations.Float32Field public class MultikFloatAlgebra( - multikEngine: Engine + multikEngine: Engine, ) : MultikDivisionTensorAlgebra<Float, Float32Field>(multikEngine) { override val elementAlgebra: Float32Field get() = Float32Field override val dataType: DataType get() = DataType.FloatDataType diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt index 06b44ece7..c6cbae554 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikIntAlgebra.kt @@ -12,11 +12,11 @@ import org.jetbrains.kotlinx.multik.ndarray.data.DataType import space.kscience.kmath.operations.Int32Ring public class MultikIntAlgebra( - multikEngine: Engine + multikEngine: Engine, ) : MultikTensorAlgebra<Int, Int32Ring>(multikEngine) { override val elementAlgebra: Int32Ring get() = Int32Ring override val dataType: DataType get() = DataType.IntDataType - override fun scalar(value: Int): MultikTensor<Int> = Multik.ndarrayOf(value).wrap() + override fun scalar(value: Int): MultikTensor<Int> = Multik.ndarrayOf(value).wrap() } //public val Int.Companion.multikAlgebra: MultikTensorAlgebra<Int, IntRing> get() = MultikIntAlgebra diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt index d977326af..b30eaa580 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikLongAlgebra.kt @@ -12,12 +12,12 @@ import org.jetbrains.kotlinx.multik.ndarray.data.DataType import space.kscience.kmath.operations.Int64Ring public class MultikLongAlgebra( - multikEngine: Engine + multikEngine: Engine, ) : MultikTensorAlgebra<Long, Int64Ring>(multikEngine) { override val elementAlgebra: Int64Ring get() = Int64Ring override val dataType: DataType get() = DataType.LongDataType - override fun scalar(value: Long): MultikTensor<Long> = Multik.ndarrayOf(value).wrap() + override fun scalar(value: Long): MultikTensor<Long> = Multik.ndarrayOf(value).wrap() } diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt index caf07fef9..9403e8d6d 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikShortAlgebra.kt @@ -12,11 +12,11 @@ import org.jetbrains.kotlinx.multik.ndarray.data.DataType import space.kscience.kmath.operations.Int16Ring public class MultikShortAlgebra( - multikEngine: Engine + multikEngine: Engine, ) : MultikTensorAlgebra<Short, Int16Ring>(multikEngine) { override val elementAlgebra: Int16Ring get() = Int16Ring override val dataType: DataType get() = DataType.ShortDataType - override fun scalar(value: Short): MultikTensor<Short> = Multik.ndarrayOf(value).wrap() + override fun scalar(value: Short): MultikTensor<Short> = Multik.ndarrayOf(value).wrap() } //public val Short.Companion.multikAlgebra: MultikTensorAlgebra<Short, ShortRing> get() = MultikShortAlgebra diff --git a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt index f0212b467..c0209338c 100644 --- a/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt +++ b/kmath-multik/src/commonMain/kotlin/space/kscience/kmath/multik/MultikTensorAlgebra.kt @@ -251,7 +251,12 @@ public abstract class MultikTensorAlgebra<T, A : Ring<T>>( TODO("Not implemented for broadcasting") } - override fun diagonalEmbedding(diagonalEntries: StructureND<T>, offset: Int, dim1: Int, dim2: Int): MultikTensor<T> { + override fun diagonalEmbedding( + diagonalEntries: StructureND<T>, + offset: Int, + dim1: Int, + dim2: Int, + ): MultikTensor<T> { TODO("Diagonal embedding not implemented") } diff --git a/kmath-nd4j/README.md b/kmath-nd4j/README.md index 55d6844bc..393a2a3e4 100644 --- a/kmath-nd4j/README.md +++ b/kmath-nd4j/README.md @@ -2,16 +2,16 @@ ND4J based implementations of KMath abstractions. - - [nd4jarraystructure](#) : NDStructure wrapper for INDArray - - [nd4jarrayrings](#) : Rings over Nd4jArrayStructure of Int and Long - - [nd4jarrayfields](#) : Fields over Nd4jArrayStructure of Float and Double - +- [nd4jarraystructure](#) : NDStructure wrapper for INDArray +- [nd4jarrayrings](#) : Rings over Nd4jArrayStructure of Int and Long +- [nd4jarrayfields](#) : Fields over Nd4jArrayStructure of Float and Double ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt index cf0ec11c3..648e5e318 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebra.kt @@ -225,7 +225,8 @@ public open class DoubleNd4jArrayFieldOps : Nd4jArrayExtendedFieldOps<Double, Fl public val Float64Field.nd4j: DoubleNd4jArrayFieldOps get() = DoubleNd4jArrayFieldOps -public class DoubleNd4jArrayField(override val shape: ShapeND) : DoubleNd4jArrayFieldOps(), FieldND<Double, Float64Field> +public class DoubleNd4jArrayField(override val shape: ShapeND) : DoubleNd4jArrayFieldOps(), + FieldND<Double, Float64Field> public fun Float64Field.nd4j(shapeFirst: Int, vararg shapeRest: Int): DoubleNd4jArrayField = DoubleNd4jArrayField(ShapeND(shapeFirst, * shapeRest)) diff --git a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt index c69e46292..095715070 100644 --- a/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt +++ b/kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/Nd4jTensorAlgebra.kt @@ -144,7 +144,9 @@ public sealed interface Nd4jTensorAlgebra<T : Number, A : Field<T>> : AnalyticTe override fun atanh(arg: StructureND<T>): Nd4jArrayStructure<T> = Transforms.atanh(arg.ndArray).wrap() override fun power(arg: StructureND<T>, pow: Number): StructureND<T> = Transforms.pow(arg.ndArray, pow).wrap() override fun ceil(arg: StructureND<T>): Nd4jArrayStructure<T> = Transforms.ceil(arg.ndArray).wrap() - override fun floor(structureND: StructureND<T>): Nd4jArrayStructure<T> = Transforms.floor(structureND.ndArray).wrap() + override fun floor(structureND: StructureND<T>): Nd4jArrayStructure<T> = + Transforms.floor(structureND.ndArray).wrap() + override fun std(structureND: StructureND<T>, dim: Int, keepDim: Boolean): Tensor<T> = structureND.ndArray.std(true, keepDim, dim).wrap() @@ -178,7 +180,10 @@ public object DoubleNd4jTensorAlgebra : Nd4jTensorAlgebra<Double, Float64Field> override fun INDArray.wrap(): Nd4jArrayStructure<Double> = asDoubleStructure() @OptIn(UnsafeKMathAPI::class) - override fun mutableStructureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): Nd4jArrayStructure<Double> { + override fun mutableStructureND( + shape: ShapeND, + initializer: Float64Field.(IntArray) -> Double, + ): Nd4jArrayStructure<Double> { val array: INDArray = Nd4j.zeros(*shape.asArray()) val indices = ColumnStrides(shape) indices.asSequence().forEach { index -> diff --git a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt index 704b28cd9..042dd72ac 100644 --- a/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt +++ b/kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/Nd4jArrayAlgebraTest.kt @@ -57,7 +57,7 @@ internal class Nd4jArrayAlgebraTest { } @Test - fun testSin() = Float64Field.nd4j{ + fun testSin() = Float64Field.nd4j { val initial = structureND(2, 2) { (i, j) -> if (i == j) PI / 2 else 0.0 } val transformed = sin(initial) val expected = structureND(2, 2) { (i, j) -> if (i == j) 1.0 else 0.0 } diff --git a/kmath-optimization/README.md b/kmath-optimization/README.md index 52a018a4e..e1e44fa4d 100644 --- a/kmath-optimization/README.md +++ b/kmath-optimization/README.md @@ -1,7 +1,5 @@ # Module kmath-optimization - - ## Usage ## Artifact: @@ -9,6 +7,7 @@ The Maven coordinates of this project are `space.kscience:kmath-optimization:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-optimization/build.gradle.kts b/kmath-optimization/build.gradle.kts index f908b127d..d69858339 100644 --- a/kmath-optimization/build.gradle.kts +++ b/kmath-optimization/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt index a891b0a7f..263576d77 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/FunctionOptimization.kt @@ -20,7 +20,7 @@ public enum class OptimizationDirection { MINIMIZE } -public object FunctionOptimizationTarget: OptimizationAttribute<OptimizationDirection> +public object FunctionOptimizationTarget : OptimizationAttribute<OptimizationDirection> public class FunctionOptimization<T>( public val expression: DifferentiableExpression<T>, @@ -47,7 +47,7 @@ public class FunctionOptimization<T>( return result } - override fun toString(): String = "FunctionOptimization(features=$attributes)" + override fun toString(): String = "FunctionOptimization(attributes=$attributes)" public companion object } @@ -76,7 +76,7 @@ public suspend fun <T> DifferentiableExpression<T>.optimizeWith( startingPoint: Map<Symbol, T>, modifier: AttributesBuilder<FunctionOptimization<T>>.() -> Unit = {}, ): FunctionOptimization<T> { - val problem = FunctionOptimization(this){ + val problem = FunctionOptimization(this) { startAt(startingPoint) modifier() } diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt index b9530f83c..2ba80251b 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/OptimizationProblem.kt @@ -35,7 +35,7 @@ public class OptimizationCovariance<T> : OptimizationAttribute<NamedMatrix<T>>, PolymorphicAttribute<NamedMatrix<T>>(safeTypeOf()) public fun <T> AttributesBuilder<OptimizationProblem<T>>.covariance(covariance: NamedMatrix<T>) { - set(OptimizationCovariance(),covariance) + set(OptimizationCovariance(), covariance) } diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt index eba637a83..07fa97efb 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/QowOptimizer.kt @@ -16,7 +16,7 @@ import space.kscience.kmath.structures.Float64Buffer import kotlin.math.abs -public object QowRuns: OptimizationAttribute<Int> +public object QowRuns : OptimizationAttribute<Int> /** diff --git a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt index 98ec198da..a3ccbfab4 100644 --- a/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt +++ b/kmath-optimization/src/commonMain/kotlin/space/kscience/kmath/optimization/logLikelihood.kt @@ -64,7 +64,7 @@ public suspend fun Optimizer<Double, FunctionOptimization<Double>>.maximumLogLik FunctionOptimizationTarget(OptimizationDirection.MAXIMIZE) } ) - return XYFit(problem.data,problem.model, result.attributes) + return XYFit(problem.data, problem.model, result.attributes) } @UnstableKMathAPI diff --git a/kmath-optimization/src/commonMain/tmp/QowFit.kt b/kmath-optimization/src/commonMain/tmp/QowFit.kt index c78aef401..493ef8d12 100644 --- a/kmath-optimization/src/commonMain/tmp/QowFit.kt +++ b/kmath-optimization/src/commonMain/tmp/QowFit.kt @@ -319,10 +319,12 @@ public class QowFit( * generateErrors. */ private fun generateErrors(): Matrix<Double> { - logger?.log { """ + logger?.log { + """ Starting errors estimation using quasioptimal weights method. The starting weight is: ${curWeight.theta} - """.trimIndent()} + """.trimIndent() + } val curWeight = QoWeight(startingPoint) val covar = getCovariance(curWeight) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/CombinedMinimumBuilder.kt b/kmath-optimization/src/commonMain/tmp/minuit/CombinedMinimumBuilder.kt index 8c5452575..7cade49dc 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/CombinedMinimumBuilder.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/CombinedMinimumBuilder.kt @@ -33,7 +33,7 @@ internal class CombinedMinimumBuilder : MinimumBuilder { seed: MinimumSeed?, strategy: MnStrategy?, maxfcn: Int, - toler: Double + toler: Double, ): FunctionMinimum { val min: FunctionMinimum = theVMMinimizer.minimize(fcn!!, gc, seed, strategy, maxfcn, toler) if (!min.isValid()) { diff --git a/kmath-optimization/src/commonMain/tmp/minuit/ContoursError.kt b/kmath-optimization/src/commonMain/tmp/minuit/ContoursError.kt index 214d94c80..a9dcf652a 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/ContoursError.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/ContoursError.kt @@ -28,7 +28,7 @@ class ContoursError internal constructor( points: List<Range>, xmnos: MinosError, ymnos: MinosError, - nfcn: Int + nfcn: Int, ) { private val theNFcn: Int private val thePoints: List<Range> = points diff --git a/kmath-optimization/src/commonMain/tmp/minuit/DavidonErrorUpdator.kt b/kmath-optimization/src/commonMain/tmp/minuit/DavidonErrorUpdator.kt index 9eb2443e4..7fde0346c 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/DavidonErrorUpdator.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/DavidonErrorUpdator.kt @@ -34,8 +34,10 @@ internal class DavidonErrorUpdator : MinimumErrorUpdator { var Vupd: MnAlgebraicSymMatrix = MnUtils.sub(MnUtils.div(MnUtils.outerProduct(dx), delgam), MnUtils.div(MnUtils.outerProduct(vg), gvg)) if (delgam > gvg) { - Vupd = MnUtils.add(Vupd, - MnUtils.mul(MnUtils.outerProduct(MnUtils.sub(MnUtils.div(dx, delgam), MnUtils.div(vg, gvg))), gvg)) + Vupd = MnUtils.add( + Vupd, + MnUtils.mul(MnUtils.outerProduct(MnUtils.sub(MnUtils.div(dx, delgam), MnUtils.div(vg, gvg))), gvg) + ) } val sum_upd: Double = MnUtils.absoluteSumOfElements(Vupd) Vupd = MnUtils.add(Vupd, V0) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/FunctionMinimum.kt b/kmath-optimization/src/commonMain/tmp/minuit/FunctionMinimum.kt index e43523291..5ffc72e43 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/FunctionMinimum.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/FunctionMinimum.kt @@ -46,11 +46,15 @@ class FunctionMinimum { internal constructor(seed: MinimumSeed, up: Double) { theSeed = seed theStates = ArrayList() - theStates.add(MinimumState(seed.parameters(), - seed.error(), - seed.gradient(), - seed.parameters().fval(), - seed.nfcn())) + theStates.add( + MinimumState( + seed.parameters(), + seed.error(), + seed.gradient(), + seed.parameters().fval(), + seed.nfcn() + ) + ) theErrorDef = up theUserState = MnUserParameterState() } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MINUITFitter.kt b/kmath-optimization/src/commonMain/tmp/minuit/MINUITFitter.kt index a26321249..3838fa8af 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MINUITFitter.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MINUITFitter.kt @@ -97,6 +97,7 @@ class MINUITFitter : Fitter { when (method) { MINUIT_MINOS, MINUIT_MINIMIZE -> minuit = MnMinimize(fcn, MINUITUtils.getFitParameters(pars, fitPars), strategy) + MINUIT_SIMPLEX -> minuit = MnSimplex(fcn, MINUITUtils.getFitParameters(pars, fitPars), strategy) else -> minuit = MnMigrad(fcn, MINUITUtils.getFitParameters(pars, fitPars), strategy) } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MINUITPlugin.kt b/kmath-optimization/src/commonMain/tmp/minuit/MINUITPlugin.kt index 7eaefd9d2..4fc5822ce 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MINUITPlugin.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MINUITPlugin.kt @@ -13,10 +13,12 @@ import hep.dataforge.context.* * @author Darksnake * @version $Id: $Id */ -@PluginDef(group = "hep.dataforge", +@PluginDef( + group = "hep.dataforge", name = "MINUIT", dependsOn = ["hep.dataforge:fitting"], - info = "The MINUIT fitter engine for DataForge fitting") + info = "The MINUIT fitter engine for DataForge fitting" +) class MINUITPlugin : BasicPlugin() { fun attach(@NotNull context: Context?) { super.attach(context) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MinimumBuilder.kt b/kmath-optimization/src/commonMain/tmp/minuit/MinimumBuilder.kt index 7d918c339..8876c9575 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MinimumBuilder.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MinimumBuilder.kt @@ -40,6 +40,6 @@ interface MinimumBuilder { seed: MinimumSeed?, strategy: MnStrategy?, maxfcn: Int, - toler: Double + toler: Double, ): FunctionMinimum } \ No newline at end of file diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnApplication.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnApplication.kt index 025eea4ae..45944ac85 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnApplication.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnApplication.kt @@ -254,14 +254,16 @@ abstract class MnApplication { if (maxfcn == 0) { maxfcn = 200 + 100 * npar + 5 * npar * npar } - val min: FunctionMinimum = minimizer().minimize(theFCN, + val min: FunctionMinimum = minimizer().minimize( + theFCN, theState, theStrategy, maxfcn, toler, theErrorDef, useAnalyticalDerivatives, - checkAnalyticalDerivatives) + checkAnalyticalDerivatives + ) theNumCall += min.nfcn() theState = min.userState() return min diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnContours.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnContours.kt index 1b700f4e2..39eda5877 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnContours.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnContours.kt @@ -113,9 +113,11 @@ class MnContours(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) return ContoursError(px, py, result, mex, mey, nfcn) } val ey: Range = mey.range() - val migrad = MnMigrad(theFCN, + val migrad = MnMigrad( + theFCN, theMinimum!!.userState().copy(), - MnStrategy(max(0, theStrategy!!.strategy() - 1))) + MnStrategy(max(0, theStrategy!!.strategy() - 1)) + ) migrad.fix(px) migrad.setValue(px, valx + ex.getSecond()) val exy_up: FunctionMinimum = migrad.minimize() @@ -131,9 +133,11 @@ class MnContours(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) MINUITPlugin.logStatic("MnContours is unable to find lower y value for x parameter $px.") return ContoursError(px, py, result, mex, mey, nfcn) } - val migrad1 = MnMigrad(theFCN, + val migrad1 = MnMigrad( + theFCN, theMinimum!!.userState().copy(), - MnStrategy(max(0, theStrategy!!.strategy() - 1))) + MnStrategy(max(0, theStrategy!!.strategy() - 1)) + ) migrad1.fix(py) migrad1.setValue(py, valy + ey.getSecond()) val eyx_up: FunctionMinimum = migrad1.minimize() diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnFunctionCross.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnFunctionCross.kt index a05590e53..da1bed482 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnFunctionCross.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnFunctionCross.kt @@ -28,7 +28,7 @@ internal class MnFunctionCross( state: MnUserParameterState, fval: Double, stra: MnStrategy?, - errorDef: Double + errorDef: Double, ) { private val theErrorDef: Double private val theFCN: MultiFunction? @@ -249,10 +249,13 @@ internal class MnFunctionCross( } } do { - val parbol: MnParabola = MnParabolaFactory.create(MnParabolaPoint(alsb[0], flsb[0]), + val parbol: MnParabola = MnParabolaFactory.create( + MnParabolaPoint(alsb[0], flsb[0]), MnParabolaPoint(alsb[1], flsb[1]), MnParabolaPoint( - alsb[2], flsb[2])) + alsb[2], flsb[2] + ) + ) val coeff1: Double = parbol.c() val coeff2: Double = parbol.b() val coeff3: Double = parbol.a() diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnHesse.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnHesse.kt index 3bb6c4551..998324ad8 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnHesse.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnHesse.kt @@ -161,7 +161,7 @@ class MnHesse { fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, - maxcalls: Int + maxcalls: Int, ): MnUserParameterState { return calculate(fcn, MnUserParameterState(par, cov), maxcalls) } @@ -186,10 +186,12 @@ class MnHesse { val gc = Numerical2PGradientCalculator(mfcn, state.getTransformation(), theStrategy) val par = MinimumParameters(x, amin) val gra: FunctionGradient = gc.gradient(par) - val tmp: MinimumState = calculate(mfcn, + val tmp: MinimumState = calculate( + mfcn, MinimumState(par, MinimumError(MnAlgebraicSymMatrix(n), 1.0), gra, state.edm(), state.nfcn()), state.getTransformation(), - maxcalls) + maxcalls + ) return MnUserParameterState(tmp, errDef, state.getTransformation()) } @@ -326,11 +328,13 @@ class MnHesse { MINUITPlugin.logStatic("MnHesse: matrix is invalid!") MINUITPlugin.logStatic("MnHesse: matrix is not pos. def.!") MINUITPlugin.logStatic("MnHesse: matrix was forced pos. def.") - return MinimumState(st.parameters(), + return MinimumState( + st.parameters(), MinimumError(vhmat, MnMadePosDef()), gr, st.edm(), - mfcn.numOfCalls()) + mfcn.numOfCalls() + ) } //calculate edm @@ -346,11 +350,13 @@ class MnHesse { vhmat[j, j] = if (tmp < prec.eps2()) 1.0 else tmp j++ } - MinimumState(st.parameters(), + MinimumState( + st.parameters(), MinimumError(vhmat, MnHesseFailed()), st.gradient(), st.edm(), - st.nfcn() + mfcn.numOfCalls()) + st.nfcn() + mfcn.numOfCalls() + ) } } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnLineSearch.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnLineSearch.kt index 7b1171d3c..6d42ad6ac 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnLineSearch.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnLineSearch.kt @@ -28,7 +28,7 @@ internal object MnLineSearch { st: MinimumParameters, step: RealVector, gdel: Double, - prec: MnMachinePrecision + prec: MnMachinePrecision, ): MnParabolaPoint { var overal = 1000.0 var undral = -100.0 @@ -154,7 +154,8 @@ internal object MnLineSearch { val toler9: Double = max(toler8, abs(toler8 * slam)) // min. of parabola at one point if (abs(p0.x() - slam) < toler9 || abs(p1.x() - slam) < toler9 || abs( - p2.x() - slam) < toler9 + p2.x() - slam + ) < toler9 ) { return MnParabolaPoint(xvmin, fvmin) } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnMigrad.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnMigrad.kt index 22616a1a6..2c0b85561 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnMigrad.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnMigrad.kt @@ -58,9 +58,11 @@ class MnMigrad * @param fcn a [MultiFunction] object. * @param par an array of double. */ - constructor(fcn: MultiFunction?, par: DoubleArray, err: DoubleArray, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: DoubleArray, err: DoubleArray, stra: Int) : this( + fcn, MnUserParameterState(par, err), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + double[] for parameters and @@ -81,9 +83,11 @@ class MnMigrad * @param fcn a [MultiFunction] object. * @param par an array of double. */ - constructor(fcn: MultiFunction?, par: DoubleArray, cov: MnUserCovariance, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: DoubleArray, cov: MnUserCovariance, stra: Int) : this( + fcn, MnUserParameterState(par, cov), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + MnUserParameters with default @@ -101,9 +105,11 @@ class MnMigrad * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. * @param fcn a [MultiFunction] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, stra: Int) : this( + fcn, MnUserParameterState(par), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + MnUserParameters + MnUserCovariance @@ -113,10 +119,12 @@ class MnMigrad * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. * @param fcn a [MultiFunction] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance) : this( + fcn, par, cov, - DEFAULT_STRATEGY) + DEFAULT_STRATEGY + ) /** * construct from MultiFunction + MnUserParameters + MnUserCovariance @@ -126,9 +134,11 @@ class MnMigrad * @param fcn a [MultiFunction] object. * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, stra: Int) : this( + fcn, MnUserParameterState(par, cov), - MnStrategy(stra)) + MnStrategy(stra) + ) override fun minimizer(): ModularFunctionMinimizer { return theMinimizer diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnMinimize.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnMinimize.kt index ea14a5453..dfafebba8 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnMinimize.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnMinimize.kt @@ -55,9 +55,11 @@ class MnMinimize * @param fcn a [MultiFunction] object. * @param par an array of double. */ - constructor(fcn: MultiFunction?, par: DoubleArray, err: DoubleArray, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: DoubleArray, err: DoubleArray, stra: Int) : this( + fcn, MnUserParameterState(par, err), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + double[] for parameters and @@ -78,9 +80,11 @@ class MnMinimize * @param fcn a [MultiFunction] object. * @param par an array of double. */ - constructor(fcn: MultiFunction?, par: DoubleArray, cov: MnUserCovariance, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: DoubleArray, cov: MnUserCovariance, stra: Int) : this( + fcn, MnUserParameterState(par, cov), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + MnUserParameters with default @@ -98,9 +102,11 @@ class MnMinimize * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. * @param fcn a [MultiFunction] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, stra: Int) : this( + fcn, MnUserParameterState(par), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + MnUserParameters + MnUserCovariance @@ -110,10 +116,12 @@ class MnMinimize * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. * @param fcn a [MultiFunction] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance) : this( + fcn, par, cov, - DEFAULT_STRATEGY) + DEFAULT_STRATEGY + ) /** * construct from MultiFunction + MnUserParameters + MnUserCovariance @@ -123,9 +131,11 @@ class MnMinimize * @param fcn a [MultiFunction] object. * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, stra: Int) : this( + fcn, MnUserParameterState(par, cov), - MnStrategy(stra)) + MnStrategy(stra) + ) override fun minimizer(): ModularFunctionMinimizer { return theMinimizer diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnPrint.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnPrint.kt index ce018c2a4..6c888f1d0 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnPrint.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnPrint.kt @@ -294,12 +294,14 @@ object MnPrint { os.println(me.upperState()) } os.println("# ext. || name || value@min || negative || positive ") - os.printf("%4d||%10s||%10g||%10g||%10g\n", + os.printf( + "%4d||%10s||%10g||%10g||%10g\n", me.parameter(), me.lowerState().name(me.parameter()), me.min(), me.lower(), - me.upper()) + me.upper() + ) os.println() } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnScan.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnScan.kt index 63e565b4f..cd253778b 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnScan.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnScan.kt @@ -51,9 +51,11 @@ class MnScan(fcn: MultiFunction?, par: MnUserParameterState, str: MnStrategy) : * @param fcn a [MultiFunction] object. * @param par an array of double. */ - constructor(fcn: MultiFunction?, par: DoubleArray, err: DoubleArray, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: DoubleArray, err: DoubleArray, stra: Int) : this( + fcn, MnUserParameterState(par, err), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + double[] for parameters and @@ -74,9 +76,11 @@ class MnScan(fcn: MultiFunction?, par: MnUserParameterState, str: MnStrategy) : * @param fcn a [MultiFunction] object. * @param par an array of double. */ - constructor(fcn: MultiFunction?, par: DoubleArray, cov: MnUserCovariance, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: DoubleArray, cov: MnUserCovariance, stra: Int) : this( + fcn, MnUserParameterState(par, cov), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + MnUserParameters with default @@ -94,9 +98,11 @@ class MnScan(fcn: MultiFunction?, par: MnUserParameterState, str: MnStrategy) : * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. * @param fcn a [MultiFunction] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, stra: Int) : this( + fcn, MnUserParameterState(par), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + MnUserParameters + MnUserCovariance @@ -106,10 +112,12 @@ class MnScan(fcn: MultiFunction?, par: MnUserParameterState, str: MnStrategy) : * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. * @param fcn a [MultiFunction] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance) : this( + fcn, par, cov, - DEFAULT_STRATEGY) + DEFAULT_STRATEGY + ) /** * construct from MultiFunction + MnUserParameters + MnUserCovariance @@ -119,9 +127,11 @@ class MnScan(fcn: MultiFunction?, par: MnUserParameterState, str: MnStrategy) : * @param fcn a [MultiFunction] object. * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, stra: Int) : this( + fcn, MnUserParameterState(par, cov), - MnStrategy(stra)) + MnStrategy(stra) + ) override fun minimizer(): ModularFunctionMinimizer { return theMinimizer diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnSeedGenerator.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnSeedGenerator.kt index a42edf4f1..4dcf89c7c 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnSeedGenerator.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnSeedGenerator.kt @@ -51,10 +51,12 @@ internal class MnSeedGenerator : MinimumSeedGenerator { val calculated: Double = hgrd.getFirst().getGradient().getEntry(i) val delta: Double = hgrd.getSecond().getEntry(i) if (abs(calculated - provided) > delta) { - MINUITPlugin.logStatic("" - + "gradient discrepancy of external parameter \"%d\" " - + "(internal parameter \"%d\") too large. Expected: \"%f\", provided: \"%f\"", - st.getTransformation().extOfInt(i), i, provided, calculated) + MINUITPlugin.logStatic( + "" + + "gradient discrepancy of external parameter \"%d\" " + + "(internal parameter \"%d\") too large. Expected: \"%f\", provided: \"%f\"", + st.getTransformation().extOfInt(i), i, provided, calculated + ) // // MINUITPlugin.logStatic("gradient discrepancy of external parameter " @@ -82,8 +84,10 @@ internal class MnSeedGenerator : MinimumSeedGenerator { dcovar = 0.0 } else { for (i in 0 until n) { - mat[i, i] = if (abs(dgrad.getGradientDerivative() - .getEntry(i)) > prec.eps2() + mat[i, i] = if (abs( + dgrad.getGradientDerivative() + .getEntry(i) + ) > prec.eps2() ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 } } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnSimplex.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnSimplex.kt index b00745f26..ef617f0a1 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnSimplex.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnSimplex.kt @@ -59,9 +59,11 @@ class MnSimplex * @param fcn a [MultiFunction] object. * @param par an array of double. */ - constructor(fcn: MultiFunction?, par: DoubleArray, err: DoubleArray, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: DoubleArray, err: DoubleArray, stra: Int) : this( + fcn, MnUserParameterState(par, err), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + double[] for parameters and @@ -82,9 +84,11 @@ class MnSimplex * @param fcn a [MultiFunction] object. * @param par an array of double. */ - constructor(fcn: MultiFunction?, par: DoubleArray, cov: MnUserCovariance, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: DoubleArray, cov: MnUserCovariance, stra: Int) : this( + fcn, MnUserParameterState(par, cov), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + MnUserParameters with default @@ -102,9 +106,11 @@ class MnSimplex * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. * @param fcn a [MultiFunction] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, stra: Int) : this( + fcn, MnUserParameterState(par), - MnStrategy(stra)) + MnStrategy(stra) + ) /** * construct from MultiFunction + MnUserParameters + MnUserCovariance @@ -114,10 +120,12 @@ class MnSimplex * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. * @param fcn a [MultiFunction] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance) : this( + fcn, par, cov, - DEFAULT_STRATEGY) + DEFAULT_STRATEGY + ) /** * construct from MultiFunction + MnUserParameters + MnUserCovariance @@ -127,9 +135,11 @@ class MnSimplex * @param fcn a [MultiFunction] object. * @param par a [hep.dataforge.MINUIT.MnUserParameters] object. */ - constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, stra: Int) : this(fcn, + constructor(fcn: MultiFunction?, par: MnUserParameters, cov: MnUserCovariance, stra: Int) : this( + fcn, MnUserParameterState(par, cov), - MnStrategy(stra)) + MnStrategy(stra) + ) /** {@inheritDoc} */ override fun minimizer(): ModularFunctionMinimizer { diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameterState.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameterState.kt index e80dd60a1..0dd2d8ae9 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameterState.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameterState.kt @@ -194,10 +194,14 @@ class MnUserParameterState { fix(ipar.name()) } else if (ipar.hasLimits()) { val i: Int = trafo.intOfExt(ipar.number()) - val err: Double = if (st.hasCovariance()) sqrt(2.0 * up * st.error().invHessian()[i, i]) else st.parameters().dirin().getEntry(i) - add(ipar.name(), + val err: Double = + if (st.hasCovariance()) sqrt(2.0 * up * st.error().invHessian()[i, i]) else st.parameters().dirin() + .getEntry(i) + add( + ipar.name(), trafo.int2ext(i, st.vec().getEntry(i)), - trafo.int2extError(i, st.vec().getEntry(i), err)) + trafo.int2extError(i, st.vec().getEntry(i), err) + ) if (ipar.hasLowerLimit() && ipar.hasUpperLimit()) { setLimits(ipar.name(), ipar.lowerLimit(), ipar.upperLimit()) } else if (ipar.hasLowerLimit() && !ipar.hasUpperLimit()) { @@ -207,7 +211,9 @@ class MnUserParameterState { } } else { val i: Int = trafo.intOfExt(ipar.number()) - val err: Double = if (st.hasCovariance()) sqrt(2.0 * up * st.error().invHessian()[i, i]) else st.parameters().dirin().getEntry(i) + val err: Double = + if (st.hasCovariance()) sqrt(2.0 * up * st.error().invHessian()[i, i]) else st.parameters().dirin() + .getEntry(i) add(ipar.name(), st.vec().getEntry(i), err) } } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnUserTransformation.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnUserTransformation.kt index 1066ac2da..c587d3244 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnUserTransformation.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnUserTransformation.kt @@ -112,9 +112,11 @@ class MnUserTransformation { val parm: MinuitParameter = theParameters[theExtOfInt[i]] if (parm.hasLimits()) { dd = if (parm.hasUpperLimit() && parm.hasLowerLimit()) { - theDoubleLimTrafo.dInt2Ext(`val`, + theDoubleLimTrafo.dInt2Ext( + `val`, parm.upperLimit(), - parm.lowerLimit()) + parm.lowerLimit() + ) } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { theUpperLimTrafo.dInt2Ext(`val`, parm.upperLimit()) } else { @@ -145,18 +147,24 @@ class MnUserTransformation { val parm: MinuitParameter = theParameters[i] return if (parm.hasLimits()) { if (parm.hasUpperLimit() && parm.hasLowerLimit()) { - theDoubleLimTrafo.ext2int(`val`, + theDoubleLimTrafo.ext2int( + `val`, parm.upperLimit(), parm.lowerLimit(), - precision()) + precision() + ) } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { - theUpperLimTrafo.ext2int(`val`, + theUpperLimTrafo.ext2int( + `val`, parm.upperLimit(), - precision()) + precision() + ) } else { - theLowerLimTrafo.ext2int(`val`, + theLowerLimTrafo.ext2int( + `val`, parm.lowerLimit(), - precision()) + precision() + ) } } else `val` } @@ -196,9 +204,11 @@ class MnUserTransformation { val parm: MinuitParameter = theParameters[theExtOfInt[i]] return if (parm.hasLimits()) { if (parm.hasUpperLimit() && parm.hasLowerLimit()) { - theDoubleLimTrafo.int2ext(`val`, + theDoubleLimTrafo.int2ext( + `val`, parm.upperLimit(), - parm.lowerLimit()) + parm.lowerLimit() + ) } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { theUpperLimTrafo.int2ext(`val`, parm.upperLimit()) } else { diff --git a/kmath-optimization/src/commonMain/tmp/minuit/ModularFunctionMinimizer.kt b/kmath-optimization/src/commonMain/tmp/minuit/ModularFunctionMinimizer.kt index 84130d24f..cb61e5b03 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/ModularFunctionMinimizer.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/ModularFunctionMinimizer.kt @@ -33,7 +33,7 @@ abstract class ModularFunctionMinimizer { toler: Double, errorDef: Double, useAnalyticalGradient: Boolean, - checkGradient: Boolean + checkGradient: Boolean, ): FunctionMinimum { var maxfcn = maxfcn val mfcn = MnUserFcn(fcn, errorDef, st.getTransformation()) @@ -64,7 +64,7 @@ abstract class ModularFunctionMinimizer { seed: MinimumSeed?, strategy: MnStrategy?, maxfcn: Int, - toler: Double + toler: Double, ): FunctionMinimum { return builder().minimum(mfcn, gc, seed, strategy, maxfcn, toler * mfcn.errorDef()) } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/NegativeG2LineSearch.kt b/kmath-optimization/src/commonMain/tmp/minuit/NegativeG2LineSearch.kt index 2e9ce5813..50266f45c 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/NegativeG2LineSearch.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/NegativeG2LineSearch.kt @@ -54,8 +54,10 @@ internal object NegativeG2LineSearch { var step: RealVector = ArrayRealVector(n) step.setEntry(i, dgrad.getStep().getEntry(i) * dgrad.getGradient().getEntry(i)) if (abs(dgrad.getGradient().getEntry(i)) > prec.eps2()) { - step.setEntry(i, - step.getEntry(i) * (-1.0 / abs(dgrad.getGradient().getEntry(i)))) + step.setEntry( + i, + step.getEntry(i) * (-1.0 / abs(dgrad.getGradient().getEntry(i))) + ) } val gdel: Double = step.getEntry(i) * dgrad.getGradient().getEntry(i) val pp: MnParabolaPoint = MnLineSearch.search(fcn, pa, step, gdel, prec) @@ -69,8 +71,10 @@ internal object NegativeG2LineSearch { } while (iter++ < 2 * n && iterate) val mat = MnAlgebraicSymMatrix(n) for (i in 0 until n) { - mat[i, i] = if (abs(dgrad.getGradientDerivative() - .getEntry(i)) > prec.eps2() + mat[i, i] = if (abs( + dgrad.getGradientDerivative() + .getEntry(i) + ) > prec.eps2() ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 } val err = MinimumError(mat, 1.0) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/ScanBuilder.kt b/kmath-optimization/src/commonMain/tmp/minuit/ScanBuilder.kt index 57f910a26..254281beb 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/ScanBuilder.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/ScanBuilder.kt @@ -33,7 +33,7 @@ internal class ScanBuilder : MinimumBuilder { seed: MinimumSeed, stra: MnStrategy?, maxfcn: Int, - toler: Double + toler: Double, ): FunctionMinimum { val x: RealVector = seed.parameters().vec().copy() val upst = MnUserParameterState(seed.state(), mfcn.errorDef(), seed.trafo()) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/SimplexBuilder.kt b/kmath-optimization/src/commonMain/tmp/minuit/SimplexBuilder.kt index 0b10155ff..08c4f40d0 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/SimplexBuilder.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/SimplexBuilder.kt @@ -31,7 +31,7 @@ internal class SimplexBuilder : MinimumBuilder { seed: MinimumSeed, strategy: MnStrategy?, maxfcn: Int, - minedm: Double + minedm: Double, ): FunctionMinimum { val prec: MnMachinePrecision = seed.precision() val x: RealVector = seed.parameters().vec().copy() diff --git a/kmath-optimization/src/commonMain/tmp/minuit/SimplexSeedGenerator.kt b/kmath-optimization/src/commonMain/tmp/minuit/SimplexSeedGenerator.kt index 577545fc3..5423820f6 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/SimplexSeedGenerator.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/SimplexSeedGenerator.kt @@ -41,8 +41,10 @@ internal class SimplexSeedGenerator : MinimumSeedGenerator { val mat = MnAlgebraicSymMatrix(n) val dcovar = 1.0 for (i in 0 until n) { - mat[i, i] = if (abs(dgrad.getGradientDerivative() - .getEntry(i)) > prec.eps2() + mat[i, i] = if (abs( + dgrad.getGradientDerivative() + .getEntry(i) + ) > prec.eps2() ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 } val err = MinimumError(mat, dcovar) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/VariableMetricBuilder.kt b/kmath-optimization/src/commonMain/tmp/minuit/VariableMetricBuilder.kt index edc6783b6..a9e4faa36 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/VariableMetricBuilder.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/VariableMetricBuilder.kt @@ -41,7 +41,7 @@ internal class VariableMetricBuilder : MinimumBuilder { seed: MinimumSeed, strategy: MnStrategy, maxfcn: Int, - edmval: Double + edmval: Double, ): FunctionMinimum { val min: FunctionMinimum = minimum(fcn, gc, seed, maxfcn, edmval) if (strategy.strategy() === 2 || strategy.strategy() === 1 && min.error().dcovar() > 0.05) { diff --git a/kmath-stat/README.md b/kmath-stat/README.md index 55ef0f693..8de601893 100644 --- a/kmath-stat/README.md +++ b/kmath-stat/README.md @@ -1,7 +1,5 @@ # Module kmath-stat - - ## Usage ## Artifact: @@ -9,6 +7,7 @@ The Maven coordinates of this project are `space.kscience:kmath-stat:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-stat/build.gradle.kts b/kmath-stat/build.gradle.kts index 7d396b460..8116a8925 100644 --- a/kmath-stat/build.gradle.kts +++ b/kmath-stat/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt index f2a1bbfe8..f425c6285 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/distributions/NormalDistribution.kt @@ -6,11 +6,12 @@ package space.kscience.kmath.distributions import space.kscience.kmath.chains.BlockingDoubleChain -import space.kscience.kmath.chains.Chain import space.kscience.kmath.operations.Float64Field.pow import space.kscience.kmath.random.RandomGenerator -import space.kscience.kmath.samplers.* +import space.kscience.kmath.samplers.GaussianSampler import space.kscience.kmath.samplers.InternalErf +import space.kscience.kmath.samplers.NormalizedGaussianSampler +import space.kscience.kmath.samplers.ZigguratNormalizedGaussianSampler import kotlin.math.* /** diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt index 5d175c5ae..34a92efe1 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/random/RandomChain.kt @@ -25,7 +25,8 @@ public class RandomChain<out R>( /** * Create a generic random chain with provided [generator] */ -public fun <R> RandomGenerator.chain(generator: suspend RandomGenerator.() -> R): RandomChain<R> = RandomChain(this, generator) +public fun <R> RandomGenerator.chain(generator: suspend RandomGenerator.() -> R): RandomChain<R> = + RandomChain(this, generator) /** * A type-specific double chunk random chain diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalGamma.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalGamma.kt index ef4a97066..08fefe322 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalGamma.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/InternalGamma.kt @@ -123,7 +123,7 @@ internal object InternalGamma { private fun regularizedGammaP( a: Double, x: Double, - maxIterations: Int = Int.MAX_VALUE + maxIterations: Int = Int.MAX_VALUE, ): Double = when { a.isNaN() || x.isNaN() || a <= 0.0 || x < 0.0 -> Double.NaN x == 0.0 -> 0.0 @@ -155,7 +155,7 @@ internal object InternalGamma { fun regularizedGammaQ( a: Double, x: Double, - maxIterations: Int = Int.MAX_VALUE + maxIterations: Int = Int.MAX_VALUE, ): Double = when { a.isNaN() || x.isNaN() || a <= 0.0 || x < 0.0 -> Double.NaN x == 0.0 -> 1.0 diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt index 146a3703f..44e099a52 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/samplers/Sampler.kt @@ -34,7 +34,7 @@ public fun interface Sampler<out T : Any> { public fun <T : Any> Sampler<T>.sampleBuffer( generator: RandomGenerator, size: Int, - bufferFactory: BufferFactory<T> + bufferFactory: BufferFactory<T>, ): Chain<Buffer<T>> { require(size > 1) //creating temporary storage once @@ -59,7 +59,7 @@ public suspend fun <T : Any> Sampler<T>.next(generator: RandomGenerator): T = sa * Generates [size] samples and chunks them into some buffers. */ @JvmName("sampleRealBuffer") -public inline fun <reified T:Any> Sampler<T>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<T>> = +public inline fun <reified T : Any> Sampler<T>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<T>> = sampleBuffer(generator, size, BufferFactory()) diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt index 6790f44e0..e47e4f69f 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/series/SeriesAlgebra.kt @@ -209,7 +209,7 @@ public open class SeriesAlgebra<T, out A : Ring<T>, out BA : BufferAlgebra<T, A> * */ public inline fun Buffer<T>.zipWithShift( shift: Int = 1, - crossinline operation: A.(left: T, right: T) -> T + crossinline operation: A.(left: T, right: T) -> T, ): Buffer<T> { val shifted = this.moveBy(shift) return zip(shifted, operation) @@ -221,7 +221,7 @@ public open class SeriesAlgebra<T, out A : Ring<T>, out BA : BufferAlgebra<T, A> override fun multiply(left: Buffer<T>, right: Buffer<T>): Buffer<T> = left.zip(right) { l, r -> l * r } - public fun Buffer<T>.difference(shift: Int=1): Buffer<T> = this.zipWithShift(shift) {l, r -> r - l} + public fun Buffer<T>.difference(shift: Int = 1): Buffer<T> = this.zipWithShift(shift) { l, r -> r - l } public companion object } diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt index 843b06f2c..846e95b18 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/Mean.kt @@ -13,7 +13,7 @@ import space.kscience.kmath.structures.indices * Arithmetic mean */ public class Mean<T>( - private val field: Field<T> + private val field: Field<T>, ) : ComposableStatistic<T, Pair<T, Int>, T>, BlockingStatistic<T, T> { override fun evaluateBlocking(data: Buffer<T>): T = with(field) { @@ -38,7 +38,7 @@ public class Mean<T>( with(field) { first.first + second.first } to (first.second + second.second) override suspend fun toResult(intermediate: Pair<T, Int>): T = with(field) { - intermediate.first/ intermediate.second + intermediate.first / intermediate.second } public companion object { diff --git a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt index 8f0aa1729..dc9a10661 100644 --- a/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt +++ b/kmath-stat/src/commonMain/kotlin/space/kscience/kmath/stat/ValueAndErrorField.kt @@ -85,7 +85,7 @@ public object ValueAndErrorField : Field<ValueAndError> { ): MutableBuffer<ValueAndError> { val values: DoubleArray = DoubleArray(size) val ds = DoubleArray(size) - repeat(size){ + repeat(size) { val (v, d) = builder(it) values[it] = v ds[it] = d diff --git a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestSeries.kt b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestSeries.kt index 68c5af6fb..461edcaf5 100644 --- a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestSeries.kt +++ b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestSeries.kt @@ -16,13 +16,13 @@ import kotlin.test.assertEquals class TestSeries { @Test - fun zip() = with(Double.algebra.bufferAlgebra.seriesAlgebra()){ + fun zip() = with(Double.algebra.bufferAlgebra.seriesAlgebra()) { val s1 = series(100) { sin(2 * PI * it / 100) + 1.0 } val s2 = s1.slice(20..50).moveTo(40) val s3: Buffer<Double> = s1.zip(s2) { l, r -> l + r } //s1 + s2 - assertEquals(s3.getByOffset(40),s1.getByOffset(40) + s1.getByOffset(20)) + assertEquals(s3.getByOffset(40), s1.getByOffset(40) + s1.getByOffset(20)) } } \ No newline at end of file diff --git a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestVarianceRatioTest.kt b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestVarianceRatioTest.kt index b5ac44bc6..1d34628c1 100644 --- a/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestVarianceRatioTest.kt +++ b/kmath-stat/src/commonTest/kotlin/space/kscience/kmath/series/TestVarianceRatioTest.kt @@ -32,7 +32,7 @@ class TestVarianceRatioTest { @Test fun volatileData() { with(Double.algebra.bufferAlgebra.seriesAlgebra()) { - val volatileData = series(10) { sin(PI * it + PI/2) + 1.0} + val volatileData = series(10) { sin(PI * it + PI / 2) + 1.0 } val resultHomo = varianceRatioTest(volatileData, 2) assertEquals(0.0, resultHomo.varianceRatio, 1e-6) // homoscedastic zScore @@ -48,7 +48,7 @@ class TestVarianceRatioTest { @Test fun negativeData() { with(Double.algebra.bufferAlgebra.seriesAlgebra()) { - val negativeData = series(10) { sin(it * 1.2)} + val negativeData = series(10) { sin(it * 1.2) } val resultHomo = varianceRatioTest(negativeData, 3) assertEquals(1.240031, resultHomo.varianceRatio, 1e-6) // homoscedastic zScore diff --git a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt index a95829eff..a58b84514 100644 --- a/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt +++ b/kmath-stat/src/jvmTest/kotlin/space/kscience/kmath/stat/MCScopeTest.kt @@ -21,7 +21,7 @@ internal class MCScopeTest { mcScope(1111) { val res = Collections.synchronizedSet(HashSet<RandomResult>()) - launch{ + launch { //println(random) repeat(10) { delay(10) diff --git a/kmath-symja/README.md b/kmath-symja/README.md index 250c0ae35..e1b1e2359 100644 --- a/kmath-symja/README.md +++ b/kmath-symja/README.md @@ -9,6 +9,7 @@ Symja integration module The Maven coordinates of this project are `space.kscience:kmath-symja:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-tensorflow/README.md b/kmath-tensorflow/README.md index 03666129d..51c49e853 100644 --- a/kmath-tensorflow/README.md +++ b/kmath-tensorflow/README.md @@ -9,6 +9,7 @@ Google tensorflow connector The Maven coordinates of this project are `space.kscience:kmath-tensorflow:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt b/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt index dd4f620c4..eefc39a11 100644 --- a/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt +++ b/kmath-tensorflow/src/test/kotlin/space/kscience/kmath/tensorflow/DoubleTensorFlowOps.kt @@ -30,7 +30,7 @@ class DoubleTensorFlowOps { } @Test - fun dot(){ + fun dot() { val dim = 1000 val tensor1 = DoubleTensorAlgebra.randomNormal(shape = ShapeND(dim, dim), 12224) @@ -42,14 +42,14 @@ class DoubleTensorFlowOps { } @Test - fun extensionOps(){ + fun extensionOps() { val res = Float64Field.produceWithTF { val i = structureND(2, 2) { 0.5 } sin(i).pow(2) + cos(i).pow(2) } - assertEquals(1.0, res[0,0],0.01) + assertEquals(1.0, res[0, 0], 0.01) } diff --git a/kmath-tensors/README.md b/kmath-tensors/README.md index 34cf33cb3..27ab26cbf 100644 --- a/kmath-tensors/README.md +++ b/kmath-tensors/README.md @@ -2,16 +2,19 @@ Common linear algebra operations on tensors. - - [tensor algebra](src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic linear algebra operations on tensors (plus, dot, etc.) - - [tensor algebra with broadcasting](src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : Basic linear algebra operations implemented with broadcasting. - - [linear algebra operations](src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc. - +- [tensor algebra](src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic linear algebra + operations on tensors (plus, dot, etc.) +- [tensor algebra with broadcasting](src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : + Basic linear algebra operations implemented with broadcasting. +- [linear algebra operations](src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : + Advanced linear algebra operations like LU decomposition, SVD, etc. ## Artifact: The Maven coordinates of this project are `space.kscience:kmath-tensors:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-tensors/build.gradle.kts b/kmath-tensors/build.gradle.kts index 82213f408..64b253044 100644 --- a/kmath-tensors/build.gradle.kts +++ b/kmath-tensors/build.gradle.kts @@ -2,11 +2,11 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js { browser { - testTask{ + testTask { useMocha().timeout = "0" } } @@ -29,8 +29,8 @@ kotlin.sourceSets { } } - commonTest{ - dependencies{ + commonTest { + dependencies { implementation(projects.testUtils) } } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/AnalyticTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/AnalyticTensorAlgebra.kt index a986edfa5..c8546094e 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/AnalyticTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/AnalyticTensorAlgebra.kt @@ -90,15 +90,15 @@ public interface AnalyticTensorAlgebra<T, A : Field<T>> : //For information: https://pytorch.org/docs/stable/generated/torch.floor.html#torch.floor public fun floor(structureND: StructureND<T>): Tensor<T> - override fun sin(arg: StructureND<T>): StructureND<T> + override fun sin(arg: StructureND<T>): StructureND<T> - override fun cos(arg: StructureND<T>): StructureND<T> + override fun cos(arg: StructureND<T>): StructureND<T> override fun asin(arg: StructureND<T>): StructureND<T> override fun acos(arg: StructureND<T>): StructureND<T> - override fun exp(arg: StructureND<T>): StructureND<T> + override fun exp(arg: StructureND<T>): StructureND<T> override fun ln(arg: StructureND<T>): StructureND<T> diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt index cea77f4ab..0024f41ad 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/DoubleTensorAlgebra.kt @@ -127,10 +127,11 @@ public open class DoubleTensorAlgebra : * @param initializer mapping tensor indices to values. * @return tensor with the [shape] shape and data generated by the [initializer]. */ - override fun mutableStructureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): DoubleTensor = fromArray( - shape, - RowStrides(shape).asSequence().map { Float64Field.initializer(it) }.toMutableList().toDoubleArray() - ) + override fun mutableStructureND(shape: ShapeND, initializer: Float64Field.(IntArray) -> Double): DoubleTensor = + fromArray( + shape, + RowStrides(shape).asSequence().map { Float64Field.initializer(it) }.toMutableList().toDoubleArray() + ) override fun Tensor<Double>.getTensor(i: Int): DoubleTensor { val dt = asDoubleTensor() @@ -713,7 +714,7 @@ public open class DoubleTensorAlgebra : override fun solve(a: MutableStructure2D<Double>, b: MutableStructure2D<Double>): MutableStructure2D<Double> { val aSvd = DoubleTensorAlgebra.svd(a) - val s = BroadcastDoubleTensorAlgebra.diagonalEmbedding(aSvd.second.map {1.0 / it}) + val s = BroadcastDoubleTensorAlgebra.diagonalEmbedding(aSvd.second.map { 1.0 / it }) val aInverse = aSvd.third.dot(s).dot(aSvd.first.transposed()) return aInverse.dot(b).as2D() } diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt index eaeb43fdc..e75564ef5 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/IntTensorAlgebra.kt @@ -252,7 +252,7 @@ public open class IntTensorAlgebra : TensorAlgebra<Int, Int32Ring> { override fun StructureND<Int>.transposed(i: Int, j: Int): Tensor<Int> { val actualI = if (i >= 0) i else shape.size + i - val actualJ = if(j>=0) j else shape.size + j + val actualJ = if (j >= 0) j else shape.size + j return asIntTensor().permute( shape.transposed(actualI, actualJ) ) { originIndex -> diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt index 3596cbaf8..df43a7e60 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/broadcastUtils.kt @@ -116,6 +116,7 @@ internal fun broadcastOuterTensors(vararg tensors: DoubleTensor): List<DoubleTen for (linearIndex in 0 until n) { val totalMultiIndex = outerTensor.indices.index(linearIndex) + @OptIn(UnsafeKMathAPI::class) var curMultiIndex = tensor.shape.slice(0..tensor.shape.size - 3).asArray() curMultiIndex = IntArray(totalMultiIndex.size - curMultiIndex.size) { 1 } + curMultiIndex diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt index 14ab35883..a28f73799 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/intTensorHelpers.kt @@ -51,7 +51,7 @@ internal fun IntTensor.vectorSequence(): Sequence<IntTensor> = vectors().asSeque internal val IntTensor.matrices: VirtualBuffer<IntTensor> - get(){ + get() { val n = shape.size check(n >= 2) { "Expected tensor with 2 or more dimensions, got size $n" } val matrixOffset = shape[n - 1] * shape[n - 2] diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt index 2a3ed87c9..239d1dd18 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/internal/linUtils.kt @@ -547,7 +547,7 @@ internal fun MutableStructure2D<Double>.svdGolubKahanHelper( h = rv1[k] f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y) g = pythag(f, 1.0) - f = ((x - z) * (x + z) + h * ((y / (f + if (f >= 0.0) abs(g) else -abs(g) )) - h)) / x + f = ((x - z) * (x + z) + h * ((y / (f + if (f >= 0.0) abs(g) else -abs(g))) - h)) / x c = 1.0 s = 1.0 diff --git a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt index 2c35f8196..9b31e5694 100644 --- a/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt +++ b/kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/tensorOps.kt @@ -214,7 +214,7 @@ public fun DoubleTensorAlgebra.svd( public fun DoubleTensorAlgebra.svdGolubKahan( structureND: StructureND<Double>, - iterations: Int = 30, epsilon: Double = 1e-10 + iterations: Int = 30, epsilon: Double = 1e-10, ): Triple<DoubleTensor, DoubleTensor, DoubleTensor> { val size = structureND.dimension val commonShape = structureND.shape.slice(0 until size - 2) @@ -235,8 +235,10 @@ public fun DoubleTensorAlgebra.svdGolubKahan( matrix.shape, matrix.source.view(0, matrixSize).copy() ) - curMatrix.as2D().svdGolubKahanHelper(uTensors[index].as2D(), sTensorVectors[index], vTensors[index].as2D(), - iterations, epsilon) + curMatrix.as2D().svdGolubKahanHelper( + uTensors[index].as2D(), sTensorVectors[index], vTensors[index].as2D(), + iterations, epsilon + ) } return Triple(uTensor, sTensor, vTensor) diff --git a/kmath-viktor/README.md b/kmath-viktor/README.md index 3b7b8152a..3d5ebd95c 100644 --- a/kmath-viktor/README.md +++ b/kmath-viktor/README.md @@ -9,6 +9,7 @@ Binding for https://github.com/JetBrains-Research/viktor The Maven coordinates of this project are `space.kscience:kmath-viktor:0.4.0-dev-3`. **Gradle Kotlin DSL:** + ```kotlin repositories { maven("https://repo.kotlin.link") diff --git a/kmath-viktor/build.gradle.kts b/kmath-viktor/build.gradle.kts index 7a135f316..d15a70e9b 100644 --- a/kmath-viktor/build.gradle.kts +++ b/kmath-viktor/build.gradle.kts @@ -10,5 +10,5 @@ dependencies { } readme { - maturity = space.kscience.gradle.Maturity.DEVELOPMENT + maturity = space.kscience.gradle.Maturity.DEPRECATED } diff --git a/test-utils/build.gradle.kts b/test-utils/build.gradle.kts index b03059eaf..663b1149b 100644 --- a/test-utils/build.gradle.kts +++ b/test-utils/build.gradle.kts @@ -2,7 +2,7 @@ plugins { id("space.kscience.gradle.mpp") } -kscience{ +kscience { jvm() js() native() diff --git a/test-utils/src/commonMain/kotlin/bufferEquality.kt b/test-utils/src/commonMain/kotlin/bufferEquality.kt index 5b2ef6e76..d4fd99506 100644 --- a/test-utils/src/commonMain/kotlin/bufferEquality.kt +++ b/test-utils/src/commonMain/kotlin/bufferEquality.kt @@ -17,4 +17,5 @@ public fun Float64Buffer.contentEquals(vararg doubles: Double): Boolean = array. public infix fun Float64Buffer.contentEquals(otherArray: DoubleArray): Boolean = array.contentEquals(otherArray) @JvmName("contentEqualsBuffer") -public infix fun Float64Buffer.contentEquals(otherBuffer: Float64Buffer): Boolean = array.contentEquals(otherBuffer.array) \ No newline at end of file +public infix fun Float64Buffer.contentEquals(otherBuffer: Float64Buffer): Boolean = + array.contentEquals(otherBuffer.array) \ No newline at end of file From 3b74968f9a356b103ca799e348d0490086d77181 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 09:11:35 +0300 Subject: [PATCH 094/103] Change logic of AttributesBuilder. It no longer exposes the constructor --- .../space/kscience/attributes/AttributesBuilder.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index 033c143cc..0a185f74c 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -14,8 +14,6 @@ public class AttributesBuilder<out O> internal constructor( private val map: MutableMap<Attribute<*>, Any?>, ) : Attributes { - public constructor() : this(mutableMapOf()) - override fun toString(): String = "Attributes(value=${content.entries})" override fun equals(other: Any?): Boolean = other is Attributes && Attributes.equals(this, other) override fun hashCode(): Int = content.hashCode() @@ -61,5 +59,9 @@ public class AttributesBuilder<out O> internal constructor( public fun build(): Attributes = AttributesImpl(map) } -public inline fun <O> Attributes(builder: AttributesBuilder<O>.() -> Unit): Attributes = - AttributesBuilder<O>().apply(builder).build() \ No newline at end of file +/** + * Create [Attributes] with a given [builder] + * @param O the type for which attributes are built. The type is used only during compilation phase for static extension dispatch + */ +public fun <O> Attributes(builder: AttributesBuilder<O>.() -> Unit): Attributes = + AttributesBuilder<O>(mutableMapOf()).apply(builder).build() \ No newline at end of file From ac851bea62ec5ce12ec42e35bf4d59cf4d90cb5c Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 09:18:46 +0300 Subject: [PATCH 095/103] Change logic of AttributesBuilder. It no longer exposes the constructor --- .../space/kscience/attributes/Attributes.kt | 20 +++++++++---------- .../kscience/attributes/AttributesBuilder.kt | 13 ++++++------ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index ad53049eb..8ddb0cbc7 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -30,14 +30,14 @@ public interface Attributes { override fun hashCode(): Int public companion object { - public val EMPTY: Attributes = AttributesImpl(emptyMap()) + public val EMPTY: Attributes = MapAttributes(emptyMap()) public fun equals(a1: Attributes, a2: Attributes): Boolean = a1.keys == a2.keys && a1.keys.all { a1[it] == a2[it] } } } -internal class AttributesImpl(override val content: Map<out Attribute<*>, Any?>) : Attributes { +internal class MapAttributes(override val content: Map<out Attribute<*>, Any?>) : Attributes { override fun toString(): String = "Attributes(value=${content.entries})" override fun equals(other: Any?): Boolean = other is Attributes && Attributes.equals(this, other) override fun hashCode(): Int = content.hashCode() @@ -75,7 +75,7 @@ public inline fun <reified A : FlagAttribute> Attributes.hasFlag(): Boolean = public fun <T, A : Attribute<T>> Attributes.withAttribute( attribute: A, attrValue: T, -): Attributes = AttributesImpl(content + (attribute to attrValue)) +): Attributes = MapAttributes(content + (attribute to attrValue)) public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attributes = withAttribute(attribute, Unit) @@ -83,7 +83,7 @@ public fun <A : Attribute<Unit>> Attributes.withAttribute(attribute: A): Attribu /** * Create a new [Attributes] by modifying the current one */ -public fun <T> Attributes.modified(block: AttributesBuilder<T>.() -> Unit): Attributes = Attributes<T> { +public fun <O> Attributes.modified(block: AttributesBuilder<O>.() -> Unit): Attributes = Attributes<O> { putAll(this@modified) block() } @@ -91,7 +91,7 @@ public fun <T> Attributes.modified(block: AttributesBuilder<T>.() -> Unit): Attr /** * Create new [Attributes] by removing [attribute] key */ -public fun Attributes.withoutAttribute(attribute: Attribute<*>): Attributes = AttributesImpl(content.minus(attribute)) +public fun Attributes.withoutAttribute(attribute: Attribute<*>): Attributes = MapAttributes(content.minus(attribute)) /** * Add an element to a [SetAttribute] @@ -101,7 +101,7 @@ public fun <T, A : SetAttribute<T>> Attributes.withAttributeElement( attrValue: T, ): Attributes { val currentSet: Set<T> = get(attribute) ?: emptySet() - return AttributesImpl( + return MapAttributes( content + (attribute to (currentSet + attrValue)) ) } @@ -114,7 +114,7 @@ public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement( attrValue: T, ): Attributes { val currentSet: Set<T> = get(attribute) ?: emptySet() - return AttributesImpl(content + (attribute to (currentSet - attrValue))) + return MapAttributes(content + (attribute to (currentSet - attrValue))) } /** @@ -123,13 +123,13 @@ public fun <T, A : SetAttribute<T>> Attributes.withoutAttributeElement( public fun <T, A : Attribute<T>> Attributes( attribute: A, attrValue: T, -): Attributes = AttributesImpl(mapOf(attribute to attrValue)) +): Attributes = MapAttributes(mapOf(attribute to attrValue)) /** * Create Attributes with a single [Unit] valued attribute */ public fun <A : Attribute<Unit>> Attributes( attribute: A, -): Attributes = AttributesImpl(mapOf(attribute to Unit)) +): Attributes = MapAttributes(mapOf(attribute to Unit)) -public operator fun Attributes.plus(other: Attributes): Attributes = AttributesImpl(content + other.content) \ No newline at end of file +public operator fun Attributes.plus(other: Attributes): Attributes = MapAttributes(content + other.content) \ No newline at end of file diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index 0a185f74c..6f42d1dcf 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -6,13 +6,14 @@ package space.kscience.attributes /** - * A safe builder for [Attributes] + * A builder for [Attributes]. + * The builder is not thread safe * * @param O type marker of an owner object, for which these attributes are made */ -public class AttributesBuilder<out O> internal constructor( - private val map: MutableMap<Attribute<*>, Any?>, -) : Attributes { +public class AttributesBuilder<out O> internal constructor() : Attributes { + + private val map = mutableMapOf<Attribute<*>, Any?>() override fun toString(): String = "Attributes(value=${content.entries})" override fun equals(other: Any?): Boolean = other is Attributes && Attributes.equals(this, other) @@ -56,7 +57,7 @@ public class AttributesBuilder<out O> internal constructor( map[this] = currentSet - attrValue } - public fun build(): Attributes = AttributesImpl(map) + public fun build(): Attributes = MapAttributes(map) } /** @@ -64,4 +65,4 @@ public class AttributesBuilder<out O> internal constructor( * @param O the type for which attributes are built. The type is used only during compilation phase for static extension dispatch */ public fun <O> Attributes(builder: AttributesBuilder<O>.() -> Unit): Attributes = - AttributesBuilder<O>(mutableMapOf()).apply(builder).build() \ No newline at end of file + AttributesBuilder<O>().apply(builder).build() \ No newline at end of file From 48b334a2b607c884e18edd764f2a61bcd9bdcd14 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 09:45:56 +0300 Subject: [PATCH 096/103] Singleton implementation for Attributes.EMPTY --- .../kotlin/space/kscience/attributes/Attributes.kt | 12 ++++++++++-- .../space/kscience/attributes/AttributesBuilder.kt | 4 ++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt index 8ddb0cbc7..ab6185520 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/Attributes.kt @@ -30,7 +30,15 @@ public interface Attributes { override fun hashCode(): Int public companion object { - public val EMPTY: Attributes = MapAttributes(emptyMap()) + public val EMPTY: Attributes = object : Attributes { + override val content: Map<out Attribute<*>, Any?> get() = emptyMap() + + override fun toString(): String = "Attributes.EMPTY" + + override fun equals(other: Any?): Boolean = (other as? Attributes)?.isEmpty() ?: false + + override fun hashCode(): Int = Unit.hashCode() + } public fun equals(a1: Attributes, a2: Attributes): Boolean = a1.keys == a2.keys && a1.keys.all { a1[it] == a2[it] } @@ -43,7 +51,7 @@ internal class MapAttributes(override val content: Map<out Attribute<*>, Any?>) override fun hashCode(): Int = content.hashCode() } -public fun Attributes.isEmpty(): Boolean = content.isEmpty() +public fun Attributes.isEmpty(): Boolean = keys.isEmpty() /** * Get attribute value or default diff --git a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt index 6f42d1dcf..ecf3da6f2 100644 --- a/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt +++ b/attributes-kt/src/commonMain/kotlin/space/kscience/attributes/AttributesBuilder.kt @@ -15,9 +15,9 @@ public class AttributesBuilder<out O> internal constructor() : Attributes { private val map = mutableMapOf<Attribute<*>, Any?>() - override fun toString(): String = "Attributes(value=${content.entries})" + override fun toString(): String = "Attributes(value=${map.entries})" override fun equals(other: Any?): Boolean = other is Attributes && Attributes.equals(this, other) - override fun hashCode(): Int = content.hashCode() + override fun hashCode(): Int = map.hashCode() override val content: Map<out Attribute<*>, Any?> get() = map From 255d4ba6b7118b5621fa82760cddcc8d6c6459cc Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 09:51:23 +0300 Subject: [PATCH 097/103] Dump API. Update readme --- README.md | 117 ++++++++++------------------ attributes-kt/README.md | 17 ++++ attributes-kt/api/attributes-kt.api | 6 +- kmath-ast/README.md | 14 ++-- kmath-commons/README.md | 5 +- kmath-complex/README.md | 10 +-- kmath-core/README.md | 31 ++++---- kmath-coroutines/README.md | 7 +- kmath-dimensions/README.md | 5 +- kmath-ejml/README.md | 12 +-- kmath-for-real/README.md | 14 ++-- kmath-functions/README.md | 18 ++--- kmath-geometry/README.md | 7 +- kmath-histograms/README.md | 7 +- kmath-jafama/README.md | 8 +- kmath-jupyter/README.md | 7 +- kmath-kotlingrad/README.md | 12 ++- kmath-memory/README.md | 7 +- kmath-multik/README.md | 5 +- kmath-nd4j/README.md | 12 +-- kmath-optimization/README.md | 7 +- kmath-stat/README.md | 7 +- kmath-symja/README.md | 5 +- kmath-tensorflow/README.md | 5 +- kmath-tensors/README.md | 15 ++-- kmath-viktor/README.md | 5 +- 26 files changed, 166 insertions(+), 199 deletions(-) diff --git a/README.md b/README.md index cd2503a12..1abd7481a 100644 --- a/README.md +++ b/README.md @@ -56,181 +56,151 @@ module definitions below. The module stability could have the following levels: ## Modules -### [attributes-kt](attributes-kt) +### [attributes-kt](attributes-kt) > An API and basic implementation for arranging objects in a continuous memory block. > > **Maturity**: DEVELOPMENT ### [benchmarks](benchmarks) - > > **Maturity**: EXPERIMENTAL ### [examples](examples) - > > **Maturity**: EXPERIMENTAL ### [kmath-ast](kmath-ast) - > > **Maturity**: EXPERIMENTAL > > **Features:** -> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and - its parser -> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode - compiler +> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser +> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler > - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler -> - [rendering](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST - rendering +> - [rendering](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering + ### [kmath-commons](kmath-commons) - > Commons math binding for kmath > > **Maturity**: EXPERIMENTAL ### [kmath-complex](kmath-complex) - > Complex numbers and quaternions. > > **Maturity**: PROTOTYPE > > **Features:** > - [complex](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations -> - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their - composition +> - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition + ### [kmath-core](kmath-core) - > Core classes, algebra definitions, basic linear algebra > > **Maturity**: DEVELOPMENT > > **Features:** -> - [algebras](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like - rings, spaces and fields. -> - [nd](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures - and operations on them. -> - [linear](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra - operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix - inversion and LU decomposition. +> - [algebras](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields. +> - [nd](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them. +> - [linear](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition. > - [buffers](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure -> - [expressions](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical - expression once, users will be able to apply different types of - objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high - performance calculations to code generation. +> - [expressions](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of +objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high +performance calculations to code generation. > - [domains](kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains) : Domains -> - [autodiff](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic - differentiation +> - [autodiff](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation +> - [Parallel linear algebra](kmath-core/#) : Parallel implementation for `LinearAlgebra` + ### [kmath-coroutines](kmath-coroutines) - > > **Maturity**: EXPERIMENTAL ### [kmath-dimensions](kmath-dimensions) - > A proof of concept module for adding type-safe dimensions to structures > > **Maturity**: PROTOTYPE ### [kmath-ejml](kmath-ejml) - > > **Maturity**: PROTOTYPE > > **Features:** > - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations. > - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation. -> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace - implementations. +> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations. + ### [kmath-for-real](kmath-for-real) - > Extension module that should be used to achieve numpy-like behavior. -> All operations are specialized to work with `Double` numbers without declaring algebraic contexts. -> One can still use generic algebras though. +All operations are specialized to work with `Double` numbers without declaring algebraic contexts. +One can still use generic algebras though. > > **Maturity**: EXPERIMENTAL > > **Features:** -> - [DoubleVector](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like - operations for Buffers/Points -> - [DoubleMatrix](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like - operations for 2d real structures +> - [DoubleVector](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for Buffers/Points +> - [DoubleMatrix](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures > - [grids](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators -### [kmath-functions](kmath-functions) +### [kmath-functions](kmath-functions) > Functions, integration and interpolation > > **Maturity**: EXPERIMENTAL > > **Features:** -> - [piecewise](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise - functions. -> - [polynomials](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial - functions. -> - [linear interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : - Linear XY interpolator. -> - [spline interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : - Cubic spline XY interpolator. +> - [piecewise](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions. +> - [polynomials](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions. +> - [linear interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY interpolator. +> - [spline interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator. > - [integration](kmath-functions/#) : Univariate and multivariate quadratures -### [kmath-geometry](kmath-geometry) +### [kmath-geometry](kmath-geometry) > > **Maturity**: PROTOTYPE ### [kmath-histograms](kmath-histograms) - > > **Maturity**: PROTOTYPE ### [kmath-jafama](kmath-jafama) - > Jafama integration module > > **Maturity**: DEPRECATED > > **Features:** -> - [jafama-double](kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations - based on Jafama +> - [jafama-double](kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama + ### [kmath-jupyter](kmath-jupyter) - > > **Maturity**: PROTOTYPE ### [kmath-kotlingrad](kmath-kotlingrad) - > Kotlin∇ integration module > > **Maturity**: EXPERIMENTAL > > **Features:** -> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : - MST based DifferentiableExpression. -> - [scalars-adapters](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : - Conversions between Kotlin∇'s SFun and MST +> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based DifferentiableExpression. +> - [scalars-adapters](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s SFun and MST + ### [kmath-memory](kmath-memory) - > An API and basic implementation for arranging objects in a continuous memory block. > > **Maturity**: DEVELOPMENT ### [kmath-multik](kmath-multik) - > JetBrains Multik connector > > **Maturity**: PROTOTYPE ### [kmath-nd4j](kmath-nd4j) - > ND4J NDStructure implementation and according NDAlgebra classes > > **Maturity**: DEPRECATED @@ -240,52 +210,45 @@ module definitions below. The module stability could have the following levels: > - [nd4jarrayrings](kmath-nd4j/#) : Rings over Nd4jArrayStructure of Int and Long > - [nd4jarrayfields](kmath-nd4j/#) : Fields over Nd4jArrayStructure of Float and Double -### [kmath-optimization](kmath-optimization) +### [kmath-optimization](kmath-optimization) > > **Maturity**: EXPERIMENTAL ### [kmath-stat](kmath-stat) - > > **Maturity**: EXPERIMENTAL ### [kmath-symja](kmath-symja) - > Symja integration module > > **Maturity**: PROTOTYPE ### [kmath-tensorflow](kmath-tensorflow) - > Google tensorflow connector > > **Maturity**: PROTOTYPE ### [kmath-tensors](kmath-tensors) - > > **Maturity**: PROTOTYPE > > **Features:** -> - [tensor algebra](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic - linear algebra operations on tensors (plus, dot, etc.) -> - [tensor algebra with broadcasting](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : - Basic linear algebra operations implemented with broadcasting. -> - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : - Advanced linear algebra operations like LU decomposition, SVD, etc. +> - [tensor algebra](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic linear algebra operations on tensors (plus, dot, etc.) +> - [tensor algebra with broadcasting](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : Basic linear algebra operations implemented with broadcasting. +> - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc. + ### [kmath-viktor](kmath-viktor) - > Binding for https://github.com/JetBrains-Research/viktor > -> **Maturity**: DEVELOPMENT +> **Maturity**: DEPRECATED ### [test-utils](test-utils) - > > **Maturity**: EXPERIMENTAL + ## Multi-platform support KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the diff --git a/attributes-kt/README.md b/attributes-kt/README.md index 53f80fcef..96d273d5b 100644 --- a/attributes-kt/README.md +++ b/attributes-kt/README.md @@ -2,3 +2,20 @@ +## Usage + +## Artifact: + +The Maven coordinates of this project are `space.kscience:attributes-kt:0.1.0`. + +**Gradle Kotlin DSL:** +```kotlin +repositories { + maven("https://repo.kotlin.link") + mavenCentral() +} + +dependencies { + implementation("space.kscience:attributes-kt:0.1.0") +} +``` diff --git a/attributes-kt/api/attributes-kt.api b/attributes-kt/api/attributes-kt.api index 403e12f5c..c735ad1dc 100644 --- a/attributes-kt/api/attributes-kt.api +++ b/attributes-kt/api/attributes-kt.api @@ -28,14 +28,14 @@ public final class space/kscience/attributes/Attributes$Companion { } public final class space/kscience/attributes/AttributesBuilder : space/kscience/attributes/Attributes { - public fun <init> ()V public final fun add (Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)V public final fun build ()Lspace/kscience/attributes/Attributes; public fun equals (Ljava/lang/Object;)Z - public final fun from (Lspace/kscience/attributes/Attributes;)V public fun getContent ()Ljava/util/Map; public fun hashCode ()I public final fun invoke (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V + public final fun put (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V + public final fun putAll (Lspace/kscience/attributes/Attributes;)V public final fun remove (Lspace/kscience/attributes/SetAttribute;Ljava/lang/Object;)V public final fun set (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)V public fun toString ()Ljava/lang/String; @@ -50,7 +50,7 @@ public final class space/kscience/attributes/AttributesKt { public static final fun Attributes (Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes; public static final fun getOrDefault (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/AttributeWithDefault;)Ljava/lang/Object; public static final fun isEmpty (Lspace/kscience/attributes/Attributes;)Z - public static final fun modify (Lspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function1;)Lspace/kscience/attributes/Attributes; + public static final fun modified (Lspace/kscience/attributes/Attributes;Lkotlin/jvm/functions/Function1;)Lspace/kscience/attributes/Attributes; public static final fun plus (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attributes;)Lspace/kscience/attributes/Attributes; public static final fun withAttribute (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attribute;)Lspace/kscience/attributes/Attributes; public static final fun withAttribute (Lspace/kscience/attributes/Attributes;Lspace/kscience/attributes/Attribute;Ljava/lang/Object;)Lspace/kscience/attributes/Attributes; diff --git a/kmath-ast/README.md b/kmath-ast/README.md index 289114dd0..48ffa4502 100644 --- a/kmath-ast/README.md +++ b/kmath-ast/README.md @@ -2,17 +2,17 @@ Extensions to MST API: transformations, dynamic compilation and visualization. -- [expression-language](src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser -- [mst-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler -- [mst-js-codegen](src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler -- [rendering](src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering + - [expression-language](src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser + - [mst-jvm-codegen](src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler + - [mst-js-codegen](src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler + - [rendering](src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-ast:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-ast:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -20,7 +20,7 @@ repositories { } dependencies { - implementation("space.kscience:kmath-ast:0.4.0-dev-3") + implementation("space.kscience:kmath-ast:0.4.0") } ``` diff --git a/kmath-commons/README.md b/kmath-commons/README.md index 7ca7dacf8..2c60f4142 100644 --- a/kmath-commons/README.md +++ b/kmath-commons/README.md @@ -6,10 +6,9 @@ Commons math binding for kmath ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-commons:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-commons:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -17,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-commons:0.4.0-dev-3") + implementation("space.kscience:kmath-commons:0.4.0") } ``` diff --git a/kmath-complex/README.md b/kmath-complex/README.md index b5e4b9d58..d641452b0 100644 --- a/kmath-complex/README.md +++ b/kmath-complex/README.md @@ -2,15 +2,15 @@ Complex and hypercomplex number systems in KMath. -- [complex](src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations -- [quaternion](src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition + - [complex](src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations + - [quaternion](src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-complex:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-complex:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -18,6 +18,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-complex:0.4.0-dev-3") + implementation("space.kscience:kmath-complex:0.4.0") } ``` diff --git a/kmath-core/README.md b/kmath-core/README.md index dd3935764..acb90a411 100644 --- a/kmath-core/README.md +++ b/kmath-core/README.md @@ -2,28 +2,23 @@ The core interfaces of KMath. -- [algebras](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces - and fields. -- [nd](src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and - operations on them. -- [linear](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, - products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU - decomposition. -- [buffers](src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure -- [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression - once, users will be able to apply different types of - objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high - performance calculations to code generation. -- [domains](src/commonMain/kotlin/space/kscience/kmath/domains) : Domains -- [autodiff](src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation -- [linear.parallel](#) : Parallel implementation for `LinearAlgebra` + - [algebras](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields. + - [nd](src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them. + - [linear](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition. + - [buffers](src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure + - [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of +objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high +performance calculations to code generation. + - [domains](src/commonMain/kotlin/space/kscience/kmath/domains) : Domains + - [autodiff](src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation + - [Parallel linear algebra](#) : Parallel implementation for `LinearAlgebra` + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-core:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-core:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -31,6 +26,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-core:0.4.0-dev-3") + implementation("space.kscience:kmath-core:0.4.0") } ``` diff --git a/kmath-coroutines/README.md b/kmath-coroutines/README.md index 5b64ccc0a..75ee7e5dc 100644 --- a/kmath-coroutines/README.md +++ b/kmath-coroutines/README.md @@ -1,13 +1,14 @@ # Module kmath-coroutines + + ## Usage ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-coroutines:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-coroutines:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -15,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-coroutines:0.4.0-dev-3") + implementation("space.kscience:kmath-coroutines:0.4.0") } ``` diff --git a/kmath-dimensions/README.md b/kmath-dimensions/README.md index f2482f965..c7ea29b91 100644 --- a/kmath-dimensions/README.md +++ b/kmath-dimensions/README.md @@ -6,10 +6,9 @@ A proof of concept module for adding type-safe dimensions to structures ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-dimensions:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-dimensions:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -17,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-dimensions:0.4.0-dev-3") + implementation("space.kscience:kmath-dimensions:0.4.0") } ``` diff --git a/kmath-ejml/README.md b/kmath-ejml/README.md index a2c38ce8e..92ec252c1 100644 --- a/kmath-ejml/README.md +++ b/kmath-ejml/README.md @@ -2,16 +2,16 @@ EJML based linear algebra implementation. -- [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations. -- [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation. -- [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations. + - [ejml-vector](src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations. + - [ejml-matrix](src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation. + - [ejml-linear-space](src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations. + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-ejml:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-ejml:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -19,6 +19,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-ejml:0.4.0-dev-3") + implementation("space.kscience:kmath-ejml:0.4.0") } ``` diff --git a/kmath-for-real/README.md b/kmath-for-real/README.md index 46762269e..c65f6db46 100644 --- a/kmath-for-real/README.md +++ b/kmath-for-real/README.md @@ -2,18 +2,16 @@ Specialization of KMath APIs for Double numbers. -- [DoubleVector](src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for - Buffers/Points -- [DoubleMatrix](src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real - structures -- [grids](src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators + - [DoubleVector](src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for Buffers/Points + - [DoubleMatrix](src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures + - [grids](src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-for-real:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-for-real:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -21,6 +19,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-for-real:0.4.0-dev-3") + implementation("space.kscience:kmath-for-real:0.4.0") } ``` diff --git a/kmath-functions/README.md b/kmath-functions/README.md index 25c802077..c53bc5c11 100644 --- a/kmath-functions/README.md +++ b/kmath-functions/README.md @@ -2,20 +2,18 @@ Functions and interpolations. -- [piecewise](src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions. -- [polynomials](src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions. -- [linear interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY - interpolator. -- [spline interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline - XY interpolator. -- [integration](#) : Univariate and multivariate quadratures + - [piecewise](src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions. + - [polynomials](src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions. + - [linear interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY interpolator. + - [spline interpolation](src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator. + - [integration](#) : Univariate and multivariate quadratures + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-functions:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-functions:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -23,6 +21,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-functions:0.4.0-dev-3") + implementation("space.kscience:kmath-functions:0.4.0") } ``` diff --git a/kmath-geometry/README.md b/kmath-geometry/README.md index 263df3a87..eed6b6cfd 100644 --- a/kmath-geometry/README.md +++ b/kmath-geometry/README.md @@ -1,13 +1,14 @@ # Module kmath-geometry + + ## Usage ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-geometry:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-geometry:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -15,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-geometry:0.4.0-dev-3") + implementation("space.kscience:kmath-geometry:0.4.0") } ``` diff --git a/kmath-histograms/README.md b/kmath-histograms/README.md index 88f0c2dd4..5f494310a 100644 --- a/kmath-histograms/README.md +++ b/kmath-histograms/README.md @@ -1,13 +1,14 @@ # Module kmath-histograms + + ## Usage ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-histograms:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-histograms:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -15,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-histograms:0.4.0-dev-3") + implementation("space.kscience:kmath-histograms:0.4.0") } ``` diff --git a/kmath-jafama/README.md b/kmath-jafama/README.md index 314ad47ab..2f8f365c1 100644 --- a/kmath-jafama/README.md +++ b/kmath-jafama/README.md @@ -2,14 +2,14 @@ Integration with [Jafama](https://github.com/jeffhain/jafama). -- [jafama-double](src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama + - [jafama-double](src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-jafama:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-jafama:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -17,7 +17,7 @@ repositories { } dependencies { - implementation("space.kscience:kmath-jafama:0.4.0-dev-3") + implementation("space.kscience:kmath-jafama:0.4.0") } ``` diff --git a/kmath-jupyter/README.md b/kmath-jupyter/README.md index 21531f632..8a425dff0 100644 --- a/kmath-jupyter/README.md +++ b/kmath-jupyter/README.md @@ -1,13 +1,14 @@ # Module kmath-jupyter + + ## Usage ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-jupyter:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-jupyter:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -15,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-jupyter:0.4.0-dev-3") + implementation("space.kscience:kmath-jupyter:0.4.0") } ``` diff --git a/kmath-kotlingrad/README.md b/kmath-kotlingrad/README.md index 2948799d3..697662245 100644 --- a/kmath-kotlingrad/README.md +++ b/kmath-kotlingrad/README.md @@ -2,17 +2,15 @@ [Kotlin∇](https://github.com/breandan/kotlingrad) integration module. -- [differentiable-mst-expression](src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based - DifferentiableExpression. -- [scalars-adapters](src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s - SFun and MST + - [differentiable-mst-expression](src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based DifferentiableExpression. + - [scalars-adapters](src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s SFun and MST + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-kotlingrad:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-kotlingrad:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -20,6 +18,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-kotlingrad:0.4.0-dev-3") + implementation("space.kscience:kmath-kotlingrad:0.4.0") } ``` diff --git a/kmath-memory/README.md b/kmath-memory/README.md index 8d66fe37d..5f08023b0 100644 --- a/kmath-memory/README.md +++ b/kmath-memory/README.md @@ -1,13 +1,14 @@ # Module kmath-memory + + ## Usage ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-memory:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-memory:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -15,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-memory:0.4.0-dev-3") + implementation("space.kscience:kmath-memory:0.4.0") } ``` diff --git a/kmath-multik/README.md b/kmath-multik/README.md index 0bfc71a82..f69d5d5d0 100644 --- a/kmath-multik/README.md +++ b/kmath-multik/README.md @@ -6,10 +6,9 @@ JetBrains Multik connector ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-multik:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-multik:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -17,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-multik:0.4.0-dev-3") + implementation("space.kscience:kmath-multik:0.4.0") } ``` diff --git a/kmath-nd4j/README.md b/kmath-nd4j/README.md index 393a2a3e4..c2e0cafe0 100644 --- a/kmath-nd4j/README.md +++ b/kmath-nd4j/README.md @@ -2,16 +2,16 @@ ND4J based implementations of KMath abstractions. -- [nd4jarraystructure](#) : NDStructure wrapper for INDArray -- [nd4jarrayrings](#) : Rings over Nd4jArrayStructure of Int and Long -- [nd4jarrayfields](#) : Fields over Nd4jArrayStructure of Float and Double + - [nd4jarraystructure](#) : NDStructure wrapper for INDArray + - [nd4jarrayrings](#) : Rings over Nd4jArrayStructure of Int and Long + - [nd4jarrayfields](#) : Fields over Nd4jArrayStructure of Float and Double + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-nd4j:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -19,7 +19,7 @@ repositories { } dependencies { - implementation("space.kscience:kmath-nd4j:0.4.0-dev-3") + implementation("space.kscience:kmath-nd4j:0.4.0") } ``` diff --git a/kmath-optimization/README.md b/kmath-optimization/README.md index e1e44fa4d..3728ab18e 100644 --- a/kmath-optimization/README.md +++ b/kmath-optimization/README.md @@ -1,13 +1,14 @@ # Module kmath-optimization + + ## Usage ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-optimization:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-optimization:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -15,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-optimization:0.4.0-dev-3") + implementation("space.kscience:kmath-optimization:0.4.0") } ``` diff --git a/kmath-stat/README.md b/kmath-stat/README.md index 8de601893..63b8bc3b8 100644 --- a/kmath-stat/README.md +++ b/kmath-stat/README.md @@ -1,13 +1,14 @@ # Module kmath-stat + + ## Usage ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-stat:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-stat:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -15,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-stat:0.4.0-dev-3") + implementation("space.kscience:kmath-stat:0.4.0") } ``` diff --git a/kmath-symja/README.md b/kmath-symja/README.md index e1b1e2359..a082d8b27 100644 --- a/kmath-symja/README.md +++ b/kmath-symja/README.md @@ -6,10 +6,9 @@ Symja integration module ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-symja:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-symja:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -17,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-symja:0.4.0-dev-3") + implementation("space.kscience:kmath-symja:0.4.0") } ``` diff --git a/kmath-tensorflow/README.md b/kmath-tensorflow/README.md index 51c49e853..6c289c808 100644 --- a/kmath-tensorflow/README.md +++ b/kmath-tensorflow/README.md @@ -6,10 +6,9 @@ Google tensorflow connector ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-tensorflow:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-tensorflow:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -17,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-tensorflow:0.4.0-dev-3") + implementation("space.kscience:kmath-tensorflow:0.4.0") } ``` diff --git a/kmath-tensors/README.md b/kmath-tensors/README.md index 27ab26cbf..92f99028b 100644 --- a/kmath-tensors/README.md +++ b/kmath-tensors/README.md @@ -2,19 +2,16 @@ Common linear algebra operations on tensors. -- [tensor algebra](src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic linear algebra - operations on tensors (plus, dot, etc.) -- [tensor algebra with broadcasting](src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : - Basic linear algebra operations implemented with broadcasting. -- [linear algebra operations](src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : - Advanced linear algebra operations like LU decomposition, SVD, etc. + - [tensor algebra](src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic linear algebra operations on tensors (plus, dot, etc.) + - [tensor algebra with broadcasting](src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : Basic linear algebra operations implemented with broadcasting. + - [linear algebra operations](src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc. + ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-tensors:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-tensors:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -22,6 +19,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-tensors:0.4.0-dev-3") + implementation("space.kscience:kmath-tensors:0.4.0") } ``` diff --git a/kmath-viktor/README.md b/kmath-viktor/README.md index 3d5ebd95c..73c8c8774 100644 --- a/kmath-viktor/README.md +++ b/kmath-viktor/README.md @@ -6,10 +6,9 @@ Binding for https://github.com/JetBrains-Research/viktor ## Artifact: -The Maven coordinates of this project are `space.kscience:kmath-viktor:0.4.0-dev-3`. +The Maven coordinates of this project are `space.kscience:kmath-viktor:0.4.0`. **Gradle Kotlin DSL:** - ```kotlin repositories { maven("https://repo.kotlin.link") @@ -17,6 +16,6 @@ repositories { } dependencies { - implementation("space.kscience:kmath-viktor:0.4.0-dev-3") + implementation("space.kscience:kmath-viktor:0.4.0") } ``` From 2fe04040c6316912969eeef5cbfe1ca799aef736 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Wed, 27 Mar 2024 09:58:28 +0300 Subject: [PATCH 098/103] Fix AttributeBuilder inlining --- .../space/kscience/kmath/integration/GaussIntegrator.kt | 2 +- .../kscience/kmath/integration/MultivariateIntegrand.kt | 2 +- .../space/kscience/kmath/integration/UnivariateIntegrand.kt | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index e2f5c77ba..c988cdbde 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -92,7 +92,7 @@ public inline fun <reified T : Any> GaussIntegrator<T>.integrate( range: ClosedRange<Double>, order: Int = 10, intervals: Int = 10, - attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {}, + noinline attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {}, noinline function: (Double) -> T, ): UnivariateIntegrand<T> { require(range.endInclusive > range.start) { "The range upper bound should be higher than lower bound" } diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt index 1afb59e5d..79e867576 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/MultivariateIntegrand.kt @@ -29,6 +29,6 @@ public fun <T> MultivariateIntegrand<T>.withAttributes( ): MultivariateIntegrand<T> = withAttributes(attributes.modified(block)) public inline fun <reified T : Any> MultivariateIntegrand( - attributeBuilder: AttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, + noinline attributeBuilder: AttributesBuilder<MultivariateIntegrand<T>>.() -> Unit, noinline function: (Point<T>) -> T, ): MultivariateIntegrand<T> = MultivariateIntegrand(safeTypeOf<T>(), Attributes(attributeBuilder), function) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt index dbe507233..e5d220f0f 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/UnivariateIntegrand.kt @@ -30,7 +30,7 @@ public fun <T> UnivariateIntegrand<T>.withAttributes( ): UnivariateIntegrand<T> = withAttributes(attributes.modified(block)) public inline fun <reified T : Any> UnivariateIntegrand( - attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, + noinline attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, noinline function: (Double) -> T, ): UnivariateIntegrand<T> = UnivariateIntegrand(safeTypeOf(), Attributes(attributeBuilder), function) @@ -68,7 +68,7 @@ public fun AttributesBuilder<UnivariateIntegrand<*>>.integrationNodes(vararg nod */ @UnstableKMathAPI public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( - attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, + noinline attributesBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit, noinline function: (Double) -> T, ): UnivariateIntegrand<T> = integrate(UnivariateIntegrand(attributesBuilder, function)) @@ -79,7 +79,7 @@ public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( @UnstableKMathAPI public inline fun <reified T : Any> UnivariateIntegrator<T>.integrate( range: ClosedRange<Double>, - attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {}, + noinline attributeBuilder: AttributesBuilder<UnivariateIntegrand<T>>.() -> Unit = {}, noinline function: (Double) -> T, ): UnivariateIntegrand<T> { From c696a22f62cfcacd9cdd326f1011118b97e32f72 Mon Sep 17 00:00:00 2001 From: SPC-code <112205870+SPC-code@users.noreply.github.com> Date: Mon, 15 Apr 2024 17:41:52 +0300 Subject: [PATCH 099/103] Update kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com> --- .../kotlin/space/kscience/kmath/integration/GaussIntegrator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt index c988cdbde..666379c7a 100644 --- a/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt +++ b/kmath-functions/src/commonMain/kotlin/space/kscience/kmath/integration/GaussIntegrator.kt @@ -19,7 +19,7 @@ import space.kscience.kmath.structures.indices * [GaussLegendreRuleFactory]. * * [IntegrationRange]—the univariate range of integration. By default, uses `0..1` interval. * * [IntegrandMaxCalls]—the maximum number of function calls during integration. For non-iterative rules, always - * use the maximum number of points. By default, uses 10 points. + * use the maximum number of points. By default, uses 10 points. * * [UnivariateIntegrandRanges]—set of ranges and number of points per range. Defaults to given * [IntegrationRange] and [IntegrandMaxCalls]. */ From f335d63659fae35030043d97961477e2f9f13985 Mon Sep 17 00:00:00 2001 From: SPC-code <112205870+SPC-code@users.noreply.github.com> Date: Mon, 15 Apr 2024 17:42:52 +0300 Subject: [PATCH 100/103] Update docs/buffers.md Co-authored-by: Gleb Minaev <43728100+lounres@users.noreply.github.com> --- docs/buffers.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/buffers.md b/docs/buffers.md index ce56d58c4..ab8bf6a77 100644 --- a/docs/buffers.md +++ b/docs/buffers.md @@ -17,4 +17,4 @@ own `MemoryBuffer.create()` factory). ## Buffer performance One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers -instead . +instead. From edbf8c05beca8bf7b509ddfa5958c731fc90b278 Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Mon, 15 Apr 2024 17:52:15 +0300 Subject: [PATCH 101/103] cleanup Minuit --- .../commonMain/tmp/minuit/MinuitParameter.kt | 16 ++--- .../commonMain/tmp/minuit/MnApplication.kt | 20 +++--- .../src/commonMain/tmp/minuit/MnMinos.kt | 12 ++-- .../commonMain/tmp/minuit/MnSeedGenerator.kt | 15 +---- .../tmp/minuit/MnUserParameterState.kt | 36 +++++------ .../commonMain/tmp/minuit/MnUserParameters.kt | 20 +++--- .../tmp/minuit/MnUserTransformation.kt | 64 +++++++++---------- .../tmp/minuit/NegativeG2LineSearch.kt | 5 +- .../tmp/minuit/SimplexSeedGenerator.kt | 5 +- 9 files changed, 88 insertions(+), 105 deletions(-) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MinuitParameter.kt b/kmath-optimization/src/commonMain/tmp/minuit/MinuitParameter.kt index ff6834df4..e1eb972d9 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MinuitParameter.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MinuitParameter.kt @@ -38,9 +38,9 @@ class MinuitParameter { * @param name a [String] object. * @param val a double. */ - constructor(num: Int, name: String, `val`: Double) { + constructor(num: Int, name: String, value: Double) { theNum = num - theValue = `val` + theValue = value theConst = true theName = name } @@ -53,9 +53,9 @@ class MinuitParameter { * @param val a double. * @param err a double. */ - constructor(num: Int, name: String, `val`: Double, err: Double) { + constructor(num: Int, name: String, value: Double, err: Double) { theNum = num - theValue = `val` + theValue = value theError = err theName = name } @@ -70,9 +70,9 @@ class MinuitParameter { * @param min a double. * @param max a double. */ - constructor(num: Int, name: String, `val`: Double, err: Double, min: Double, max: Double) { + constructor(num: Int, name: String, value: Double, err: Double, min: Double, max: Double) { theNum = num - theValue = `val` + theValue = value theError = err theLoLimit = min theUpLimit = max @@ -288,8 +288,8 @@ class MinuitParameter { * * @param val a double. */ - fun setValue(`val`: Double) { - theValue = `val` + fun setValue(value: Double) { + theValue = value } /** diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnApplication.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnApplication.kt index 45944ac85..18707980b 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnApplication.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnApplication.kt @@ -77,8 +77,8 @@ abstract class MnApplication { * @param val a double. * @param name a [String] object. */ - fun add(name: String, `val`: Double, err: Double) { - theState.add(name, `val`, err) + fun add(name: String, value: Double, err: Double) { + theState.add(name, value, err) } /** @@ -90,8 +90,8 @@ abstract class MnApplication { * @param val a double. * @param err a double. */ - fun add(name: String, `val`: Double, err: Double, low: Double, up: Double) { - theState.add(name, `val`, err, low, up) + fun add(name: String, value: Double, err: Double, low: Double, up: Double) { + theState.add(name, value, err, low, up) } /** @@ -100,8 +100,8 @@ abstract class MnApplication { * @param name a [String] object. * @param val a double. */ - fun add(name: String, `val`: Double) { - theState.add(name, `val`) + fun add(name: String, value: Double) { + theState.add(name, value) } /** @@ -471,8 +471,8 @@ abstract class MnApplication { * @param index a int. * @param val a double. */ - fun setValue(index: Int, `val`: Double) { - theState.setValue(index, `val`) + fun setValue(index: Int, value: Double) { + theState.setValue(index, value) } /** @@ -482,8 +482,8 @@ abstract class MnApplication { * @param name a [String] object. * @param val a double. */ - fun setValue(name: String?, `val`: Double) { - theState.setValue(name, `val`) + fun setValue(name: String?, value: Double) { + theState.setValue(name, value) } /** diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnMinos.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnMinos.kt index d49379b3b..05499bd93 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnMinos.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnMinos.kt @@ -106,8 +106,8 @@ class MnMinos(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) { val para = intArrayOf(par) val upar: MnUserParameterState = theMinimum!!.userState().copy() val err: Double = upar.error(par) - val `val`: Double = upar.value(par) - err - val xmid = doubleArrayOf(`val`) + val value: Double = upar.value(par) - err + val xmid = doubleArrayOf(value) val xdir = doubleArrayOf(-err) val ind: Int = upar.intOfExt(par) val m: MnAlgebraicSymMatrix = theMinimum!!.error().matrix() @@ -121,7 +121,7 @@ class MnMinos(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) { upar.setValue(ext, upar.value(ext) - xdev) } upar.fix(par) - upar.setValue(par, `val`) + upar.setValue(par, value) val toler = 0.1 val cross = MnFunctionCross(theFCN, upar, theMinimum!!.fval(), theStrategy, errDef) val aopt: MnCross = cross.cross(para, xmid, xdir, toler, maxcalls) @@ -330,8 +330,8 @@ class MnMinos(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) { val para = intArrayOf(par) val upar: MnUserParameterState = theMinimum!!.userState().copy() val err: Double = upar.error(par) - val `val`: Double = upar.value(par) + err - val xmid = doubleArrayOf(`val`) + val value: Double = upar.value(par) + err + val xmid = doubleArrayOf(value) val xdir = doubleArrayOf(err) val ind: Int = upar.intOfExt(par) val m: MnAlgebraicSymMatrix = theMinimum!!.error().matrix() @@ -345,7 +345,7 @@ class MnMinos(fcn: MultiFunction?, min: FunctionMinimum?, stra: MnStrategy?) { upar.setValue(ext, upar.value(ext) + xdev) } upar.fix(par) - upar.setValue(par, `val`) + upar.setValue(par, value) val toler = 0.1 val cross = MnFunctionCross(theFCN, upar, theMinimum!!.fval(), theStrategy, errDef) val aopt: MnCross = cross.cross(para, xmid, xdir, toler, maxcalls) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnSeedGenerator.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnSeedGenerator.kt index 4dcf89c7c..8bc038f16 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnSeedGenerator.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnSeedGenerator.kt @@ -52,17 +52,9 @@ internal class MnSeedGenerator : MinimumSeedGenerator { val delta: Double = hgrd.getSecond().getEntry(i) if (abs(calculated - provided) > delta) { MINUITPlugin.logStatic( - "" - + "gradient discrepancy of external parameter \"%d\" " - + "(internal parameter \"%d\") too large. Expected: \"%f\", provided: \"%f\"", + """gradient discrepancy of external parameter "%d" (internal parameter "%d") too large. Expected: "%f", provided: "%f"""", st.getTransformation().extOfInt(i), i, provided, calculated ) - -// -// MINUITPlugin.logStatic("gradient discrepancy of external parameter " -// + st.getTransformation().extOfInt(i) -// + " (internal parameter " + i + ") too large."); -// good = false; } } if (!good) { @@ -84,10 +76,7 @@ internal class MnSeedGenerator : MinimumSeedGenerator { dcovar = 0.0 } else { for (i in 0 until n) { - mat[i, i] = if (abs( - dgrad.getGradientDerivative() - .getEntry(i) - ) > prec.eps2() + mat[i, i] = if (abs(dgrad.getGradientDerivative().getEntry(i)) > prec.eps2() ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 } } diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameterState.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameterState.kt index 0dd2d8ae9..8b2f8786e 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameterState.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameterState.kt @@ -235,9 +235,9 @@ class MnUserParameterState { * @param val a double. * @param name a [String] object. */ - fun add(name: String, `val`: Double, err: Double) { - theParameters.add(name, `val`, err) - theIntParameters.add(`val`) + fun add(name: String, value: Double, err: Double) { + theParameters.add(name, value, err) + theIntParameters.add(value) theCovarianceValid = false theGCCValid = false theValid = true @@ -252,10 +252,10 @@ class MnUserParameterState { * @param err a double. * @param up a double. */ - fun add(name: String, `val`: Double, err: Double, low: Double, up: Double) { - theParameters.add(name, `val`, err, low, up) + fun add(name: String, value: Double, err: Double, low: Double, up: Double) { + theParameters.add(name, value, err, low, up) theCovarianceValid = false - theIntParameters.add(ext2int(index(name), `val`)) + theIntParameters.add(ext2int(index(name), value)) theGCCValid = false theValid = true } @@ -266,8 +266,8 @@ class MnUserParameterState { * @param name a [String] object. * @param val a double. */ - fun add(name: String, `val`: Double) { - theParameters.add(name, `val`) + fun add(name: String, value: Double) { + theParameters.add(name, value) theValid = true } @@ -331,8 +331,8 @@ class MnUserParameterState { return theParameters.errors() } - fun ext2int(i: Int, `val`: Double): Double { - return theParameters.trafo().ext2int(i, `val`) + fun ext2int(i: Int, value: Double): Double { + return theParameters.trafo().ext2int(i, value) } /** @@ -426,8 +426,8 @@ class MnUserParameterState { } // transformation internal <-> external - fun int2ext(i: Int, `val`: Double): Double { - return theParameters.trafo().int2ext(i, `val`) + fun int2ext(i: Int, value: Double): Double { + return theParameters.trafo().int2ext(i, value) } fun intCovariance(): MnUserCovariance { @@ -700,14 +700,14 @@ class MnUserParameterState { * @param e a int. * @param val a double. */ - fun setValue(e: Int, `val`: Double) { - theParameters.setValue(e, `val`) + fun setValue(e: Int, value: Double) { + theParameters.setValue(e, value) if (!parameter(e).isFixed() && !parameter(e).isConst()) { val i = intOfExt(e) if (parameter(e).hasLimits()) { - theIntParameters[i] = ext2int(e, `val`) + theIntParameters[i] = ext2int(e, value) } else { - theIntParameters[i] = `val` + theIntParameters[i] = value } } } @@ -719,8 +719,8 @@ class MnUserParameterState { * @param name a [String] object. * @param val a double. */ - fun setValue(name: String?, `val`: Double) { - setValue(index(name), `val`) + fun setValue(name: String?, value: Double) { + setValue(index(name), value) } /** {@inheritDoc} */ diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameters.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameters.kt index 9bac54b25..bdbefb4d1 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameters.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnUserParameters.kt @@ -65,8 +65,8 @@ class MnUserParameters { * @param val a double. * @param name a [String] object. */ - fun add(name: String, `val`: Double, err: Double) { - theTransformation.add(name, `val`, err) + fun add(name: String, value: Double, err: Double) { + theTransformation.add(name, value, err) } /** @@ -78,8 +78,8 @@ class MnUserParameters { * @param val a double. * @param err a double. */ - fun add(name: String, `val`: Double, err: Double, low: Double, up: Double) { - theTransformation.add(name, `val`, err, low, up) + fun add(name: String, value: Double, err: Double, low: Double, up: Double) { + theTransformation.add(name, value, err, low, up) } /** @@ -88,8 +88,8 @@ class MnUserParameters { * @param name a [String] object. * @param val a double. */ - fun add(name: String, `val`: Double) { - theTransformation.add(name, `val`) + fun add(name: String, value: Double) { + theTransformation.add(name, value) } /** @@ -344,8 +344,8 @@ class MnUserParameters { * @param index a int. * @param val a double. */ - fun setValue(index: Int, `val`: Double) { - theTransformation.setValue(index, `val`) + fun setValue(index: Int, value: Double) { + theTransformation.setValue(index, value) } /** @@ -355,8 +355,8 @@ class MnUserParameters { * @param name a [String] object. * @param val a double. */ - fun setValue(name: String?, `val`: Double) { - theTransformation.setValue(name, `val`) + fun setValue(name: String?, value: Double) { + theTransformation.setValue(name, value) } /** {@inheritDoc} */ diff --git a/kmath-optimization/src/commonMain/tmp/minuit/MnUserTransformation.kt b/kmath-optimization/src/commonMain/tmp/minuit/MnUserTransformation.kt index c587d3244..ca17611b1 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/MnUserTransformation.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/MnUserTransformation.kt @@ -64,12 +64,12 @@ class MnUserTransformation { * @param err * @param val */ - fun add(name: String, `val`: Double, err: Double) { + fun add(name: String, value: Double, err: Double) { require(!nameMap.containsKey(name)) { "duplicate name: $name" } nameMap[name] = theParameters.size theExtOfInt.add(theParameters.size) - theCache.add(`val`) - theParameters.add(MinuitParameter(theParameters.size, name, `val`, err)) + theCache.add(value) + theParameters.add(MinuitParameter(theParameters.size, name, value, err)) } /** @@ -77,12 +77,12 @@ class MnUserTransformation { * @param up * @param low */ - fun add(name: String, `val`: Double, err: Double, low: Double, up: Double) { + fun add(name: String, value: Double, err: Double, low: Double, up: Double) { require(!nameMap.containsKey(name)) { "duplicate name: $name" } nameMap[name] = theParameters.size theExtOfInt.add(theParameters.size) - theCache.add(`val`) - theParameters.add(MinuitParameter(theParameters.size, name, `val`, err, low, up)) + theCache.add(value) + theParameters.add(MinuitParameter(theParameters.size, name, value, err, low, up)) } /** @@ -90,11 +90,11 @@ class MnUserTransformation { * @param name * @param val */ - fun add(name: String, `val`: Double) { + fun add(name: String, value: Double) { require(!nameMap.containsKey(name)) { "duplicate name: $name" } nameMap[name] = theParameters.size - theCache.add(`val`) - theParameters.add(MinuitParameter(theParameters.size, name, `val`)) + theCache.add(value) + theParameters.add(MinuitParameter(theParameters.size, name, value)) } /** @@ -107,20 +107,20 @@ class MnUserTransformation { return MnUserTransformation(this) } - fun dInt2Ext(i: Int, `val`: Double): Double { + fun dInt2Ext(i: Int, value: Double): Double { var dd = 1.0 val parm: MinuitParameter = theParameters[theExtOfInt[i]] if (parm.hasLimits()) { dd = if (parm.hasUpperLimit() && parm.hasLowerLimit()) { theDoubleLimTrafo.dInt2Ext( - `val`, + value, parm.upperLimit(), parm.lowerLimit() ) } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { - theUpperLimTrafo.dInt2Ext(`val`, parm.upperLimit()) + theUpperLimTrafo.dInt2Ext(value, parm.upperLimit()) } else { - theLowerLimTrafo.dInt2Ext(`val`, parm.lowerLimit()) + theLowerLimTrafo.dInt2Ext(value, parm.lowerLimit()) } } return dd @@ -143,30 +143,30 @@ class MnUserTransformation { return result } - fun ext2int(i: Int, `val`: Double): Double { + fun ext2int(i: Int, value: Double): Double { val parm: MinuitParameter = theParameters[i] return if (parm.hasLimits()) { if (parm.hasUpperLimit() && parm.hasLowerLimit()) { theDoubleLimTrafo.ext2int( - `val`, + value, parm.upperLimit(), parm.lowerLimit(), precision() ) } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { theUpperLimTrafo.ext2int( - `val`, + value, parm.upperLimit(), precision() ) } else { theLowerLimTrafo.ext2int( - `val`, + value, parm.lowerLimit(), precision() ) } - } else `val` + } else value } fun extOfInt(internal: Int): Int { @@ -200,21 +200,21 @@ class MnUserTransformation { return nameMap[name]!! } - fun int2ext(i: Int, `val`: Double): Double { + fun int2ext(i: Int, value: Double): Double { val parm: MinuitParameter = theParameters[theExtOfInt[i]] return if (parm.hasLimits()) { if (parm.hasUpperLimit() && parm.hasLowerLimit()) { theDoubleLimTrafo.int2ext( - `val`, + value, parm.upperLimit(), parm.lowerLimit() ) } else if (parm.hasUpperLimit() && !parm.hasLowerLimit()) { - theUpperLimTrafo.int2ext(`val`, parm.upperLimit()) + theUpperLimTrafo.int2ext(value, parm.upperLimit()) } else { - theLowerLimTrafo.int2ext(`val`, parm.lowerLimit()) + theLowerLimTrafo.int2ext(value, parm.lowerLimit()) } - } else `val` + } else value } fun int2extCovariance(vec: RealVector, cov: MnAlgebraicSymMatrix): MnUserCovariance { @@ -235,13 +235,13 @@ class MnUserTransformation { return result } - fun int2extError(i: Int, `val`: Double, err: Double): Double { + fun int2extError(i: Int, value: Double, err: Double): Double { var dx = err val parm: MinuitParameter = theParameters[theExtOfInt[i]] if (parm.hasLimits()) { - val ui = int2ext(i, `val`) - var du1 = int2ext(i, `val` + dx) - ui - val du2 = int2ext(i, `val` - dx) - ui + val ui = int2ext(i, value) + var du1 = int2ext(i, value + dx) - ui + val du2 = int2ext(i, value - dx) - ui if (parm.hasUpperLimit() && parm.hasLowerLimit()) { if (dx > 1.0) { du1 = parm.upperLimit() - parm.lowerLimit() @@ -354,13 +354,13 @@ class MnUserTransformation { setUpperLimit(index(name), up) } - fun setValue(index: Int, `val`: Double) { - theParameters[index].setValue(`val`) - theCache[index] = `val` + fun setValue(index: Int, value: Double) { + theParameters[index].setValue(value) + theCache[index] = value } - fun setValue(name: String?, `val`: Double) { - setValue(index(name), `val`) + fun setValue(name: String?, value: Double) { + setValue(index(name), value) } fun transform(pstates: RealVector): ArrayRealVector { diff --git a/kmath-optimization/src/commonMain/tmp/minuit/NegativeG2LineSearch.kt b/kmath-optimization/src/commonMain/tmp/minuit/NegativeG2LineSearch.kt index 50266f45c..bc2b35234 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/NegativeG2LineSearch.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/NegativeG2LineSearch.kt @@ -71,10 +71,7 @@ internal object NegativeG2LineSearch { } while (iter++ < 2 * n && iterate) val mat = MnAlgebraicSymMatrix(n) for (i in 0 until n) { - mat[i, i] = if (abs( - dgrad.getGradientDerivative() - .getEntry(i) - ) > prec.eps2() + mat[i, i] = if (abs(dgrad.getGradientDerivative().getEntry(i)) > prec.eps2() ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 } val err = MinimumError(mat, 1.0) diff --git a/kmath-optimization/src/commonMain/tmp/minuit/SimplexSeedGenerator.kt b/kmath-optimization/src/commonMain/tmp/minuit/SimplexSeedGenerator.kt index 5423820f6..21f1868eb 100644 --- a/kmath-optimization/src/commonMain/tmp/minuit/SimplexSeedGenerator.kt +++ b/kmath-optimization/src/commonMain/tmp/minuit/SimplexSeedGenerator.kt @@ -41,10 +41,7 @@ internal class SimplexSeedGenerator : MinimumSeedGenerator { val mat = MnAlgebraicSymMatrix(n) val dcovar = 1.0 for (i in 0 until n) { - mat[i, i] = if (abs( - dgrad.getGradientDerivative() - .getEntry(i) - ) > prec.eps2() + mat[i, i] = if (abs(dgrad.getGradientDerivative().getEntry(i)) > prec.eps2() ) 1.0 / dgrad.getGradientDerivative().getEntry(i) else 1.0 } val err = MinimumError(mat, dcovar) From 9228e6019c94a4b813c21dfbfffb30a1cb6cf35b Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Mon, 15 Apr 2024 17:57:00 +0300 Subject: [PATCH 102/103] Update Attributes version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 537cc2708..d90529e08 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { id("org.jetbrains.kotlinx.kover") version "0.7.6" } -val attributesVersion by extra("0.1.0") +val attributesVersion by extra("0.2.0") allprojects { repositories { From fc0393436f1e9698370099b0e9d03fc53ceb85cf Mon Sep 17 00:00:00 2001 From: Alexander Nozik <altavir@gmail.com> Date: Mon, 15 Apr 2024 18:01:58 +0300 Subject: [PATCH 103/103] Document `ShapeND.asArray()` --- .../src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt index dee22e49f..d5cdc6286 100644 --- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt +++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/ShapeND.kt @@ -68,6 +68,9 @@ public operator fun ShapeND.component3(): Int = get(2) */ public fun ShapeND.toArray(): IntArray = array.copyOf() +/** + * Provide internal content of [ShapeND]. Must not be modified. + */ @UnsafeKMathAPI public fun ShapeND.asArray(): IntArray = array