forked from kscience/kmath
Minor refactoring + domains
This commit is contained in:
parent
71846a3279
commit
668d13c9d1
@ -2,7 +2,7 @@ plugins {
|
|||||||
id("scientifik.publish") apply false
|
id("scientifik.publish") apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
val kmathVersion by extra("0.1.4-dev-7")
|
val kmathVersion by extra("0.1.4-dev-8")
|
||||||
|
|
||||||
val bintrayRepo by extra("scientifik")
|
val bintrayRepo by extra("scientifik")
|
||||||
val githubProject by extra("kmath")
|
val githubProject by extra("kmath")
|
||||||
|
@ -4,8 +4,8 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
|
|||||||
plugins {
|
plugins {
|
||||||
java
|
java
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
kotlin("plugin.allopen") version "1.3.71"
|
kotlin("plugin.allopen") version "1.3.72"
|
||||||
id("kotlinx.benchmark") version "0.2.0-dev-7"
|
id("kotlinx.benchmark") version "0.2.0-dev-8"
|
||||||
}
|
}
|
||||||
|
|
||||||
configure<AllOpenExtension> {
|
configure<AllOpenExtension> {
|
||||||
@ -33,8 +33,8 @@ dependencies {
|
|||||||
implementation(project(":kmath-dimensions"))
|
implementation(project(":kmath-dimensions"))
|
||||||
implementation("com.kyonifer:koma-core-ejml:0.12")
|
implementation("com.kyonifer:koma-core-ejml:0.12")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.2.0-npm-dev-6")
|
implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.2.0-npm-dev-6")
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-7")
|
implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-8")
|
||||||
"benchmarksCompile"(sourceSets.main.get().compileClasspath)
|
"benchmarksCompile"(sourceSets.main.get().output + sourceSets.main.get().compileClasspath) //sourceSets.main.output + sourceSets.main.runtimeClasspath
|
||||||
}
|
}
|
||||||
|
|
||||||
// Configure benchmark
|
// Configure benchmark
|
||||||
|
@ -20,7 +20,7 @@ class ViktorBenchmark {
|
|||||||
final val viktorField = ViktorNDField(intArrayOf(dim, dim))
|
final val viktorField = ViktorNDField(intArrayOf(dim, dim))
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun `Automatic field addition`() {
|
fun automaticFieldAddition() {
|
||||||
autoField.run {
|
autoField.run {
|
||||||
var res = one
|
var res = one
|
||||||
repeat(n) {
|
repeat(n) {
|
||||||
@ -30,7 +30,7 @@ class ViktorBenchmark {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun `Viktor field addition`() {
|
fun viktorFieldAddition() {
|
||||||
viktorField.run {
|
viktorField.run {
|
||||||
var res = one
|
var res = one
|
||||||
repeat(n) {
|
repeat(n) {
|
||||||
@ -40,7 +40,7 @@ class ViktorBenchmark {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun `Raw Viktor`() {
|
fun rawViktor() {
|
||||||
val one = F64Array.full(init = 1.0, shape = *intArrayOf(dim, dim))
|
val one = F64Array.full(init = 1.0, shape = *intArrayOf(dim, dim))
|
||||||
var res = one
|
var res = one
|
||||||
repeat(n) {
|
repeat(n) {
|
||||||
@ -49,7 +49,7 @@ class ViktorBenchmark {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun `Real field log`() {
|
fun realdFieldLog() {
|
||||||
realField.run {
|
realField.run {
|
||||||
val fortyTwo = produce { 42.0 }
|
val fortyTwo = produce { 42.0 }
|
||||||
var res = one
|
var res = one
|
||||||
@ -61,7 +61,7 @@ class ViktorBenchmark {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Benchmark
|
@Benchmark
|
||||||
fun `Raw Viktor log`() {
|
fun rawViktorLog() {
|
||||||
val fortyTwo = F64Array.full(dim, dim, init = 42.0)
|
val fortyTwo = F64Array.full(dim, dim, init = 42.0)
|
||||||
var res: F64Array
|
var res: F64Array
|
||||||
repeat(n) {
|
repeat(n) {
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package scientifik.kmath.commons.random
|
||||||
|
|
||||||
|
import scientifik.kmath.prob.RandomGenerator
|
||||||
|
|
||||||
|
class CMRandomGeneratorWrapper(val factory: (IntArray) -> RandomGenerator) :
|
||||||
|
org.apache.commons.math3.random.RandomGenerator {
|
||||||
|
private var generator = factory(intArrayOf())
|
||||||
|
|
||||||
|
override fun nextBoolean(): Boolean = generator.nextBoolean()
|
||||||
|
|
||||||
|
override fun nextFloat(): Float = generator.nextDouble().toFloat()
|
||||||
|
|
||||||
|
override fun setSeed(seed: Int) {
|
||||||
|
generator = factory(intArrayOf(seed))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setSeed(seed: IntArray) {
|
||||||
|
generator = factory(seed)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setSeed(seed: Long) {
|
||||||
|
setSeed(seed.toInt())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextBytes(bytes: ByteArray) {
|
||||||
|
generator.fillBytes(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nextInt(): Int = generator.nextInt()
|
||||||
|
|
||||||
|
override fun nextInt(n: Int): Int = generator.nextInt(n)
|
||||||
|
|
||||||
|
override fun nextGaussian(): Double = TODO()
|
||||||
|
|
||||||
|
override fun nextDouble(): Double = generator.nextDouble()
|
||||||
|
|
||||||
|
override fun nextLong(): Long = generator.nextLong()
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package scientifik.kmath.domains
|
||||||
|
|
||||||
|
import scientifik.kmath.linear.Point
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple geometric domain
|
||||||
|
*/
|
||||||
|
interface Domain<T : Any> {
|
||||||
|
operator fun contains(point: Point<T>): Boolean
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of hyperspace dimensions
|
||||||
|
*/
|
||||||
|
val dimension: Int
|
||||||
|
}
|
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Alexander Nozik.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package scientifik.kmath.domains
|
||||||
|
|
||||||
|
import scientifik.kmath.linear.Point
|
||||||
|
import scientifik.kmath.structures.DoubleBuffer
|
||||||
|
import scientifik.kmath.structures.indices
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* HyperSquareDomain class.
|
||||||
|
*
|
||||||
|
* @author Alexander Nozik
|
||||||
|
*/
|
||||||
|
class HyperSquareDomain(private val lower: DoubleBuffer, private val upper: DoubleBuffer) : RealDomain {
|
||||||
|
|
||||||
|
override operator fun contains(point: Point<Double>): Boolean = point.indices.all { i ->
|
||||||
|
point[i] in lower[i]..upper[i]
|
||||||
|
}
|
||||||
|
|
||||||
|
override val dimension: Int get() = lower.size
|
||||||
|
|
||||||
|
override fun getLowerBound(num: Int, point: Point<Double>): Double? = lower[num]
|
||||||
|
|
||||||
|
override fun getLowerBound(num: Int): Double? = lower[num]
|
||||||
|
|
||||||
|
override fun getUpperBound(num: Int, point: Point<Double>): Double? = upper[num]
|
||||||
|
|
||||||
|
override fun getUpperBound(num: Int): Double? = upper[num]
|
||||||
|
|
||||||
|
override fun nearestInDomain(point: Point<Double>): Point<Double> {
|
||||||
|
val res: DoubleArray = DoubleArray(point.size) { i ->
|
||||||
|
when {
|
||||||
|
point[i] < lower[i] -> lower[i]
|
||||||
|
point[i] > upper[i] -> upper[i]
|
||||||
|
else -> point[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return DoubleBuffer(*res)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun volume(): Double {
|
||||||
|
var res = 1.0
|
||||||
|
for (i in 0 until dimension) {
|
||||||
|
if (lower[i].isInfinite() || upper[i].isInfinite()) {
|
||||||
|
return Double.POSITIVE_INFINITY
|
||||||
|
}
|
||||||
|
if (upper[i] > lower[i]) {
|
||||||
|
res *= upper[i] - lower[i]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Alexander Nozik.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package scientifik.kmath.domains
|
||||||
|
|
||||||
|
import scientifik.kmath.linear.Point
|
||||||
|
|
||||||
|
/**
|
||||||
|
* n-dimensional volume
|
||||||
|
*
|
||||||
|
* @author Alexander Nozik
|
||||||
|
*/
|
||||||
|
interface RealDomain: Domain<Double> {
|
||||||
|
|
||||||
|
fun nearestInDomain(point: Point<Double>): Point<Double>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The lower edge for the domain going down from point
|
||||||
|
* @param num
|
||||||
|
* @param point
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
fun getLowerBound(num: Int, point: Point<Double>): Double?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The upper edge of the domain going up from point
|
||||||
|
* @param num
|
||||||
|
* @param point
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
fun getUpperBound(num: Int, point: Point<Double>): Double?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global lower edge
|
||||||
|
* @param num
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
fun getLowerBound(num: Int): Double?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Global upper edge
|
||||||
|
* @param num
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
fun getUpperBound(num: Int): Double?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hyper volume
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
fun volume(): Double
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2015 Alexander Nozik.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package scientifik.kmath.domains
|
||||||
|
|
||||||
|
import scientifik.kmath.linear.Point
|
||||||
|
|
||||||
|
class UnconstrainedDomain(override val dimension: Int) : RealDomain {
|
||||||
|
|
||||||
|
override operator fun contains(point: Point<Double>): Boolean = true
|
||||||
|
|
||||||
|
override fun getLowerBound(num: Int, point: Point<Double>): Double? = Double.NEGATIVE_INFINITY
|
||||||
|
|
||||||
|
override fun getLowerBound(num: Int): Double? = Double.NEGATIVE_INFINITY
|
||||||
|
|
||||||
|
override fun getUpperBound(num: Int, point: Point<Double>): Double? = Double.POSITIVE_INFINITY
|
||||||
|
|
||||||
|
override fun getUpperBound(num: Int): Double? = Double.POSITIVE_INFINITY
|
||||||
|
|
||||||
|
override fun nearestInDomain(point: Point<Double>): Point<Double> = point
|
||||||
|
|
||||||
|
override fun volume(): Double = Double.POSITIVE_INFINITY
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package scientifik.kmath.domains
|
||||||
|
|
||||||
|
import scientifik.kmath.linear.Point
|
||||||
|
import scientifik.kmath.structures.asBuffer
|
||||||
|
|
||||||
|
inline class UnivariateDomain(val range: ClosedFloatingPointRange<Double>) : RealDomain {
|
||||||
|
|
||||||
|
operator fun contains(d: Double): Boolean = range.contains(d)
|
||||||
|
|
||||||
|
override operator fun contains(point: Point<Double>): Boolean {
|
||||||
|
require(point.size == 0)
|
||||||
|
return contains(point[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun nearestInDomain(point: Point<Double>): Point<Double> {
|
||||||
|
require(point.size == 1)
|
||||||
|
val value = point[0]
|
||||||
|
return when{
|
||||||
|
value in range -> point
|
||||||
|
value >= range.endInclusive -> doubleArrayOf(range.endInclusive).asBuffer()
|
||||||
|
else -> doubleArrayOf(range.start).asBuffer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLowerBound(num: Int, point: Point<Double>): Double? {
|
||||||
|
require(num == 0)
|
||||||
|
return range.start
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUpperBound(num: Int, point: Point<Double>): Double? {
|
||||||
|
require(num == 0)
|
||||||
|
return range.endInclusive
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getLowerBound(num: Int): Double? {
|
||||||
|
require(num == 0)
|
||||||
|
return range.start
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getUpperBound(num: Int): Double? {
|
||||||
|
require(num == 0)
|
||||||
|
return range.endInclusive
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun volume(): Double = range.endInclusive - range.start
|
||||||
|
|
||||||
|
override val dimension: Int get() = 1
|
||||||
|
}
|
@ -12,26 +12,23 @@ import scientifik.kmath.structures.asBuffer
|
|||||||
import scientifik.kmath.structures.asIterable
|
import scientifik.kmath.structures.asIterable
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
typealias RealPoint = Point<Double>
|
||||||
|
|
||||||
fun DoubleArray.asVector() = RealVector(this.asBuffer())
|
fun DoubleArray.asVector() = RealVector(this.asBuffer())
|
||||||
fun List<Double>.asVector() = RealVector(this.asBuffer())
|
fun List<Double>.asVector() = RealVector(this.asBuffer())
|
||||||
|
|
||||||
|
|
||||||
object VectorL2Norm : Norm<Point<out Number>, Double> {
|
object VectorL2Norm : Norm<Point<out Number>, Double> {
|
||||||
override fun norm(arg: Point<out Number>): Double = sqrt(arg.asIterable().sumByDouble { it.toDouble() })
|
override fun norm(arg: Point<out Number>): Double = sqrt(arg.asIterable().sumByDouble { it.toDouble() })
|
||||||
}
|
}
|
||||||
|
|
||||||
inline class RealVector(private val point: Point<Double>) :
|
inline class RealVector(private val point: Point<Double>) :
|
||||||
SpaceElement<Point<Double>, RealVector, VectorSpace<Double, RealField>>, Point<Double> {
|
SpaceElement<RealPoint, RealVector, VectorSpace<Double, RealField>>, RealPoint {
|
||||||
|
|
||||||
override val context: VectorSpace<Double, RealField>
|
override val context: VectorSpace<Double, RealField> get() = space(point.size)
|
||||||
get() = space(
|
|
||||||
point.size
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun unwrap(): Point<Double> = point
|
override fun unwrap(): RealPoint = point
|
||||||
|
|
||||||
override fun Point<Double>.wrap(): RealVector =
|
override fun RealPoint.wrap(): RealVector = RealVector(this)
|
||||||
RealVector(this)
|
|
||||||
|
|
||||||
override val size: Int get() = point.size
|
override val size: Int get() = point.size
|
||||||
|
|
||||||
@ -48,12 +45,8 @@ inline class RealVector(private val point: Point<Double>) :
|
|||||||
|
|
||||||
operator fun invoke(vararg values: Double): RealVector = values.asVector()
|
operator fun invoke(vararg values: Double): RealVector = values.asVector()
|
||||||
|
|
||||||
fun space(dim: Int): BufferVectorSpace<Double, RealField> =
|
fun space(dim: Int): BufferVectorSpace<Double, RealField> = spaceCache.getOrPut(dim) {
|
||||||
spaceCache.getOrPut(dim) {
|
BufferVectorSpace(dim, RealField) { size, init -> Buffer.real(size, init) }
|
||||||
BufferVectorSpace(
|
}
|
||||||
dim,
|
|
||||||
RealField
|
|
||||||
) { size, init -> Buffer.real(size, init) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -27,6 +27,10 @@ typealias RealMatrix = Matrix<Double>
|
|||||||
fun realMatrix(rowNum: Int, colNum: Int, initializer: (i: Int, j: Int) -> Double): RealMatrix =
|
fun realMatrix(rowNum: Int, colNum: Int, initializer: (i: Int, j: Int) -> Double): RealMatrix =
|
||||||
MatrixContext.real.produce(rowNum, colNum, initializer)
|
MatrixContext.real.produce(rowNum, colNum, initializer)
|
||||||
|
|
||||||
|
fun Array<DoubleArray>.toMatrix(): RealMatrix{
|
||||||
|
return MatrixContext.real.produce(size, this[0].size) { row, col -> this[row][col] }
|
||||||
|
}
|
||||||
|
|
||||||
fun Sequence<DoubleArray>.toMatrix(): RealMatrix = toList().let {
|
fun Sequence<DoubleArray>.toMatrix(): RealMatrix = toList().let {
|
||||||
MatrixContext.real.produce(it.size, it[0].size) { row, col -> it[row][col] }
|
MatrixContext.real.produce(it.size, it[0].size) { row, col -> it[row][col] }
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,10 @@
|
|||||||
package scientifik.kmath.histogram
|
package scientifik.kmath.histogram
|
||||||
|
|
||||||
|
import scientifik.kmath.domains.Domain
|
||||||
import scientifik.kmath.linear.Point
|
import scientifik.kmath.linear.Point
|
||||||
import scientifik.kmath.structures.ArrayBuffer
|
import scientifik.kmath.structures.ArrayBuffer
|
||||||
import scientifik.kmath.structures.DoubleBuffer
|
import scientifik.kmath.structures.DoubleBuffer
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple geometric domain
|
|
||||||
* TODO move to geometry module
|
|
||||||
*/
|
|
||||||
interface Domain<T : Any> {
|
|
||||||
operator fun contains(vector: Point<out T>): Boolean
|
|
||||||
val dimension: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The bin in the histogram. The histogram is by definition always done in the real space
|
* The bin in the histogram. The histogram is by definition always done in the real space
|
||||||
*/
|
*/
|
||||||
|
@ -10,6 +10,7 @@ interface MemorySpec<T : Any> {
|
|||||||
val objectSize: Int
|
val objectSize: Int
|
||||||
|
|
||||||
fun MemoryReader.read(offset: Int): T
|
fun MemoryReader.read(offset: Int): T
|
||||||
|
//TODO consider thread safety
|
||||||
fun MemoryWriter.write(offset: Int, value: T)
|
fun MemoryWriter.write(offset: Int, value: T)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user