Add fast quaternion implementation, minor changes to complex #156

Merged
CommanderTvis merged 40 commits from feature/quaternion into dev 2021-02-11 11:01:30 +03:00
41 changed files with 570 additions and 350 deletions

View File

@ -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`.
### Changed ### Changed
- Package changed from `scientifik` to `kscience.kmath` - Package changed from `scientifik` to `kscience.kmath`
@ -38,6 +39,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

View File

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

View File

@ -30,6 +30,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"))

View File

@ -1,7 +1,8 @@
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
package kscience.kmath.operations package kscience.kmath.operations
import kscience.kmath.complex.Complex
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
import kscience.kmath.complex.complex
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
import kscience.kmath.nd.NDAlgebra import kscience.kmath.nd.NDAlgebra
import kscience.kmath.nd.complex
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
fun main() { fun main() {
// 2d element // 2d element
@ -18,5 +19,6 @@ fun main() {
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
(a pow b) + c (a pow b) + c
} }
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
println(result) println(result)
} }

altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please
altavir commented 2021-02-08 19:09:11 +03:00 (Migrated from github.com)
Review

Revert to more readable with please

Revert to more readable `with` please

View File

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

View File

@ -1,9 +1,8 @@
kotlin.code.style=official kotlin.code.style=official
kotlin.parallel.tasks.in.project=true
kotlin.mpp.enableGranularSourceSetsMetadata=true kotlin.mpp.enableGranularSourceSetsMetadata=true
kotlin.native.enableDependencyPropagation=false
kotlin.mpp.stability.nowarn=true kotlin.mpp.stability.nowarn=true
kotlin.native.enableDependencyPropagation=false
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
systemProp.org.gradle.internal.publish.checksums.insecure=true systemProp.org.gradle.internal.publish.checksums.insecure=true

View File

@ -61,7 +61,7 @@ For example, the following builder:
RealField.mstInField { symbol("x") + 2 }.compile() 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 ```java
package kscience.kmath.asm.generated; package kscience.kmath.asm.generated;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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.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

View File

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

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.structures.Buffer
import kscience.kmath.operations.complex
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals 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.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

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

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

View File

@ -1,17 +1,21 @@
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
import ru.mipt.npm.gradle.Maturity
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
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 {
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
commonMain {
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
dependencies { dependencies {
api(project(":kmath-memory")) api(project(":kmath-memory"))
} }
} }
}
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
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
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md")) propertyByTemplate("artifact", rootProject.file("docs/templates/ARTIFACT-TEMPLATE.md"))
feature( feature(

altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.
altavir commented 2021-02-08 19:52:45 +03:00 (Migrated from github.com)
Review

Move appropriate tests to kmath-complex and remove the dependency.

Move appropriate tests to kmath-complex and remove the dependency.

View File

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

View File

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

View File

@ -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)
@ -23,19 +22,6 @@ class ExpressionFieldTest {
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
fun separateContext() { fun separateContext() {
fun <T> FunctionalExpressionField<T, *>.expression(): Expression<T> { fun <T> FunctionalExpressionField<T, *>.expression(): Expression<T> {

View File

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

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

View File

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

View File

@ -1,4 +1,4 @@
package kscience.kmath.operations.internal package kscience.kmath.testutils
import kscience.kmath.operations.Algebra 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.Field
import kscience.kmath.operations.invoke 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.Ring
import kscience.kmath.operations.invoke 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.Space
import kscience.kmath.operations.invoke import kscience.kmath.operations.invoke

View File

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

View File

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

View File

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

View File

@ -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",