Merge pull request #49 from mipt-npm/dev
Dev
This commit is contained in:
commit
d929cfeab8
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,4 +8,4 @@
|
|||||||
# Cache of project
|
# Cache of project
|
||||||
.gradletasknamecache
|
.gradletasknamecache
|
||||||
|
|
||||||
artifactory.gradle
|
gradle.properties
|
55
README.md
55
README.md
@ -1,27 +1,48 @@
|
|||||||
|
Bintray: [ ![Download](https://api.bintray.com/packages/mipt-npm/scientifik/scientifik.kmath/images/download.svg) ](https://bintray.com/mipt-npm/scientifik/scientifik.kmath/_latestVersion)
|
||||||
|
|
||||||
# KMath
|
# KMath
|
||||||
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.
|
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.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
|
Actual feature list is [here](doc/features.md)
|
||||||
|
|
||||||
* **Algebra**
|
* **Algebra**
|
||||||
* Algebraic structures like rings, spaces and field (**TODO** add example to wiki)
|
* Algebraic structures like rings, spaces and field (**TODO** add example to wiki)
|
||||||
* Basic linear algebra operations (sums, products, etc.), backed by the `Space` API.
|
* 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).
|
* Complex numbers backed by the `Field` API (meaning that they will be usable in any structure like vectors and N-dimensional arrays).
|
||||||
* [In progress] advanced linear algebra operations like matrix inversion and LU decomposition.
|
* Advanced linear algebra operations like matrix inversion and LU decomposition.
|
||||||
* **Array-like structures** Full support of [numpy-like ndarrays](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.html) including mixed arithmetic operations and function operations over arrays and numbers just like in Python (with the added benefit of static type checking).
|
|
||||||
|
|
||||||
* **Expressions** Expressions are one of the ultimate goals of KMath. By writing a single mathematical expression
|
* **Array-like structures** Full support of many-dimenstional 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. Exceptions
|
once, users will be able to apply different types of objects to the expression by providing a context. Exceptions
|
||||||
can be used for a wide variety of purposes from high performance calculations to code generation.
|
can be used for a wide variety of purposes from high performance calculations to code generation.
|
||||||
|
|
||||||
## Planned features
|
* **Histograms** Fast multi-dimensional histograms.
|
||||||
|
|
||||||
* **Common mathematics** It is planned to gradually wrap most parts of [Apache commons-math](http://commons.apache.org/proper/commons-math/)
|
* **Streaming** Streaming operations on mathematica objects and objects buffers.
|
||||||
|
|
||||||
|
* **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
|
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.
|
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.
|
||||||
|
|
||||||
|
## Planned features
|
||||||
|
|
||||||
* **Messaging** A mathematical notation to support multi-language and multi-node communication for mathematical tasks.
|
* **Messaging** A mathematical notation to support multi-language and multi-node communication for mathematical tasks.
|
||||||
|
|
||||||
|
* **Array statistics**
|
||||||
|
|
||||||
|
* **Integration** Univariate and multivariate integration framework.
|
||||||
|
|
||||||
|
* **Probability and distributions**
|
||||||
|
|
||||||
|
* **Fitting** Non-linear curve fitting facilities
|
||||||
|
|
||||||
## Multi-platform support
|
## Multi-platform support
|
||||||
|
|
||||||
KMath is developed as a multi-platform library, which means that most of interfaces are declared in the [common module](kmath-core/src/commonMain).
|
KMath is developed as a multi-platform library, which means that most of interfaces are declared in the [common module](kmath-core/src/commonMain).
|
||||||
@ -39,6 +60,10 @@ of optimized parts should be better than SciPy.
|
|||||||
|
|
||||||
## Releases
|
## Releases
|
||||||
|
|
||||||
|
Working builds can be obtained here: [![](https://jitpack.io/v/altavir/kmath.svg)](https://jitpack.io/#altavir/kmath).
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
The project is currently in pre-release stage. Nightly builds can be used by adding an additional repository to the Gradle config like so:
|
The project is currently in pre-release stage. Nightly builds can be used by adding an additional repository to the Gradle config like so:
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
@ -52,7 +77,7 @@ or for the Gradle Kotlin DSL:
|
|||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
repositories {
|
repositories {
|
||||||
maven { setUrl("http://npm.mipt.ru:8081/artifactory/gradle-dev") }
|
maven("http://npm.mipt.ru:8081/artifactory/gradle-dev")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
@ -60,16 +85,28 @@ repositories {
|
|||||||
Then use a regular dependency like so:
|
Then use a regular dependency like so:
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
compile(group: 'scientifik', name: 'kmath-core', version: '0.0.1-SNAPSHOT')
|
api "scientifik:kmath-core-jvm:0.1.0-dev"
|
||||||
```
|
```
|
||||||
|
|
||||||
or in the Gradle Kotlin DSL:
|
or in the Gradle Kotlin DSL:
|
||||||
|
|
||||||
```kotlin
|
```kotlin
|
||||||
compile(group = "scientifik", name = "kmath-core", version = "0.0.1-SNAPSHOT")
|
api("scientifik:kmath-core-jvm:0.1.0-dev")
|
||||||
```
|
```
|
||||||
|
|
||||||
Working builds can be obtained here: [![](https://jitpack.io/v/altavir/kmath.svg)](https://jitpack.io/#altavir/kmath).
|
### Release
|
||||||
|
|
||||||
|
Release artifacts are accessible from bintray with following configuration:
|
||||||
|
|
||||||
|
```kotlin
|
||||||
|
repositories{
|
||||||
|
maven("https://dl.bintray.com/mipt-npm/scientifik")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies{
|
||||||
|
api("scientifik:kmath-core-jvm:0.1.0")
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package scientifik.kmath.structures
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
import scientifik.kmath.structures.Buffer.Companion.DoubleBufferFactory
|
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
|
|
||||||
@ -8,7 +7,7 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
val n = 6000
|
val n = 6000
|
||||||
|
|
||||||
val structure = NDStructure.build(intArrayOf(n, n), DoubleBufferFactory) { 1.0 }
|
val structure = NDStructure.build(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 }
|
||||||
|
|
||||||
structure.mapToBuffer { it + 1 } // warm-up
|
structure.mapToBuffer { it + 1 } // warm-up
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ buildscript {
|
|||||||
val ioVersion: String by rootProject.extra("0.1.5")
|
val ioVersion: String by rootProject.extra("0.1.5")
|
||||||
val coroutinesVersion: String by rootProject.extra("1.1.1")
|
val coroutinesVersion: String by rootProject.extra("1.1.1")
|
||||||
val atomicfuVersion: String by rootProject.extra("0.12.1")
|
val atomicfuVersion: String by rootProject.extra("0.12.1")
|
||||||
|
val dokkaVersion: String by rootProject.extra("0.9.17")
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
//maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
//maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
@ -14,6 +15,8 @@ buildscript {
|
|||||||
dependencies {
|
dependencies {
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||||
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4+")
|
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4+")
|
||||||
|
classpath("com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4")
|
||||||
|
classpath("org.jetbrains.dokka:dokka-gradle-plugin:$dokkaVersion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -21,20 +24,31 @@ plugins {
|
|||||||
id("com.jfrog.artifactory") version "4.9.1" apply false
|
id("com.jfrog.artifactory") version "4.9.1" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
val kmathVersion by extra("0.1.0")
|
||||||
if (project.name.startsWith("kmath")) {
|
|
||||||
apply(plugin = "maven-publish")
|
|
||||||
apply(plugin = "com.jfrog.artifactory")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
allprojects {
|
||||||
group = "scientifik"
|
group = "scientifik"
|
||||||
version = "0.0.3-dev"
|
version = kmathVersion
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
//maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
//maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
apply(plugin = "maven")
|
||||||
|
apply(plugin = "maven-publish")
|
||||||
|
|
||||||
|
// apply bintray configuration
|
||||||
|
apply(from = "${rootProject.rootDir}/gradle/bintray.gradle")
|
||||||
|
|
||||||
|
//apply artifactory configuration
|
||||||
|
apply(from = "${rootProject.rootDir}/gradle/artifactory.gradle")
|
||||||
|
}
|
||||||
|
|
||||||
|
subprojects {
|
||||||
|
if (!name.startsWith("kmath")) return@subprojects
|
||||||
|
|
||||||
|
|
||||||
extensions.findByType<KotlinMultiplatformExtension>()?.apply {
|
extensions.findByType<KotlinMultiplatformExtension>()?.apply {
|
||||||
jvm {
|
jvm {
|
||||||
compilations.all {
|
compilations.all {
|
||||||
@ -48,9 +62,49 @@ allprojects {
|
|||||||
languageSettings.progressiveMode = true
|
languageSettings.progressiveMode = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extensions.findByType<PublishingExtension>()?.apply {
|
||||||
|
publications.filterIsInstance<MavenPublication>().forEach { publication ->
|
||||||
|
if (publication.name == "kotlinMultiplatform") {
|
||||||
|
// for our root metadata publication, set artifactId with a package and project name
|
||||||
|
publication.artifactId = project.name
|
||||||
|
} else {
|
||||||
|
// for targets, set artifactId with a package, project name and target name (e.g. iosX64)
|
||||||
|
publication.artifactId = "${project.name}-${publication.name}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file("artifactory.gradle").exists()) {
|
// Create empty jar for sources classifier to satisfy maven requirements
|
||||||
apply(from = "artifactory.gradle")
|
val stubSources by tasks.registering(Jar::class) {
|
||||||
|
archiveClassifier.set("sources")
|
||||||
|
//from(sourceSets.main.get().allSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create empty jar for javadoc classifier to satisfy maven requirements
|
||||||
|
val stubJavadoc by tasks.registering(Jar::class) {
|
||||||
|
archiveClassifier.set("javadoc")
|
||||||
|
}
|
||||||
|
|
||||||
|
extensions.findByType<KotlinMultiplatformExtension>()?.apply {
|
||||||
|
|
||||||
|
targets.forEach { target ->
|
||||||
|
val publication = publications.findByName(target.name) as MavenPublication
|
||||||
|
|
||||||
|
// Patch publications with fake javadoc
|
||||||
|
publication.artifact(stubJavadoc)
|
||||||
|
|
||||||
|
// Remove gradle metadata publishing from all targets which are not native
|
||||||
|
// if (target.platformType.name != "native") {
|
||||||
|
// publication.gradleModuleMetadataFile = null
|
||||||
|
// tasks.matching { it.name == "generateMetadataFileFor${name.capitalize()}Publication" }.all {
|
||||||
|
// onlyIf { false }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -68,3 +68,44 @@ One important distinction between algebra elements and algebra contexts is that
|
|||||||
The middle type is needed in case algebra members do not store context. For example, it is not possible to add
|
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.
|
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.
|
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`.
|
||||||
|
@ -1 +1,15 @@
|
|||||||
**TODO**
|
# 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).
|
||||||
|
|
||||||
|
## Buffer performance
|
||||||
|
One should avoid using default boxing buffer wherever it is possible. Try to use primitive buffers or memory buffers instead
|
@ -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) - 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
|
||||||
|
|
@ -1,3 +1,7 @@
|
|||||||
|
# Nd-structure generation and operations
|
||||||
|
|
||||||
|
**TODO**
|
||||||
|
|
||||||
# Performance for n-dimensional structures operations
|
# Performance for n-dimensional structures operations
|
||||||
|
|
||||||
One of the most sought after features of mathematical libraries is the high-performance operations on n-dimensional
|
One of the most sought after features of mathematical libraries is the high-performance operations on n-dimensional
|
@ -1,40 +0,0 @@
|
|||||||
## 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
|
|
||||||
`BufferSpec`. This feature is in development phase.
|
|
31
gradle/artifactory.gradle
Normal file
31
gradle/artifactory.gradle
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
apply plugin: "com.jfrog.artifactory"
|
||||||
|
|
||||||
|
artifactory {
|
||||||
|
def artifactory_user = project.hasProperty('artifactoryUser') ? project.property('artifactoryUser') : ""
|
||||||
|
def artifactory_password = project.hasProperty('artifactoryPassword') ? project.property('artifactoryPassword') : ""
|
||||||
|
def artifactory_contextUrl = 'http://npm.mipt.ru:8081/artifactory'
|
||||||
|
|
||||||
|
contextUrl = artifactory_contextUrl //The base Artifactory URL if not overridden by the publisher/resolver
|
||||||
|
publish {
|
||||||
|
repository {
|
||||||
|
repoKey = 'gradle-dev-local'
|
||||||
|
username = artifactory_user
|
||||||
|
password = artifactory_password
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults {
|
||||||
|
publications('jvm', 'js', 'kotlinMultiplatform', 'metadata')
|
||||||
|
publishBuildInfo = false
|
||||||
|
publishArtifacts = true
|
||||||
|
publishPom = true
|
||||||
|
publishIvy = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
resolve {
|
||||||
|
repository {
|
||||||
|
repoKey = 'gradle-dev'
|
||||||
|
username = artifactory_user
|
||||||
|
password = artifactory_password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
85
gradle/bintray.gradle
Normal file
85
gradle/bintray.gradle
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
apply plugin: 'com.jfrog.bintray'
|
||||||
|
|
||||||
|
def vcs = "https://github.com/mipt-npm/kmath"
|
||||||
|
|
||||||
|
def pomConfig = {
|
||||||
|
licenses {
|
||||||
|
license {
|
||||||
|
name "The Apache Software License, Version 2.0"
|
||||||
|
url "http://www.apache.org/licenses/LICENSE-2.0.txt"
|
||||||
|
distribution "repo"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
developers {
|
||||||
|
developer {
|
||||||
|
id "MIPT-NPM"
|
||||||
|
name "MIPT nuclear physics methods laboratory"
|
||||||
|
organization "MIPT"
|
||||||
|
organizationUrl "http://npm.mipt.ru"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scm {
|
||||||
|
url vcs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
project.ext.configureMavenCentralMetadata = { pom ->
|
||||||
|
def root = asNode()
|
||||||
|
root.appendNode('name', project.name)
|
||||||
|
root.appendNode('description', project.description)
|
||||||
|
root.appendNode('url', vcs)
|
||||||
|
root.children().last() + pomConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
project.ext.configurePom = pomConfig
|
||||||
|
|
||||||
|
|
||||||
|
// Configure publishing
|
||||||
|
publishing {
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
url = "https://bintray.com/mipt-npm/scientifik"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process each publication we have in this project
|
||||||
|
publications.all { publication ->
|
||||||
|
// apply changes to pom.xml files, see pom.gradle
|
||||||
|
pom.withXml(configureMavenCentralMetadata)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bintray {
|
||||||
|
user = project.hasProperty('bintrayUser') ? project.property('bintrayUser') : System.getenv('BINTRAY_USER')
|
||||||
|
key = project.hasProperty('bintrayApiKey') ? project.property('bintrayApiKey') : System.getenv('BINTRAY_API_KEY')
|
||||||
|
publish = true
|
||||||
|
override = true // for multi-platform Kotlin/Native publishing
|
||||||
|
|
||||||
|
pkg {
|
||||||
|
userOrg = "mipt-npm"
|
||||||
|
repo = "scientifik"
|
||||||
|
name = "scientifik.kmath"
|
||||||
|
issueTrackerUrl = "https://github.com/mipt-npm/kmath/issues"
|
||||||
|
licenses = ['Apache-2.0']
|
||||||
|
vcsUrl = vcs
|
||||||
|
version {
|
||||||
|
name = project.version
|
||||||
|
vcsTag = project.version
|
||||||
|
released = new Date()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bintrayUpload.dependsOn publishToMavenLocal
|
||||||
|
|
||||||
|
// This is for easier debugging of bintray uploading problems
|
||||||
|
bintrayUpload.doFirst {
|
||||||
|
publications = project.publishing.publications.findAll {
|
||||||
|
!it.name.contains('-test') && it.name != 'kotlinMultiplatform'
|
||||||
|
}.collect {
|
||||||
|
println("Uploading artifact '$it.groupId:$it.artifactId:$it.version' from publication '$it.name'")
|
||||||
|
it.name//https://github.com/bintray/gradle-bintray-plugin/issues/256
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm")
|
kotlin("jvm")
|
||||||
|
`maven-publish`
|
||||||
}
|
}
|
||||||
|
|
||||||
description = "Commons math binding for kmath"
|
description = "Commons math binding for kmath"
|
||||||
@ -11,3 +12,18 @@ dependencies {
|
|||||||
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
testImplementation("org.jetbrains.kotlin:kotlin-test")
|
||||||
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
|
testImplementation("org.jetbrains.kotlin:kotlin-test-junit")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
val sourcesJar by tasks.registering(Jar::class) {
|
||||||
|
classifier = "sources"
|
||||||
|
from(sourceSets.main.get().allSource)
|
||||||
|
}
|
||||||
|
|
||||||
|
publishing {
|
||||||
|
publications {
|
||||||
|
register("jvm", MavenPublication::class) {
|
||||||
|
from(components["java"])
|
||||||
|
artifact(sourcesJar.get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ package scientifik.kmath.linear
|
|||||||
|
|
||||||
import scientifik.kmath.operations.Ring
|
import scientifik.kmath.operations.Ring
|
||||||
import scientifik.kmath.structures.*
|
import scientifik.kmath.structures.*
|
||||||
|
import kotlin.jvm.JvmSynthetic
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic implementation of Matrix space based on [NDStructure]
|
* Basic implementation of Matrix space based on [NDStructure]
|
||||||
@ -32,7 +33,6 @@ class BufferMatrix<T : Any>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override val shape: IntArray get() = intArrayOf(rowNum, colNum)
|
override val shape: IntArray get() = intArrayOf(rowNum, colNum)
|
||||||
|
|
||||||
override fun suggestFeature(vararg features: MatrixFeature) =
|
override fun suggestFeature(vararg features: MatrixFeature) =
|
||||||
|
@ -4,7 +4,6 @@ import scientifik.kmath.operations.RealField
|
|||||||
import scientifik.kmath.operations.Ring
|
import scientifik.kmath.operations.Ring
|
||||||
import scientifik.kmath.operations.sum
|
import scientifik.kmath.operations.sum
|
||||||
import scientifik.kmath.structures.*
|
import scientifik.kmath.structures.*
|
||||||
import scientifik.kmath.structures.Buffer.Companion.DoubleBufferFactory
|
|
||||||
import scientifik.kmath.structures.Buffer.Companion.boxing
|
import scientifik.kmath.structures.Buffer.Companion.boxing
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
@ -33,7 +32,7 @@ interface MatrixContext<T : Any> {
|
|||||||
/**
|
/**
|
||||||
* Non-boxing double matrix
|
* Non-boxing double matrix
|
||||||
*/
|
*/
|
||||||
val real = BufferMatrixContext(RealField, DoubleBufferFactory)
|
val real = BufferMatrixContext(RealField, Buffer.Companion::auto)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A structured matrix with custom buffer
|
* A structured matrix with custom buffer
|
||||||
|
@ -42,7 +42,7 @@ interface VectorSpace<T : Any, S : Space<T>> : Space<Point<T>> {
|
|||||||
* Non-boxing double vector space
|
* Non-boxing double vector space
|
||||||
*/
|
*/
|
||||||
fun real(size: Int): BufferVectorSpace<Double, RealField> {
|
fun real(size: Int): BufferVectorSpace<Double, RealField> {
|
||||||
return realSpaceCache.getOrPut(size) { BufferVectorSpace(size, RealField, Buffer.DoubleBufferFactory) }
|
return realSpaceCache.getOrPut(size) { BufferVectorSpace(size, RealField, Buffer.Companion::auto) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package scientifik.kmath.operations
|
package scientifik.kmath.operations
|
||||||
|
|
||||||
import scientifik.kmath.structures.Buffer
|
import scientifik.kmath.structures.Buffer
|
||||||
|
import scientifik.kmath.structures.MemoryBuffer
|
||||||
import scientifik.kmath.structures.MutableBuffer
|
import scientifik.kmath.structures.MutableBuffer
|
||||||
import scientifik.kmath.structures.ObjectBuffer
|
|
||||||
import scientifik.memory.MemoryReader
|
import scientifik.memory.MemoryReader
|
||||||
import scientifik.memory.MemorySpec
|
import scientifik.memory.MemorySpec
|
||||||
import scientifik.memory.MemoryWriter
|
import scientifik.memory.MemoryWriter
|
||||||
@ -88,10 +88,10 @@ data class Complex(val re: Double, val im: Double) : FieldElement<Complex, Compl
|
|||||||
|
|
||||||
fun Double.toComplex() = Complex(this, 0.0)
|
fun Double.toComplex() = Complex(this, 0.0)
|
||||||
|
|
||||||
fun Buffer.Companion.complex(size: Int, init: (Int) -> Complex): Buffer<Complex> {
|
inline fun Buffer.Companion.complex(size: Int, crossinline init: (Int) -> Complex): Buffer<Complex> {
|
||||||
return ObjectBuffer.create(Complex, size, init)
|
return MemoryBuffer.create(Complex, size, init)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableBuffer.Companion.complex(size: Int, init: (Int) -> Complex): Buffer<Complex> {
|
inline fun MutableBuffer.Companion.complex(size: Int, crossinline init: (Int) -> Complex): Buffer<Complex> {
|
||||||
return ObjectBuffer.create(Complex, size, init)
|
return MemoryBuffer.create(Complex, size, init)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
package scientifik.kmath.structures
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
|
import scientifik.kmath.operations.Complex
|
||||||
|
import scientifik.kmath.operations.complex
|
||||||
|
|
||||||
|
|
||||||
typealias BufferFactory<T> = (Int, (Int) -> T) -> Buffer<T>
|
typealias BufferFactory<T> = (Int, (Int) -> T) -> Buffer<T>
|
||||||
typealias MutableBufferFactory<T> = (Int, (Int) -> T) -> MutableBuffer<T>
|
typealias MutableBufferFactory<T> = (Int, (Int) -> T) -> MutableBuffer<T>
|
||||||
@ -43,21 +46,16 @@ interface Buffer<T> {
|
|||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
inline fun <reified T : Any> auto(size: Int, crossinline initializer: (Int) -> T): Buffer<T> {
|
inline fun <reified T : Any> auto(size: Int, crossinline initializer: (Int) -> T): Buffer<T> {
|
||||||
|
//TODO add resolution based on Annotation or companion resolution
|
||||||
return when (T::class) {
|
return when (T::class) {
|
||||||
Double::class -> DoubleBuffer(DoubleArray(size) { initializer(it) as Double }) as Buffer<T>
|
Double::class -> DoubleBuffer(DoubleArray(size) { initializer(it) as Double }) as Buffer<T>
|
||||||
Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as Buffer<T>
|
Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as Buffer<T>
|
||||||
Int::class -> IntBuffer(IntArray(size) { initializer(it) as Int }) as Buffer<T>
|
Int::class -> IntBuffer(IntArray(size) { initializer(it) as Int }) as Buffer<T>
|
||||||
Long::class -> LongBuffer(LongArray(size) { initializer(it) as Long }) as Buffer<T>
|
Long::class -> LongBuffer(LongArray(size) { initializer(it) as Long }) as Buffer<T>
|
||||||
|
Complex::class -> complex(size) { initializer(it) as Complex } as Buffer<T>
|
||||||
else -> boxing(size, initializer)
|
else -> boxing(size, initializer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val DoubleBufferFactory: BufferFactory<Double> =
|
|
||||||
{ size, initializer -> DoubleBuffer(DoubleArray(size, initializer)) }
|
|
||||||
val ShortBufferFactory: BufferFactory<Short> =
|
|
||||||
{ size, initializer -> ShortBuffer(ShortArray(size, initializer)) }
|
|
||||||
val IntBufferFactory: BufferFactory<Int> = { size, initializer -> IntBuffer(IntArray(size, initializer)) }
|
|
||||||
val LongBufferFactory: BufferFactory<Long> = { size, initializer -> LongBuffer(LongArray(size, initializer)) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import scientifik.memory.*
|
|||||||
/**
|
/**
|
||||||
* A non-boxing buffer based on [ByteBuffer] storage
|
* A non-boxing buffer based on [ByteBuffer] storage
|
||||||
*/
|
*/
|
||||||
open class ObjectBuffer<T : Any>(protected val memory: Memory, protected val spec: MemorySpec<T>) : Buffer<T> {
|
open class MemoryBuffer<T : Any>(protected val memory: Memory, protected val spec: MemorySpec<T>) : Buffer<T> {
|
||||||
|
|
||||||
override val size: Int get() = memory.size / spec.objectSize
|
override val size: Int get() = memory.size / spec.objectSize
|
||||||
|
|
||||||
@ -18,14 +18,14 @@ open class ObjectBuffer<T : Any>(protected val memory: Memory, protected val spe
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun <T : Any> create(spec: MemorySpec<T>, size: Int) =
|
fun <T : Any> create(spec: MemorySpec<T>, size: Int) =
|
||||||
ObjectBuffer(Memory.allocate(size * spec.objectSize), spec)
|
MemoryBuffer(Memory.allocate(size * spec.objectSize), spec)
|
||||||
|
|
||||||
inline fun <T : Any> create(
|
inline fun <T : Any> create(
|
||||||
spec: MemorySpec<T>,
|
spec: MemorySpec<T>,
|
||||||
size: Int,
|
size: Int,
|
||||||
crossinline initializer: (Int) -> T
|
crossinline initializer: (Int) -> T
|
||||||
): ObjectBuffer<T> =
|
): MemoryBuffer<T> =
|
||||||
MutableObjectBuffer(Memory.allocate(size * spec.objectSize), spec).also { buffer ->
|
MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec).also { buffer ->
|
||||||
(0 until size).forEach {
|
(0 until size).forEach {
|
||||||
buffer[it] = initializer(it)
|
buffer[it] = initializer(it)
|
||||||
}
|
}
|
||||||
@ -33,16 +33,28 @@ open class ObjectBuffer<T : Any>(protected val memory: Memory, protected val spe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class MutableObjectBuffer<T : Any>(memory: Memory, spec: MemorySpec<T>) : ObjectBuffer<T>(memory, spec),
|
class MutableMemoryBuffer<T : Any>(memory: Memory, spec: MemorySpec<T>) : MemoryBuffer<T>(memory, spec),
|
||||||
MutableBuffer<T> {
|
MutableBuffer<T> {
|
||||||
|
|
||||||
private val writer = memory.writer()
|
private val writer = memory.writer()
|
||||||
|
|
||||||
override fun set(index: Int, value: T) = writer.write(spec, spec.objectSize * index, value)
|
override fun set(index: Int, value: T) = writer.write(spec, spec.objectSize * index, value)
|
||||||
|
|
||||||
override fun copy(): MutableBuffer<T> = MutableObjectBuffer(memory.copy(), spec)
|
override fun copy(): MutableBuffer<T> = MutableMemoryBuffer(memory.copy(), spec)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
fun <T : Any> create(spec: MemorySpec<T>, size: Int) =
|
||||||
|
MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec)
|
||||||
|
|
||||||
|
inline fun <T : Any> create(
|
||||||
|
spec: MemorySpec<T>,
|
||||||
|
size: Int,
|
||||||
|
crossinline initializer: (Int) -> T
|
||||||
|
) =
|
||||||
|
MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec).also { buffer ->
|
||||||
|
(0 until size).forEach {
|
||||||
|
buffer[it] = initializer(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package scientifik.memory
|
package scientifik.memory
|
||||||
|
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A specification to read or write custom objects with fixed size in bytes
|
* A specification to read or write custom objects with fixed size in bytes
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user