Compare commits

...

19 Commits

Author SHA1 Message Date
72b0d9edc9 Workaround for dokka bug: https://github.com/Kotlin/dokka/issues/4001 2026-01-09 14:48:39 +03:00
f8b23261e1 Update Readme.
Move last projects from JVM to MPP.
Update changelog.
2026-01-09 14:00:17 +03:00
d64a117a9f Update changelog 2026-01-08 15:55:52 +03:00
845aea0cd7 Merge pull request 'Replace FlagAttributes with BooleanAttributes for matrices to solve KS-626' (!530) from feature/boolean-flag-attributes into dev
Reviewed-on: #530
Reviewed-by: Gleb Minaev <glebminaev02@yandex.ru>
2025-11-30 11:55:14 +03:00
7267880126 Remove unnecessary attributes type arguments for MatrixWrapper 2025-11-30 09:10:51 +03:00
f3e9e338bf Merge branch 'dev' into feature/boolean-flag-attributes 2025-11-30 08:37:03 +03:00
73a6ad28c3 Merge pull request 'Add contracts to operator functions that were missing' (!531) from add-contracts-to-operators into dev
Reviewed-on: #531
Reviewed-by: Alexander Nozik <altavir@gmail.com>
2025-11-30 08:36:47 +03:00
Gleb Minaev
7da0ace8f8 Add contracts. 2025-11-29 22:12:38 +03:00
9c22b51fa5 Minor fixes to builders 2025-11-28 18:17:05 +03:00
26dfdf39df Merge remote-tracking branch 'spc/feature/boolean-flag-attributes' into feature/boolean-flag-attributes 2025-11-28 18:03:12 +03:00
58a3f749a7 Merge branch 'dev' into feature/boolean-flag-attributes 2025-11-28 18:03:00 +03:00
5abc90a4ba Merge branch 'dev' into feature/boolean-flag-attributes 2025-11-28 09:39:59 +03:00
6e97e513fb Update github actions config 2025-11-28 09:13:55 +03:00
7d08aed5eb Remove unnecessary inheritance from BooleanAttributes for matrix attributes. 2025-11-28 09:06:29 +03:00
b9c1947b70 Replace FlagAttributes with BooleanAttributes for matrices to solve KS-626 2025-11-27 13:17:43 +03:00
b1446741db add test for failure on cholesky non positive-defined input 2025-11-27 10:14:08 +03:00
98dd43d404 adoptation fixes 2025-11-27 08:44:22 +03:00
577401bb08 Merge branch 'refs/heads/beta/kotlin-2.3.0' into dev 2025-11-25 21:30:40 +03:00
896822ec77 Fix for KS-627 2025-11-25 21:27:21 +03:00
53 changed files with 338 additions and 284 deletions

View File

@@ -10,15 +10,25 @@ jobs:
runs-on: windows-latest
timeout-minutes: 20
steps:
- uses: actions/checkout@v3
- uses: actions/setup-java@v3.5.1
- uses: actions/checkout@v6
- uses: actions/setup-java@v5
with:
java-version: '17'
java-version: '21'
distribution: 'liberica'
cache: 'gradle'
- name: Gradle Wrapper Validation
uses: gradle/wrapper-validation-action@v1.0.4
- name: Gradle Build
uses: gradle/gradle-build-action@v2.4.2
uses: gradle/gradle-build-action@v3
with:
arguments: test jvmTest
- name: Publish Test Report
uses: mikepenz/action-junit-report@v6
if: ${{ !cancelled() }} # always run even if the previous step fails
with:
report_paths: '**/test-results/**/TEST-*.xml'
annotate_only: true
detailed_summary: true
flaky_summary: true
include_empty_in_summary: false
skip_success_summary: true

View File

@@ -10,18 +10,13 @@ jobs:
runs-on: ubuntu-24.04
timeout-minutes: 40
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
- uses: actions/checkout@v6
- uses: actions/setup-java@v5
with:
java-version: 17
java-version: 21
distribution: liberica
- name: Cache konan
uses: actions/cache@v3
with:
path: ~/.konan
key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Gradle Wrapper Validation
uses: gradle/wrapper-validation-action@v1.0.4
- uses: gradle/gradle-build-action@v3
with:
arguments: dokkaGenerate --no-parallel

View File

@@ -3,10 +3,8 @@
## Unreleased
### Added
- Fit accessors with Attribute
### Changed
- Upgrade tensorflow version to 1.0.0
### Deprecated
@@ -16,6 +14,22 @@
### Security
## 0.5.0 - 2026-01-09
### Added
- More statistics functions by @qwazer
- Fit accessors with Attribute
### Changed
- Flag attributes are replaced with boolean attributes to properly support missing values
- Upgrade tensorflow version to 1.0.0
### Removed
- Support for ND4J
## 0.4.2 - 2025-01-27
### Added

View File

@@ -5,10 +5,7 @@
# KMath
Could be pronounced as `key-math`. The **K**otlin **Math**ematics library was initially intended as a Kotlin-based
analog to Python's NumPy library. Later we found that kotlin is much more flexible language and allows superior
architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like
experience could be achieved with [kmath-for-real](/kmath-for-real) extension module.
Could be pronounced as `key-math`. The **K**otlin **Math**ematics library was initially intended as a Kotlin-based analog to Python's NumPy library. Later we found that kotlin is a much more flexible language and allows superior architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like experience could be achieved with [kmath-for-real](kmath-for-real) extension module.
[Documentation site](https://SciProgCentre.github.io/kmath/)
@@ -34,15 +31,17 @@ experience could be achieved with [kmath-for-real](/kmath-for-real) extension mo
* Be like NumPy. It was the idea at the beginning, but we decided that we can do better in API.
* Provide the best performance out of the box. We have specialized libraries for that. Need only API wrappers for them.
* Cover all cases as immediately and in one bundle. We will modularize everything and add new features gradually.
* Provide specialized behavior in the core. API is made generic on purpose, so one needs to specialize for types, like
for `Double` in the core. For that we will have specialization modules like `kmath-for-real`, which will give better
experience for those, who want to work with specific types.
* Provide specialized behavior in the core. API is made generic on purpose, so one needs to specialize for types, like for `Float64` in the core. For that we will have specialization modules like [kmath-for-real](kmath-for-real), which will give a better experience for those who want to work with specific types.
## Contributing
The project requires a lot of additional work. The most important thing we need is feedback about what features are required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues marked with [good first issue](https://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label.
Project roadmap will be available at [GitHub Projects](https://github.com/orgs/SciProgCentre/projects/3).
## Features and stability
KMath is a modular library. Different modules provide different features with different API stability guarantees. All
core modules are released with the same version, but with different API change policy. The features are described in
module definitions below. The module stability could have the following levels:
KMath is a modular library. Different modules provide different features with different API stability guarantees. All core modules are released with the same version, but with different API change policy. The features are described in module definitions below. The module stability could have the following levels:
* **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could
break any moment. You can still use it, but be sure to fix the specific version.
@@ -50,7 +49,7 @@ module definitions below. The module stability could have the following levels:
with `@UnstableKMathAPI` or other stability warning annotations.
* **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor
versions, but not in patch versions. API is protected
with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool.
with [binary-compatibility-validator](https://kotlinlang.org/docs/gradle-binary-compatibility-validation.html) tool.
* **STABLE**. The API stabilized. Breaking changes are allowed only in major releases.
## Modules
@@ -60,10 +59,6 @@ module definitions below. The module stability could have the following levels:
>
> **Maturity**: EXPERIMENTAL
### [examples](examples)
>
> **Maturity**: EXPERIMENTAL
### [kmath-ast](kmath-ast)
>
> **Maturity**: EXPERIMENTAL
@@ -98,9 +93,9 @@ module definitions below. The module stability could have the following levels:
> **Features:**
> - [algebras](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields.
> - [nd](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them.
> - [linear](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition.
> - [linear](kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API.
> - [buffers](kmath-core/src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure
> - [expressions](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
> - [expressions](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
> - [domains](kmath-core/src/commonMain/kotlin/space/kscience/kmath/domains) : Domains
> - [autodiff](kmath-core/src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation
> - [Parallel linear algebra](kmath-core/#) : Parallel implementation for `LinearAlgebra`
@@ -183,17 +178,6 @@ One can still use generic algebras though.
>
> **Maturity**: PROTOTYPE
### [kmath-nd4j](kmath-nd4j)
> ND4J NDStructure implementation and according NDAlgebra classes
>
> **Maturity**: DEPRECATED
>
> **Features:**
> - [nd4jarraystructure](kmath-nd4j/#) : NDStructure wrapper for INDArray
> - [nd4jarrayrings](kmath-nd4j/#) : Rings over Nd4jArrayStructure of Int and Long
> - [nd4jarrayfields](kmath-nd4j/#) : Fields over Nd4jArrayStructure of Float and Double
### [kmath-ojalgo](kmath-ojalgo)
> Ojalgo bindings for kmath
>
@@ -239,34 +223,21 @@ One can still use generic algebras though.
## Multi-platform support
KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the
[common source sets](/kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features
are delegated to platform-specific implementations even if they could be provided in the common module for performance
reasons. Currently, Kotlin/JVM is the primary platform, however, Kotlin/Native and Kotlin/JS contributions and
feedback are also welcome.
KMath is developed as a multi-platform library, which means that most of the interfaces are declared in common source sets like [common source sets](kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features are delegated to platform-specific implementations even if they could be provided in the common module for performance reasons. Currently, Kotlin/JVM is the primary platform, however, Kotlin/Native, Kotlin/JS and Kotlin/Wasm contributions and feedback are also welcome.
## Performance
Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to
achieve both
performance and flexibility.
Performance of mathematical operations is hard to achieve without a lot of effort. KMath focus is to provide a reasonable performance for common cases, out of the box and good interoperability with optimized libraries for edge cases. For example, one could prototype an algorithm using KMath core implementations and then use Multik or Ojalgo for performance-critical parts just by adding a dependency and algebra context switch.
We expect to focus on creating a convenient universal API first and then work on increasing performance for specific
cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized
native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be
better than SciPy.
As for core implementations, we expect to focus on creating a convenient universal API first and then work on increasing performance for specific cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy.
## Requirements
KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or
Oracle GraalVM for execution to get better performance.
KMath currently relies on JDK 21 for compilation and execution of Kotlin-JVM part.
### Repositories
Release and development artifacts are accessible from mipt-npm [Space](https://www.jetbrains.com/space/)
repository `https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven` (see documentation of
[Kotlin Multiplatform](https://kotlinlang.org/docs/reference/multiplatform.html) for more details). The repository could
be reached through [repo.kotlin.link](https://repo.kotlin.link) proxy:
Intermediate releases are published to [Kotlin.Link](https://repo.kotlin.link) repository.
```kotlin
repositories {
@@ -278,11 +249,3 @@ dependencies {
// api("space.kscience:kmath-core-jvm:$version") for jvm-specific version
}
```
## Contributing
The project requires a lot of additional work. The most important thing we need is feedback about what features are
required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues
marked
with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
label.

View File

@@ -1,121 +1,122 @@
# Module KMath-Benchmarks
# BenchmarksResult
## Report for benchmark configuration <code>main</code>
* Run on OpenJDK 64-Bit Server VM (build 17.0.11+9) with Java process:
* Run on OpenJDK 64-Bit Server VM (build 21.0.9+10-LTS) with Java process:
```
C:\Users\altavir\scoop\apps\gradle\current\.gradle\jdks\eclipse_adoptium-17-amd64-windows.2\bin\java.exe -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant
C:\Users\altavir\.gradle\jdks\eclipse_adoptium-21-amd64-windows.2\bin\java.exe -Dfile.encoding=UTF-8 -Duser.country=US -Duser.language=en -Duser.variant
```
* JMH 1.21 was used in `thrpt` mode with 5 warmup iterations by 10 s and 5 measurement iterations by 10 s.
* JMH 1.37 was used in `thrpt` mode with 5 warmup iterations by 10 s and 5 measurement iterations by 10 s.
### [ArrayBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`benchmarkArrayRead`|3.9E+06 &plusmn; 3.4E+05 ops/s|
|`benchmarkBufferRead`|4.0E+06 &plusmn; 3.2E+05 ops/s|
|`nativeBufferRead`|3.9E+06 &plusmn; 2.0E+05 ops/s|
|`benchmarkArrayRead`|3.9E+06 &plusmn; 1.1E+06 ops/s|
|`benchmarkBufferRead`|4.0E+06 &plusmn; 2.2E+05 ops/s|
|`nativeBufferRead`|4.0E+06 &plusmn; 1.7E+05 ops/s|
### [BigIntBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`jvmAdd`|3.1E+07 &plusmn; 1.8E+07 ops/s|
|`jvmAddLarge`|4.5E+04 &plusmn; 5.5E+03 ops/s|
|`jvmMultiply`|3.6E+07 &plusmn; 1.7E+07 ops/s|
|`jvmMultiplyLarge`|1.9E+02 &plusmn; 95 ops/s|
|`jvmParsing10`|4.0E+06 &plusmn; 8.8E+05 ops/s|
|`jvmParsing16`|3.6E+06 &plusmn; 6.5E+05 ops/s|
|`jvmPower`|25 &plusmn; 1.4 ops/s|
|`jvmSmallAdd`|5.7E+07 &plusmn; 9.7E+05 ops/s|
|`kmAdd`|2.6E+07 &plusmn; 8.8E+05 ops/s|
|`kmAddLarge`|2.3E+04 &plusmn; 1.2E+03 ops/s|
|`kmMultiply`|3.8E+07 &plusmn; 5.5E+06 ops/s|
|`kmMultiplyLarge`|36 &plusmn; 3.8 ops/s|
|`kmParsing10`|2.5E+06 &plusmn; 1.4E+05 ops/s|
|`kmParsing16`|3.7E+06 &plusmn; 4.7E+05 ops/s|
|`kmPower`|6.6 &plusmn; 1.0 ops/s|
|`kmSmallAdd`|2.0E+07 &plusmn; 1.7E+06 ops/s|
|`jvmAdd`|2.9E+07 &plusmn; 2.8E+06 ops/s|
|`jvmAddLarge`|3.8E+04 &plusmn; 6.4E+03 ops/s|
|`jvmMultiply`|5.3E+07 &plusmn; 6.1E+06 ops/s|
|`jvmMultiplyLarge`|2.2E+02 &plusmn; 1.9 ops/s|
|`jvmParsing10`|3.9E+06 &plusmn; 4.7E+05 ops/s|
|`jvmParsing16`|3.1E+06 &plusmn; 4.6E+05 ops/s|
|`jvmPower`|24 &plusmn; 1.7 ops/s|
|`jvmSmallAdd`|4.7E+07 &plusmn; 4.6E+06 ops/s|
|`kmAdd`|2.3E+07 &plusmn; 5.1E+06 ops/s|
|`kmAddLarge`|2.6E+04 &plusmn; 3.0E+02 ops/s|
|`kmMultiply`|3.7E+07 &plusmn; 2.9E+06 ops/s|
|`kmMultiplyLarge`|34 &plusmn; 2.8 ops/s|
|`kmParsing10`|2.5E+06 &plusmn; 1.5E+05 ops/s|
|`kmParsing16`|4.0E+06 &plusmn; 2.4E+05 ops/s|
|`kmPower`|6.5 &plusmn; 0.69 ops/s|
|`kmSmallAdd`|1.6E+07 &plusmn; 8.0E+05 ops/s|
### [BufferBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`bufferViewReadWrite`|6.0E+06 &plusmn; 7.4E+05 ops/s|
|`bufferViewReadWriteSpecialized`|7.6E+05 &plusmn; 1.1E+04 ops/s|
|`complexBufferReadWrite`|2.4E+06 &plusmn; 2.7E+05 ops/s|
|`doubleArrayReadWrite`|7.3E+06 &plusmn; 4.3E+05 ops/s|
|`doubleBufferReadWrite`|7.3E+06 &plusmn; 3.4E+05 ops/s|
|`bufferViewReadWrite`|5.4E+06 &plusmn; 3.8E+05 ops/s|
|`bufferViewReadWriteSpecialized`|5.0E+06 &plusmn; 1.2E+06 ops/s|
|`complexBufferReadWrite`|2.2E+06 &plusmn; 5.7E+04 ops/s|
|`doubleArrayReadWrite`|6.9E+06 &plusmn; 1.2E+06 ops/s|
|`doubleBufferReadWrite`|6.6E+06 &plusmn; 1.1E+06 ops/s|
### [DotBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`bufferedDot`|1.3 &plusmn; 0.032 ops/s|
|`cmDot`|0.42 &plusmn; 0.20 ops/s|
|`cmDotWithConversion`|0.83 &plusmn; 0.12 ops/s|
|`ejmlDot`|2.6 &plusmn; 0.049 ops/s|
|`ejmlDotWithConversion`|2.5 &plusmn; 0.075 ops/s|
|`multikDot`|25 &plusmn; 0.52 ops/s|
|`ojalgoDot`|11 &plusmn; 1.3 ops/s|
|`parallelDot`|11 &plusmn; 0.17 ops/s|
|`tensorDot`|1.1 &plusmn; 0.028 ops/s|
|`tfDot`|4.7 &plusmn; 0.14 ops/s|
|`bufferedDot`|1.2 &plusmn; 0.20 ops/s|
|`cmDot`|0.36 &plusmn; 0.14 ops/s|
|`cmDotWithConversion`|0.80 &plusmn; 0.092 ops/s|
|`ejmlDot`|2.9 &plusmn; 0.61 ops/s|
|`ejmlDotWithConversion`|2.7 &plusmn; 0.15 ops/s|
|`multikDot`|23 &plusmn; 2.4 ops/s|
|`ojalgoDot`|11 &plusmn; 0.79 ops/s|
|`parallelDot`|9.4 &plusmn; 1.3 ops/s|
|`tensorDot`|1.0 &plusmn; 0.15 ops/s|
|`tfDot`|3.9 &plusmn; 0.90 ops/s|
### [ExpressionsInterpretersBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`asmGenericExpression`|12 &plusmn; 0.099 ops/s|
|`asmPrimitiveExpression`|26 &plusmn; 0.57 ops/s|
|`asmPrimitiveExpressionArray`|74 &plusmn; 1.7 ops/s|
|`functionalExpression`|5.3 &plusmn; 0.015 ops/s|
|`justCalculate`|74 &plusmn; 0.85 ops/s|
|`mstExpression`|4.2 &plusmn; 0.10 ops/s|
|`rawExpression`|25 &plusmn; 0.74 ops/s|
|`asmGenericExpression`|15 &plusmn; 1.8 ops/s|
|`asmPrimitiveExpression`|27 &plusmn; 0.98 ops/s|
|`asmPrimitiveExpressionArray`|78 &plusmn; 14 ops/s|
|`functionalExpression`|4.4 &plusmn; 0.25 ops/s|
|`justCalculate`|79 &plusmn; 5.4 ops/s|
|`mstExpression`|4.2 &plusmn; 0.93 ops/s|
|`rawExpression`|25 &plusmn; 5.0 ops/s|
### [IntegrationBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`complexIntegration`|2.6E+03 &plusmn; 46 ops/s|
|`doubleIntegration`|2.8E+03 &plusmn; 1.1E+02 ops/s|
|`complexIntegration`|2.2E+03 &plusmn; 3.0E+02 ops/s|
|`doubleIntegration`|2.3E+03 &plusmn; 6.4E+02 ops/s|
### [MatrixInverseBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`cmLUPInversion`|2.1E+03 &plusmn; 35 ops/s|
|`ejmlInverse`|1.2E+03 &plusmn; 27 ops/s|
|`kmathLupInversion`|4.0E+02 &plusmn; 52 ops/s|
|`kmathParallelLupInversion`|4.0E+02 &plusmn; 9.6 ops/s|
|`ojalgoInverse`|2.1E+03 &plusmn; 3.3E+02 ops/s|
### [MinStatisticBenchmark.kt](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MinStatisticBenchmark.kt)
|`cmLUPInversion`|2.0E+03 &plusmn; 1.1E+02 ops/s|
|`ejmlInverse`|1.2E+03 &plusmn; 29 ops/s|
|`kmathLupInversion`|3.9E+02 &plusmn; 92 ops/s|
|`kmathParallelLupInversion`|55 &plusmn; 5.0 ops/s|
|`ojalgoInverse`|1.7E+03 &plusmn; 35 ops/s|
### [MinStatisticBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MinStatisticBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`kotlinArrayMin`| 1875.7 &plusmn; 401.5 ops/s |
|`minBlocking`| 1357.9 &plusmn; 72.0 ops/s |
|`kotlinArrayMin`|1.6E+03 &plusmn; 3.0E+02 ops/s|
|`minBlocking`|1.2E+03 &plusmn; 1.2E+02 ops/s|
### [NDFieldBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`boxingFieldAdd`|1.7 &plusmn; 0.11 ops/s|
|`multikAdd`|7.0 &plusmn; 0.41 ops/s|
|`multikInPlaceAdd`|34 &plusmn; 1.7 ops/s|
|`specializedFieldAdd`|7.2 &plusmn; 1.2 ops/s|
|`tensorAdd`|7.2 &plusmn; 1.6 ops/s|
|`tensorInPlaceAdd`|7.4 &plusmn; 4.9 ops/s|
|`viktorAdd`|5.8 &plusmn; 0.65 ops/s|
|`boxingFieldAdd`|1.9 &plusmn; 0.089 ops/s|
|`multikAdd`|6.8 &plusmn; 1.0 ops/s|
|`multikInPlaceAdd`|32 &plusmn; 4.7 ops/s|
|`specializedFieldAdd`|6.7 &plusmn; 0.98 ops/s|
|`tensorAdd`|7.9 &plusmn; 1.1 ops/s|
|`tensorInPlaceAdd`|11 &plusmn; 3.4 ops/s|
|`viktorAdd`|6.4 &plusmn; 0.41 ops/s|
### [ViktorBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`doubleFieldAddition`|7.1 &plusmn; 2.0 ops/s|
|`rawViktor`|6.2 &plusmn; 1.0 ops/s|
|`viktorFieldAddition`|6.4 &plusmn; 0.29 ops/s|
|`doubleFieldAddition`|7.3 &plusmn; 1.1 ops/s|
|`rawViktor`|6.0 &plusmn; 0.88 ops/s|
|`viktorFieldAddition`|6.7 &plusmn; 0.47 ops/s|
### [ViktorLogBenchmark](src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt)
| Benchmark | Score |
|:---------:|:-----:|
|`rawViktorLog`|1.3 &plusmn; 0.016 ops/s|
|`realFieldLog`|1.3 &plusmn; 0.019 ops/s|
|`viktorFieldLog`|1.3 &plusmn; 0.020 ops/s|
|`rawViktorLog`|1.3 &plusmn; 0.40 ops/s|
|`realFieldLog`|1.2 &plusmn; 0.34 ops/s|
|`viktorFieldLog`|1.3 &plusmn; 0.0073 ops/s|

View File

@@ -1,3 +1,5 @@
# Module KMath-Benchmarks
# BenchmarksResult
${benchmarkMain}

View File

@@ -1,3 +1,4 @@
import org.jetbrains.kotlin.gradle.dsl.abi.ExperimentalAbiValidation
import space.kscience.gradle.useApache2Licence
import space.kscience.gradle.useSPCTeam
@@ -14,7 +15,7 @@ allprojects {
}
group = "space.kscience"
version = "0.4.3-dev-1"
version = "0.5.0"
}
dependencies {
@@ -87,7 +88,15 @@ kscienceProject {
publishTo("spc", "https://maven.sciprog.center/kscience")
publishToCentral()
@OptIn(ExperimentalAbiValidation::class)
abiValidation {
filters {
excluded {
annotatedWith.add("space.kscience.kmath.UnstableKMathAPI")
}
}
}
}
//apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI")

View File

@@ -2,14 +2,10 @@
[![DOI](https://zenodo.org/badge/129486382.svg)](https://zenodo.org/badge/latestdoi/129486382)
![Gradle build](https://github.com/SciProgCentre/kmath/workflows/Gradle%20build/badge.svg)
[![Maven Central](https://img.shields.io/maven-central/v/space.kscience/kmath-core.svg?label=Maven%20Central)](https://search.maven.org/search?q=g:%22space.kscience%22)
[![Space](https://img.shields.io/badge/dynamic/xml?color=orange&label=Space&query=//metadata/versioning/latest&url=https%3A%2F%2Fmaven.pkg.jetbrains.space%2Fmipt-npm%2Fp%2Fsci%2Fmaven%2Fspace%2Fkscience%2Fkmath-core%2Fmaven-metadata.xml)](https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven/space/kscience/)
# KMath
Could be pronounced as `key-math`. The **K**otlin **Math**ematics library was initially intended as a Kotlin-based
analog to Python's NumPy library. Later we found that kotlin is much more flexible language and allows superior
architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like
experience could be achieved with [kmath-for-real](/kmath-for-real) extension module.
Could be pronounced as `key-math`. The **K**otlin **Math**ematics library was initially intended as a Kotlin-based analog to Python's NumPy library. Later we found that kotlin is a much more flexible language and allows superior architecture designs. In contrast to `numpy` and `scipy` it is modular and has a lightweight core. The `numpy`-like experience could be achieved with [kmath-for-real](kmath-for-real) extension module.
[Documentation site](https://SciProgCentre.github.io/kmath/)
@@ -35,15 +31,17 @@ experience could be achieved with [kmath-for-real](/kmath-for-real) extension mo
* Be like NumPy. It was the idea at the beginning, but we decided that we can do better in API.
* Provide the best performance out of the box. We have specialized libraries for that. Need only API wrappers for them.
* Cover all cases as immediately and in one bundle. We will modularize everything and add new features gradually.
* Provide specialized behavior in the core. API is made generic on purpose, so one needs to specialize for types, like
for `Double` in the core. For that we will have specialization modules like `kmath-for-real`, which will give better
experience for those, who want to work with specific types.
* Provide specialized behavior in the core. API is made generic on purpose, so one needs to specialize for types, like for `Float64` in the core. For that we will have specialization modules like [kmath-for-real](kmath-for-real), which will give a better experience for those who want to work with specific types.
## Contributing
The project requires a lot of additional work. The most important thing we need is feedback about what features are required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues marked with [good first issue](https://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label.
Project roadmap will be available at [GitHub Projects](https://github.com/orgs/SciProgCentre/projects/3).
## Features and stability
KMath is a modular library. Different modules provide different features with different API stability guarantees. All
core modules are released with the same version, but with different API change policy. The features are described in
module definitions below. The module stability could have the following levels:
KMath is a modular library. Different modules provide different features with different API stability guarantees. All core modules are released with the same version, but with different API change policy. The features are described in module definitions below. The module stability could have the following levels:
* **PROTOTYPE**. On this level there are no compatibility guarantees. All methods and classes form those modules could
break any moment. You can still use it, but be sure to fix the specific version.
@@ -51,7 +49,7 @@ module definitions below. The module stability could have the following levels:
with `@UnstableKMathAPI` or other stability warning annotations.
* **DEVELOPMENT**. API breaking generally follows semantic versioning ideology. There could be changes in minor
versions, but not in patch versions. API is protected
with [binary-compatibility-validator](https://github.com/Kotlin/binary-compatibility-validator) tool.
with [binary-compatibility-validator](https://kotlinlang.org/docs/gradle-binary-compatibility-validation.html) tool.
* **STABLE**. The API stabilized. Breaking changes are allowed only in major releases.
## Modules
@@ -60,34 +58,21 @@ ${modules}
## Multi-platform support
KMath is developed as a multi-platform library, which means that most of the interfaces are declared in the
[common source sets](/kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features
are delegated to platform-specific implementations even if they could be provided in the common module for performance
reasons. Currently, Kotlin/JVM is the primary platform, however, Kotlin/Native and Kotlin/JS contributions and
feedback are also welcome.
KMath is developed as a multi-platform library, which means that most of the interfaces are declared in common source sets like [common source sets](kmath-core/src/commonMain) and implemented there wherever it is possible. In some cases, features are delegated to platform-specific implementations even if they could be provided in the common module for performance reasons. Currently, Kotlin/JVM is the primary platform, however, Kotlin/Native, Kotlin/JS and Kotlin/Wasm contributions and feedback are also welcome.
## Performance
Calculation of performance is one of the major goals of KMath in the future, but in some cases it is impossible to
achieve both
performance and flexibility.
Performance of mathematical operations is hard to achieve without a lot of effort. KMath focus is to provide a reasonable performance for common cases, out of the box and good interoperability with optimized libraries for edge cases. For example, one could prototype an algorithm using KMath core implementations and then use Multik or Ojalgo for performance-critical parts just by adding a dependency and algebra context switch.
We expect to focus on creating a convenient universal API first and then work on increasing performance for specific
cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized
native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be
better than SciPy.
As for core implementations, we expect to focus on creating a convenient universal API first and then work on increasing performance for specific cases. We expect the worst KMath benchmarks will perform better than native Python, but worse than optimized native/SciPy (mostly due to boxing operations on primitive numbers). The best performance of optimized parts could be better than SciPy.
## Requirements
KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend using GraalVM-CE or
Oracle GraalVM for execution to get better performance.
KMath currently relies on JDK 21 for compilation and execution of Kotlin-JVM part.
### Repositories
Release and development artifacts are accessible from mipt-npm [Space](https://www.jetbrains.com/space/)
repository `https://maven.pkg.jetbrains.space/mipt-npm/p/sci/maven` (see documentation of
[Kotlin Multiplatform](https://kotlinlang.org/docs/reference/multiplatform.html) for more details). The repository could
be reached through [repo.kotlin.link](https://repo.kotlin.link) proxy:
Intermediate releases are published to [Kotlin.Link](https://repo.kotlin.link) repository.
```kotlin
repositories {
@@ -99,11 +84,3 @@ dependencies {
// api("${group}:kmath-core-jvm:$version") for jvm-specific version
}
```
## Contributing
The project requires a lot of additional work. The most important thing we need is feedback about what features are
required the most. Feel free to create feature requests. We are also welcome to code contributions, especially in issues
marked
with [good first issue](hhttps://github.com/SciProgCentre/kmath/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)
label.

View File

@@ -2,7 +2,6 @@
# Copyright 2018-2021 KMath contributors.
# Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
#
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx4096m
org.gradle.parallel=true
org.gradle.workers.max=4
@@ -13,4 +12,4 @@ kotlin.native.ignoreDisabledTargets=true
org.jetbrains.dokka.experimental.gradle.pluginMode=V2Enabled
kotlin.native.enableKlibsCrossCompilation=true
toolsVersion=0.20.0-kotlin-2.3.0-Beta1
toolsVersion=0.20.2-kotlin-2.3.0

View File

@@ -3,10 +3,10 @@
commons-rng = "1.6"
multik = "0.2.3"
nd4j = "1.0.0-M2.1"
tensorflow = "1.0.0"
tensorflow = "1.1.0"
[libraries]
attributes = "space.kscience:attributes-kt:0.3.0"
attributes = "space.kscience:attributes-kt:0.4.0"
commons-math = "org.apache.commons:commons-math3:3.6.1"
@@ -19,7 +19,7 @@ multik-default = { module = "org.jetbrains.kotlinx:multik-default", version.ref
nd4j-api = { module = "org.nd4j:nd4j-api", version.ref = "nd4j" }
nd4j-native-platform = { module = "org.nd4j:nd4j-native-platform", version.ref = "nd4j" }
ojalgo = "org.ojalgo:ojalgo:55.1.0"
ojalgo = "org.ojalgo:ojalgo:56.2.0"
tensorflow-core-api = {module = "org.tensorflow:tensorflow-core-api", version.ref="tensorflow"}

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -10,7 +10,7 @@ Extensions to MST API: transformations, dynamic compilation and visualization.
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-ast:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-ast:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -20,7 +20,7 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-ast:0.4.2")
implementation("space.kscience:kmath-ast:0.5.0")
}
```

View File

@@ -5,11 +5,16 @@
package space.kscience.kmath.asm.internal
import org.objectweb.asm.*
import org.objectweb.asm.ClassWriter
import org.objectweb.asm.FieldVisitor
import org.objectweb.asm.Opcodes.*
import org.objectweb.asm.Type
import org.objectweb.asm.Type.*
import org.objectweb.asm.commons.InstructionAdapter
import space.kscience.kmath.expressions.*
import space.kscience.kmath.expressions.Expression
import space.kscience.kmath.expressions.MST
import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.expressions.invoke
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType
import java.nio.file.Paths
@@ -24,6 +29,7 @@ import kotlin.io.path.writeBytes
* @property expressionResultCallback the function to apply to this object when generating expression value.
* @author Iaroslav Postovalov
*/
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN")
internal class GenericAsmBuilder<T>(
classOfT: Class<*>,
private val className: String,

View File

@@ -6,7 +6,7 @@ Commons math binding for kmath
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-commons:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-commons:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-commons:0.4.2")
implementation("space.kscience:kmath-commons:0.5.0")
}
```

View File

@@ -8,7 +8,7 @@ Complex and hypercomplex number systems in KMath.
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-complex:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-complex:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -18,6 +18,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-complex:0.4.2")
implementation("space.kscience:kmath-complex:0.5.0")
}
```

View File

@@ -4,9 +4,9 @@ The core interfaces of KMath.
- [algebras](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Algebraic structures like rings, spaces and fields.
- [nd](src/commonMain/kotlin/space/kscience/kmath/structures/StructureND.kt) : Many-dimensional structures and operations on them.
- [linear](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition.
- [linear](src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt) : Basic linear algebra operations (sums, products, etc.), backed by the `Space` API.
- [buffers](src/commonMain/kotlin/space/kscience/kmath/structures/Buffers.kt) : One-dimensional structure
- [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
- [expressions](src/commonMain/kotlin/space/kscience/kmath/expressions) : By writing a single mathematical expression once, users will be able to apply different types of
- [domains](src/commonMain/kotlin/space/kscience/kmath/domains) : Domains
- [autodiff](src/commonMain/kotlin/space/kscience/kmath/expressions/SimpleAutoDiff.kt) : Automatic differentiation
- [Parallel linear algebra](#) : Parallel implementation for `LinearAlgebra`
@@ -14,7 +14,7 @@ The core interfaces of KMath.
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-core:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-core:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -24,6 +24,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-core:0.4.2")
implementation("space.kscience:kmath-core:0.5.0")
}
```

View File

@@ -44,7 +44,12 @@ readme {
feature(
id = "linear",
ref = "src/commonMain/kotlin/space/kscience/kmath/operations/Algebra.kt",
) { "Basic linear algebra operations (sums, products, etc.), backed by the `Space` API. Advanced linear algebra operations like matrix inversion and LU decomposition." }
) {
"""
Basic linear algebra operations (sums, products, etc.), backed by the `Space` API.
Advanced linear algebra operations like matrix inversion and LU decomposition.
""".trimIndent()
}
feature(
id = "buffers",
@@ -56,7 +61,7 @@ readme {
ref = "src/commonMain/kotlin/space/kscience/kmath/expressions"
) {
"""
By writing a single mathematical expression once, users will be able to apply different types of
By writing a single mathematical expression once, users will be able to apply different types of
objects to the expression by providing a context. Expressions can be used for a wide variety of purposes from high
performance calculations to code generation.
""".trimIndent()

View File

@@ -5,13 +5,20 @@
package space.kscience.kmath.linear
import space.kscience.attributes.*
import space.kscience.attributes.Attributes
import space.kscience.attributes.SafeType
import space.kscience.attributes.withAttribute
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.nd.*
import space.kscience.kmath.nd.MutableStructure2D
import space.kscience.kmath.nd.Structure2D
import space.kscience.kmath.nd.StructureAttribute
import space.kscience.kmath.nd.as1D
import space.kscience.kmath.operations.BufferRingOps
import space.kscience.kmath.operations.Ring
import space.kscience.kmath.operations.invoke
import space.kscience.kmath.structures.Buffer
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
/**
* Alias for [Structure2D] with more familiar name.
@@ -179,7 +186,7 @@ public interface LinearSpace<T, out A : Ring<T>> : MatrixScope<T> {
* If the structure holds given [attribute] return itself. Otherwise, return a new [Matrix] that contains a computed attribute.
*
* This method is used to compute and cache attribute inside the structure. If one needs an attribute only once,
* better use [StructureND.getOrComputeAttribute].
* better use [Structure2D.getOrComputeAttribute].
*/
@UnstableKMathAPI
public fun <V : Any, A : StructureAttribute<V>> Matrix<T>.withComputedAttribute(
@@ -210,7 +217,12 @@ public interface LinearSpace<T, out A : Ring<T>> : MatrixScope<T> {
}
public inline operator fun <LS : LinearSpace<*, *>, R> LS.invoke(block: LS.() -> R): R = run(block)
public inline operator fun <LS : LinearSpace<*, *>, R> LS.invoke(block: LS.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return this.block()
}
/**

View File

@@ -15,7 +15,9 @@ import space.kscience.kmath.PerformancePitfall
import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.*
import space.kscience.kmath.structures.*
import space.kscience.kmath.structures.Float64
import space.kscience.kmath.structures.IntBuffer
import space.kscience.kmath.structures.asBuffer
public interface LupDecomposition<T> {
public val pivot: IntBuffer
@@ -47,7 +49,7 @@ public class GenericLupDecomposition<T>(
override val l: Matrix<T>
get() = VirtualMatrix(lu.rowNum, lu.colNum, attributes = Attributes(LowerTriangular)) { i, j ->
get() = VirtualMatrix(lu.rowNum, lu.colNum, attributes = Attributes(LowerTriangular, true)) { i, j ->
when {
j < i -> lu[i, j]
j == i -> elementAlgebra.one
@@ -56,7 +58,7 @@ public class GenericLupDecomposition<T>(
}
override val u: Matrix<T>
get() = VirtualMatrix(lu.rowNum, lu.colNum, attributes = Attributes(UpperTriangular)) { i, j ->
get() = VirtualMatrix(lu.rowNum, lu.colNum, attributes = Attributes(UpperTriangular,true)) { i, j ->
if (j >= i) lu[i, j] else elementAlgebra.zero
}

View File

@@ -80,7 +80,7 @@ public fun <T, A : Ring<T>> MatrixBuilder<T, A>.diagonal(
builder: A.(Int) -> T
): Matrix<T> = with(linearSpace.elementAlgebra) {
require(colNum == rowNum) { "In order to build symmetric matrix, number of rows $rowNum should be equal to number of columns $colNum" }
return VirtualMatrix(rowNum, colNum, attributes = Attributes(IsDiagonal)) { i, j ->
return VirtualMatrix(rowNum, colNum, attributes = Attributes(IsDiagonal, true)) { i, j ->
check(i in 0 until rowNum) { "$i out of bounds: 0..<$rowNum" }
check(j in 0 until colNum) { "$j out of bounds: 0..<$colNum" }
if (i == j) {
@@ -97,7 +97,8 @@ public fun <T, A : Ring<T>> MatrixBuilder<T, A>.diagonal(
@UnstableKMathAPI
public fun <T> MatrixBuilder<T, Ring<T>>.diagonal(vararg elements: T): Matrix<T> {
require(colNum == rowNum) { "In order to build symmetric matrix, number of rows $rowNum should be equal to number of columns $colNum" }
return return VirtualMatrix(rowNum, colNum, attributes = Attributes(IsDiagonal)) { i, j ->
return VirtualMatrix(rowNum, colNum, attributes = Attributes(IsDiagonal,true)) { i, j ->
check(i in 0 until rowNum) { "$i out of bounds: 0..<$rowNum" }
check(j in 0 until colNum) { "$j out of bounds: 0..<$colNum" }
if (i == j) {

View File

@@ -36,8 +36,8 @@ public val <T : Any> Matrix<T>.origin: Matrix<T>
/**
* Add a single feature to a [Matrix]
*/
public fun <T, A : Attribute<T>> Matrix<T>.withAttribute(
attribute: A,
public fun <T> Matrix<T>.withAttribute(
attribute: Attribute<T>,
attrValue: T,
): MatrixWrapper<T> = if (this is MatrixWrapper) {
MatrixWrapper(origin, attributes.withAttribute(attribute, attrValue))
@@ -45,14 +45,26 @@ public fun <T, A : Attribute<T>> Matrix<T>.withAttribute(
MatrixWrapper(this, Attributes(attribute, attrValue))
}
public fun <T, A : Attribute<Unit>> Matrix<T>.withAttribute(
attribute: A,
public fun <T> Matrix<T>.withAttribute(
attribute: Attribute<Unit>,
): MatrixWrapper<T> = if (this is MatrixWrapper) {
MatrixWrapper(origin, attributes.withFlag(attribute))
} else {
MatrixWrapper(this, Attributes(attribute, Unit))
}
/**
* Add boolean attribute with default value `true`
*/
public fun <T> Matrix<T>.withAttribute(
attribute: Attribute<Boolean>,
value: Boolean = true
): MatrixWrapper<T> = if (this is MatrixWrapper) {
MatrixWrapper(origin, attributes.withAttribute(attribute, value))
} else {
MatrixWrapper(this, Attributes(attribute, value))
}
/**
* Modify matrix attributes
*/

View File

@@ -23,11 +23,14 @@ public interface MatrixScope<T> : WithType<T>
*/
public interface MatrixAttribute<T> : StructureAttribute<T>
public typealias BooleanAttribute = Attribute<Boolean>
/**
* Matrices with this feature are symmetric, meaning `matrix[i,j] == matrix[j,i]`
*/
public interface Symmetric : MatrixAttribute<Unit>, FlagAttribute{
public companion object: Symmetric
public interface Symmetric : MatrixAttribute<Boolean> {
public companion object : Symmetric
}
/**
@@ -72,12 +75,12 @@ public val <T> MatrixScope<T>.Determinant: Determinant<T> get() = Determinant(ty
/**
* Matrices with this feature are lower triangular ones.
*/
public object LowerTriangular : MatrixAttribute<Unit>, FlagAttribute
public object LowerTriangular : MatrixAttribute<Boolean>
/**
* Matrices with this feature are upper triangular ones.
*/
public object UpperTriangular : MatrixAttribute<Unit>, FlagAttribute
public object UpperTriangular : MatrixAttribute<Boolean>
/**
* Matrices with this feature support LU factorization: *a = [l] &middot; [u]* where *a* is the owning matrix.
@@ -102,7 +105,7 @@ public val <T> MatrixScope<T>.LU: LuDecompositionAttribute<T> get() = LuDecompos
* Matrices with this feature are orthogonal ones: *a &middot; a<sup>T</sup> = u* where *a* is the owning matrix, *u*
* is the unit matrix ([IsUnit]).
*/
public object OrthogonalAttribute : MatrixAttribute<Unit>, FlagAttribute
public object OrthogonalAttribute : MatrixAttribute<Boolean>
public interface QRDecomposition<out T> {

View File

@@ -11,6 +11,8 @@ import space.kscience.kmath.UnstableKMathAPI
import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.operations.Ring.Companion.optimizedPower
import space.kscience.kmath.structures.MutableBufferFactory
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
/**
* Represents an algebraic structure.
@@ -122,8 +124,12 @@ public fun <T> Algebra<T>.bindSymbol(symbol: Symbol): T = bindSymbol(symbol.iden
/**
* Call a block with an [Algebra] as receiver.
*/
// TODO add contract when KT-32313 is fixed
public inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R = run(block)
public inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
return this.block()
}
/**
* Represents group without neutral element (also known as inverse semigroup) i.e., algebraic structure with

View File

@@ -6,7 +6,7 @@
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-coroutines:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-coroutines:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-coroutines:0.4.2")
implementation("space.kscience:kmath-coroutines:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@ A proof of concept module for adding type-safe dimensions to structures
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-dimensions:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-dimensions:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-dimensions:0.4.2")
implementation("space.kscience:kmath-dimensions:0.5.0")
}
```

View File

@@ -9,7 +9,7 @@ EJML based linear algebra implementation.
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-ejml:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-ejml:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -19,6 +19,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-ejml:0.4.2")
implementation("space.kscience:kmath-ejml:0.5.0")
}
```

View File

@@ -9,7 +9,7 @@ Specialization of KMath APIs for Double numbers.
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-for-real:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-for-real:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -19,6 +19,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-for-real:0.4.2")
implementation("space.kscience:kmath-for-real:0.5.0")
}
```

View File

@@ -11,7 +11,7 @@ Functions and interpolations.
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-functions:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-functions:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -21,6 +21,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-functions:0.4.2")
implementation("space.kscience:kmath-functions:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-geometry:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-geometry:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-geometry:0.4.2")
implementation("space.kscience:kmath-geometry:0.5.0")
}
```

View File

@@ -8,17 +8,18 @@
package space.kscience.kmath.geometry
import space.kscience.kmath.operations.Group
import space.kscience.kmath.operations.invoke
/**
* Get a line, containing this [LineSegment]
*/
context(algebra: Group<V>)
context(group: Group<V>)
public val <V : Any> LineSegment<V>.line: Line<V>
get() = with(algebra) { Line(begin, end - begin) }
get() = Line(begin, group { end - begin })
/**
* Get a length of a line segment
*/
context(algebra: GeometrySpace<V, D>)
context(space: GeometrySpace<V, D>)
public val <V : Any, D : Comparable<D>> LineSegment<V>.length: D
get() = with(algebra) { norm(end - begin) }
get() = space { norm(end - begin) }

View File

@@ -6,7 +6,7 @@
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-histograms:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-histograms:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-histograms:0.4.2")
implementation("space.kscience:kmath-histograms:0.5.0")
}
```

View File

@@ -82,7 +82,7 @@ internal class MultivariateHistogramTest {
assertTrue {
res.bins.count() >= histogram1.bins.count()
}
assertEquals(0.0, res.bins.sumOf { it.binValue.toDouble() })
assertEquals(0.0, res.bins.sumOf { it.binValue })
}
}
}

View File

@@ -6,7 +6,7 @@
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-jupyter:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-jupyter:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-jupyter:0.4.2")
implementation("space.kscience:kmath-jupyter:0.5.0")
}
```

View File

@@ -1,19 +1,25 @@
plugins {
id("space.kscience.gradle.jvm")
id("space.kscience.gradle.mpp")
alias(spclibs.plugins.kotlin.jupyter.api)
}
dependencies {
api(spclibs.kotlinx.html)
api(project(":kmath-ast"))
api(project(":kmath-complex"))
api(project(":kmath-for-real"))
kscience {
jvm()
jvmMain {
api(spclibs.kotlinx.html)
api(project(":kmath-ast"))
api(project(":kmath-complex"))
api(project(":kmath-for-real"))
}
}
readme {
maturity = space.kscience.gradle.Maturity.PROTOTYPE
}
tasks.processJupyterApiResources {
libraryProducers = listOf("space.kscience.kmath.jupyter.KMathJupyter")
kotlinJupyter {
integrations {
producer("space.kscience.kmath.jupyter.KMathJupyter")
}
}

View File

@@ -8,7 +8,7 @@
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-kotlingrad:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-kotlingrad:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -18,6 +18,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-kotlingrad:0.4.2")
implementation("space.kscience:kmath-kotlingrad:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-memory:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-memory:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-memory:0.4.2")
implementation("space.kscience:kmath-memory:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@ JetBrains Multik connector
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-multik:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-multik:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-multik:0.4.2")
implementation("space.kscience:kmath-multik:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@ Ojalgo bindings for kmath
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-ojalgo:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-ojalgo:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-ojalgo:0.4.2")
implementation("space.kscience:kmath-ojalgo:0.5.0")
}
```

View File

@@ -5,6 +5,7 @@
package space.kscience.kmath.ojalgo
import org.ojalgo.matrix.decomposition.MatrixDecomposition
import org.ojalgo.matrix.store.MatrixStore
import org.ojalgo.matrix.store.PhysicalStore
import space.kscience.kmath.UnstableKMathAPI
@@ -34,6 +35,13 @@ public value class OjalgoMatrix<T : Comparable<T>>(public val ojalgoVector: Matr
override fun get(i: Int, j: Int): T = ojalgoVector.get(i.toLong(), j.toLong())
}
/**
* Decompose matrix and throw exception if decomposition failed
*/
private fun <T: Comparable<T>, D: MatrixDecomposition<T>> D.decomposeOrFail(matrix: MatrixStore<T>): D = apply {
if(!decompose(matrix)) error("Matrix decomposition failed")
}
public class OjalgoLinearSpace<T : Comparable<T>, A : Ring<T>>(
public val ojalgo: Ojalgo<T, A>
@@ -97,13 +105,13 @@ public class OjalgoLinearSpace<T : Comparable<T>, A : Ring<T>>(
val origin = structure.toOjalgo()
val raw: Any? = when (attribute) {
Determinant -> ojalgo.lu.make(origin).apply { decompose(origin) }.determinant
Determinant -> ojalgo.lu.make(origin).decomposeOrFail(origin).determinant
Inverted -> ojalgo.lu.make().apply { decompose(origin) }.inverse.asMatrix()
Inverted -> ojalgo.lu.make().decomposeOrFail(origin).inverse.asMatrix()
LUP -> object : LupDecomposition<T> {
val lup by lazy {
ojalgo.lu.make(origin).apply { decompose(origin) }
ojalgo.lu.make(origin).decomposeOrFail(origin)
}
override val pivot: IntBuffer get() = lup.pivotOrder.asBuffer()
override val l: Matrix<T> get() = lup.l.asMatrix().withAttribute(LowerTriangular)
@@ -112,14 +120,14 @@ public class OjalgoLinearSpace<T : Comparable<T>, A : Ring<T>>(
Cholesky -> object : CholeskyDecomposition<T> {
val cholesky by lazy {
ojalgo.cholesky.make(origin).apply { decompose(origin) }
ojalgo.cholesky.make(origin).decomposeOrFail(origin)
}
override val l: Matrix<T> get() = cholesky.l.asMatrix()
}
QR -> object : QRDecomposition<T> {
val qr by lazy {
ojalgo.qr.make(origin).apply { decompose(origin) }
ojalgo.qr.make(origin).decomposeOrFail(origin)
}
override val q: Matrix<T> get() = qr.q.asMatrix().withAttribute(OrthogonalAttribute)
override val r: Matrix<T> get() = qr.r.asMatrix().withAttribute(UpperTriangular)
@@ -127,7 +135,7 @@ public class OjalgoLinearSpace<T : Comparable<T>, A : Ring<T>>(
SVD -> object : SingularValueDecomposition<T> {
val svd by lazy {
ojalgo.svd.make(origin).apply { decompose(origin) }
ojalgo.svd.make(origin).decomposeOrFail(origin)
}
override val u: Matrix<T> get() = svd.u.asMatrix()
@@ -141,7 +149,7 @@ public class OjalgoLinearSpace<T : Comparable<T>, A : Ring<T>>(
EIG -> object : EigenDecomposition<T> {
val eigen by lazy {
ojalgo.eigen.make(origin).apply { decompose(origin) }
ojalgo.eigen.make(origin).decomposeOrFail(origin)
}
override val v: Matrix<T> get() = eigen.v.asMatrix()

View File

@@ -13,6 +13,7 @@ import space.kscience.kmath.nd.StructureND
import space.kscience.kmath.structures.Float64
import space.kscience.kmath.testutils.assertStructureEquals
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertTrue
@@ -22,14 +23,14 @@ import kotlin.test.assertTrue
class OjalgoMatrixTest {
@Test
fun testTranspose() = with(Ojalgo.Companion.R064.linearSpace) {
fun testTranspose() = with(Ojalgo.R064.linearSpace) {
val matrix = one(3, 3)
val transposed = matrix.transposed()
assertTrue { StructureND.Companion.contentEquals(matrix, transposed) }
}
@Test
fun testBuilder() = Ojalgo.Companion.R064.linearSpace {
fun testBuilder() = Ojalgo.R064.linearSpace {
val matrix = MatrixBuilder(2, 3).fill(
1.0, 0.0, 0.0,
0.0, 1.0, 2.0
@@ -39,7 +40,7 @@ class OjalgoMatrixTest {
}
@Test
fun testMatrixExtension() = with(Ojalgo.Companion.R064.linearSpace) {
fun testMatrixExtension() = with(Ojalgo.R064.linearSpace) {
val transitionMatrix: Matrix<Float64> = VirtualMatrix(6, 6) { row, col ->
when {
col == 0 -> .50
@@ -61,7 +62,7 @@ class OjalgoMatrixTest {
}
@Test
fun test2DDot() = with(Ojalgo.Companion.R064.linearSpace) {
fun test2DDot() = with(Ojalgo.R064.linearSpace) {
val firstMatrix = buildMatrix(2, 3) { i, j -> (i + j).toDouble() }
val secondMatrix = buildMatrix(3, 2) { i, j -> (i + j).toDouble() }
@@ -76,7 +77,7 @@ class OjalgoMatrixTest {
}
@Test
fun testCholesky() = with(Ojalgo.Companion.R064.linearSpace) {
fun testCholesky() = with(Ojalgo.R064.linearSpace) {
val l = MatrixBuilder(4, 4).fill(
1.0, 0.0, 0.0, 0.0,
1.0, 1.0, 0.0, 0.0,
@@ -90,4 +91,18 @@ class OjalgoMatrixTest {
assertStructureEquals(l, chol!!.l, 1e-4)
}
@Test
fun testCholeskyNonPositive(): Unit = with(Ojalgo.R064.linearSpace) {
val matrix = MatrixBuilder(2, 2).fill(
1.0, 0.0,
0.0, -1.0,
)
assertFailsWith<IllegalStateException> {
computeAttribute(matrix, Cholesky)!!.l
}
}
}

View File

@@ -6,7 +6,7 @@
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-optimization:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-optimization:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-optimization:0.4.2")
implementation("space.kscience:kmath-optimization:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-stat:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-stat:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-stat:0.4.2")
implementation("space.kscience:kmath-stat:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@ Symja integration module
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-symja:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-symja:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-symja:0.4.2")
implementation("space.kscience:kmath-symja:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@ Google tensorflow connector
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-tensorflow:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-tensorflow:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-tensorflow:0.4.2")
implementation("space.kscience:kmath-tensorflow:0.5.0")
}
```

View File

@@ -1,13 +1,20 @@
plugins {
id("space.kscience.gradle.jvm")
id("space.kscience.gradle.mpp")
}
description = "Google tensorflow connector"
dependencies {
api(projects.kmathTensors)
api(libs.tensorflow.core.api)
testImplementation(libs.tensorflow.core.platform)
kscience {
jvm()
jvmMain {
api(projects.kmathTensors)
api(libs.tensorflow.core.api)
}
jvmTest {
implementation(libs.tensorflow.core.platform)
}
}
readme {

View File

@@ -9,7 +9,7 @@ Common linear algebra operations on tensors.
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-tensors:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-tensors:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -19,6 +19,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-tensors:0.4.2")
implementation("space.kscience:kmath-tensors:0.5.0")
}
```

View File

@@ -6,7 +6,7 @@ Binding for https://github.com/JetBrains-Research/viktor
## Artifact:
The Maven coordinates of this project are `space.kscience:kmath-viktor:0.4.2`.
The Maven coordinates of this project are `space.kscience:kmath-viktor:0.5.0`.
**Gradle Kotlin DSL:**
```kotlin
@@ -16,6 +16,6 @@ repositories {
}
dependencies {
implementation("space.kscience:kmath-viktor:0.4.2")
implementation("space.kscience:kmath-viktor:0.5.0")
}
```