Merge branch 'dev' into gsl-experiment

# Conflicts:
#	CHANGELOG.md
#	gradle.properties
#	kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt
#	kmath-stat/build.gradle.kts
This commit is contained in:
Iaroslav Postovalov 2021-02-11 17:28:22 +07:00
commit 228b55f5ea
No known key found for this signature in database
GPG Key ID: 46E15E4A31B3BCD7
50 changed files with 591 additions and 361 deletions
CHANGELOG.mdREADME.md
examples
build.gradle.kts
src
benchmarks/kotlin/kscience/kmath/benchmarks
main/kotlin/kscience/kmath
operations
structures
gradle.properties
kmath-ast
build.gradle.kts
src
jsTest/kotlin/kscience/kmath/estree
jvmTest/kotlin/kscience/kmath
kmath-commons
build.gradle.kts
src/main/kotlin/kscience/kmath/commons/transform
kmath-complex
kmath-core
kmath-coroutines
kmath-for-real/src/commonTest/kotlin/kaceince/kmath/real
kmath-stat
settings.gradle.kts

@ -18,6 +18,7 @@
- Some minor utilities to `kmath-for-real` - Some minor utilities to `kmath-for-real`
- Generic operation result parameter to `MatrixContext` - Generic operation result parameter to `MatrixContext`
- New `MatrixFeature` interfaces for matrix decompositions - New `MatrixFeature` interfaces for matrix decompositions
- Basic Quaternion vector support in `kmath-complex`.
- Integration with GNU Scientific Library with `kmath-gsl` for Kotlin/Native Linux x64 target. - Integration with GNU Scientific Library with `kmath-gsl` for Kotlin/Native Linux x64 target.
### Changed ### Changed
@ -39,6 +40,7 @@
- Capitalization of LUP in many names changed to Lup. - Capitalization of LUP in many names changed to Lup.
- Refactored `NDStructure` algebra to be more simple, preferring under-the-hood conversion to explicit NDStructure types - Refactored `NDStructure` algebra to be more simple, preferring under-the-hood conversion to explicit NDStructure types
- Refactor histograms. They are marked as prototype - Refactor histograms. They are marked as prototype
- `Complex` and related features moved to a separate module `kmath-complex`
- Refactor AlgebraElement - Refactor AlgebraElement
### Deprecated ### Deprecated

@ -104,6 +104,17 @@ KMath is a modular library. Different modules provide different features with di
> **Maturity**: EXPERIMENTAL > **Maturity**: EXPERIMENTAL
<hr/> <hr/>
* ### [kmath-complex](kmath-complex)
> Complex numbers and quaternions.
>
> **Maturity**: PROTOTYPE
>
> **Features:**
> - [complex](kmath-complex/src/commonMain/kotlin/kscience/kmath/complex/Complex.kt) : Complex Numbers
> - [quaternion](kmath-complex/src/commonMain/kotlin/kscience/kmath/complex/Quaternion.kt) : Quaternions
<hr/>
* ### [kmath-core](kmath-core) * ### [kmath-core](kmath-core)
> Core classes, algebra definitions, basic linear algebra > Core classes, algebra definitions, basic linear algebra
> >

@ -29,6 +29,7 @@ dependencies {
implementation(project(":kmath-core")) implementation(project(":kmath-core"))
implementation(project(":kmath-coroutines")) implementation(project(":kmath-coroutines"))
implementation(project(":kmath-commons")) implementation(project(":kmath-commons"))
implementation(project(":kmath-complex"))
implementation(project(":kmath-stat")) implementation(project(":kmath-stat"))
implementation(project(":kmath-viktor")) implementation(project(":kmath-viktor"))
implementation(project(":kmath-dimensions")) implementation(project(":kmath-dimensions"))

@ -14,7 +14,7 @@ import org.openjdk.jmh.annotations.State
import kotlin.random.Random import kotlin.random.Random
@State(Scope.Benchmark) @State(Scope.Benchmark)
class DotBenchmark { internal class DotBenchmark {
companion object { companion object {
val random = Random(12224) val random = Random(12224)
val dim = 1000 val dim = 1000

@ -1,6 +1,8 @@
package kscience.kmath.ast package kscience.kmath.benchmarks
import kscience.kmath.asm.compile import kscience.kmath.asm.compile
import kscience.kmath.ast.MstField
import kscience.kmath.ast.mstInField
import kscience.kmath.expressions.Expression import kscience.kmath.expressions.Expression
import kscience.kmath.expressions.expressionInField import kscience.kmath.expressions.expressionInField
import kscience.kmath.expressions.invoke import kscience.kmath.expressions.invoke
@ -37,7 +39,7 @@ internal class ExpressionsInterpretersBenchmark {
@Benchmark @Benchmark
fun asmExpression() { fun asmExpression() {
val expr = algebra.mstInField { val expr = algebra.mstInField {
symbol("x") * 2.0 + 2.0 / symbol("x") - 16.0 MstField.symbol("x") * 2.0 + 2.0 / MstField.symbol("x") - 16.0
}.compile() }.compile()
invokeAndSum(expr) invokeAndSum(expr)

@ -1,5 +1,4 @@
package kscience.kmath.linear package kscience.kmath.benchmarks
import kotlinx.benchmark.Benchmark import kotlinx.benchmark.Benchmark
import kscience.kmath.commons.linear.CMMatrixContext import kscience.kmath.commons.linear.CMMatrixContext
@ -7,14 +6,17 @@ import kscience.kmath.commons.linear.CMMatrixContext.dot
import kscience.kmath.commons.linear.inverse import kscience.kmath.commons.linear.inverse
import kscience.kmath.ejml.EjmlMatrixContext import kscience.kmath.ejml.EjmlMatrixContext
import kscience.kmath.ejml.inverse import kscience.kmath.ejml.inverse
import kscience.kmath.linear.Matrix
import kscience.kmath.linear.MatrixContext
import kscience.kmath.linear.inverseWithLup
import kscience.kmath.linear.real
import kscience.kmath.operations.invoke import kscience.kmath.operations.invoke
import kscience.kmath.structures.Matrix
import org.openjdk.jmh.annotations.Scope import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State import org.openjdk.jmh.annotations.State
import kotlin.random.Random import kotlin.random.Random
@State(Scope.Benchmark) @State(Scope.Benchmark)
class LinearAlgebraBenchmark { internal class LinearAlgebraBenchmark {
companion object { companion object {
val random = Random(1224) val random = Random(1224)
val dim = 100 val dim = 100

@ -1,11 +1,12 @@
package kscience.kmath.operations package kscience.kmath.operations
import kscience.kmath.complex.Complex
import kscience.kmath.complex.complex
import kscience.kmath.nd.NDAlgebra import kscience.kmath.nd.NDAlgebra
import kscience.kmath.nd.complex
fun main() { fun main() {
// 2d element // 2d element
val element = NDAlgebra.complex(2, 2).produce { (i,j) -> val element = NDAlgebra.complex(2, 2).produce { (i, j) ->
Complex(i.toDouble() - j.toDouble(), i.toDouble() + j.toDouble()) Complex(i.toDouble() - j.toDouble(), i.toDouble() + j.toDouble())
} }
println(element) println(element)
@ -18,5 +19,6 @@ fun main() {
(a pow b) + c (a pow b) + c
} }
println(result) println(result)
} }

@ -2,10 +2,12 @@
package kscience.kmath.structures package kscience.kmath.structures
import kscience.kmath.complex.*
import kscience.kmath.linear.transpose import kscience.kmath.linear.transpose
import kscience.kmath.nd.* import kscience.kmath.nd.NDAlgebra
import kscience.kmath.operations.Complex import kscience.kmath.nd.NDStructure
import kscience.kmath.operations.ComplexField import kscience.kmath.nd.as2D
import kscience.kmath.nd.real
import kscience.kmath.operations.invoke import kscience.kmath.operations.invoke
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis

@ -2,7 +2,6 @@ kotlin.code.style=official
kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.mpp.stability.nowarn=true kotlin.mpp.stability.nowarn=true
kotlin.native.enableDependencyPropagation=false kotlin.native.enableDependencyPropagation=false
kotlin.native.ignoreDisabledTargets=true
kotlin.parallel.tasks.in.project=true kotlin.parallel.tasks.in.project=true
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
org.gradle.parallel=true org.gradle.parallel=true

@ -25,6 +25,12 @@ kotlin.sourceSets {
} }
} }
commonTest {
dependencies {
implementation(project(":kmath-complex"))
}
}
jsMain { jsMain {
dependencies { dependencies {
implementation(npm("astring", "1.4.3")) implementation(npm("astring", "1.4.3"))

@ -1,11 +1,11 @@
package kscience.kmath.estree package kscience.kmath.estree
import kscience.kmath.ast.* import kscience.kmath.ast.*
import kscience.kmath.complex.ComplexField
import kscience.kmath.complex.toComplex
import kscience.kmath.expressions.invoke import kscience.kmath.expressions.invoke
import kscience.kmath.operations.ByteRing import kscience.kmath.operations.ByteRing
import kscience.kmath.operations.ComplexField
import kscience.kmath.operations.RealField import kscience.kmath.operations.RealField
import kscience.kmath.operations.toComplex
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

@ -1,11 +1,10 @@
package kscience.kmath.asm package kscience.kmath.asm
import kscience.kmath.ast.* import kscience.kmath.ast.*
import kscience.kmath.complex.*
import kscience.kmath.expressions.invoke import kscience.kmath.expressions.invoke
import kscience.kmath.operations.ByteRing import kscience.kmath.operations.ByteRing
import kscience.kmath.operations.ComplexField
import kscience.kmath.operations.RealField import kscience.kmath.operations.RealField
import kscience.kmath.operations.toComplex
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

@ -1,9 +1,9 @@
package kscience.kmath.ast package kscience.kmath.ast
import kscience.kmath.complex.Complex
import kscience.kmath.complex.ComplexField
import kscience.kmath.expressions.invoke import kscience.kmath.expressions.invoke
import kscience.kmath.operations.Algebra import kscience.kmath.operations.Algebra
import kscience.kmath.operations.Complex
import kscience.kmath.operations.ComplexField
import kscience.kmath.operations.RealField import kscience.kmath.operations.RealField
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

@ -5,6 +5,7 @@ description = "Commons math binding for kmath"
dependencies { dependencies {
api(project(":kmath-core")) api(project(":kmath-core"))
api(project(":kmath-complex"))
api(project(":kmath-coroutines")) api(project(":kmath-coroutines"))
api(project(":kmath-stat")) api(project(":kmath-stat"))
api(project(":kmath-functions")) api(project(":kmath-functions"))

@ -3,7 +3,7 @@ package kscience.kmath.commons.transform
import kotlinx.coroutines.FlowPreview import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import kscience.kmath.operations.Complex import kscience.kmath.complex.*
import kscience.kmath.streaming.chunked import kscience.kmath.streaming.chunked
import kscience.kmath.streaming.spread import kscience.kmath.streaming.spread
import kscience.kmath.structures.* import kscience.kmath.structures.*

45
kmath-complex/README.md Normal file

@ -0,0 +1,45 @@
# The Core Module (`kmath-core`)
Complex and hypercomplex number systems in KMath:
- [complex](src/commonMain/kotlin/kscience/kmath/complex/Complex.kt) : Complex Numbers
- [quaternion](src/commonMain/kotlin/kscience/kmath/complex/Quaternion.kt) : Quaternions
> #### Artifact:
>
> This module artifact: `kscience.kmath:kmath-complex:0.2.0-dev-6`.
>
> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-complex/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-complex/_latestVersion)
>
> Bintray development version: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-complex/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-complex/_latestVersion)
>
> **Gradle:**
>
> ```gradle
> repositories {
> maven { url "https://dl.bintray.com/kotlin/kotlin-eap" }
> maven { url 'https://dl.bintray.com/mipt-npm/kscience' }
> maven { url 'https://dl.bintray.com/mipt-npm/dev' }
> maven { url 'https://dl.bintray.com/hotkeytlt/maven' }
>
> }
>
> dependencies {
> implementation 'kscience.kmath:kmath-complex:0.2.0-dev-6'
> }
> ```
> **Gradle Kotlin DSL:**
>
> ```kotlin
> repositories {
> maven("https://dl.bintray.com/kotlin/kotlin-eap")
> maven("https://dl.bintray.com/mipt-npm/kscience")
> maven("https://dl.bintray.com/mipt-npm/dev")
> maven("https://dl.bintray.com/hotkeytlt/maven")
> }
>
> dependencies {
> implementation("kscience.kmath:kmath-complex:0.2.0-dev-6")
> }
> ```

@ -0,0 +1,36 @@
import ru.mipt.npm.gradle.Maturity
plugins {
id("ru.mipt.npm.mpp")
id("ru.mipt.npm.native")
}
kotlin.sourceSets {
all {
languageSettings.useExperimentalAnnotation("kscience.kmath.misc.UnstableKMathAPI")
}
commonMain {
dependencies {
api(project(":kmath-core"))
}
}
}
readme {
description = "Complex numbers and quaternions."
maturity = Maturity.PROTOTYPE
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature(
id = "complex",
description = "Complex Numbers",
ref = "src/commonMain/kotlin/kscience/kmath/complex/Complex.kt"
)
feature(
id = "quaternion",
description = "Quaternions",
ref = "src/commonMain/kotlin/kscience/kmath/complex/Quaternion.kt"
)
}

@ -0,0 +1,7 @@
# The Core Module (`kmath-core`)
Complex and hypercomplex number systems in KMath:
${features}
${artifact}

@ -1,9 +1,12 @@
package kscience.kmath.operations package kscience.kmath.complex
import kscience.kmath.memory.MemoryReader import kscience.kmath.memory.MemoryReader
import kscience.kmath.memory.MemorySpec import kscience.kmath.memory.MemorySpec
import kscience.kmath.memory.MemoryWriter import kscience.kmath.memory.MemoryWriter
import kscience.kmath.misc.UnstableKMathAPI import kscience.kmath.operations.ExtendedField
import kscience.kmath.operations.FieldElement
import kscience.kmath.operations.Norm
import kscience.kmath.operations.RingWithNumbers
import kscience.kmath.structures.Buffer import kscience.kmath.structures.Buffer
import kscience.kmath.structures.MemoryBuffer import kscience.kmath.structures.MemoryBuffer
import kscience.kmath.structures.MutableBuffer import kscience.kmath.structures.MutableBuffer
@ -42,74 +45,70 @@ private val PI_DIV_2 = Complex(PI / 2, 0)
/** /**
* A field of [Complex]. * A field of [Complex].
*/ */
@OptIn(UnstableKMathAPI::class)
public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, RingWithNumbers<Complex> { public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, RingWithNumbers<Complex> {
override val zero: Complex = 0.0.toComplex() public override val zero: Complex = 0.0.toComplex()
override val one: Complex = 1.0.toComplex() public override val one: Complex = 1.0.toComplex()
/** /**
* The imaginary unit. * The imaginary unit.
*/ */
public val i: Complex = Complex(0.0, 1.0) public val i: Complex by lazy { Complex(0.0, 1.0) }
override fun add(a: Complex, b: Complex): Complex = Complex(a.re + b.re, a.im + b.im) public override fun add(a: Complex, b: Complex): Complex = Complex(a.re + b.re, a.im + b.im)
public override fun multiply(a: Complex, k: Number): Complex = Complex(a.re * k.toDouble(), a.im * k.toDouble())
override fun multiply(a: Complex, k: Number): Complex = Complex(a.re * k.toDouble(), a.im * k.toDouble()) public override fun multiply(a: Complex, b: Complex): Complex =
override fun multiply(a: Complex, b: Complex): Complex =
Complex(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re) Complex(a.re * b.re - a.im * b.im, a.re * b.im + a.im * b.re)
override fun divide(a: Complex, b: Complex): Complex = when { public override fun divide(a: Complex, b: Complex): Complex = when {
b.re.isNaN() || b.im.isNaN() -> Complex(Double.NaN, Double.NaN) abs(b.im) < abs(b.re) -> {
(if (b.im < 0) -b.im else +b.im) < (if (b.re < 0) -b.re else +b.re) -> {
val wr = b.im / b.re val wr = b.im / b.re
val wd = b.re + wr * b.im val wd = b.re + wr * b.im
if (wd.isNaN() || wd == 0.0) if (wd.isNaN() || wd == 0.0)
Complex(Double.NaN, Double.NaN) throw ArithmeticException("Division by zero or infinity")
else else
Complex((a.re + a.im * wr) / wd, (a.im - a.re * wr) / wd) Complex((a.re + a.im * wr) / wd, (a.im - a.re * wr) / wd)
} }
b.im == 0.0 -> Complex(Double.NaN, Double.NaN) b.im == 0.0 -> throw ArithmeticException("Division by zero")
else -> { else -> {
val wr = b.re / b.im val wr = b.re / b.im
val wd = b.im + wr * b.re val wd = b.im + wr * b.re
if (wd.isNaN() || wd == 0.0) if (wd.isNaN() || wd == 0.0)
Complex(Double.NaN, Double.NaN) throw ArithmeticException("Division by zero or infinity")
else else
Complex((a.re * wr + a.im) / wd, (a.im * wr - a.re) / wd) Complex((a.re * wr + a.im) / wd, (a.im * wr - a.re) / wd)
} }
} }
override fun sin(arg: Complex): Complex = i * (exp(-i * arg) - exp(i * arg)) / 2 public override fun sin(arg: Complex): Complex = i * (exp(-i * arg) - exp(i * arg)) / 2
override fun cos(arg: Complex): Complex = (exp(-i * arg) + exp(i * arg)) / 2 public override fun cos(arg: Complex): Complex = (exp(-i * arg) + exp(i * arg)) / 2
override fun tan(arg: Complex): Complex { public override fun tan(arg: Complex): Complex {
val e1 = exp(-i * arg) val e1 = exp(-i * arg)
val e2 = exp(i * arg) val e2 = exp(i * arg)
return i * (e1 - e2) / (e1 + e2) return i * (e1 - e2) / (e1 + e2)
} }
override fun asin(arg: Complex): Complex = -i * ln(sqrt(1 - (arg * arg)) + i * arg) public override fun asin(arg: Complex): Complex = -i * ln(sqrt(1 - (arg * arg)) + i * arg)
override fun acos(arg: Complex): Complex = PI_DIV_2 + i * ln(sqrt(1 - (arg * arg)) + i * arg) public override fun acos(arg: Complex): Complex = PI_DIV_2 + i * ln(sqrt(1 - (arg * arg)) + i * arg)
override fun atan(arg: Complex): Complex { public override fun atan(arg: Complex): Complex {
val iArg = i * arg val iArg = i * arg
return i * (ln(1 - iArg) - ln(1 + iArg)) / 2 return i * (ln(1 - iArg) - ln(1 + iArg)) / 2
} }
override fun power(arg: Complex, pow: Number): Complex = if (arg.im == 0.0) public override fun power(arg: Complex, pow: Number): Complex = if (arg.im == 0.0)
arg.re.pow(pow.toDouble()).toComplex() arg.re.pow(pow.toDouble()).toComplex()
else else
exp(pow * ln(arg)) exp(pow * ln(arg))
override fun exp(arg: Complex): Complex = exp(arg.re) * (cos(arg.im) + i * sin(arg.im)) public override fun exp(arg: Complex): Complex = exp(arg.re) * (cos(arg.im) + i * sin(arg.im))
override fun ln(arg: Complex): Complex = ln(arg.r) + i * atan2(arg.im, arg.re) public override fun ln(arg: Complex): Complex = ln(arg.r) + i * atan2(arg.im, arg.re)
/** /**
* Adds complex number to real one. * Adds complex number to real one.
@ -156,9 +155,9 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, Rin
*/ */
public operator fun Double.times(c: Complex): Complex = Complex(c.re * this, c.im * this) public operator fun Double.times(c: Complex): Complex = Complex(c.re * this, c.im * this)
override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg) public override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg)
override fun symbol(value: String): Complex = if (value == "i") i else super<ExtendedField>.symbol(value) public override fun symbol(value: String): Complex = if (value == "i") i else super<ExtendedField>.symbol(value)
} }
/** /**
@ -167,29 +166,21 @@ public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, Rin
* @property re The real part. * @property re The real part.
* @property im The imaginary part. * @property im The imaginary part.
*/ */
@OptIn(UnstableKMathAPI::class) public data class Complex(val re: Double, val im: Double) : FieldElement<Complex, ComplexField> {
public data class Complex(
val re: Double,
val im: Double,
) : FieldElement<Complex, ComplexField>, Comparable<Complex> {
public constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble()) public constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble())
public constructor(re: Number) : this(re.toDouble(), 0.0)
override val context: ComplexField get() = ComplexField public override val context: ComplexField get() = ComplexField
override fun compareTo(other: Complex): Int = r.compareTo(other.r)
override fun toString(): String {
return "($re + i*$im)"
}
public override fun toString(): String = "($re + i*$im)"
public companion object : MemorySpec<Complex> { public companion object : MemorySpec<Complex> {
override val objectSize: Int public override val objectSize: Int
get() = 16 get() = 16
override fun MemoryReader.read(offset: Int): Complex = Complex(readDouble(offset), readDouble(offset + 8)) public override fun MemoryReader.read(offset: Int): Complex = Complex(readDouble(offset), readDouble(offset + 8))
override fun MemoryWriter.write(offset: Int, value: Complex) { public override fun MemoryWriter.write(offset: Int, value: Complex) {
writeDouble(offset, value.re) writeDouble(offset, value.re)
writeDouble(offset + 8, value.im) writeDouble(offset + 8, value.im)
} }
@ -203,7 +194,7 @@ public data class Complex(
* @receiver the real part. * @receiver the real part.
* @return the new complex number. * @return the new complex number.
*/ */
public fun Number.toComplex(): Complex = Complex(this, 0.0) public fun Number.toComplex(): Complex = Complex(this)
/** /**
* Creates a new buffer of complex numbers with the specified [size], where each element is calculated by calling the * Creates a new buffer of complex numbers with the specified [size], where each element is calculated by calling the

@ -1,6 +1,10 @@
package kscience.kmath.nd package kscience.kmath.complex
import kscience.kmath.misc.UnstableKMathAPI import kscience.kmath.misc.UnstableKMathAPI
import kscience.kmath.nd.BufferedNDField
import kscience.kmath.nd.NDAlgebra
import kscience.kmath.nd.NDBuffer
import kscience.kmath.nd.NDStructure
import kscience.kmath.operations.* import kscience.kmath.operations.*
import kscience.kmath.structures.Buffer import kscience.kmath.structures.Buffer
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind

@ -0,0 +1,259 @@
package kscience.kmath.complex
import kscience.kmath.memory.MemoryReader
import kscience.kmath.memory.MemorySpec
import kscience.kmath.memory.MemoryWriter
import kscience.kmath.operations.*
import kscience.kmath.structures.Buffer
import kscience.kmath.structures.MemoryBuffer
import kscience.kmath.structures.MutableBuffer
import kscience.kmath.structures.MutableMemoryBuffer
import kotlin.math.*
/**
* This quaternion's conjugate.
*/
public val Quaternion.conjugate: Quaternion
get() = QuaternionField { z - x * i - y * j - z * k }
/**
* This quaternion's reciprocal.
*/
public val Quaternion.reciprocal: Quaternion
get() {
val n = QuaternionField { norm(this@reciprocal) }
return conjugate / (n * n)
}
/**
* Absolute value of the quaternion.
*/
public val Quaternion.r: Double
get() = sqrt(w * w + x * x + y * y + z * z)
/**
* A field of [Quaternion].
*/
public object QuaternionField : Field<Quaternion>, Norm<Quaternion, Quaternion>, PowerOperations<Quaternion>,
ExponentialOperations<Quaternion>, RingWithNumbers<Quaternion> {
override val zero: Quaternion = 0.toQuaternion()
override val one: Quaternion = 1.toQuaternion()
/**
* The `i` quaternion unit.
*/
public val i: Quaternion = Quaternion(0, 1)
/**
* The `j` quaternion unit.
*/
public val j: Quaternion = Quaternion(0, 0, 1)
/**
* The `k` quaternion unit.
*/
public val k: Quaternion = Quaternion(0, 0, 0, 1)
public override fun add(a: Quaternion, b: Quaternion): Quaternion =
Quaternion(a.w + b.w, a.x + b.x, a.y + b.y, a.z + b.z)
public override fun multiply(a: Quaternion, k: Number): Quaternion {
val d = k.toDouble()
return Quaternion(a.w * d, a.x * d, a.y * d, a.z * d)
}
public override fun multiply(a: Quaternion, b: Quaternion): Quaternion = Quaternion(
a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z,
a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,
)
public override fun divide(a: Quaternion, b: Quaternion): Quaternion {
val s = b.w * b.w + b.x * b.x + b.y * b.y + b.z * b.z
return Quaternion(
(b.w * a.w + b.x * a.x + b.y * a.y + b.z * a.z) / s,
(b.w * a.x - b.x * a.w - b.y * a.z + b.z * a.y) / s,
(b.w * a.y + b.x * a.z - b.y * a.w - b.z * a.x) / s,
(b.w * a.z - b.x * a.y + b.y * a.x - b.z * a.w) / s,
)
}
public override fun power(arg: Quaternion, pow: Number): Quaternion {
if (pow is Int) return pwr(arg, pow)
if (floor(pow.toDouble()) == pow.toDouble()) return pwr(arg, pow.toInt())
return exp(pow * ln(arg))
}
private fun pwr(x: Quaternion, a: Int): Quaternion = when {
a < 0 -> -(pwr(x, -a))
a == 0 -> one
a == 1 -> x
a == 2 -> pwr2(x)
a == 3 -> pwr3(x)
a == 4 -> pwr4(x)
else -> {
val x4 = pwr4(x)
var y = x4
repeat((1 until a / 4).count()) { y *= x4 }
if (a % 4 == 3) y *= pwr3(x)
if (a % 4 == 2) y *= pwr2(x)
if (a % 4 == 1) y *= x
y
}
}
private fun pwr2(x: Quaternion): Quaternion {
val aa = 2 * x.w
return Quaternion(x.w * x.w - (x.x * x.x + x.y * x.y + x.z * x.z), aa * x.x, aa * x.y, aa * x.z)
}
private fun pwr3(x: Quaternion): Quaternion {
val a2 = x.w * x.w
val n1 = x.x * x.x + x.y * x.y + x.z * x.z
val n2 = 3.0 * a2 - n1
return Quaternion(x.w * (a2 - 3 * n1), x.x * n2, x.y * n2, x.z * n2)
}
private fun pwr4(x: Quaternion): Quaternion {
val a2 = x.w * x.w
val n1 = x.x * x.x + x.y * x.y + x.z * x.z
val n2 = 4 * x.w * (a2 - n1)
return Quaternion(a2 * a2 - 6 * a2 * n1 + n1 * n1, x.x * n2, x.y * n2, x.z * n2)
}
public override fun exp(arg: Quaternion): Quaternion {
val un = arg.x * arg.x + arg.y * arg.y + arg.z * arg.z
if (un == 0.0) return exp(arg.w).toQuaternion()
val n1 = sqrt(un)
val ea = exp(arg.w)
val n2 = ea * sin(n1) / n1
return Quaternion(ea * cos(n1), n2 * arg.x, n2 * arg.y, n2 * arg.z)
}
public override fun ln(arg: Quaternion): Quaternion {
val nu2 = arg.x * arg.x + arg.y * arg.y + arg.z * arg.z
if (nu2 == 0.0)
return if (arg.w > 0)
Quaternion(ln(arg.w), 0, 0, 0)
else {
val l = ComplexField { ComplexField.ln(arg.w.toComplex()) }
Quaternion(l.re, l.im, 0, 0)
}
val a = arg.w
check(nu2 > 0)
val n = sqrt(a * a + nu2)
val th = acos(a / n) / sqrt(nu2)
return Quaternion(ln(n), th * arg.x, th * arg.y, th * arg.z)
}
public override operator fun Number.plus(b: Quaternion): Quaternion = Quaternion(toDouble() + b.w, b.x, b.y, b.z)
public override operator fun Number.minus(b: Quaternion): Quaternion =
Quaternion(toDouble() - b.w, -b.x, -b.y, -b.z)
public override operator fun Quaternion.plus(b: Number): Quaternion = Quaternion(w + b.toDouble(), x, y, z)
public override operator fun Quaternion.minus(b: Number): Quaternion = Quaternion(w - b.toDouble(), x, y, z)
public override operator fun Number.times(b: Quaternion): Quaternion =
Quaternion(toDouble() * b.w, toDouble() * b.x, toDouble() * b.y, toDouble() * b.z)
public override fun Quaternion.unaryMinus(): Quaternion = Quaternion(-w, -x, -y, -z)
public override fun norm(arg: Quaternion): Quaternion = sqrt(arg.conjugate * arg)
public override fun symbol(value: String): Quaternion = when (value) {
"i" -> i
"j" -> j
"k" -> k
else -> super<Field>.symbol(value)
}
}
/**
* Represents `double`-based quaternion.
*
* @property w The first component.
* @property x The second component.
* @property y The third component.
* @property z The fourth component.
*/
public data class Quaternion(val w: Double, val x: Double, val y: Double, val z: Double) :
FieldElement<Quaternion, QuaternionField> {
public constructor(w: Number, x: Number, y: Number, z: Number) : this(
w.toDouble(),
x.toDouble(),
y.toDouble(),
z.toDouble(),
)
public constructor(w: Number, x: Number, y: Number) : this(w.toDouble(), x.toDouble(), y.toDouble(), 0.0)
public constructor(w: Number, x: Number) : this(w.toDouble(), x.toDouble(), 0.0, 0.0)
public constructor(w: Number) : this(w.toDouble(), 0.0, 0.0, 0.0)
public constructor(wx: Complex, yz: Complex) : this(wx.re, wx.im, yz.re, yz.im)
public constructor(wx: Complex) : this(wx.re, wx.im, 0, 0)
init {
require(!w.isNaN()) { "w-component of quaternion is not-a-number" }
require(!x.isNaN()) { "x-component of quaternion is not-a-number" }
require(!y.isNaN()) { "x-component of quaternion is not-a-number" }
require(!z.isNaN()) { "x-component of quaternion is not-a-number" }
}
public override val context: QuaternionField
get() = QuaternionField
/**
* Returns a string representation of this quaternion.
*/
public override fun toString(): String = "($w + $x * i + $y * j + $z * k)"
public companion object : MemorySpec<Quaternion> {
public override val objectSize: Int
get() = 32
public override fun MemoryReader.read(offset: Int): Quaternion =
Quaternion(readDouble(offset), readDouble(offset + 8), readDouble(offset + 16), readDouble(offset + 24))
public override fun MemoryWriter.write(offset: Int, value: Quaternion) {
writeDouble(offset, value.w)
writeDouble(offset + 8, value.x)
writeDouble(offset + 16, value.y)
writeDouble(offset + 24, value.z)
}
}
}
/**
* Creates a quaternion with real part equal to this real.
*
* @receiver the real part.
* @return a new quaternion.
*/
public fun Number.toQuaternion(): Quaternion = Quaternion(this)
/**
* Creates a quaternion with `w`-component equal to `re`-component of given complex and `x`-component equal to
* `im`-component of given complex.
*
* @receiver the complex number.
* @return a new quaternion.
*/
public fun Complex.toQuaternion(): Quaternion = Quaternion(this)
/**
* Creates a new buffer of quaternions with the specified [size], where each element is calculated by calling the
* specified [init] function.
*/
public inline fun Buffer.Companion.quaternion(size: Int, init: (Int) -> Quaternion): Buffer<Quaternion> =
MemoryBuffer.create(Quaternion, size, init)
/**
* Creates a new buffer of quaternions with the specified [size], where each element is calculated by calling the
* specified [init] function.
*/
public inline fun MutableBuffer.Companion.quaternion(size: Int, init: (Int) -> Quaternion): MutableBuffer<Quaternion> =
MutableMemoryBuffer.create(Quaternion, size, init)

@ -1,7 +1,6 @@
package kscience.kmath.structures package kscience.kmath.complex
import kscience.kmath.operations.Complex import kscience.kmath.structures.Buffer
import kscience.kmath.operations.complex
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

@ -1,6 +1,6 @@
package kscience.kmath.operations package kscience.kmath.complex
import kscience.kmath.operations.internal.FieldVerifier import kscience.kmath.operations.invoke
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.abs import kotlin.math.abs
import kotlin.test.Test import kotlin.test.Test
@ -8,8 +8,9 @@ import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
internal class ComplexFieldTest { internal class ComplexFieldTest {
@Test // TODO make verifier classes available in this source set
fun verify() = ComplexField { FieldVerifier(this, 42.0 * i, 66.0 + 28 * i, 2.0 + 0 * i, 5).verify() } // @Test
// fun verify() = ComplexField { FieldVerifier(this, 42.0 * i, 66.0 + 28 * i, 2.0 + 0 * i, 5).verify() }
@Test @Test
fun testAddition() { fun testAddition() {
@ -37,8 +38,6 @@ internal class ComplexFieldTest {
assertEquals(Complex(42, 42), ComplexField { Complex(0, 168) / Complex(2, 2) }) assertEquals(Complex(42, 42), ComplexField { Complex(0, 168) / Complex(2, 2) })
assertEquals(Complex(42, 56), ComplexField { Complex(86, 56) - 44 }) assertEquals(Complex(42, 56), ComplexField { Complex(86, 56) - 44 })
assertEquals(Complex(42, 56), ComplexField { 86 - Complex(44, -56) }) assertEquals(Complex(42, 56), ComplexField { 86 - Complex(44, -56) })
assertEquals(Complex(Double.NaN, Double.NaN), ComplexField { Complex(1, 1) / Complex(Double.NaN, Double.NaN) })
assertEquals(Complex(Double.NaN, Double.NaN), ComplexField { Complex(1, 1) / Complex(0, 0) })
} }
@Test @Test

@ -0,0 +1,31 @@
package kscience.kmath.complex
import kscience.kmath.operations.invoke
import kotlin.math.sqrt
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
internal class ComplexTest {
@Test
fun conjugate() = ComplexField { assertEquals(Complex(0, 42), Complex(0, -42).conjugate) }
@Test
fun reciprocal() = ComplexField { assertTrue((Complex(0.5, -0.0) - 2.toComplex().reciprocal).r < 1e-10) }
@Test
fun r() = ComplexField { assertEquals(sqrt(2.0), (i + 1.0.toComplex()).r) }
@Test
fun theta() = assertEquals(0.0, 1.toComplex().theta)
@Test
fun toComplex() {
assertEquals(Complex(42), 42.toComplex())
assertEquals(Complex(42.0), 42.0.toComplex())
assertEquals(Complex(42f), 42f.toComplex())
assertEquals(Complex(42.0), 42.0.toComplex())
assertEquals(Complex(42.toByte()), 42.toByte().toComplex())
assertEquals(Complex(42.toShort()), 42.toShort().toComplex())
}
}

@ -0,0 +1,26 @@
package kscience.kmath.complex
import kscience.kmath.expressions.FunctionalExpressionField
import kscience.kmath.expressions.bind
import kscience.kmath.expressions.invoke
import kscience.kmath.expressions.symbol
import kscience.kmath.operations.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
internal class ExpressionFieldForComplexTest {
val x by symbol
@Test
fun testComplex() {
val context = FunctionalExpressionField(ComplexField)
val expression = context {
val x = bind(x)
x * x + 2 * x + one
}
assertEquals(expression(x to Complex(1.0, 0.0)), Complex(4.0, 0.0))
//assertEquals(expression(), Complex(9.0, 0.0))
}
}

@ -0,0 +1,45 @@
package kscience.kmath.complex
import kscience.kmath.operations.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
internal class QuaternionFieldTest {
@Test
fun testAddition() {
assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(16, 16) + Quaternion(26, 26) })
assertEquals(Quaternion(42, 16), QuaternionField { Quaternion(16, 16) + 26 })
assertEquals(Quaternion(42, 16), QuaternionField { 26 + Quaternion(16, 16) })
}
// @Test
// fun testSubtraction() {
// assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(86, 55) - Quaternion(44, 13) })
// assertEquals(Quaternion(42, 56), QuaternionField { Quaternion(86, 56) - 44 })
// assertEquals(Quaternion(42, 56), QuaternionField { 86 - Quaternion(44, -56) })
// }
@Test
fun testMultiplication() {
assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(4.2, 0) * Quaternion(10, 10) })
assertEquals(Quaternion(42, 21), QuaternionField { Quaternion(4.2, 2.1) * 10 })
assertEquals(Quaternion(42, 21), QuaternionField { 10 * Quaternion(4.2, 2.1) })
}
// @Test
// fun testDivision() {
// assertEquals(Quaternion(42, 42), QuaternionField { Quaternion(0, 168) / Quaternion(2, 2) })
// assertEquals(Quaternion(42, 56), QuaternionField { Quaternion(86, 56) - 44 })
// assertEquals(Quaternion(42, 56) , QuaternionField { 86 - Quaternion(44, -56) })
// }
@Test
fun testPower() {
assertEquals(QuaternionField.zero, QuaternionField { zero pow 2 })
assertEquals(QuaternionField.zero, QuaternionField { zero pow 2 })
assertEquals(
QuaternionField { i * 8 }.let { it.x.toInt() to it.w.toInt() },
QuaternionField { Quaternion(2, 2) pow 2 }.let { it.x.toInt() to it.w.toInt() })
}
}

@ -1038,71 +1038,6 @@ public class kscience/kmath/nd/BufferedNDSpace : kscience/kmath/nd/BufferNDAlgeb
public fun unaryPlus (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDStructure; public fun unaryPlus (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDStructure;
} }
public final class kscience/kmath/nd/ComplexNDField : kscience/kmath/nd/BufferedNDField, kscience/kmath/operations/ExtendedField, kscience/kmath/operations/RingWithNumbers {
public fun <init> ([I)V
public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object;
public fun acos (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object;
public fun acosh (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object;
public fun asin (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object;
public fun asinh (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object;
public fun atan (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object;
public fun atanh (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object;
public fun cos (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object;
public fun cosh (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object;
public fun exp (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun getOne ()Ljava/lang/Object;
public fun getOne ()Lkscience/kmath/nd/NDBuffer;
public synthetic fun getZero ()Ljava/lang/Object;
public fun getZero ()Lkscience/kmath/nd/NDBuffer;
public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDStructure;
public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object;
public fun ln (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun minus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public fun minus (Ljava/lang/Number;Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDStructure;
public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public fun minus (Lkscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lkscience/kmath/nd/NDStructure;
public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object;
public fun number (Ljava/lang/Number;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun plus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public fun plus (Ljava/lang/Number;Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDStructure;
public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public fun plus (Lkscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lkscience/kmath/nd/NDStructure;
public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public fun pow (Lkscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lkscience/kmath/nd/NDStructure;
public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public fun power (Lkscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public fun rightSideNumberOperation (Ljava/lang/String;Lkscience/kmath/nd/NDStructure;Ljava/lang/Number;)Lkscience/kmath/nd/NDStructure;
public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object;
public fun sin (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
public fun sinh (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object;
public fun sqrt (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDStructure;
public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object;
public fun tan (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object;
public fun tanh (Lkscience/kmath/nd/NDStructure;)Lkscience/kmath/nd/NDBuffer;
public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
}
public final class kscience/kmath/nd/ComplexNDFieldKt {
public static final fun complex (Lkscience/kmath/nd/NDAlgebra$Companion;[I)Lkscience/kmath/nd/ComplexNDField;
public static final fun nd (Lkscience/kmath/operations/ComplexField;[ILkotlin/jvm/functions/Function1;)Ljava/lang/Object;
public static final fun produceInline (Lkscience/kmath/nd/BufferedNDField;Lkotlin/jvm/functions/Function2;)Lkscience/kmath/nd/NDBuffer;
}
public final class kscience/kmath/nd/DefaultStrides : kscience/kmath/nd/Strides { public final class kscience/kmath/nd/DefaultStrides : kscience/kmath/nd/Strides {
public static final field Companion Lkscience/kmath/nd/DefaultStrides$Companion; public static final field Companion Lkscience/kmath/nd/DefaultStrides$Companion;
public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V
@ -1682,145 +1617,6 @@ public final class kscience/kmath/operations/ByteRing : kscience/kmath/operation
public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object; public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object;
} }
public final class kscience/kmath/operations/Complex : java/lang/Comparable, kscience/kmath/operations/FieldElement {
public static final field Companion Lkscience/kmath/operations/Complex$Companion;
public fun <init> (DD)V
public fun <init> (Ljava/lang/Number;Ljava/lang/Number;)V
public synthetic fun compareTo (Ljava/lang/Object;)I
public fun compareTo (Lkscience/kmath/operations/Complex;)I
public final fun component1 ()D
public final fun component2 ()D
public final fun copy (DD)Lkscience/kmath/operations/Complex;
public static synthetic fun copy$default (Lkscience/kmath/operations/Complex;DDILjava/lang/Object;)Lkscience/kmath/operations/Complex;
public fun equals (Ljava/lang/Object;)Z
public synthetic fun getContext ()Lkscience/kmath/operations/Algebra;
public fun getContext ()Lkscience/kmath/operations/ComplexField;
public final fun getIm ()D
public final fun getRe ()D
public fun hashCode ()I
public fun toString ()Ljava/lang/String;
}
public final class kscience/kmath/operations/Complex$Companion : kscience/kmath/memory/MemorySpec {
public fun getObjectSize ()I
public synthetic fun read (Lkscience/kmath/memory/MemoryReader;I)Ljava/lang/Object;
public fun read (Lkscience/kmath/memory/MemoryReader;I)Lkscience/kmath/operations/Complex;
public synthetic fun write (Lkscience/kmath/memory/MemoryWriter;ILjava/lang/Object;)V
public fun write (Lkscience/kmath/memory/MemoryWriter;ILkscience/kmath/operations/Complex;)V
}
public final class kscience/kmath/operations/ComplexField : kscience/kmath/operations/ExtendedField, kscience/kmath/operations/Norm, kscience/kmath/operations/RingWithNumbers {
public static final field INSTANCE Lkscience/kmath/operations/ComplexField;
public synthetic fun acos (Ljava/lang/Object;)Ljava/lang/Object;
public fun acos (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun acosh (Ljava/lang/Object;)Ljava/lang/Object;
public fun acosh (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun add (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public fun add (Lkscience/kmath/operations/Complex;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun asin (Ljava/lang/Object;)Ljava/lang/Object;
public fun asin (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun asinh (Ljava/lang/Object;)Ljava/lang/Object;
public fun asinh (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun atan (Ljava/lang/Object;)Ljava/lang/Object;
public fun atan (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun atanh (Ljava/lang/Object;)Ljava/lang/Object;
public fun atanh (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun binaryOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public fun binaryOperation (Ljava/lang/String;Lkscience/kmath/operations/Complex;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public fun binaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public synthetic fun cos (Ljava/lang/Object;)Ljava/lang/Object;
public fun cos (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun cosh (Ljava/lang/Object;)Ljava/lang/Object;
public fun cosh (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun div (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public fun div (Ljava/lang/Number;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public synthetic fun div (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public fun div (Lkscience/kmath/operations/Complex;Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public fun div (Lkscience/kmath/operations/Complex;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun divide (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public fun divide (Lkscience/kmath/operations/Complex;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun exp (Ljava/lang/Object;)Ljava/lang/Object;
public fun exp (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public final fun getI ()Lkscience/kmath/operations/Complex;
public synthetic fun getOne ()Ljava/lang/Object;
public fun getOne ()Lkscience/kmath/operations/Complex;
public synthetic fun getZero ()Ljava/lang/Object;
public fun getZero ()Lkscience/kmath/operations/Complex;
public synthetic fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public fun leftSideNumberOperation (Ljava/lang/String;Ljava/lang/Number;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public fun leftSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public synthetic fun ln (Ljava/lang/Object;)Ljava/lang/Object;
public fun ln (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public final fun minus (DLkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun minus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public fun minus (Ljava/lang/Number;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public synthetic fun minus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public final fun minus (Lkscience/kmath/operations/Complex;D)Lkscience/kmath/operations/Complex;
public fun minus (Lkscience/kmath/operations/Complex;Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public fun minus (Lkscience/kmath/operations/Complex;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public synthetic fun multiply (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public fun multiply (Lkscience/kmath/operations/Complex;Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public fun multiply (Lkscience/kmath/operations/Complex;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun norm (Ljava/lang/Object;)Ljava/lang/Object;
public fun norm (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun number (Ljava/lang/Number;)Ljava/lang/Object;
public fun number (Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public final fun plus (DLkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun plus (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public fun plus (Ljava/lang/Number;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public synthetic fun plus (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public final fun plus (Lkscience/kmath/operations/Complex;D)Lkscience/kmath/operations/Complex;
public fun plus (Lkscience/kmath/operations/Complex;Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public fun plus (Lkscience/kmath/operations/Complex;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun pow (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public fun pow (Lkscience/kmath/operations/Complex;Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public synthetic fun power (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public fun power (Lkscience/kmath/operations/Complex;Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public synthetic fun rightSideNumberOperation (Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public fun rightSideNumberOperation (Ljava/lang/String;Lkscience/kmath/operations/Complex;Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public fun rightSideNumberOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function2;
public synthetic fun sin (Ljava/lang/Object;)Ljava/lang/Object;
public fun sin (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun sinh (Ljava/lang/Object;)Ljava/lang/Object;
public fun sinh (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun sqrt (Ljava/lang/Object;)Ljava/lang/Object;
public fun sqrt (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun symbol (Ljava/lang/String;)Ljava/lang/Object;
public fun symbol (Ljava/lang/String;)Lkscience/kmath/operations/Complex;
public synthetic fun tan (Ljava/lang/Object;)Ljava/lang/Object;
public fun tan (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun tanh (Ljava/lang/Object;)Ljava/lang/Object;
public fun tanh (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public final fun times (DLkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun times (Ljava/lang/Number;Ljava/lang/Object;)Ljava/lang/Object;
public fun times (Ljava/lang/Number;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun times (Ljava/lang/Object;Ljava/lang/Number;)Ljava/lang/Object;
public synthetic fun times (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
public fun times (Lkscience/kmath/operations/Complex;Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
public fun times (Lkscience/kmath/operations/Complex;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun unaryMinus (Ljava/lang/Object;)Ljava/lang/Object;
public fun unaryMinus (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public synthetic fun unaryOperation (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object;
public fun unaryOperation (Ljava/lang/String;Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public fun unaryOperationFunction (Ljava/lang/String;)Lkotlin/jvm/functions/Function1;
public synthetic fun unaryPlus (Ljava/lang/Object;)Ljava/lang/Object;
public fun unaryPlus (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
}
public final class kscience/kmath/operations/ComplexKt {
public static final fun complex (Lkscience/kmath/structures/Buffer$Companion;ILkotlin/jvm/functions/Function1;)Lkscience/kmath/structures/Buffer;
public static final fun complex (Lkscience/kmath/structures/MutableBuffer$Companion;ILkotlin/jvm/functions/Function1;)Lkscience/kmath/structures/MutableBuffer;
public static final fun getConjugate (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public static final fun getR (Lkscience/kmath/operations/Complex;)D
public static final fun getReciprocal (Lkscience/kmath/operations/Complex;)Lkscience/kmath/operations/Complex;
public static final fun getTheta (Lkscience/kmath/operations/Complex;)D
public static final fun toComplex (Ljava/lang/Number;)Lkscience/kmath/operations/Complex;
}
public abstract interface class kscience/kmath/operations/ExponentialOperations : kscience/kmath/operations/Algebra { public abstract interface class kscience/kmath/operations/ExponentialOperations : kscience/kmath/operations/Algebra {
public static final field Companion Lkscience/kmath/operations/ExponentialOperations$Companion; public static final field Companion Lkscience/kmath/operations/ExponentialOperations$Companion;
public static final field EXP_OPERATION Ljava/lang/String; public static final field EXP_OPERATION Ljava/lang/String;

@ -1,17 +1,21 @@
import ru.mipt.npm.gradle.Maturity
plugins { plugins {
id("ru.mipt.npm.mpp") id("ru.mipt.npm.mpp")
id("ru.mipt.npm.native") id("ru.mipt.npm.native")
} }
kotlin.sourceSets.commonMain { kotlin.sourceSets {
dependencies { commonMain {
api(project(":kmath-memory")) dependencies {
api(project(":kmath-memory"))
}
} }
} }
readme { readme {
description = "Core classes, algebra definitions, basic linear algebra" description = "Core classes, algebra definitions, basic linear algebra"
maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT maturity = Maturity.DEVELOPMENT
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature( feature(

@ -83,6 +83,7 @@ public interface MatrixContext<T : Any, out M : Matrix<T>> : SpaceOperations<Mat
public fun <F : Any> getFeature(m: Matrix<T>, type: KClass<F>): F? = m.getFeature(type) public fun <F : Any> getFeature(m: Matrix<T>, type: KClass<F>): F? = m.getFeature(type)
public companion object { public companion object {
/** /**
* A structured matrix with custom buffer * A structured matrix with custom buffer
*/ */
@ -123,7 +124,7 @@ public inline fun <T : Any, reified F : Any> MatrixContext<T, *>.getFeature(m: M
*/ */
public interface GenericMatrixContext<T : Any, R : Ring<T>, out M : Matrix<T>> : MatrixContext<T, M> { public interface GenericMatrixContext<T : Any, R : Ring<T>, out M : Matrix<T>> : MatrixContext<T, M> {
/** /**
* The ring instance of [T]. * The ring over matrix elements.
*/ */
public val elementContext: R public val elementContext: R

@ -1,5 +1,10 @@
package kscience.kmath.linear package kscience.kmath.linear
/**
* The matrix where each element is evaluated each time when is being accessed.
*
* @property generator the function that provides elements.
*/
public class VirtualMatrix<T : Any>( public class VirtualMatrix<T : Any>(
override val rowNum: Int, override val rowNum: Int,
override val colNum: Int, override val colNum: Int,

@ -86,3 +86,10 @@ public fun <T> NDStructure<T>.as2D(): Structure2D<T> = if (shape.size == 2)
Structure2DWrapper(this) Structure2DWrapper(this)
else else
error("Can't create 2d-structure from ${shape.size}d-structure") error("Can't create 2d-structure from ${shape.size}d-structure")
/**
* Alias for [Structure2D] with more familiar name.
*
* @param T the type of items in the matrix.
*/
public typealias Matrix<T> = Structure2D<T>

@ -1,7 +1,5 @@
package kscience.kmath.structures package kscience.kmath.structures
import kscience.kmath.operations.Complex
import kscience.kmath.operations.complex
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**
@ -76,7 +74,6 @@ public interface Buffer<T> {
Int::class -> IntBuffer(size) { initializer(it) as Int } as Buffer<T> Int::class -> IntBuffer(size) { initializer(it) as Int } as Buffer<T>
Long::class -> LongBuffer(size) { initializer(it) as Long } as Buffer<T> Long::class -> LongBuffer(size) { initializer(it) as Long } as Buffer<T>
Float::class -> FloatBuffer(size) { initializer(it) as Float } as Buffer<T> Float::class -> FloatBuffer(size) { initializer(it) as Float } as Buffer<T>
Complex::class -> complex(size) { initializer(it) as Complex } as Buffer<T>
else -> boxing(size, initializer) else -> boxing(size, initializer)
} }
@ -149,7 +146,6 @@ public interface MutableBuffer<T> : Buffer<T> {
Int::class -> IntBuffer(size) { initializer(it) as Int } as MutableBuffer<T> Int::class -> IntBuffer(size) { initializer(it) as Int } as MutableBuffer<T>
Float::class -> FloatBuffer(size) { initializer(it) as Float } as MutableBuffer<T> Float::class -> FloatBuffer(size) { initializer(it) as Float } as MutableBuffer<T>
Long::class -> LongBuffer(size) { initializer(it) as Long } as MutableBuffer<T> Long::class -> LongBuffer(size) { initializer(it) as Long } as MutableBuffer<T>
Complex::class -> complex(size) { initializer(it) as Complex } as MutableBuffer<T>
else -> boxing(size, initializer) else -> boxing(size, initializer)
} }

@ -43,8 +43,8 @@ public class MutableMemoryBuffer<T : Any>(memory: Memory, spec: MemorySpec<T>) :
private val writer: MemoryWriter = memory.writer() private val writer: MemoryWriter = memory.writer()
override operator fun set(index: Int, value: T): Unit = writer.write(spec, spec.objectSize * index, value) public override operator fun set(index: Int, value: T): Unit = writer.write(spec, spec.objectSize * index, value)
override fun copy(): MutableBuffer<T> = MutableMemoryBuffer(memory.copy(), spec) public override fun copy(): MutableBuffer<T> = MutableMemoryBuffer(memory.copy(), spec)
public companion object { public companion object {
public fun <T : Any> create(spec: MemorySpec<T>, size: Int): MutableMemoryBuffer<T> = public fun <T : Any> create(spec: MemorySpec<T>, size: Int): MutableMemoryBuffer<T> =

@ -1,7 +1,5 @@
package kscience.kmath.expressions package kscience.kmath.expressions
import kscience.kmath.operations.Complex
import kscience.kmath.operations.ComplexField
import kscience.kmath.operations.RealField import kscience.kmath.operations.RealField
import kscience.kmath.operations.invoke import kscience.kmath.operations.invoke
import kotlin.test.Test import kotlin.test.Test
@ -10,6 +8,7 @@ import kotlin.test.assertFails
class ExpressionFieldTest { class ExpressionFieldTest {
val x by symbol val x by symbol
@Test @Test
fun testExpression() { fun testExpression() {
val context = FunctionalExpressionField(RealField) val context = FunctionalExpressionField(RealField)
@ -20,20 +19,7 @@ class ExpressionFieldTest {
} }
assertEquals(expression(x to 1.0), 4.0) assertEquals(expression(x to 1.0), 4.0)
assertFails { expression()} assertFails { expression() }
}
@Test
fun testComplex() {
val context = FunctionalExpressionField(ComplexField)
val expression = context {
val x = bind(x)
x * x + 2 * x + one
}
assertEquals(expression(x to Complex(1.0, 0.0)), Complex(4.0, 0.0))
//assertEquals(expression(), Complex(9.0, 0.0))
} }
@Test @Test

@ -1,6 +1,6 @@
package kscience.kmath.operations package kscience.kmath.operations
import kscience.kmath.operations.internal.RingVerifier import kscience.kmath.testutils.RingVerifier
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

@ -1,39 +0,0 @@
package kscience.kmath.operations
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertTrue
internal class ComplexTest {
@Test
fun conjugate() {
assertEquals(
Complex(0, -42), (ComplexField.i * 42).conjugate
)
}
@Test
fun reciprocal() {
assertTrue { (Complex(0.5, -0.0) - 2.toComplex().reciprocal).r < 1e-10}
}
@Test
fun r() {
assertEquals(kotlin.math.sqrt(2.0), (ComplexField.i + 1.0.toComplex()).r)
}
@Test
fun theta() {
assertEquals(0.0, 1.toComplex().theta)
}
@Test
fun toComplex() {
assertEquals(Complex(42, 0), 42.toComplex())
assertEquals(Complex(42.0, 0), 42.0.toComplex())
assertEquals(Complex(42f, 0), 42f.toComplex())
assertEquals(Complex(42.0, 0), 42.0.toComplex())
assertEquals(Complex(42.toByte(), 0), 42.toByte().toComplex())
assertEquals(Complex(42.toShort(), 0), 42.toShort().toComplex())
}
}

@ -1,6 +1,6 @@
package kscience.kmath.operations package kscience.kmath.operations
import kscience.kmath.operations.internal.FieldVerifier import kscience.kmath.testutils.FieldVerifier
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals

@ -3,14 +3,15 @@ package kscience.kmath.structures
import kscience.kmath.nd.NDAlgebra import kscience.kmath.nd.NDAlgebra
import kscience.kmath.nd.get import kscience.kmath.nd.get
import kscience.kmath.nd.real import kscience.kmath.nd.real
import kscience.kmath.operations.internal.FieldVerifier import kscience.kmath.testutils.FieldVerifier
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kscience.kmath.operations.invoke
internal class NDFieldTest { internal class NDFieldTest {
@Test @Test
fun verify() { fun verify() {
NDAlgebra.real(12, 32).run { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) } (NDAlgebra.real(12, 32)) { FieldVerifier(this, one + 3, one - 23, one * 12, 6.66) }
} }
@Test @Test

@ -1,4 +1,4 @@
package kscience.kmath.operations.internal package kscience.kmath.testutils
import kscience.kmath.operations.Algebra import kscience.kmath.operations.Algebra

@ -1,4 +1,4 @@
package kscience.kmath.operations.internal package kscience.kmath.testutils
import kscience.kmath.operations.Field import kscience.kmath.operations.Field
import kscience.kmath.operations.invoke import kscience.kmath.operations.invoke

@ -1,4 +1,4 @@
package kscience.kmath.operations.internal package kscience.kmath.testutils
import kscience.kmath.operations.Ring import kscience.kmath.operations.Ring
import kscience.kmath.operations.invoke import kscience.kmath.operations.invoke

@ -1,4 +1,4 @@
package kscience.kmath.operations.internal package kscience.kmath.testutils
import kscience.kmath.operations.Space import kscience.kmath.operations.Space
import kscience.kmath.operations.invoke import kscience.kmath.operations.invoke

@ -12,6 +12,7 @@ kotlin.sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api(project(":kmath-core")) api(project(":kmath-core"))
api(project(":kmath-complex"))
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}") api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}")
} }
} }

@ -2,6 +2,7 @@ package kaceince.kmath.real
import kscience.kmath.linear.Matrix import kscience.kmath.linear.Matrix
import kscience.kmath.linear.build import kscience.kmath.linear.build
import kscience.kmath.misc.UnstableKMathAPI
import kscience.kmath.real.* import kscience.kmath.real.*
import kscience.kmath.structures.contentEquals import kscience.kmath.structures.contentEquals
import kotlin.test.Test import kotlin.test.Test
@ -91,6 +92,7 @@ internal class RealMatrixTest {
assertEquals(matrix1.pow(3), matrix3) assertEquals(matrix1.pow(3), matrix3)
} }
@OptIn(UnstableKMathAPI::class)
@Test @Test
fun testTwoMatrixOperations() { fun testTwoMatrixOperations() {
val matrix1 = Matrix.build(2, 3)( val matrix1 = Matrix.build(2, 3)(

@ -4,7 +4,7 @@ plugins {
kotlin.sourceSets { kotlin.sourceSets {
all { all {
with(languageSettings) { languageSettings.apply {
useExperimentalAnnotation("kotlinx.coroutines.FlowPreview") useExperimentalAnnotation("kotlinx.coroutines.FlowPreview")
useExperimentalAnnotation("kotlinx.coroutines.ExperimentalCoroutinesApi") useExperimentalAnnotation("kotlinx.coroutines.ExperimentalCoroutinesApi")
useExperimentalAnnotation("kotlinx.coroutines.ObsoleteCoroutinesApi") useExperimentalAnnotation("kotlinx.coroutines.ObsoleteCoroutinesApi")

@ -26,9 +26,10 @@ rootProject.name = "kmath"
include( include(
":kmath-memory", ":kmath-memory",
":kmath-complex",
":kmath-core", ":kmath-core",
":kmath-functions",
":kmath-coroutines", ":kmath-coroutines",
":kmath-functions",
":kmath-histograms", ":kmath-histograms",
":kmath-commons", ":kmath-commons",
":kmath-viktor", ":kmath-viktor",