Add more explicit public modifiers

This commit is contained in:
Iaroslav Postovalov 2020-09-09 21:12:18 +07:00
parent 96a7edc497
commit 8ae9a071ef
No known key found for this signature in database
GPG Key ID: 70D5F4DCB0972F1B
29 changed files with 298 additions and 319 deletions

View File

@ -15,8 +15,8 @@ public class DerivativeStructureField(
public val order: Int, public val order: Int,
public val parameters: Map<String, Double> public val parameters: Map<String, Double>
) : ExtendedField<DerivativeStructure> { ) : ExtendedField<DerivativeStructure> {
override val zero: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size) } public override val zero: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size) }
override val one: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size, 1.0) } public override val one: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size, 1.0) }
private val variables: Map<String, DerivativeStructure> = parameters.mapValues { (key, value) -> private val variables: Map<String, DerivativeStructure> = parameters.mapValues { (key, value) ->
DerivativeStructure(parameters.size, order, parameters.keys.indexOf(key), value) DerivativeStructure(parameters.size, order, parameters.keys.indexOf(key), value)
@ -40,46 +40,43 @@ public class DerivativeStructureField(
} }
public fun DerivativeStructure.deriv(vararg orders: Pair<String, Int>): Double = deriv(mapOf(*orders)) public fun DerivativeStructure.deriv(vararg orders: Pair<String, Int>): Double = deriv(mapOf(*orders))
public override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b)
override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b) public override fun multiply(a: DerivativeStructure, k: Number): DerivativeStructure = when (k) {
override fun multiply(a: DerivativeStructure, k: Number): DerivativeStructure = when (k) {
is Double -> a.multiply(k) is Double -> a.multiply(k)
is Int -> a.multiply(k) is Int -> a.multiply(k)
else -> a.multiply(k.toDouble()) else -> a.multiply(k.toDouble())
} }
override fun multiply(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.multiply(b) public override fun multiply(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.multiply(b)
public override fun divide(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.divide(b)
public override fun sin(arg: DerivativeStructure): DerivativeStructure = arg.sin()
public override fun cos(arg: DerivativeStructure): DerivativeStructure = arg.cos()
public override fun tan(arg: DerivativeStructure): DerivativeStructure = arg.tan()
public override fun asin(arg: DerivativeStructure): DerivativeStructure = arg.asin()
public override fun acos(arg: DerivativeStructure): DerivativeStructure = arg.acos()
public override fun atan(arg: DerivativeStructure): DerivativeStructure = arg.atan()
public override fun sinh(arg: DerivativeStructure): DerivativeStructure = arg.sinh()
public override fun cosh(arg: DerivativeStructure): DerivativeStructure = arg.cosh()
public override fun tanh(arg: DerivativeStructure): DerivativeStructure = arg.tanh()
public override fun asinh(arg: DerivativeStructure): DerivativeStructure = arg.asinh()
public override fun acosh(arg: DerivativeStructure): DerivativeStructure = arg.acosh()
public override fun atanh(arg: DerivativeStructure): DerivativeStructure = arg.atanh()
override fun divide(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.divide(b) public override fun power(arg: DerivativeStructure, pow: Number): DerivativeStructure = when (pow) {
override fun sin(arg: DerivativeStructure): DerivativeStructure = arg.sin()
override fun cos(arg: DerivativeStructure): DerivativeStructure = arg.cos()
override fun tan(arg: DerivativeStructure): DerivativeStructure = arg.tan()
override fun asin(arg: DerivativeStructure): DerivativeStructure = arg.asin()
override fun acos(arg: DerivativeStructure): DerivativeStructure = arg.acos()
override fun atan(arg: DerivativeStructure): DerivativeStructure = arg.atan()
override fun sinh(arg: DerivativeStructure): DerivativeStructure = arg.sinh()
override fun cosh(arg: DerivativeStructure): DerivativeStructure = arg.cosh()
override fun tanh(arg: DerivativeStructure): DerivativeStructure = arg.tanh()
override fun asinh(arg: DerivativeStructure): DerivativeStructure = arg.asinh()
override fun acosh(arg: DerivativeStructure): DerivativeStructure = arg.acosh()
override fun atanh(arg: DerivativeStructure): DerivativeStructure = arg.atanh()
override fun power(arg: DerivativeStructure, pow: Number): DerivativeStructure = when (pow) {
is Double -> arg.pow(pow) is Double -> arg.pow(pow)
is Int -> arg.pow(pow) is Int -> arg.pow(pow)
else -> arg.pow(pow.toDouble()) else -> arg.pow(pow.toDouble())
} }
public fun power(arg: DerivativeStructure, pow: DerivativeStructure): DerivativeStructure = arg.pow(pow) public fun power(arg: DerivativeStructure, pow: DerivativeStructure): DerivativeStructure = arg.pow(pow)
override fun exp(arg: DerivativeStructure): DerivativeStructure = arg.exp() public override fun exp(arg: DerivativeStructure): DerivativeStructure = arg.exp()
override fun ln(arg: DerivativeStructure): DerivativeStructure = arg.log() public override fun ln(arg: DerivativeStructure): DerivativeStructure = arg.log()
override operator fun DerivativeStructure.plus(b: Number): DerivativeStructure = add(b.toDouble()) public override operator fun DerivativeStructure.plus(b: Number): DerivativeStructure = add(b.toDouble())
override operator fun DerivativeStructure.minus(b: Number): DerivativeStructure = subtract(b.toDouble()) public override operator fun DerivativeStructure.minus(b: Number): DerivativeStructure = subtract(b.toDouble())
override operator fun Number.plus(b: DerivativeStructure): DerivativeStructure = b + this public override operator fun Number.plus(b: DerivativeStructure): DerivativeStructure = b + this
override operator fun Number.minus(b: DerivativeStructure): DerivativeStructure = b - this public override operator fun Number.minus(b: DerivativeStructure): DerivativeStructure = b - this
} }
/** /**
@ -87,10 +84,10 @@ public class DerivativeStructureField(
*/ */
public class DiffExpression(public val function: DerivativeStructureField.() -> DerivativeStructure) : public class DiffExpression(public val function: DerivativeStructureField.() -> DerivativeStructure) :
Expression<Double> { Expression<Double> {
override operator fun invoke(arguments: Map<String, Double>): Double = DerivativeStructureField( public override operator fun invoke(arguments: Map<String, Double>): Double = DerivativeStructureField(
0, 0,
arguments arguments
).run(function).value ).function().value
/** /**
* Get the derivative expression with given orders * Get the derivative expression with given orders
@ -110,25 +107,22 @@ public fun DiffExpression.derivative(name: String): Expression<Double> = derivat
* A context for [DiffExpression] (not to be confused with [DerivativeStructure]) * A context for [DiffExpression] (not to be confused with [DerivativeStructure])
*/ */
public object DiffExpressionAlgebra : ExpressionAlgebra<Double, DiffExpression>, Field<DiffExpression> { public object DiffExpressionAlgebra : ExpressionAlgebra<Double, DiffExpression>, Field<DiffExpression> {
override fun variable(name: String, default: Double?): DiffExpression = public override val zero: DiffExpression = DiffExpression { 0.0.const() }
public override val one: DiffExpression = DiffExpression { 1.0.const() }
public override fun variable(name: String, default: Double?): DiffExpression =
DiffExpression { variable(name, default?.const()) } DiffExpression { variable(name, default?.const()) }
override fun const(value: Double): DiffExpression = public override fun const(value: Double): DiffExpression = DiffExpression { value.const() }
DiffExpression { value.const() }
override fun add(a: DiffExpression, b: DiffExpression): DiffExpression = public override fun add(a: DiffExpression, b: DiffExpression): DiffExpression =
DiffExpression { a.function(this) + b.function(this) } DiffExpression { a.function(this) + b.function(this) }
override val zero: DiffExpression = DiffExpression { 0.0.const() } public override fun multiply(a: DiffExpression, k: Number): DiffExpression = DiffExpression { a.function(this) * k }
override fun multiply(a: DiffExpression, k: Number): DiffExpression = public override fun multiply(a: DiffExpression, b: DiffExpression): DiffExpression =
DiffExpression { a.function(this) * k }
override val one: DiffExpression = DiffExpression { 1.0.const() }
override fun multiply(a: DiffExpression, b: DiffExpression): DiffExpression =
DiffExpression { a.function(this) * b.function(this) } DiffExpression { a.function(this) * b.function(this) }
override fun divide(a: DiffExpression, b: DiffExpression): DiffExpression = public override fun divide(a: DiffExpression, b: DiffExpression): DiffExpression =
DiffExpression { a.function(this) / b.function(this) } DiffExpression { a.function(this) / b.function(this) }
} }

View File

@ -5,32 +5,32 @@ import scientifik.kmath.linear.*
import scientifik.kmath.structures.Matrix import scientifik.kmath.structures.Matrix
import scientifik.kmath.structures.NDStructure import scientifik.kmath.structures.NDStructure
class CMMatrix(val origin: RealMatrix, features: Set<MatrixFeature>? = null) : public class CMMatrix(public val origin: RealMatrix, features: Set<MatrixFeature>? = null) :
FeaturedMatrix<Double> { FeaturedMatrix<Double> {
override val rowNum: Int get() = origin.rowDimension public override val rowNum: Int get() = origin.rowDimension
override val colNum: Int get() = origin.columnDimension public override val colNum: Int get() = origin.columnDimension
override val features: Set<MatrixFeature> = features ?: sequence<MatrixFeature> { public override val features: Set<MatrixFeature> = features ?: sequence<MatrixFeature> {
if (origin is DiagonalMatrix) yield(DiagonalFeature) if (origin is DiagonalMatrix) yield(DiagonalFeature)
}.toHashSet() }.toHashSet()
override fun suggestFeature(vararg features: MatrixFeature): CMMatrix = public override fun suggestFeature(vararg features: MatrixFeature): CMMatrix =
CMMatrix(origin, this.features + features) CMMatrix(origin, this.features + features)
override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j) public override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j)
override fun equals(other: Any?): Boolean { public override fun equals(other: Any?): Boolean {
return NDStructure.equals(this, other as? NDStructure<*> ?: return false) return NDStructure.equals(this, other as? NDStructure<*> ?: return false)
} }
override fun hashCode(): Int { public override fun hashCode(): Int {
var result = origin.hashCode() var result = origin.hashCode()
result = 31 * result + features.hashCode() result = 31 * result + features.hashCode()
return result return result
} }
} }
fun Matrix<Double>.toCM(): CMMatrix = if (this is CMMatrix) { public fun Matrix<Double>.toCM(): CMMatrix = if (this is CMMatrix) {
this this
} else { } else {
//TODO add feature analysis //TODO add feature analysis
@ -38,56 +38,56 @@ fun Matrix<Double>.toCM(): CMMatrix = if (this is CMMatrix) {
CMMatrix(Array2DRowRealMatrix(array)) CMMatrix(Array2DRowRealMatrix(array))
} }
fun RealMatrix.asMatrix(): CMMatrix = CMMatrix(this) public fun RealMatrix.asMatrix(): CMMatrix = CMMatrix(this)
class CMVector(val origin: RealVector) : Point<Double> { public class CMVector(public val origin: RealVector) : Point<Double> {
override val size: Int get() = origin.dimension public override val size: Int get() = origin.dimension
override operator fun get(index: Int): Double = origin.getEntry(index) public override operator fun get(index: Int): Double = origin.getEntry(index)
override operator fun iterator(): Iterator<Double> = origin.toArray().iterator() public override operator fun iterator(): Iterator<Double> = origin.toArray().iterator()
} }
fun Point<Double>.toCM(): CMVector = if (this is CMVector) this else { public fun Point<Double>.toCM(): CMVector = if (this is CMVector) this else {
val array = DoubleArray(size) { this[it] } val array = DoubleArray(size) { this[it] }
CMVector(ArrayRealVector(array)) CMVector(ArrayRealVector(array))
} }
fun RealVector.toPoint(): CMVector = CMVector(this) public fun RealVector.toPoint(): CMVector = CMVector(this)
object CMMatrixContext : MatrixContext<Double> { public object CMMatrixContext : MatrixContext<Double> {
override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): CMMatrix { public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): CMMatrix {
val array = Array(rows) { i -> DoubleArray(columns) { j -> initializer(i, j) } } val array = Array(rows) { i -> DoubleArray(columns) { j -> initializer(i, j) } }
return CMMatrix(Array2DRowRealMatrix(array)) return CMMatrix(Array2DRowRealMatrix(array))
} }
override fun Matrix<Double>.dot(other: Matrix<Double>): CMMatrix = public override fun Matrix<Double>.dot(other: Matrix<Double>): CMMatrix =
CMMatrix(this.toCM().origin.multiply(other.toCM().origin)) CMMatrix(toCM().origin.multiply(other.toCM().origin))
override fun Matrix<Double>.dot(vector: Point<Double>): CMVector = public override fun Matrix<Double>.dot(vector: Point<Double>): CMVector =
CMVector(this.toCM().origin.preMultiply(vector.toCM().origin)) CMVector(toCM().origin.preMultiply(vector.toCM().origin))
override operator fun Matrix<Double>.unaryMinus(): CMMatrix = public override operator fun Matrix<Double>.unaryMinus(): CMMatrix =
produce(rowNum, colNum) { i, j -> -get(i, j) } produce(rowNum, colNum) { i, j -> -get(i, j) }
override fun add(a: Matrix<Double>, b: Matrix<Double>): CMMatrix = public override fun add(a: Matrix<Double>, b: Matrix<Double>): CMMatrix =
CMMatrix(a.toCM().origin.multiply(b.toCM().origin)) CMMatrix(a.toCM().origin.multiply(b.toCM().origin))
override operator fun Matrix<Double>.minus(b: Matrix<Double>): CMMatrix = public override operator fun Matrix<Double>.minus(b: Matrix<Double>): CMMatrix =
CMMatrix(this.toCM().origin.subtract(b.toCM().origin)) CMMatrix(toCM().origin.subtract(b.toCM().origin))
override fun multiply(a: Matrix<Double>, k: Number): CMMatrix = public override fun multiply(a: Matrix<Double>, k: Number): CMMatrix =
CMMatrix(a.toCM().origin.scalarMultiply(k.toDouble())) CMMatrix(a.toCM().origin.scalarMultiply(k.toDouble()))
override operator fun Matrix<Double>.times(value: Double): Matrix<Double> = public override operator fun Matrix<Double>.times(value: Double): Matrix<Double> =
produce(rowNum, colNum) { i, j -> get(i, j) * value } produce(rowNum, colNum) { i, j -> get(i, j) * value }
} }
operator fun CMMatrix.plus(other: CMMatrix): CMMatrix = public operator fun CMMatrix.plus(other: CMMatrix): CMMatrix =
CMMatrix(this.origin.add(other.origin)) CMMatrix(origin.add(other.origin))
operator fun CMMatrix.minus(other: CMMatrix): CMMatrix = public operator fun CMMatrix.minus(other: CMMatrix): CMMatrix =
CMMatrix(this.origin.subtract(other.origin)) CMMatrix(origin.subtract(other.origin))
infix fun CMMatrix.dot(other: CMMatrix): CMMatrix = public infix fun CMMatrix.dot(other: CMMatrix): CMMatrix =
CMMatrix(this.origin.multiply(other.origin)) CMMatrix(origin.multiply(other.origin))

View File

@ -4,7 +4,7 @@ import org.apache.commons.math3.linear.*
import scientifik.kmath.linear.Point import scientifik.kmath.linear.Point
import scientifik.kmath.structures.Matrix import scientifik.kmath.structures.Matrix
enum class CMDecomposition { public enum class CMDecomposition {
LUP, LUP,
QR, QR,
RRQR, RRQR,
@ -12,29 +12,30 @@ enum class CMDecomposition {
CHOLESKY CHOLESKY
} }
public fun CMMatrixContext.solver(
a: Matrix<Double>,
decomposition: CMDecomposition = CMDecomposition.LUP
): DecompositionSolver = when (decomposition) {
CMDecomposition.LUP -> LUDecomposition(a.toCM().origin).solver
CMDecomposition.RRQR -> RRQRDecomposition(a.toCM().origin).solver
CMDecomposition.QR -> QRDecomposition(a.toCM().origin).solver
CMDecomposition.EIGEN -> EigenDecomposition(a.toCM().origin).solver
CMDecomposition.CHOLESKY -> CholeskyDecomposition(a.toCM().origin).solver
}
fun CMMatrixContext.solver(a: Matrix<Double>, decomposition: CMDecomposition = CMDecomposition.LUP) = public fun CMMatrixContext.solve(
when (decomposition) {
CMDecomposition.LUP -> LUDecomposition(a.toCM().origin).solver
CMDecomposition.RRQR -> RRQRDecomposition(a.toCM().origin).solver
CMDecomposition.QR -> QRDecomposition(a.toCM().origin).solver
CMDecomposition.EIGEN -> EigenDecomposition(a.toCM().origin).solver
CMDecomposition.CHOLESKY -> CholeskyDecomposition(a.toCM().origin).solver
}
fun CMMatrixContext.solve(
a: Matrix<Double>, a: Matrix<Double>,
b: Matrix<Double>, b: Matrix<Double>,
decomposition: CMDecomposition = CMDecomposition.LUP decomposition: CMDecomposition = CMDecomposition.LUP
) = solver(a, decomposition).solve(b.toCM().origin).asMatrix() ): CMMatrix = solver(a, decomposition).solve(b.toCM().origin).asMatrix()
fun CMMatrixContext.solve( public fun CMMatrixContext.solve(
a: Matrix<Double>, a: Matrix<Double>,
b: Point<Double>, b: Point<Double>,
decomposition: CMDecomposition = CMDecomposition.LUP decomposition: CMDecomposition = CMDecomposition.LUP
) = solver(a, decomposition).solve(b.toCM().origin).toPoint() ): CMVector = solver(a, decomposition).solve(b.toCM().origin).toPoint()
fun CMMatrixContext.inverse( public fun CMMatrixContext.inverse(
a: Matrix<Double>, a: Matrix<Double>,
decomposition: CMDecomposition = CMDecomposition.LUP decomposition: CMDecomposition = CMDecomposition.LUP
) = solver(a, decomposition).inverse.asMatrix() ): CMMatrix = solver(a, decomposition).inverse.asMatrix()

View File

@ -2,32 +2,32 @@ package scientifik.kmath.commons.random
import scientifik.kmath.prob.RandomGenerator import scientifik.kmath.prob.RandomGenerator
class CMRandomGeneratorWrapper(val factory: (IntArray) -> RandomGenerator) : public class CMRandomGeneratorWrapper(public val factory: (IntArray) -> RandomGenerator) :
org.apache.commons.math3.random.RandomGenerator { org.apache.commons.math3.random.RandomGenerator {
private var generator: RandomGenerator = factory(intArrayOf()) private var generator: RandomGenerator = factory(intArrayOf())
override fun nextBoolean(): Boolean = generator.nextBoolean() public override fun nextBoolean(): Boolean = generator.nextBoolean()
override fun nextFloat(): Float = generator.nextDouble().toFloat() public override fun nextFloat(): Float = generator.nextDouble().toFloat()
override fun setSeed(seed: Int) { public override fun setSeed(seed: Int) {
generator = factory(intArrayOf(seed)) generator = factory(intArrayOf(seed))
} }
override fun setSeed(seed: IntArray) { public override fun setSeed(seed: IntArray) {
generator = factory(seed) generator = factory(seed)
} }
override fun setSeed(seed: Long) { public override fun setSeed(seed: Long) {
setSeed(seed.toInt()) setSeed(seed.toInt())
} }
override fun nextBytes(bytes: ByteArray) { public override fun nextBytes(bytes: ByteArray) {
generator.fillBytes(bytes) generator.fillBytes(bytes)
} }
override fun nextInt(): Int = generator.nextInt() public override fun nextInt(): Int = generator.nextInt()
override fun nextInt(n: Int): Int = generator.nextInt(n) public override fun nextInt(n: Int): Int = generator.nextInt(n)
override fun nextGaussian(): Double = TODO() public override fun nextGaussian(): Double = TODO()
override fun nextDouble(): Double = generator.nextDouble() public override fun nextDouble(): Double = generator.nextDouble()
override fun nextLong(): Long = generator.nextLong() public override fun nextLong(): Long = generator.nextLong()
} }

View File

@ -13,8 +13,7 @@ import scientifik.kmath.structures.*
/** /**
* Streaming and buffer transformations * Streaming and buffer transformations
*/ */
object Transformations { public object Transformations {
private fun Buffer<Complex>.toArray(): Array<org.apache.commons.math3.complex.Complex> = private fun Buffer<Complex>.toArray(): Array<org.apache.commons.math3.complex.Complex> =
Array(size) { org.apache.commons.math3.complex.Complex(get(it).re, get(it).im) } Array(size) { org.apache.commons.math3.complex.Complex(get(it).re, get(it).im) }
@ -32,35 +31,35 @@ object Transformations {
Complex(value.real, value.imaginary) Complex(value.real, value.imaginary)
} }
fun fourier( public fun fourier(
normalization: DftNormalization = DftNormalization.STANDARD, normalization: DftNormalization = DftNormalization.STANDARD,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): SuspendBufferTransform<Complex, Complex> = { ): SuspendBufferTransform<Complex, Complex> = {
FastFourierTransformer(normalization).transform(it.toArray(), direction).asBuffer() FastFourierTransformer(normalization).transform(it.toArray(), direction).asBuffer()
} }
fun realFourier( public fun realFourier(
normalization: DftNormalization = DftNormalization.STANDARD, normalization: DftNormalization = DftNormalization.STANDARD,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): SuspendBufferTransform<Double, Complex> = { ): SuspendBufferTransform<Double, Complex> = {
FastFourierTransformer(normalization).transform(it.asArray(), direction).asBuffer() FastFourierTransformer(normalization).transform(it.asArray(), direction).asBuffer()
} }
fun sine( public fun sine(
normalization: DstNormalization = DstNormalization.STANDARD_DST_I, normalization: DstNormalization = DstNormalization.STANDARD_DST_I,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): SuspendBufferTransform<Double, Double> = { ): SuspendBufferTransform<Double, Double> = {
FastSineTransformer(normalization).transform(it.asArray(), direction).asBuffer() FastSineTransformer(normalization).transform(it.asArray(), direction).asBuffer()
} }
fun cosine( public fun cosine(
normalization: DctNormalization = DctNormalization.STANDARD_DCT_I, normalization: DctNormalization = DctNormalization.STANDARD_DCT_I,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): SuspendBufferTransform<Double, Double> = { ): SuspendBufferTransform<Double, Double> = {
FastCosineTransformer(normalization).transform(it.asArray(), direction).asBuffer() FastCosineTransformer(normalization).transform(it.asArray(), direction).asBuffer()
} }
fun hadamard( public fun hadamard(
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): SuspendBufferTransform<Double, Double> = { ): SuspendBufferTransform<Double, Double> = {
FastHadamardTransformer().transform(it.asArray(), direction).asBuffer() FastHadamardTransformer().transform(it.asArray(), direction).asBuffer()
@ -71,7 +70,7 @@ object Transformations {
* Process given [Flow] with commons-math fft transformation * Process given [Flow] with commons-math fft transformation
*/ */
@FlowPreview @FlowPreview
fun Flow<Buffer<Complex>>.FFT( public fun Flow<Buffer<Complex>>.FFT(
normalization: DftNormalization = DftNormalization.STANDARD, normalization: DftNormalization = DftNormalization.STANDARD,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): Flow<Buffer<Complex>> { ): Flow<Buffer<Complex>> {
@ -81,7 +80,7 @@ fun Flow<Buffer<Complex>>.FFT(
@FlowPreview @FlowPreview
@JvmName("realFFT") @JvmName("realFFT")
fun Flow<Buffer<Double>>.FFT( public fun Flow<Buffer<Double>>.FFT(
normalization: DftNormalization = DftNormalization.STANDARD, normalization: DftNormalization = DftNormalization.STANDARD,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): Flow<Buffer<Complex>> { ): Flow<Buffer<Complex>> {
@ -90,20 +89,18 @@ fun Flow<Buffer<Double>>.FFT(
} }
/** /**
* Process a continous flow of real numbers in FFT splitting it in chunks of [bufferSize]. * Process a continuous flow of real numbers in FFT splitting it in chunks of [bufferSize].
*/ */
@FlowPreview @FlowPreview
@JvmName("realFFT") @JvmName("realFFT")
fun Flow<Double>.FFT( public fun Flow<Double>.FFT(
bufferSize: Int = Int.MAX_VALUE, bufferSize: Int = Int.MAX_VALUE,
normalization: DftNormalization = DftNormalization.STANDARD, normalization: DftNormalization = DftNormalization.STANDARD,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): Flow<Complex> { ): Flow<Complex> = chunked(bufferSize).FFT(normalization, direction).spread()
return chunked(bufferSize).FFT(normalization,direction).spread()
}
/** /**
* Map a complex flow into real flow by taking real part of each number * Map a complex flow into real flow by taking real part of each number
*/ */
@FlowPreview @FlowPreview
fun Flow<Complex>.real(): Flow<Double> = map{it.re} public fun Flow<Complex>.real(): Flow<Double> = map { it.re }

View File

@ -6,12 +6,16 @@ import kotlin.contracts.contract
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
inline fun <R> diff(order: Int, vararg parameters: Pair<String, Double>, block: DerivativeStructureField.() -> R): R { internal inline fun <R> diff(
order: Int,
vararg parameters: Pair<String, Double>,
block: DerivativeStructureField.() -> R
): R {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
return DerivativeStructureField(order, mapOf(*parameters)).run(block) return DerivativeStructureField(order, mapOf(*parameters)).run(block)
} }
class AutoDiffTest { internal class AutoDiffTest {
@Test @Test
fun derivativeStructureFieldTest() { fun derivativeStructureFieldTest() {
val res = diff(3, "x" to 1.0, "y" to 1.0) { val res = diff(3, "x" to 1.0, "y" to 1.0) {

View File

@ -41,10 +41,10 @@ public class BigInt internal constructor(
private val magnitude: Magnitude private val magnitude: Magnitude
) : Comparable<BigInt> { ) : Comparable<BigInt> {
public override fun compareTo(other: BigInt): Int = when { public override fun compareTo(other: BigInt): Int = when {
(this.sign == 0.toByte()) and (other.sign == 0.toByte()) -> 0 (sign == 0.toByte()) and (other.sign == 0.toByte()) -> 0
this.sign < other.sign -> -1 sign < other.sign -> -1
this.sign > other.sign -> 1 sign > other.sign -> 1
else -> this.sign * compareMagnitudes(this.magnitude, other.magnitude) else -> sign * compareMagnitudes(magnitude, other.magnitude)
} }
public override fun equals(other: Any?): Boolean = public override fun equals(other: Any?): Boolean =
@ -123,7 +123,7 @@ public class BigInt internal constructor(
return Pair(BigInt((this.sign * other.sign).toByte(), q.magnitude), r) return Pair(BigInt((this.sign * other.sign).toByte(), q.magnitude), r)
} }
public operator fun div(other: BigInt): BigInt = this.division(other).first public operator fun div(other: BigInt): BigInt = division(other).first
public infix fun shl(i: Int): BigInt { public infix fun shl(i: Int): BigInt {
if (this == ZERO) return ZERO if (this == ZERO) return ZERO
@ -132,16 +132,16 @@ public class BigInt internal constructor(
val relShift = i % BASE_SIZE val relShift = i % BASE_SIZE
val shiftLeft = { x: UInt -> if (relShift >= 32) 0U else x shl relShift } val shiftLeft = { x: UInt -> if (relShift >= 32) 0U else x shl relShift }
val shiftRight = { x: UInt -> if (BASE_SIZE - relShift >= 32) 0U else x shr (BASE_SIZE - relShift) } val shiftRight = { x: UInt -> if (BASE_SIZE - relShift >= 32) 0U else x shr (BASE_SIZE - relShift) }
val newMagnitude = Magnitude(this.magnitude.size + fullShifts) val newMagnitude = Magnitude(magnitude.size + fullShifts)
for (j in this.magnitude.indices) { for (j in magnitude.indices) {
newMagnitude[j + fullShifts - 1] = shiftLeft(this.magnitude[j]) newMagnitude[j + fullShifts - 1] = shiftLeft(this.magnitude[j])
if (j != 0) if (j != 0)
newMagnitude[j + fullShifts - 1] = newMagnitude[j + fullShifts - 1] or shiftRight(this.magnitude[j - 1]) newMagnitude[j + fullShifts - 1] = newMagnitude[j + fullShifts - 1] or shiftRight(this.magnitude[j - 1])
} }
newMagnitude[this.magnitude.size + fullShifts - 1] = shiftRight(this.magnitude.last()) newMagnitude[magnitude.size + fullShifts - 1] = shiftRight(magnitude.last())
return BigInt(this.sign, stripLeadingZeros(newMagnitude)) return BigInt(this.sign, stripLeadingZeros(newMagnitude))
} }
@ -153,13 +153,13 @@ public class BigInt internal constructor(
val shiftRight = { x: UInt -> if (relShift >= 32) 0U else x shr relShift } val shiftRight = { x: UInt -> if (relShift >= 32) 0U else x shr relShift }
val shiftLeft = { x: UInt -> if (BASE_SIZE - relShift >= 32) 0U else x shl (BASE_SIZE - relShift) } val shiftLeft = { x: UInt -> if (BASE_SIZE - relShift >= 32) 0U else x shl (BASE_SIZE - relShift) }
if (this.magnitude.size - fullShifts <= 0) return ZERO if (this.magnitude.size - fullShifts <= 0) return ZERO
val newMagnitude: Magnitude = Magnitude(this.magnitude.size - fullShifts) val newMagnitude: Magnitude = Magnitude(magnitude.size - fullShifts)
for (j in fullShifts until this.magnitude.size) { for (j in fullShifts until magnitude.size) {
newMagnitude[j - fullShifts] = shiftRight(this.magnitude[j]) newMagnitude[j - fullShifts] = shiftRight(magnitude[j])
if (j != this.magnitude.size - 1) if (j != magnitude.size - 1)
newMagnitude[j - fullShifts] = newMagnitude[j - fullShifts] or shiftLeft(this.magnitude[j + 1]) newMagnitude[j - fullShifts] = newMagnitude[j - fullShifts] or shiftLeft(magnitude[j + 1])
} }
return BigInt(this.sign, stripLeadingZeros(newMagnitude)) return BigInt(this.sign, stripLeadingZeros(newMagnitude))
@ -168,11 +168,11 @@ public class BigInt internal constructor(
public infix fun or(other: BigInt): BigInt { public infix fun or(other: BigInt): BigInt {
if (this == ZERO) return other if (this == ZERO) return other
if (other == ZERO) return this if (other == ZERO) return this
val resSize = max(this.magnitude.size, other.magnitude.size) val resSize = max(magnitude.size, other.magnitude.size)
val newMagnitude: Magnitude = Magnitude(resSize) val newMagnitude: Magnitude = Magnitude(resSize)
for (i in 0 until resSize) { for (i in 0 until resSize) {
if (i < this.magnitude.size) newMagnitude[i] = newMagnitude[i] or this.magnitude[i] if (i < magnitude.size) newMagnitude[i] = newMagnitude[i] or magnitude[i]
if (i < other.magnitude.size) newMagnitude[i] = newMagnitude[i] or other.magnitude[i] if (i < other.magnitude.size) newMagnitude[i] = newMagnitude[i] or other.magnitude[i]
} }

View File

@ -149,13 +149,16 @@ public fun <T, R> Chain<T>.collect(mapper: suspend (Chain<T>) -> R): Chain<R> =
override fun fork(): Chain<R> = this@collect.fork().collect(mapper) override fun fork(): Chain<R> = this@collect.fork().collect(mapper)
} }
public fun <T, S, R> Chain<T>.collectWithState(state: S, stateFork: (S) -> S, mapper: suspend S.(Chain<T>) -> R): Chain<R> = public fun <T, S, R> Chain<T>.collectWithState(
object : Chain<R> { state: S,
override suspend fun next(): R = state.mapper(this@collectWithState) stateFork: (S) -> S,
mapper: suspend S.(Chain<T>) -> R
): Chain<R> = object : Chain<R> {
override suspend fun next(): R = state.mapper(this@collectWithState)
override fun fork(): Chain<R> = override fun fork(): Chain<R> =
this@collectWithState.fork().collectWithState(stateFork(state), stateFork, mapper) this@collectWithState.fork().collectWithState(stateFork(state), stateFork, mapper)
} }
/** /**
* Zip two chains together using given transformation * Zip two chains together using given transformation

View File

@ -49,10 +49,8 @@ public fun Flow<Double>.chunked(bufferSize: Int): Flow<RealBuffer> = flow {
require(bufferSize > 0) { "Resulting chunk size must be more than zero" } require(bufferSize > 0) { "Resulting chunk size must be more than zero" }
if (this@chunked is BlockingRealChain) { if (this@chunked is BlockingRealChain) {
//performance optimization for blocking primitive chain // performance optimization for blocking primitive chain
while (true) { while (true) emit(nextBlock(bufferSize).asBuffer())
emit(nextBlock(bufferSize).asBuffer())
}
} else { } else {
val array = DoubleArray(bufferSize) val array = DoubleArray(bufferSize)
var counter = 0 var counter = 0
@ -60,6 +58,7 @@ public fun Flow<Double>.chunked(bufferSize: Int): Flow<RealBuffer> = flow {
this@chunked.collect { element -> this@chunked.collect { element ->
array[counter] = element array[counter] = element
counter++ counter++
if (counter == bufferSize) { if (counter == bufferSize) {
val buffer = RealBuffer(array) val buffer = RealBuffer(array)
emit(buffer) emit(buffer)

View File

@ -5,13 +5,12 @@ import kotlinx.coroutines.runBlocking
/** /**
* Represent a chain as regular iterator (uses blocking calls) * Represent a chain as regular iterator (uses blocking calls)
*/ */
operator fun <R> Chain<R>.iterator(): Iterator<R> = object : Iterator<R> { public operator fun <R> Chain<R>.iterator(): Iterator<R> = object : Iterator<R> {
override fun hasNext(): Boolean = true override fun hasNext(): Boolean = true
override fun next(): R = runBlocking { next() } override fun next(): R = runBlocking { next() }
} }
/** /**
* Represent a chain as a sequence * Represent a chain as a sequence
*/ */
fun <R> Chain<R>.asSequence(): Sequence<R> = Sequence { this@asSequence.iterator() } public fun <R> Chain<R>.asSequence(): Sequence<R> = Sequence { this@asSequence.iterator() }

View File

@ -37,10 +37,10 @@ public class LazyNDStructure<T>(
} }
public fun <T> NDStructure<T>.deferred(index: IntArray): Deferred<T> = public fun <T> NDStructure<T>.deferred(index: IntArray): Deferred<T> =
if (this is LazyNDStructure<T>) this.deferred(index) else CompletableDeferred(get(index)) if (this is LazyNDStructure<T>) deferred(index) else CompletableDeferred(get(index))
public suspend fun <T> NDStructure<T>.await(index: IntArray): T = public suspend fun <T> NDStructure<T>.await(index: IntArray): T =
if (this is LazyNDStructure<T>) this.await(index) else get(index) if (this is LazyNDStructure<T>) await(index) else get(index)
/** /**
* PENDING would benefit from KEEP-176 * PENDING would benefit from KEEP-176

View File

@ -14,7 +14,7 @@ import kotlin.test.Test
@ExperimentalCoroutinesApi @ExperimentalCoroutinesApi
@InternalCoroutinesApi @InternalCoroutinesApi
@FlowPreview @FlowPreview
class BufferFlowTest { internal class BufferFlowTest {
val dispatcher: CoroutineDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher() val dispatcher: CoroutineDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
@Test @Test

View File

@ -6,7 +6,7 @@ import scientifik.kmath.structures.asSequence
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class RingBufferTest { internal class RingBufferTest {
@Test @Test
fun push() { fun push() {
val buffer = RingBuffer.build(20, Double.NaN) val buffer = RingBuffer.build(20, Double.NaN)

View File

@ -5,7 +5,7 @@ import scientifik.kmath.dimensions.D3
import scientifik.kmath.dimensions.DMatrixContext import scientifik.kmath.dimensions.DMatrixContext
import kotlin.test.Test import kotlin.test.Test
class DMatrixContextTest { internal class DMatrixContextTest {
@Test @Test
fun testDimensionSafeMatrix() { fun testDimensionSafeMatrix() {
val res = with(DMatrixContext.real) { val res = with(DMatrixContext.real) {

View File

@ -2,21 +2,17 @@ package scientifik.kmath.dimensions
import kotlin.reflect.KClass import kotlin.reflect.KClass
private val dimensionMap = hashMapOf<UInt, Dimension>( private val dimensionMap: MutableMap<UInt, Dimension> = hashMapOf(1u to D1, 2u to D2, 3u to D3)
1u to D1,
2u to D2,
3u to D3
)
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
public actual fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D { public actual fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D = dimensionMap
return dimensionMap.entries.find { it.value::class == type }?.value as? D ?: error("Can't resolve dimension $type") .entries
} .map(MutableMap.MutableEntry<UInt, Dimension>::value)
.find { it::class == type } as? D
?: error("Can't resolve dimension $type")
public actual fun Dimension.Companion.of(dim: UInt): Dimension { public actual fun Dimension.Companion.of(dim: UInt): Dimension = dimensionMap.getOrPut(dim) {
return dimensionMap.getOrPut(dim) { object : Dimension {
object : Dimension { override val dim: UInt get() = dim
override val dim: UInt get() = dim
}
} }
} }

View File

@ -2,17 +2,15 @@ package scientifik.kmath.dimensions
import kotlin.reflect.KClass import kotlin.reflect.KClass
public actual fun <D:Dimension> Dimension.Companion.resolve(type: KClass<D>): D{ public actual fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D =
return type.objectInstance ?: error("No object instance for dimension class") type.objectInstance ?: error("No object instance for dimension class")
}
public actual fun Dimension.Companion.of(dim: UInt): Dimension{ public actual fun Dimension.Companion.of(dim: UInt): Dimension = when (dim) {
return when(dim){ 1u -> D1
1u -> D1 2u -> D2
2u -> D2 3u -> D3
3u -> D3
else -> object : Dimension { else -> object : Dimension {
override val dim: UInt get() = dim override val dim: UInt get() = dim
}
} }
} }

View File

@ -14,11 +14,11 @@ import kotlin.math.sqrt
public typealias RealPoint = Point<Double> public typealias RealPoint = Point<Double>
public fun DoubleArray.asVector(): RealVector = RealVector(this.asBuffer()) public fun DoubleArray.asVector(): RealVector = RealVector(asBuffer())
public fun List<Double>.asVector(): RealVector = RealVector(this.asBuffer()) public fun List<Double>.asVector(): RealVector = RealVector(asBuffer())
public object VectorL2Norm : Norm<Point<out Number>, Double> { public 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(Number::toDouble))
} }
public inline class RealVector(private val point: Point<Double>) : public inline class RealVector(private val point: Point<Double>) :
@ -27,13 +27,9 @@ public inline class RealVector(private val point: Point<Double>) :
public override val context: VectorSpace<Double, RealField> get() = space(point.size) public override val context: VectorSpace<Double, RealField> get() = space(point.size)
public override fun unwrap(): RealPoint = point public override fun unwrap(): RealPoint = point
public override fun RealPoint.wrap(): RealVector = RealVector(this) public override fun RealPoint.wrap(): RealVector = RealVector(this)
public override operator fun get(index: Int): Double = point[index]
public override operator fun iterator(): Iterator<Double> = point.iterator()
override operator fun get(index: Int): Double = point[index]
override operator fun iterator(): Iterator<Double> = point.iterator()
public companion object { public companion object {
private val spaceCache: MutableMap<Int, BufferVectorSpace<Double, RealField>> = hashMapOf() private val spaceCache: MutableMap<Int, BufferVectorSpace<Double, RealField>> = hashMapOf()

View File

@ -8,7 +8,7 @@ import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
class RealMatrixTest { internal class RealMatrixTest {
@Test @Test
fun testSum() { fun testSum() {
val m = realMatrix(10, 10) { i, j -> (i + j).toDouble() } val m = realMatrix(10, 10) { i, j -> (i + j).toDouble() }

View File

@ -5,7 +5,7 @@ import scientifik.kmath.real.RealVector
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class VectorTest { internal class VectorTest {
@Test @Test
fun testSum() { fun testSum() {
val vector1 = RealVector(5) { it.toDouble() } val vector1 = RealVector(5) { it.toDouble() }

View File

@ -5,28 +5,28 @@ import scientifik.kmath.operations.SpaceElement
import scientifik.kmath.operations.invoke import scientifik.kmath.operations.invoke
import kotlin.math.sqrt import kotlin.math.sqrt
public interface Vector2D : Point<Double>, Vector, SpaceElement<Vector2D, Vector2D, Euclidean2DSpace> {
public val x: Double
public val y: Double
public override val context: Euclidean2DSpace get() = Euclidean2DSpace
public override val size: Int get() = 2
interface Vector2D : Point<Double>, Vector, SpaceElement<Vector2D, Vector2D, Euclidean2DSpace> { public override operator fun get(index: Int): Double = when (index) {
val x: Double
val y: Double
override val context: Euclidean2DSpace get() = Euclidean2DSpace
override val size: Int get() = 2
override operator fun get(index: Int): Double = when (index) {
1 -> x 1 -> x
2 -> y 2 -> y
else -> error("Accessing outside of point bounds") else -> error("Accessing outside of point bounds")
} }
override operator fun iterator(): Iterator<Double> = listOf(x, y).iterator() public override operator fun iterator(): Iterator<Double> = listOf(x, y).iterator()
override fun unwrap(): Vector2D = this public override fun unwrap(): Vector2D = this
override fun Vector2D.wrap(): Vector2D = this public override fun Vector2D.wrap(): Vector2D = this
} }
val Vector2D.r: Double get() = Euclidean2DSpace { sqrt(norm()) } public val Vector2D.r: Double
get() = Euclidean2DSpace { sqrt(norm()) }
@Suppress("FunctionName") @Suppress("FunctionName")
fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y) public fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y)
private data class Vector2DImpl( private data class Vector2DImpl(
override val x: Double, override val x: Double,
@ -36,19 +36,12 @@ private data class Vector2DImpl(
/** /**
* 2D Euclidean space * 2D Euclidean space
*/ */
object Euclidean2DSpace : GeometrySpace<Vector2D> { public object Euclidean2DSpace : GeometrySpace<Vector2D> {
fun Vector2D.norm(): Double = sqrt(x * x + y * y) public override val zero: Vector2D by lazy { Vector2D(0.0, 0.0) }
override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm() public fun Vector2D.norm(): Double = sqrt(x * x + y * y)
public override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm()
override fun add(a: Vector2D, b: Vector2D): Vector2D = public override fun add(a: Vector2D, b: Vector2D): Vector2D = Vector2D(a.x + b.x, a.y + b.y)
Vector2D(a.x + b.x, a.y + b.y) public override fun multiply(a: Vector2D, k: Number): Vector2D = Vector2D(a.x * k.toDouble(), a.y * k.toDouble())
public override fun Vector2D.dot(other: Vector2D): Double = x * other.x + y * other.y
override fun multiply(a: Vector2D, k: Number): Vector2D =
Vector2D(a.x * k.toDouble(), a.y * k.toDouble())
override val zero: Vector2D = Vector2D(0.0, 0.0)
override fun Vector2D.dot(other: Vector2D): Double =
x * other.x + y * other.y
} }

View File

@ -5,32 +5,29 @@ import scientifik.kmath.operations.SpaceElement
import scientifik.kmath.operations.invoke import scientifik.kmath.operations.invoke
import kotlin.math.sqrt import kotlin.math.sqrt
public interface Vector3D : Point<Double>, Vector, SpaceElement<Vector3D, Vector3D, Euclidean3DSpace> {
public val x: Double
public val y: Double
public val z: Double
public override val context: Euclidean3DSpace get() = Euclidean3DSpace
public override val size: Int get() = 3
interface Vector3D : Point<Double>, Vector, SpaceElement<Vector3D, Vector3D, Euclidean3DSpace> { public override operator fun get(index: Int): Double = when (index) {
val x: Double
val y: Double
val z: Double
override val context: Euclidean3DSpace get() = Euclidean3DSpace
override val size: Int get() = 3
override operator fun get(index: Int): Double = when (index) {
1 -> x 1 -> x
2 -> y 2 -> y
3 -> z 3 -> z
else -> error("Accessing outside of point bounds") else -> error("Accessing outside of point bounds")
} }
override operator fun iterator(): Iterator<Double> = listOf(x, y, z).iterator() public override operator fun iterator(): Iterator<Double> = listOf(x, y, z).iterator()
public override fun unwrap(): Vector3D = this
override fun unwrap(): Vector3D = this public override fun Vector3D.wrap(): Vector3D = this
override fun Vector3D.wrap(): Vector3D = this
} }
@Suppress("FunctionName") @Suppress("FunctionName")
fun Vector3D(x: Double, y: Double, z: Double): Vector3D = Vector3DImpl(x, y, z) public fun Vector3D(x: Double, y: Double, z: Double): Vector3D = Vector3DImpl(x, y, z)
val Vector3D.r: Double get() = Euclidean3DSpace { sqrt(norm()) } public val Vector3D.r: Double get() = Euclidean3DSpace { sqrt(norm()) }
private data class Vector3DImpl( private data class Vector3DImpl(
override val x: Double, override val x: Double,
@ -38,19 +35,19 @@ private data class Vector3DImpl(
override val z: Double override val z: Double
) : Vector3D ) : Vector3D
object Euclidean3DSpace : GeometrySpace<Vector3D> { public object Euclidean3DSpace : GeometrySpace<Vector3D> {
override val zero: Vector3D = Vector3D(0.0, 0.0, 0.0) public override val zero: Vector3D by lazy { Vector3D(0.0, 0.0, 0.0) }
fun Vector3D.norm(): Double = sqrt(x * x + y * y + z * z) public fun Vector3D.norm(): Double = sqrt(x * x + y * y + z * z)
override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm() public override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm()
override fun add(a: Vector3D, b: Vector3D): Vector3D = public override fun add(a: Vector3D, b: Vector3D): Vector3D =
Vector3D(a.x + b.x, a.y + b.y, a.z + b.z) Vector3D(a.x + b.x, a.y + b.y, a.z + b.z)
override fun multiply(a: Vector3D, k: Number): Vector3D = public override fun multiply(a: Vector3D, k: Number): Vector3D =
Vector3D(a.x * k.toDouble(), a.y * k.toDouble(), a.z * k.toDouble()) Vector3D(a.x * k.toDouble(), a.y * k.toDouble(), a.z * k.toDouble())
override fun Vector3D.dot(other: Vector3D): Double = public override fun Vector3D.dot(other: Vector3D): Double =
x * other.x + y * other.y + z * other.z x * other.x + y * other.y + z * other.z
} }

View File

@ -2,16 +2,16 @@ package scientifik.kmath.geometry
import scientifik.kmath.operations.Space import scientifik.kmath.operations.Space
interface Vector public interface Vector
interface GeometrySpace<V: Vector>: Space<V> { public interface GeometrySpace<V: Vector>: Space<V> {
/** /**
* L2 distance * L2 distance
*/ */
fun V.distanceTo(other: V): Double public fun V.distanceTo(other: V): Double
/** /**
* Scalar product * Scalar product
*/ */
infix fun V.dot(other: V): Double public infix fun V.dot(other: V): Double
} }

View File

@ -1,6 +1,6 @@
package scientifik.kmath.geometry package scientifik.kmath.geometry
data class Line<V: Vector>(val base: V, val direction: V) public data class Line<V : Vector>(val base: V, val direction: V)
typealias Line2D = Line<Vector2D> public typealias Line2D = Line<Vector2D>
typealias Line3D = Line<Vector3D> public typealias Line3D = Line<Vector3D>

View File

@ -1,4 +1,3 @@
package scientifik.kmath.geometry package scientifik.kmath.geometry
interface ReferenceFrame { public interface ReferenceFrame
}

View File

@ -7,67 +7,64 @@ import scientifik.kmath.operations.invoke
import scientifik.kmath.structures.Matrix import scientifik.kmath.structures.Matrix
import scientifik.kmath.structures.NDStructure import scientifik.kmath.structures.NDStructure
class KomaMatrixContext<T : Any>( public class KomaMatrixContext<T : Any>(
private val factory: MatrixFactory<koma.matrix.Matrix<T>>, private val factory: MatrixFactory<koma.matrix.Matrix<T>>,
private val space: Space<T> private val space: Space<T>
) : MatrixContext<T> { ) : MatrixContext<T> {
public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): KomaMatrix<T> =
override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): KomaMatrix<T> =
KomaMatrix(factory.zeros(rows, columns).fill(initializer)) KomaMatrix(factory.zeros(rows, columns).fill(initializer))
fun Matrix<T>.toKoma(): KomaMatrix<T> = if (this is KomaMatrix) { public fun Matrix<T>.toKoma(): KomaMatrix<T> = if (this is KomaMatrix)
this this
} else { else
produce(rowNum, colNum) { i, j -> get(i, j) } produce(rowNum, colNum) { i, j -> get(i, j) }
}
fun Point<T>.toKoma(): KomaVector<T> = if (this is KomaVector) { public fun Point<T>.toKoma(): KomaVector<T> = if (this is KomaVector)
this this
} else { else
KomaVector(factory.zeros(size, 1).fill { i, _ -> get(i) }) KomaVector(factory.zeros(size, 1).fill { i, _ -> get(i) })
}
public override fun Matrix<T>.dot(other: Matrix<T>): KomaMatrix<T> =
override fun Matrix<T>.dot(other: Matrix<T>): KomaMatrix<T> =
KomaMatrix(toKoma().origin * other.toKoma().origin) KomaMatrix(toKoma().origin * other.toKoma().origin)
override fun Matrix<T>.dot(vector: Point<T>): KomaVector<T> = public override fun Matrix<T>.dot(vector: Point<T>): KomaVector<T> =
KomaVector(toKoma().origin * vector.toKoma().origin) KomaVector(toKoma().origin * vector.toKoma().origin)
override operator fun Matrix<T>.unaryMinus(): KomaMatrix<T> = public override operator fun Matrix<T>.unaryMinus(): KomaMatrix<T> =
KomaMatrix(toKoma().origin.unaryMinus()) KomaMatrix(toKoma().origin.unaryMinus())
override fun add(a: Matrix<T>, b: Matrix<T>): KomaMatrix<T> = public override fun add(a: Matrix<T>, b: Matrix<T>): KomaMatrix<T> =
KomaMatrix(a.toKoma().origin + b.toKoma().origin) KomaMatrix(a.toKoma().origin + b.toKoma().origin)
override operator fun Matrix<T>.minus(b: Matrix<T>): KomaMatrix<T> = public override operator fun Matrix<T>.minus(b: Matrix<T>): KomaMatrix<T> =
KomaMatrix(toKoma().origin - b.toKoma().origin) KomaMatrix(toKoma().origin - b.toKoma().origin)
override fun multiply(a: Matrix<T>, k: Number): Matrix<T> = public override fun multiply(a: Matrix<T>, k: Number): Matrix<T> =
produce(a.rowNum, a.colNum) { i, j -> space { a[i, j] * k } } produce(a.rowNum, a.colNum) { i, j -> space { a[i, j] * k } }
override operator fun Matrix<T>.times(value: T): KomaMatrix<T> = public override operator fun Matrix<T>.times(value: T): KomaMatrix<T> =
KomaMatrix(toKoma().origin * value) KomaMatrix(toKoma().origin * value)
companion object public companion object
} }
fun <T : Any> KomaMatrixContext<T>.solve(a: Matrix<T>, b: Matrix<T>) = public fun <T : Any> KomaMatrixContext<T>.solve(a: Matrix<T>, b: Matrix<T>): KomaMatrix<T> =
KomaMatrix(a.toKoma().origin.solve(b.toKoma().origin)) KomaMatrix(a.toKoma().origin.solve(b.toKoma().origin))
fun <T : Any> KomaMatrixContext<T>.solve(a: Matrix<T>, b: Point<T>) = public fun <T : Any> KomaMatrixContext<T>.solve(a: Matrix<T>, b: Point<T>): KomaVector<T> =
KomaVector(a.toKoma().origin.solve(b.toKoma().origin)) KomaVector(a.toKoma().origin.solve(b.toKoma().origin))
fun <T : Any> KomaMatrixContext<T>.inverse(a: Matrix<T>) = public fun <T : Any> KomaMatrixContext<T>.inverse(a: Matrix<T>): KomaMatrix<T> =
KomaMatrix(a.toKoma().origin.inv()) KomaMatrix(a.toKoma().origin.inv())
class KomaMatrix<T : Any>(val origin: koma.matrix.Matrix<T>, features: Set<MatrixFeature>? = null) : FeaturedMatrix<T> { public class KomaMatrix<T : Any>(public val origin: koma.matrix.Matrix<T>, features: Set<MatrixFeature>? = null) :
override val rowNum: Int get() = origin.numRows() FeaturedMatrix<T> {
override val colNum: Int get() = origin.numCols() public override val rowNum: Int get() = origin.numRows()
public override val colNum: Int get() = origin.numCols()
override val shape: IntArray get() = intArrayOf(origin.numRows(), origin.numCols()) public override val shape: IntArray get() = intArrayOf(origin.numRows(), origin.numCols())
override val features: Set<MatrixFeature> = features ?: hashSetOf( public override val features: Set<MatrixFeature> = features ?: hashSetOf(
object : DeterminantFeature<T> { object : DeterminantFeature<T> {
override val determinant: T get() = origin.det() override val determinant: T get() = origin.det()
}, },
@ -94,11 +91,9 @@ class KomaMatrix<T : Any>(val origin: koma.matrix.Matrix<T>, features: Set<Matri
result = 31 * result + features.hashCode() result = 31 * result + features.hashCode()
return result return result
} }
} }
class KomaVector<T : Any> internal constructor(val origin: koma.matrix.Matrix<T>) : Point<T> { public class KomaVector<T : Any> internal constructor(public val origin: koma.matrix.Matrix<T>) : Point<T> {
override val size: Int get() = origin.numRows() override val size: Int get() = origin.numRows()
init { init {

View File

@ -13,4 +13,8 @@ kotlin.sourceSets {
api("org.apache.commons:commons-rng-simple:1.3") api("org.apache.commons:commons-rng-simple:1.3")
} }
} }
jvmTest {
languageSettings.useExperimentalAnnotation("kotlinx.coroutines.FlowPreview")
}
} }

View File

@ -6,7 +6,7 @@ import kotlinx.coroutines.runBlocking
import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
class CommonsDistributionsTest { internal class CommonsDistributionsTest {
@Test @Test
fun testNormalDistributionSuspend() { fun testNormalDistributionSuspend() {
val distribution = Distribution.normal(7.0, 2.0) val distribution = Distribution.normal(7.0, 2.0)
@ -24,5 +24,4 @@ class CommonsDistributionsTest {
val sample = distribution.sample(generator).nextBlock(1000) val sample = distribution.sample(generator).nextBlock(1000)
Assertions.assertEquals(7.0, sample.average(), 0.1) Assertions.assertEquals(7.0, sample.average(), 0.1)
} }
} }

View File

@ -7,12 +7,14 @@ import kotlinx.coroutines.runBlocking
import scientifik.kmath.streaming.chunked import scientifik.kmath.streaming.chunked
import kotlin.test.Test import kotlin.test.Test
class StatisticTest { internal class StatisticTest {
//create a random number generator. //create a random number generator.
val generator = RandomGenerator.default(1) val generator = RandomGenerator.default(1)
//Create a stateless chain from generator. //Create a stateless chain from generator.
val data = generator.chain { nextDouble() } val data = generator.chain { nextDouble() }
//Convert a chaint to Flow and break it into chunks.
//Convert a chain to Flow and break it into chunks.
val chunked = data.chunked(1000) val chunked = data.chunked(1000)
@Test @Test
@ -22,6 +24,7 @@ class StatisticTest {
.flow(chunked) //create a flow with results .flow(chunked) //create a flow with results
.drop(99) // Skip first 99 values and use one with total data .drop(99) // Skip first 99 values and use one with total data
.first() //get 1e5 data samples average .first() //get 1e5 data samples average
println(average) println(average)
} }
} }

View File

@ -5,82 +5,84 @@ import scientifik.kmath.operations.RealField
import scientifik.kmath.structures.DefaultStrides import scientifik.kmath.structures.DefaultStrides
import scientifik.kmath.structures.MutableNDStructure import scientifik.kmath.structures.MutableNDStructure
import scientifik.kmath.structures.NDField import scientifik.kmath.structures.NDField
import scientifik.kmath.structures.Strides
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") @Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
inline class ViktorNDStructure(val f64Buffer: F64Array) : MutableNDStructure<Double> { public inline class ViktorNDStructure(public val f64Buffer: F64Array) : MutableNDStructure<Double> {
public override val shape: IntArray get() = f64Buffer.shape
override val shape: IntArray get() = f64Buffer.shape public override inline fun get(index: IntArray): Double = f64Buffer.get(*index)
override inline fun get(index: IntArray): Double = f64Buffer.get(*index) public override inline fun set(index: IntArray, value: Double) {
override inline fun set(index: IntArray, value: Double) {
f64Buffer.set(*index, value = value) f64Buffer.set(*index, value = value)
} }
override fun elements(): Sequence<Pair<IntArray, Double>> { public override fun elements(): Sequence<Pair<IntArray, Double>> =
return DefaultStrides(shape).indices().map { it to get(it) } DefaultStrides(shape).indices().map { it to get(it) }
}
} }
fun F64Array.asStructure(): ViktorNDStructure = ViktorNDStructure(this) public fun F64Array.asStructure(): ViktorNDStructure = ViktorNDStructure(this)
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE") @Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
class ViktorNDField(override val shape: IntArray) : NDField<Double, RealField, ViktorNDStructure> { public class ViktorNDField(public override val shape: IntArray) : NDField<Double, RealField, ViktorNDStructure> {
override val zero: ViktorNDStructure public override val zero: ViktorNDStructure
get() = F64Array.full(init = 0.0, shape = *shape).asStructure() get() = F64Array.full(init = 0.0, shape = *shape).asStructure()
override val one: ViktorNDStructure
public override val one: ViktorNDStructure
get() = F64Array.full(init = 1.0, shape = *shape).asStructure() get() = F64Array.full(init = 1.0, shape = *shape).asStructure()
val strides = DefaultStrides(shape) public val strides: Strides = DefaultStrides(shape)
override val elementContext: RealField get() = RealField public override val elementContext: RealField get() = RealField
override fun produce(initializer: RealField.(IntArray) -> Double): ViktorNDStructure = F64Array(*shape).apply { public override fun produce(initializer: RealField.(IntArray) -> Double): ViktorNDStructure =
this@ViktorNDField.strides.indices().forEach { index ->
set(value = RealField.initializer(index), indices = *index)
}
}.asStructure()
override fun map(arg: ViktorNDStructure, transform: RealField.(Double) -> Double): ViktorNDStructure =
F64Array(*shape).apply { F64Array(*shape).apply {
this@ViktorNDField.strides.indices().forEach { index -> this@ViktorNDField.strides.indices().forEach { index ->
set(value = RealField.transform(arg[index]), indices = *index) set(value = RealField.initializer(index), indices = index)
} }
}.asStructure() }.asStructure()
override fun mapIndexed( public override fun map(arg: ViktorNDStructure, transform: RealField.(Double) -> Double): ViktorNDStructure =
F64Array(*shape).apply {
this@ViktorNDField.strides.indices().forEach { index ->
set(value = RealField.transform(arg[index]), indices = index)
}
}.asStructure()
public override fun mapIndexed(
arg: ViktorNDStructure, arg: ViktorNDStructure,
transform: RealField.(index: IntArray, Double) -> Double transform: RealField.(index: IntArray, Double) -> Double
): ViktorNDStructure = F64Array(*shape).apply { ): ViktorNDStructure = F64Array(*shape).apply {
this@ViktorNDField.strides.indices().forEach { index -> this@ViktorNDField.strides.indices().forEach { index ->
set(value = RealField.transform(index, arg[index]), indices = *index) set(value = RealField.transform(index, arg[index]), indices = index)
} }
}.asStructure() }.asStructure()
override fun combine( public override fun combine(
a: ViktorNDStructure, a: ViktorNDStructure,
b: ViktorNDStructure, b: ViktorNDStructure,
transform: RealField.(Double, Double) -> Double transform: RealField.(Double, Double) -> Double
): ViktorNDStructure = F64Array(*shape).apply { ): ViktorNDStructure = F64Array(*shape).apply {
this@ViktorNDField.strides.indices().forEach { index -> this@ViktorNDField.strides.indices().forEach { index ->
set(value = RealField.transform(a[index], b[index]), indices = *index) set(value = RealField.transform(a[index], b[index]), indices = index)
} }
}.asStructure() }.asStructure()
override fun add(a: ViktorNDStructure, b: ViktorNDStructure): ViktorNDStructure { public override fun add(a: ViktorNDStructure, b: ViktorNDStructure): ViktorNDStructure =
return (a.f64Buffer + b.f64Buffer).asStructure() (a.f64Buffer + b.f64Buffer).asStructure()
}
override fun multiply(a: ViktorNDStructure, k: Number): ViktorNDStructure = public override fun multiply(a: ViktorNDStructure, k: Number): ViktorNDStructure =
(a.f64Buffer * k.toDouble()).asStructure() (a.f64Buffer * k.toDouble()).asStructure()
override inline fun ViktorNDStructure.plus(b: ViktorNDStructure): ViktorNDStructure = public override inline fun ViktorNDStructure.plus(b: ViktorNDStructure): ViktorNDStructure =
(f64Buffer + b.f64Buffer).asStructure() (f64Buffer + b.f64Buffer).asStructure()
override inline fun ViktorNDStructure.minus(b: ViktorNDStructure): ViktorNDStructure = public override inline fun ViktorNDStructure.minus(b: ViktorNDStructure): ViktorNDStructure =
(f64Buffer - b.f64Buffer).asStructure() (f64Buffer - b.f64Buffer).asStructure()
override inline fun ViktorNDStructure.times(k: Number): ViktorNDStructure = (f64Buffer * k.toDouble()).asStructure() public override inline fun ViktorNDStructure.times(k: Number): ViktorNDStructure =
(f64Buffer * k.toDouble()).asStructure()
override inline fun ViktorNDStructure.plus(arg: Double): ViktorNDStructure = (f64Buffer.plus(arg)).asStructure() public override inline fun ViktorNDStructure.plus(arg: Double): ViktorNDStructure =
(f64Buffer.plus(arg)).asStructure()
} }