Skip to content

Commit 5d2eaaf

Browse files
committed
Add contracts to some functions, fix multiple style issues
1 parent d50163d commit 5d2eaaf

File tree

73 files changed

+209
-199
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+209
-199
lines changed

benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ import space.kscience.kmath.jafama.JafamaDoubleField
1313
import space.kscience.kmath.jafama.StrictJafamaDoubleField
1414
import space.kscience.kmath.operations.DoubleField
1515
import space.kscience.kmath.operations.invoke
16+
import kotlin.contracts.InvocationKind
17+
import kotlin.contracts.contract
1618
import kotlin.random.Random
1719

1820
@State(Scope.Benchmark)
@@ -31,9 +33,10 @@ internal class JafamaBenchmark {
3133
fun strictJafama(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x ->
3234
StrictJafamaDoubleField { x * power(x, 4) * exp(x) / cos(x) + sin(x) }
3335
}
36+
}
3437

35-
private inline fun invokeBenchmarks(blackhole: Blackhole, expr: (Double) -> Double) {
36-
val rng = Random(0)
37-
repeat(1000000) { blackhole.consume(expr(rng.nextDouble())) }
38-
}
38+
private inline fun invokeBenchmarks(blackhole: Blackhole, expr: (Double) -> Double) {
39+
contract { callsInPlace(expr, InvocationKind.AT_LEAST_ONCE) }
40+
val rng = Random(0)
41+
repeat(1000000) { blackhole.consume(expr(rng.nextDouble())) }
3942
}

benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ internal class MatrixInverseBenchmark {
4040

4141
@Benchmark
4242
fun cmLUPInversion(blackhole: Blackhole) {
43-
with(CMLinearSpace) {
43+
CMLinearSpace {
4444
blackhole.consume(inverse(matrix))
4545
}
4646
}
4747

4848
@Benchmark
4949
fun ejmlInverse(blackhole: Blackhole) {
50-
with(EjmlLinearSpaceDDRM) {
50+
EjmlLinearSpaceDDRM {
5151
blackhole.consume(matrix.getFeature<InverseMatrixFeature<Double>>()?.inverse)
5252
}
5353
}

docs/nd-structure.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ via extension function.
115115
Usually it is bad idea to compare the direct numerical operation performance in different languages, but it hard to
116116
work completely without frame of reference. In this case, simple numpy code:
117117
```python
118+
import numpy as np
119+
118120
res = np.ones((1000,1000))
119121
for i in range(1000):
120122
res = res + 1.0

examples/src/main/kotlin/space/kscience/kmath/ast/astRendering.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import space.kscience.kmath.ast.rendering.LatexSyntaxRenderer
1010
import space.kscience.kmath.ast.rendering.MathMLSyntaxRenderer
1111
import space.kscience.kmath.ast.rendering.renderWithStringBuilder
1212

13-
public fun main() {
13+
fun main() {
1414
val mst = "exp(sqrt(x))-asin(2*x)/(2e10+x^3)/(-12)".parseMath()
1515
val syntax = FeaturedMathRendererWithPostProcess.Default.render(mst)
1616
println("MathSyntax:")

kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/features.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import space.kscience.kmath.operations.*
1313
import kotlin.reflect.KClass
1414

1515
/**
16-
* Prints any [Symbol] as a [SymbolSyntax] containing the [Symbol.value] of it.
16+
* Prints any [Symbol] as a [SymbolSyntax] containing the [Symbol.identity] of it.
1717
*
1818
* @author Iaroslav Postovalov
1919
*/

kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerConsistencyWithInterpreter.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import space.kscience.kmath.expressions.Symbol.Companion.x
1111
import space.kscience.kmath.expressions.interpret
1212
import space.kscience.kmath.operations.DoubleField
1313
import space.kscience.kmath.operations.IntRing
14-
import space.kscience.kmath.operations.bindSymbol
1514
import space.kscience.kmath.operations.invoke
1615
import kotlin.test.Test
1716
import kotlin.test.assertEquals

kmath-ast/src/commonTest/kotlin/space/kscience/kmath/ast/TestCompilerVariables.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import space.kscience.kmath.expressions.MstRing
99
import space.kscience.kmath.expressions.Symbol.Companion.x
1010
import space.kscience.kmath.expressions.invoke
1111
import space.kscience.kmath.operations.IntRing
12-
import space.kscience.kmath.operations.bindSymbol
1312
import space.kscience.kmath.operations.invoke
1413
import kotlin.test.Test
1514
import kotlin.test.assertEquals

kmath-ast/src/jsMain/kotlin/space/kscience/kmath/internal/estree/estree.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
44
*/
55

6+
@file:Suppress("ClassName")
7+
68
package space.kscience.kmath.internal.estree
79

810
import kotlin.js.RegExp

kmath-ast/src/jsTest/kotlin/space/kscience/kmath/ast/utils.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import space.kscience.kmath.expressions.MST
1010
import space.kscience.kmath.expressions.Symbol
1111
import space.kscience.kmath.operations.DoubleField
1212
import space.kscience.kmath.operations.IntRing
13+
import kotlin.contracts.InvocationKind
14+
import kotlin.contracts.contract
1315
import space.kscience.kmath.estree.compile as estreeCompile
1416
import space.kscience.kmath.estree.compileToExpression as estreeCompileToExpression
1517
import space.kscience.kmath.wasm.compile as wasmCompile
@@ -34,6 +36,7 @@ private object ESTreeCompilerTestContext : CompilerTestContext {
3436
}
3537

3638
internal actual inline fun runCompilerTest(action: CompilerTestContext.() -> Unit) {
39+
contract { callsInPlace(action, InvocationKind.AT_LEAST_ONCE) }
3740
action(WasmCompilerTestContext)
3841
action(ESTreeCompilerTestContext)
3942
}

kmath-ast/src/jsTest/kotlin/space/kscience/kmath/wasm/TestWasmSpecific.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import space.kscience.kmath.expressions.invoke
1111
import space.kscience.kmath.expressions.symbol
1212
import space.kscience.kmath.operations.DoubleField
1313
import space.kscience.kmath.operations.IntRing
14-
import space.kscience.kmath.operations.bindSymbol
1514
import space.kscience.kmath.operations.invoke
1615
import kotlin.test.Test
1716
import kotlin.test.assertEquals

kmath-ast/src/jvmTest/kotlin/space/kscience/kmath/ast/utils.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import space.kscience.kmath.expressions.MST
1010
import space.kscience.kmath.expressions.Symbol
1111
import space.kscience.kmath.operations.DoubleField
1212
import space.kscience.kmath.operations.IntRing
13+
import kotlin.contracts.InvocationKind
14+
import kotlin.contracts.contract
1315
import space.kscience.kmath.asm.compile as asmCompile
1416
import space.kscience.kmath.asm.compileToExpression as asmCompileToExpression
1517

@@ -22,4 +24,7 @@ private object AsmCompilerTestContext : CompilerTestContext {
2224
asmCompile(algebra, arguments)
2325
}
2426

25-
internal actual inline fun runCompilerTest(action: CompilerTestContext.() -> Unit) = action(AsmCompilerTestContext)
27+
internal actual inline fun runCompilerTest(action: CompilerTestContext.() -> Unit) {
28+
contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
29+
action(AsmCompilerTestContext)
30+
}

kmath-commons/src/main/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpression.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import space.kscience.kmath.operations.NumbersAddOperations
1515
* A field over commons-math [DerivativeStructure].
1616
*
1717
* @property order The derivation order.
18-
* @property bindings The map of bindings values. All bindings are considered free parameters
18+
* @param bindings The map of bindings values. All bindings are considered free parameters
1919
*/
2020
@OptIn(UnstableKMathAPI::class)
2121
public class DerivativeStructureField(

kmath-commons/src/main/kotlin/space/kscience/kmath/commons/optimization/CMOptimization.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ public class CMOptimization(
5252

5353
public fun exportOptimizationData(): List<OptimizationData> = optimizationData.values.toList()
5454

55-
public override fun initialGuess(map: Map<Symbol, Double>): Unit {
55+
public override fun initialGuess(map: Map<Symbol, Double>) {
5656
addOptimizationData(InitialGuess(map.toDoubleArray()))
5757
}
5858

59-
public override fun function(expression: Expression<Double>): Unit {
59+
public override fun function(expression: Expression<Double>) {
6060
val objectiveFunction = ObjectiveFunction {
6161
val args = it.toMap()
6262
expression(args)

kmath-commons/src/main/kotlin/space/kscience/kmath/commons/transform/Transformations.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public object Transformations {
3232
/**
3333
* Create a virtual buffer on top of array
3434
*/
35-
private fun Array<org.apache.commons.math3.complex.Complex>.asBuffer() = VirtualBuffer<Complex>(size) {
35+
private fun Array<org.apache.commons.math3.complex.Complex>.asBuffer() = VirtualBuffer(size) {
3636
val value = get(it)
3737
Complex(value.real, value.imaginary)
3838
}

kmath-commons/src/test/kotlin/space/kscience/kmath/commons/expressions/DerivativeStructureExpressionTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ internal inline fun diff(
1616
order: Int,
1717
vararg parameters: Pair<Symbol, Double>,
1818
block: DerivativeStructureField.() -> Unit,
19-
): Unit {
19+
) {
2020
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
2121
DerivativeStructureField(order, mapOf(*parameters)).run(block)
2222
}

kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Quaternion>,
147147
return if (arg.w > 0)
148148
Quaternion(ln(arg.w), 0, 0, 0)
149149
else {
150-
val l = ComplexField { ComplexField.ln(arg.w.toComplex()) }
150+
val l = ComplexField { ln(arg.w.toComplex()) }
151151
Quaternion(l.re, l.im, 0, 0)
152152
}
153153

kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYColumnarData.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import kotlin.math.max
1616
* The buffer of X values.
1717
*/
1818
@UnstableKMathAPI
19-
public interface XYColumnarData<T, out X : T, out Y : T> : ColumnarData<T> {
19+
public interface XYColumnarData<out T, out X : T, out Y : T> : ColumnarData<T> {
2020
/**
2121
* The buffer of X values
2222
*/

kmath-core/src/commonMain/kotlin/space/kscience/kmath/data/XYZColumnarData.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import space.kscience.kmath.structures.Buffer
1414
* Inherits [XYColumnarData].
1515
*/
1616
@UnstableKMathAPI
17-
public interface XYZColumnarData<T, out X : T, out Y : T, out Z : T> : XYColumnarData<T, X, Y> {
17+
public interface XYZColumnarData<out T, out X : T, out Y : T, out Z : T> : XYColumnarData<T, X, Y> {
1818
public val z: Buffer<Z>
1919

2020
override fun get(symbol: Symbol): Buffer<T>? = when (symbol) {
@@ -23,4 +23,4 @@ public interface XYZColumnarData<T, out X : T, out Y : T, out Z : T> : XYColumna
2323
Symbol.z -> z
2424
else -> null
2525
}
26-
}
26+
}

kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains/Domain.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import space.kscience.kmath.linear.Point
1212
*
1313
* @param T the type of element of this domain.
1414
*/
15-
public interface Domain<T : Any> {
15+
public interface Domain<in T : Any> {
1616
/**
1717
* Checks if the specified point is contained in this domain.
1818
*/

kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/DifferentiableExpression.kt

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ package space.kscience.kmath.expressions
99
* Represents expression which structure can be differentiated.
1010
*
1111
* @param T the type this expression takes as argument and returns.
12-
* @param R the type of expression this expression can be differentiated to.
1312
*/
1413
public interface DifferentiableExpression<T> : Expression<T> {
1514
/**
@@ -24,16 +23,18 @@ public interface DifferentiableExpression<T> : Expression<T> {
2423
public fun <T> DifferentiableExpression<T>.derivative(symbols: List<Symbol>): Expression<T> =
2524
derivativeOrNull(symbols) ?: error("Derivative by symbols $symbols not provided")
2625

27-
public fun <T> DifferentiableExpression<T>.derivative(vararg symbols: Symbol): Expression<T> =
26+
public fun <T> DifferentiableExpression<T>.derivative(vararg symbols: Symbol): Expression<T> =
2827
derivative(symbols.toList())
2928

30-
public fun <T> DifferentiableExpression<T>.derivative(name: String): Expression<T> =
29+
public fun <T> DifferentiableExpression<T>.derivative(name: String): Expression<T> =
3130
derivative(StringSymbol(name))
3231

3332
/**
34-
* A special type of [DifferentiableExpression] which returns typed expressions as derivatives
33+
* A special type of [DifferentiableExpression] which returns typed expressions as derivatives.
34+
*
35+
* @param R the type of expression this expression can be differentiated to.
3536
*/
36-
public interface SpecialDifferentiableExpression<T, R: Expression<T>>: DifferentiableExpression<T> {
37+
public interface SpecialDifferentiableExpression<T, out R : Expression<T>> : DifferentiableExpression<T> {
3738
override fun derivativeOrNull(symbols: List<Symbol>): R?
3839
}
3940

@@ -53,9 +54,9 @@ public abstract class FirstDerivativeExpression<T> : DifferentiableExpression<T>
5354
/**
5455
* Returns first derivative of this expression by given [symbol].
5556
*/
56-
public abstract fun derivativeOrNull(symbol: Symbol): Expression<T>?
57+
public abstract fun derivativeOrNull(symbol: Symbol): Expression<T>?
5758

58-
public final override fun derivativeOrNull(symbols: List<Symbol>): Expression<T>? {
59+
public final override fun derivativeOrNull(symbols: List<Symbol>): Expression<T>? {
5960
val dSymbol = symbols.firstOrNull() ?: return null
6061
return derivativeOrNull(dSymbol)
6162
}
@@ -64,6 +65,6 @@ public abstract class FirstDerivativeExpression<T> : DifferentiableExpression<T>
6465
/**
6566
* A factory that converts an expression in autodiff variables to a [DifferentiableExpression]
6667
*/
67-
public fun interface AutoDiffProcessor<T : Any, I : Any, A : ExpressionAlgebra<T, I>, out R : Expression<T>> {
68+
public fun interface AutoDiffProcessor<T : Any, I : Any, out A : ExpressionAlgebra<T, I>, out R : Expression<T>> {
6869
public fun process(function: A.() -> I): DifferentiableExpression<T>
6970
}

kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
package space.kscience.kmath.expressions
77

88
import space.kscience.kmath.operations.*
9+
import kotlin.contracts.InvocationKind
10+
import kotlin.contracts.contract
911

1012
/**
1113
* A context class for [Expression] construction.
1214
*
1315
* @param algebra The algebra to provide for Expressions built.
1416
*/
15-
public abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(
17+
public abstract class FunctionalExpressionAlgebra<T, out A : Algebra<T>>(
1618
public val algebra: A,
1719
) : ExpressionAlgebra<T, Expression<T>> {
1820
/**
@@ -29,19 +31,13 @@ public abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(
2931
?: error("Symbol '$value' is not supported in $this")
3032
}
3133

32-
/**
33-
* Builds an Expression of dynamic call of binary operation [operation] on [left] and [right].
34-
*/
3534
public override fun binaryOperationFunction(operation: String): (left: Expression<T>, right: Expression<T>) -> Expression<T> =
3635
{ left, right ->
3736
Expression { arguments ->
3837
algebra.binaryOperationFunction(operation)(left.invoke(arguments), right.invoke(arguments))
3938
}
4039
}
4140

42-
/**
43-
* Builds an Expression of dynamic call of unary operation with name [operation] on [arg].
44-
*/
4541
public override fun unaryOperationFunction(operation: String): (arg: Expression<T>) -> Expression<T> = { arg ->
4642
Expression { arguments -> algebra.unaryOperationFunction(operation)(arg.invoke(arguments)) }
4743
}
@@ -50,7 +46,7 @@ public abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(
5046
/**
5147
* A context class for [Expression] construction for [Ring] algebras.
5248
*/
53-
public open class FunctionalExpressionGroup<T, A : Group<T>>(
49+
public open class FunctionalExpressionGroup<T, out A : Group<T>>(
5450
algebra: A,
5551
) : FunctionalExpressionAlgebra<T, A>(algebra), Group<Expression<T>> {
5652
public override val zero: Expression<T> get() = const(algebra.zero)
@@ -84,7 +80,7 @@ public open class FunctionalExpressionGroup<T, A : Group<T>>(
8480

8581
}
8682

87-
public open class FunctionalExpressionRing<T, A : Ring<T>>(
83+
public open class FunctionalExpressionRing<T, out A : Ring<T>>(
8884
algebra: A,
8985
) : FunctionalExpressionGroup<T, A>(algebra), Ring<Expression<T>> {
9086
public override val one: Expression<T> get() = const(algebra.one)
@@ -105,7 +101,7 @@ public open class FunctionalExpressionRing<T, A : Ring<T>>(
105101
super<FunctionalExpressionGroup>.binaryOperationFunction(operation)
106102
}
107103

108-
public open class FunctionalExpressionField<T, A : Field<T>>(
104+
public open class FunctionalExpressionField<T, out A : Field<T>>(
109105
algebra: A,
110106
) : FunctionalExpressionRing<T, A>(algebra), Field<Expression<T>>, ScaleOperations<Expression<T>> {
111107
/**
@@ -131,7 +127,7 @@ public open class FunctionalExpressionField<T, A : Field<T>>(
131127
super<FunctionalExpressionRing>.bindSymbolOrNull(value)
132128
}
133129

134-
public open class FunctionalExpressionExtendedField<T, A : ExtendedField<T>>(
130+
public open class FunctionalExpressionExtendedField<T, out A : ExtendedField<T>>(
135131
algebra: A,
136132
) : FunctionalExpressionField<T, A>(algebra), ExtendedField<Expression<T>> {
137133
public override fun number(value: Number): Expression<T> = const(algebra.number(value))
@@ -172,14 +168,26 @@ public open class FunctionalExpressionExtendedField<T, A : ExtendedField<T>>(
172168
public override fun bindSymbol(value: String): Expression<T> = super<FunctionalExpressionField>.bindSymbol(value)
173169
}
174170

175-
public inline fun <T, A : Ring<T>> A.expressionInSpace(block: FunctionalExpressionGroup<T, A>.() -> Expression<T>): Expression<T> =
176-
FunctionalExpressionGroup(this).block()
171+
public inline fun <T, A : Group<T>> A.expressionInGroup(
172+
block: FunctionalExpressionGroup<T, A>.() -> Expression<T>,
173+
): Expression<T> {
174+
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
175+
return FunctionalExpressionGroup(this).block()
176+
}
177177

178-
public inline fun <T, A : Ring<T>> A.expressionInRing(block: FunctionalExpressionRing<T, A>.() -> Expression<T>): Expression<T> =
179-
FunctionalExpressionRing(this).block()
178+
public inline fun <T, A : Ring<T>> A.expressionInRing(
179+
block: FunctionalExpressionRing<T, A>.() -> Expression<T>,
180+
): Expression<T> {
181+
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
182+
return FunctionalExpressionRing(this).block()
183+
}
180184

181-
public inline fun <T, A : Field<T>> A.expressionInField(block: FunctionalExpressionField<T, A>.() -> Expression<T>): Expression<T> =
182-
FunctionalExpressionField(this).block()
185+
public inline fun <T, A : Field<T>> A.expressionInField(
186+
block: FunctionalExpressionField<T, A>.() -> Expression<T>,
187+
): Expression<T> {
188+
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
189+
return FunctionalExpressionField(this).block()
190+
}
183191

184192
public inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField(
185193
block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>,

0 commit comments

Comments
 (0)