diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
deleted file mode 100644
index 7273b6a50..000000000
--- a/.github/CODEOWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-@altavir
-
-/kmath-trajectory @ESchouten
\ No newline at end of file
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index 6ad294e18..000000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-name: Gradle build
-
-on:
- push:
- branches: [ dev, master ]
- pull_request:
-
-jobs:
- build:
- runs-on: windows-latest
- timeout-minutes: 20
- steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-java@v3.5.1
- with:
- java-version: '11'
- 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
- with:
- arguments: test jvmTest
diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
new file mode 100644
index 000000000..adc74adfe
--- /dev/null
+++ b/.github/workflows/gradle.yml
@@ -0,0 +1,17 @@
+name: Gradle build
+
+on: [push]
+
+jobs:
+ build:
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v1
+ - name: Set up JDK 11
+ uses: actions/setup-java@v1
+ with:
+ java-version: 11
+ - name: Build with Gradle
+ run: ./gradlew build
diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
deleted file mode 100644
index ba1f5d1e3..000000000
--- a/.github/workflows/pages.yml
+++ /dev/null
@@ -1,31 +0,0 @@
-name: Dokka publication
-
-on:
- workflow_dispatch:
- release:
- types: [ created ]
-
-jobs:
- build:
- runs-on: ubuntu-20.04
- timeout-minutes: 40
- steps:
- - uses: actions/checkout@v3.0.0
- - uses: actions/setup-java@v3.0.0
- with:
- java-version: 11
- distribution: liberica
- - name: Cache konan
- uses: actions/cache@v3.0.1
- with:
- path: ~/.konan
- key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
- restore-keys: |
- ${{ runner.os }}-gradle-
- - uses: gradle/gradle-build-action@v2.4.2
- with:
- arguments: dokkaHtmlMultiModule --no-parallel
- - uses: JamesIves/github-pages-deploy-action@v4.3.0
- with:
- branch: gh-pages
- folder: build/dokka/htmlMultiModule
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
deleted file mode 100644
index 31d539cdd..000000000
--- a/.github/workflows/publish.yml
+++ /dev/null
@@ -1,50 +0,0 @@
-name: Gradle publish
-
-on:
- workflow_dispatch:
- release:
- types: [ created ]
-
-jobs:
- publish:
- environment:
- name: publish
- strategy:
- matrix:
- os: [ macOS-latest, windows-latest ]
- runs-on: ${{matrix.os}}
- steps:
- - uses: actions/checkout@v3.0.0
- - uses: actions/setup-java@v3.10.0
- with:
- java-version: 11
- distribution: liberica
- - name: Cache konan
- uses: actions/cache@v3.0.1
- with:
- path: ~/.konan
- key: ${{ runner.os }}-gradle-${{ hashFiles('*.gradle.kts') }}
- restore-keys: |
- ${{ runner.os }}-gradle-
- - name: Publish Windows Artifacts
- if: matrix.os == 'windows-latest'
- uses: gradle/gradle-build-action@v2.4.2
- with:
- arguments: |
- publishAllPublicationsToSpaceRepository
- -Ppublishing.targets=all
- -Ppublishing.space.user=${{ secrets.SPACE_APP_ID }}
- -Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }}
- - name: Publish Mac Artifacts
- if: matrix.os == 'macOS-latest'
- uses: gradle/gradle-build-action@v2.4.2
- with:
- arguments: |
- publishMacosX64PublicationToSpaceRepository
- publishMacosArm64PublicationToSpaceRepository
- publishIosX64PublicationToSpaceRepository
- publishIosArm64PublicationToSpaceRepository
- publishIosSimulatorArm64PublicationToSpaceRepository
- -Ppublishing.targets=all
- -Ppublishing.space.user=${{ secrets.SPACE_APP_ID }}
- -Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }}
diff --git a/.gitignore b/.gitignore
index 96a556ae1..a9294eff9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,11 +1,7 @@
.gradle
build/
out/
-
.idea/
-.vscode/
-.fleet/
-
# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar
@@ -13,11 +9,4 @@ out/
# Cache of project
.gradletasknamecache
-# Generated by javac -h and runtime
-*.class
-*.log
-
-!/.idea/copyright/
-!/.idea/scopes/
-/gradle/yarn.lock
-
+gradle.properties
\ No newline at end of file
diff --git a/.idea/copyright/kmath.xml b/.idea/copyright/kmath.xml
deleted file mode 100644
index 840e0c87c..000000000
--- a/.idea/copyright/kmath.xml
+++ /dev/null
@@ -1,7 +0,0 @@
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index 1c10bd6f5..000000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/scopes/Apply_copyright.xml b/.idea/scopes/Apply_copyright.xml
deleted file mode 100644
index a2575f774..000000000
--- a/.idea/scopes/Apply_copyright.xml
+++ /dev/null
@@ -1,3 +0,0 @@
-
-
-
\ No newline at end of file
diff --git a/.space.kts b/.space.kts
deleted file mode 100644
index ce52a2f5c..000000000
--- a/.space.kts
+++ /dev/null
@@ -1,48 +0,0 @@
-import kotlin.io.path.readText
-
-val projectName = "kmath"
-
-job("Build") {
- //Perform only jvm tests
- gradlew("spc.registry.jetbrains.space/p/sci/containers/kotlin-ci:1.0.3", "test", "jvmTest")
-}
-
-job("Publish") {
- startOn {
- gitPush { enabled = false }
- }
- container("spc.registry.jetbrains.space/p/sci/containers/kotlin-ci:1.0.3") {
- env["SPACE_USER"] = "{{ project:space_user }}"
- env["SPACE_TOKEN"] = "{{ project:space_token }}"
- kotlinScript { api ->
-
- val spaceUser = System.getenv("SPACE_USER")
- val spaceToken = System.getenv("SPACE_TOKEN")
-
- // write the version to the build directory
- api.gradlew("version")
-
- //read the version from build file
- val version = java.nio.file.Path.of("build/project-version.txt").readText()
-
- val revisionSuffix = if (version.endsWith("SNAPSHOT")) {
- "-" + api.gitRevision().take(7)
- } else {
- ""
- }
-
- api.space().projects.automation.deployments.start(
- project = api.projectIdentifier(),
- targetIdentifier = TargetIdentifier.Key(projectName),
- version = version+revisionSuffix,
- // automatically update deployment status based on the status of a job
- syncWithAutomationJob = true
- )
- api.gradlew(
- "publishAllPublicationsToSpaceRepository",
- "-Ppublishing.space.user=\"$spaceUser\"",
- "-Ppublishing.space.token=\"$spaceToken\"",
- )
- }
- }
-}
\ No newline at end of file
diff --git a/.space/CODEOWNERS b/.space/CODEOWNERS
deleted file mode 100644
index e69de29bb..000000000
diff --git a/CHANGELOG.md b/CHANGELOG.md
deleted file mode 100644
index 27b67a4d8..000000000
--- a/CHANGELOG.md
+++ /dev/null
@@ -1,217 +0,0 @@
-# KMath
-
-## Unreleased
-
-### Added
-- Integer division algebras
-- Float32 geometries
-
-### Changed
-- Default naming for algebra and buffers now uses IntXX/FloatXX notation instead of Java types.
-- Remove unnecessary inlines in basic algebras.
-- QuaternionField -> QuaternionAlgebra and does not implement `Field` anymore since it is non-commutative
-- kmath-geometry is split into `euclidean2d` and `euclidean3d`
-
-### Deprecated
-
-### Removed
-
-### Fixed
-- Median statistics
-
-### Security
-
-## 0.3.1 - 2023-04-09
-
-### Added
-- Wasm support for `memory`, `core`, `complex` and `functions` modules.
-- Generic builders for `BufferND` and `MutableBufferND`
-- `NamedMatrix` - matrix with symbol-based indexing
-- `Expression` with default arguments
-- Type-aliases for numbers like `Float64`
-- Autodiff for generic algebra elements in core!
-- Algebra now has an obligatory `bufferFactory` (#477).
-
-### Changed
-- Geometry uses type-safe angles
-- Tensor operations switched to prefix notation
-- Row-wise and column-wise ND shapes in the core
-- Shape is read-only
-- Major refactor of tensors (only minor API changes)
-- Kotlin 1.8.20
-- `LazyStructure` `deffered` -> `async` to comply with coroutines code style
-- Default `dot` operation in tensor algebra no longer support broadcasting. Instead `matmul` operation is added to `DoubleTensorAlgebra`.
-- Multik went MPP
-
-### Removed
-- Trajectory moved to https://github.com/SciProgCentre/maps-kt
-- Polynomials moved to https://github.com/SciProgCentre/kmath-polynomial
-
-## 0.3.0
-
-### Added
-- `ScaleOperations` interface
-- `Field` extends `ScaleOperations`
-- Basic integration API
-- Basic MPP distributions and samplers
-- `bindSymbolOrNull`
-- Blocking chains and Statistics
-- Multiplatform integration
-- Integration for any Field element
-- Extended operations for ND4J fields
-- Jupyter Notebook integration module (kmath-jupyter)
-- `@PerformancePitfall` annotation to mark possibly slow API
-- Unified architecture for Integration and Optimization using features.
-- `BigInt` operation performance improvement and fixes by @zhelenskiy (#328)
-- Integration between `MST` and Symja `IExpr`
-- Complex power
-- Separate methods for UInt, Int and Number powers. NaN safety.
-- Tensorflow prototype
-- `ValueAndErrorField`
-- MST compilation to WASM: #286
-- Jafama integration: #176
-- `contentEquals` with tolerance: #364
-- Compilation to TeX for MST: #254
-
-### Changed
-- Annotations moved to `space.kscience.kmath`
-- Exponential operations merged with hyperbolic functions
-- Space is replaced by Group. Space is reserved for vector spaces.
-- VectorSpace is now a vector space
-- Buffer factories for primitives moved to MutableBuffer.Companion
-- Rename `NDStructure` and `NDAlgebra` to `StructureND` and `AlgebraND` respectively
-- `Real` -> `Double`
-- DataSets are moved from functions to core
-- Redesign advanced Chain API
-- Redesign `MST`. Remove `MstExpression`.
-- Move `MST` to core
-- Separated benchmarks and examples
-- Rewrite `kmath-ejml` without `ejml-simple` artifact, support sparse matrices
-- Promote stability of kmath-ast and kmath-kotlingrad to EXPERIMENTAL.
-- ColumnarData returns nullable column
-- `MST` is made sealed interface
-- Replace `MST.Symbolic` by `Symbol`, `Symbol` now implements MST
-- Remove Any restriction on polynomials
-- Add `out` variance to type parameters of `StructureND` and its implementations where possible
-- Rename `DifferentiableMstExpression` to `KotlingradExpression`
-- `FeatureSet` now accepts only `Feature`. It is possible to override keys and use interfaces.
-- Use `Symbol` factory function instead of `StringSymbol`
-- New discoverability pattern: `.algebra.`
-- Adjusted commons-math API for linear solvers to match conventions.
-- Buffer algebra does not require size anymore
-- Operations -> Ops
-- Default Buffer and ND algebras are now Ops and lack neutral elements (0, 1) as well as algebra-level shapes.
-- Tensor algebra takes read-only structures as input and inherits AlgebraND
-- `UnivariateDistribution` renamed to `Distribution1D`
-- Rework of histograms.
-- `UnivariateFunction` -> `Function1D`, `MultivariateFunction` -> `FunctionND`
-
-### Deprecated
-- Specialized `DoubleBufferAlgebra`
-
-### Removed
-- Nearest in Domain. To be implemented in geometry package.
-- Number multiplication and division in main Algebra chain
-- `contentEquals` from Buffer. It moved to the companion.
-- MSTExpression
-- Expression algebra builders
-- Complex and Quaternion no longer are elements.
-- Second generic from DifferentiableExpression
-- Algebra elements are completely removed. Use algebra contexts instead.
-
-### Fixed
-- Ring inherits RingOperations, not GroupOperations
-- Univariate histogram filling
-
-## 0.2.0
-
-### Added
-- `fun` annotation for SAM interfaces in library
-- Explicit `public` visibility for all public APIs
-- Better trigonometric and hyperbolic functions for `AutoDiffField` (https://github.com/mipt-npm/kmath/pull/140)
-- Automatic README generation for features (#139)
-- Native support for `memory`, `core` and `dimensions`
-- `kmath-ejml` to supply EJML SimpleMatrix wrapper (https://github.com/mipt-npm/kmath/pull/136)
-- A separate `Symbol` entity, which is used for global unbound symbol.
-- A `Symbol` indexing scope.
-- Basic optimization API for Commons-math.
-- Chi squared optimization for array-like data in CM
-- `Fitting` utility object in prob/stat
-- ND4J support module submitting `NDStructure` and `NDAlgebra` over `INDArray`
-- Coroutine-deterministic Monte-Carlo scope with a random number generator
-- Some minor utilities to `kmath-for-real`
-- Generic operation result parameter to `MatrixContext`
-- New `MatrixFeature` interfaces for matrix decompositions
-- Basic Quaternion vector support in `kmath-complex`.
-
-### Changed
-- Package changed from `scientifik` to `space.kscience`
-- Gradle version: 6.6 -> 6.8.2
-- Minor exceptions refactor (throwing `IllegalArgumentException` by argument checks instead of `IllegalStateException`)
-- `Polynomial` secondary constructor made function
-- Kotlin version: 1.3.72 -> 1.4.30
-- `kmath-ast` doesn't depend on heavy `kotlin-reflect` library
-- Full autodiff refactoring based on `Symbol`
-- `kmath-prob` renamed to `kmath-stat`
-- Grid generators moved to `kmath-for-real`
-- Use `Point` instead of specialized type in `kmath-for-real`
-- Optimized dot product for buffer matrices moved to `kmath-for-real`
-- EjmlMatrix context is an object
-- Matrix LUP `inverse` renamed to `inverseWithLup`
-- `NumericAlgebra` moved outside of regular algebra chain (`Ring` no longer implements it).
-- Features moved to NDStructure and became transparent.
-- Capitalization of LUP in many names changed to Lup.
-- Refactored `NDStructure` algebra to be more simple, preferring under-the-hood conversion to explicit NDStructure types
-- Refactor histograms. They are marked as prototype
-- `Complex` and related features moved to a separate module `kmath-complex`
-- Refactor AlgebraElement
-- `symbol` method in `Algebra` renamed to `bindSymbol` to avoid ambiguity
-- Add `out` projection to `Buffer` generic
-
-### Removed
-- `kmath-koma` module because it doesn't support Kotlin 1.4.
-- Support of `legacy` JS backend (we will support only IR)
-- `toGrid` method.
-- Public visibility of `BufferAccessor2D`
-- `Real` class
-- StructureND identity and equals
-
-### Fixed
-- `symbol` method in `MstExtendedField` (https://github.com/mipt-npm/kmath/pull/140)
-
-## 0.1.4
-
-### Added
-- Functional Expressions API
-- Mathematical Syntax Tree, its interpreter and API
-- String to MST parser (https://github.com/mipt-npm/kmath/pull/120)
-- MST to JVM bytecode translator (https://github.com/mipt-npm/kmath/pull/94)
-- FloatBuffer (specialized MutableBuffer over FloatArray)
-- FlaggedBuffer to associate primitive numbers buffer with flags (to mark values infinite or missing, etc.)
-- Specialized builder functions for all primitive buffers like `IntBuffer(25) { it + 1 }` (https://github.com/mipt-npm/kmath/pull/125)
-- Interface `NumericAlgebra` where `number` operation is available to convert numbers to algebraic elements
-- Inverse trigonometric functions support in ExtendedField (`asin`, `acos`, `atan`) (https://github.com/mipt-npm/kmath/pull/114)
-- New space extensions: `average` and `averageWith`
-- Local coding conventions
-- Geometric Domains API in `kmath-core`
-- Blocking chains in `kmath-coroutines`
-- Full hyperbolic functions support and default implementations within `ExtendedField`
-- Norm support for `Complex`
-
-### Changed
-- `readAsMemory` now has `throws IOException` in JVM signature.
-- Several functions taking functional types were made `inline`.
-- Several functions taking functional types now have `callsInPlace` contracts.
-- BigInteger and BigDecimal algebra: JBigDecimalField has companion object with default math context; minor optimizations
-- `power(T, Int)` extension function has preconditions and supports `Field`
-- Memory objects have more preconditions (overflow checking)
-- `tg` function is renamed to `tan` (https://github.com/mipt-npm/kmath/pull/114)
-- Gradle version: 6.3 -> 6.6
-- Moved probability distributions to commons-rng and to `kmath-prob`
-
-### Fixed
-- Missing copy method in Memory implementation on JS (https://github.com/mipt-npm/kmath/pull/106)
-- D3.dim value in `kmath-dimensions`
-- Multiplication in integer rings in `kmath-core` (https://github.com/mipt-npm/kmath/pull/101)
-- Commons RNG compatibility (https://github.com/mipt-npm/kmath/issues/93)
-- Multiplication of BigInt by scalar
diff --git a/license/LICENSE.txt b/LICENSE
similarity index 99%
rename from license/LICENSE.txt
rename to LICENSE
index d64569567..261eeb9e9 100644
--- a/license/LICENSE.txt
+++ b/LICENSE
@@ -1,4 +1,3 @@
-
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
diff --git a/README.md b/README.md
index 7c1f759c1..34761e838 100644
--- a/README.md
+++ b/README.md
@@ -1,300 +1,104 @@
[![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
[![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/spc/p/sci/maven/space/kscience/)
+
+![Gradle build](https://github.com/mipt-npm/kmath/workflows/Gradle%20build/badge.svg)
+
+Bintray: [ ![Download](https://api.bintray.com/packages/mipt-npm/scientifik/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/scientifik/kmath-core/_latestVersion)
+
+Bintray-dev: [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/scientifik/kmath-core/_latestVersion)
# 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.
-
-[Documentation site (**WIP**)](https://SciProgCentre.github.io/kmath/)
-
-## Publications and talks
-
-* [A conceptual article about context-oriented design](https://proandroiddev.com/an-introduction-context-oriented-programming-in-kotlin-2e79d316b0a2)
-* [Another article about context-oriented design](https://proandroiddev.com/diving-deeper-into-context-oriented-programming-in-kotlin-3ecb4ec38814)
-* [ACAT 2019 conference paper](https://aip.scitation.org/doi/abs/10.1063/1.5130103)
+Could be pronounced as `key-math`.
+The Kotlin MATHematics library is intended as a Kotlin-based analog to Python's `numpy` library. In contrast to `numpy` and `scipy` it is modular and has a lightweight core.
# Goal
-
-* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM, JS and Native)
- .
+* Provide a flexible and powerful API to work with mathematics abstractions in Kotlin-multiplatform (JVM and JS for now and Native in future).
* Provide basic multiplatform implementations for those abstractions (without significant performance optimization).
* Provide bindings and wrappers with those abstractions for popular optimized platform libraries.
## Non-goals
-
-* 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.
+* Be like Numpy. It was the idea at the beginning, but we decided that we can do better in terms of API.
+* Provide 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 `Double` in the core. For that we will have specialization modules like `for-real`, which will give better experience for those, who want to work with specific types.
-## Features and stability
+## Features
-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:
+Actual feature list is [here](doc/features.md)
-* **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.
-* **EXPERIMENTAL**. The general API is decided, but some changes could be made. Volatile API is marked
- 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.
-* **STABLE**. The API stabilized. Breaking changes are allowed only in major releases.
+* **Algebra**
+ * Algebraic structures like rings, spaces and field (**TODO** add example to wiki)
+ * Basic linear algebra operations (sums, products, etc.), backed by the `Space` API.
+ * Complex numbers backed by the `Field` API (meaning that they will be usable in any structure like vectors and N-dimensional arrays).
+ * Advanced linear algebra operations like matrix inversion and LU decomposition.
-## Modules
+* **Array-like structures** Full support of many-dimensional array-like structures
+including mixed arithmetic operations and function operations over arrays and numbers (with the added benefit of static type checking).
+* **Expressions** 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.
-### [benchmarks](benchmarks)
->
->
-> **Maturity**: EXPERIMENTAL
+* **Histograms** Fast multi-dimensional histograms.
-### [examples](examples)
->
->
-> **Maturity**: EXPERIMENTAL
+* **Streaming** Streaming operations on mathematical objects and objects buffers.
-### [kmath-ast](kmath-ast)
->
->
-> **Maturity**: EXPERIMENTAL
->
-> **Features:**
-> - [expression-language](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/parser.kt) : Expression language and its parser
-> - [mst-jvm-codegen](kmath-ast/src/jvmMain/kotlin/space/kscience/kmath/asm/asm.kt) : Dynamic MST to JVM bytecode compiler
-> - [mst-js-codegen](kmath-ast/src/jsMain/kotlin/space/kscience/kmath/estree/estree.kt) : Dynamic MST to JS compiler
-> - [rendering](kmath-ast/src/commonMain/kotlin/space/kscience/kmath/ast/rendering/MathRenderer.kt) : Extendable MST rendering
+* **Type-safe dimensions** Type-safe dimensions for matrix operations.
+* **Commons-math wrapper** It is planned to gradually wrap most parts of [Apache commons-math](http://commons.apache.org/proper/commons-math/)
+ library in Kotlin code and maybe rewrite some parts to better suit the Kotlin programming paradigm, however there is no fixed roadmap for that. Feel free
+ to submit a feature request if you want something to be done first.
+
+* **Koma wrapper** [Koma](https://github.com/kyonifer/koma) is a well established numerics library in Kotlin, specifically linear algebra.
+The plan is to have wrappers for koma implementations for compatibility with kmath API.
-### [kmath-commons](kmath-commons)
->
->
-> **Maturity**: EXPERIMENTAL
+## Planned features
-### [kmath-complex](kmath-complex)
-> Complex numbers and quaternions.
->
-> **Maturity**: PROTOTYPE
->
-> **Features:**
-> - [complex](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Complex.kt) : Complex numbers operations
-> - [quaternion](kmath-complex/src/commonMain/kotlin/space/kscience/kmath/complex/Quaternion.kt) : Quaternions and their composition
+* **Messaging** A mathematical notation to support multi-language and multi-node communication for mathematical tasks.
+* **Array statistics**
-### [kmath-core](kmath-core)
-> Core classes, algebra definitions, basic linear algebra
->
-> **Maturity**: DEVELOPMENT
->
-> **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.
-> - [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
-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.
-> - [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
+* **Integration** Univariate and multivariate integration framework.
+* **Probability and distributions**
-### [kmath-coroutines](kmath-coroutines)
->
->
-> **Maturity**: EXPERIMENTAL
-
-### [kmath-dimensions](kmath-dimensions)
->
->
-> **Maturity**: PROTOTYPE
-
-### [kmath-ejml](kmath-ejml)
->
->
-> **Maturity**: PROTOTYPE
->
-> **Features:**
-> - [ejml-vector](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlVector.kt) : Point implementations.
-> - [ejml-matrix](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlMatrix.kt) : Matrix implementation.
-> - [ejml-linear-space](kmath-ejml/src/main/kotlin/space/kscience/kmath/ejml/EjmlLinearSpace.kt) : LinearSpace implementations.
-
-
-### [kmath-for-real](kmath-for-real)
-> Extension module that should be used to achieve numpy-like behavior.
-All operations are specialized to work with `Double` numbers without declaring algebraic contexts.
-One can still use generic algebras though.
->
-> **Maturity**: EXPERIMENTAL
->
-> **Features:**
-> - [DoubleVector](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleVector.kt) : Numpy-like operations for Buffers/Points
-> - [DoubleMatrix](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/real/DoubleMatrix.kt) : Numpy-like operations for 2d real structures
-> - [grids](kmath-for-real/src/commonMain/kotlin/space/kscience/kmath/structures/grids.kt) : Uniform grid generators
-
-
-### [kmath-functions](kmath-functions)
->
->
-> **Maturity**: EXPERIMENTAL
->
-> **Features:**
-> - [piecewise](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Piecewise.kt) : Piecewise functions.
-> - [polynomials](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/functions/Polynomial.kt) : Polynomial functions.
-> - [linear interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/LinearInterpolator.kt) : Linear XY interpolator.
-> - [spline interpolation](kmath-functions/src/commonMain/kotlin/space/kscience/kmath/interpolation/SplineInterpolator.kt) : Cubic spline XY interpolator.
-> - [integration](kmath-functions/#) : Univariate and multivariate quadratures
-
-
-### [kmath-geometry](kmath-geometry)
->
->
-> **Maturity**: PROTOTYPE
-
-### [kmath-histograms](kmath-histograms)
->
->
-> **Maturity**: PROTOTYPE
-
-### [kmath-jafama](kmath-jafama)
->
->
-> **Maturity**: PROTOTYPE
->
-> **Features:**
-> - [jafama-double](kmath-jafama/src/main/kotlin/space/kscience/kmath/jafama/) : Double ExtendedField implementations based on Jafama
-
-
-### [kmath-jupyter](kmath-jupyter)
->
->
-> **Maturity**: PROTOTYPE
-
-### [kmath-kotlingrad](kmath-kotlingrad)
->
->
-> **Maturity**: EXPERIMENTAL
->
-> **Features:**
-> - [differentiable-mst-expression](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/KotlingradExpression.kt) : MST based DifferentiableExpression.
-> - [scalars-adapters](kmath-kotlingrad/src/main/kotlin/space/kscience/kmath/kotlingrad/scalarsAdapters.kt) : Conversions between Kotlin∇'s SFun and MST
-
-
-### [kmath-memory](kmath-memory)
-> An API and basic implementation for arranging objects in a continuous memory block.
->
-> **Maturity**: DEVELOPMENT
-
-### [kmath-multik](kmath-multik)
->
->
-> **Maturity**: PROTOTYPE
-
-### [kmath-nd4j](kmath-nd4j)
->
->
-> **Maturity**: EXPERIMENTAL
->
-> **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-optimization](kmath-optimization)
->
->
-> **Maturity**: EXPERIMENTAL
-
-### [kmath-stat](kmath-stat)
->
->
-> **Maturity**: EXPERIMENTAL
-
-### [kmath-symja](kmath-symja)
->
->
-> **Maturity**: PROTOTYPE
-
-### [kmath-tensorflow](kmath-tensorflow)
->
->
-> **Maturity**: PROTOTYPE
-
-### [kmath-tensors](kmath-tensors)
->
->
-> **Maturity**: PROTOTYPE
->
-> **Features:**
-> - [tensor algebra](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/TensorAlgebra.kt) : Basic linear algebra operations on tensors (plus, dot, etc.)
-> - [tensor algebra with broadcasting](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/core/BroadcastDoubleTensorAlgebra.kt) : Basic linear algebra operations implemented with broadcasting.
-> - [linear algebra operations](kmath-tensors/src/commonMain/kotlin/space/kscience/kmath/tensors/api/LinearOpsTensorAlgebra.kt) : Advanced linear algebra operations like LU decomposition, SVD, etc.
-
-
-### [kmath-viktor](kmath-viktor)
->
->
-> **Maturity**: DEVELOPMENT
-
-### [test-utils](test-utils)
->
->
-> **Maturity**: EXPERIMENTAL
-
+* **Fitting** Non-linear curve fitting facilities
## 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, the 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 interfaces are declared in the [common module](kmath-core/src/commonMain). Implementation is also done in the common module wherever possible. In some cases, features are delegated to platform-specific implementations even if they could be done in the common module for performance reasons. Currently, the JVM is the main focus of development, however Kotlin/Native and Kotlin/JS contributions are also welcome.
## Performance
-Calculation performance is one of major goals of KMath in the future, but in some cases it is impossible to achieve both
-performance and flexibility.
+Calculation performance is one of major goals of KMath in the future, but in some cases it is not possible to achieve both performance and flexibility. We expect to focus on creating 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.
-We expect to focus on creating 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.
+### Dependency
-## Requirements
-
-KMath currently relies on JDK 11 for compilation and execution of Kotlin-JVM part. We recommend to use GraalVM-CE 11 for
-execution to get better performance.
-
-### 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:
+Release artifacts are accessible from bintray with following configuration (see documentation for [kotlin-multiplatform](https://kotlinlang.org/docs/reference/multiplatform.html) form more details):
```kotlin
-repositories {
- maven("https://repo.kotlin.link")
+repositories{
+ maven("https://dl.bintray.com/mipt-npm/scientifik")
}
-dependencies {
- api("space.kscience:kmath-core:$version")
- // api("space.kscience:kmath-core-jvm:$version") for jvm-specific version
+dependencies{
+ api("scientifik:kmath-core:${kmathVersion}")
+ //api("scientifik:kmath-core-jvm:${kmathVersion}") for jvm-specific version
}
```
-Gradle `6.0+` is required for multiplatform artifacts.
+Gradle `5.2+` is required for multiplatform artifacts.
+
+### Development
+
+Development builds are accessible from the reposirtory
+```kotlin
+repositories{
+ maven("https://dl.bintray.com/mipt-npm/dev")
+}
+```
+with the same artifact names.
## Contributing
-The project requires a lot of additional work. The most important thing we need is a 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 [waiting for a hero](https://github.com/SciProgCentre/kmath/labels/waiting%20for%20a%20hero) label.
\ No newline at end of file
+The project requires a lot of additional work. Please feel free to contribute in any way and propose new features.
diff --git a/benchmarks/README.md b/benchmarks/README.md
deleted file mode 100644
index cd8fbafd3..000000000
--- a/benchmarks/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Module benchmarks
-
-
-
diff --git a/benchmarks/build.gradle.kts b/benchmarks/build.gradle.kts
deleted file mode 100644
index 24471a9e4..000000000
--- a/benchmarks/build.gradle.kts
+++ /dev/null
@@ -1,174 +0,0 @@
-@file:Suppress("UNUSED_VARIABLE")
-
-import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile
-import space.kscience.kmath.benchmarks.addBenchmarkProperties
-
-plugins {
- kotlin("multiplatform")
- alias(spclibs.plugins.kotlin.plugin.allopen)
- id("org.jetbrains.kotlinx.benchmark")
-}
-
-allOpen.annotation("org.openjdk.jmh.annotations.State")
-sourceSets.register("benchmarks")
-
-repositories {
- mavenCentral()
-}
-
-val multikVersion: String by rootProject.extra
-
-kotlin {
- jvm()
-
- js(IR) {
- nodejs()
- }
-
- sourceSets {
- all {
- languageSettings {
- progressiveMode = true
- optIn("kotlin.contracts.ExperimentalContracts")
- optIn("kotlin.ExperimentalUnsignedTypes")
- optIn("space.kscience.kmath.UnstableKMathAPI")
- }
- }
-
- val commonMain by getting {
- dependencies {
- implementation(project(":kmath-ast"))
- implementation(project(":kmath-core"))
- implementation(project(":kmath-coroutines"))
- implementation(project(":kmath-complex"))
- implementation(project(":kmath-stat"))
- implementation(project(":kmath-dimensions"))
- implementation(project(":kmath-for-real"))
- implementation(project(":kmath-tensors"))
- implementation(project(":kmath-multik"))
- implementation("org.jetbrains.kotlinx:multik-default:$multikVersion")
- implementation(spclibs.kotlinx.benchmark.runtime)
- }
- }
-
- val jvmMain by getting {
- dependencies {
- implementation(project(":kmath-commons"))
- implementation(project(":kmath-ejml"))
- implementation(project(":kmath-nd4j"))
- implementation(project(":kmath-kotlingrad"))
- implementation(project(":kmath-viktor"))
- implementation(project(":kmath-jafama"))
- implementation(projects.kmath.kmathTensorflow)
- implementation("org.tensorflow:tensorflow-core-platform:0.4.0")
- implementation("org.nd4j:nd4j-native:1.0.0-M1")
- // uncomment if your system supports AVX2
- // val os = System.getProperty("os.name")
- //
- // if (System.getProperty("os.arch") in arrayOf("x86_64", "amd64")) when {
- // os.startsWith("Windows") -> implementation("org.nd4j:nd4j-native:1.0.0-beta7:windows-x86_64-avx2")
- // os == "Linux" -> implementation("org.nd4j:nd4j-native:1.0.0-beta7:linux-x86_64-avx2")
- // os == "Mac OS X" -> implementation("org.nd4j:nd4j-native:1.0.0-beta7:macosx-x86_64-avx2")
- // } else
- // implementation("org.nd4j:nd4j-native-platform:1.0.0-beta7")
- }
- }
- }
-}
-
-// Configure benchmark
-benchmark {
- // Setup configurations
- targets {
- register("jvm")
- register("js")
- }
-
- fun kotlinx.benchmark.gradle.BenchmarkConfiguration.commonConfiguration() {
- warmups = 2
- iterations = 5
- iterationTime = 2000
- iterationTimeUnit = "ms"
- }
-
- configurations.register("buffer") {
- commonConfiguration()
- include("BufferBenchmark")
- }
-
- configurations.register("nd") {
- commonConfiguration()
- include("NDFieldBenchmark")
- }
-
- configurations.register("dot") {
- commonConfiguration()
- include("DotBenchmark")
- }
-
- configurations.register("expressions") {
- // Some extra precision
- warmups = 2
- iterations = 10
- iterationTime = 10
- iterationTimeUnit = "s"
- outputTimeUnit = "s"
- include("ExpressionsInterpretersBenchmark")
- }
-
- configurations.register("matrixInverse") {
- commonConfiguration()
- include("MatrixInverseBenchmark")
- }
-
- configurations.register("bigInt") {
- commonConfiguration()
- include("BigIntBenchmark")
- }
-
- configurations.register("jafamaDouble") {
- commonConfiguration()
- include("JafamaBenchmark")
- }
-
- configurations.register("tensorAlgebra") {
- commonConfiguration()
- include("TensorAlgebraBenchmark")
- }
-
- configurations.register("viktor") {
- commonConfiguration()
- include("ViktorBenchmark")
- }
-
- configurations.register("viktorLog") {
- commonConfiguration()
- include("ViktorLogBenchmark")
- }
-
- configurations.register("integration") {
- commonConfiguration()
- include("IntegrationBenchmark")
- }
-}
-
-kotlin.sourceSets.all {
- with(languageSettings) {
- optIn("kotlin.contracts.ExperimentalContracts")
- optIn("kotlin.ExperimentalUnsignedTypes")
- optIn("space.kscience.kmath.UnstableKMathAPI")
- }
-}
-
-tasks.withType {
- kotlinOptions {
- jvmTarget = "11"
- freeCompilerArgs = freeCompilerArgs + "-Xjvm-default=all" + "-Xlambdas=indy"
- }
-}
-
-readme {
- maturity = space.kscience.gradle.Maturity.EXPERIMENTAL
-}
-
-addBenchmarkProperties()
diff --git a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
deleted file mode 100644
index a3cfce52f..000000000
--- a/benchmarks/src/jsMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
+++ /dev/null
@@ -1,106 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import space.kscience.kmath.UnstableKMathAPI
-import space.kscience.kmath.expressions.*
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.operations.bindSymbol
-import space.kscience.kmath.operations.invoke
-import kotlin.math.sin
-import kotlin.random.Random
-import space.kscience.kmath.estree.compileToExpression as estreeCompileToExpression
-import space.kscience.kmath.wasm.compileToExpression as wasmCompileToExpression
-
-@State(Scope.Benchmark)
-class ExpressionsInterpretersBenchmark {
- /**
- * Benchmark case for [Expression] created with [expressionInExtendedField].
- */
- @Benchmark
- fun functionalExpression(blackhole: Blackhole) = invokeAndSum(functional, blackhole)
-
- /**
- * Benchmark case for [Expression] created with [toExpression].
- */
- @Benchmark
- fun mstExpression(blackhole: Blackhole) = invokeAndSum(mst, blackhole)
-
- /**
- * Benchmark case for [Expression] created with [compileToExpression].
- */
- @Benchmark
- fun wasmExpression(blackhole: Blackhole) = invokeAndSum(wasm, blackhole)
-
- /**
- * Benchmark case for [Expression] created with [compileToExpression].
- */
- @Benchmark
- fun estreeExpression(blackhole: Blackhole) = invokeAndSum(estree, blackhole)
-
- /**
- * Benchmark case for [Expression] implemented manually with `kotlin.math` functions.
- */
- @Benchmark
- fun rawExpression(blackhole: Blackhole) = invokeAndSum(raw, blackhole)
-
- /**
- * Benchmark case for direct computation w/o [Expression].
- */
- @Benchmark
- fun justCalculate(blackhole: Blackhole) {
- val random = Random(0)
- var sum = 0.0
-
- repeat(times) {
- val x = random.nextDouble()
- sum += x * 2.0 + 2.0 / x - 16.0 / sin(x)
- }
-
- blackhole.consume(sum)
- }
-
- private fun invokeAndSum(expr: Expression, blackhole: Blackhole) {
- val random = Random(0)
- var sum = 0.0
- val m = HashMap()
-
- repeat(times) {
- m[x] = random.nextDouble()
- sum += expr(m)
- }
-
- blackhole.consume(sum)
- }
-
- private companion object {
- private val x by symbol
- private const val times = 1_000_000
-
- private val functional = Float64Field.expression {
- val x = bindSymbol(Symbol.x)
- x * number(2.0) + 2.0 / x - 16.0 / sin(x)
- }
-
- private val node = MstExtendedField {
- x * 2.0 + number(2.0) / x - number(16.0) / sin(x)
- }
-
- private val mst = node.toExpression(Float64Field)
- @OptIn(UnstableKMathAPI::class)
- private val wasm = node.wasmCompileToExpression(Float64Field)
- private val estree = node.estreeCompileToExpression(Float64Field)
-
- private val raw = Expression { args ->
- val x = args[x]!!
- x * 2.0 + 2.0 / x - 16.0 / sin(x)
- }
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt
deleted file mode 100644
index abfc8cbf2..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ArrayBenchmark.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import java.nio.IntBuffer
-
-@State(Scope.Benchmark)
-internal class ArrayBenchmark {
- @Benchmark
- fun benchmarkArrayRead(blackhole: Blackhole) {
- var res = 0
- for (i in 1..size) res += array[size - i]
- blackhole.consume(res)
- }
-
- @Benchmark
- fun benchmarkBufferRead(blackhole: Blackhole) {
- var res = 0
- for (i in 1..size) res += arrayBuffer[size - i]
- blackhole.consume(res)
- }
-
- @Benchmark
- fun nativeBufferRead(blackhole: Blackhole) {
- var res = 0
- for (i in 1..size) res += nativeBuffer[size - i]
- blackhole.consume(res)
- }
-
- private companion object {
- private const val size = 1000
- private val array = IntArray(size) { it }
- private val arrayBuffer = IntBuffer.wrap(array)
- private val nativeBuffer = IntBuffer.allocate(size).also { for (i in 0 until size) it.put(i, i) }
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt
deleted file mode 100644
index d07b7b4df..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BigIntBenchmark.kt
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-
-import kotlinx.benchmark.Blackhole
-import org.openjdk.jmh.annotations.Benchmark
-import org.openjdk.jmh.annotations.Scope
-import org.openjdk.jmh.annotations.State
-import space.kscience.kmath.UnstableKMathAPI
-import space.kscience.kmath.operations.BigIntField
-import space.kscience.kmath.operations.JBigIntegerField
-import space.kscience.kmath.operations.invoke
-import space.kscience.kmath.operations.parseBigInteger
-import java.math.BigInteger
-
-
-@UnstableKMathAPI
-@State(Scope.Benchmark)
-internal class BigIntBenchmark {
-
- val kmSmallNumber = BigIntField.number(100)
- val jvmSmallNumber = JBigIntegerField.number(100)
- val kmNumber = BigIntField.number(Int.MAX_VALUE)
- val jvmNumber = JBigIntegerField.number(Int.MAX_VALUE)
- val kmLargeNumber = BigIntField { number(11).pow(100_000U) }
- val jvmLargeNumber: BigInteger = JBigIntegerField { number(11).pow(100_000) }
- val bigExponent = 50_000
-
- @Benchmark
- fun kmSmallAdd(blackhole: Blackhole) = BigIntField {
- blackhole.consume(kmSmallNumber + kmSmallNumber + kmSmallNumber)
- }
-
- @Benchmark
- fun jvmSmallAdd(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume(jvmSmallNumber + jvmSmallNumber + jvmSmallNumber)
- }
-
- @Benchmark
- fun kmAdd(blackhole: Blackhole) = BigIntField {
- blackhole.consume(kmNumber + kmNumber + kmNumber)
- }
-
- @Benchmark
- fun jvmAdd(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume(jvmNumber + jvmNumber + jvmNumber)
- }
-
- @Benchmark
- fun kmAddLarge(blackhole: Blackhole) = BigIntField {
- blackhole.consume(kmLargeNumber + kmLargeNumber + kmLargeNumber)
- }
-
- @Benchmark
- fun jvmAddLarge(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume(jvmLargeNumber + jvmLargeNumber + jvmLargeNumber)
- }
-
- @Benchmark
- fun kmMultiply(blackhole: Blackhole) = BigIntField {
- blackhole.consume(kmNumber * kmNumber * kmNumber)
- }
-
- @Benchmark
- fun kmMultiplyLarge(blackhole: Blackhole) = BigIntField {
- blackhole.consume(kmLargeNumber*kmLargeNumber)
- }
-
- @Benchmark
- fun jvmMultiply(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume(jvmNumber * jvmNumber * jvmNumber)
- }
-
- @Benchmark
- fun jvmMultiplyLarge(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume(jvmLargeNumber*jvmLargeNumber)
- }
-
- @Benchmark
- fun kmPower(blackhole: Blackhole) = BigIntField {
- blackhole.consume(kmNumber.pow(bigExponent.toUInt()))
- }
-
- @Benchmark
- fun jvmPower(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume(jvmNumber.pow(bigExponent))
- }
-
- @Benchmark
- fun kmParsing16(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume("0x7f57ed8b89c29a3b9a85c7a5b84ca3929c7b7488593".parseBigInteger())
- }
-
- @Benchmark
- fun kmParsing10(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume("236656783929183747565738292847574838922010".parseBigInteger())
- }
-
- @Benchmark
- fun jvmParsing10(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume("236656783929183747565738292847574838922010".toBigInteger(10))
- }
-
- @Benchmark
- fun jvmParsing16(blackhole: Blackhole) = JBigIntegerField {
- blackhole.consume("7f57ed8b89c29a3b9a85c7a5b84ca3929c7b7488593".toBigInteger(16))
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt
deleted file mode 100644
index 1675216eb..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/BufferBenchmark.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import space.kscience.kmath.complex.Complex
-import space.kscience.kmath.complex.ComplexField
-import space.kscience.kmath.complex.complex
-import space.kscience.kmath.operations.invoke
-import space.kscience.kmath.structures.Buffer
-import space.kscience.kmath.structures.Float64Buffer
-import space.kscience.kmath.structures.getDouble
-import space.kscience.kmath.structures.permute
-
-@State(Scope.Benchmark)
-internal class BufferBenchmark {
-
- @Benchmark
- fun doubleArrayReadWrite(blackhole: Blackhole) {
- val buffer = DoubleArray(size) { it.toDouble() }
- var res = 0.0
- (0 until size).forEach {
- res += buffer[it]
- }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun doubleBufferReadWrite(blackhole: Blackhole) {
- val buffer = Float64Buffer(size) { it.toDouble() }
- var res = 0.0
- (0 until size).forEach {
- res += buffer[it]
- }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun bufferViewReadWrite(blackhole: Blackhole) {
- val buffer = Float64Buffer(size) { it.toDouble() }.permute(reversedIndices)
- var res = 0.0
- (0 until size).forEach {
- res += buffer[it]
- }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun bufferViewReadWriteSpecialized(blackhole: Blackhole) {
- val buffer = Float64Buffer(size) { it.toDouble() }.permute(reversedIndices)
- var res = 0.0
- (0 until size).forEach {
- res += buffer.getDouble(it)
- }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun complexBufferReadWrite(blackhole: Blackhole) = ComplexField {
- val buffer = Buffer.complex(size / 2) { Complex(it.toDouble(), -it.toDouble()) }
-
- var res = zero
- (0 until size / 2).forEach {
- res += buffer[it]
- }
-
- blackhole.consume(res)
- }
-
- private companion object {
- private const val size = 100
- private val reversedIndices = IntArray(size){it}.apply { reverse() }
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt
deleted file mode 100644
index 5784c32b1..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/DotBenchmark.kt
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import space.kscience.kmath.commons.linear.CMLinearSpace
-import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
-import space.kscience.kmath.linear.invoke
-import space.kscience.kmath.linear.linearSpace
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.operations.invoke
-import space.kscience.kmath.tensorflow.produceWithTF
-import space.kscience.kmath.tensors.core.DoubleTensorAlgebra
-import space.kscience.kmath.tensors.core.tensorAlgebra
-import kotlin.random.Random
-
-@State(Scope.Benchmark)
-internal class DotBenchmark {
- companion object {
- val random = Random(12224)
- const val dim = 1000
-
- //creating invertible matrix
- val matrix1 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ ->
- random.nextDouble()
- }
- val matrix2 = Float64Field.linearSpace.buildMatrix(dim, dim) { _, _ ->
- random.nextDouble()
- }
-
- val cmMatrix1 = CMLinearSpace { matrix1.toCM() }
- val cmMatrix2 = CMLinearSpace { matrix2.toCM() }
-
- val ejmlMatrix1 = EjmlLinearSpaceDDRM { matrix1.toEjml() }
- val ejmlMatrix2 = EjmlLinearSpaceDDRM { matrix2.toEjml() }
- }
-
-
- @Benchmark
- fun tfDot(blackhole: Blackhole) {
- blackhole.consume(
- Float64Field.produceWithTF {
- matrix1 dot matrix1
- }
- )
- }
-
- @Benchmark
- fun cmDotWithConversion(blackhole: Blackhole) = CMLinearSpace {
- blackhole.consume(matrix1 dot matrix2)
- }
-
- @Benchmark
- fun cmDot(blackhole: Blackhole) = CMLinearSpace {
- blackhole.consume(cmMatrix1 dot cmMatrix2)
- }
-
- @Benchmark
- fun ejmlDot(blackhole: Blackhole) = EjmlLinearSpaceDDRM {
- blackhole.consume(ejmlMatrix1 dot ejmlMatrix2)
- }
-
- @Benchmark
- fun ejmlDotWithConversion(blackhole: Blackhole) = EjmlLinearSpaceDDRM {
- blackhole.consume(matrix1 dot matrix2)
- }
-
- @Benchmark
- fun tensorDot(blackhole: Blackhole) = with(Float64Field.tensorAlgebra) {
- blackhole.consume(matrix1 dot matrix2)
- }
-
- @Benchmark
- fun multikDot(blackhole: Blackhole) = with(multikAlgebra) {
- blackhole.consume(matrix1 dot matrix2)
- }
-
- @Benchmark
- fun bufferedDot(blackhole: Blackhole) = with(Float64Field.linearSpace) {
- blackhole.consume(matrix1 dot matrix2)
- }
-
- @Benchmark
- fun doubleDot(blackhole: Blackhole) = with(Float64Field.linearSpace) {
- blackhole.consume(matrix1 dot matrix2)
- }
-
- @Benchmark
- fun doubleTensorDot(blackhole: Blackhole) = DoubleTensorAlgebra.invoke {
- blackhole.consume(matrix1 dot matrix2)
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
deleted file mode 100644
index def90ba22..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ExpressionsInterpretersBenchmark.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import space.kscience.kmath.asm.compileToExpression
-import space.kscience.kmath.expressions.*
-import space.kscience.kmath.operations.Algebra
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.operations.bindSymbol
-import space.kscience.kmath.operations.invoke
-import kotlin.math.sin
-import kotlin.random.Random
-
-@State(Scope.Benchmark)
-internal class ExpressionsInterpretersBenchmark {
- /**
- * Benchmark case for [Expression] created with [expressionInExtendedField].
- */
- @Benchmark
- fun functionalExpression(blackhole: Blackhole) = invokeAndSum(functional, blackhole)
-
- /**
- * Benchmark case for [Expression] created with [toExpression].
- */
- @Benchmark
- fun mstExpression(blackhole: Blackhole) = invokeAndSum(mst, blackhole)
-
- /**
- * Benchmark case for [Expression] created with [compileToExpression].
- */
- @Benchmark
- fun asmGenericExpression(blackhole: Blackhole) = invokeAndSum(asmGeneric, blackhole)
-
- /**
- * Benchmark case for [Expression] created with [compileToExpression].
- */
- @Benchmark
- fun asmPrimitiveExpressionArray(blackhole: Blackhole) {
- val random = Random(0)
- var sum = 0.0
- val m = DoubleArray(1)
-
- repeat(times) {
- m[xIdx] = random.nextDouble()
- sum += asmPrimitive(m)
- }
-
- blackhole.consume(sum)
- }
-
- /**
- * Benchmark case for [Expression] created with [compileToExpression].
- */
- @Benchmark
- fun asmPrimitiveExpression(blackhole: Blackhole) = invokeAndSum(asmPrimitive, blackhole)
-
- /**
- * Benchmark case for [Expression] implemented manually with `kotlin.math` functions.
- */
- @Benchmark
- fun rawExpression(blackhole: Blackhole) = invokeAndSum(raw, blackhole)
-
- /**
- * Benchmark case for direct computation w/o [Expression].
- */
- @Benchmark
- fun justCalculate(blackhole: Blackhole) {
- val random = Random(0)
- var sum = 0.0
-
- repeat(times) {
- val x = random.nextDouble()
- sum += x * 2.0 + 2.0 / x - 16.0 / sin(x)
- }
-
- blackhole.consume(sum)
- }
-
- private fun invokeAndSum(expr: Expression, blackhole: Blackhole) {
- val random = Random(0)
- var sum = 0.0
- val m = HashMap()
-
- repeat(times) {
- m[x] = random.nextDouble()
- sum += expr(m)
- }
-
- blackhole.consume(sum)
- }
-
- private companion object {
- private val x by symbol
- private const val times = 1_000_000
-
- private val functional = Float64Field.expression {
- val x = bindSymbol(Symbol.x)
- x * number(2.0) + 2.0 / x - 16.0 / sin(x)
- }
-
- private val node = MstExtendedField {
- x * 2.0 + number(2.0) / x - number(16.0) / sin(x)
- }
-
- private val mst = node.toExpression(Float64Field)
-
- private val asmPrimitive = node.compileToExpression(Float64Field)
- private val xIdx = asmPrimitive.indexer.indexOf(x)
-
- private val asmGeneric = node.compileToExpression(Float64Field as Algebra)
-
- private val raw = Expression { args ->
- val x = args[x]!!
- x * 2.0 + 2.0 / x - 16.0 / sin(x)
- }
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt
deleted file mode 100644
index 6cc649fe9..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/IntegrationBenchmark.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright 2018-2023 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import org.openjdk.jmh.annotations.Benchmark
-import org.openjdk.jmh.annotations.Scope
-import org.openjdk.jmh.annotations.State
-import org.openjdk.jmh.infra.Blackhole
-import space.kscience.kmath.complex.Complex
-import space.kscience.kmath.complex.algebra
-import space.kscience.kmath.integration.gaussIntegrator
-import space.kscience.kmath.integration.integrate
-import space.kscience.kmath.integration.value
-import space.kscience.kmath.operations.algebra
-
-
-@State(Scope.Benchmark)
-internal class IntegrationBenchmark {
-
- @Benchmark
- fun doubleIntegration(blackhole: Blackhole) {
- val res = Double.algebra.gaussIntegrator.integrate(0.0..1.0, intervals = 1000) { x: Double ->
- //sin(1 / x)
- 1/x
- }.value
- blackhole.consume(res)
- }
-
- @Benchmark
- fun complexIntegration(blackhole: Blackhole) = with(Complex.algebra) {
- val res = gaussIntegrator.integrate(0.0..1.0, intervals = 1000) { x: Double ->
-// sin(1 / x) + i * cos(1 / x)
- 1/x - i/x
- }.value
- blackhole.consume(res)
- }
-}
\ No newline at end of file
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt
deleted file mode 100644
index 355f54c65..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/JafamaBenchmark.kt
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Blackhole
-import org.openjdk.jmh.annotations.Benchmark
-import org.openjdk.jmh.annotations.Scope
-import org.openjdk.jmh.annotations.State
-import space.kscience.kmath.jafama.JafamaDoubleField
-import space.kscience.kmath.jafama.StrictJafamaDoubleField
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.operations.invoke
-import kotlin.contracts.InvocationKind
-import kotlin.contracts.contract
-import kotlin.random.Random
-
-@State(Scope.Benchmark)
-internal class JafamaBenchmark {
- @Benchmark
- fun jafama(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x ->
- JafamaDoubleField { x * power(x, 4) * exp(x) / cos(x) + sin(x) }
- }
-
- @Benchmark
- fun core(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x ->
- Float64Field { x * power(x, 4) * exp(x) / cos(x) + sin(x) }
- }
-
- @Benchmark
- fun strictJafama(blackhole: Blackhole) = invokeBenchmarks(blackhole) { x ->
- StrictJafamaDoubleField { x * power(x, 4) * exp(x) / cos(x) + sin(x) }
- }
-}
-
-private inline fun invokeBenchmarks(blackhole: Blackhole, expr: (Double) -> Double) {
- contract { callsInPlace(expr, InvocationKind.AT_LEAST_ONCE) }
- val rng = Random(0)
- repeat(1000000) { blackhole.consume(expr(rng.nextDouble())) }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt
deleted file mode 100644
index f7aac8199..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/MatrixInverseBenchmark.kt
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import space.kscience.kmath.commons.linear.CMLinearSpace
-import space.kscience.kmath.commons.linear.lupSolver
-import space.kscience.kmath.ejml.EjmlLinearSpaceDDRM
-import space.kscience.kmath.linear.invoke
-import space.kscience.kmath.linear.linearSpace
-import space.kscience.kmath.linear.lupSolver
-import space.kscience.kmath.operations.algebra
-import kotlin.random.Random
-
-@State(Scope.Benchmark)
-internal class MatrixInverseBenchmark {
- private companion object {
- private val random = Random(1224)
- private const val dim = 100
-
- private val space = Double.algebra.linearSpace
-
- //creating invertible matrix
- private val u = space.buildMatrix(dim, dim) { i, j -> if (i <= j) random.nextDouble() else 0.0 }
- private val l = space.buildMatrix(dim, dim) { i, j -> if (i >= j) random.nextDouble() else 0.0 }
- private val matrix = space { l dot u }
- }
-
- @Benchmark
- fun kmathLupInversion(blackhole: Blackhole) {
- blackhole.consume(Double.algebra.linearSpace.lupSolver().inverse(matrix))
- }
-
- @Benchmark
- fun cmLUPInversion(blackhole: Blackhole) {
- CMLinearSpace {
- blackhole.consume(lupSolver().inverse(matrix))
- }
- }
-
- @Benchmark
- fun ejmlInverse(blackhole: Blackhole) {
- EjmlLinearSpaceDDRM {
- blackhole.consume(matrix.toEjml().inverse())
- }
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt
deleted file mode 100644
index ec7f940a0..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/NDFieldBenchmark.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import org.jetbrains.kotlinx.multik.api.Multik
-import org.jetbrains.kotlinx.multik.api.ones
-import org.jetbrains.kotlinx.multik.ndarray.data.DN
-import org.jetbrains.kotlinx.multik.ndarray.data.DataType
-import space.kscience.kmath.UnsafeKMathAPI
-import space.kscience.kmath.nd.*
-import space.kscience.kmath.nd4j.nd4j
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.tensors.core.DoubleTensor
-import space.kscience.kmath.tensors.core.one
-import space.kscience.kmath.tensors.core.tensorAlgebra
-import space.kscience.kmath.viktor.viktorAlgebra
-
-@State(Scope.Benchmark)
-internal class NDFieldBenchmark {
-
- @Benchmark
- fun specializedFieldAdd(blackhole: Blackhole) = with(specializedField) {
- var res: StructureND = one(shape)
- repeat(n) { res += 1.0 }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun boxingFieldAdd(blackhole: Blackhole) = with(genericField) {
- var res: StructureND = one(shape)
- repeat(n) { res += 1.0 }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun multikAdd(blackhole: Blackhole) = with(multikAlgebra) {
- var res: StructureND = one(shape)
- repeat(n) { res += 1.0 }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun viktorAdd(blackhole: Blackhole) = with(viktorField) {
- var res: StructureND = one(shape)
- repeat(n) { res += 1.0 }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun tensorAdd(blackhole: Blackhole) = with(Double.tensorAlgebra) {
- var res: DoubleTensor = one(shape)
- repeat(n) { res = res + 1.0 }
- blackhole.consume(res)
- }
-
- @Benchmark
- fun tensorInPlaceAdd(blackhole: Blackhole) = with(Double.tensorAlgebra) {
- val res: DoubleTensor = one(shape)
- repeat(n) { res += 1.0 }
- blackhole.consume(res)
- }
-
- @OptIn(UnsafeKMathAPI::class)
- @Benchmark
- fun multikInPlaceAdd(blackhole: Blackhole) = with(multikAlgebra) {
- val res = Multik.ones(shape.asArray(), DataType.DoubleDataType).wrap()
- repeat(n) { res += 1.0 }
- blackhole.consume(res)
- }
-
-// @Benchmark
-// fun nd4jAdd(blackhole: Blackhole) = with(nd4jField) {
-// var res: StructureND = one(dim, dim)
-// repeat(n) { res += 1.0 }
-// blackhole.consume(res)
-// }
-
- private companion object {
- private const val dim = 1000
- private const val n = 100
- private val shape = ShapeND(dim, dim)
- private val specializedField = Float64Field.ndAlgebra
- private val genericField = BufferedFieldOpsND(Float64Field)
- private val nd4jField = Float64Field.nd4j
- private val viktorField = Float64Field.viktorAlgebra
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt
deleted file mode 100644
index 8bdb101f6..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/TensorAlgebraBenchmark.kt
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import space.kscience.kmath.linear.linearSpace
-import space.kscience.kmath.linear.matrix
-import space.kscience.kmath.linear.symmetric
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.tensors.core.symEigJacobi
-import space.kscience.kmath.tensors.core.symEigSvd
-import space.kscience.kmath.tensors.core.tensorAlgebra
-import kotlin.random.Random
-
-@State(Scope.Benchmark)
-internal class TensorAlgebraBenchmark {
- companion object {
- private val random = Random(12224)
- private const val dim = 30
-
- private val matrix = Float64Field.linearSpace.matrix(dim, dim).symmetric { _, _ -> random.nextDouble() }
- }
-
- @Benchmark
- fun tensorSymEigSvd(blackhole: Blackhole) = with(Double.tensorAlgebra) {
- blackhole.consume(symEigSvd(matrix, 1e-10))
- }
-
- @Benchmark
- fun tensorSymEigJacobi(blackhole: Blackhole) = with(Double.tensorAlgebra) {
- blackhole.consume(symEigJacobi(matrix, 50, 1e-10))
- }
-}
\ No newline at end of file
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt
deleted file mode 100644
index b424491f6..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorBenchmark.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import org.jetbrains.bio.viktor.F64Array
-import space.kscience.kmath.nd.ShapeND
-import space.kscience.kmath.nd.StructureND
-import space.kscience.kmath.nd.ndAlgebra
-import space.kscience.kmath.nd.one
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.viktor.ViktorFieldND
-
-@State(Scope.Benchmark)
-internal class ViktorBenchmark {
-
- @Benchmark
- fun doubleFieldAddition(blackhole: Blackhole) {
- with(doubleField) {
- var res: StructureND = one(shape)
- repeat(n) { res += 1.0 }
- blackhole.consume(res)
- }
- }
-
- @Benchmark
- fun viktorFieldAddition(blackhole: Blackhole) {
- with(viktorField) {
- var res = one(shape)
- repeat(n) { res += 1.0 }
- blackhole.consume(res)
- }
- }
-
- @Benchmark
- fun rawViktor(blackhole: Blackhole) {
- val one = F64Array.full(init = 1.0, shape = intArrayOf(dim, dim))
- var res = one
- repeat(n) { res = res + one }
- blackhole.consume(res)
- }
-
- private companion object {
- private const val dim = 1000
- private const val n = 100
- private val shape = ShapeND(dim, dim)
-
- // automatically build context most suited for given type.
- private val doubleField = Float64Field.ndAlgebra
- private val viktorField = ViktorFieldND(dim, dim)
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt
deleted file mode 100644
index b6a485821..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/ViktorLogBenchmark.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import kotlinx.benchmark.Benchmark
-import kotlinx.benchmark.Blackhole
-import kotlinx.benchmark.Scope
-import kotlinx.benchmark.State
-import org.jetbrains.bio.viktor.F64Array
-import space.kscience.kmath.nd.ShapeND
-import space.kscience.kmath.nd.ndAlgebra
-import space.kscience.kmath.nd.one
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.viktor.ViktorFieldND
-
-@State(Scope.Benchmark)
-internal class ViktorLogBenchmark {
- @Benchmark
- fun realFieldLog(blackhole: Blackhole) {
- with(doubleField) {
- val fortyTwo = structureND(shape) { 42.0 }
- var res = one(shape)
- repeat(n) { res = ln(fortyTwo) }
- blackhole.consume(res)
- }
- }
-
- @Benchmark
- fun viktorFieldLog(blackhole: Blackhole) {
- with(viktorField) {
- val fortyTwo = structureND(shape) { 42.0 }
- var res = one
- repeat(n) { res = ln(fortyTwo) }
- blackhole.consume(res)
- }
- }
-
- @Benchmark
- fun rawViktorLog(blackhole: Blackhole) {
- val fortyTwo = F64Array.full(dim, dim, init = 42.0)
- lateinit var res: F64Array
- repeat(n) { res = fortyTwo.log() }
- blackhole.consume(res)
- }
-
- private companion object {
- private const val dim = 1000
- private const val n = 100
- private val shape = ShapeND(dim, dim)
-
- // automatically build context most suited for given type.
- private val doubleField = Float64Field.ndAlgebra
- private val viktorField = ViktorFieldND(dim, dim)
- }
-}
diff --git a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/globals.kt b/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/globals.kt
deleted file mode 100644
index f6d278d83..000000000
--- a/benchmarks/src/jvmMain/kotlin/space/kscience/kmath/benchmarks/globals.kt
+++ /dev/null
@@ -1,11 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import org.jetbrains.kotlinx.multik.default.DefaultEngine
-import space.kscience.kmath.multik.MultikDoubleAlgebra
-
-val multikAlgebra = MultikDoubleAlgebra(DefaultEngine())
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
index e2c5fc44f..6d102a77a 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,80 +1,24 @@
-import space.kscience.gradle.isInDevelopment
-import space.kscience.gradle.useApache2Licence
-import space.kscience.gradle.useSPCTeam
-
plugins {
- id("space.kscience.gradle.project")
- id("org.jetbrains.kotlinx.kover") version "0.6.0"
+ id("scientifik.publish") apply false
}
+val kmathVersion by extra("0.1.4-dev-7")
+
+val bintrayRepo by extra("scientifik")
+val githubProject by extra("kmath")
+
allprojects {
repositories {
- maven("https://repo.kotlin.link")
- maven("https://oss.sonatype.org/content/repositories/snapshots")
- mavenCentral()
+ jcenter()
+ maven("https://dl.bintray.com/kotlin/kotlinx")
}
- group = "space.kscience"
- version = "0.4.0-dev-2"
+ group = "scientifik"
+ version = kmathVersion
}
subprojects {
- if (name.startsWith("kmath")) apply()
-
- plugins.withId("org.jetbrains.dokka") {
- tasks.withType {
- dependsOn(tasks["assemble"])
-
- dokkaSourceSets.all {
- val readmeFile = this@subprojects.projectDir.resolve("README.md")
- if (readmeFile.exists()) includes.from(readmeFile)
- val kotlinDirPath = "src/$name/kotlin"
- val kotlinDir = file(kotlinDirPath)
-
- if (kotlinDir.exists()) sourceLink {
- localDirectory.set(kotlinDir)
-
- remoteUrl.set(
- java.net.URL("https://github.com/SciProgCentre/kmath/tree/master/${this@subprojects.name}/$kotlinDirPath")
- )
- }
-
- externalDocumentationLink("https://commons.apache.org/proper/commons-math/javadocs/api-3.6.1/")
- externalDocumentationLink("https://deeplearning4j.org/api/latest/")
- externalDocumentationLink("https://axelclk.bitbucket.io/symja/javadoc/")
-
- externalDocumentationLink(
- "https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/",
- "https://kotlin.github.io/kotlinx.coroutines/package-list",
- )
-
- externalDocumentationLink(
- "https://breandan.net/kotlingrad/kotlingrad/",
- "https://breandan.net/kotlingrad/kotlingrad/kotlingrad/package-list",
- )
- }
- }
+ if (name.startsWith("kmath")) {
+ apply(plugin = "scientifik.publish")
}
-}
-
-readme.readmeTemplate = file("docs/templates/README-TEMPLATE.md")
-
-ksciencePublish {
- pom("https://github.com/SciProgCentre/kmath") {
- useApache2Licence()
- useSPCTeam()
- }
- github("kmath", "SciProgCentre")
- space(
- if (isInDevelopment) {
- "https://maven.pkg.jetbrains.space/spc/p/sci/dev"
- } else {
- "https://maven.pkg.jetbrains.space/spc/p/sci/maven"
- }
- )
- sonatype("https://oss.sonatype.org")
-}
-
-apiValidation.nonPublicMarkers.add("space.kscience.kmath.UnstableKMathAPI")
-
-val multikVersion by extra("0.2.0")
+}
\ No newline at end of file
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
deleted file mode 100644
index 734f60091..000000000
--- a/buildSrc/build.gradle.kts
+++ /dev/null
@@ -1,34 +0,0 @@
-plugins {
- `kotlin-dsl`
- `version-catalog`
-}
-
-repositories {
- mavenLocal()
- maven("https://repo.kotlin.link")
- mavenCentral()
- gradlePluginPortal()
-}
-
-val toolsVersion = spclibs.versions.tools.get()
-val kotlinVersion = spclibs.versions.kotlin.asProvider().get()
-val benchmarksVersion = spclibs.versions.kotlinx.benchmark.get()
-
-dependencies {
- api("space.kscience:gradle-tools:$toolsVersion")
- //plugins form benchmarks
- api("org.jetbrains.kotlinx:kotlinx-benchmark-plugin:0.4.7")
- //api("org.jetbrains.kotlin:kotlin-allopen:$kotlinVersion")
- //to be used inside build-script only
- //implementation(spclibs.kotlinx.serialization.json)
- implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.+")
-}
-
-kotlin{
- jvmToolchain{
- languageVersion.set(JavaLanguageVersion.of(11))
- }
- sourceSets.all {
- languageSettings.optIn("kotlin.OptIn")
- }
-}
diff --git a/buildSrc/settings.gradle.kts b/buildSrc/settings.gradle.kts
deleted file mode 100644
index e6b69b0b3..000000000
--- a/buildSrc/settings.gradle.kts
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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.
- */
-rootProject.name = "kmath"
-
-enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
-
-dependencyResolutionManagement {
- val projectProperties = java.util.Properties()
- file("../gradle.properties").inputStream().use {
- projectProperties.load(it)
- }
-
- projectProperties.forEach { key, value ->
- extra.set(key.toString(), value)
- }
-
-
- val toolsVersion: String = projectProperties["toolsVersion"].toString()
-
- repositories {
- mavenLocal()
- maven("https://repo.kotlin.link")
- mavenCentral()
- gradlePluginPortal()
- }
-
- versionCatalogs {
- create("spclibs") {
- from("space.kscience:version-catalog:$toolsVersion")
- }
- }
-}
diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/JmhReport.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/JmhReport.kt
deleted file mode 100644
index 3a4fcdc79..000000000
--- a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/JmhReport.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-data class JmhReport(
- val jmhVersion: String,
- val benchmark: String,
- val mode: String,
- val threads: Int,
- val forks: Int,
- val jvm: String,
- val jvmArgs: List,
- val jdkVersion: String,
- val vmName: String,
- val vmVersion: String,
- val warmupIterations: Int,
- val warmupTime: String,
- val warmupBatchSize: Int,
- val measurementIterations: Int,
- val measurementTime: String,
- val measurementBatchSize: Int,
- val params: Map = emptyMap(),
- val primaryMetric: PrimaryMetric,
- val secondaryMetrics: Map,
-) {
- interface Metric {
- val score: Double
- val scoreError: Double
- val scoreConfidence: List
- val scorePercentiles: Map
- val scoreUnit: String
- }
-
- data class PrimaryMetric(
- override val score: Double,
- override val scoreError: Double,
- override val scoreConfidence: List,
- override val scorePercentiles: Map,
- override val scoreUnit: String,
- val rawDataHistogram: List>>>? = null,
- val rawData: List>? = null,
- ) : Metric
-
- data class SecondaryMetric(
- override val score: Double,
- override val scoreError: Double,
- override val scoreConfidence: List,
- override val scorePercentiles: Map,
- override val scoreUnit: String,
- val rawData: List>,
- ) : Metric
-}
diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt
deleted file mode 100644
index a3a475885..000000000
--- a/buildSrc/src/main/kotlin/space/kscience/kmath/benchmarks/addBenchmarkProperties.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-package space.kscience.kmath.benchmarks
-
-import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
-import com.fasterxml.jackson.module.kotlin.readValue
-import kotlinx.benchmark.gradle.BenchmarksExtension
-import org.gradle.api.Project
-import space.kscience.gradle.KScienceReadmeExtension
-import java.time.LocalDateTime
-import java.time.ZoneId
-import java.time.format.DateTimeFormatter
-import java.time.format.DateTimeFormatterBuilder
-import java.time.format.SignStyle
-import java.time.temporal.ChronoField.*
-import java.util.*
-
-private val ISO_DATE_TIME: DateTimeFormatter = DateTimeFormatterBuilder().run {
- parseCaseInsensitive()
- appendValue(YEAR, 4, 10, SignStyle.EXCEEDS_PAD)
- appendLiteral('-')
- appendValue(MONTH_OF_YEAR, 2)
- appendLiteral('-')
- appendValue(DAY_OF_MONTH, 2)
- appendLiteral('T')
- appendValue(HOUR_OF_DAY, 2)
- appendLiteral('.')
- appendValue(MINUTE_OF_HOUR, 2)
- optionalStart()
- appendLiteral('.')
- appendValue(SECOND_OF_MINUTE, 2)
- optionalStart()
- appendFraction(NANO_OF_SECOND, 0, 9, true)
- optionalStart()
- appendOffsetId()
- optionalStart()
- appendLiteral('[')
- parseCaseSensitive()
- appendZoneRegionId()
- appendLiteral(']')
- toFormatter()
-}
-
-private fun noun(number: Number, singular: String, plural: String) = if (number.toLong() == 1L) singular else plural
-
-private val jsonMapper = jacksonObjectMapper()
-
-fun Project.addBenchmarkProperties() {
- val benchmarksProject = this
- rootProject.subprojects.forEach { p ->
- p.extensions.findByType(KScienceReadmeExtension::class.java)?.run {
- benchmarksProject.extensions.findByType(BenchmarksExtension::class.java)?.configurations?.forEach { cfg ->
- property("benchmark${cfg.name.replaceFirstChar { if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString() }}") {
- val launches = benchmarksProject.buildDir.resolve("reports/benchmarks/${cfg.name}")
-
- val resDirectory = launches.listFiles()?.maxByOrNull {
- LocalDateTime.parse(it.name, ISO_DATE_TIME).atZone(ZoneId.systemDefault()).toInstant()
- }
-
- if (resDirectory == null || !(resDirectory.resolve("jvm.json")).exists()) {
- "> **Can't find appropriate benchmark data. Try generating readme files after running benchmarks**."
- } else {
- val reports: List = jsonMapper.readValue>(resDirectory.resolve("jvm.json"))
-
- buildString {
- appendLine("")
- appendLine("")
- appendLine("Report for benchmark configuration ${cfg.name}")
- appendLine("")
- appendLine()
- val first = reports.first()
-
- appendLine("* Run on ${first.vmName} (build ${first.vmVersion}) with Java process:")
- appendLine()
- appendLine("```")
- appendLine("${first.jvm} ${
- first.jvmArgs.joinToString(" ")
- }")
- appendLine("```")
-
- appendLine("* JMH ${first.jmhVersion} was used in `${first.mode}` mode with ${first.warmupIterations} warmup ${
- noun(first.warmupIterations, "iteration", "iterations")
- } by ${first.warmupTime} and ${first.measurementIterations} measurement ${
- noun(first.measurementIterations, "iteration", "iterations")
- } by ${first.measurementTime}.")
-
- appendLine()
- appendLine("| Benchmark | Score |")
- appendLine("|:---------:|:-----:|")
-
- reports.forEach { report ->
- appendLine("|`${report.benchmark}`|${report.primaryMetric.score} ± ${report.primaryMetric.scoreError} ${report.primaryMetric.scoreUnit}|")
- }
-
- appendLine("")
- }
- }
- }
- }
- }
- }
-}
diff --git a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt b/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt
deleted file mode 100644
index 41b88f093..000000000
--- a/buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt
+++ /dev/null
@@ -1,433 +0,0 @@
-/*
- * Copyright 2018-2022 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.
- */
-
-@file:Suppress("KDocUnresolvedReference")
-
-package space.kscience.kmath.ejml.codegen
-
-import org.intellij.lang.annotations.Language
-import java.io.File
-
-private fun Appendable.appendEjmlVector(type: String, ejmlMatrixType: String) {
- @Language("kotlin") val text = """/**
- * [EjmlVector] specialization for [$type].
- */
-public class Ejml${type}Vector(override val origin: M) : EjmlVector<$type, M>(origin) {
- init {
- require(origin.numRows == 1) { "The origin matrix must have only one row to form a vector" }
- }
-
- override operator fun get(index: Int): $type = origin[0, index]
-}"""
- appendLine(text)
- appendLine()
-}
-
-private fun Appendable.appendEjmlMatrix(type: String, ejmlMatrixType: String) {
- val text = """/**
- * [EjmlMatrix] specialization for [$type].
- */
-public class Ejml${type}Matrix(override val origin: M) : EjmlMatrix<$type, M>(origin) {
- override operator fun get(i: Int, j: Int): $type = origin[i, j]
-}"""
- appendLine(text)
- appendLine()
-}
-
-private fun Appendable.appendEjmlLinearSpace(
- type: String,
- kmathAlgebra: String,
- ejmlMatrixParentTypeMatrix: String,
- ejmlMatrixType: String,
- ejmlMatrixDenseType: String,
- ops: String,
- denseOps: String,
- isDense: Boolean,
-) {
- @Language("kotlin") val text = """/**
- * [EjmlLinearSpace] implementation based on [CommonOps_$ops], [DecompositionFactory_${ops}] operations and
- * [${ejmlMatrixType}] matrices.
- */
-public object EjmlLinearSpace${ops} : EjmlLinearSpace<${type}, ${kmathAlgebra}, $ejmlMatrixType>() {
- /**
- * The [${kmathAlgebra}] reference.
- */
- override val elementAlgebra: $kmathAlgebra get() = $kmathAlgebra
-
- @Suppress("UNCHECKED_CAST")
- override fun Matrix<${type}>.toEjml(): Ejml${type}Matrix<${ejmlMatrixType}> = when {
- this is Ejml${type}Matrix<*> && origin is $ejmlMatrixType -> this as Ejml${type}Matrix<${ejmlMatrixType}>
- else -> buildMatrix(rowNum, colNum) { i, j -> get(i, j) }
- }
-
- @Suppress("UNCHECKED_CAST")
- override fun Point<${type}>.toEjml(): Ejml${type}Vector<${ejmlMatrixType}> = when {
- this is Ejml${type}Vector<*> && origin is $ejmlMatrixType -> this as Ejml${type}Vector<${ejmlMatrixType}>
- else -> Ejml${type}Vector(${ejmlMatrixType}(size, 1).also {
- (0 until it.numRows).forEach { row -> it[row, 0] = get(row) }
- })
- }
-
- override fun buildMatrix(
- rows: Int,
- columns: Int,
- initializer: ${kmathAlgebra}.(i: Int, j: Int) -> ${type},
- ): Ejml${type}Matrix<${ejmlMatrixType}> = ${ejmlMatrixType}(rows, columns).also {
- (0 until rows).forEach { row ->
- (0 until columns).forEach { col -> it[row, col] = elementAlgebra.initializer(row, col) }
- }
- }.wrapMatrix()
-
- override fun buildVector(
- size: Int,
- initializer: ${kmathAlgebra}.(Int) -> ${type},
- ): Ejml${type}Vector<${ejmlMatrixType}> = Ejml${type}Vector(${ejmlMatrixType}(size, 1).also {
- (0 until it.numRows).forEach { row -> it[row, 0] = elementAlgebra.initializer(row) }
- })
-
- private fun T.wrapMatrix() = Ejml${type}Matrix(this)
- private fun T.wrapVector() = Ejml${type}Vector(this)
-
- override fun Matrix<${type}>.unaryMinus(): Matrix<${type}> = this * elementAlgebra { -one }
-
- override fun Matrix<${type}>.dot(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> {
- val out = ${ejmlMatrixType}(1, 1)
- CommonOps_${ops}.mult(toEjml().origin, other.toEjml().origin, out)
- return out.wrapMatrix()
- }
-
- override fun Matrix<${type}>.dot(vector: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> {
- val out = ${ejmlMatrixType}(1, 1)
- CommonOps_${ops}.mult(toEjml().origin, vector.toEjml().origin, out)
- return out.wrapVector()
- }
-
- override operator fun Matrix<${type}>.minus(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> {
- val out = ${ejmlMatrixType}(1, 1)
-
- CommonOps_${ops}.add(
- elementAlgebra.one,
- toEjml().origin,
- elementAlgebra { -one },
- other.toEjml().origin,
- out,${
- if (isDense) "" else
- """
- null,
- null,"""
- }
- )
-
- return out.wrapMatrix()
- }
-
- override operator fun Matrix<${type}>.times(value: ${type}): Ejml${type}Matrix<${ejmlMatrixType}> {
- val res = ${ejmlMatrixType}(1, 1)
- CommonOps_${ops}.scale(value, toEjml().origin, res)
- return res.wrapMatrix()
- }
-
- override fun Point<${type}>.unaryMinus(): Ejml${type}Vector<${ejmlMatrixType}> {
- val res = ${ejmlMatrixType}(1, 1)
- CommonOps_${ops}.changeSign(toEjml().origin, res)
- return res.wrapVector()
- }
-
- override fun Matrix<${type}>.plus(other: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> {
- val out = ${ejmlMatrixType}(1, 1)
-
- CommonOps_${ops}.add(
- elementAlgebra.one,
- toEjml().origin,
- elementAlgebra.one,
- other.toEjml().origin,
- out,${
- if (isDense) "" else
- """
- null,
- null,"""
- }
- )
-
- return out.wrapMatrix()
- }
-
- override fun Point<${type}>.plus(other: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> {
- val out = ${ejmlMatrixType}(1, 1)
-
- CommonOps_${ops}.add(
- elementAlgebra.one,
- toEjml().origin,
- elementAlgebra.one,
- other.toEjml().origin,
- out,${
- if (isDense) "" else
- """
- null,
- null,"""
- }
- )
-
- return out.wrapVector()
- }
-
- override fun Point<${type}>.minus(other: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> {
- val out = ${ejmlMatrixType}(1, 1)
-
- CommonOps_${ops}.add(
- elementAlgebra.one,
- toEjml().origin,
- elementAlgebra { -one },
- other.toEjml().origin,
- out,${
- if (isDense) "" else
- """
- null,
- null,"""
- }
- )
-
- return out.wrapVector()
- }
-
- override fun ${type}.times(m: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> = m * this
-
- override fun Point<${type}>.times(value: ${type}): Ejml${type}Vector<${ejmlMatrixType}> {
- val res = ${ejmlMatrixType}(1, 1)
- CommonOps_${ops}.scale(value, toEjml().origin, res)
- return res.wrapVector()
- }
-
- override fun ${type}.times(v: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> = v * this
-
- @UnstableKMathAPI
- override fun computeFeature(structure: Matrix<${type}>, type: KClass): F? {
- structure.getFeature(type)?.let { return it }
- val origin = structure.toEjml().origin
-
- return when (type) {
- ${
- if (isDense)
- """ InverseMatrixFeature::class -> object : InverseMatrixFeature<${type}> {
- override val inverse: Matrix<${type}> by lazy {
- val res = origin.copy()
- CommonOps_${ops}.invert(res)
- res.wrapMatrix()
- }
- }
-
- DeterminantFeature::class -> object : DeterminantFeature<${type}> {
- override val determinant: $type by lazy { CommonOps_${ops}.det(origin) }
- }
-
- SingularValueDecompositionFeature::class -> object : SingularValueDecompositionFeature<${type}> {
- private val svd by lazy {
- DecompositionFactory_${ops}.svd(origin.numRows, origin.numCols, true, true, false)
- .apply { decompose(origin.copy()) }
- }
-
- override val u: Matrix<${type}> by lazy { svd.getU(null, false).wrapMatrix() }
- override val s: Matrix<${type}> by lazy { svd.getW(null).wrapMatrix() }
- override val v: Matrix<${type}> by lazy { svd.getV(null, false).wrapMatrix() }
- override val singularValues: Point<${type}> by lazy { ${type}Buffer(svd.singularValues) }
- }
-
- QRDecompositionFeature::class -> object : QRDecompositionFeature<${type}> {
- private val qr by lazy {
- DecompositionFactory_${ops}.qr().apply { decompose(origin.copy()) }
- }
-
- override val q: Matrix<${type}> by lazy {
- qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature)
- }
-
- override val r: Matrix<${type}> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) }
- }
-
- CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<${type}> {
- override val l: Matrix<${type}> by lazy {
- val cholesky =
- DecompositionFactory_${ops}.chol(structure.rowNum, true).apply { decompose(origin.copy()) }
-
- cholesky.getT(null).wrapMatrix().withFeature(LFeature)
- }
- }
-
- LupDecompositionFeature::class -> object : LupDecompositionFeature<${type}> {
- private val lup by lazy {
- DecompositionFactory_${ops}.lu(origin.numRows, origin.numCols).apply { decompose(origin.copy()) }
- }
-
- override val l: Matrix<${type}> by lazy {
- lup.getLower(null).wrapMatrix().withFeature(LFeature)
- }
-
- override val u: Matrix<${type}> by lazy {
- lup.getUpper(null).wrapMatrix().withFeature(UFeature)
- }
-
- override val p: Matrix<${type}> by lazy { lup.getRowPivot(null).wrapMatrix() }
- }""" else """ QRDecompositionFeature::class -> object : QRDecompositionFeature<$type> {
- private val qr by lazy {
- DecompositionFactory_${ops}.qr(FillReducing.NONE).apply { decompose(origin.copy()) }
- }
-
- override val q: Matrix<${type}> by lazy {
- qr.getQ(null, false).wrapMatrix().withFeature(OrthogonalFeature)
- }
-
- override val r: Matrix<${type}> by lazy { qr.getR(null, false).wrapMatrix().withFeature(UFeature) }
- }
-
- CholeskyDecompositionFeature::class -> object : CholeskyDecompositionFeature<${type}> {
- override val l: Matrix<${type}> by lazy {
- val cholesky =
- DecompositionFactory_${ops}.cholesky().apply { decompose(origin.copy()) }
-
- (cholesky.getT(null) as ${ejmlMatrixParentTypeMatrix}).wrapMatrix().withFeature(LFeature)
- }
- }
-
- LUDecompositionFeature::class, DeterminantFeature::class, InverseMatrixFeature::class -> object :
- LUDecompositionFeature<${type}>, DeterminantFeature<${type}>, InverseMatrixFeature<${type}> {
- private val lu by lazy {
- DecompositionFactory_${ops}.lu(FillReducing.NONE).apply { decompose(origin.copy()) }
- }
-
- override val l: Matrix<${type}> by lazy {
- lu.getLower(null).wrapMatrix().withFeature(LFeature)
- }
-
- override val u: Matrix<${type}> by lazy {
- lu.getUpper(null).wrapMatrix().withFeature(UFeature)
- }
-
- override val inverse: Matrix<${type}> by lazy {
- var a = origin
- val inverse = ${ejmlMatrixDenseType}(1, 1)
- val solver = LinearSolverFactory_${ops}.lu(FillReducing.NONE)
- if (solver.modifiesA()) a = a.copy()
- val i = CommonOps_${denseOps}.identity(a.numRows)
- solver.solve(i, inverse)
- inverse.wrapMatrix()
- }
-
- override val determinant: $type by lazy { elementAlgebra.number(lu.computeDeterminant().real) }
- }"""
- }
-
- else -> null
- }?.let{
- type.cast(it)
- }
- }
-
- /**
- * Solves for *x* in the following equation: *x = [a] -1 · [b]*.
- *
- * @param a the base matrix.
- * @param b n by p matrix.
- * @return the solution for *x* that is n by p.
- */
- public fun solve(a: Matrix<${type}>, b: Matrix<${type}>): Ejml${type}Matrix<${ejmlMatrixType}> {
- val res = ${ejmlMatrixType}(1, 1)
- CommonOps_${ops}.solve(${ejmlMatrixType}(a.toEjml().origin), ${ejmlMatrixType}(b.toEjml().origin), res)
- return res.wrapMatrix()
- }
-
- /**
- * Solves for *x* in the following equation: *x = [a] -1 · [b]*.
- *
- * @param a the base matrix.
- * @param b n by p vector.
- * @return the solution for *x* that is n by p.
- */
- public fun solve(a: Matrix<${type}>, b: Point<${type}>): Ejml${type}Vector<${ejmlMatrixType}> {
- val res = ${ejmlMatrixType}(1, 1)
- CommonOps_${ops}.solve(${ejmlMatrixType}(a.toEjml().origin), ${ejmlMatrixType}(b.toEjml().origin), res)
- return Ejml${type}Vector(res)
- }
-}"""
- appendLine(text)
- appendLine()
-}
-
-
-/**
- * Generates routine EJML classes.
- */
-fun ejmlCodegen(outputFile: String): Unit = File(outputFile).run {
- parentFile.mkdirs()
-
- writer().use {
- it.appendLine("/*")
- it.appendLine(" * Copyright 2018-2021 KMath contributors.")
- it.appendLine(" * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.")
- it.appendLine(" */")
- it.appendLine()
- it.appendLine("/* This file is generated with buildSrc/src/main/kotlin/space/kscience/kmath/ejml/codegen/ejmlCodegen.kt */")
- it.appendLine()
- it.appendLine("package space.kscience.kmath.ejml")
- it.appendLine()
- it.appendLine("""import org.ejml.data.*
-import org.ejml.dense.row.CommonOps_DDRM
-import org.ejml.dense.row.CommonOps_FDRM
-import org.ejml.dense.row.factory.DecompositionFactory_DDRM
-import org.ejml.dense.row.factory.DecompositionFactory_FDRM
-import org.ejml.sparse.FillReducing
-import org.ejml.sparse.csc.CommonOps_DSCC
-import org.ejml.sparse.csc.CommonOps_FSCC
-import org.ejml.sparse.csc.factory.DecompositionFactory_DSCC
-import org.ejml.sparse.csc.factory.DecompositionFactory_FSCC
-import org.ejml.sparse.csc.factory.LinearSolverFactory_DSCC
-import org.ejml.sparse.csc.factory.LinearSolverFactory_FSCC
-import space.kscience.kmath.linear.*
-import space.kscience.kmath.linear.Matrix
-import space.kscience.kmath.UnstableKMathAPI
-import space.kscience.kmath.nd.StructureFeature
-import space.kscience.kmath.structures.Float64
-import space.kscience.kmath.structures.Float32
-import space.kscience.kmath.operations.Float64Field
-import space.kscience.kmath.operations.Float32Field
-import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.FloatField
-import space.kscience.kmath.operations.invoke
-import space.kscience.kmath.structures.Float64Buffer
-import space.kscience.kmath.structures.Float32Buffer
-import space.kscience.kmath.structures.DoubleBuffer
-import space.kscience.kmath.structures.FloatBuffer
-import kotlin.reflect.KClass
-import kotlin.reflect.cast""")
- it.appendLine()
- it.appendEjmlVector("Double", "DMatrix")
- it.appendEjmlVector("Float", "FMatrix")
- it.appendEjmlMatrix("Double", "DMatrix")
- it.appendEjmlMatrix("Float", "FMatrix")
- it.appendEjmlLinearSpace("Double", "Float64Field", "DMatrix", "DMatrixRMaj", "DMatrixRMaj", "DDRM", "DDRM", true)
- it.appendEjmlLinearSpace("Float", "Float32Field", "FMatrix", "FMatrixRMaj", "FMatrixRMaj", "FDRM", "FDRM", true)
-
- it.appendEjmlLinearSpace(
- type = "Double",
- kmathAlgebra = "Float64Field",
- ejmlMatrixParentTypeMatrix = "DMatrix",
- ejmlMatrixType = "DMatrixSparseCSC",
- ejmlMatrixDenseType = "DMatrixRMaj",
- ops = "DSCC",
- denseOps = "DDRM",
- isDense = false,
- )
-
- it.appendEjmlLinearSpace(
- type = "Float",
- kmathAlgebra = "Float32Field",
- ejmlMatrixParentTypeMatrix = "FMatrix",
- ejmlMatrixType = "FMatrixSparseCSC",
- ejmlMatrixDenseType = "FMatrixRMaj",
- ops = "FSCC",
- denseOps = "FDRM",
- isDense = false,
- )
- }
-}
diff --git a/doc/algebra.md b/doc/algebra.md
new file mode 100644
index 000000000..015f4fc82
--- /dev/null
+++ b/doc/algebra.md
@@ -0,0 +1,111 @@
+# Algebra and algebra elements
+
+The mathematical operations in `kmath` are generally separated from mathematical objects.
+This means that in order to perform an operation, say `+`, one needs two objects of a type `T` and
+and algebra context which defines appropriate operation, say `Space`. Next one needs to run actual operation
+in the context:
+
+```kotlin
+val a: T
+val b: T
+val space: Space
+
+val c = space.run{a + b}
+```
+
+From the first glance, this distinction seems to be a needless complication, but in fact one needs
+to remember that in mathematics, one could define different operations on the same objects. For example,
+one could use different types of geometry for vectors.
+
+## Algebra hierarchy
+
+Mathematical contexts have the following hierarchy:
+
+**Space** <- **Ring** <- **Field**
+
+All classes follow abstract mathematical constructs.
+[Space](http://mathworld.wolfram.com/Space.html) defines `zero` element, addition operation and multiplication by constant,
+[Ring](http://mathworld.wolfram.com/Ring.html) adds multiplication and unit `one` element,
+[Field](http://mathworld.wolfram.com/Field.html) adds division operation.
+
+Typical case of `Field` is the `RealField` which works on doubles. And typical case of `Space` is a `VectorSpace`.
+
+In some cases algebra context could hold additional operation like `exp` or `sin`, in this case it inherits appropriate
+interface. Also a context could have an operation which produces an element outside of its context. For example
+`Matrix` `dot` operation produces a matrix with new dimensions which can be incompatible with initial matrix in
+terms of linear operations.
+
+## Algebra element
+
+In order to achieve more familiar behavior (where you apply operations directly to mathematical objects), without involving contexts
+`kmath` introduces special type objects called `MathElement`. A `MathElement` is basically some object coupled to
+a mathematical context. For example `Complex` is the pair of real numbers representing real and imaginary parts,
+but it also holds reference to the `ComplexField` singleton which allows to perform direct operations on `Complex`
+numbers without explicit involving the context like:
+
+```kotlin
+ val c1 = Complex(1.0, 1.0)
+ val c2 = Complex(1.0, -1.0)
+ val c3 = c1 + c2 + 3.0.toComplex()
+ //or with field notation:
+ val c4 = ComplexField.run{c1 + i - 2.0}
+```
+
+Both notations have their pros and cons.
+
+The hierarchy for algebra elements follows the hierarchy for the corresponding algebra.
+
+**MathElement** <- **SpaceElement** <- **RingElement** <- **FieldElement**
+
+**MathElement** is the generic common ancestor of the class with context.
+
+One important distinction between algebra elements and algebra contexts is that algebra element has three type parameters:
+
+1. The type of elements, field operates on.
+2. The self-type of the element returned from operation (must be algebra element).
+3. The type of the algebra over first type-parameter.
+
+The middle type is needed in case algebra members do not store context. For example, it is not possible to add
+a context to regular `Double`. The element performs automatic conversions from context types and back.
+One should used context operations in all important places. The performance of element operations is not guaranteed.
+
+## Spaces and fields
+
+An obvious first choice of mathematical objects to implement in a context-oriented style are algebraic elements like spaces,
+rings and fields. Those are located in the `scientifik.kmath.operations.Algebra.kt` file. Alongside common contexts, the file includes definitions for algebra elements like `FieldElement`. A `FieldElement` object
+stores a reference to the `Field` which contains additive and multiplicative operations, meaning
+it has one fixed context attached and does not require explicit external context. So those `MathElements` can be operated without context:
+
+```kotlin
+val c1 = Complex(1.0, 2.0)
+val c2 = ComplexField.i
+val c3 = c1 + c2
+```
+
+`ComplexField` also features special operations to mix complex and real numbers, for example:
+
+```kotlin
+val c1 = Complex(1.0, 2.0)
+val c2 = ComplexField.run{ c1 - 1.0} // Returns: [re:0.0, im: 2.0]
+val c3 = ComplexField.run{ c1 - i*2.0}
+```
+
+**Note**: In theory it is possible to add behaviors directly to the context, but currently kotlin syntax does not support
+that. Watch [KT-10468](https://youtrack.jetbrains.com/issue/KT-10468) and [KEEP-176](https://github.com/Kotlin/KEEP/pull/176) for updates.
+
+## Nested fields
+
+Contexts allow one to build more complex structures. For example, it is possible to create a `Matrix` from complex elements like so:
+
+```kotlin
+val element = NDElement.complex(shape = intArrayOf(2,2)){ index: IntArray ->
+ Complex(index[0].toDouble() - index[1].toDouble(), index[0].toDouble() + index[1].toDouble())
+}
+```
+
+The `element` in this example is a member of the `Field` of 2-d structures, each element of which is a member of its own
+`ComplexField`. The important thing is one does not need to create a special n-d class to hold complex
+numbers and implement operations on it, one just needs to provide a field for its elements.
+
+**Note**: Fields themselves do not solve the problem of JVM boxing, but it is possible to solve with special contexts like
+`MemorySpec`.
diff --git a/docs/buffers.md b/doc/buffers.md
similarity index 58%
rename from docs/buffers.md
rename to doc/buffers.md
index e7573497e..b0b7489b3 100644
--- a/docs/buffers.md
+++ b/doc/buffers.md
@@ -1,20 +1,15 @@
# Buffers
-
-Buffer is one of main building blocks of kmath. It is a basic interface allowing random-access read and write (
-with `MutableBuffer`). There are different types of buffers:
+Buffer is one of main building blocks of kmath. It is a basic interface allowing random-access read and write (with `MutableBuffer`).
+There are different types of buffers:
* Primitive buffers wrapping like `DoubleBuffer` which are wrapping primitive arrays.
* Boxing `ListBuffer` wrapping a list
* Functionally defined `VirtualBuffer` which does not hold a state itself, but provides a function to calculate value
* `MemoryBuffer` allows direct allocation of objects in continuous memory block.
-Some kmath features require a `BufferFactory` class to operate properly. A general convention is to use functions
-defined in
-`Buffer` and `MutableBuffer` companion classes. For example factory `Buffer.Companion::auto` in most cases creates the
-most suitable buffer for given reified type (for types with custom memory buffer it still better to use their
-own `MemoryBuffer.create()` factory).
+Some kmath features require a `BufferFactory` class to operate properly. A general convention is to use functions defined in
+`Buffer` and `MutableBuffer` companion classes. For example factory `Buffer.Companion::auto` in most cases creates the most suitable
+buffer for given reified type (for types with custom memory buffer it still better to use their own `MemoryBuffer.create()` factory).
## Buffer performance
-
-One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers
-instead .
+One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers instead
\ No newline at end of file
diff --git a/doc/contexts.md b/doc/contexts.md
new file mode 100644
index 000000000..58b198046
--- /dev/null
+++ b/doc/contexts.md
@@ -0,0 +1,73 @@
+# Context-oriented mathematics
+
+## The problem
+
+A known problem for implementing mathematics in statically-typed languages (but not only in them) is that different
+sets of mathematical operators can be defined on the same mathematical objects. Sometimes there is no single way to
+treat some operations, including basic arithmetic operations, on a Java/Kotlin `Number`. Sometimes there are different ways to
+define the same structure, such as Euclidean and elliptic geometry vector spaces over real vectors. Another problem arises when
+one wants to add some kind of behavior to an existing entity. In dynamic languages those problems are usually solved
+by adding dynamic context-specific behaviors at runtime, but this solution has a lot of drawbacks.
+
+## Context-oriented approach
+
+One possible solution to these problems is to divorce numerical representations from behaviors.
+For example in Kotlin one can define a separate class which represents some entity without any operations,
+ex. a complex number:
+
+```kotlin
+data class Complex(val re: Double, val im: Double)
+```
+
+And then to define a separate class or singleton, representing an operation on those complex numbers:
+
+```kotlin
+object ComplexOperations {
+ operator fun Complex.plus(other: Complex) = Complex(re + other.re, im + other.im)
+ operator fun Complex.minus(other: Complex) = Complex(re - other.re, im - other.im)
+}
+```
+
+In Java, applying such external operations could be very cumbersome, but Kotlin has a unique feature which allows us
+implement this naturally: [extensions with receivers](https://kotlinlang.org/docs/reference/extensions.html#extension-functions).
+In Kotlin, an operation on complex number could be implemented as:
+
+```kotlin
+with(ComplexOperations) { c1 + c2 - c3 }
+```
+
+Kotlin also allows the creation of functions with receivers:
+
+```kotlin
+fun ComplexOperations.doSomethingWithComplex(c1: Complex, c2: Complex, c3: Complex) = c1 + c2 - c3
+
+ComplexOperations.doComethingWithComplex(c1, c2, c3)
+```
+
+In fact, whole parts of a program may be run within a mathematical context or even multiple nested contexts.
+
+In KMath, contexts are not only responsible for operations, but also for raw object creation and advanced features.
+
+## Other possibilities
+
+### Type classes
+
+An obvious candidate to get more or less the same functionality is the type class, which allows one to bind a behavior to
+a specific type without modifying the type itself. On the plus side, type classes do not require explicit context
+declaration, so the code looks cleaner. On the minus side, if there are different sets of behaviors for the same types,
+it is impossible to combine them into one module. Also, unlike type classes, context can have parameters or even
+state. For example in KMath, sizes and strides for `NDElement` or `Matrix` could be moved to context to optimize
+performance in case of a large amount of structures.
+
+### Wildcard imports and importing-on-demand
+
+Sometimes, one may wish to use a single context throughout a file. In this case, is possible to import all members
+from a package or file, via `import context.complex.*`. Effectively, this is the same as enclosing an entire file
+with a single context. However when using multiple contexts, this technique can introduce operator ambiguity, due to
+namespace pollution. If there are multiple scoped contexts which define the same operation, it is still possible to
+to import specific operations as needed, without using an explicit context with extension functions, for example:
+
+```
+import context.complex.op1
+import context.quaternion.op2
+```
diff --git a/doc/expressions.md b/doc/expressions.md
new file mode 100644
index 000000000..1e05e5340
--- /dev/null
+++ b/doc/expressions.md
@@ -0,0 +1,26 @@
+# Expressions
+
+**Experimental: this API is in early stage and could change any time**
+
+Expressions is an experimental feature which allows to construct lazily or immediately calculated parametric mathematical
+expressions.
+
+The potential use-cases for it (so far) are following:
+
+* Lazy evaluation (in general simple lambda is better, but there are some border cases)
+
+* Automatic differentiation in single-dimension and in multiple dimensions
+
+* Generation of mathematical syntax trees with subsequent code generation for other languages
+
+* Maybe symbolic computations (needs additional research)
+
+The workhorse of this API is `Expression` interface which exposes single `operator fun invoke(arguments: Map): T`
+method. `ExpressionContext` is used to generate expressions and introduce variables.
+
+Currently there are two implementations:
+
+* Generic `ExpressionField` in `kmath-core` which allows construction of custom lazy expressions
+
+* Auto-differentiation expression in `kmath-commons` module allows to use full power of `DerivativeStructure`
+from commons-math. **TODO: add example**
diff --git a/doc/features.md b/doc/features.md
new file mode 100644
index 000000000..e6a820c1e
--- /dev/null
+++ b/doc/features.md
@@ -0,0 +1,17 @@
+# Features
+
+* [Algebra](./algebra.md) - [Context-based](./contexts.md) operations on different primitives and structures.
+
+* [NDStructures](./nd-structure.md)
+
+* [Linear algebra](./linear.md) - Matrices, operations and linear equations solving. To be moved to separate module. Currently supports basic
+api and multiple library back-ends.
+
+* [Histograms](./histograms.md) - Multidimensional histogram calculation and operations.
+
+* [Expressions](./expressions.md)
+
+* Commons math integration
+
+* Koma integration
+
diff --git a/docs/histograms.md b/doc/histograms.md
similarity index 100%
rename from docs/histograms.md
rename to doc/histograms.md
diff --git a/doc/linear.md b/doc/linear.md
new file mode 100644
index 000000000..bbcc435ba
--- /dev/null
+++ b/doc/linear.md
@@ -0,0 +1,19 @@
+## Basic linear algebra layout
+
+Kmath support for linear algebra organized in a context-oriented way. Meaning that operations are in most cases declared
+in context classes, and are not the members of classes that store data. This allows more flexible approach to maintain multiple
+back-ends. The new operations added as extensions to contexts instead of being member functions of data structures.
+
+Two major contexts used for linear algebra and hyper-geometry:
+
+* `VectorSpace` forms a mathematical space on top of array-like structure (`Buffer` and its typealias `Point` used for geometry).
+
+* `MatrixContext` forms a space-like context for 2d-structures. It does not store matrix size and therefore does not implement
+`Space` interface (it is not possible to create zero element without knowing the matrix size).
+
+## Vector spaces
+
+
+## Matrix operations
+
+## Back-end overview
\ No newline at end of file
diff --git a/docs/nd-structure.md b/doc/nd-structure.md
similarity index 81%
rename from docs/nd-structure.md
rename to doc/nd-structure.md
index 3e9203ec0..cf13c6a29 100644
--- a/docs/nd-structure.md
+++ b/doc/nd-structure.md
@@ -1,4 +1,4 @@
-# ND-structure generation and operations
+# Nd-structure generation and operations
**TODO**
@@ -10,17 +10,17 @@ structures. In `kmath` performance depends on which particular context was used
Let us consider following contexts:
```kotlin
// automatically build context most suited for given type.
- val autoField = NDField.auto(DoubleField, dim, dim)
- // specialized nd-field for Double. It works as generic Double field as well.
+ val autoField = NDField.auto(RealField, dim, dim)
+ // specialized nd-field for Double. It works as generic Double field as well
val specializedField = NDField.real(dim, dim)
//A generic boxing field. It should be used for objects, not primitives.
- val genericField = NDField.buffered(DoubleField, dim, dim)
+ val genericField = NDField.buffered(RealField, dim, dim)
```
-Now let us perform several tests and see, which implementation is best suited for each case:
+Now let us perform several tests and see which implementation is best suited for each case:
## Test case
-To test performance we will take 2d-structures with `dim = 1000` and add a structure filled with `1.0`
+In order to test performance we will take 2d-structures with `dim = 1000` and add a structure filled with `1.0`
to it `n = 1000` times.
## Specialized
@@ -35,8 +35,8 @@ The code to run this looks like:
```
The performance of this code is the best of all tests since it inlines all operations and is specialized for operation
with doubles. We will measure everything else relative to this one, so time for this test will be `1x` (real time
-on my computer is about 4.5 seconds). The only problem with this approach is that it requires specifying type
-from the beginning. Everyone does so anyway, so it is the recommended approach.
+on my computer is about 4.5 seconds). The only problem with this approach is that it requires to specify type
+from the beginning. Everyone do so anyway, so it is the recommended approach.
## Automatic
Let's do the same with automatic field inference:
@@ -49,7 +49,7 @@ Let's do the same with automatic field inference:
}
```
Ths speed of this operation is approximately the same as for specialized case since `NDField.auto` just
-returns the same `RealNDField` in this case. Of course, it is usually better to use specialized method to be sure.
+returns the same `RealNDField` in this case. Of course it is usually better to use specialized method to be sure.
## Lazy
Lazy field does not produce a structure when asked, instead it generates an empty structure and fills it on-demand
@@ -63,7 +63,7 @@ When one calls
}
}
```
-The result will be calculated almost immediately but the result will be empty. To get the full result
+The result will be calculated almost immediately but the result will be empty. In order to get the full result
structure one needs to call all its elements. In this case computation overhead will be huge. So this field never
should be used if one expects to use the full result structure. Though if one wants only small fraction, it could
save a lot of time.
@@ -94,7 +94,7 @@ The boxing field produced by
}
}
```
-is the slowest one, because it requires boxing and unboxing the `double` on each operation. It takes about
+obviously is the slowest one, because it requires to box and unbox the `double` on each operation. It takes about
`15x` time (**TODO: there seems to be a problem here, it should be slow, but not that slow**). This field should
never be used for primitives.
@@ -115,14 +115,12 @@ via extension function.
Usually it is bad idea to compare the direct numerical operation performance in different languages, but it hard to
work completely without frame of reference. In this case, simple numpy code:
```python
-import numpy as np
-
res = np.ones((1000,1000))
for i in range(1000):
res = res + 1.0
```
gives the completion time of about `1.1x`, which means that specialized kotlin code in fact is working faster (I think it is
because better memory management). Of course if one writes `res += 1.0`, the performance will be different,
-but it would be different case, because numpy overrides `+=` with in-place operations. In-place operations are
+but it would be differenc case, because numpy overrides `+=` with in-place operations. In-place operations are
available in `kmath` with `MutableNDStructure` but there is no field for it (one can still work with mapping
functions).
\ No newline at end of file
diff --git a/docs/algebra.md b/docs/algebra.md
deleted file mode 100644
index 20158a125..000000000
--- a/docs/algebra.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# Algebraic Structures and Algebraic Elements
-
-The mathematical operations in KMath are generally separated from mathematical objects. This means that to perform an
-operation, say `+`, one needs two objects of a type `T` and an algebra context, which draws appropriate operation up,
-say `Group`. Next one needs to run the actual operation in the context:
-
-```kotlin
-import space.kscience.kmath.operations.*
-
-val a: T = ...
-val b: T = ...
-val group: Group = ...
-
-val c = group { a + b }
-```
-
-At first glance, this distinction seems to be a needless complication, but in fact one needs to remember that in
-mathematics, one could draw up different operations on same objects. For example, one could use different types of
-geometry for vectors.
-
-## Algebraic Structures
-
-Primary mathematical contexts have the following hierarchy:
-
-`Field <: Ring <: Group <: Algebra`
-
-These interfaces follow real algebraic structures:
-
-- [Group](https://mathworld.wolfram.com/Group.html) defines addition, its identity element (i.e., 0) and additive
- inverse (-x);
-- [Ring](http://mathworld.wolfram.com/Ring.html) adds multiplication and its identity element (i.e., 1);
-- [Field](http://mathworld.wolfram.com/Field.html) adds division operation.
-
-A typical implementation of `Field` is the `DoubleField` which works on doubles, and `VectorSpace` for `Space`.
-
-In some cases algebra context can hold additional operations like `exp` or `sin`, and then it inherits appropriate
-interface. Also, contexts may have operations, which produce elements outside the context. For example, `Matrix.dot`
-operation produces a matrix with new dimensions, which can be incompatible with initial matrix in linear operations.
-
-## Spaces and Fields
-
-KMath introduces contexts for builtin algebraic structures:
-
-```kotlin
-import space.kscience.kmath.operations.*
-
-val c1 = Complex(1.0, 2.0)
-val c2 = ComplexField.i
-
-val c3 = c1 + c2
-// or
-val c3 = ComplexField { c1 + c2 }
-```
-
-Also, `ComplexField` features special operations to mix complex and real numbers, for example:
-
-```kotlin
-import space.kscience.kmath.operations.*
-
-val c1 = Complex(1.0, 2.0)
-val c2 = ComplexField { c1 - 1.0 } // Returns: Complex(re=0.0, im=2.0)
-val c3 = ComplexField { c1 - i * 2.0 }
-```
-
-**Note**: In theory it is possible to add behaviors directly to the context, but as for now Kotlin does not support
-that. Watch [KT-10468](https://youtrack.jetbrains.com/issue/KT-10468) and
-[KEEP-176](https://github.com/Kotlin/KEEP/pull/176) for updates.
-
-## Nested fields
-
-Contexts allow one to build more complex structures. For example, it is possible to create a `Matrix` from complex
-elements like so:
-
-```kotlin
-val element = NDElement.complex(shape = intArrayOf(2, 2)) { index: IntArray ->
- Complex(index[0].toDouble() - index[1].toDouble(), index[0].toDouble() + index[1].toDouble())
-}
-```
-
-The `element` in this example is a member of the `Field` of 2D structures, each element of which is a member of its own
-`ComplexField`. It is important one does not need to create a special n-d class to hold complex numbers and implement
-operations on it, one just needs to provide a field for its elements.
-
-**Note**: Fields themselves do not solve the problem of JVM boxing, but it is possible to solve with special contexts
-like
-`MemorySpec`.
diff --git a/docs/codestyle.md b/docs/codestyle.md
index 73ba5f754..53789f7b2 100644
--- a/docs/codestyle.md
+++ b/docs/codestyle.md
@@ -1,27 +1,22 @@
-# Coding Conventions
+# Local coding conventions
-Generally, KMath code follows general [Kotlin coding conventions](https://kotlinlang.org/docs/reference/coding-conventions.html), but with a number of small changes and clarifications.
+Kmath and other `scientifik` projects use general [kotlin code conventions](https://kotlinlang.org/docs/reference/coding-conventions.html), but with a number of small changes and clarifications.
-## Utility Class Naming
+## Utility class names
+File name should coincide with a name of one of the classes contained in the file or start with small letter and describe its contents.
-Filename should coincide with a name of one of the classes contained in the file or start with small letter and describe its contents.
-
-The code convention [here](https://kotlinlang.org/docs/reference/coding-conventions.html#source-file-names) says that file names should start with a capital letter even if file does not contain classes. Yet starting utility classes and aggregators with a small letter seems to be a good way to visually separate those files.
+The code convention [here](https://kotlinlang.org/docs/reference/coding-conventions.html#source-file-names) says that file names should start with capital letter even if file does not contain classes. Yet starting utility classes and aggregators with a small letter seems to be a good way to clearly visually separate those files.
This convention could be changed in future in a non-breaking way.
-## Private Variable Naming
+## Private variable names
+Private variable names could start with underscore `_` in case the private mutable variable is shadowed by the public read-only value with the same meaning.
-Private variables' names may start with underscore `_` for of the private mutable variable is shadowed by the public read-only value with the same meaning.
-
-This rule does not permit underscores in names, but it is sometimes useful to "underscore" the fact that public and private versions draw up the same entity. It is allowed only for private variables.
+Code convention do not permit underscores in names, but is is sometimes useful to "underscore" the fact that public and private versions define the same entity. It is allowed only for private variables.
This convention could be changed in future in a non-breaking way.
-## Functions and Properties One-liners
+## Functions and properties one-liners
+Use one-liners when they occupy single code window line both for functions and properties with getters like `val b: String get() = "fff"`. The same should be done with multiline expressions when they could be cleanly separated.
-Use one-liners when they occupy single code window line both for functions and properties with getters like
-`val b: String get() = "fff"`. The same should be performed with multiline expressions when they could be
-cleanly separated.
-
-There is no universal consensus whenever use `fun a() = ...` or `fun a() { return ... }`. Yet from reader outlook one-lines seem to better show that the property or function is easily calculated.
+There is not general consensus whenever use `fun a() = {}` or `fun a(){return}`. Yet from reader perspective one-lines seem to better show that the property or function is easily calculated.
\ No newline at end of file
diff --git a/docs/contexts.md b/docs/contexts.md
deleted file mode 100644
index c26333860..000000000
--- a/docs/contexts.md
+++ /dev/null
@@ -1,73 +0,0 @@
-# Context-oriented mathematics
-
-## The problem
-
-A known problem for implementing mathematics in statically-typed languages (but not only in them) is that different sets
-of mathematical operators can be defined on the same mathematical objects. Sometimes there is no single way to treat
-some operations, including basic arithmetic operations, on a Java/Kotlin `Number`. Sometimes there are different ways to
-define the same structure, such as Euclidean and elliptic geometry vector spaces over real vectors. Another problem
-arises when one wants to add some kind of behavior to an existing entity. In dynamic languages those problems are
-usually solved by adding dynamic context-specific behaviors at runtime, but this solution has a lot of drawbacks.
-
-## Context-oriented approach
-
-One possible solution to these problems is to divorce numerical representations from behaviors. For example in Kotlin
-one can define a separate class representing some entity without any operations, ex. a complex number:
-
-```kotlin
-data class Complex(val re: Double, val im: Double)
-```
-
-And then to define a separate class or singleton, representing an operation on those complex numbers:
-
-```kotlin
-object ComplexOperations {
- operator fun Complex.plus(other: Complex) = Complex(re + other.re, im + other.im)
- operator fun Complex.minus(other: Complex) = Complex(re - other.re, im - other.im)
-}
-```
-
-In Java, applying such external operations could be cumbersome, but Kotlin has a unique feature that allows us
-implement this
-naturally: [extensions with receivers](https://kotlinlang.org/docs/reference/extensions.html#extension-functions). In
-Kotlin, an operation on complex number could be implemented as:
-
-```kotlin
-with(ComplexOperations) { c1 + c2 - c3 }
-```
-
-Kotlin also allows the creation of functions with receivers:
-
-```kotlin
-fun ComplexOperations.doSomethingWithComplex(c1: Complex, c2: Complex, c3: Complex) = c1 + c2 - c3
-
-ComplexOperations.doComethingWithComplex(c1, c2, c3)
-```
-
-In fact, whole parts of a program may be run within a mathematical context or even multiple nested contexts.
-
-In KMath, contexts are not only responsible for operations, but also for raw object creation and advanced features.
-
-## Other possibilities
-
-### Type classes
-
-An obvious candidate to get more or less the same functionality is the type class, which allows one to bind a behavior
-to a specific type without modifying the type itself. On the plus side, type classes do not require explicit context
-declaration, so the code looks cleaner. On the minus side, if there are different sets of behaviors for the same types,
-it is impossible to combine them into one module. Also, unlike type classes, context can have parameters or even state.
-For example in KMath, sizes and strides for `NDElement` or `Matrix` could be moved to context to optimize performance in
-case of a large amount of structures.
-
-### Wildcard imports and importing-on-demand
-
-Sometimes, one may wish to use a single context throughout a file. In this case, is possible to import all members from
-a package or file, via `import context.complex.*`. Effectively, this is the same as enclosing an entire file with a
-single context. However, when using multiple contexts, this technique can introduce operator ambiguity, due to namespace
-pollution. If there are multiple scoped contexts that define the same operation, it is still possible to import
-specific operations as needed, without using an explicit context with extension functions, for example:
-
-```
-import context.complex.op1
-import context.quaternion.op2
-```
diff --git a/docs/diagrams/core.puml b/docs/diagrams/core.puml
deleted file mode 100644
index 87f8f2e2d..000000000
--- a/docs/diagrams/core.puml
+++ /dev/null
@@ -1,1020 +0,0 @@
-@startuml
-interface "ColumnarData" {
- size: Int
-}
-interface "XYColumnarData" {
- x: Buffer
- y: Buffer
-}
-interface "XYErrorColumnarData" {
- yErr: Buffer
-}
-interface "XYZColumnarData" {
- z: Buffer
-}
-interface "Domain" {
- dimension: Int
-}
-interface "DoubleDomain" {
-
-}
-class "HyperSquareDomain" {
- lower: Buffer
- upper: Buffer
-}
-class "UnconstrainedDomain" {
- dimension: Int
-}
-class "UnivariateDomain" {
- range: ClosedFloatingPointRange
-}
-interface "DifferentiableExpression" {
-
-}
-interface "SpecialDifferentiableExpression" {
-
-}
-abstract "FirstDerivativeExpression" {
-
-}
-interface "AutoDiffProcessor" {
-
-}
-interface "Expression" {
-
-}
-interface "ExpressionAlgebra" {
-
-}
-abstract "FunctionalExpressionAlgebra" {
- algebra: A
-}
-class "FunctionalExpressionGroup" {
- algebra: A
-}
-class "FunctionalExpressionRing" {
- algebra: A
-}
-class "FunctionalExpressionField" {
- algebra: A
-}
-class "FunctionalExpressionExtendedField" {
- algebra: A
-}
-interface "MST" {
-
-}
-class "Numeric" {
- value: Number
-}
-class "Unary" {
- operation: String
- value: MST
-}
-class "Binary" {
- operation: String
- left: MST
- right: MST
-}
-class "InnerAlgebra" {
- algebra: Algebra
- arguments: Map
-}
-class "MstNumericAlgebra" {
- number()
- bindSymbolOrNull()
- bindSymbol()
- unaryOperationFunction()
- binaryOperationFunction()
-}
-class "MstGroup" {
- zero: MST.Numericnumber()
- bindSymbolOrNull()
- add()
- unaryPlus()
- unaryMinus()
- minus()
- scale()
- binaryOperationFunction()
- unaryOperationFunction()
-}
-class "MstRing" {
- zero: MST.Numeric
- one: MST.Numericnumber()
- bindSymbolOrNull()
- add()
- scale()
- multiply()
- unaryPlus()
- unaryMinus()
- minus()
- binaryOperationFunction()
- unaryOperationFunction()
-}
-class "MstField" {
- zero: MST.Numeric
- one: MST.NumericbindSymbolOrNull()
- number()
- add()
- scale()
- multiply()
- divide()
- unaryPlus()
- unaryMinus()
- minus()
- binaryOperationFunction()
- unaryOperationFunction()
-}
-class "MstExtendedField" {
- zero: MST.Numeric
- one: MST.NumericbindSymbolOrNull()
- number()
- sin()
- cos()
- tan()
- asin()
- acos()
- atan()
- sinh()
- cosh()
- tanh()
- asinh()
- acosh()
- atanh()
- add()
- sqrt()
- scale()
- multiply()
- divide()
- unaryPlus()
- unaryMinus()
- minus()
- power()
- exp()
- ln()
- binaryOperationFunction()
- unaryOperationFunction()
-}
-class "MstLogicAlgebra" {
- bindSymbolOrNull()
- const()
- not()
- and()
- or()
- xor()
-}
-class "AutoDiffValue" {
- value: T
-}
-class "DerivationResult" {
- value: T
- derivativeValues: Map
- context: Field
-}
-class "SimpleAutoDiffField" {
- context: F
- bindings: Map
-}
-class "AutoDiffVariableWithDerivative" {
- identity: String
- value: T
- d: T
-}
-class "SimpleAutoDiffExpression" {
- field: F
- function: SimpleAutoDiffField
-}
-class "SimpleAutoDiffExtendedField" {
- context: F
- bindings: Map
-}
-interface "Symbol" {
- identity: String
-}
-class "StringSymbol" {
- identity: String
-}
-interface "SymbolIndexer" {
- symbols: List
-}
-class "SimpleSymbolIndexer" {
- symbols: List
-}
-class "BufferedLinearSpace" {
- elementAlgebra: A
- bufferFactory: BufferFactory
-}
-interface "LinearSolver" {
-
-}
-interface "LinearSpace" {
- elementAlgebra: A
-}
-class "LupDecomposition" {
- context: LinearSpace
- elementContext: Field
- lu: Matrix
- pivot: IntArray
- even: Boolean
-}
-class "MatrixBuilder" {
- linearSpace: LinearSpace
- rows: Int
- columns: Int
-}
-class "SymmetricMatrixFeature" {
-
-}
-interface "MatrixFeature" {
-
-}
-interface "DiagonalFeature" {
-
-}
-class "ZeroFeature" {
-
-}
-class "UnitFeature" {
-
-}
-interface "InverseMatrixFeature" {
- inverse: Matrix
-}
-interface "DeterminantFeature" {
- determinant: T
-}
-class "LFeature" {
-
-}
-class "UFeature" {
-
-}
-interface "LUDecompositionFeature" {
- l: Matrix
- u: Matrix
-}
-interface "LupDecompositionFeature" {
- l: Matrix
- u: Matrix
- p: Matrix
-}
-class "OrthogonalFeature" {
-
-}
-interface "QRDecompositionFeature" {
- q: Matrix
- r: Matrix
-}
-interface "CholeskyDecompositionFeature" {
- l: Matrix
-}
-interface "SingularValueDecompositionFeature" {
- u: Matrix
- s: Matrix
- v: Matrix
- singularValues: Point
-}
-class "MatrixWrapper" {
- origin: Matrix
- features: FeatureSet
-}
-class "TransposedFeature" {
- original: Matrix
-}
-class "VirtualMatrix" {
- rowNum: Int
- colNum: Int
- generator: (i:Int,j:Int)->T
-}
-class "UnstableKMathAPI" {
-
-}
-class "PerformancePitfall" {
- message: String
-}
-interface "Featured" {
-
-}
-interface "Feature" {
- key: FeatureKey
-}
-class "FeatureSet" {
- features: Map
-}
-interface "Loggable" {
-
-}
-class "ShapeMismatchException" {
- expected: IntArray
- actual: IntArray
-}
-interface "AlgebraND" {
- shape: IntArray
- elementContext: C
-}
-interface "GroupND" {
-
-}
-interface "RingND" {
-
-}
-interface "FieldND" {
-
-}
-interface "BufferAlgebraND" {
- strides: Strides
- bufferFactory: BufferFactory
- buffer: Buffer
-}
-class "BufferedGroupND" {
- shape: IntArray
- elementContext: A
- bufferFactory: BufferFactory
-}
-class "BufferedRingND" {
- shape: IntArray
- elementContext: R
- bufferFactory: BufferFactory
-}
-class "BufferedFieldND" {
- shape: IntArray
- elementContext: R
- bufferFactory: BufferFactory
-}
-class "BufferND" {
- strides: Strides
- buffer: Buffer
-}
-class "MutableBufferND" {
- strides: Strides
- mutableBuffer: MutableBuffer
-}
-class "DoubleFieldND" {
- shape: IntArray
-}
-class "ShortRingND" {
- shape: IntArray
-}
-interface "Structure1D" {
- dimension: Int
-}
-interface "MutableStructure1D" {
-
-}
-class "Structure1DWrapper" {
- structure: StructureND
-}
-class "MutableStructure1DWrapper" {
- structure: MutableStructureND
-}
-class "Buffer1DWrapper" {
- buffer: Buffer
-}
-class "MutableBuffer1DWrapper" {
- buffer: MutableBuffer
-}
-interface "Structure2D" {
- rowNum: Int
- colNum: Int
- shape: IntArray
- rows: List
- columns: List
-}
-interface "MutableStructure2D" {
- rows: List
- columns: List
-}
-class "Structure2DWrapper" {
- structure: StructureND
-}
-class "MutableStructure2DWrapper" {
- structure: MutableStructureND
-}
-interface "StructureFeature" {
-
-}
-interface "StructureND" {
- shape: IntArray
- dimension: Int
-}
-interface "MutableStructureND" {
-
-}
-interface "Strides" {
- shape: IntArray
- strides: IntArray
- linearSize: Int
-}
-class "DefaultStrides" {
- shape: IntArray
-}
-class "KMathContext" {
-
-}
-interface "Algebra" {
-
-}
-interface "GroupOperations" {
-
-}
-interface "Group" {
- zero: T
-}
-interface "RingOperations" {
-
-}
-interface "Ring" {
- one: T
-}
-interface "FieldOperations" {
-
-}
-interface "Field" {
-
-}
-interface "AlgebraElement" {
- context: C
-}
-interface "GroupElement" {
-
-}
-interface "RingElement" {
-
-}
-interface "FieldElement" {
-
-}
-class "BigIntField" {
- zero: BigInt
- one: BigIntnumber()
- unaryMinus()
- add()
- scale()
- multiply()
- divide()
- unaryPlus()
- unaryMinus()
-}
-class "BigInt" {
- sign: Byte
- magnitude: Magnitude
-}
-interface "BufferAlgebra" {
- bufferFactory: BufferFactory
- elementAlgebra: A
-}
-class "BufferField" {
- bufferFactory: BufferFactory
- elementAlgebra: A
- size: Int
-}
-interface "LogicAlgebra" {
-
-}
-class "BooleanAlgebra" {
- const()
- not()
- and()
- or()
- xor()
-}
-interface "ExtendedFieldOperations" {
-
-}
-interface "ExtendedField" {
-
-}
-class "DoubleField" {
- zero: Double
- one: Doublenumber()
- binaryOperationFunction()
- add()
- multiply()
- divide()
- scale()
- sin()
- cos()
- tan()
- acos()
- asin()
- atan()
- sinh()
- cosh()
- tanh()
- asinh()
- acosh()
- atanh()
- sqrt()
- power()
- exp()
- ln()
- norm()
- unaryMinus()
- plus()
- minus()
- times()
- div()
-}
-class "FloatField" {
- zero: Float
- one: Floatnumber()
- binaryOperationFunction()
- add()
- scale()
- multiply()
- divide()
- sin()
- cos()
- tan()
- acos()
- asin()
- atan()
- sinh()
- cosh()
- tanh()
- asinh()
- acosh()
- atanh()
- sqrt()
- power()
- exp()
- ln()
- norm()
- unaryMinus()
- plus()
- minus()
- times()
- div()
-}
-class "IntRing" {
- zero: Int
- one: Intnumber()
- add()
- multiply()
- norm()
- unaryMinus()
- plus()
- minus()
- times()
-}
-class "ShortRing" {
- zero: Short
- one: Shortnumber()
- add()
- multiply()
- norm()
- unaryMinus()
- plus()
- minus()
- times()
-}
-class "ByteRing" {
- zero: Byte
- one: Bytenumber()
- add()
- multiply()
- norm()
- unaryMinus()
- plus()
- minus()
- times()
-}
-class "LongRing" {
- zero: Long
- one: Longnumber()
- add()
- multiply()
- norm()
- unaryMinus()
- plus()
- minus()
- times()
-}
-interface "NumericAlgebra" {
-
-}
-interface "ScaleOperations" {
-
-}
-interface "NumbersAddOperations" {
-
-}
-interface "TrigonometricOperations" {
-
-}
-interface "PowerOperations" {
-
-}
-interface "ExponentialOperations" {
-
-}
-interface "Norm" {
-
-}
-interface "Buffer" {
- size: Int
-}
-interface "MutableBuffer" {
-
-}
-class "ListBuffer" {
- list: List
-}
-class "MutableListBuffer" {
- list: MutableList
-}
-class "ArrayBuffer" {
- array: Array
-}
-class "ReadOnlyBuffer" {
- buffer: MutableBuffer
-}
-class "VirtualBuffer" {
- size: Int
- generator: (Int)->T
-}
-class "BufferAccessor2D" {
- rowNum: Int
- colNum: Int
- factory: MutableBufferFactory
-}
-class "Row" {
- buffer: MutableBuffer
- rowIndex: Int
-}
-class "DoubleBuffer" {
- array: DoubleArray
-}
-class "DoubleBufferFieldOperations" {
- unaryMinus()
- add()
- multiply()
- divide()
- sin()
- cos()
- tan()
- asin()
- acos()
- atan()
- sinh()
- cosh()
- tanh()
- asinh()
- acosh()
- atanh()
- power()
- exp()
- ln()
-}
-class "DoubleL2Norm" {
- norm()
-}
-class "DoubleBufferField" {
- size: Int
-}
-enum "ValueFlag" {
- NAN
- MISSING
- NEGATIVE_INFINITY
- POSITIVE_INFINITY
-}
-interface "FlaggedBuffer" {
-
-}
-class "FlaggedDoubleBuffer" {
- values: DoubleArray
- flags: ByteArray
-}
-class "FloatBuffer" {
- array: FloatArray
-}
-class "IntBuffer" {
- array: IntArray
-}
-class "LongBuffer" {
- array: LongArray
-}
-class "MemoryBuffer" {
- memory: Memory
- spec: MemorySpec
-}
-class "MutableMemoryBuffer" {
- memory: Memory
- spec: MemorySpec
-}
-class "ShortBuffer" {
- array: ShortArray
-}
-class "ExpressionFieldTest" {
- x
-}
-class "InterpretTest" {
-
-}
-class "SimpleAutoDiffTest" {
- x
- y
- z
-}
-class "DoubleLUSolverTest" {
-
-}
-class "MatrixTest" {
-
-}
-class "CumulativeKtTest" {
-
-}
-class "BigIntAlgebraTest" {
-
-}
-class "BigIntConstructorTest" {
-
-}
-class "BigIntConversionsTest" {
-
-}
-class "BigIntOperationsTest" {
-
-}
-class "DoubleFieldTest" {
-
-}
-class "NDFieldTest" {
-
-}
-class "NumberNDFieldTest" {
- algebra
- array1
- array2
-}
-class "L2Norm" {
- norm()
-}
-interface "AlgebraicVerifier" {
- algebra: A
-}
-class "FieldVerifier" {
- algebra: A
- a: T
- b: T
- c: T
- x: Number
-}
-class "RingVerifier" {
- algebra: A
- a: T
- b: T
- c: T
- x: Number
-}
-class "SpaceVerifier" {
- algebra: S
- a: T
- b: T
- c: T
- x: Number
-}
-class "JBigIntegerField" {
- zero: BigInteger
- one: BigIntegernumber()
- add()
- minus()
- multiply()
- unaryMinus()
-}
-abstract "JBigDecimalFieldBase" {
- mathContext: MathContext
-}
-class "JBigDecimalField" {
- mathContext: MathContext
-}
-"ColumnarData" <|--- XYColumnarData
-"XYColumnarData" <|--- XYErrorColumnarData
-"XYColumnarData" <|--- XYZColumnarData
-"Domain" <|--- DoubleDomain
-"DoubleDomain" <|--- HyperSquareDomain
-"DoubleDomain" <|--- UnconstrainedDomain
-"DoubleDomain" <|--- UnivariateDomain
-"Expression" <|--- DifferentiableExpression
-"DifferentiableExpression" <|--- SpecialDifferentiableExpression
-"DifferentiableExpression" <|--- FirstDerivativeExpression
-"Algebra" <|--- ExpressionAlgebra
-"ExpressionAlgebra" <|--- FunctionalExpressionAlgebra
-"FunctionalExpressionAlgebra" <|--- FunctionalExpressionGroup
-"Group" <|--- FunctionalExpressionGroup
-"FunctionalExpressionGroup" <|--- FunctionalExpressionRing
-"Ring" <|--- FunctionalExpressionRing
-"FunctionalExpressionRing" <|--- FunctionalExpressionField
-"Field" <|--- FunctionalExpressionField
-"ScaleOperations" <|--- FunctionalExpressionField
-"FunctionalExpressionField" <|--- FunctionalExpressionExtendedField
-"ExtendedField" <|--- FunctionalExpressionExtendedField
-"MST" <|--- Numeric
-"MST" <|--- Unary
-"MST" <|--- Binary
-"NumericAlgebra" <|--- InnerAlgebra
-"NumericAlgebra" <|--- MstNumericAlgebra
-"Group" <|--- MstGroup
-"NumericAlgebra" <|--- MstGroup
-"ScaleOperations" <|--- MstGroup
-"Ring" <|--- MstRing
-"NumbersAddOperations" <|--- MstRing
-"ScaleOperations" <|--- MstRing
-"Field" <|--- MstField
-"NumbersAddOperations" <|--- MstField
-"ScaleOperations" <|--- MstField
-"ExtendedField" <|--- MstExtendedField
-"NumericAlgebra" <|--- MstExtendedField
-"LogicAlgebra" <|--- MstLogicAlgebra
-"Field" <|--- SimpleAutoDiffField
-"ExpressionAlgebra" <|--- SimpleAutoDiffField
-"NumbersAddOperations" <|--- SimpleAutoDiffField
-"AutoDiffValue" <|--- AutoDiffVariableWithDerivative
-"Symbol" <|--- AutoDiffVariableWithDerivative
-"FirstDerivativeExpression" <|--- SimpleAutoDiffExpression
-"ExtendedField" <|--- SimpleAutoDiffExtendedField
-"ScaleOperations" <|--- SimpleAutoDiffExtendedField
-'"" <|--- SimpleAutoDiffExtendedField
-"SimpleAutoDiffField" <|--- SimpleAutoDiffExtendedField
-"MST" <|--- Symbol
-"Symbol" <|--- StringSymbol
-"SymbolIndexer" <|--- SimpleSymbolIndexer
-"LinearSpace" <|--- BufferedLinearSpace
-"LupDecompositionFeature" <|--- LupDecomposition
-"DeterminantFeature" <|--- LupDecomposition
-"MatrixFeature" <|--- SymmetricMatrixFeature
-"StructureFeature" <|--- MatrixFeature
-"MatrixFeature" <|--- DiagonalFeature
-"DiagonalFeature" <|--- ZeroFeature
-"DiagonalFeature" <|--- UnitFeature
-"MatrixFeature" <|--- InverseMatrixFeature
-"MatrixFeature" <|--- DeterminantFeature
-"MatrixFeature" <|--- LFeature
-"MatrixFeature" <|--- UFeature
-"MatrixFeature" <|--- LUDecompositionFeature
-"MatrixFeature" <|--- LupDecompositionFeature
-"MatrixFeature" <|--- OrthogonalFeature
-"MatrixFeature" <|--- QRDecompositionFeature
-"MatrixFeature" <|--- CholeskyDecompositionFeature
-"MatrixFeature" <|--- SingularValueDecompositionFeature
-'"Matrixbyorigin{
-'
-'
-' @UnstableKMathAPI
-' @Suppress
-'overridefungetFeature:F? =
-'features.getFeature
-'
-'overridefuntoString"
-'}" <|--- MatrixWrapper
-"MatrixFeature" <|--- TransposedFeature
-"Matrix" <|--- VirtualMatrix
-"Featured" <|--- FeatureSet
-"RuntimeException" <|--- ShapeMismatchException
-"Group" <|--- GroupND
-"AlgebraND" <|--- GroupND
-"Ring" <|--- RingND
-"GroupND" <|--- RingND
-"Field" <|--- FieldND
-"RingND" <|--- FieldND
-"AlgebraND" <|--- BufferAlgebraND
-"GroupND" <|--- BufferedGroupND
-"BufferAlgebraND" <|--- BufferedGroupND
-"BufferedGroupND" <|--- BufferedRingND
-"RingND" <|--- BufferedRingND
-"BufferedRingND" <|--- BufferedFieldND
-"FieldND" <|--- BufferedFieldND
-"StructureND" <|--- BufferND
-"MutableStructureND" <|--- MutableBufferND
-"BufferND" <|--- MutableBufferND
-"BufferedFieldND" <|--- DoubleFieldND
-'"
-'" <|--- DoubleFieldND
-'"NumbersAddOperations" <|--- DoubleFieldND
-'"
-'" <|--- DoubleFieldND
-'"ScaleOperations" <|--- DoubleFieldND
-'"
-'" <|--- DoubleFieldND
-"ExtendedField" <|--- DoubleFieldND
-"BufferedRingND" <|--- ShortRingND
-'"
-'" <|--- ShortRingND
-"NumbersAddOperations" <|--- ShortRingND
-"StructureND" <|--- Structure1D
-"Buffer" <|--- Structure1D
-"Structure1D" <|--- MutableStructure1D
-"MutableStructureND" <|--- MutableStructure1D
-"MutableBuffer" <|--- MutableStructure1D
-"Structure1D" <|--- Structure1DWrapper
-"MutableStructure1D" <|--- MutableStructure1DWrapper
-"Structure1D" <|--- Buffer1DWrapper
-"MutableStructure1D" <|--- MutableBuffer1DWrapper
-"StructureND" <|--- Structure2D
-"Structure2D" <|--- MutableStructure2D
-"MutableStructureND" <|--- MutableStructure2D
-"Structure2D" <|--- Structure2DWrapper
-"MutableStructure2D" <|--- MutableStructure2DWrapper
-"Feature" <|--- StructureFeature
-"Featured" <|--- StructureND
-"StructureND" <|--- MutableStructureND
-"Strides" <|--- DefaultStrides
-"Algebra" <|--- GroupOperations
-"GroupOperations" <|--- Group
-"GroupOperations" <|--- RingOperations
-"Group" <|--- Ring
-"RingOperations" <|--- Ring
-"RingOperations" <|--- FieldOperations
-"Ring" <|--- Field
-"FieldOperations" <|--- Field
-"ScaleOperations" <|--- Field
-"NumericAlgebra" <|--- Field
-"AlgebraElement" <|--- GroupElement
-"GroupElement" <|--- RingElement
-"RingElement" <|--- FieldElement
-"Field" <|--- BigIntField
-"NumbersAddOperations" <|--- BigIntField
-"ScaleOperations" <|--- BigIntField
-"Comparable" <|--- BigInt
-"Algebra" <|--- BufferAlgebra
-"BufferAlgebra" <|--- BufferField
-"Field" <|--- BufferField
-"Algebra" <|--- LogicAlgebra
-"LogicAlgebra" <|--- BooleanAlgebra
-"FieldOperations" <|--- ExtendedFieldOperations
-'"
-'" <|--- ExtendedFieldOperations
-'"TrigonometricOperations" <|--- ExtendedFieldOperations
-'"
-'" <|--- ExtendedFieldOperations
-'"PowerOperations" <|--- ExtendedFieldOperations
-'"
-'" <|--- ExtendedFieldOperations
-"ExponentialOperations" <|--- ExtendedFieldOperations
-"ExtendedFieldOperations" <|--- ExtendedField
-"Field" <|--- ExtendedField
-"NumericAlgebra" <|--- ExtendedField
-"ScaleOperations" <|--- ExtendedField
-"ExtendedField" <|--- DoubleField
-"Norm" <|--- DoubleField
-"ScaleOperations" <|--- DoubleField
-"ExtendedField" <|--- FloatField
-"Norm" <|--- FloatField
-"Ring" <|--- IntRing
-"Norm" <|--- IntRing
-"NumericAlgebra" <|--- IntRing
-"Ring" <|--- ShortRing
-"Norm" <|--- ShortRing
-"NumericAlgebra" <|--- ShortRing
-"Ring" <|--- ByteRing
-"Norm" <|--- ByteRing
-"NumericAlgebra" <|--- ByteRing
-"Ring" <|--- LongRing
-"Norm" <|--- LongRing
-"NumericAlgebra" <|--- LongRing
-"Algebra" <|--- NumericAlgebra
-"Algebra" <|--- ScaleOperations
-"Ring" <|--- NumbersAddOperations
-"NumericAlgebra" <|--- NumbersAddOperations
-"Algebra" <|--- TrigonometricOperations
-"Algebra" <|--- PowerOperations
-"Algebra" <|--- ExponentialOperations
-"Buffer" <|--- MutableBuffer
-"Buffer" <|--- ListBuffer
-"MutableBuffer" <|--- MutableListBuffer
-"MutableBuffer" <|--- ArrayBuffer
-"Buffer" <|--- ReadOnlyBuffer
-"Buffer" <|--- VirtualBuffer
-"MutableBuffer" <|--- Row
-"MutableBuffer" <|--- DoubleBuffer
-"ExtendedFieldOperations" <|--- DoubleBufferFieldOperations
-"Norm" <|--- DoubleL2Norm
-"ExtendedField" <|--- DoubleBufferField
-"Norm" <|--- DoubleBufferField
-"Buffer" <|--- FlaggedBuffer
-"FlaggedBuffer" <|--- FlaggedDoubleBuffer
-'"
-'" <|--- FlaggedDoubleBuffer
-"Buffer" <|--- FlaggedDoubleBuffer
-"MutableBuffer" <|--- FloatBuffer
-"MutableBuffer" <|--- IntBuffer
-"MutableBuffer" <|--- LongBuffer
-"Buffer" <|--- MemoryBuffer
-"MemoryBuffer" <|--- MutableMemoryBuffer
-'"
-'" <|--- MutableMemoryBuffer
-"MutableBuffer" <|--- MutableMemoryBuffer
-"MutableBuffer" <|--- ShortBuffer
-"Norm" <|--- L2Norm
-"RingVerifier" <|--- FieldVerifier
-"SpaceVerifier" <|--- RingVerifier
-"AlgebraicVerifier" <|--- SpaceVerifier
-"Ring" <|--- JBigIntegerField
-"NumericAlgebra" <|--- JBigIntegerField
-"Field" <|--- JBigDecimalFieldBase
-"PowerOperations" <|--- JBigDecimalFieldBase
-"NumericAlgebra" <|--- JBigDecimalFieldBase
-"ScaleOperations" <|--- JBigDecimalFieldBase
-"JBigDecimalFieldBase" <|--- JBigDecimalField
-@enduml
\ No newline at end of file
diff --git a/docs/expressions.md b/docs/expressions.md
deleted file mode 100644
index e6250110c..000000000
--- a/docs/expressions.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# Expressions
-
-Expressions is a feature, which allows constructing lazily or immediately calculated parametric mathematical expressions.
-
-The potential use-cases for it (so far) are following:
-
-* lazy evaluation (in general simple lambda is better, but there are some border cases);
-* automatic differentiation in single-dimension and in multiple dimensions;
-* generation of mathematical syntax trees with subsequent code generation for other languages;
-* symbolic computations, especially differentiation (and some other actions with `kmath-symja` integration with Symja's `IExpr`—integration, simplification, and more);
-* visualization with `kmath-jupyter`.
-
-The workhorse of this API is `Expression` interface, which exposes single `operator fun invoke(arguments: Map): T`
-method. `ExpressionAlgebra` is used to generate expressions and introduce variables.
-
-Currently there are two implementations:
-
-* Generic `ExpressionField` in `kmath-core` which allows construction of custom lazy expressions
-
-* Auto-differentiation expression in `kmath-commons` module allows using full power of `DerivativeStructure`
-from commons-math. **TODO: add example**
diff --git a/docs/images/KM.svg b/docs/images/KM.svg
deleted file mode 100644
index 55a4339b1..000000000
--- a/docs/images/KM.svg
+++ /dev/null
@@ -1,67 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/docs/images/KM_mono.svg b/docs/images/KM_mono.svg
deleted file mode 100644
index f1194f887..000000000
--- a/docs/images/KM_mono.svg
+++ /dev/null
@@ -1,62 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/docs/images/KMath.svg b/docs/images/KMath.svg
deleted file mode 100644
index 509a184bc..000000000
--- a/docs/images/KMath.svg
+++ /dev/null
@@ -1,101 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/docs/images/KMath_mono.svg b/docs/images/KMath_mono.svg
deleted file mode 100644
index e781979e2..000000000
--- a/docs/images/KMath_mono.svg
+++ /dev/null
@@ -1,397 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/docs/linear.md b/docs/linear.md
deleted file mode 100644
index 2a05499ef..000000000
--- a/docs/linear.md
+++ /dev/null
@@ -1,31 +0,0 @@
-## Basic linear algebra layout
-
-KMath support for linear algebra organized in a context-oriented way, which means that operations are in most cases declared in context classes, and are not the members of classes that store data. This allows more flexible approach to maintain multiple back-ends. The new operations added as extensions to contexts instead of being member functions of data structures.
-
-The main context for linear algebra over matrices and vectors is `LinearSpace`, which defines addition and dot products of matrices and vectors:
-
-```kotlin
-import space.kscience.kmath.linear.*
-
-LinearSpace.Companion.real {
- val vec = buildVector(10) { i -> i.toDouble() }
- val mat = buildMatrix(10, 10) { i, j -> i.toDouble() + j }
-
- // Addition
- vec + vec
- mat + mat
-
- // Multiplication by scalar
- vec * 2.0
- mat * 2.0
-
- // Dot product
- mat dot vec
- mat dot mat
-}
-```
-
-## Backends overview
-
-### EJML
-### Commons Math
diff --git a/docs/polynomials.md b/docs/polynomials.md
deleted file mode 100644
index b255acda1..000000000
--- a/docs/polynomials.md
+++ /dev/null
@@ -1,172 +0,0 @@
-# Polynomials and Rational Functions
-
-KMath provides a way to work with uni- and multivariate polynomials and rational functions. It includes full support of arithmetic operations of integers, **constants** (elements of ring polynomials are build over), variables (for certain multivariate implementations), polynomials and rational functions encapsulated in so-called **polynomial space** and **rational function space** and some other utilities such as algebraic differentiation and substitution.
-
-## Concrete realizations
-
-There are 3 approaches to represent polynomials:
-1. For univariate polynomials one can represent and store polynomial as a list of coefficients for each power of the variable. I.e. polynomial $a_0 + \dots + a_n x^n $ can be represented as a finite sequence $(a_0; \dots; a_n)$. (Compare to sequential definition of polynomials.)
-2. For multivariate polynomials one can represent and store polynomial as a matching (in programming it is called "map" or "dictionary", in math it is called [functional relation](https://en.wikipedia.org/wiki/Binary_relation#Special_types_of_binary_relations)) of each "**term signature**" (that describes what variables and in what powers appear in the term) with corresponding coefficient of the term. But there are 2 possible approaches of term signature representation:
- 1. One can number all the variables, so term signature can be represented as a sequence describing powers of the variables. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for natural or zero $d_i $) can be represented as a finite sequence $(d_0; \dots; d_n)$.
- 2. One can represent variables as objects ("**labels**"), so term signature can be also represented as a matching of each appeared variable with its power in the term. I.e. signature of term $c \\; x_0^{d_0} \dots x_n^{d_n} $ (for natural non-zero $d_i $) can be represented as a finite matching $(x_0 \to d_1; \dots; x_n \to d_n)$.
-
-All that three approaches are implemented by "list", "numbered", and "labeled" versions of polynomials and polynomial spaces respectively. Whereas all rational functions are represented as fractions with corresponding polynomial numerator and denominator, and rational functions' spaces are implemented in the same way as usual field of rational numbers (or more precisely, as any field of fractions over integral domain) should be implemented.
-
-So here are a bit of details. Let `C` by type of constants. Then:
-1. `ListPolynomial`, `ListPolynomialSpace`, `ListRationalFunction` and `ListRationalFunctionSpace` implement the first scenario. `ListPolynomial` stores polynomial $a_0 + \dots + a_n x^n $ as a coefficients list `listOf(a_0, ..., a_n)` (of type `List`).
-
- They also have variation `ScalableListPolynomialSpace` that replaces former polynomials and implements `ScaleOperations`.
-2. `NumberedPolynomial`, `NumberedPolynomialSpace`, `NumberedRationalFunction` and `NumberedRationalFunctionSpace` implement second scenario. `NumberedPolynomial` stores polynomials as structures of type `Map, C>`. Signatures are stored as `List`. To prevent ambiguity signatures should not end with zeros.
-3. `LabeledPolynomial`, `LabeledPolynomialSpace`, `LabeledRationalFunction` and `LabeledRationalFunctionSpace` implement third scenario using common `Symbol` as variable type. `LabeledPolynomial` stores polynomials as structures of type `Map