Dev #280

Merged
altavir merged 99 commits from dev into master 2021-04-16 19:45:55 +03:00
57 changed files with 633 additions and 387 deletions
Showing only changes of commit d69a04bb6e - Show all commits

View File

@ -18,6 +18,7 @@
- Some minor utilities to `kmath-for-real`
- Generic operation result parameter to `MatrixContext`
- New `MatrixFeature` interfaces for matrix decompositions
- Basic Quaternion vector support in `kmath-complex`.
### Changed
- Package changed from `scientifik` to `kscience.kmath`
@ -38,6 +39,7 @@
- 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
- Refactor histograms. They are marked as prototype
- `Complex` and related features moved to a separate module `kmath-complex`
- Refactor AlgebraElement
### Deprecated

View File

@ -104,6 +104,17 @@ KMath is a modular library. Different modules provide different features with di
> **Maturity**: EXPERIMENTAL
<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)
> Core classes, algebra definitions, basic linear algebra
>
@ -246,8 +257,8 @@ repositories {
}
dependencies {
api("kscience.kmath:kmath-core:0.2.0-dev-6")
// api("kscience.kmath:kmath-core-jvm:0.2.0-dev-6") for jvm-specific version
api("kscience.kmath:kmath-core:0.2.0-dev-7")
// api("kscience.kmath:kmath-core-jvm:0.2.0-dev-7") for jvm-specific version
}
```

View File

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

View File

@ -1,7 +1,7 @@
package kscience.kmath.benchmarks
import kscience.kmath.operations.Complex
import kscience.kmath.operations.complex
import kscience.kmath.complex.Complex
import kscience.kmath.complex.complex
import kscience.kmath.structures.MutableBuffer
import kscience.kmath.structures.RealBuffer
import org.openjdk.jmh.annotations.Benchmark

View File

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

View File

@ -1,6 +1,8 @@
package kscience.kmath.ast
package kscience.kmath.benchmarks
import kscience.kmath.asm.compile
import kscience.kmath.ast.MstField
import kscience.kmath.ast.mstInField
import kscience.kmath.expressions.Expression
import kscience.kmath.expressions.expressionInField
import kscience.kmath.expressions.invoke
@ -37,7 +39,7 @@ internal class ExpressionsInterpretersBenchmark {
@Benchmark
fun asmExpression() {
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()
invokeAndSum(expr)

View File

@ -1,5 +1,4 @@
package kscience.kmath.linear
package kscience.kmath.benchmarks
import kotlinx.benchmark.Benchmark
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.ejml.EjmlMatrixContext
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.structures.Matrix
import org.openjdk.jmh.annotations.Scope
import org.openjdk.jmh.annotations.State
import kotlin.random.Random
@State(Scope.Benchmark)
class LinearAlgebraBenchmark {
internal class LinearAlgebraBenchmark {
companion object {
val random = Random(1224)
val dim = 100

View File

@ -1,7 +1,8 @@
package kscience.kmath.operations
import kscience.kmath.complex.Complex
import kscience.kmath.complex.complex
import kscience.kmath.nd.NDAlgebra
import kscience.kmath.nd.complex
fun main() {
// 2d element
@ -18,5 +19,6 @@ fun main() {
(a pow b) + c
}
println(result)
}

View File

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

View File

@ -1,9 +1,8 @@
kotlin.code.style=official
kotlin.parallel.tasks.in.project=true
kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false
kotlin.mpp.stability.nowarn=true
kotlin.native.enableDependencyPropagation=false
kotlin.parallel.tasks.in.project=true
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
org.gradle.parallel=true
systemProp.org.gradle.internal.publish.checksums.insecure=true

View File

@ -12,7 +12,7 @@ This subproject implements the following features:
> #### Artifact:
>
> This module artifact: `kscience.kmath:kmath-ast:0.2.0-dev-6`.
> This module artifact: `kscience.kmath:kmath-ast:0.2.0-dev-7`.
>
> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-ast/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-ast/_latestVersion)
>
@ -30,7 +30,7 @@ This subproject implements the following features:
> }
>
> dependencies {
> implementation 'kscience.kmath:kmath-ast:0.2.0-dev-6'
> implementation 'kscience.kmath:kmath-ast:0.2.0-dev-7'
> }
> ```
> **Gradle Kotlin DSL:**
@ -44,7 +44,7 @@ This subproject implements the following features:
> }
>
> dependencies {
> implementation("kscience.kmath:kmath-ast:0.2.0-dev-6")
> implementation("kscience.kmath:kmath-ast:0.2.0-dev-7")
> }
> ```
@ -61,7 +61,7 @@ For example, the following builder:
RealField.mstInField { symbol("x") + 2 }.compile()
```
… leads to generation of bytecode, which can be decompiled to the following Java class:
leads to generation of bytecode, which can be decompiled to the following Java class:
```java
package kscience.kmath.asm.generated;
@ -75,7 +75,7 @@ import kscience.kmath.expressions.Symbol;
public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
private final Object[] constants;
public final Double invoke(Map<Symbol, Double> arguments) {
public final Double invoke(Map<Symbol, ? extends Double> arguments) {
return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2);
}

View File

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

View File

@ -33,7 +33,7 @@ import kscience.kmath.expressions.Symbol;
public final class AsmCompiledExpression_45045_0 implements Expression<Double> {
private final Object[] constants;
public final Double invoke(Map<Symbol, Double> arguments) {
public final Double invoke(Map<Symbol, ? extends Double> arguments) {
return (Double)((Function2)this.constants[0]).invoke((Double)MapIntrinsics.getOrFail(arguments, "x"), 2);
}

View File

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

View File

@ -83,7 +83,7 @@ internal class AsmBuilder<T>(
ACC_PUBLIC or ACC_FINAL,
"invoke",
getMethodDescriptor(tType, MAP_TYPE),
"(L${MAP_TYPE.internalName}<${SYMBOL_TYPE.descriptor}${if (Modifier.isFinal(classOfT.modifiers)) "" else "+"}${tType.descriptor}>;)${tType.descriptor}",
"(L${MAP_TYPE.internalName}<${SYMBOL_TYPE.descriptor}+${tType.descriptor}>;)${tType.descriptor}",
null,
).instructionAdapter {
invokeMethodVisitor = this

View File

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

View File

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

View File

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

View File

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

45
kmath-complex/README.md Normal file
View 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-7`.
>
> 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-7'
> }
> ```
> **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-7")
> }
> ```

View File

@ -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"
)
}

View File

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

View File

@ -1,9 +1,12 @@
package kscience.kmath.operations
package kscience.kmath.complex
import kscience.kmath.memory.MemoryReader
import kscience.kmath.memory.MemorySpec
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.MemoryBuffer
import kscience.kmath.structures.MutableBuffer
@ -42,74 +45,70 @@ private val PI_DIV_2 = Complex(PI / 2, 0)
/**
* A field of [Complex].
*/
@OptIn(UnstableKMathAPI::class)
public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex>, RingWithNumbers<Complex> {
override val zero: Complex = 0.0.toComplex()
override val one: Complex = 1.0.toComplex()
public override val zero: Complex = 0.0.toComplex()
public override val one: Complex = 1.0.toComplex()
/**
* 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())
override fun multiply(a: Complex, b: Complex): Complex =
public 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)
override fun divide(a: Complex, b: Complex): Complex = when {
b.re.isNaN() || b.im.isNaN() -> Complex(Double.NaN, Double.NaN)
(if (b.im < 0) -b.im else +b.im) < (if (b.re < 0) -b.re else +b.re) -> {
public override fun divide(a: Complex, b: Complex): Complex = when {
abs(b.im) < abs(b.re) -> {
val wr = b.im / b.re
val wd = b.re + wr * b.im
if (wd.isNaN() || wd == 0.0)
Complex(Double.NaN, Double.NaN)
throw ArithmeticException("Division by zero or infinity")
else
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 -> {
val wr = b.re / b.im
val wd = b.im + wr * b.re
if (wd.isNaN() || wd == 0.0)
Complex(Double.NaN, Double.NaN)
throw ArithmeticException("Division by zero or infinity")
else
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
override fun cos(arg: Complex): Complex = (exp(-i * arg) + exp(i * arg)) / 2
public override fun sin(arg: Complex): Complex = i * (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 e2 = exp(i * arg)
return i * (e1 - e2) / (e1 + e2)
}
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 asin(arg: Complex): Complex = -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
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()
else
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.
@ -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)
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 im The imaginary part.
*/
@OptIn(UnstableKMathAPI::class)
public data class Complex(
val re: Double,
val im: Double,
) : FieldElement<Complex, ComplexField>, Comparable<Complex> {
public data class Complex(val re: Double, val im: Double) : FieldElement<Complex, ComplexField> {
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
override fun compareTo(other: Complex): Int = r.compareTo(other.r)
override fun toString(): String {
return "($re + i*$im)"
}
public override val context: ComplexField get() = ComplexField
public override fun toString(): String = "($re + i*$im)"
public companion object : MemorySpec<Complex> {
override val objectSize: Int
public override val objectSize: Int
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 + 8, value.im)
}
@ -203,7 +194,7 @@ public data class Complex(
* @receiver the real part.
* @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

View File

@ -1,6 +1,10 @@
package kscience.kmath.nd
package kscience.kmath.complex
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.structures.Buffer
import kotlin.contracts.InvocationKind

View File

@ -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)

View File

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

View File

@ -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.abs
import kotlin.test.Test
@ -8,8 +8,9 @@ import kotlin.test.assertEquals
import kotlin.test.assertTrue
internal class ComplexFieldTest {
@Test
fun verify() = ComplexField { FieldVerifier(this, 42.0 * i, 66.0 + 28 * i, 2.0 + 0 * i, 5).verify() }
// TODO make verifier classes available in this source set
// @Test
// fun verify() = ComplexField { FieldVerifier(this, 42.0 * i, 66.0 + 28 * i, 2.0 + 0 * i, 5).verify() }
@Test
fun testAddition() {
@ -37,8 +38,6 @@ internal class ComplexFieldTest {
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 { 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

View File

@ -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())
}
}

View File

@ -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))
}
}

View File

@ -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() })
}
}

View File

@ -15,7 +15,7 @@ performance calculations to code generation.
> #### Artifact:
>
> This module artifact: `kscience.kmath:kmath-core:0.2.0-dev-6`.
> This module artifact: `kscience.kmath:kmath-core:0.2.0-dev-7`.
>
> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-core/_latestVersion)
>
@ -33,7 +33,7 @@ performance calculations to code generation.
> }
>
> dependencies {
> implementation 'kscience.kmath:kmath-core:0.2.0-dev-6'
> implementation 'kscience.kmath:kmath-core:0.2.0-dev-7'
> }
> ```
> **Gradle Kotlin DSL:**
@ -47,6 +47,6 @@ performance calculations to code generation.
> }
>
> dependencies {
> implementation("kscience.kmath:kmath-core:0.2.0-dev-6")
> implementation("kscience.kmath:kmath-core:0.2.0-dev-7")
> }
> ```

View File

@ -1033,71 +1033,6 @@ public class kscience/kmath/nd/BufferedNDSpace : kscience/kmath/nd/BufferNDAlgeb
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 static final field Companion Lkscience/kmath/nd/DefaultStrides$Companion;
public synthetic fun <init> ([ILkotlin/jvm/internal/DefaultConstructorMarker;)V
@ -1677,145 +1612,6 @@ public final class kscience/kmath/operations/ByteRing : kscience/kmath/operation
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 static final field Companion Lkscience/kmath/operations/ExponentialOperations$Companion;
public static final field EXP_OPERATION Ljava/lang/String;

View File

@ -1,17 +1,21 @@
import ru.mipt.npm.gradle.Maturity
plugins {
id("ru.mipt.npm.mpp")
id("ru.mipt.npm.native")
}
kotlin.sourceSets.commonMain {
kotlin.sourceSets {
commonMain {
dependencies {
api(project(":kmath-memory"))
}
}
}
readme {
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"))
feature(

View File

@ -9,7 +9,10 @@ import kscience.kmath.structures.BufferFactory
import kscience.kmath.structures.asSequence
/**
* Basic operations on matrices. Operates on [Matrix]
* Basic operations on matrices. Operates on [Matrix].
*
* @param T the type of items in the matrices.
* @param M the type of operated matrices.
*/
public interface MatrixContext<T : Any, out M : Matrix<T>> : SpaceOperations<Matrix<T>> {
/**
@ -83,9 +86,16 @@ public interface MatrixContext<T : Any, out M : Matrix<T>> : SpaceOperations<Mat
}
}
/**
* Partial implementation of [MatrixContext] for matrices of [Ring].
*
* @param T the type of items in the matrices.
* @param R the type of ring of matrix elements.
* @param M the type of operated matrices.
*/
public interface GenericMatrixContext<T : Any, R : Ring<T>, out M : Matrix<T>> : MatrixContext<T, M> {
/**
* The ring context for matrix elements
* The ring over matrix elements.
*/
public val elementContext: R

View File

@ -1,5 +1,10 @@
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>(
override val rowNum: Int,
override val colNum: Int,

View File

@ -86,3 +86,10 @@ public fun <T> NDStructure<T>.as2D(): Structure2D<T> = if (shape.size == 2)
Structure2DWrapper(this)
else
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>

View File

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

View File

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

View File

@ -1,7 +1,5 @@
package kscience.kmath.expressions
import kscience.kmath.operations.Complex
import kscience.kmath.operations.ComplexField
import kscience.kmath.operations.RealField
import kscience.kmath.operations.invoke
import kotlin.test.Test
@ -10,6 +8,7 @@ import kotlin.test.assertFails
class ExpressionFieldTest {
val x by symbol
@Test
fun testExpression() {
val context = FunctionalExpressionField(RealField)
@ -23,19 +22,6 @@ class ExpressionFieldTest {
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
fun separateContext() {
fun <T> FunctionalExpressionField<T, *>.expression(): Expression<T> {

View File

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

View File

@ -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())
}
}

View File

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

View File

@ -3,14 +3,15 @@ package kscience.kmath.structures
import kscience.kmath.nd.NDAlgebra
import kscience.kmath.nd.get
import kscience.kmath.nd.real
import kscience.kmath.operations.internal.FieldVerifier
import kscience.kmath.testutils.FieldVerifier
import kotlin.test.Test
import kotlin.test.assertEquals
import kscience.kmath.operations.invoke
internal class NDFieldTest {
@Test
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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -7,7 +7,7 @@
> #### Artifact:
>
> This module artifact: `kscience.kmath:kmath-for-real:0.2.0-dev-6`.
> This module artifact: `kscience.kmath:kmath-for-real:0.2.0-dev-7`.
>
> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-for-real/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-for-real/_latestVersion)
>
@ -25,7 +25,7 @@
> }
>
> dependencies {
> implementation 'kscience.kmath:kmath-for-real:0.2.0-dev-6'
> implementation 'kscience.kmath:kmath-for-real:0.2.0-dev-7'
> }
> ```
> **Gradle Kotlin DSL:**
@ -39,6 +39,6 @@
> }
>
> dependencies {
> implementation("kscience.kmath:kmath-for-real:0.2.0-dev-6")
> implementation("kscience.kmath:kmath-for-real:0.2.0-dev-7")
> }
> ```

View File

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

View File

@ -10,7 +10,7 @@ Functions and interpolations:
> #### Artifact:
>
> This module artifact: `kscience.kmath:kmath-functions:0.2.0-dev-6`.
> This module artifact: `kscience.kmath:kmath-functions:0.2.0-dev-7`.
>
> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-functions/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-functions/_latestVersion)
>
@ -28,7 +28,7 @@ Functions and interpolations:
> }
>
> dependencies {
> implementation 'kscience.kmath:kmath-functions:0.2.0-dev-6'
> implementation 'kscience.kmath:kmath-functions:0.2.0-dev-7'
> }
> ```
> **Gradle Kotlin DSL:**
@ -42,6 +42,6 @@ Functions and interpolations:
> }
>
> dependencies {
> implementation("kscience.kmath:kmath-functions:0.2.0-dev-6")
> implementation("kscience.kmath:kmath-functions:0.2.0-dev-7")
> }
> ```

View File

@ -9,7 +9,7 @@ This subproject implements the following features:
> #### Artifact:
>
> This module artifact: `kscience.kmath:kmath-nd4j:0.2.0-dev-6`.
> This module artifact: `kscience.kmath:kmath-nd4j:0.2.0-dev-7`.
>
> Bintray release version: [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-nd4j/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-nd4j/_latestVersion)
>
@ -27,7 +27,7 @@ This subproject implements the following features:
> }
>
> dependencies {
> implementation 'kscience.kmath:kmath-nd4j:0.2.0-dev-6'
> implementation 'kscience.kmath:kmath-nd4j:0.2.0-dev-7'
> }
> ```
> **Gradle Kotlin DSL:**
@ -41,7 +41,7 @@ This subproject implements the following features:
> }
>
> dependencies {
> implementation("kscience.kmath:kmath-nd4j:0.2.0-dev-6")
> implementation("kscience.kmath:kmath-nd4j:0.2.0-dev-7")
> }
> ```

View File

@ -3,6 +3,13 @@ plugins {
}
kotlin.sourceSets {
all {
languageSettings.apply {
useExperimentalAnnotation("kotlinx.coroutines.FlowPreview")
useExperimentalAnnotation("kotlinx.coroutines.ExperimentalCoroutinesApi")
}
}
commonMain {
dependencies {
api(project(":kmath-coroutines"))

View File

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