diff --git a/.space.kts b/.space.kts
new file mode 100644
index 000000000..9dda0cbf7
--- /dev/null
+++ b/.space.kts
@@ -0,0 +1 @@
+job("Build") { gradlew("openjdk:11", "build") }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ba271bb01..aa314fcb4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,18 +2,27 @@
 
 ## [Unreleased]
 ### 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).
 - `kmath-ejml` to supply EJML SimpleMatrix wrapper.
 
 ### Changed
+- Package changed from `scientifik` to `kscience.kmath`.
+- Gradle version: 6.6 -> 6.6.1
+- Minor exceptions refactor (throwing `IllegalArgumentException` by argument checks instead of `IllegalStateException`)
+- `Polynomial` secondary constructor made function.
 
 ### Deprecated
 
 ### Removed
-- `kmath-koma` module.
+- `kmath-koma` module because it doesn't support Kotlin 1.4.
 
 ### Fixed
+- `symbol` method in `MstExtendedField` (https://github.com/mipt-npm/kmath/pull/140)
 
 ### Security
+
 ## [0.1.4]
 
 ### Added
diff --git a/README.md b/README.md
index 6bfbc717a..c2e67e815 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 
 ![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:        [ ![Download](https://api.bintray.com/packages/mipt-npm/kscience/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/kscience/kmath-core/_latestVersion)
 
 Bintray-dev:    [ ![Download](https://api.bintray.com/packages/mipt-npm/dev/kmath-core/images/download.svg) ](https://bintray.com/mipt-npm/dev/kmath-core/_latestVersion)
 
@@ -53,7 +53,7 @@ can be used for a wide variety of purposes from high performance calculations to
 * **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.
-
+                           
 ## Planned features
 
 * **Messaging** A mathematical notation to support multi-language and multi-node communication for mathematical tasks.
@@ -80,12 +80,12 @@ Release artifacts are accessible from bintray with following configuration (see
 
 ```kotlin
 repositories{
-    maven("https://dl.bintray.com/mipt-npm/scientifik")
+    maven("https://dl.bintray.com/mipt-npm/kscience")
 }
 
 dependencies{
-    api("scientifik:kmath-core:${kmathVersion}")
-    //api("scientifik:kmath-core-jvm:${kmathVersion}") for jvm-specific version
+    api("kscience.kmath:kmath-core:${kmathVersion}")
+    //api("kscience.kmath:kmath-core-jvm:${kmathVersion}") for jvm-specific version
 }
 ```
 
diff --git a/build.gradle.kts b/build.gradle.kts
index 96434d01f..838a05771 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,13 +1,10 @@
-import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension
-import scientifik.ScientifikPublishPlugin
-
 plugins {
-    id("scientifik.publish") apply false
+    id("ru.mipt.npm.base")
     id("org.jetbrains.changelog") version "0.4.0"
 }
 
-val kmathVersion by extra("0.1.4")
-val bintrayRepo by extra("scientifik")
+val kmathVersion by extra("0.2.0-dev-1")
+val bintrayRepo by extra("kscience")
 val githubProject by extra("kmath")
 
 allprojects {
@@ -19,17 +16,6 @@ allprojects {
 
     group = "kscience.kmath"
     version = kmathVersion
-
-    afterEvaluate {
-        extensions.findByType<KotlinProjectExtension>()?.run {
-            sourceSets.all {
-                languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
-            }
-        }
-    }
 }
 
-subprojects {
-    if (name.startsWith("kmath"))
-        apply<ScientifikPublishPlugin>()
-}
\ No newline at end of file
+subprojects { if (name.startsWith("kmath")) apply(plugin = "ru.mipt.npm.publish") }
diff --git a/doc/algebra.md b/doc/algebra.md
index b1b77a31f..c3227517f 100644
--- a/doc/algebra.md
+++ b/doc/algebra.md
@@ -5,7 +5,7 @@ operation, say `+`, one needs two objects of a type `T` and an algebra context,
 say `Space<T>`. Next one needs to run the actual operation in the context:
 
 ```kotlin
-import scientifik.kmath.operations.*
+import kscience.kmath.operations.*
 
 val a: T = ...
 val b: T = ...
@@ -47,7 +47,7 @@ but it also holds reference to the `ComplexField` singleton, which allows perfor
 numbers without explicit involving the context like:
 
 ```kotlin
-import scientifik.kmath.operations.*
+import kscience.kmath.operations.*
 
 // Using elements
 val c1 = Complex(1.0, 1.0)
@@ -82,7 +82,7 @@ operations in all performance-critical places. The performance of element operat
 KMath submits both contexts and elements for builtin algebraic structures:
 
 ```kotlin
-import scientifik.kmath.operations.*
+import kscience.kmath.operations.*
 
 val c1 = Complex(1.0, 2.0)
 val c2 = ComplexField.i
@@ -95,7 +95,7 @@ val c3 = ComplexField { c1 + c2 }
 Also, `ComplexField` features special operations to mix complex and real numbers, for example:
 
 ```kotlin
-import scientifik.kmath.operations.*
+import kscience.kmath.operations.*
 
 val c1 = Complex(1.0, 2.0)
 val c2 = ComplexField { c1 - 1.0 } // Returns: Complex(re=0.0, im=2.0)
diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts
index 519c72615..1c90db101 100644
--- a/examples/build.gradle.kts
+++ b/examples/build.gradle.kts
@@ -1,30 +1,25 @@
-import org.jetbrains.kotlin.allopen.gradle.AllOpenExtension
 import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
 
 plugins {
     java
     kotlin("jvm")
-    kotlin("plugin.allopen") version "1.3.72"
-    id("kotlinx.benchmark") version "0.2.0-dev-8"
+    kotlin("plugin.allopen") version "1.4.20-dev-3898-14"
+    id("kotlinx.benchmark") version "0.2.0-dev-20"
 }
 
-configure<AllOpenExtension> {
-    annotation("org.openjdk.jmh.annotations.State")
-}
+allOpen.annotation("org.openjdk.jmh.annotations.State")
 
 repositories {
-    maven("http://dl.bintray.com/kyonifer/maven")
-    maven("https://dl.bintray.com/mipt-npm/scientifik")
+    maven("https://dl.bintray.com/mipt-npm/kscience")
     maven("https://dl.bintray.com/mipt-npm/dev")
+    maven("https://dl.bintray.com/kotlin/kotlin-dev/")
     mavenCentral()
 }
 
-sourceSets {
-    register("benchmarks")
-}
+sourceSets.register("benchmarks")
 
 dependencies {
-    implementation(project(":kmath-ast"))
+//    implementation(project(":kmath-ast"))
     implementation(project(":kmath-core"))
     implementation(project(":kmath-coroutines"))
     implementation(project(":kmath-commons"))
@@ -33,25 +28,22 @@ dependencies {
     implementation(project(":kmath-dimensions"))
     implementation(project(":kmath-ejml"))
     implementation("org.jetbrains.kotlinx:kotlinx-io-jvm:0.2.0-npm-dev-6")
-    implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-8")
+    implementation("org.jetbrains.kotlinx:kotlinx.benchmark.runtime:0.2.0-dev-20")
     "benchmarksCompile"(sourceSets.main.get().output + sourceSets.main.get().compileClasspath) //sourceSets.main.output + sourceSets.main.runtimeClasspath
 }
 
 // Configure benchmark
 benchmark {
     // Setup configurations
-    targets {
+    targets
         // This one matches sourceSet name above
-        register("benchmarks")
-    }
+        .register("benchmarks")
 
-    configurations {
-        register("fast") {
-            warmups = 5 // number of warmup iterations
-            iterations = 3 // number of iterations
-            iterationTime = 500 // time in seconds per iteration
-            iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
-        }
+    configurations.register("fast") {
+        warmups = 5 // number of warmup iterations
+        iterations = 3 // number of iterations
+        iterationTime = 500 // time in seconds per iteration
+        iterationTimeUnit = "ms" // time unity for iterationTime, default is seconds
     }
 }
 
@@ -62,9 +54,4 @@ kotlin.sourceSets.all {
     }
 }
 
-tasks.withType<KotlinCompile> {
-    kotlinOptions {
-        jvmTarget = Scientifik.JVM_TARGET.toString()
-        freeCompilerArgs = freeCompilerArgs + "-Xopt-in=kotlin.RequiresOptIn"
-    }
-}
+tasks.withType<KotlinCompile> { kotlinOptions.jvmTarget = "11" }
diff --git a/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt
new file mode 100644
index 000000000..2673552f5
--- /dev/null
+++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ArrayBenchmark.kt
@@ -0,0 +1,39 @@
+package kscience.kmath.structures
+
+import org.openjdk.jmh.annotations.Benchmark
+import org.openjdk.jmh.annotations.Scope
+import org.openjdk.jmh.annotations.State
+import java.nio.IntBuffer
+
+@State(Scope.Benchmark)
+class ArrayBenchmark {
+    @Benchmark
+    fun benchmarkArrayRead() {
+        var res = 0
+        for (i in 1.._root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) res += _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.array[_root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size - i]
+    }
+
+    @Benchmark
+    fun benchmarkBufferRead() {
+        var res = 0
+        for (i in 1.._root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) res += _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.arrayBuffer.get(
+            _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size - i)
+    }
+
+    @Benchmark
+    fun nativeBufferRead() {
+        var res = 0
+        for (i in 1.._root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) res += _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.nativeBuffer.get(
+            _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size - i)
+    }
+
+    companion object {
+        const val size: Int = 1000
+        val array: IntArray = IntArray(_root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) { it }
+        val arrayBuffer: IntBuffer = IntBuffer.wrap(_root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.array)
+
+        val nativeBuffer: IntBuffer = IntBuffer.allocate(_root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size).also {
+            for (i in 0 until _root_ide_package_.kscience.kmath.structures.ArrayBenchmark.Companion.size) it.put(i, i)
+        }
+    }
+}
diff --git a/examples/src/benchmarks/kotlin/scientifik/kmath/structures/BufferBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt
similarity index 83%
rename from examples/src/benchmarks/kotlin/scientifik/kmath/structures/BufferBenchmark.kt
rename to examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt
index e40b0c4b7..009d51001 100644
--- a/examples/src/benchmarks/kotlin/scientifik/kmath/structures/BufferBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/BufferBenchmark.kt
@@ -1,10 +1,10 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.complex
 import org.openjdk.jmh.annotations.Benchmark
 import org.openjdk.jmh.annotations.Scope
 import org.openjdk.jmh.annotations.State
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.complex
 
 @State(Scope.Benchmark)
 class BufferBenchmark {
diff --git a/examples/src/benchmarks/kotlin/scientifik/kmath/structures/NDFieldBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt
similarity index 89%
rename from examples/src/benchmarks/kotlin/scientifik/kmath/structures/NDFieldBenchmark.kt
rename to examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt
index 46da6c6d8..64f279c39 100644
--- a/examples/src/benchmarks/kotlin/scientifik/kmath/structures/NDFieldBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/NDFieldBenchmark.kt
@@ -1,10 +1,10 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.invoke
 import org.openjdk.jmh.annotations.Benchmark
 import org.openjdk.jmh.annotations.Scope
 import org.openjdk.jmh.annotations.State
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.invoke
 
 @State(Scope.Benchmark)
 class NDFieldBenchmark {
diff --git a/examples/src/benchmarks/kotlin/scientifik/kmath/structures/ViktorBenchmark.kt b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt
similarity index 89%
rename from examples/src/benchmarks/kotlin/scientifik/kmath/structures/ViktorBenchmark.kt
rename to examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt
index 9627743c9..a4b831f7c 100644
--- a/examples/src/benchmarks/kotlin/scientifik/kmath/structures/ViktorBenchmark.kt
+++ b/examples/src/benchmarks/kotlin/kscience/kmath/structures/ViktorBenchmark.kt
@@ -1,12 +1,12 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.invoke
+import kscience.kmath.viktor.ViktorNDField
 import org.jetbrains.bio.viktor.F64Array
 import org.openjdk.jmh.annotations.Benchmark
 import org.openjdk.jmh.annotations.Scope
 import org.openjdk.jmh.annotations.State
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.viktor.ViktorNDField
 
 @State(Scope.Benchmark)
 class ViktorBenchmark {
diff --git a/examples/src/benchmarks/kotlin/scientifik/kmath/utils/utils.kt b/examples/src/benchmarks/kotlin/kscience/kmath/utils/utils.kt
similarity index 91%
rename from examples/src/benchmarks/kotlin/scientifik/kmath/utils/utils.kt
rename to examples/src/benchmarks/kotlin/kscience/kmath/utils/utils.kt
index 3b0d56291..329b7b17b 100644
--- a/examples/src/benchmarks/kotlin/scientifik/kmath/utils/utils.kt
+++ b/examples/src/benchmarks/kotlin/kscience/kmath/utils/utils.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.utils
+package kscience.kmath.utils
 
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
diff --git a/examples/src/benchmarks/kotlin/scientifik/kmath/structures/ArrayBenchmark.kt b/examples/src/benchmarks/kotlin/scientifik/kmath/structures/ArrayBenchmark.kt
deleted file mode 100644
index d605e1b9c..000000000
--- a/examples/src/benchmarks/kotlin/scientifik/kmath/structures/ArrayBenchmark.kt
+++ /dev/null
@@ -1,48 +0,0 @@
-package scientifik.kmath.structures
-
-import org.openjdk.jmh.annotations.Benchmark
-import org.openjdk.jmh.annotations.Scope
-import org.openjdk.jmh.annotations.State
-import java.nio.IntBuffer
-
-
-@State(Scope.Benchmark)
-class ArrayBenchmark {
-
-    @Benchmark
-    fun benchmarkArrayRead() {
-        var res = 0
-        for (i in 1..size) {
-            res += array[size - i]
-        }
-    }
-
-    @Benchmark
-    fun benchmarkBufferRead() {
-        var res = 0
-        for (i in 1..size) {
-            res += arrayBuffer.get(size - i)
-        }
-    }
-
-    @Benchmark
-    fun nativeBufferRead() {
-        var res = 0
-        for (i in 1..size) {
-            res += nativeBuffer.get(size - i)
-        }
-    }
-
-    companion object {
-        val size = 1000
-
-        val array = IntArray(size) { it }
-        val arrayBuffer = IntBuffer.wrap(array)
-        val nativeBuffer = IntBuffer.allocate(size).also {
-            for (i in 0 until size) {
-                it.put(i, i)
-            }
-
-        }
-    }
-}
\ No newline at end of file
diff --git a/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt
new file mode 100644
index 000000000..a5768f1f5
--- /dev/null
+++ b/examples/src/main/kotlin/kscience/kmath/ast/ExpressionsInterpretersBenchmark.kt
@@ -0,0 +1,70 @@
+//package kscience.kmath.ast
+//
+//import kscience.kmath.asm.compile
+//import kscience.kmath.expressions.Expression
+//import kscience.kmath.expressions.expressionInField
+//import kscience.kmath.expressions.invoke
+//import kscience.kmath.operations.Field
+//import kscience.kmath.operations.RealField
+//import kotlin.random.Random
+//import kotlin.system.measureTimeMillis
+//
+//class ExpressionsInterpretersBenchmark {
+//    private val algebra: Field<Double> = RealField
+//    fun functionalExpression() {
+//        val expr = algebra.expressionInField {
+//            variable("x") * const(2.0) + const(2.0) / variable("x") - const(16.0)
+//        }
+//
+//        invokeAndSum(expr)
+//    }
+//
+//    fun mstExpression() {
+//        val expr = algebra.mstInField {
+//            symbol("x") * number(2.0) + number(2.0) / symbol("x") - number(16.0)
+//        }
+//
+//        invokeAndSum(expr)
+//    }
+//
+//    fun asmExpression() {
+//        val expr = algebra.mstInField {
+//            symbol("x") * number(2.0) + number(2.0) / symbol("x") - number(16.0)
+//        }.compile()
+//
+//        invokeAndSum(expr)
+//    }
+//
+//    private fun invokeAndSum(expr: Expression<Double>) {
+//        val random = Random(0)
+//        var sum = 0.0
+//
+//        repeat(1000000) {
+//            sum += expr("x" to random.nextDouble())
+//        }
+//
+//        println(sum)
+//    }
+//}
+//
+//fun main() {
+//    val benchmark = ExpressionsInterpretersBenchmark()
+//
+//    val fe = measureTimeMillis {
+//        benchmark.functionalExpression()
+//    }
+//
+//    println("fe=$fe")
+//
+//    val mst = measureTimeMillis {
+//        benchmark.mstExpression()
+//    }
+//
+//    println("mst=$mst")
+//
+//    val asm = measureTimeMillis {
+//        benchmark.asmExpression()
+//    }
+//
+//    println("asm=$asm")
+//}
diff --git a/examples/src/main/kotlin/scientifik/kmath/commons/prob/DistributionBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt
similarity index 94%
rename from examples/src/main/kotlin/scientifik/kmath/commons/prob/DistributionBenchmark.kt
rename to examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt
index b060cddb6..57a9c55c5 100644
--- a/examples/src/main/kotlin/scientifik/kmath/commons/prob/DistributionBenchmark.kt
+++ b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionBenchmark.kt
@@ -1,12 +1,12 @@
-package scientifik.kmath.commons.prob
+package kscience.kmath.commons.prob
 
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.async
 import kotlinx.coroutines.runBlocking
+import kscience.kmath.chains.BlockingRealChain
+import kscience.kmath.prob.*
 import org.apache.commons.rng.sampling.distribution.ZigguratNormalizedGaussianSampler
 import org.apache.commons.rng.simple.RandomSource
-import scientifik.kmath.chains.BlockingRealChain
-import scientifik.kmath.prob.*
 import java.time.Duration
 import java.time.Instant
 
diff --git a/examples/src/main/kotlin/scientifik/kmath/commons/prob/DistributionDemo.kt b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionDemo.kt
similarity index 72%
rename from examples/src/main/kotlin/scientifik/kmath/commons/prob/DistributionDemo.kt
rename to examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionDemo.kt
index e059415dc..dbb51267b 100644
--- a/examples/src/main/kotlin/scientifik/kmath/commons/prob/DistributionDemo.kt
+++ b/examples/src/main/kotlin/kscience/kmath/commons/prob/DistributionDemo.kt
@@ -1,11 +1,11 @@
-package scientifik.kmath.commons.prob
+package kscience.kmath.commons.prob
 
 import kotlinx.coroutines.runBlocking
-import scientifik.kmath.chains.Chain
-import scientifik.kmath.chains.collectWithState
-import scientifik.kmath.prob.Distribution
-import scientifik.kmath.prob.RandomGenerator
-import scientifik.kmath.prob.normal
+import kscience.kmath.chains.Chain
+import kscience.kmath.chains.collectWithState
+import kscience.kmath.prob.Distribution
+import kscience.kmath.prob.RandomGenerator
+import kscience.kmath.prob.normal
 
 data class AveragingChainState(var num: Int = 0, var value: Double = 0.0)
 
diff --git a/examples/src/main/kotlin/scientifik/kmath/operations/BigIntDemo.kt b/examples/src/main/kotlin/kscience/kmath/operations/BigIntDemo.kt
similarity index 72%
rename from examples/src/main/kotlin/scientifik/kmath/operations/BigIntDemo.kt
rename to examples/src/main/kotlin/kscience/kmath/operations/BigIntDemo.kt
index 10b038943..692ea6d8c 100644
--- a/examples/src/main/kotlin/scientifik/kmath/operations/BigIntDemo.kt
+++ b/examples/src/main/kotlin/kscience/kmath/operations/BigIntDemo.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 fun main() {
     val res = BigIntField {
diff --git a/examples/src/main/kotlin/scientifik/kmath/operations/ComplexDemo.kt b/examples/src/main/kotlin/kscience/kmath/operations/ComplexDemo.kt
similarity index 68%
rename from examples/src/main/kotlin/scientifik/kmath/operations/ComplexDemo.kt
rename to examples/src/main/kotlin/kscience/kmath/operations/ComplexDemo.kt
index 6dbfebce1..3c97940a8 100644
--- a/examples/src/main/kotlin/scientifik/kmath/operations/ComplexDemo.kt
+++ b/examples/src/main/kotlin/kscience/kmath/operations/ComplexDemo.kt
@@ -1,8 +1,8 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
-import scientifik.kmath.structures.NDElement
-import scientifik.kmath.structures.NDField
-import scientifik.kmath.structures.complex
+import kscience.kmath.structures.NDElement
+import kscience.kmath.structures.NDField
+import kscience.kmath.structures.complex
 
 fun main() {
     val element = NDElement.complex(2, 2) { index: IntArray ->
diff --git a/examples/src/main/kotlin/scientifik/kmath/structures/ComplexND.kt b/examples/src/main/kotlin/kscience/kmath/structures/ComplexND.kt
similarity index 85%
rename from examples/src/main/kotlin/scientifik/kmath/structures/ComplexND.kt
rename to examples/src/main/kotlin/kscience/kmath/structures/ComplexND.kt
index 2329f3fc3..aa4b10ef2 100644
--- a/examples/src/main/kotlin/scientifik/kmath/structures/ComplexND.kt
+++ b/examples/src/main/kotlin/kscience/kmath/structures/ComplexND.kt
@@ -1,9 +1,9 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.linear.transpose
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.ComplexField
-import scientifik.kmath.operations.invoke
+import kscience.kmath.linear.transpose
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.ComplexField
+import kscience.kmath.operations.invoke
 import kotlin.system.measureTimeMillis
 
 fun main() {
diff --git a/examples/src/main/kotlin/scientifik/kmath/structures/NDField.kt b/examples/src/main/kotlin/kscience/kmath/structures/NDField.kt
similarity index 93%
rename from examples/src/main/kotlin/scientifik/kmath/structures/NDField.kt
rename to examples/src/main/kotlin/kscience/kmath/structures/NDField.kt
index 54ffcb67c..28bfab779 100644
--- a/examples/src/main/kotlin/scientifik/kmath/structures/NDField.kt
+++ b/examples/src/main/kotlin/kscience/kmath/structures/NDField.kt
@@ -1,8 +1,8 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
 import kotlinx.coroutines.GlobalScope
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.invoke
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.invoke
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
 import kotlin.system.measureTimeMillis
diff --git a/examples/src/main/kotlin/scientifik/kmath/structures/StructureReadBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt
similarity index 93%
rename from examples/src/main/kotlin/scientifik/kmath/structures/StructureReadBenchmark.kt
rename to examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt
index a33fdb2c4..a2bfea2f9 100644
--- a/examples/src/main/kotlin/scientifik/kmath/structures/StructureReadBenchmark.kt
+++ b/examples/src/main/kotlin/kscience/kmath/structures/StructureReadBenchmark.kt
@@ -1,8 +1,8 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
 import kotlin.system.measureTimeMillis
 
-fun main(args: Array<String>) {
+fun main() {
     val n = 6000
 
     val array = DoubleArray(n * n) { 1.0 }
diff --git a/examples/src/main/kotlin/scientifik/kmath/structures/StructureWriteBenchmark.kt b/examples/src/main/kotlin/kscience/kmath/structures/StructureWriteBenchmark.kt
similarity index 93%
rename from examples/src/main/kotlin/scientifik/kmath/structures/StructureWriteBenchmark.kt
rename to examples/src/main/kotlin/kscience/kmath/structures/StructureWriteBenchmark.kt
index 0241f12ad..b2975393f 100644
--- a/examples/src/main/kotlin/scientifik/kmath/structures/StructureWriteBenchmark.kt
+++ b/examples/src/main/kotlin/kscience/kmath/structures/StructureWriteBenchmark.kt
@@ -1,10 +1,8 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
 import kotlin.system.measureTimeMillis
 
-
-fun main(args: Array<String>) {
-
+fun main() {
     val n = 6000
 
     val structure = NDStructure.build(intArrayOf(n, n), Buffer.Companion::auto) { 1.0 }
diff --git a/examples/src/main/kotlin/scientifik/kmath/structures/typeSafeDimensions.kt b/examples/src/main/kotlin/kscience/kmath/structures/typeSafeDimensions.kt
similarity index 71%
rename from examples/src/main/kotlin/scientifik/kmath/structures/typeSafeDimensions.kt
rename to examples/src/main/kotlin/kscience/kmath/structures/typeSafeDimensions.kt
index 5d323823a..bf83a9f05 100644
--- a/examples/src/main/kotlin/scientifik/kmath/structures/typeSafeDimensions.kt
+++ b/examples/src/main/kotlin/kscience/kmath/structures/typeSafeDimensions.kt
@@ -1,10 +1,10 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.dimensions.D2
-import scientifik.kmath.dimensions.D3
-import scientifik.kmath.dimensions.DMatrixContext
-import scientifik.kmath.dimensions.Dimension
-import scientifik.kmath.operations.RealField
+import kscience.kmath.dimensions.D2
+import kscience.kmath.dimensions.D3
+import kscience.kmath.dimensions.DMatrixContext
+import kscience.kmath.dimensions.Dimension
+import kscience.kmath.operations.RealField
 
 fun DMatrixContext<Double, RealField>.simple() {
     val m1 = produce<D2, D3> { i, j -> (i + j).toDouble() }
diff --git a/examples/src/main/kotlin/scientifik/kmath/ast/ExpressionsInterpretersBenchmark.kt b/examples/src/main/kotlin/scientifik/kmath/ast/ExpressionsInterpretersBenchmark.kt
deleted file mode 100644
index 17a70a4aa..000000000
--- a/examples/src/main/kotlin/scientifik/kmath/ast/ExpressionsInterpretersBenchmark.kt
+++ /dev/null
@@ -1,70 +0,0 @@
-package scientifik.kmath.ast
-
-import scientifik.kmath.asm.compile
-import scientifik.kmath.expressions.Expression
-import scientifik.kmath.expressions.expressionInField
-import scientifik.kmath.expressions.invoke
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.RealField
-import kotlin.random.Random
-import kotlin.system.measureTimeMillis
-
-class ExpressionsInterpretersBenchmark {
-    private val algebra: Field<Double> = RealField
-    fun functionalExpression() {
-        val expr = algebra.expressionInField {
-            variable("x") * const(2.0) + const(2.0) / variable("x") - const(16.0)
-        }
-
-        invokeAndSum(expr)
-    }
-
-    fun mstExpression() {
-        val expr = algebra.mstInField {
-            symbol("x") * number(2.0) + number(2.0) / symbol("x") - number(16.0)
-        }
-
-        invokeAndSum(expr)
-    }
-
-    fun asmExpression() {
-        val expr = algebra.mstInField {
-            symbol("x") * number(2.0) + number(2.0) / symbol("x") - number(16.0)
-        }.compile()
-
-        invokeAndSum(expr)
-    }
-
-    private fun invokeAndSum(expr: Expression<Double>) {
-        val random = Random(0)
-        var sum = 0.0
-
-        repeat(1000000) {
-            sum += expr("x" to random.nextDouble())
-        }
-
-        println(sum)
-    }
-}
-
-fun main() {
-    val benchmark = ExpressionsInterpretersBenchmark()
-
-    val fe = measureTimeMillis {
-        benchmark.functionalExpression()
-    }
-
-    println("fe=$fe")
-
-    val mst = measureTimeMillis {
-        benchmark.mstExpression()
-    }
-
-    println("mst=$mst")
-
-    val asm = measureTimeMillis {
-        benchmark.asmExpression()
-    }
-
-    println("asm=$asm")
-}
diff --git a/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt b/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt
index 58ad8a77c..3316f3236 100644
--- a/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt
+++ b/examples/src/main/kotlin/scientifik/kmath/linear/LinearAlgebraBenchmark.kt
@@ -1,13 +1,13 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.commons.linear.CMMatrixContext
-import scientifik.kmath.commons.linear.inverse
-import scientifik.kmath.commons.linear.toCM
-import scientifik.kmath.ejml.EjmlMatrixContext
-import scientifik.kmath.ejml.inverse
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.structures.Matrix
+import kscience.kmath.commons.linear.CMMatrixContext
+import kscience.kmath.commons.linear.inverse
+import kscience.kmath.commons.linear.toCM
+import kscience.kmath.ejml.EjmlMatrixContext
+import kscience.kmath.ejml.inverse
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.invoke
+import kscience.kmath.structures.Matrix
 import kotlin.random.Random
 import kotlin.system.measureTimeMillis
 
diff --git a/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt b/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt
index 6e3f786ea..b82c8aac4 100644
--- a/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt
+++ b/examples/src/main/kotlin/scientifik/kmath/linear/MultiplicationBenchmark.kt
@@ -1,11 +1,11 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.commons.linear.CMMatrixContext
-import scientifik.kmath.commons.linear.toCM
-import scientifik.kmath.ejml.EjmlMatrixContext
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.structures.Matrix
+import kscience.kmath.commons.linear.CMMatrixContext
+import kscience.kmath.commons.linear.toCM
+import kscience.kmath.ejml.EjmlMatrixContext
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.invoke
+import kscience.kmath.structures.Matrix
 import kotlin.random.Random
 import kotlin.system.measureTimeMillis
 
@@ -36,3 +36,14 @@ fun main() {
     val genericTime = measureTimeMillis { val res = matrix1 dot matrix2 }
     println("Generic implementation time: $genericTime")
 }
+
+    (EjmlMatrixContext(RealField)) {
+        val ejmlMatrix1 = matrix1.toEjml()
+        val ejmlMatrix2 = matrix2.toEjml()
+        val ejmlTime = measureTimeMillis { ejmlMatrix1 dot ejmlMatrix2 }
+        println("EJML implementation time: $ejmlTime")
+    }
+
+    val genericTime = measureTimeMillis { val res = matrix1 dot matrix2 }
+    println("Generic implementation time: $genericTime")
+}
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index 62d4c0535..e708b1c02 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index bb8b2fc26..12d38de6a 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.5.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
 zipStoreBase=GRADLE_USER_HOME
 zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index fbd7c5158..4f906e0c8 100755
--- a/gradlew
+++ b/gradlew
@@ -130,7 +130,7 @@ fi
 if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
     APP_HOME=`cygpath --path --mixed "$APP_HOME"`
     CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
-    
+
     JAVACMD=`cygpath --unix "$JAVACMD"`
 
     # We build the pattern for arguments to be converted via cygpath
diff --git a/gradlew.bat b/gradlew.bat
index 5093609d5..107acd32c 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -40,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
 
 set JAVA_EXE=java.exe
 %JAVA_EXE% -version >NUL 2>&1
-if "%ERRORLEVEL%" == "0" goto init
+if "%ERRORLEVEL%" == "0" goto execute
 
 echo.
 echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +54,7 @@ goto fail
 set JAVA_HOME=%JAVA_HOME:"=%
 set JAVA_EXE=%JAVA_HOME%/bin/java.exe
 
-if exist "%JAVA_EXE%" goto init
+if exist "%JAVA_EXE%" goto execute
 
 echo.
 echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,21 +64,6 @@ echo location of your Java installation.
 
 goto fail
 
-:init
-@rem Get command-line arguments, handling Windows variants
-
-if not "%OS%" == "Windows_NT" goto win9xME_args
-
-:win9xME_args
-@rem Slurp the command line arguments.
-set CMD_LINE_ARGS=
-set _SKIP=2
-
-:win9xME_args_slurp
-if "x%~1" == "x" goto execute
-
-set CMD_LINE_ARGS=%*
-
 :execute
 @rem Setup the command line
 
@@ -86,7 +71,7 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
 
 
 @rem Execute Gradle
-"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
 
 :end
 @rem End local scope for the variables with windows NT shell
diff --git a/kmath-ast/README.md b/kmath-ast/README.md
index 2339d0426..043224800 100644
--- a/kmath-ast/README.md
+++ b/kmath-ast/README.md
@@ -8,32 +8,32 @@ This subproject implements the following features:
 - Evaluating expressions by traversing MST.
 
 > #### Artifact:
-> This module is distributed in the artifact `scientifik:kmath-ast:0.1.4-dev-8`.
+> This module is distributed in the artifact `kscience.kmath:kmath-ast:0.1.4-dev-8`.
 > 
 > **Gradle:**
 >
 > ```gradle
 > repositories {
->     maven { url 'https://dl.bintray.com/mipt-npm/scientifik' }
+>     maven { url 'https://dl.bintray.com/mipt-npm/kscience' }
 >     maven { url 'https://dl.bintray.com/mipt-npm/dev' }
 >     maven { url https://dl.bintray.com/hotkeytlt/maven' }
 > }
 > 
 > dependencies {
->     implementation 'scientifik:kmath-ast:0.1.4-dev-8'
+>     implementation 'kscience.kmath:kmath-ast:0.1.4-dev-8'
 > }
 > ```
 > **Gradle Kotlin DSL:**
 >
 > ```kotlin
 > repositories {
->     maven("https://dl.bintray.com/mipt-npm/scientifik")
+>     maven("https://dl.bintray.com/mipt-npm/kscience")
 >     maven("https://dl.bintray.com/mipt-npm/dev")
 >     maven("https://dl.bintray.com/hotkeytlt/maven")
 > }
 > 
 > dependencies {
->     implementation("scientifik:kmath-ast:0.1.4-dev-8")
+>     implementation("kscience.kmath:kmath-ast:0.1.4-dev-8")
 > }
 > ```
 >
@@ -52,12 +52,12 @@ RealField.mstInField { symbol("x") + 2 }.compile()
 … leads to generation of bytecode, which can be decompiled to the following Java class: 
 
 ```java
-package scientifik.kmath.asm.generated;
+package kscience.kmath.asm.generated;
 
 import java.util.Map;
-import scientifik.kmath.asm.internal.MapIntrinsics;
-import scientifik.kmath.expressions.Expression;
-import scientifik.kmath.operations.RealField;
+import kscience.kmath.asm.internal.MapIntrinsics;
+import kscience.kmath.expressions.Expression;
+import kscience.kmath.operations.RealField;
 
 public final class AsmCompiledExpression_1073786867_0 implements Expression<Double> {
     private final RealField algebra;
diff --git a/kmath-ast/build.gradle.kts b/kmath-ast/build.gradle.kts
index ace121a09..df876df10 100644
--- a/kmath-ast/build.gradle.kts
+++ b/kmath-ast/build.gradle.kts
@@ -1,12 +1,11 @@
 plugins {
-    id("scientifik.mpp")
+    id("ru.mipt.npm.mpp")
 }
 
 kotlin.sourceSets {
     commonMain {
         dependencies {
             api(project(":kmath-core"))
-            implementation("com.github.h0tk3y.betterParse:better-parse:0.4.0")
         }
     }
 
@@ -14,7 +13,8 @@ kotlin.sourceSets {
         dependencies {
             implementation("org.ow2.asm:asm:8.0.1")
             implementation("org.ow2.asm:asm-commons:8.0.1")
+            implementation("com.github.h0tk3y.betterParse:better-parse:0.4.0")
             implementation(kotlin("reflect"))
         }
     }
-}
\ No newline at end of file
+}
diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MST.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt
similarity index 76%
rename from kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MST.kt
rename to kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt
index 0e8151c04..f312323b9 100644
--- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MST.kt
+++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MST.kt
@@ -1,26 +1,28 @@
-package scientifik.kmath.ast
+package kscience.kmath.ast
 
-import scientifik.kmath.operations.Algebra
-import scientifik.kmath.operations.NumericAlgebra
-import scientifik.kmath.operations.RealField
+import kscience.kmath.operations.Algebra
+import kscience.kmath.operations.NumericAlgebra
+import kscience.kmath.operations.RealField
 
 /**
  * A Mathematical Syntax Tree node for mathematical expressions.
+ *
+ * @author Alexander Nozik
  */
-sealed class MST {
+public sealed class MST {
     /**
      * A node containing raw string.
      *
      * @property value the value of this node.
      */
-    data class Symbolic(val value: String) : MST()
+    public data class Symbolic(val value: String) : MST()
 
     /**
      * A node containing a numeric value or scalar.
      *
      * @property value the value of this number.
      */
-    data class Numeric(val value: Number) : MST()
+    public data class Numeric(val value: Number) : MST()
 
     /**
      * A node containing an unary operation.
@@ -28,9 +30,7 @@ sealed class MST {
      * @property operation the identifier of operation.
      * @property value the argument of this operation.
      */
-    data class Unary(val operation: String, val value: MST) : MST() {
-        companion object
-    }
+    public data class Unary(val operation: String, val value: MST) : MST()
 
     /**
      * A node containing binary operation.
@@ -39,9 +39,7 @@ sealed class MST {
      * @property left the left operand.
      * @property right the right operand.
      */
-    data class Binary(val operation: String, val left: MST, val right: MST) : MST() {
-        companion object
-    }
+    public data class Binary(val operation: String, val left: MST, val right: MST) : MST()
 }
 
 // TODO add a function with named arguments
@@ -52,8 +50,9 @@ sealed class MST {
  * @receiver the algebra that provides operations.
  * @param node the node to evaluate.
  * @return the value of expression.
+ * @author Alexander Nozik
  */
-fun <T> Algebra<T>.evaluate(node: MST): T = when (node) {
+public fun <T> Algebra<T>.evaluate(node: MST): T = when (node) {
     is MST.Numeric -> (this as? NumericAlgebra<T>)?.number(node.value)
         ?: error("Numeric nodes are not supported by $this")
     is MST.Symbolic -> symbol(node.value)
@@ -84,4 +83,4 @@ fun <T> Algebra<T>.evaluate(node: MST): T = when (node) {
  * @param algebra the algebra that provides operations.
  * @return the value of expression.
  */
-fun <T> MST.interpret(algebra: Algebra<T>): T = algebra.evaluate(this)
+public fun <T> MST.interpret(algebra: Algebra<T>): T = algebra.evaluate(this)
diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt
similarity index 63%
rename from kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt
rename to kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt
index 23deae24b..64a820b20 100644
--- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstAlgebra.kt
+++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstAlgebra.kt
@@ -1,11 +1,11 @@
-package scientifik.kmath.ast
+package kscience.kmath.ast
 
-import scientifik.kmath.operations.*
+import kscience.kmath.operations.*
 
 /**
  * [Algebra] over [MST] nodes.
  */
-object MstAlgebra : NumericAlgebra<MST> {
+public object MstAlgebra : NumericAlgebra<MST> {
     override fun number(value: Number): MST = MST.Numeric(value)
 
     override fun symbol(value: String): MST = MST.Symbolic(value)
@@ -20,7 +20,7 @@ object MstAlgebra : NumericAlgebra<MST> {
 /**
  * [Space] over [MST] nodes.
  */
-object MstSpace : Space<MST>, NumericAlgebra<MST> {
+public object MstSpace : Space<MST>, NumericAlgebra<MST> {
     override val zero: MST = number(0.0)
 
     override fun number(value: Number): MST = MstAlgebra.number(value)
@@ -37,8 +37,9 @@ object MstSpace : Space<MST>, NumericAlgebra<MST> {
 /**
  * [Ring] over [MST] nodes.
  */
-object MstRing : Ring<MST>, NumericAlgebra<MST> {
-    override val zero: MST = number(0.0)
+public object MstRing : Ring<MST>, NumericAlgebra<MST> {
+    override val zero: MST
+        get() = MstSpace.zero
     override val one: MST = number(1.0)
 
     override fun number(value: Number): MST = MstSpace.number(value)
@@ -58,18 +59,21 @@ object MstRing : Ring<MST>, NumericAlgebra<MST> {
 /**
  * [Field] over [MST] nodes.
  */
-object MstField : Field<MST> {
-    override val zero: MST = number(0.0)
-    override val one: MST = number(1.0)
+public object MstField : Field<MST> {
+    public override val zero: MST
+        get() = MstRing.zero
 
-    override fun symbol(value: String): MST = MstRing.symbol(value)
-    override fun number(value: Number): MST = MstRing.number(value)
-    override fun add(a: MST, b: MST): MST = MstRing.add(a, b)
-    override fun multiply(a: MST, k: Number): MST = MstRing.multiply(a, k)
-    override fun multiply(a: MST, b: MST): MST = MstRing.multiply(a, b)
-    override fun divide(a: MST, b: MST): MST = binaryOperation(FieldOperations.DIV_OPERATION, a, b)
+    public override val one: MST
+        get() = MstRing.one
 
-    override fun binaryOperation(operation: String, left: MST, right: MST): MST =
+    public override fun symbol(value: String): MST = MstRing.symbol(value)
+    public override fun number(value: Number): MST = MstRing.number(value)
+    public override fun add(a: MST, b: MST): MST = MstRing.add(a, b)
+    public override fun multiply(a: MST, k: Number): MST = MstRing.multiply(a, k)
+    public override fun multiply(a: MST, b: MST): MST = MstRing.multiply(a, b)
+    public override fun divide(a: MST, b: MST): MST = binaryOperation(FieldOperations.DIV_OPERATION, a, b)
+
+    public override fun binaryOperation(operation: String, left: MST, right: MST): MST =
         MstRing.binaryOperation(operation, left, right)
 
     override fun unaryOperation(operation: String, arg: MST): MST = MstRing.unaryOperation(operation, arg)
@@ -78,15 +82,26 @@ object MstField : Field<MST> {
 /**
  * [ExtendedField] over [MST] nodes.
  */
-object MstExtendedField : ExtendedField<MST> {
-    override val zero: MST = number(0.0)
-    override val one: MST = number(1.0)
+public object MstExtendedField : ExtendedField<MST> {
+    override val zero: MST
+        get() = MstField.zero
 
+    override val one: MST
+        get() = MstField.one
+
+    override fun symbol(value: String): MST = MstField.symbol(value)
     override fun sin(arg: MST): MST = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg)
     override fun cos(arg: MST): MST = unaryOperation(TrigonometricOperations.COS_OPERATION, arg)
+    override fun tan(arg: MST): MST = unaryOperation(TrigonometricOperations.TAN_OPERATION, arg)
     override fun asin(arg: MST): MST = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg)
     override fun acos(arg: MST): MST = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg)
     override fun atan(arg: MST): MST = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg)
+    override fun sinh(arg: MST): MST = unaryOperation(HyperbolicOperations.SINH_OPERATION, arg)
+    override fun cosh(arg: MST): MST = unaryOperation(HyperbolicOperations.COSH_OPERATION, arg)
+    override fun tanh(arg: MST): MST = unaryOperation(HyperbolicOperations.TANH_OPERATION, arg)
+    override fun asinh(arg: MST): MST = unaryOperation(HyperbolicOperations.ASINH_OPERATION, arg)
+    override fun acosh(arg: MST): MST = unaryOperation(HyperbolicOperations.ACOSH_OPERATION, arg)
+    override fun atanh(arg: MST): MST = unaryOperation(HyperbolicOperations.ATANH_OPERATION, arg)
     override fun add(a: MST, b: MST): MST = MstField.add(a, b)
     override fun multiply(a: MST, k: Number): MST = MstField.multiply(a, k)
     override fun multiply(a: MST, b: MST): MST = MstField.multiply(a, b)
diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstExpression.kt b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt
similarity index 61%
rename from kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstExpression.kt
rename to kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt
index 293152cdd..483bc530c 100644
--- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/MstExpression.kt
+++ b/kmath-ast/src/commonMain/kotlin/kscience/kmath/ast/MstExpression.kt
@@ -1,7 +1,7 @@
-package scientifik.kmath.ast
+package kscience.kmath.ast
 
-import scientifik.kmath.expressions.*
-import scientifik.kmath.operations.*
+import kscience.kmath.expressions.*
+import kscience.kmath.operations.*
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
 
@@ -11,8 +11,9 @@ import kotlin.contracts.contract
  *
  * @property algebra the algebra that provides operations.
  * @property mst the [MST] node.
+ * @author Alexander Nozik
  */
-class MstExpression<T>(val algebra: Algebra<T>, val mst: MST) : Expression<T> {
+public class MstExpression<T>(public val algebra: Algebra<T>, public val mst: MST) : Expression<T> {
     private inner class InnerAlgebra(val arguments: Map<String, T>) : NumericAlgebra<T> {
         override fun symbol(value: String): T = arguments[value] ?: algebra.symbol(value)
         override fun unaryOperation(operation: String, arg: T): T = algebra.unaryOperation(operation, arg)
@@ -31,72 +32,92 @@ class MstExpression<T>(val algebra: Algebra<T>, val mst: MST) : Expression<T> {
 
 /**
  * Builds [MstExpression] over [Algebra].
+ *
+ * @author Alexander Nozik
  */
-inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst(
+public inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst(
     mstAlgebra: E,
     block: E.() -> MST
 ): MstExpression<T> = MstExpression(this, mstAlgebra.block())
 
 /**
  * Builds [MstExpression] over [Space].
+ *
+ * @author Alexander Nozik
  */
-inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> {
+public inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return MstExpression(this, MstSpace.block())
 }
 
 /**
  * Builds [MstExpression] over [Ring].
+ *
+ * @author Alexander Nozik
  */
-inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST): MstExpression<T> {
+public inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST): MstExpression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return MstExpression(this, MstRing.block())
 }
 
 /**
  * Builds [MstExpression] over [Field].
+ *
+ * @author Alexander Nozik
  */
-inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MST): MstExpression<T> {
+public inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MST): MstExpression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return MstExpression(this, MstField.block())
 }
 
 /**
  * Builds [MstExpression] over [ExtendedField].
+ *
+ * @author Iaroslav Postovalov
  */
-inline fun <reified T : Any> Field<T>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> {
+public inline fun <reified T : Any> Field<T>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return MstExpression(this, MstExtendedField.block())
 }
 
 /**
  * Builds [MstExpression] over [FunctionalExpressionSpace].
+ *
+ * @author Alexander Nozik
  */
-inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> {
+public inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return algebra.mstInSpace(block)
 }
 
 /**
  * Builds [MstExpression] over [FunctionalExpressionRing].
+ *
+ * @author Alexander Nozik
  */
-inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.mstInRing(block: MstRing.() -> MST): MstExpression<T> {
+public inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.mstInRing(block: MstRing.() -> MST): MstExpression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return algebra.mstInRing(block)
 }
 
 /**
  * Builds [MstExpression] over [FunctionalExpressionField].
+ *
+ * @author Alexander Nozik
  */
-inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A>.mstInField(block: MstField.() -> MST): MstExpression<T> {
+public inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A>.mstInField(block: MstField.() -> MST): MstExpression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return algebra.mstInField(block)
 }
 
 /**
  * Builds [MstExpression] over [FunctionalExpressionExtendedField].
+ *
+ * @author Iaroslav Postovalov
  */
-inline fun <reified T : Any, A : ExtendedField<T>> FunctionalExpressionExtendedField<T, A>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> {
+public inline fun <reified T : Any, A : ExtendedField<T>> FunctionalExpressionExtendedField<T, A>.mstInExtendedField(
+    block: MstExtendedField.() -> MST
+): MstExpression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return algebra.mstInExtendedField(block)
 }
diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt
similarity index 55%
rename from kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt
rename to kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt
index ee0ea15ff..edfe7f01d 100644
--- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/asm.kt
+++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/asm.kt
@@ -1,19 +1,24 @@
-package scientifik.kmath.asm
+package kscience.kmath.asm
 
-import scientifik.kmath.asm.internal.AsmBuilder
-import scientifik.kmath.asm.internal.MstType
-import scientifik.kmath.asm.internal.buildAlgebraOperationCall
-import scientifik.kmath.asm.internal.buildName
-import scientifik.kmath.ast.MST
-import scientifik.kmath.ast.MstExpression
-import scientifik.kmath.expressions.Expression
-import scientifik.kmath.operations.Algebra
+import kscience.kmath.asm.internal.AsmBuilder
+import kscience.kmath.asm.internal.MstType
+import kscience.kmath.asm.internal.buildAlgebraOperationCall
+import kscience.kmath.asm.internal.buildName
+import kscience.kmath.ast.MST
+import kscience.kmath.ast.MstExpression
+import kscience.kmath.expressions.Expression
+import kscience.kmath.operations.Algebra
 import kotlin.reflect.KClass
 
 /**
- * Compile given MST to an Expression using AST compiler
+ * Compiles given MST to an Expression using AST compiler.
+ *
+ * @param type the target type.
+ * @param algebra the target algebra.
+ * @return the compiled expression.
+ * @author Alexander Nozik
  */
-fun <T : Any> MST.compileWith(type: KClass<T>, algebra: Algebra<T>): Expression<T> {
+public fun <T : Any> MST.compileWith(type: KClass<T>, algebra: Algebra<T>): Expression<T> {
     fun AsmBuilder<T>.visit(node: MST) {
         when (node) {
             is MST.Symbolic -> {
@@ -54,11 +59,15 @@ fun <T : Any> MST.compileWith(type: KClass<T>, algebra: Algebra<T>): Expression<
 }
 
 /**
- * Compile an [MST] to ASM using given algebra
+ * Compiles an [MST] to ASM using given algebra.
+ *
+ * @author Alexander Nozik.
  */
-inline fun <reified T : Any> Algebra<T>.expression(mst: MST): Expression<T> = mst.compileWith(T::class, this)
+public inline fun <reified T : Any> Algebra<T>.expression(mst: MST): Expression<T> = mst.compileWith(T::class, this)
 
 /**
- * Optimize performance of an [MstExpression] using ASM codegen
+ * Optimizes performance of an [MstExpression] using ASM codegen.
+ *
+ * @author Alexander Nozik.
  */
-inline fun <reified T : Any> MstExpression<T>.compile(): Expression<T> = mst.compileWith(T::class, algebra)
+public inline fun <reified T : Any> MstExpression<T>.compile(): Expression<T> = mst.compileWith(T::class, algebra)
diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/AsmBuilder.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt
similarity index 98%
rename from kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/AsmBuilder.kt
rename to kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt
index f8c159baf..ab2de97aa 100644
--- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/AsmBuilder.kt
+++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/AsmBuilder.kt
@@ -1,13 +1,13 @@
-package scientifik.kmath.asm.internal
+package kscience.kmath.asm.internal
 
+import kscience.kmath.asm.internal.AsmBuilder.ClassLoader
+import kscience.kmath.ast.MST
+import kscience.kmath.expressions.Expression
+import kscience.kmath.operations.Algebra
+import kscience.kmath.operations.NumericAlgebra
 import org.objectweb.asm.*
 import org.objectweb.asm.Opcodes.*
 import org.objectweb.asm.commons.InstructionAdapter
-import scientifik.kmath.asm.internal.AsmBuilder.ClassLoader
-import scientifik.kmath.ast.MST
-import scientifik.kmath.expressions.Expression
-import scientifik.kmath.operations.Algebra
-import scientifik.kmath.operations.NumericAlgebra
 import java.util.*
 import java.util.stream.Collectors
 import kotlin.reflect.KClass
@@ -20,6 +20,7 @@ import kotlin.reflect.KClass
  * @property algebra the algebra the applied AsmExpressions use.
  * @property className the unique class name of new loaded class.
  * @property invokeLabel0Visitor the function to apply to this object when generating invoke method, label 0.
+ * @author Iaroslav Postovalov
  */
 internal class AsmBuilder<T> internal constructor(
     private val classOfT: KClass<*>,
@@ -563,6 +564,6 @@ internal class AsmBuilder<T> internal constructor(
         /**
          * ASM type for MapIntrinsics.
          */
-        internal val MAP_INTRINSICS_TYPE: Type by lazy { Type.getObjectType("scientifik/kmath/asm/internal/MapIntrinsics") }
+        internal val MAP_INTRINSICS_TYPE: Type by lazy { Type.getObjectType("kscience/kmath/asm/internal/MapIntrinsics") }
     }
 }
diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/MstType.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/MstType.kt
similarity index 62%
rename from kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/MstType.kt
rename to kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/MstType.kt
index bf73d304b..526c27305 100644
--- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/MstType.kt
+++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/MstType.kt
@@ -1,7 +1,10 @@
-package scientifik.kmath.asm.internal
+package kscience.kmath.asm.internal
 
-import scientifik.kmath.ast.MST
+import kscience.kmath.ast.MST
 
+/**
+ * Represents types known in [MST], numbers and general values.
+ */
 internal enum class MstType {
     GENERAL,
     NUMBER;
diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/codegenUtils.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt
similarity index 81%
rename from kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/codegenUtils.kt
rename to kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt
index 021c8ae02..67fce40ac 100644
--- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/codegenUtils.kt
+++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/codegenUtils.kt
@@ -1,11 +1,14 @@
-package scientifik.kmath.asm.internal
+package kscience.kmath.asm.internal
 
+import kscience.kmath.ast.MST
+import kscience.kmath.expressions.Expression
+import kscience.kmath.operations.Algebra
+import kscience.kmath.operations.FieldOperations
+import kscience.kmath.operations.RingOperations
+import kscience.kmath.operations.SpaceOperations
 import org.objectweb.asm.*
 import org.objectweb.asm.Opcodes.INVOKEVIRTUAL
 import org.objectweb.asm.commons.InstructionAdapter
-import scientifik.kmath.ast.MST
-import scientifik.kmath.expressions.Expression
-import scientifik.kmath.operations.Algebra
 import java.lang.reflect.Method
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
@@ -13,20 +16,27 @@ import kotlin.reflect.KClass
 
 private val methodNameAdapters: Map<Pair<String, Int>, String> by lazy {
     hashMapOf(
-        "+" to 2 to "add",
-        "*" to 2 to "multiply",
-        "/" to 2 to "divide",
-        "+" to 1 to "unaryPlus",
-        "-" to 1 to "unaryMinus",
-        "-" to 2 to "minus"
+        SpaceOperations.PLUS_OPERATION to 2 to "add",
+        RingOperations.TIMES_OPERATION to 2 to "multiply",
+        FieldOperations.DIV_OPERATION to 2 to "divide",
+        SpaceOperations.PLUS_OPERATION to 1 to "unaryPlus",
+        SpaceOperations.MINUS_OPERATION to 1 to "unaryMinus",
+        SpaceOperations.MINUS_OPERATION to 2 to "minus"
     )
 }
 
+/**
+ * Returns ASM [Type] for given [KClass].
+ *
+ * @author Iaroslav Postovalov
+ */
 internal val KClass<*>.asm: Type
     get() = Type.getType(java)
 
 /**
  * Returns singleton array with this value if the [predicate] is true, returns empty array otherwise.
+ *
+ * @author Iaroslav Postovalov
  */
 internal inline fun <reified T> T.wrapToArrayIf(predicate: (T) -> Boolean): Array<T> {
     contract { callsInPlace(predicate, InvocationKind.EXACTLY_ONCE) }
@@ -35,11 +45,15 @@ internal inline fun <reified T> T.wrapToArrayIf(predicate: (T) -> Boolean): Arra
 
 /**
  * Creates an [InstructionAdapter] from this [MethodVisitor].
+ *
+ * @author Iaroslav Postovalov
  */
 private fun MethodVisitor.instructionAdapter(): InstructionAdapter = InstructionAdapter(this)
 
 /**
  * Creates an [InstructionAdapter] from this [MethodVisitor] and applies [block] to it.
+ *
+ * @author Iaroslav Postovalov
  */
 internal inline fun MethodVisitor.instructionAdapter(block: InstructionAdapter.() -> Unit): InstructionAdapter {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
@@ -48,6 +62,8 @@ internal inline fun MethodVisitor.instructionAdapter(block: InstructionAdapter.(
 
 /**
  * Constructs a [Label], then applies it to this visitor.
+ *
+ * @author Iaroslav Postovalov
  */
 internal fun MethodVisitor.label(): Label = Label().also { visitLabel(it) }
 
@@ -56,9 +72,11 @@ internal fun MethodVisitor.label(): Label = Label().also { visitLabel(it) }
  *
  * This methods helps to avoid collisions of class name to prevent loading several classes with the same name. If there
  * is a colliding class, change [collision] parameter or leave it `0` to check existing classes recursively.
+ *
+ * @author Iaroslav Postovalov
  */
 internal tailrec fun buildName(mst: MST, collision: Int = 0): String {
-    val name = "scientifik.kmath.asm.generated.AsmCompiledExpression_${mst.hashCode()}_$collision"
+    val name = "kscience.kmath.asm.generated.AsmCompiledExpression_${mst.hashCode()}_$collision"
 
     try {
         Class.forName(name)
@@ -75,6 +93,11 @@ internal inline fun ClassWriter(flags: Int, block: ClassWriter.() -> Unit): Clas
     return ClassWriter(flags).apply(block)
 }
 
+/**
+ * Invokes [visitField] and applies [block] to the [FieldVisitor].
+ *
+ * @author Iaroslav Postovalov
+ */
 internal inline fun ClassWriter.visitField(
     access: Int,
     name: String,
@@ -104,7 +127,7 @@ private fun <T> AsmBuilder<T>.findSpecific(context: Algebra<T>, name: String, pa
  * Checks if the target [context] for code generation contains a method with needed [name] and arity, also builds
  * type expectation stack for needed arity.
  *
- * @return `true` if contains, else `false`.
+ * @author Iaroslav Postovalov
  */
 private fun <T> AsmBuilder<T>.buildExpectationStack(
     context: Algebra<T>,
@@ -136,7 +159,7 @@ private fun <T> AsmBuilder<T>.mapTypes(method: Method, parameterTypes: Array<Mst
  * Checks if the target [context] for code generation contains a method with needed [name] and arity and inserts
  * [AsmBuilder.invokeAlgebraOperation] of this method.
  *
- * @return `true` if contains, else `false`.
+ * @author Iaroslav Postovalov
  */
 private fun <T> AsmBuilder<T>.tryInvokeSpecific(
     context: Algebra<T>,
@@ -160,7 +183,9 @@ private fun <T> AsmBuilder<T>.tryInvokeSpecific(
 }
 
 /**
- * Builds specialized algebra call with option to fallback to generic algebra operation accepting String.
+ * Builds specialized [context] call with option to fallback to generic algebra operation accepting [String].
+ *
+ * @author Iaroslav Postovalov
  */
 internal inline fun <T> AsmBuilder<T>.buildAlgebraOperationCall(
     context: Algebra<T>,
diff --git a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/mapIntrinsics.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/mapIntrinsics.kt
similarity index 51%
rename from kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/mapIntrinsics.kt
rename to kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/mapIntrinsics.kt
index 80e83c1bf..708b3c2b4 100644
--- a/kmath-ast/src/jvmMain/kotlin/scientifik/kmath/asm/internal/mapIntrinsics.kt
+++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/asm/internal/mapIntrinsics.kt
@@ -1,7 +1,12 @@
 @file:JvmName("MapIntrinsics")
 
-package scientifik.kmath.asm.internal
+package kscience.kmath.asm.internal
 
+/**
+ * Gets value with given [key] or throws [IllegalStateException] whenever it is not present.
+ *
+ * @author Iaroslav Postovalov
+ */
 @JvmOverloads
 internal fun <K, V> Map<K, V>.getOrFail(key: K, default: V? = null): V =
     this[key] ?: default ?: error("Parameter not found: $key")
diff --git a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/parser.kt b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt
similarity index 71%
rename from kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/parser.kt
rename to kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt
index cba335a8d..15e6625db 100644
--- a/kmath-ast/src/commonMain/kotlin/scientifik/kmath/ast/parser.kt
+++ b/kmath-ast/src/jvmMain/kotlin/kscience/kmath/ast/parser.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.ast
+package kscience.kmath.ast
 
 import com.github.h0tk3y.betterParse.combinators.*
 import com.github.h0tk3y.betterParse.grammar.Grammar
@@ -10,15 +10,16 @@ import com.github.h0tk3y.betterParse.lexer.TokenMatch
 import com.github.h0tk3y.betterParse.lexer.regexToken
 import com.github.h0tk3y.betterParse.parser.ParseResult
 import com.github.h0tk3y.betterParse.parser.Parser
-import scientifik.kmath.operations.FieldOperations
-import scientifik.kmath.operations.PowerOperations
-import scientifik.kmath.operations.RingOperations
-import scientifik.kmath.operations.SpaceOperations
+import kscience.kmath.operations.FieldOperations
+import kscience.kmath.operations.PowerOperations
+import kscience.kmath.operations.RingOperations
+import kscience.kmath.operations.SpaceOperations
 
 /**
- * TODO move to core
+ * TODO move to common after IR version is released
+ * @author Alexander Nozik and Iaroslav Postovalov
  */
-object ArithmeticsEvaluator : Grammar<MST>() {
+public object ArithmeticsEvaluator : Grammar<MST>() {
     // TODO replace with "...".toRegex() when better-parse 0.4.1 is released
     private val num: Token by regexToken("[\\d.]+(?:[eE][-+]?\\d+)?")
     private val id: Token by regexToken("[a-z_A-Z][\\da-z_A-Z]*")
@@ -35,23 +36,23 @@ object ArithmeticsEvaluator : Grammar<MST>() {
     private val number: Parser<MST> by num use { MST.Numeric(text.toDouble()) }
     private val singular: Parser<MST> by id use { MST.Symbolic(text) }
 
-    private val unaryFunction: Parser<MST> by (id and skip(lpar) and parser(::subSumChain) and skip(rpar))
+    private val unaryFunction: Parser<MST> by (id and -lpar and parser(ArithmeticsEvaluator::subSumChain) and -rpar)
         .map { (id, term) -> MST.Unary(id.text, term) }
 
     private val binaryFunction: Parser<MST> by id
-        .and(skip(lpar))
-        .and(parser(::subSumChain))
-        .and(skip(comma))
-        .and(parser(::subSumChain))
-        .and(skip(rpar))
+        .and(-lpar)
+        .and(parser(ArithmeticsEvaluator::subSumChain))
+        .and(-comma)
+        .and(parser(ArithmeticsEvaluator::subSumChain))
+        .and(-rpar)
         .map { (id, left, right) -> MST.Binary(id.text, left, right) }
 
     private val term: Parser<MST> by number
         .or(binaryFunction)
         .or(unaryFunction)
         .or(singular)
-        .or(skip(minus) and parser(::term) map { MST.Unary(SpaceOperations.MINUS_OPERATION, it) })
-        .or(skip(lpar) and parser(::subSumChain) and skip(rpar))
+        .or(-minus and parser(ArithmeticsEvaluator::term) map { MST.Unary(SpaceOperations.MINUS_OPERATION, it) })
+        .or(-lpar and parser(ArithmeticsEvaluator::subSumChain) and -rpar)
 
     private val powChain: Parser<MST> by leftAssociative(term = term, operator = pow) { a, _, b ->
         MST.Binary(PowerOperations.POW_OPERATION, a, b)
@@ -85,13 +86,15 @@ object ArithmeticsEvaluator : Grammar<MST>() {
  *
  * @receiver the string to parse.
  * @return the [MST] node.
+ * @author Alexander Nozik
  */
-fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd(this)
+public fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd(this)
 
 /**
  * Parses the string into [MST].
  *
  * @receiver the string to parse.
  * @return the [MST] node.
+ * @author Alexander Nozik
  */
-fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this)
+public fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this)
diff --git a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmAlgebras.kt b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmAlgebras.kt
index 3acc6eb28..5d8f90c9b 100644
--- a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmAlgebras.kt
+++ b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmAlgebras.kt
@@ -1,12 +1,12 @@
 package scietifik.kmath.asm
 
-import scientifik.kmath.asm.compile
-import scientifik.kmath.ast.mstInField
-import scientifik.kmath.ast.mstInRing
-import scientifik.kmath.ast.mstInSpace
-import scientifik.kmath.expressions.invoke
-import scientifik.kmath.operations.ByteRing
-import scientifik.kmath.operations.RealField
+import kscience.kmath.asm.compile
+import kscience.kmath.ast.mstInField
+import kscience.kmath.ast.mstInRing
+import kscience.kmath.ast.mstInSpace
+import kscience.kmath.expressions.invoke
+import kscience.kmath.operations.ByteRing
+import kscience.kmath.operations.RealField
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmExpressions.kt b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmExpressions.kt
index 36c254c38..c2e45b8ff 100644
--- a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmExpressions.kt
+++ b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmExpressions.kt
@@ -1,10 +1,10 @@
 package scietifik.kmath.asm
 
-import scientifik.kmath.asm.compile
-import scientifik.kmath.ast.mstInField
-import scientifik.kmath.ast.mstInSpace
-import scientifik.kmath.expressions.invoke
-import scientifik.kmath.operations.RealField
+import kscience.kmath.asm.compile
+import kscience.kmath.ast.mstInField
+import kscience.kmath.ast.mstInSpace
+import kscience.kmath.expressions.invoke
+import kscience.kmath.operations.RealField
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmSpecialization.kt b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmSpecialization.kt
index a88431e9d..2b27fdc0f 100644
--- a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmSpecialization.kt
+++ b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmSpecialization.kt
@@ -1,9 +1,9 @@
 package scietifik.kmath.asm
 
-import scientifik.kmath.asm.compile
-import scientifik.kmath.ast.mstInField
-import scientifik.kmath.expressions.invoke
-import scientifik.kmath.operations.RealField
+import kscience.kmath.asm.compile
+import kscience.kmath.ast.mstInField
+import kscience.kmath.expressions.invoke
+import kscience.kmath.operations.RealField
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmVariables.kt b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmVariables.kt
index aafc75448..3511be97c 100644
--- a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmVariables.kt
+++ b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/asm/TestAsmVariables.kt
@@ -1,8 +1,8 @@
 package scietifik.kmath.asm
 
-import scientifik.kmath.ast.mstInRing
-import scientifik.kmath.expressions.invoke
-import scientifik.kmath.operations.ByteRing
+import kscience.kmath.ast.mstInRing
+import kscience.kmath.expressions.invoke
+import kscience.kmath.operations.ByteRing
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertFailsWith
diff --git a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/AsmTest.kt b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/AsmTest.kt
index 75659cc35..bb371bed0 100644
--- a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/AsmTest.kt
+++ b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/AsmTest.kt
@@ -1,12 +1,12 @@
 package scietifik.kmath.ast
 
-import scientifik.kmath.asm.compile
-import scientifik.kmath.asm.expression
-import scientifik.kmath.ast.mstInField
-import scientifik.kmath.ast.parseMath
-import scientifik.kmath.expressions.invoke
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.ComplexField
+import kscience.kmath.asm.compile
+import kscience.kmath.asm.expression
+import kscience.kmath.ast.mstInField
+import kscience.kmath.ast.parseMath
+import kscience.kmath.expressions.invoke
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.ComplexField
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/ParserPrecedenceTest.kt b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/ParserPrecedenceTest.kt
index 9bdbb12c9..21ee47d13 100644
--- a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/ParserPrecedenceTest.kt
+++ b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/ParserPrecedenceTest.kt
@@ -1,9 +1,9 @@
 package scietifik.kmath.ast
 
-import scientifik.kmath.ast.evaluate
-import scientifik.kmath.ast.parseMath
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.RealField
+import kscience.kmath.ast.evaluate
+import kscience.kmath.ast.parseMath
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.RealField
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/ParserTest.kt b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/ParserTest.kt
index 9179c3428..8a5d6ba48 100644
--- a/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/ParserTest.kt
+++ b/kmath-ast/src/jvmTest/kotlin/scietifik/kmath/ast/ParserTest.kt
@@ -1,13 +1,13 @@
 package scietifik.kmath.ast
 
-import scientifik.kmath.ast.evaluate
-import scientifik.kmath.ast.mstInField
-import scientifik.kmath.ast.parseMath
-import scientifik.kmath.expressions.invoke
-import scientifik.kmath.operations.Algebra
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.ComplexField
-import scientifik.kmath.operations.RealField
+import kscience.kmath.ast.evaluate
+import kscience.kmath.ast.mstInField
+import kscience.kmath.ast.parseMath
+import kscience.kmath.expressions.invoke
+import kscience.kmath.operations.Algebra
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.ComplexField
+import kscience.kmath.operations.RealField
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-commons/build.gradle.kts b/kmath-commons/build.gradle.kts
index a77d8ab47..ed6452ad8 100644
--- a/kmath-commons/build.gradle.kts
+++ b/kmath-commons/build.gradle.kts
@@ -1,13 +1,12 @@
 plugins {
-    id("scientifik.jvm")
+    id("ru.mipt.npm.jvm")
 }
-
 description = "Commons math binding for kmath"
 
 dependencies {
     api(project(":kmath-core"))
     api(project(":kmath-coroutines"))
     api(project(":kmath-prob"))
-    api(project(":kmath-functions"))
+//    api(project(":kmath-functions"))
     api("org.apache.commons:commons-math3:3.6.1")
 }
diff --git a/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt b/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt
new file mode 100644
index 000000000..3ac908536
--- /dev/null
+++ b/kmath-commons/src/main/kotlin/kscience/kmath/commons/expressions/DiffExpression.kt
@@ -0,0 +1,128 @@
+package kscience.kmath.commons.expressions
+
+import kscience.kmath.expressions.Expression
+import kscience.kmath.expressions.ExpressionAlgebra
+import kscience.kmath.operations.ExtendedField
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.invoke
+import org.apache.commons.math3.analysis.differentiation.DerivativeStructure
+import kotlin.properties.ReadOnlyProperty
+
+/**
+ * A field wrapping commons-math derivative structures
+ */
+public class DerivativeStructureField(
+    public val order: Int,
+    public val parameters: Map<String, Double>
+) : ExtendedField<DerivativeStructure> {
+    public override val zero: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size) }
+    public override val one: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size, 1.0) }
+
+    private val variables: Map<String, DerivativeStructure> = parameters.mapValues { (key, value) ->
+        DerivativeStructure(parameters.size, order, parameters.keys.indexOf(key), value)
+    }
+
+    public val variable: ReadOnlyProperty<Any?, DerivativeStructure> = ReadOnlyProperty { _, property ->
+        variables[property.name] ?: error("A variable with name ${property.name} does not exist")
+    }
+
+    public fun variable(name: String, default: DerivativeStructure? = null): DerivativeStructure =
+        variables[name] ?: default ?: error("A variable with name $name does not exist")
+
+    public fun Number.const(): DerivativeStructure = DerivativeStructure(order, parameters.size, toDouble())
+
+    public fun DerivativeStructure.deriv(parName: String, order: Int = 1): Double {
+        return deriv(mapOf(parName to order))
+    }
+
+    public fun DerivativeStructure.deriv(orders: Map<String, Int>): Double {
+        return getPartialDerivative(*parameters.keys.map { orders[it] ?: 0 }.toIntArray())
+    }
+
+    public fun DerivativeStructure.deriv(vararg orders: Pair<String, Int>): Double = deriv(mapOf(*orders))
+    public override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b)
+
+    public override fun multiply(a: DerivativeStructure, k: Number): DerivativeStructure = when (k) {
+        is Double -> a.multiply(k)
+        is Int -> a.multiply(k)
+        else -> a.multiply(k.toDouble())
+    }
+
+    public override fun multiply(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.multiply(b)
+    public override fun divide(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.divide(b)
+    public override fun sin(arg: DerivativeStructure): DerivativeStructure = arg.sin()
+    public override fun cos(arg: DerivativeStructure): DerivativeStructure = arg.cos()
+    public override fun tan(arg: DerivativeStructure): DerivativeStructure = arg.tan()
+    public override fun asin(arg: DerivativeStructure): DerivativeStructure = arg.asin()
+    public override fun acos(arg: DerivativeStructure): DerivativeStructure = arg.acos()
+    public override fun atan(arg: DerivativeStructure): DerivativeStructure = arg.atan()
+    public override fun sinh(arg: DerivativeStructure): DerivativeStructure = arg.sinh()
+    public override fun cosh(arg: DerivativeStructure): DerivativeStructure = arg.cosh()
+    public override fun tanh(arg: DerivativeStructure): DerivativeStructure = arg.tanh()
+    public override fun asinh(arg: DerivativeStructure): DerivativeStructure = arg.asinh()
+    public override fun acosh(arg: DerivativeStructure): DerivativeStructure = arg.acosh()
+    public override fun atanh(arg: DerivativeStructure): DerivativeStructure = arg.atanh()
+
+    public override fun power(arg: DerivativeStructure, pow: Number): DerivativeStructure = when (pow) {
+        is Double -> arg.pow(pow)
+        is Int -> arg.pow(pow)
+        else -> arg.pow(pow.toDouble())
+    }
+
+    public fun power(arg: DerivativeStructure, pow: DerivativeStructure): DerivativeStructure = arg.pow(pow)
+    public override fun exp(arg: DerivativeStructure): DerivativeStructure = arg.exp()
+    public override fun ln(arg: DerivativeStructure): DerivativeStructure = arg.log()
+
+    public override operator fun DerivativeStructure.plus(b: Number): DerivativeStructure = add(b.toDouble())
+    public override operator fun DerivativeStructure.minus(b: Number): DerivativeStructure = subtract(b.toDouble())
+    public override operator fun Number.plus(b: DerivativeStructure): DerivativeStructure = b + this
+    public override operator fun Number.minus(b: DerivativeStructure): DerivativeStructure = b - this
+}
+
+/**
+ * A constructs that creates a derivative structure with required order on-demand
+ */
+public class DiffExpression(public val function: DerivativeStructureField.() -> DerivativeStructure) :
+    Expression<Double> {
+    public override operator fun invoke(arguments: Map<String, Double>): Double = DerivativeStructureField(
+        0,
+        arguments
+    ).function().value
+
+    /**
+     * Get the derivative expression with given orders
+     * TODO make result [DiffExpression]
+     */
+    public fun derivative(orders: Map<String, Int>): Expression<Double> = Expression { arguments ->
+        (DerivativeStructureField(orders.values.max() ?: 0, arguments)) { function().deriv(orders) }
+    }
+
+    //TODO add gradient and maybe other vector operators
+}
+
+public fun DiffExpression.derivative(vararg orders: Pair<String, Int>): Expression<Double> = derivative(mapOf(*orders))
+public fun DiffExpression.derivative(name: String): Expression<Double> = derivative(name to 1)
+
+/**
+ * A context for [DiffExpression] (not to be confused with [DerivativeStructure])
+ */
+public object DiffExpressionAlgebra : ExpressionAlgebra<Double, DiffExpression>, Field<DiffExpression> {
+    public override val zero: DiffExpression = DiffExpression { 0.0.const() }
+    public override val one: DiffExpression = DiffExpression { 1.0.const() }
+
+    public override fun variable(name: String, default: Double?): DiffExpression =
+        DiffExpression { variable(name, default?.const()) }
+
+    public override fun const(value: Double): DiffExpression = DiffExpression { value.const() }
+
+    public override fun add(a: DiffExpression, b: DiffExpression): DiffExpression =
+        DiffExpression { a.function(this) + b.function(this) }
+
+    public override fun multiply(a: DiffExpression, k: Number): DiffExpression = DiffExpression { a.function(this) * k }
+
+    public override fun multiply(a: DiffExpression, b: DiffExpression): DiffExpression =
+        DiffExpression { a.function(this) * b.function(this) }
+
+    public override fun divide(a: DiffExpression, b: DiffExpression): DiffExpression =
+        DiffExpression { a.function(this) / b.function(this) }
+}
diff --git a/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMMatrix.kt
new file mode 100644
index 000000000..377d167bc
--- /dev/null
+++ b/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMMatrix.kt
@@ -0,0 +1,93 @@
+package kscience.kmath.commons.linear
+
+import kscience.kmath.linear.*
+import kscience.kmath.structures.Matrix
+import kscience.kmath.structures.NDStructure
+import org.apache.commons.math3.linear.*
+
+public class CMMatrix(public val origin: RealMatrix, features: Set<MatrixFeature>? = null) :
+    FeaturedMatrix<Double> {
+    public override val rowNum: Int get() = origin.rowDimension
+    public override val colNum: Int get() = origin.columnDimension
+
+    public override val features: Set<MatrixFeature> = features ?: sequence<MatrixFeature> {
+        if (origin is DiagonalMatrix) yield(DiagonalFeature)
+    }.toHashSet()
+
+    public override fun suggestFeature(vararg features: MatrixFeature): CMMatrix =
+        CMMatrix(origin, this.features + features)
+
+    public override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j)
+
+    public override fun equals(other: Any?): Boolean {
+        return NDStructure.equals(this, other as? NDStructure<*> ?: return false)
+    }
+
+    public override fun hashCode(): Int {
+        var result = origin.hashCode()
+        result = 31 * result + features.hashCode()
+        return result
+    }
+}
+
+public fun Matrix<Double>.toCM(): CMMatrix = if (this is CMMatrix) {
+    this
+} else {
+    //TODO add feature analysis
+    val array = Array(rowNum) { i -> DoubleArray(colNum) { j -> get(i, j) } }
+    CMMatrix(Array2DRowRealMatrix(array))
+}
+
+public fun RealMatrix.asMatrix(): CMMatrix = CMMatrix(this)
+
+public class CMVector(public val origin: RealVector) : Point<Double> {
+    public override val size: Int get() = origin.dimension
+
+    public override operator fun get(index: Int): Double = origin.getEntry(index)
+
+    public override operator fun iterator(): Iterator<Double> = origin.toArray().iterator()
+}
+
+public fun Point<Double>.toCM(): CMVector = if (this is CMVector) this else {
+    val array = DoubleArray(size) { this[it] }
+    CMVector(ArrayRealVector(array))
+}
+
+public fun RealVector.toPoint(): CMVector = CMVector(this)
+
+public object CMMatrixContext : MatrixContext<Double> {
+    public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): CMMatrix {
+        val array = Array(rows) { i -> DoubleArray(columns) { j -> initializer(i, j) } }
+        return CMMatrix(Array2DRowRealMatrix(array))
+    }
+
+    public override fun Matrix<Double>.dot(other: Matrix<Double>): CMMatrix =
+        CMMatrix(toCM().origin.multiply(other.toCM().origin))
+
+    public override fun Matrix<Double>.dot(vector: Point<Double>): CMVector =
+        CMVector(toCM().origin.preMultiply(vector.toCM().origin))
+
+    public override operator fun Matrix<Double>.unaryMinus(): CMMatrix =
+        produce(rowNum, colNum) { i, j -> -get(i, j) }
+
+    public override fun add(a: Matrix<Double>, b: Matrix<Double>): CMMatrix =
+        CMMatrix(a.toCM().origin.multiply(b.toCM().origin))
+
+    public override operator fun Matrix<Double>.minus(b: Matrix<Double>): CMMatrix =
+        CMMatrix(toCM().origin.subtract(b.toCM().origin))
+
+    public override fun multiply(a: Matrix<Double>, k: Number): CMMatrix =
+        CMMatrix(a.toCM().origin.scalarMultiply(k.toDouble()))
+
+    public override operator fun Matrix<Double>.times(value: Double): Matrix<Double> =
+        produce(rowNum, colNum) { i, j -> get(i, j) * value }
+}
+
+public operator fun CMMatrix.plus(other: CMMatrix): CMMatrix =
+    CMMatrix(origin.add(other.origin))
+
+public operator fun CMMatrix.minus(other: CMMatrix): CMMatrix =
+    CMMatrix(origin.subtract(other.origin))
+
+public infix fun CMMatrix.dot(other: CMMatrix): CMMatrix =
+    CMMatrix(origin.multiply(other.origin))
diff --git a/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMSolver.kt b/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMSolver.kt
new file mode 100644
index 000000000..210014e1a
--- /dev/null
+++ b/kmath-commons/src/main/kotlin/kscience/kmath/commons/linear/CMSolver.kt
@@ -0,0 +1,41 @@
+package kscience.kmath.commons.linear
+
+import kscience.kmath.linear.Point
+import kscience.kmath.structures.Matrix
+import org.apache.commons.math3.linear.*
+
+public enum class CMDecomposition {
+    LUP,
+    QR,
+    RRQR,
+    EIGEN,
+    CHOLESKY
+}
+
+public fun CMMatrixContext.solver(
+    a: Matrix<Double>,
+    decomposition: CMDecomposition = CMDecomposition.LUP
+): DecompositionSolver = when (decomposition) {
+    CMDecomposition.LUP -> LUDecomposition(a.toCM().origin).solver
+    CMDecomposition.RRQR -> RRQRDecomposition(a.toCM().origin).solver
+    CMDecomposition.QR -> QRDecomposition(a.toCM().origin).solver
+    CMDecomposition.EIGEN -> EigenDecomposition(a.toCM().origin).solver
+    CMDecomposition.CHOLESKY -> CholeskyDecomposition(a.toCM().origin).solver
+}
+
+public fun CMMatrixContext.solve(
+    a: Matrix<Double>,
+    b: Matrix<Double>,
+    decomposition: CMDecomposition = CMDecomposition.LUP
+): CMMatrix = solver(a, decomposition).solve(b.toCM().origin).asMatrix()
+
+public fun CMMatrixContext.solve(
+    a: Matrix<Double>,
+    b: Point<Double>,
+    decomposition: CMDecomposition = CMDecomposition.LUP
+): CMVector = solver(a, decomposition).solve(b.toCM().origin).toPoint()
+
+public fun CMMatrixContext.inverse(
+    a: Matrix<Double>,
+    decomposition: CMDecomposition = CMDecomposition.LUP
+): CMMatrix = solver(a, decomposition).inverse.asMatrix()
diff --git a/kmath-commons/src/main/kotlin/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt b/kmath-commons/src/main/kotlin/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt
new file mode 100644
index 000000000..58609deae
--- /dev/null
+++ b/kmath-commons/src/main/kotlin/kscience/kmath/commons/random/CMRandomGeneratorWrapper.kt
@@ -0,0 +1,33 @@
+package kscience.kmath.commons.random
+
+import kscience.kmath.prob.RandomGenerator
+
+public class CMRandomGeneratorWrapper(public val factory: (IntArray) -> RandomGenerator) :
+    org.apache.commons.math3.random.RandomGenerator {
+    private var generator: RandomGenerator = factory(intArrayOf())
+
+    public override fun nextBoolean(): Boolean = generator.nextBoolean()
+    public override fun nextFloat(): Float = generator.nextDouble().toFloat()
+
+    public override fun setSeed(seed: Int) {
+        generator = factory(intArrayOf(seed))
+    }
+
+    public override fun setSeed(seed: IntArray) {
+        generator = factory(seed)
+    }
+
+    public override fun setSeed(seed: Long) {
+        setSeed(seed.toInt())
+    }
+
+    public override fun nextBytes(bytes: ByteArray) {
+        generator.fillBytes(bytes)
+    }
+
+    public override fun nextInt(): Int = generator.nextInt()
+    public override fun nextInt(n: Int): Int = generator.nextInt(n)
+    public override fun nextGaussian(): Double = TODO()
+    public override fun nextDouble(): Double = generator.nextDouble()
+    public override fun nextLong(): Long = generator.nextLong()
+}
diff --git a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/transform/Transformations.kt b/kmath-commons/src/main/kotlin/kscience/kmath/commons/transform/Transformations.kt
similarity index 81%
rename from kmath-commons/src/main/kotlin/scientifik/kmath/commons/transform/Transformations.kt
rename to kmath-commons/src/main/kotlin/kscience/kmath/commons/transform/Transformations.kt
index eb1b5b69a..cd2896be6 100644
--- a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/transform/Transformations.kt
+++ b/kmath-commons/src/main/kotlin/kscience/kmath/commons/transform/Transformations.kt
@@ -1,20 +1,19 @@
-package scientifik.kmath.commons.transform
+package kscience.kmath.commons.transform
 
 import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.map
+import kscience.kmath.operations.Complex
+import kscience.kmath.streaming.chunked
+import kscience.kmath.streaming.spread
+import kscience.kmath.structures.*
 import org.apache.commons.math3.transform.*
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.streaming.chunked
-import scientifik.kmath.streaming.spread
-import scientifik.kmath.structures.*
 
 
 /**
  * Streaming and buffer transformations
  */
-object Transformations {
-
+public object Transformations {
     private fun Buffer<Complex>.toArray(): Array<org.apache.commons.math3.complex.Complex> =
         Array(size) { org.apache.commons.math3.complex.Complex(get(it).re, get(it).im) }
 
@@ -32,35 +31,35 @@ object Transformations {
         Complex(value.real, value.imaginary)
     }
 
-    fun fourier(
+    public fun fourier(
         normalization: DftNormalization = DftNormalization.STANDARD,
         direction: TransformType = TransformType.FORWARD
     ): SuspendBufferTransform<Complex, Complex> = {
         FastFourierTransformer(normalization).transform(it.toArray(), direction).asBuffer()
     }
 
-    fun realFourier(
+    public fun realFourier(
         normalization: DftNormalization = DftNormalization.STANDARD,
         direction: TransformType = TransformType.FORWARD
     ): SuspendBufferTransform<Double, Complex> = {
         FastFourierTransformer(normalization).transform(it.asArray(), direction).asBuffer()
     }
 
-    fun sine(
+    public fun sine(
         normalization: DstNormalization = DstNormalization.STANDARD_DST_I,
         direction: TransformType = TransformType.FORWARD
     ): SuspendBufferTransform<Double, Double> = {
         FastSineTransformer(normalization).transform(it.asArray(), direction).asBuffer()
     }
 
-    fun cosine(
+    public fun cosine(
         normalization: DctNormalization = DctNormalization.STANDARD_DCT_I,
         direction: TransformType = TransformType.FORWARD
     ): SuspendBufferTransform<Double, Double> = {
         FastCosineTransformer(normalization).transform(it.asArray(), direction).asBuffer()
     }
 
-    fun hadamard(
+    public fun hadamard(
         direction: TransformType = TransformType.FORWARD
     ): SuspendBufferTransform<Double, Double> = {
         FastHadamardTransformer().transform(it.asArray(), direction).asBuffer()
@@ -71,7 +70,7 @@ object Transformations {
  * Process given [Flow] with commons-math fft transformation
  */
 @FlowPreview
-fun Flow<Buffer<Complex>>.FFT(
+public fun Flow<Buffer<Complex>>.FFT(
     normalization: DftNormalization = DftNormalization.STANDARD,
     direction: TransformType = TransformType.FORWARD
 ): Flow<Buffer<Complex>> {
@@ -81,7 +80,7 @@ fun Flow<Buffer<Complex>>.FFT(
 
 @FlowPreview
 @JvmName("realFFT")
-fun Flow<Buffer<Double>>.FFT(
+public fun Flow<Buffer<Double>>.FFT(
     normalization: DftNormalization = DftNormalization.STANDARD,
     direction: TransformType = TransformType.FORWARD
 ): Flow<Buffer<Complex>> {
@@ -90,20 +89,18 @@ fun Flow<Buffer<Double>>.FFT(
 }
 
 /**
- * Process a continous flow of real numbers in FFT splitting it in chunks of [bufferSize].
+ * Process a continuous flow of real numbers in FFT splitting it in chunks of [bufferSize].
  */
 @FlowPreview
 @JvmName("realFFT")
-fun Flow<Double>.FFT(
+public fun Flow<Double>.FFT(
     bufferSize: Int = Int.MAX_VALUE,
     normalization: DftNormalization = DftNormalization.STANDARD,
     direction: TransformType = TransformType.FORWARD
-): Flow<Complex> {
-    return chunked(bufferSize).FFT(normalization,direction).spread()
-}
+): Flow<Complex> = chunked(bufferSize).FFT(normalization, direction).spread()
 
 /**
  * Map a complex flow into real flow by taking real part of each number
  */
 @FlowPreview
-fun Flow<Complex>.real(): Flow<Double> = map{it.re}
\ No newline at end of file
+public fun Flow<Complex>.real(): Flow<Double> = map { it.re }
diff --git a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/expressions/DiffExpression.kt b/kmath-commons/src/main/kotlin/scientifik/kmath/commons/expressions/DiffExpression.kt
deleted file mode 100644
index 9119991e5..000000000
--- a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/expressions/DiffExpression.kt
+++ /dev/null
@@ -1,137 +0,0 @@
-package scientifik.kmath.commons.expressions
-
-import org.apache.commons.math3.analysis.differentiation.DerivativeStructure
-import scientifik.kmath.expressions.Expression
-import scientifik.kmath.expressions.ExpressionAlgebra
-import scientifik.kmath.operations.ExtendedField
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.invoke
-import kotlin.properties.ReadOnlyProperty
-import kotlin.reflect.KProperty
-
-/**
- * A field wrapping commons-math derivative structures
- */
-class DerivativeStructureField(
-    val order: Int,
-    val parameters: Map<String, Double>
-) : ExtendedField<DerivativeStructure> {
-    override val zero: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size) }
-    override val one: DerivativeStructure by lazy { DerivativeStructure(order, parameters.size, 1.0) }
-
-    private val variables: Map<String, DerivativeStructure> = parameters.mapValues { (key, value) ->
-        DerivativeStructure(parameters.size, order, parameters.keys.indexOf(key), value)
-    }
-
-    val variable: ReadOnlyProperty<Any?, DerivativeStructure> = object : ReadOnlyProperty<Any?, DerivativeStructure> {
-        override fun getValue(thisRef: Any?, property: KProperty<*>): DerivativeStructure =
-            variables[property.name] ?: error("A variable with name ${property.name} does not exist")
-    }
-
-    fun variable(name: String, default: DerivativeStructure? = null): DerivativeStructure =
-        variables[name] ?: default ?: error("A variable with name $name does not exist")
-
-    fun Number.const(): DerivativeStructure = DerivativeStructure(order, parameters.size, toDouble())
-
-    fun DerivativeStructure.deriv(parName: String, order: Int = 1): Double {
-        return deriv(mapOf(parName to order))
-    }
-
-    fun DerivativeStructure.deriv(orders: Map<String, Int>): Double {
-        return getPartialDerivative(*parameters.keys.map { orders[it] ?: 0 }.toIntArray())
-    }
-
-    fun DerivativeStructure.deriv(vararg orders: Pair<String, Int>): Double = deriv(mapOf(*orders))
-
-    override fun add(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.add(b)
-
-    override fun multiply(a: DerivativeStructure, k: Number): DerivativeStructure = when (k) {
-        is Double -> a.multiply(k)
-        is Int -> a.multiply(k)
-        else -> a.multiply(k.toDouble())
-    }
-
-    override fun multiply(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.multiply(b)
-
-    override fun divide(a: DerivativeStructure, b: DerivativeStructure): DerivativeStructure = a.divide(b)
-
-    override fun sin(arg: DerivativeStructure): DerivativeStructure = arg.sin()
-    override fun cos(arg: DerivativeStructure): DerivativeStructure = arg.cos()
-    override fun tan(arg: DerivativeStructure): DerivativeStructure = arg.tan()
-    override fun asin(arg: DerivativeStructure): DerivativeStructure = arg.asin()
-    override fun acos(arg: DerivativeStructure): DerivativeStructure = arg.acos()
-    override fun atan(arg: DerivativeStructure): DerivativeStructure = arg.atan()
-
-    override fun sinh(arg: DerivativeStructure): DerivativeStructure = arg.sinh()
-    override fun cosh(arg: DerivativeStructure): DerivativeStructure = arg.cosh()
-    override fun tanh(arg: DerivativeStructure): DerivativeStructure = arg.tanh()
-    override fun asinh(arg: DerivativeStructure): DerivativeStructure = arg.asinh()
-    override fun acosh(arg: DerivativeStructure): DerivativeStructure = arg.acosh()
-    override fun atanh(arg: DerivativeStructure): DerivativeStructure = arg.atanh()
-
-    override fun power(arg: DerivativeStructure, pow: Number): DerivativeStructure = when (pow) {
-        is Double -> arg.pow(pow)
-        is Int -> arg.pow(pow)
-        else -> arg.pow(pow.toDouble())
-    }
-
-    fun power(arg: DerivativeStructure, pow: DerivativeStructure): DerivativeStructure = arg.pow(pow)
-    override fun exp(arg: DerivativeStructure): DerivativeStructure = arg.exp()
-    override fun ln(arg: DerivativeStructure): DerivativeStructure = arg.log()
-
-    override operator fun DerivativeStructure.plus(b: Number): DerivativeStructure = add(b.toDouble())
-    override operator fun DerivativeStructure.minus(b: Number): DerivativeStructure = subtract(b.toDouble())
-    override operator fun Number.plus(b: DerivativeStructure): DerivativeStructure = b + this
-    override operator fun Number.minus(b: DerivativeStructure): DerivativeStructure = b - this
-}
-
-/**
- * A constructs that creates a derivative structure with required order on-demand
- */
-class DiffExpression(val function: DerivativeStructureField.() -> DerivativeStructure) : Expression<Double> {
-    override operator fun invoke(arguments: Map<String, Double>): Double = DerivativeStructureField(
-        0,
-        arguments
-    ).run(function).value
-
-    /**
-     * Get the derivative expression with given orders
-     * TODO make result [DiffExpression]
-     */
-    fun derivative(orders: Map<String, Int>): Expression<Double> = object : Expression<Double> {
-        override operator fun invoke(arguments: Map<String, Double>): Double =
-            (DerivativeStructureField(orders.values.max() ?: 0, arguments)) { function().deriv(orders) }
-    }
-
-    //TODO add gradient and maybe other vector operators
-}
-
-fun DiffExpression.derivative(vararg orders: Pair<String, Int>): Expression<Double> = derivative(mapOf(*orders))
-fun DiffExpression.derivative(name: String): Expression<Double> = derivative(name to 1)
-
-/**
- * A context for [DiffExpression] (not to be confused with [DerivativeStructure])
- */
-object DiffExpressionAlgebra : ExpressionAlgebra<Double, DiffExpression>, Field<DiffExpression> {
-    override fun variable(name: String, default: Double?): DiffExpression =
-        DiffExpression { variable(name, default?.const()) }
-
-    override fun const(value: Double): DiffExpression =
-        DiffExpression { value.const() }
-
-    override fun add(a: DiffExpression, b: DiffExpression): DiffExpression =
-        DiffExpression { a.function(this) + b.function(this) }
-
-    override val zero: DiffExpression = DiffExpression { 0.0.const() }
-
-    override fun multiply(a: DiffExpression, k: Number): DiffExpression =
-        DiffExpression { a.function(this) * k }
-
-    override val one: DiffExpression = DiffExpression { 1.0.const() }
-
-    override fun multiply(a: DiffExpression, b: DiffExpression): DiffExpression =
-        DiffExpression { a.function(this) * b.function(this) }
-
-    override fun divide(a: DiffExpression, b: DiffExpression): DiffExpression =
-        DiffExpression { a.function(this) / b.function(this) }
-}
diff --git a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/linear/CMMatrix.kt b/kmath-commons/src/main/kotlin/scientifik/kmath/commons/linear/CMMatrix.kt
deleted file mode 100644
index f0bbdbe65..000000000
--- a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/linear/CMMatrix.kt
+++ /dev/null
@@ -1,93 +0,0 @@
-package scientifik.kmath.commons.linear
-
-import org.apache.commons.math3.linear.*
-import scientifik.kmath.linear.*
-import scientifik.kmath.structures.Matrix
-import scientifik.kmath.structures.NDStructure
-
-class CMMatrix(val origin: RealMatrix, features: Set<MatrixFeature>? = null) :
-    FeaturedMatrix<Double> {
-    override val rowNum: Int get() = origin.rowDimension
-    override val colNum: Int get() = origin.columnDimension
-
-    override val features: Set<MatrixFeature> = features ?: sequence<MatrixFeature> {
-        if (origin is DiagonalMatrix) yield(DiagonalFeature)
-    }.toHashSet()
-
-    override fun suggestFeature(vararg features: MatrixFeature): CMMatrix =
-        CMMatrix(origin, this.features + features)
-
-    override operator fun get(i: Int, j: Int): Double = origin.getEntry(i, j)
-
-    override fun equals(other: Any?): Boolean {
-        return NDStructure.equals(this, other as? NDStructure<*> ?: return false)
-    }
-
-    override fun hashCode(): Int {
-        var result = origin.hashCode()
-        result = 31 * result + features.hashCode()
-        return result
-    }
-}
-
-fun Matrix<Double>.toCM(): CMMatrix = if (this is CMMatrix) {
-    this
-} else {
-    //TODO add feature analysis
-    val array = Array(rowNum) { i -> DoubleArray(colNum) { j -> get(i, j) } }
-    CMMatrix(Array2DRowRealMatrix(array))
-}
-
-fun RealMatrix.asMatrix(): CMMatrix = CMMatrix(this)
-
-class CMVector(val origin: RealVector) : Point<Double> {
-    override val size: Int get() = origin.dimension
-
-    override operator fun get(index: Int): Double = origin.getEntry(index)
-
-    override operator fun iterator(): Iterator<Double> = origin.toArray().iterator()
-}
-
-fun Point<Double>.toCM(): CMVector = if (this is CMVector) this else {
-    val array = DoubleArray(size) { this[it] }
-    CMVector(ArrayRealVector(array))
-}
-
-fun RealVector.toPoint(): CMVector = CMVector(this)
-
-object CMMatrixContext : MatrixContext<Double> {
-    override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): CMMatrix {
-        val array = Array(rows) { i -> DoubleArray(columns) { j -> initializer(i, j) } }
-        return CMMatrix(Array2DRowRealMatrix(array))
-    }
-
-    override fun Matrix<Double>.dot(other: Matrix<Double>): CMMatrix =
-        CMMatrix(this.toCM().origin.multiply(other.toCM().origin))
-
-    override fun Matrix<Double>.dot(vector: Point<Double>): CMVector =
-        CMVector(this.toCM().origin.preMultiply(vector.toCM().origin))
-
-    override operator fun Matrix<Double>.unaryMinus(): CMMatrix =
-        produce(rowNum, colNum) { i, j -> -get(i, j) }
-
-    override fun add(a: Matrix<Double>, b: Matrix<Double>): CMMatrix =
-        CMMatrix(a.toCM().origin.multiply(b.toCM().origin))
-
-    override operator fun Matrix<Double>.minus(b: Matrix<Double>): CMMatrix =
-        CMMatrix(this.toCM().origin.subtract(b.toCM().origin))
-
-    override fun multiply(a: Matrix<Double>, k: Number): CMMatrix =
-        CMMatrix(a.toCM().origin.scalarMultiply(k.toDouble()))
-
-    override operator fun Matrix<Double>.times(value: Double): Matrix<Double> =
-        produce(rowNum, colNum) { i, j -> get(i, j) * value }
-}
-
-operator fun CMMatrix.plus(other: CMMatrix): CMMatrix =
-    CMMatrix(this.origin.add(other.origin))
-
-operator fun CMMatrix.minus(other: CMMatrix): CMMatrix =
-    CMMatrix(this.origin.subtract(other.origin))
-
-infix fun CMMatrix.dot(other: CMMatrix): CMMatrix =
-    CMMatrix(this.origin.multiply(other.origin))
diff --git a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/linear/CMSolver.kt b/kmath-commons/src/main/kotlin/scientifik/kmath/commons/linear/CMSolver.kt
deleted file mode 100644
index 77b688e31..000000000
--- a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/linear/CMSolver.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package scientifik.kmath.commons.linear
-
-import org.apache.commons.math3.linear.*
-import scientifik.kmath.linear.Point
-import scientifik.kmath.structures.Matrix
-
-enum class CMDecomposition {
-    LUP,
-    QR,
-    RRQR,
-    EIGEN,
-    CHOLESKY
-}
-
-
-fun CMMatrixContext.solver(a: Matrix<Double>, decomposition: CMDecomposition = CMDecomposition.LUP) =
-    when (decomposition) {
-        CMDecomposition.LUP -> LUDecomposition(a.toCM().origin).solver
-        CMDecomposition.RRQR -> RRQRDecomposition(a.toCM().origin).solver
-        CMDecomposition.QR -> QRDecomposition(a.toCM().origin).solver
-        CMDecomposition.EIGEN -> EigenDecomposition(a.toCM().origin).solver
-        CMDecomposition.CHOLESKY -> CholeskyDecomposition(a.toCM().origin).solver
-    }
-
-fun CMMatrixContext.solve(
-    a: Matrix<Double>,
-    b: Matrix<Double>,
-    decomposition: CMDecomposition = CMDecomposition.LUP
-) = solver(a, decomposition).solve(b.toCM().origin).asMatrix()
-
-fun CMMatrixContext.solve(
-    a: Matrix<Double>,
-    b: Point<Double>,
-    decomposition: CMDecomposition = CMDecomposition.LUP
-) = solver(a, decomposition).solve(b.toCM().origin).toPoint()
-
-fun CMMatrixContext.inverse(
-    a: Matrix<Double>,
-    decomposition: CMDecomposition = CMDecomposition.LUP
-) = solver(a, decomposition).inverse.asMatrix()
diff --git a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/random/CMRandomGeneratorWrapper.kt b/kmath-commons/src/main/kotlin/scientifik/kmath/commons/random/CMRandomGeneratorWrapper.kt
deleted file mode 100644
index cb2b5dd9c..000000000
--- a/kmath-commons/src/main/kotlin/scientifik/kmath/commons/random/CMRandomGeneratorWrapper.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package scientifik.kmath.commons.random
-
-import scientifik.kmath.prob.RandomGenerator
-
-class CMRandomGeneratorWrapper(val factory: (IntArray) -> RandomGenerator) :
-    org.apache.commons.math3.random.RandomGenerator {
-    private var generator: RandomGenerator = factory(intArrayOf())
-
-    override fun nextBoolean(): Boolean = generator.nextBoolean()
-    override fun nextFloat(): Float = generator.nextDouble().toFloat()
-
-    override fun setSeed(seed: Int) {
-        generator = factory(intArrayOf(seed))
-    }
-
-    override fun setSeed(seed: IntArray) {
-        generator = factory(seed)
-    }
-
-    override fun setSeed(seed: Long) {
-        setSeed(seed.toInt())
-    }
-
-    override fun nextBytes(bytes: ByteArray) {
-        generator.fillBytes(bytes)
-    }
-
-    override fun nextInt(): Int = generator.nextInt()
-    override fun nextInt(n: Int): Int = generator.nextInt(n)
-    override fun nextGaussian(): Double = TODO()
-    override fun nextDouble(): Double = generator.nextDouble()
-    override fun nextLong(): Long = generator.nextLong()
-}
diff --git a/kmath-commons/src/test/kotlin/scientifik/kmath/commons/expressions/AutoDiffTest.kt b/kmath-commons/src/test/kotlin/kscience/kmath/commons/expressions/AutoDiffTest.kt
similarity index 76%
rename from kmath-commons/src/test/kotlin/scientifik/kmath/commons/expressions/AutoDiffTest.kt
rename to kmath-commons/src/test/kotlin/kscience/kmath/commons/expressions/AutoDiffTest.kt
index bbdcff2fc..f905e6818 100644
--- a/kmath-commons/src/test/kotlin/scientifik/kmath/commons/expressions/AutoDiffTest.kt
+++ b/kmath-commons/src/test/kotlin/kscience/kmath/commons/expressions/AutoDiffTest.kt
@@ -1,17 +1,21 @@
-package scientifik.kmath.commons.expressions
+package kscience.kmath.commons.expressions
 
-import scientifik.kmath.expressions.invoke
+import kscience.kmath.expressions.invoke
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-inline fun <R> diff(order: Int, vararg parameters: Pair<String, Double>, block: DerivativeStructureField.() -> R): R {
+internal inline fun <R> diff(
+    order: Int,
+    vararg parameters: Pair<String, Double>,
+    block: DerivativeStructureField.() -> R
+): R {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return DerivativeStructureField(order, mapOf(*parameters)).run(block)
 }
 
-class AutoDiffTest {
+internal class AutoDiffTest {
     @Test
     fun derivativeStructureFieldTest() {
         val res = diff(3, "x" to 1.0, "y" to 1.0) {
@@ -33,4 +37,4 @@ class AutoDiffTest {
         assertEquals(10.0, f("x" to 1.0, "y" to 2.0))
         assertEquals(6.0, f.derivative("x")("x" to 1.0, "y" to 2.0))
     }
-}
\ No newline at end of file
+}
diff --git a/kmath-core/README.md b/kmath-core/README.md
index aed33a257..9d05331f9 100644
--- a/kmath-core/README.md
+++ b/kmath-core/README.md
@@ -10,31 +10,31 @@ The core features of KMath:
 - Automatic differentiation.
 
 > #### Artifact:
-> This module is distributed in the artifact `scientifik:kmath-core:0.1.4-dev-8`.
+> This module is distributed in the artifact `kscience.kmath:kmath-core:0.1.4-dev-8`.
 > 
 > **Gradle:**
 >
 > ```gradle
 > repositories {
->     maven { url 'https://dl.bintray.com/mipt-npm/scientifik' }
+>     maven { url 'https://dl.bintray.com/mipt-npm/kscience' }
 >     maven { url 'https://dl.bintray.com/mipt-npm/dev' }
 >     maven { url https://dl.bintray.com/hotkeytlt/maven' }
 > }
 > 
 > dependencies {
->     implementation 'scientifik:kmath-core:0.1.4-dev-8'
+>     implementation 'kscience.kmath:kmath-core:0.1.4-dev-8'
 > }
 > ```
 > **Gradle Kotlin DSL:**
 >
 > ```kotlin
 > repositories {
->     maven("https://dl.bintray.com/mipt-npm/scientifik")
+>     maven("https://dl.bintray.com/mipt-npm/kscience")
 >     maven("https://dl.bintray.com/mipt-npm/dev")
 >     maven("https://dl.bintray.com/hotkeytlt/maven")
 > }
 > 
-> dependencies {``
->     implementation("scientifik:kmath-core:0.1.4-dev-8")
+> dependencies {
+>     implementation("kscience.kmath:kmath-core:0.1.4-dev-8")
 > }
 > ```
diff --git a/kmath-core/build.gradle.kts b/kmath-core/build.gradle.kts
index 5a5a8be6d..e315e1640 100644
--- a/kmath-core/build.gradle.kts
+++ b/kmath-core/build.gradle.kts
@@ -1,6 +1,4 @@
-plugins {
-    id("scientifik.mpp")
-}
+plugins { id("ru.mipt.npm.mpp") }
 
 kotlin.sourceSets.commonMain {
     dependencies {
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/Domain.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/Domain.kt
similarity index 54%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/Domain.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/domains/Domain.kt
index 341383bfb..5c3cff2c5 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/Domain.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/Domain.kt
@@ -1,20 +1,20 @@
-package scientifik.kmath.domains
+package kscience.kmath.domains
 
-import scientifik.kmath.linear.Point
+import kscience.kmath.linear.Point
 
 /**
  * A simple geometric domain.
  *
  * @param T the type of element of this domain.
  */
-interface Domain<T : Any> {
+public interface Domain<T : Any> {
     /**
      * Checks if the specified point is contained in this domain.
      */
-    operator fun contains(point: Point<T>): Boolean
+    public operator fun contains(point: Point<T>): Boolean
 
     /**
      * Number of hyperspace dimensions.
      */
-    val dimension: Int
+    public val dimension: Int
 }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/HyperSquareDomain.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/HyperSquareDomain.kt
similarity index 54%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/HyperSquareDomain.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/domains/HyperSquareDomain.kt
index 66798c42f..b45cf6bf5 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/HyperSquareDomain.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/HyperSquareDomain.kt
@@ -13,11 +13,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package scientifik.kmath.domains
+package kscience.kmath.domains
 
-import scientifik.kmath.linear.Point
-import scientifik.kmath.structures.RealBuffer
-import scientifik.kmath.structures.indices
+import kscience.kmath.linear.Point
+import kscience.kmath.structures.RealBuffer
+import kscience.kmath.structures.indices
 
 /**
  *
@@ -25,23 +25,22 @@ import scientifik.kmath.structures.indices
  *
  * @author Alexander Nozik
  */
-class HyperSquareDomain(private val lower: RealBuffer, private val upper: RealBuffer) : RealDomain {
+public class HyperSquareDomain(private val lower: RealBuffer, private val upper: RealBuffer) : RealDomain {
+    public override val dimension: Int get() = lower.size
 
-    override operator fun contains(point: Point<Double>): Boolean = point.indices.all { i ->
+    public override operator fun contains(point: Point<Double>): Boolean = point.indices.all { i ->
         point[i] in lower[i]..upper[i]
     }
 
-    override val dimension: Int get() = lower.size
+    public override fun getLowerBound(num: Int, point: Point<Double>): Double? = lower[num]
 
-    override fun getLowerBound(num: Int, point: Point<Double>): Double? = lower[num]
+    public override fun getLowerBound(num: Int): Double? = lower[num]
 
-    override fun getLowerBound(num: Int): Double? = lower[num]
+    public override fun getUpperBound(num: Int, point: Point<Double>): Double? = upper[num]
 
-    override fun getUpperBound(num: Int, point: Point<Double>): Double? = upper[num]
+    public override fun getUpperBound(num: Int): Double? = upper[num]
 
-    override fun getUpperBound(num: Int): Double? = upper[num]
-
-    override fun nearestInDomain(point: Point<Double>): Point<Double> {
+    public override fun nearestInDomain(point: Point<Double>): Point<Double> {
         val res = DoubleArray(point.size) { i ->
             when {
                 point[i] < lower[i] -> lower[i]
@@ -53,16 +52,14 @@ class HyperSquareDomain(private val lower: RealBuffer, private val upper: RealBu
         return RealBuffer(*res)
     }
 
-    override fun volume(): Double {
+    public override fun volume(): Double {
         var res = 1.0
+
         for (i in 0 until dimension) {
-            if (lower[i].isInfinite() || upper[i].isInfinite()) {
-                return Double.POSITIVE_INFINITY
-            }
-            if (upper[i] > lower[i]) {
-                res *= upper[i] - lower[i]
-            }
+            if (lower[i].isInfinite() || upper[i].isInfinite()) return Double.POSITIVE_INFINITY
+            if (upper[i] > lower[i]) res *= upper[i] - lower[i]
         }
+
         return res
     }
 }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/RealDomain.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/RealDomain.kt
similarity index 71%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/RealDomain.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/domains/RealDomain.kt
index 7507ccd59..369b093bb 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/RealDomain.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/RealDomain.kt
@@ -13,17 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package scientifik.kmath.domains
+package kscience.kmath.domains
 
-import scientifik.kmath.linear.Point
+import kscience.kmath.linear.Point
 
 /**
  * n-dimensional volume
  *
  * @author Alexander Nozik
  */
-interface RealDomain : Domain<Double> {
-    fun nearestInDomain(point: Point<Double>): Point<Double>
+public interface RealDomain : Domain<Double> {
+    public fun nearestInDomain(point: Point<Double>): Point<Double>
 
     /**
      * The lower edge for the domain going down from point
@@ -31,7 +31,7 @@ interface RealDomain : Domain<Double> {
      * @param point
      * @return
      */
-    fun getLowerBound(num: Int, point: Point<Double>): Double?
+    public fun getLowerBound(num: Int, point: Point<Double>): Double?
 
     /**
      * The upper edge of the domain going up from point
@@ -39,25 +39,25 @@ interface RealDomain : Domain<Double> {
      * @param point
      * @return
      */
-    fun getUpperBound(num: Int, point: Point<Double>): Double?
+    public fun getUpperBound(num: Int, point: Point<Double>): Double?
 
     /**
      * Global lower edge
      * @param num
      * @return
      */
-    fun getLowerBound(num: Int): Double?
+    public fun getLowerBound(num: Int): Double?
 
     /**
      * Global upper edge
      * @param num
      * @return
      */
-    fun getUpperBound(num: Int): Double?
+    public fun getUpperBound(num: Int): Double?
 
     /**
      * Hyper volume
      * @return
      */
-    fun volume(): Double
+    public fun volume(): Double
 }
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/UnconstrainedDomain.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/UnconstrainedDomain.kt
new file mode 100644
index 000000000..e2efb51ab
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/UnconstrainedDomain.kt
@@ -0,0 +1,34 @@
+/* 
+ * Copyright 2015 Alexander Nozik.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package kscience.kmath.domains
+
+import kscience.kmath.linear.Point
+
+public class UnconstrainedDomain(public override val dimension: Int) : RealDomain {
+    public override operator fun contains(point: Point<Double>): Boolean = true
+
+    public override fun getLowerBound(num: Int, point: Point<Double>): Double? = Double.NEGATIVE_INFINITY
+
+    public override fun getLowerBound(num: Int): Double? = Double.NEGATIVE_INFINITY
+
+    public override fun getUpperBound(num: Int, point: Point<Double>): Double? = Double.POSITIVE_INFINITY
+
+    public override fun getUpperBound(num: Int): Double? = Double.POSITIVE_INFINITY
+
+    public override fun nearestInDomain(point: Point<Double>): Point<Double> = point
+
+    public override fun volume(): Double = Double.POSITIVE_INFINITY
+}
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/UnivariateDomain.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/UnivariateDomain.kt
new file mode 100644
index 000000000..bf090f2e5
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/domains/UnivariateDomain.kt
@@ -0,0 +1,49 @@
+package kscience.kmath.domains
+
+import kscience.kmath.linear.Point
+import kscience.kmath.structures.asBuffer
+
+public inline class UnivariateDomain(public val range: ClosedFloatingPointRange<Double>) : RealDomain {
+    public override val dimension: Int
+        get() = 1
+
+    public operator fun contains(d: Double): Boolean = range.contains(d)
+
+    public override operator fun contains(point: Point<Double>): Boolean {
+        require(point.size == 0)
+        return contains(point[0])
+    }
+
+    public override fun nearestInDomain(point: Point<Double>): Point<Double> {
+        require(point.size == 1)
+        val value = point[0]
+
+        return when {
+            value in range -> point
+            value >= range.endInclusive -> doubleArrayOf(range.endInclusive).asBuffer()
+            else -> doubleArrayOf(range.start).asBuffer()
+        }
+    }
+
+    public override fun getLowerBound(num: Int, point: Point<Double>): Double? {
+        require(num == 0)
+        return range.start
+    }
+
+    public override fun getUpperBound(num: Int, point: Point<Double>): Double? {
+        require(num == 0)
+        return range.endInclusive
+    }
+
+    public override fun getLowerBound(num: Int): Double? {
+        require(num == 0)
+        return range.start
+    }
+
+    public override fun getUpperBound(num: Int): Double? {
+        require(num == 0)
+        return range.endInclusive
+    }
+
+    public override fun volume(): Double = range.endInclusive - range.start
+}
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/Expression.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/Expression.kt
new file mode 100644
index 000000000..5ade9e3ca
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/Expression.kt
@@ -0,0 +1,41 @@
+package kscience.kmath.expressions
+
+import kscience.kmath.operations.Algebra
+
+/**
+ * An elementary function that could be invoked on a map of arguments
+ */
+public fun interface Expression<T> {
+    /**
+     * Calls this expression from arguments.
+     *
+     * @param arguments the map of arguments.
+     * @return the value.
+     */
+    public operator fun invoke(arguments: Map<String, T>): T
+
+    public companion object
+}
+
+/**
+ * Calls this expression from arguments.
+ *
+ * @param pairs the pair of arguments' names to values.
+ * @return the value.
+ */
+public operator fun <T> Expression<T>.invoke(vararg pairs: Pair<String, T>): T = invoke(mapOf(*pairs))
+
+/**
+ * A context for expression construction
+ */
+public interface ExpressionAlgebra<T, E> : Algebra<E> {
+    /**
+     * Introduce a variable into expression context
+     */
+    public fun variable(name: String, default: T? = null): E
+
+    /**
+     * A constant expression which does not depend on arguments
+     */
+    public fun const(value: T): E
+}
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt
new file mode 100644
index 000000000..49844a2be
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/FunctionalExpressionAlgebra.kt
@@ -0,0 +1,171 @@
+package kscience.kmath.expressions
+
+import kscience.kmath.operations.*
+
+internal class FunctionalUnaryOperation<T>(val context: Algebra<T>, val name: String, private val expr: Expression<T>) :
+    Expression<T> {
+    public override operator fun invoke(arguments: Map<String, T>): T =
+        context.unaryOperation(name, expr.invoke(arguments))
+}
+
+internal class FunctionalBinaryOperation<T>(
+    val context: Algebra<T>,
+    val name: String,
+    val first: Expression<T>,
+    val second: Expression<T>
+) : Expression<T> {
+    public override operator fun invoke(arguments: Map<String, T>): T =
+        context.binaryOperation(name, first.invoke(arguments), second.invoke(arguments))
+}
+
+internal class FunctionalVariableExpression<T>(val name: String, val default: T? = null) : Expression<T> {
+    public override operator fun invoke(arguments: Map<String, T>): T =
+        arguments[name] ?: default ?: error("Parameter not found: $name")
+}
+
+internal class FunctionalConstantExpression<T>(val value: T) : Expression<T> {
+    public override operator fun invoke(arguments: Map<String, T>): T = value
+}
+
+internal class FunctionalConstProductExpression<T>(
+    val context: Space<T>,
+    private val expr: Expression<T>,
+    val const: Number
+) : Expression<T> {
+    public override operator fun invoke(arguments: Map<String, T>): T = context.multiply(expr.invoke(arguments), const)
+}
+
+/**
+ * A context class for [Expression] construction.
+ *
+ * @param algebra The algebra to provide for Expressions built.
+ */
+public abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(public val algebra: A) :
+    ExpressionAlgebra<T, Expression<T>> {
+    /**
+     * Builds an Expression of constant expression which does not depend on arguments.
+     */
+    public override fun const(value: T): Expression<T> = FunctionalConstantExpression(value)
+
+    /**
+     * Builds an Expression to access a variable.
+     */
+    public override fun variable(name: String, default: T?): Expression<T> = FunctionalVariableExpression(name, default)
+
+    /**
+     * Builds an Expression of dynamic call of binary operation [operation] on [left] and [right].
+     */
+    public override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
+        FunctionalBinaryOperation(algebra, operation, left, right)
+
+    /**
+     * Builds an Expression of dynamic call of unary operation with name [operation] on [arg].
+     */
+    public override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
+        FunctionalUnaryOperation(algebra, operation, arg)
+}
+
+/**
+ * A context class for [Expression] construction for [Space] algebras.
+ */
+public open class FunctionalExpressionSpace<T, A : Space<T>>(algebra: A) :
+    FunctionalExpressionAlgebra<T, A>(algebra), Space<Expression<T>> {
+    public override val zero: Expression<T> get() = const(algebra.zero)
+
+    /**
+     * Builds an Expression of addition of two another expressions.
+     */
+    public override fun add(a: Expression<T>, b: Expression<T>): Expression<T> =
+        binaryOperation(SpaceOperations.PLUS_OPERATION, a, b)
+
+    /**
+     * Builds an Expression of multiplication of expression by number.
+     */
+    public override fun multiply(a: Expression<T>, k: Number): Expression<T> =
+        FunctionalConstProductExpression(algebra, a, k)
+
+    public operator fun Expression<T>.plus(arg: T): Expression<T> = this + const(arg)
+    public operator fun Expression<T>.minus(arg: T): Expression<T> = this - const(arg)
+    public operator fun T.plus(arg: Expression<T>): Expression<T> = arg + this
+    public operator fun T.minus(arg: Expression<T>): Expression<T> = arg - this
+
+    public override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
+        super<FunctionalExpressionAlgebra>.unaryOperation(operation, arg)
+
+    public override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
+        super<FunctionalExpressionAlgebra>.binaryOperation(operation, left, right)
+}
+
+public open class FunctionalExpressionRing<T, A>(algebra: A) : FunctionalExpressionSpace<T, A>(algebra),
+    Ring<Expression<T>> where  A : Ring<T>, A : NumericAlgebra<T> {
+    public override val one: Expression<T>
+        get() = const(algebra.one)
+
+    /**
+     * Builds an Expression of multiplication of two expressions.
+     */
+    public override fun multiply(a: Expression<T>, b: Expression<T>): Expression<T> =
+        binaryOperation(RingOperations.TIMES_OPERATION, a, b)
+
+    public operator fun Expression<T>.times(arg: T): Expression<T> = this * const(arg)
+    public operator fun T.times(arg: Expression<T>): Expression<T> = arg * this
+
+    public override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
+        super<FunctionalExpressionSpace>.unaryOperation(operation, arg)
+
+    public override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
+        super<FunctionalExpressionSpace>.binaryOperation(operation, left, right)
+}
+
+public open class FunctionalExpressionField<T, A>(algebra: A) :
+    FunctionalExpressionRing<T, A>(algebra),
+    Field<Expression<T>> where A : Field<T>, A : NumericAlgebra<T> {
+    /**
+     * Builds an Expression of division an expression by another one.
+     */
+    public override fun divide(a: Expression<T>, b: Expression<T>): Expression<T> =
+        binaryOperation(FieldOperations.DIV_OPERATION, a, b)
+
+    public operator fun Expression<T>.div(arg: T): Expression<T> = this / const(arg)
+    public operator fun T.div(arg: Expression<T>): Expression<T> = arg / this
+
+    public override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
+        super<FunctionalExpressionRing>.unaryOperation(operation, arg)
+
+    public override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
+        super<FunctionalExpressionRing>.binaryOperation(operation, left, right)
+}
+
+public open class FunctionalExpressionExtendedField<T, A>(algebra: A) :
+    FunctionalExpressionField<T, A>(algebra),
+    ExtendedField<Expression<T>> where A : ExtendedField<T>, A : NumericAlgebra<T> {
+    public override fun sin(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg)
+    public override fun cos(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.COS_OPERATION, arg)
+    public override fun asin(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg)
+    public override fun acos(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg)
+    public override fun atan(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg)
+
+    public override fun power(arg: Expression<T>, pow: Number): Expression<T> =
+        binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow))
+
+    public override fun exp(arg: Expression<T>): Expression<T> = unaryOperation(ExponentialOperations.EXP_OPERATION, arg)
+    public override fun ln(arg: Expression<T>): Expression<T> = unaryOperation(ExponentialOperations.LN_OPERATION, arg)
+
+    public override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
+        super<FunctionalExpressionField>.unaryOperation(operation, arg)
+
+    public override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
+        super<FunctionalExpressionField>.binaryOperation(operation, left, right)
+}
+
+public inline fun <T, A : Space<T>> A.expressionInSpace(block: FunctionalExpressionSpace<T, A>.() -> Expression<T>): Expression<T> =
+    FunctionalExpressionSpace(this).block()
+
+public inline fun <T, A : Ring<T>> A.expressionInRing(block: FunctionalExpressionRing<T, A>.() -> Expression<T>): Expression<T> =
+    FunctionalExpressionRing(this).block()
+
+public inline fun <T, A : Field<T>> A.expressionInField(block: FunctionalExpressionField<T, A>.() -> Expression<T>): Expression<T> =
+    FunctionalExpressionField(this).block()
+
+public inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField(block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>): Expression<T> =
+    FunctionalExpressionExtendedField(this).block()
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/expressionBuilders.kt
similarity index 52%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/expressionBuilders.kt
index 8090db75e..1702a5921 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Builders.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/expressions/expressionBuilders.kt
@@ -1,16 +1,16 @@
-package scientifik.kmath.expressions
+package kscience.kmath.expressions
 
-import scientifik.kmath.operations.ExtendedField
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.Space
+import kscience.kmath.operations.ExtendedField
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.Space
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
 
 /**
  * Creates a functional expression with this [Space].
  */
-inline fun <T> Space<T>.spaceExpression(block: FunctionalExpressionSpace<T, Space<T>>.() -> Expression<T>): Expression<T> {
+public inline fun <T> Space<T>.spaceExpression(block: FunctionalExpressionSpace<T, Space<T>>.() -> Expression<T>): Expression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return FunctionalExpressionSpace(this).block()
 }
@@ -18,7 +18,7 @@ inline fun <T> Space<T>.spaceExpression(block: FunctionalExpressionSpace<T, Spac
 /**
  * Creates a functional expression with this [Ring].
  */
-inline fun <T> Ring<T>.ringExpression(block: FunctionalExpressionRing<T, Ring<T>>.() -> Expression<T>): Expression<T> {
+public inline fun <T> Ring<T>.ringExpression(block: FunctionalExpressionRing<T, Ring<T>>.() -> Expression<T>): Expression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return FunctionalExpressionRing(this).block()
 }
@@ -26,7 +26,7 @@ inline fun <T> Ring<T>.ringExpression(block: FunctionalExpressionRing<T, Ring<T>
 /**
  * Creates a functional expression with this [Field].
  */
-inline fun <T> Field<T>.fieldExpression(block: FunctionalExpressionField<T, Field<T>>.() -> Expression<T>): Expression<T> {
+public inline fun <T> Field<T>.fieldExpression(block: FunctionalExpressionField<T, Field<T>>.() -> Expression<T>): Expression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return FunctionalExpressionField(this).block()
 }
@@ -34,7 +34,7 @@ inline fun <T> Field<T>.fieldExpression(block: FunctionalExpressionField<T, Fiel
 /**
  * Creates a functional expression with this [ExtendedField].
  */
-inline fun <T> ExtendedField<T>.extendedFieldExpression(block: FunctionalExpressionExtendedField<T, ExtendedField<T>>.() -> Expression<T>): Expression<T> {
+public inline fun <T> ExtendedField<T>.extendedFieldExpression(block: FunctionalExpressionExtendedField<T, ExtendedField<T>>.() -> Expression<T>): Expression<T> {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     return FunctionalExpressionExtendedField(this).block()
 }
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/BufferMatrix.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/BufferMatrix.kt
new file mode 100644
index 000000000..d51f40890
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/BufferMatrix.kt
@@ -0,0 +1,113 @@
+package kscience.kmath.linear
+
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.Ring
+import kscience.kmath.structures.*
+
+/**
+ * Basic implementation of Matrix space based on [NDStructure]
+ */
+public class BufferMatrixContext<T : Any, R : Ring<T>>(
+    public override val elementContext: R,
+    private val bufferFactory: BufferFactory<T>
+) : GenericMatrixContext<T, R> {
+    public override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): BufferMatrix<T> {
+        val buffer = bufferFactory(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
+        return BufferMatrix(rows, columns, buffer)
+    }
+
+    public override fun point(size: Int, initializer: (Int) -> T): Point<T> = bufferFactory(size, initializer)
+
+    public companion object
+}
+
+@Suppress("OVERRIDE_BY_INLINE")
+public object RealMatrixContext : GenericMatrixContext<Double, RealField> {
+    public override val elementContext: RealField
+        get() = RealField
+
+    public override inline fun produce(
+        rows: Int,
+        columns: Int,
+        initializer: (i: Int, j: Int) -> Double
+    ): Matrix<Double> {
+        val buffer = RealBuffer(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
+        return BufferMatrix(rows, columns, buffer)
+    }
+
+    public override inline fun point(size: Int, initializer: (Int) -> Double): Point<Double> =
+        RealBuffer(size, initializer)
+}
+
+public class BufferMatrix<T : Any>(
+    public override val rowNum: Int,
+    public override val colNum: Int,
+    public val buffer: Buffer<out T>,
+    public override val features: Set<MatrixFeature> = emptySet()
+) : FeaturedMatrix<T> {
+    override val shape: IntArray
+        get() = intArrayOf(rowNum, colNum)
+
+    init {
+        require(buffer.size == rowNum * colNum) { "Dimension mismatch for matrix structure" }
+    }
+
+    public override fun suggestFeature(vararg features: MatrixFeature): BufferMatrix<T> =
+        BufferMatrix(rowNum, colNum, buffer, this.features + features)
+
+    public override operator fun get(index: IntArray): T = get(index[0], index[1])
+    public override operator fun get(i: Int, j: Int): T = buffer[i * colNum + j]
+
+    public override fun elements(): Sequence<Pair<IntArray, T>> = sequence {
+        for (i in 0 until rowNum) for (j in 0 until colNum) yield(intArrayOf(i, j) to get(i, j))
+    }
+
+    public override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+
+        return when (other) {
+            is NDStructure<*> -> return NDStructure.equals(this, other)
+            else -> false
+        }
+    }
+
+    public override fun hashCode(): Int {
+        var result = buffer.hashCode()
+        result = 31 * result + features.hashCode()
+        return result
+    }
+
+    public override fun toString(): String {
+        return if (rowNum <= 5 && colNum <= 5)
+            "Matrix(rowsNum = $rowNum, colNum = $colNum, features=$features)\n" +
+                    rows.asSequence().joinToString(prefix = "(", postfix = ")", separator = "\n ") { buffer ->
+                        buffer.asSequence().joinToString(separator = "\t") { it.toString() }
+                    }
+        else "Matrix(rowsNum = $rowNum, colNum = $colNum, features=$features)"
+    }
+}
+
+/**
+ * Optimized dot product for real matrices
+ */
+public infix fun BufferMatrix<Double>.dot(other: BufferMatrix<Double>): BufferMatrix<Double> {
+    require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
+    val array = DoubleArray(this.rowNum * other.colNum)
+
+    //convert to array to insure there is not memory indirection
+    fun Buffer<out Double>.unsafeArray() = if (this is RealBuffer)
+        array
+    else
+        DoubleArray(size) { get(it) }
+
+    val a = this.buffer.unsafeArray()
+    val b = other.buffer.unsafeArray()
+
+    for (i in (0 until rowNum))
+        for (j in (0 until other.colNum))
+            for (k in (0 until colNum))
+                array[i * other.colNum + j] += a[i * colNum + k] * b[k * other.colNum + j]
+
+    val buffer = RealBuffer(array)
+    return BufferMatrix(rowNum, other.colNum, buffer)
+}
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/FeaturedMatrix.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt
similarity index 50%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/FeaturedMatrix.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt
index 7237739fb..65dc8df76 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/FeaturedMatrix.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/FeaturedMatrix.kt
@@ -1,20 +1,17 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.structures.Matrix
-import scientifik.kmath.structures.Structure2D
-import scientifik.kmath.structures.asBuffer
-import kotlin.contracts.contract
+import kscience.kmath.operations.Ring
+import kscience.kmath.structures.Matrix
+import kscience.kmath.structures.Structure2D
+import kscience.kmath.structures.asBuffer
 import kotlin.math.sqrt
 
 /**
  * A 2d structure plus optional matrix-specific features
  */
-interface FeaturedMatrix<T : Any> : Matrix<T> {
-
+public interface FeaturedMatrix<T : Any> : Matrix<T> {
     override val shape: IntArray get() = intArrayOf(rowNum, colNum)
-
-    val features: Set<MatrixFeature>
+    public val features: Set<MatrixFeature>
 
     /**
      * Suggest new feature for this matrix. The result is the new matrix that may or may not reuse existing data structure.
@@ -22,44 +19,42 @@ interface FeaturedMatrix<T : Any> : Matrix<T> {
      * The implementation does not guarantee to check that matrix actually have the feature, so one should be careful to
      * add only those features that are valid.
      */
-    fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix<T>
+    public fun suggestFeature(vararg features: MatrixFeature): FeaturedMatrix<T>
 
-    companion object
+    public companion object
 }
 
-inline fun Structure2D.Companion.real(rows: Int, columns: Int, initializer: (Int, Int) -> Double): Matrix<Double> {
-    contract { callsInPlace(initializer) }
-    return MatrixContext.real.produce(rows, columns, initializer)
-}
+public inline fun Structure2D.Companion.real(rows: Int, columns: Int, initializer: (Int, Int) -> Double): Matrix<Double> =
+    MatrixContext.real.produce(rows, columns, initializer)
 
 /**
  * Build a square matrix from given elements.
  */
-fun <T : Any> Structure2D.Companion.square(vararg elements: T): FeaturedMatrix<T> {
+public fun <T : Any> Structure2D.Companion.square(vararg elements: T): FeaturedMatrix<T> {
     val size: Int = sqrt(elements.size.toDouble()).toInt()
     require(size * size == elements.size) { "The number of elements ${elements.size} is not a full square" }
     val buffer = elements.asBuffer()
     return BufferMatrix(size, size, buffer)
 }
 
-val Matrix<*>.features: Set<MatrixFeature> get() = (this as? FeaturedMatrix)?.features ?: emptySet()
+public val Matrix<*>.features: Set<MatrixFeature> get() = (this as? FeaturedMatrix)?.features ?: emptySet()
 
 /**
  * Check if matrix has the given feature class
  */
-inline fun <reified T : Any> Matrix<*>.hasFeature(): Boolean =
+public inline fun <reified T : Any> Matrix<*>.hasFeature(): Boolean =
     features.find { it is T } != null
 
 /**
  * Get the first feature matching given class. Does not guarantee that matrix has only one feature matching the criteria
  */
-inline fun <reified T : Any> Matrix<*>.getFeature(): T? =
+public inline fun <reified T : Any> Matrix<*>.getFeature(): T? =
     features.filterIsInstance<T>().firstOrNull()
 
 /**
  * Diagonal matrix of ones. The matrix is virtual no actual matrix is created
  */
-fun <T : Any, R : Ring<T>> GenericMatrixContext<T, R>.one(rows: Int, columns: Int): FeaturedMatrix<T> =
+public fun <T : Any, R : Ring<T>> GenericMatrixContext<T, R>.one(rows: Int, columns: Int): FeaturedMatrix<T> =
     VirtualMatrix(rows, columns, DiagonalFeature) { i, j ->
         if (i == j) elementContext.one else elementContext.zero
     }
@@ -68,20 +63,20 @@ fun <T : Any, R : Ring<T>> GenericMatrixContext<T, R>.one(rows: Int, columns: In
 /**
  * A virtual matrix of zeroes
  */
-fun <T : Any, R : Ring<T>> GenericMatrixContext<T, R>.zero(rows: Int, columns: Int): FeaturedMatrix<T> =
+public fun <T : Any, R : Ring<T>> GenericMatrixContext<T, R>.zero(rows: Int, columns: Int): FeaturedMatrix<T> =
     VirtualMatrix(rows, columns) { _, _ -> elementContext.zero }
 
-class TransposedFeature<T : Any>(val original: Matrix<T>) : MatrixFeature
+public class TransposedFeature<T : Any>(public val original: Matrix<T>) : MatrixFeature
 
 /**
  * Create a virtual transposed matrix without copying anything. `A.transpose().transpose() === A`
  */
-fun <T : Any> Matrix<T>.transpose(): Matrix<T> {
-    return this.getFeature<TransposedFeature<T>>()?.original ?: VirtualMatrix(
-        this.colNum,
-        this.rowNum,
+public fun <T : Any> Matrix<T>.transpose(): Matrix<T> {
+    return getFeature<TransposedFeature<T>>()?.original ?: VirtualMatrix(
+        colNum,
+        rowNum,
         setOf(TransposedFeature(this))
     ) { i, j -> get(j, i) }
 }
 
-infix fun Matrix<Double>.dot(other: Matrix<Double>): Matrix<Double> = with(MatrixContext.real) { dot(other) }
+public infix fun Matrix<Double>.dot(other: Matrix<Double>): Matrix<Double> = with(MatrixContext.real) { dot(other) }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LUPDecomposition.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/LUPDecomposition.kt
similarity index 78%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LUPDecomposition.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/linear/LUPDecomposition.kt
index f3e4f648f..bb80bcafd 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LUPDecomposition.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/LUPDecomposition.kt
@@ -1,25 +1,25 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.structures.BufferAccessor2D
-import scientifik.kmath.structures.Matrix
-import scientifik.kmath.structures.Structure2D
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.invoke
+import kscience.kmath.structures.BufferAccessor2D
+import kscience.kmath.structures.Matrix
+import kscience.kmath.structures.Structure2D
 import kotlin.reflect.KClass
 
 /**
  * Common implementation of [LUPDecompositionFeature]
  */
-class LUPDecomposition<T : Any>(
-    val context: GenericMatrixContext<T, out Field<T>>,
-    val lu: Structure2D<T>,
-    val pivot: IntArray,
+public class LUPDecomposition<T : Any>(
+    public val context: GenericMatrixContext<T, out Field<T>>,
+    public val lu: Structure2D<T>,
+    public val pivot: IntArray,
     private val even: Boolean
 ) : LUPDecompositionFeature<T>, DeterminantFeature<T> {
-
-    val elementContext: Field<T> get() = context.elementContext
+    public val elementContext: Field<T>
+        get() = context.elementContext
 
     /**
      * Returns the matrix L of the decomposition.
@@ -44,7 +44,6 @@ class LUPDecomposition<T : Any>(
         if (j >= i) lu[i, j] else elementContext.zero
     }
 
-
     /**
      * Returns the P rows permutation matrix.
      *
@@ -55,7 +54,6 @@ class LUPDecomposition<T : Any>(
         if (j == pivot[i]) elementContext.one else elementContext.zero
     }
 
-
     /**
      * Return the determinant of the matrix
      * @return determinant of the matrix
@@ -66,22 +64,18 @@ class LUPDecomposition<T : Any>(
 
 }
 
-fun <T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.abs(value: T): T =
+public fun <T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.abs(value: T): T =
     if (value > elementContext.zero) value else elementContext { -value }
 
-
 /**
  * Create a lup decomposition of generic matrix
  */
-fun <T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.lup(
+public inline fun <T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.lup(
     type: KClass<T>,
     matrix: Matrix<T>,
     checkSingular: (T) -> Boolean
 ): LUPDecomposition<T> {
-    if (matrix.rowNum != matrix.colNum) {
-        error("LU decomposition supports only square matrices")
-    }
-
+    require(matrix.rowNum == matrix.colNum) { "LU decomposition supports only square matrices" }
     val m = matrix.colNum
     val pivot = IntArray(matrix.rowNum)
 
@@ -154,15 +148,15 @@ fun <T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.lup(
     }
 }
 
-inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.lup(
+public inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.lup(
     matrix: Matrix<T>,
-    noinline checkSingular: (T) -> Boolean
+    checkSingular: (T) -> Boolean
 ): LUPDecomposition<T> = lup(T::class, matrix, checkSingular)
 
-fun GenericMatrixContext<Double, RealField>.lup(matrix: Matrix<Double>): LUPDecomposition<Double> =
+public fun GenericMatrixContext<Double, RealField>.lup(matrix: Matrix<Double>): LUPDecomposition<Double> =
     lup(Double::class, matrix) { it < 1e-11 }
 
-fun <T : Any> LUPDecomposition<T>.solve(type: KClass<T>, matrix: Matrix<T>): Matrix<T> {
+public fun <T : Any> LUPDecomposition<T>.solve(type: KClass<T>, matrix: Matrix<T>): Matrix<T> {
     require(matrix.rowNum == pivot.size) { "Matrix dimension mismatch. Expected ${pivot.size}, but got ${matrix.colNum}" }
 
     BufferAccessor2D(type, matrix.rowNum, matrix.colNum).run {
@@ -207,27 +201,27 @@ fun <T : Any> LUPDecomposition<T>.solve(type: KClass<T>, matrix: Matrix<T>): Mat
     }
 }
 
-inline fun <reified T : Any> LUPDecomposition<T>.solve(matrix: Matrix<T>): Matrix<T> = solve(T::class, matrix)
+public inline fun <reified T : Any> LUPDecomposition<T>.solve(matrix: Matrix<T>): Matrix<T> = solve(T::class, matrix)
 
 /**
  * Solve a linear equation **a*x = b**
  */
-inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.solve(
+public inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.solve(
     a: Matrix<T>,
     b: Matrix<T>,
-    noinline checkSingular: (T) -> Boolean
+    checkSingular: (T) -> Boolean
 ): Matrix<T> {
     // Use existing decomposition if it is provided by matrix
     val decomposition = a.getFeature() ?: lup(T::class, a, checkSingular)
     return decomposition.solve(T::class, b)
 }
 
-fun RealMatrixContext.solve(a: Matrix<Double>, b: Matrix<Double>): Matrix<Double> = solve(a, b) { it < 1e-11 }
+public fun RealMatrixContext.solve(a: Matrix<Double>, b: Matrix<Double>): Matrix<Double> = solve(a, b) { it < 1e-11 }
 
-inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.inverse(
+public inline fun <reified T : Comparable<T>, F : Field<T>> GenericMatrixContext<T, F>.inverse(
     matrix: Matrix<T>,
-    noinline checkSingular: (T) -> Boolean
+    checkSingular: (T) -> Boolean
 ): Matrix<T> = solve(matrix, one(matrix.rowNum, matrix.colNum), checkSingular)
 
-fun RealMatrixContext.inverse(matrix: Matrix<Double>): Matrix<Double> =
+public fun RealMatrixContext.inverse(matrix: Matrix<Double>): Matrix<Double> =
     solve(matrix, one(matrix.rowNum, matrix.colNum)) { it < 1e-11 }
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/LinearAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/LinearAlgebra.kt
new file mode 100644
index 000000000..034decc2f
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/LinearAlgebra.kt
@@ -0,0 +1,27 @@
+package kscience.kmath.linear
+
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.Matrix
+import kscience.kmath.structures.VirtualBuffer
+
+public typealias Point<T> = Buffer<T>
+
+/**
+ * A group of methods to resolve equation A dot X = B, where A and B are matrices or vectors
+ */
+public interface LinearSolver<T : Any> {
+    public fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T>
+    public fun solve(a: Matrix<T>, b: Point<T>): Point<T> = solve(a, b.asMatrix()).asPoint()
+    public fun inverse(a: Matrix<T>): Matrix<T>
+}
+
+/**
+ * Convert matrix to vector if it is possible
+ */
+public fun <T : Any> Matrix<T>.asPoint(): Point<T> =
+    if (this.colNum == 1)
+        VirtualBuffer(rowNum) { get(it, 0) }
+    else
+        error("Can't convert matrix with more than one column to vector")
+
+public fun <T : Any> Point<T>.asMatrix(): VirtualMatrix<T> = VirtualMatrix(size, 1) { i, _ -> get(i) }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixBuilder.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixBuilder.kt
similarity index 54%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixBuilder.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixBuilder.kt
index 390362f8c..91c1ec824 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixBuilder.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixBuilder.kt
@@ -1,12 +1,12 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.BufferFactory
-import scientifik.kmath.structures.Structure2D
-import scientifik.kmath.structures.asBuffer
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.BufferFactory
+import kscience.kmath.structures.Structure2D
+import kscience.kmath.structures.asBuffer
 
-class MatrixBuilder(val rows: Int, val columns: Int) {
-    operator fun <T : Any> invoke(vararg elements: T): FeaturedMatrix<T> {
+public class MatrixBuilder(public val rows: Int, public val columns: Int) {
+    public operator fun <T : Any> invoke(vararg elements: T): FeaturedMatrix<T> {
         require(rows * columns == elements.size) { "The number of elements ${elements.size} is not equal $rows * $columns" }
         val buffer = elements.asBuffer()
         return BufferMatrix(rows, columns, buffer)
@@ -15,14 +15,14 @@ class MatrixBuilder(val rows: Int, val columns: Int) {
     //TODO add specific matrix builder functions like diagonal, etc
 }
 
-fun Structure2D.Companion.build(rows: Int, columns: Int): MatrixBuilder = MatrixBuilder(rows, columns)
+public fun Structure2D.Companion.build(rows: Int, columns: Int): MatrixBuilder = MatrixBuilder(rows, columns)
 
-fun <T : Any> Structure2D.Companion.row(vararg values: T): FeaturedMatrix<T> {
+public fun <T : Any> Structure2D.Companion.row(vararg values: T): FeaturedMatrix<T> {
     val buffer = values.asBuffer()
     return BufferMatrix(1, values.size, buffer)
 }
 
-inline fun <reified T : Any> Structure2D.Companion.row(
+public inline fun <reified T : Any> Structure2D.Companion.row(
     size: Int,
     factory: BufferFactory<T> = Buffer.Companion::auto,
     noinline builder: (Int) -> T
@@ -31,12 +31,12 @@ inline fun <reified T : Any> Structure2D.Companion.row(
     return BufferMatrix(1, size, buffer)
 }
 
-fun <T : Any> Structure2D.Companion.column(vararg values: T): FeaturedMatrix<T> {
+public fun <T : Any> Structure2D.Companion.column(vararg values: T): FeaturedMatrix<T> {
     val buffer = values.asBuffer()
     return BufferMatrix(values.size, 1, buffer)
 }
 
-inline fun <reified T : Any> Structure2D.Companion.column(
+public inline fun <reified T : Any> Structure2D.Companion.column(
     size: Int,
     factory: BufferFactory<T> = Buffer.Companion::auto,
     noinline builder: (Int) -> T
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt
similarity index 61%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt
index b7e79f1bc..f4dbce89a 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixContext.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixContext.kt
@@ -1,24 +1,24 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.SpaceOperations
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.operations.sum
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.BufferFactory
-import scientifik.kmath.structures.Matrix
-import scientifik.kmath.structures.asSequence
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.SpaceOperations
+import kscience.kmath.operations.invoke
+import kscience.kmath.operations.sum
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.BufferFactory
+import kscience.kmath.structures.Matrix
+import kscience.kmath.structures.asSequence
 
 /**
  * Basic operations on matrices. Operates on [Matrix]
  */
-interface MatrixContext<T : Any> : SpaceOperations<Matrix<T>> {
+public interface MatrixContext<T : Any> : SpaceOperations<Matrix<T>> {
     /**
      * Produce a matrix with this context and given dimensions
      */
-    fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): Matrix<T>
+    public fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): Matrix<T>
 
-    override fun binaryOperation(operation: String, left: Matrix<T>, right: Matrix<T>): Matrix<T> = when (operation) {
+    public override fun binaryOperation(operation: String, left: Matrix<T>, right: Matrix<T>): Matrix<T> = when (operation) {
         "dot" -> left dot right
         else -> super.binaryOperation(operation, left, right)
     }
@@ -30,7 +30,7 @@ interface MatrixContext<T : Any> : SpaceOperations<Matrix<T>> {
      * @param other the multiplier.
      * @return the dot product.
      */
-    infix fun Matrix<T>.dot(other: Matrix<T>): Matrix<T>
+    public infix fun Matrix<T>.dot(other: Matrix<T>): Matrix<T>
 
     /**
      * Computes the dot product of this matrix and a vector.
@@ -39,7 +39,7 @@ interface MatrixContext<T : Any> : SpaceOperations<Matrix<T>> {
      * @param vector the multiplier.
      * @return the dot product.
      */
-    infix fun Matrix<T>.dot(vector: Point<T>): Point<T>
+    public infix fun Matrix<T>.dot(vector: Point<T>): Point<T>
 
     /**
      * Multiplies a matrix by its element.
@@ -48,7 +48,7 @@ interface MatrixContext<T : Any> : SpaceOperations<Matrix<T>> {
      * @param value the multiplier.
      * @receiver the product.
      */
-    operator fun Matrix<T>.times(value: T): Matrix<T>
+    public operator fun Matrix<T>.times(value: T): Matrix<T>
 
     /**
      * Multiplies an element by a matrix of it.
@@ -57,18 +57,18 @@ interface MatrixContext<T : Any> : SpaceOperations<Matrix<T>> {
      * @param value the multiplier.
      * @receiver the product.
      */
-    operator fun T.times(m: Matrix<T>): Matrix<T> = m * this
+    public operator fun T.times(m: Matrix<T>): Matrix<T> = m * this
 
-    companion object {
+    public companion object {
         /**
          * Non-boxing double matrix
          */
-        val real: RealMatrixContext = RealMatrixContext
+        public val real: RealMatrixContext = RealMatrixContext
 
         /**
          * A structured matrix with custom buffer
          */
-        fun <T : Any, R : Ring<T>> buffered(
+        public fun <T : Any, R : Ring<T>> buffered(
             ring: R,
             bufferFactory: BufferFactory<T> = Buffer.Companion::boxing
         ): GenericMatrixContext<T, R> = BufferMatrixContext(ring, bufferFactory)
@@ -76,23 +76,23 @@ interface MatrixContext<T : Any> : SpaceOperations<Matrix<T>> {
         /**
          * Automatic buffered matrix, unboxed if it is possible
          */
-        inline fun <reified T : Any, R : Ring<T>> auto(ring: R): GenericMatrixContext<T, R> =
+        public inline fun <reified T : Any, R : Ring<T>> auto(ring: R): GenericMatrixContext<T, R> =
             buffered(ring, Buffer.Companion::auto)
     }
 }
 
-interface GenericMatrixContext<T : Any, R : Ring<T>> : MatrixContext<T> {
+public interface GenericMatrixContext<T : Any, R : Ring<T>> : MatrixContext<T> {
     /**
      * The ring context for matrix elements
      */
-    val elementContext: R
+    public val elementContext: R
 
     /**
      * Produce a point compatible with matrix space
      */
-    fun point(size: Int, initializer: (Int) -> T): Point<T>
+    public fun point(size: Int, initializer: (Int) -> T): Point<T>
 
-    override infix fun Matrix<T>.dot(other: Matrix<T>): Matrix<T> {
+    public override infix fun Matrix<T>.dot(other: Matrix<T>): Matrix<T> {
         //TODO add typed error
         require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
 
@@ -103,7 +103,7 @@ interface GenericMatrixContext<T : Any, R : Ring<T>> : MatrixContext<T> {
         }
     }
 
-    override infix fun Matrix<T>.dot(vector: Point<T>): Point<T> {
+    public override infix fun Matrix<T>.dot(vector: Point<T>): Point<T> {
         //TODO add typed error
         require(colNum == vector.size) { "Matrix dot vector operation dimension mismatch: ($rowNum, $colNum) x (${vector.size})" }
 
@@ -113,10 +113,10 @@ interface GenericMatrixContext<T : Any, R : Ring<T>> : MatrixContext<T> {
         }
     }
 
-    override operator fun Matrix<T>.unaryMinus(): Matrix<T> =
+    public override operator fun Matrix<T>.unaryMinus(): Matrix<T> =
         produce(rowNum, colNum) { i, j -> elementContext { -get(i, j) } }
 
-    override fun add(a: Matrix<T>, b: Matrix<T>): Matrix<T> {
+    public override fun add(a: Matrix<T>, b: Matrix<T>): Matrix<T> {
         require(a.rowNum == b.rowNum && a.colNum == b.colNum) {
             "Matrix operation dimension mismatch. [${a.rowNum},${a.colNum}] + [${b.rowNum},${b.colNum}]"
         }
@@ -124,7 +124,7 @@ interface GenericMatrixContext<T : Any, R : Ring<T>> : MatrixContext<T> {
         return produce(a.rowNum, a.colNum) { i, j -> elementContext { a[i, j] + b[i, j] } }
     }
 
-    override operator fun Matrix<T>.minus(b: Matrix<T>): Matrix<T> {
+    public override operator fun Matrix<T>.minus(b: Matrix<T>): Matrix<T> {
         require(rowNum == b.rowNum && colNum == b.colNum) {
             "Matrix operation dimension mismatch. [$rowNum,$colNum] - [${b.rowNum},${b.colNum}]"
         }
@@ -132,11 +132,11 @@ interface GenericMatrixContext<T : Any, R : Ring<T>> : MatrixContext<T> {
         return produce(rowNum, colNum) { i, j -> elementContext { get(i, j) + b[i, j] } }
     }
 
-    override fun multiply(a: Matrix<T>, k: Number): Matrix<T> =
+    public override fun multiply(a: Matrix<T>, k: Number): Matrix<T> =
         produce(a.rowNum, a.colNum) { i, j -> elementContext { a[i, j] * k } }
 
-    operator fun Number.times(matrix: FeaturedMatrix<T>): Matrix<T> = matrix * this
+    public operator fun Number.times(matrix: FeaturedMatrix<T>): Matrix<T> = matrix * this
 
-    override operator fun Matrix<T>.times(value: T): Matrix<T> =
+    public override operator fun Matrix<T>.times(value: T): Matrix<T> =
         produce(rowNum, colNum) { i, j -> elementContext { get(i, j) * value } }
 }
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixFeatures.kt
new file mode 100644
index 000000000..a82032e50
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/MatrixFeatures.kt
@@ -0,0 +1,62 @@
+package kscience.kmath.linear
+
+/**
+ * A marker interface representing some matrix feature like diagonal, sparse, zero, etc. Features used to optimize matrix
+ * operations performance in some cases.
+ */
+public interface MatrixFeature
+
+/**
+ * The matrix with this feature is considered to have only diagonal non-null elements
+ */
+public object DiagonalFeature : MatrixFeature
+
+/**
+ * Matrix with this feature has all zero elements
+ */
+public object ZeroFeature : MatrixFeature
+
+/**
+ * Matrix with this feature have unit elements on diagonal and zero elements in all other places
+ */
+public object UnitFeature : MatrixFeature
+
+/**
+ * Inverted matrix feature
+ */
+public interface InverseMatrixFeature<T : Any> : MatrixFeature {
+    public val inverse: FeaturedMatrix<T>
+}
+
+/**
+ * A determinant container
+ */
+public interface DeterminantFeature<T : Any> : MatrixFeature {
+    public val determinant: T
+}
+
+@Suppress("FunctionName")
+public fun <T : Any> DeterminantFeature(determinant: T): DeterminantFeature<T> = object : DeterminantFeature<T> {
+    override val determinant: T = determinant
+}
+
+/**
+ * Lower triangular matrix
+ */
+public object LFeature : MatrixFeature
+
+/**
+ * Upper triangular feature
+ */
+public object UFeature : MatrixFeature
+
+/**
+ * TODO add documentation
+ */
+public interface LUPDecompositionFeature<T : Any> : MatrixFeature {
+    public val l: FeaturedMatrix<T>
+    public val u: FeaturedMatrix<T>
+    public val p: FeaturedMatrix<T>
+}
+
+//TODO add sparse matrix feature
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VectorSpace.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/VectorSpace.kt
similarity index 65%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VectorSpace.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/linear/VectorSpace.kt
index 82e5c7ef6..67056c6b2 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VectorSpace.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/VectorSpace.kt
@@ -1,21 +1,21 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.Space
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.BufferFactory
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.Space
+import kscience.kmath.operations.invoke
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.BufferFactory
 
 /**
  * A linear space for vectors.
  * Could be used on any point-like structure
  */
-interface VectorSpace<T : Any, S : Space<T>> : Space<Point<T>> {
-    val size: Int
-    val space: S
+public interface VectorSpace<T : Any, S : Space<T>> : Space<Point<T>> {
+    public val size: Int
+    public val space: S
     override val zero: Point<T> get() = produce { space.zero }
 
-    fun produce(initializer: (Int) -> T): Point<T>
+    public fun produce(initializer: (Int) -> T): Point<T>
 
     /**
      * Produce a space-element of this vector space for expressions
@@ -28,13 +28,13 @@ interface VectorSpace<T : Any, S : Space<T>> : Space<Point<T>> {
 
     //TODO add basis
 
-    companion object {
+    public companion object {
         private val realSpaceCache: MutableMap<Int, BufferVectorSpace<Double, RealField>> = hashMapOf()
 
         /**
          * Non-boxing double vector space
          */
-        fun real(size: Int): BufferVectorSpace<Double, RealField> = realSpaceCache.getOrPut(size) {
+        public fun real(size: Int): BufferVectorSpace<Double, RealField> = realSpaceCache.getOrPut(size) {
             BufferVectorSpace(
                 size,
                 RealField,
@@ -45,7 +45,7 @@ interface VectorSpace<T : Any, S : Space<T>> : Space<Point<T>> {
         /**
          * A structured vector space with custom buffer
          */
-        fun <T : Any, S : Space<T>> buffered(
+        public fun <T : Any, S : Space<T>> buffered(
             size: Int,
             space: S,
             bufferFactory: BufferFactory<T> = Buffer.Companion::boxing
@@ -54,16 +54,16 @@ interface VectorSpace<T : Any, S : Space<T>> : Space<Point<T>> {
         /**
          * Automatic buffered vector, unboxed if it is possible
          */
-        inline fun <reified T : Any, S : Space<T>> auto(size: Int, space: S): VectorSpace<T, S> =
+        public inline fun <reified T : Any, S : Space<T>> auto(size: Int, space: S): VectorSpace<T, S> =
             buffered(size, space, Buffer.Companion::auto)
     }
 }
 
 
-class BufferVectorSpace<T : Any, S : Space<T>>(
+public class BufferVectorSpace<T : Any, S : Space<T>>(
     override val size: Int,
     override val space: S,
-    val bufferFactory: BufferFactory<T>
+    public val bufferFactory: BufferFactory<T>
 ) : VectorSpace<T, S> {
     override fun produce(initializer: (Int) -> T): Buffer<T> = bufferFactory(size, initializer)
     //override fun produceElement(initializer: (Int) -> T): Vector<T, S> = BufferVector(this, produce(initializer))
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VirtualMatrix.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/VirtualMatrix.kt
similarity index 70%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VirtualMatrix.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/linear/VirtualMatrix.kt
index 5266dc884..e0a1d0026 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/VirtualMatrix.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/linear/VirtualMatrix.kt
@@ -1,15 +1,19 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.structures.Matrix
+import kscience.kmath.structures.Matrix
 
-class VirtualMatrix<T : Any>(
+public class VirtualMatrix<T : Any>(
     override val rowNum: Int,
     override val colNum: Int,
     override val features: Set<MatrixFeature> = emptySet(),
-    val generator: (i: Int, j: Int) -> T
+    public val generator: (i: Int, j: Int) -> T
 ) : FeaturedMatrix<T> {
-
-    constructor(rowNum: Int, colNum: Int, vararg features: MatrixFeature, generator: (i: Int, j: Int) -> T) : this(
+    public constructor(
+        rowNum: Int,
+        colNum: Int,
+        vararg features: MatrixFeature,
+        generator: (i: Int, j: Int) -> T
+    ) : this(
         rowNum,
         colNum,
         setOf(*features),
@@ -42,18 +46,15 @@ class VirtualMatrix<T : Any>(
     }
 
 
-    companion object {
+    public companion object {
         /**
          * Wrap a matrix adding additional features to it
          */
-        fun <T : Any> wrap(matrix: Matrix<T>, vararg features: MatrixFeature): FeaturedMatrix<T> {
-            return if (matrix is VirtualMatrix) {
+        public fun <T : Any> wrap(matrix: Matrix<T>, vararg features: MatrixFeature): FeaturedMatrix<T> {
+            return if (matrix is VirtualMatrix)
                 VirtualMatrix(matrix.rowNum, matrix.colNum, matrix.features + features, matrix.generator)
-            } else {
-                VirtualMatrix(matrix.rowNum, matrix.colNum, matrix.features + features) { i, j ->
-                    matrix[i, j]
-                }
-            }
+            else
+                VirtualMatrix(matrix.rowNum, matrix.colNum, matrix.features + features) { i, j -> matrix[i, j] }
         }
     }
 }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/AutoDiff.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/AutoDiff.kt
similarity index 58%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/AutoDiff.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/misc/AutoDiff.kt
index 808312877..b4a610eb1 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/AutoDiff.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/AutoDiff.kt
@@ -1,11 +1,11 @@
-package scientifik.kmath.misc
+package kscience.kmath.misc
 
-import scientifik.kmath.linear.Point
-import scientifik.kmath.operations.ExtendedField
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.operations.sum
-import scientifik.kmath.structures.asBuffer
+import kscience.kmath.linear.Point
+import kscience.kmath.operations.ExtendedField
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.invoke
+import kscience.kmath.operations.sum
+import kscience.kmath.structures.asBuffer
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
 
@@ -18,24 +18,24 @@ import kotlin.contracts.contract
  * Differentiable variable with value and derivative of differentiation ([deriv]) result
  * with respect to this variable.
  */
-open class Variable<T : Any>(val value: T)
+public open class Variable<T : Any>(public val value: T)
 
-class DerivationResult<T : Any>(
+public class DerivationResult<T : Any>(
     value: T,
-    val deriv: Map<Variable<T>, T>,
-    val context: Field<T>
+    public val deriv: Map<Variable<T>, T>,
+    public val context: Field<T>
 ) : Variable<T>(value) {
-    fun deriv(variable: Variable<T>): T = deriv[variable] ?: context.zero
+    public fun deriv(variable: Variable<T>): T = deriv[variable] ?: context.zero
 
     /**
      * compute divergence
      */
-    fun div(): T = context { sum(deriv.values) }
+    public fun div(): T = context { sum(deriv.values) }
 
     /**
      * Compute a gradient for variables in given order
      */
-    fun grad(vararg variables: Variable<T>): Point<T> {
+    public fun grad(vararg variables: Variable<T>): Point<T> {
         check(variables.isNotEmpty()) { "Variable order is not provided for gradient construction" }
         return variables.map(::deriv).asBuffer()
     }
@@ -54,7 +54,7 @@ class DerivationResult<T : Any>(
  * assertEquals(9.0, x.d)  // dy/dx
  * ```
  */
-inline fun <T : Any, F : Field<T>> F.deriv(body: AutoDiffField<T, F>.() -> Variable<T>): DerivationResult<T> {
+public inline fun <T : Any, F : Field<T>> F.deriv(body: AutoDiffField<T, F>.() -> Variable<T>): DerivationResult<T> {
     contract { callsInPlace(body, InvocationKind.EXACTLY_ONCE) }
 
     return (AutoDiffContext(this)) {
@@ -65,15 +65,14 @@ inline fun <T : Any, F : Field<T>> F.deriv(body: AutoDiffField<T, F>.() -> Varia
     }
 }
 
-
-abstract class AutoDiffField<T : Any, F : Field<T>> : Field<Variable<T>> {
-    abstract val context: F
+public abstract class AutoDiffField<T : Any, F : Field<T>> : Field<Variable<T>> {
+    public abstract val context: F
 
     /**
      * A variable accessing inner state of derivatives.
      * Use this function in inner builders to avoid creating additional derivative bindings
      */
-    abstract var Variable<T>.d: T
+    public abstract var Variable<T>.d: T
 
     /**
      * Performs update of derivative after the rest of the formula in the back-pass.
@@ -86,11 +85,11 @@ abstract class AutoDiffField<T : Any, F : Field<T>> : Field<Variable<T>> {
      * }
      * ```
      */
-    abstract fun <R> derive(value: R, block: F.(R) -> Unit): R
+    public abstract fun <R> derive(value: R, block: F.(R) -> Unit): R
 
-    abstract fun variable(value: T): Variable<T>
+    public abstract fun variable(value: T): Variable<T>
 
-    inline fun variable(block: F.() -> T): Variable<T> = variable(context.block())
+    public inline fun variable(block: F.() -> T): Variable<T> = variable(context.block())
 
     // Overloads for Double constants
 
@@ -152,7 +151,6 @@ internal class AutoDiffContext<T : Any, F : Field<T>>(override val context: F) :
 
     // Basic math (+, -, *, /)
 
-
     override fun add(a: Variable<T>, b: Variable<T>): Variable<T> = derive(variable { a.value + b.value }) { z ->
         a.d += z.d
         b.d += z.d
@@ -176,35 +174,73 @@ internal class AutoDiffContext<T : Any, F : Field<T>>(override val context: F) :
 // Extensions for differentiation of various basic mathematical functions
 
 // x ^ 2
-fun <T : Any, F : Field<T>> AutoDiffField<T, F>.sqr(x: Variable<T>): Variable<T> =
+public fun <T : Any, F : Field<T>> AutoDiffField<T, F>.sqr(x: Variable<T>): Variable<T> =
     derive(variable { x.value * x.value }) { z -> x.d += z.d * 2 * x.value }
 
 // x ^ 1/2
-fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.sqrt(x: Variable<T>): Variable<T> =
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.sqrt(x: Variable<T>): Variable<T> =
     derive(variable { sqrt(x.value) }) { z -> x.d += z.d * 0.5 / z.value }
 
 // x ^ y (const)
-fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.pow(x: Variable<T>, y: Double): Variable<T> =
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.pow(x: Variable<T>, y: Double): Variable<T> =
     derive(variable { power(x.value, y) }) { z -> x.d += z.d * y * power(x.value, y - 1) }
 
-fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.pow(x: Variable<T>, y: Int): Variable<T> = pow(x, y.toDouble())
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.pow(x: Variable<T>, y: Int): Variable<T> =
+    pow(x, y.toDouble())
 
 // exp(x)
-fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.exp(x: Variable<T>): Variable<T> =
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.exp(x: Variable<T>): Variable<T> =
     derive(variable { exp(x.value) }) { z -> x.d += z.d * z.value }
 
 // ln(x)
-fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.ln(x: Variable<T>): Variable<T> =
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.ln(x: Variable<T>): Variable<T> =
     derive(variable { ln(x.value) }) { z -> x.d += z.d / x.value }
 
 // x ^ y (any)
-fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.pow(x: Variable<T>, y: Variable<T>): Variable<T> =
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.pow(x: Variable<T>, y: Variable<T>): Variable<T> =
     exp(y * ln(x))
 
 // sin(x)
-fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.sin(x: Variable<T>): Variable<T> =
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.sin(x: Variable<T>): Variable<T> =
     derive(variable { sin(x.value) }) { z -> x.d += z.d * cos(x.value) }
 
 // cos(x)
-fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.cos(x: Variable<T>): Variable<T> =
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.cos(x: Variable<T>): Variable<T> =
     derive(variable { cos(x.value) }) { z -> x.d -= z.d * sin(x.value) }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.tan(x: Variable<T>): Variable<T> =
+    derive(variable { tan(x.value) }) { z ->
+        val c = cos(x.value)
+        x.d += z.d / (c * c)
+    }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.asin(x: Variable<T>): Variable<T> =
+    derive(variable { asin(x.value) }) { z -> x.d += z.d / sqrt(one - x.value * x.value) }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.acos(x: Variable<T>): Variable<T> =
+    derive(variable { acos(x.value) }) { z -> x.d -= z.d / sqrt(one - x.value * x.value) }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.atan(x: Variable<T>): Variable<T> =
+    derive(variable { atan(x.value) }) { z -> x.d += z.d / (one + x.value * x.value) }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.sinh(x: Variable<T>): Variable<T> =
+    derive(variable { sin(x.value) }) { z -> x.d += z.d * cosh(x.value) }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.cosh(x: Variable<T>): Variable<T> =
+    derive(variable { cos(x.value) }) { z -> x.d += z.d * sinh(x.value) }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.tanh(x: Variable<T>): Variable<T> =
+    derive(variable { tan(x.value) }) { z ->
+        val c = cosh(x.value)
+        x.d += z.d / (c * c)
+    }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.asinh(x: Variable<T>): Variable<T> =
+    derive(variable { asinh(x.value) }) { z -> x.d += z.d / sqrt(one + x.value * x.value) }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.acosh(x: Variable<T>): Variable<T> =
+    derive(variable { acosh(x.value) }) { z -> x.d += z.d / (sqrt((x.value - one) * (x.value + one))) }
+
+public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.atanh(x: Variable<T>): Variable<T> =
+    derive(variable { atanh(x.value) }) { z -> x.d += z.d / (one - x.value * x.value) }
+
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/Grids.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/Grids.kt
similarity index 80%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/Grids.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/misc/Grids.kt
index 1272ddd1c..4d058c366 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/Grids.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/Grids.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.misc
+package kscience.kmath.misc
 
 import kotlin.math.abs
 
@@ -10,17 +10,21 @@ import kotlin.math.abs
  *
  * If step is negative, the same goes from upper boundary downwards
  */
-fun ClosedFloatingPointRange<Double>.toSequenceWithStep(step: Double): Sequence<Double> = when {
+public fun ClosedFloatingPointRange<Double>.toSequenceWithStep(step: Double): Sequence<Double> = when {
     step == 0.0 -> error("Zero step in double progression")
+
     step > 0 -> sequence {
         var current = start
+
         while (current <= endInclusive) {
             yield(current)
             current += step
         }
     }
+
     else -> sequence {
         var current = endInclusive
+
         while (current >= start) {
             yield(current)
             current += step
@@ -31,7 +35,7 @@ fun ClosedFloatingPointRange<Double>.toSequenceWithStep(step: Double): Sequence<
 /**
  * Convert double range to sequence with the fixed number of points
  */
-fun ClosedFloatingPointRange<Double>.toSequenceWithPoints(numPoints: Int): Sequence<Double> {
+public fun ClosedFloatingPointRange<Double>.toSequenceWithPoints(numPoints: Int): Sequence<Double> {
     require(numPoints > 1) { "The number of points should be more than 2" }
     return toSequenceWithStep(abs(endInclusive - start) / (numPoints - 1))
 }
@@ -40,7 +44,7 @@ fun ClosedFloatingPointRange<Double>.toSequenceWithPoints(numPoints: Int): Seque
  * Convert double range to array of evenly spaced doubles, where the size of array equals [numPoints]
  */
 @Deprecated("Replace by 'toSequenceWithPoints'")
-fun ClosedFloatingPointRange<Double>.toGrid(numPoints: Int): DoubleArray {
+public fun ClosedFloatingPointRange<Double>.toGrid(numPoints: Int): DoubleArray {
     require(numPoints >= 2) { "Can't create generic grid with less than two points" }
     return DoubleArray(numPoints) { i -> start + (endInclusive - start) / (numPoints - 1) * i }
 }
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/cumulative.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/cumulative.kt
new file mode 100644
index 000000000..72d2f2388
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/misc/cumulative.kt
@@ -0,0 +1,74 @@
+package kscience.kmath.misc
+
+import kscience.kmath.operations.Space
+import kscience.kmath.operations.invoke
+import kotlin.jvm.JvmName
+
+/**
+ * Generic cumulative operation on iterator.
+ *
+ * @param T the type of initial iterable.
+ * @param R the type of resulting iterable.
+ * @param initial lazy evaluated.
+ */
+public inline fun <T, R> Iterator<T>.cumulative(initial: R, crossinline operation: (R, T) -> R): Iterator<R> =
+    object : Iterator<R> {
+        var state: R = initial
+
+        override fun hasNext(): Boolean = this@cumulative.hasNext()
+
+        override fun next(): R {
+            state = operation(state, this@cumulative.next())
+            return state
+        }
+    }
+
+public inline fun <T, R> Iterable<T>.cumulative(initial: R, crossinline operation: (R, T) -> R): Iterable<R> =
+    Iterable { this@cumulative.iterator().cumulative(initial, operation) }
+
+public inline fun <T, R> Sequence<T>.cumulative(initial: R, crossinline operation: (R, T) -> R): Sequence<R> =
+    Sequence { this@cumulative.iterator().cumulative(initial, operation) }
+
+public fun <T, R> List<T>.cumulative(initial: R, operation: (R, T) -> R): List<R> =
+    iterator().cumulative(initial, operation).asSequence().toList()
+
+//Cumulative sum
+
+/**
+ * Cumulative sum with custom space
+ */
+public fun <T> Iterable<T>.cumulativeSum(space: Space<T>): Iterable<T> =
+    space { cumulative(zero) { element: T, sum: T -> sum + element } }
+
+@JvmName("cumulativeSumOfDouble")
+public fun Iterable<Double>.cumulativeSum(): Iterable<Double> = cumulative(0.0) { element, sum -> sum + element }
+
+@JvmName("cumulativeSumOfInt")
+public fun Iterable<Int>.cumulativeSum(): Iterable<Int> = cumulative(0) { element, sum -> sum + element }
+
+@JvmName("cumulativeSumOfLong")
+public fun Iterable<Long>.cumulativeSum(): Iterable<Long> = cumulative(0L) { element, sum -> sum + element }
+
+public fun <T> Sequence<T>.cumulativeSum(space: Space<T>): Sequence<T> =
+    space { cumulative(zero) { element: T, sum: T -> sum + element } }
+
+@JvmName("cumulativeSumOfDouble")
+public fun Sequence<Double>.cumulativeSum(): Sequence<Double> = cumulative(0.0) { element, sum -> sum + element }
+
+@JvmName("cumulativeSumOfInt")
+public fun Sequence<Int>.cumulativeSum(): Sequence<Int> = cumulative(0) { element, sum -> sum + element }
+
+@JvmName("cumulativeSumOfLong")
+public fun Sequence<Long>.cumulativeSum(): Sequence<Long> = cumulative(0L) { element, sum -> sum + element }
+
+public fun <T> List<T>.cumulativeSum(space: Space<T>): List<T> =
+    space { cumulative(zero) { element: T, sum: T -> sum + element } }
+
+@JvmName("cumulativeSumOfDouble")
+public fun List<Double>.cumulativeSum(): List<Double> = cumulative(0.0) { element, sum -> sum + element }
+
+@JvmName("cumulativeSumOfInt")
+public fun List<Int>.cumulativeSum(): List<Int> = cumulative(0) { element, sum -> sum + element }
+
+@JvmName("cumulativeSumOfLong")
+public fun List<Long>.cumulativeSum(): List<Long> = cumulative(0L) { element, sum -> sum + element }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Algebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt
similarity index 74%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Algebra.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt
index f18bde597..12a45615a 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Algebra.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Algebra.kt
@@ -1,31 +1,31 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 /**
  * Stub for DSL the [Algebra] is.
  */
 @DslMarker
-annotation class KMathContext
+public annotation class KMathContext
 
 /**
  * Represents an algebraic structure.
  *
  * @param T the type of element of this structure.
  */
-interface Algebra<T> {
+public interface Algebra<T> {
     /**
      * Wrap raw string or variable
      */
-    fun symbol(value: String): T = error("Wrapping of '$value' is not supported in $this")
+    public fun symbol(value: String): T = error("Wrapping of '$value' is not supported in $this")
 
     /**
      * Dynamic call of unary operation with name [operation] on [arg]
      */
-    fun unaryOperation(operation: String, arg: T): T
+    public fun unaryOperation(operation: String, arg: T): T
 
     /**
      * Dynamic call of binary operation [operation] on [left] and [right]
      */
-    fun binaryOperation(operation: String, left: T, right: T): T
+    public fun binaryOperation(operation: String, left: T, right: T): T
 }
 
 /**
@@ -33,29 +33,30 @@ interface Algebra<T> {
  *
  * @param T the type of element of this structure.
  */
-interface NumericAlgebra<T> : Algebra<T> {
+public interface NumericAlgebra<T> : Algebra<T> {
     /**
      * Wraps a number.
      */
-    fun number(value: Number): T
+    public fun number(value: Number): T
 
     /**
      * Dynamic call of binary operation [operation] on [left] and [right] where left element is [Number].
      */
-    fun leftSideNumberOperation(operation: String, left: Number, right: T): T =
+    public fun leftSideNumberOperation(operation: String, left: Number, right: T): T =
         binaryOperation(operation, number(left), right)
 
     /**
      * Dynamic call of binary operation [operation] on [left] and [right] where right element is [Number].
      */
-    fun rightSideNumberOperation(operation: String, left: T, right: Number): T =
+    public fun rightSideNumberOperation(operation: String, left: T, right: Number): T =
         leftSideNumberOperation(operation, right, left)
 }
 
 /**
  * Call a block with an [Algebra] as receiver.
  */
-inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R = run(block)
+// TODO add contract when KT-32313 is fixed
+public inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R = block()
 
 /**
  * Represents "semispace", i.e. algebraic structure with associative binary operation called "addition" as well as
@@ -63,7 +64,7 @@ inline operator fun <A : Algebra<*>, R> A.invoke(block: A.() -> R): R = run(bloc
  *
  * @param T the type of element of this semispace.
  */
-interface SpaceOperations<T> : Algebra<T> {
+public interface SpaceOperations<T> : Algebra<T> {
     /**
      * Addition of two elements.
      *
@@ -71,7 +72,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @param b the augend.
      * @return the sum.
      */
-    fun add(a: T, b: T): T
+    public fun add(a: T, b: T): T
 
     /**
      * Multiplication of element by scalar.
@@ -80,7 +81,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @param k the multiplicand.
      * @return the produce.
      */
-    fun multiply(a: T, k: Number): T
+    public fun multiply(a: T, k: Number): T
 
     // Operations to be performed in this context. Could be moved to extensions in case of KEEP-176
 
@@ -90,7 +91,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @receiver this value.
      * @return the additive inverse of this value.
      */
-    operator fun T.unaryMinus(): T = multiply(this, -1.0)
+    public operator fun T.unaryMinus(): T = multiply(this, -1.0)
 
     /**
      * Returns this value.
@@ -98,7 +99,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @receiver this value.
      * @return this value.
      */
-    operator fun T.unaryPlus(): T = this
+    public operator fun T.unaryPlus(): T = this
 
     /**
      * Addition of two elements.
@@ -107,7 +108,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @param b the augend.
      * @return the sum.
      */
-    operator fun T.plus(b: T): T = add(this, b)
+    public operator fun T.plus(b: T): T = add(this, b)
 
     /**
      * Subtraction of two elements.
@@ -116,7 +117,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @param b the subtrahend.
      * @return the difference.
      */
-    operator fun T.minus(b: T): T = add(this, -b)
+    public operator fun T.minus(b: T): T = add(this, -b)
 
     /**
      * Multiplication of this element by a scalar.
@@ -125,7 +126,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @param k the multiplicand.
      * @return the product.
      */
-    operator fun T.times(k: Number): T = multiply(this, k.toDouble())
+    public operator fun T.times(k: Number): T = multiply(this, k.toDouble())
 
     /**
      * Division of this element by scalar.
@@ -134,7 +135,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @param k the divisor.
      * @return the quotient.
      */
-    operator fun T.div(k: Number): T = multiply(this, 1.0 / k.toDouble())
+    public operator fun T.div(k: Number): T = multiply(this, 1.0 / k.toDouble())
 
     /**
      * Multiplication of this number by element.
@@ -143,7 +144,7 @@ interface SpaceOperations<T> : Algebra<T> {
      * @param b the multiplicand.
      * @return the product.
      */
-    operator fun Number.times(b: T): T = b * this
+    public operator fun Number.times(b: T): T = b * this
 
     override fun unaryOperation(operation: String, arg: T): T = when (operation) {
         PLUS_OPERATION -> arg
@@ -157,18 +158,16 @@ interface SpaceOperations<T> : Algebra<T> {
         else -> error("Binary operation $operation not defined in $this")
     }
 
-    companion object {
+    public companion object {
         /**
          * The identifier of addition.
          */
-        const val PLUS_OPERATION: String = "+"
+        public const val PLUS_OPERATION: String = "+"
 
         /**
          * The identifier of subtraction (and negation).
          */
-        const val MINUS_OPERATION: String = "-"
-
-        const val NOT_OPERATION: String = "!"
+        public const val MINUS_OPERATION: String = "-"
     }
 }
 
@@ -178,11 +177,11 @@ interface SpaceOperations<T> : Algebra<T> {
  *
  * @param T the type of element of this group.
  */
-interface Space<T> : SpaceOperations<T> {
+public interface Space<T> : SpaceOperations<T> {
     /**
      * The neutral element of addition.
      */
-    val zero: T
+    public val zero: T
 }
 
 /**
@@ -191,14 +190,14 @@ interface Space<T> : SpaceOperations<T> {
  *
  * @param T the type of element of this semiring.
  */
-interface RingOperations<T> : SpaceOperations<T> {
+public interface RingOperations<T> : SpaceOperations<T> {
     /**
      * Multiplies two elements.
      *
      * @param a the multiplier.
      * @param b the multiplicand.
      */
-    fun multiply(a: T, b: T): T
+    public fun multiply(a: T, b: T): T
 
     /**
      * Multiplies this element by scalar.
@@ -206,18 +205,18 @@ interface RingOperations<T> : SpaceOperations<T> {
      * @receiver the multiplier.
      * @param b the multiplicand.
      */
-    operator fun T.times(b: T): T = multiply(this, b)
+    public operator fun T.times(b: T): T = multiply(this, b)
 
     override fun binaryOperation(operation: String, left: T, right: T): T = when (operation) {
         TIMES_OPERATION -> multiply(left, right)
         else -> super.binaryOperation(operation, left, right)
     }
 
-    companion object {
+    public companion object {
         /**
          * The identifier of multiplication.
          */
-        const val TIMES_OPERATION: String = "*"
+        public const val TIMES_OPERATION: String = "*"
     }
 }
 
@@ -227,11 +226,11 @@ interface RingOperations<T> : SpaceOperations<T> {
  *
  * @param T the type of element of this ring.
  */
-interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
+public interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
     /**
      * neutral operation for multiplication
      */
-    val one: T
+    public val one: T
 
     override fun number(value: Number): T = one * value.toDouble()
 
@@ -255,7 +254,7 @@ interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
      * @receiver the addend.
      * @param b the augend.
      */
-    operator fun T.plus(b: Number): T = this + number(b)
+    public operator fun T.plus(b: Number): T = this + number(b)
 
     /**
      * Addition of scalar and element.
@@ -263,7 +262,7 @@ interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
      * @receiver the addend.
      * @param b the augend.
      */
-    operator fun Number.plus(b: T): T = b + this
+    public operator fun Number.plus(b: T): T = b + this
 
     /**
      * Subtraction of element from number.
@@ -272,7 +271,7 @@ interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
      * @param b the subtrahend.
      * @receiver the difference.
      */
-    operator fun T.minus(b: Number): T = this - number(b)
+    public operator fun T.minus(b: Number): T = this - number(b)
 
     /**
      * Subtraction of number from element.
@@ -281,7 +280,7 @@ interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
      * @param b the subtrahend.
      * @receiver the difference.
      */
-    operator fun Number.minus(b: T): T = -b + this
+    public operator fun Number.minus(b: T): T = -b + this
 }
 
 /**
@@ -290,7 +289,7 @@ interface Ring<T> : Space<T>, RingOperations<T>, NumericAlgebra<T> {
  *
  * @param T the type of element of this semifield.
  */
-interface FieldOperations<T> : RingOperations<T> {
+public interface FieldOperations<T> : RingOperations<T> {
     /**
      * Division of two elements.
      *
@@ -298,7 +297,7 @@ interface FieldOperations<T> : RingOperations<T> {
      * @param b the divisor.
      * @return the quotient.
      */
-    fun divide(a: T, b: T): T
+    public fun divide(a: T, b: T): T
 
     /**
      * Division of two elements.
@@ -307,18 +306,18 @@ interface FieldOperations<T> : RingOperations<T> {
      * @param b the divisor.
      * @return the quotient.
      */
-    operator fun T.div(b: T): T = divide(this, b)
+    public operator fun T.div(b: T): T = divide(this, b)
 
     override fun binaryOperation(operation: String, left: T, right: T): T = when (operation) {
         DIV_OPERATION -> divide(left, right)
         else -> super.binaryOperation(operation, left, right)
     }
 
-    companion object {
+    public companion object {
         /**
          * The identifier of division.
          */
-        const val DIV_OPERATION: String = "/"
+        public const val DIV_OPERATION: String = "/"
     }
 }
 
@@ -328,7 +327,7 @@ interface FieldOperations<T> : RingOperations<T> {
  *
  * @param T the type of element of this semifield.
  */
-interface Field<T> : Ring<T>, FieldOperations<T> {
+public interface Field<T> : Ring<T>, FieldOperations<T> {
     /**
      * Division of element by scalar.
      *
@@ -336,5 +335,5 @@ interface Field<T> : Ring<T>, FieldOperations<T> {
      * @param b the divisor.
      * @return the quotient.
      */
-    operator fun Number.div(b: T): T = this * divide(one, b)
+    public operator fun Number.div(b: T): T = this * divide(one, b)
 }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/AlgebraElements.kt
similarity index 64%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/operations/AlgebraElements.kt
index 197897c14..94328dcb5 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraElements.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/AlgebraElements.kt
@@ -1,15 +1,15 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 /**
  * The generic mathematics elements which is able to store its context
  *
  * @param C the type of mathematical context for this element.
  */
-interface MathElement<C> {
+public interface MathElement<C> {
     /**
      * The context this element belongs to.
      */
-    val context: C
+    public val context: C
 }
 
 /**
@@ -18,16 +18,16 @@ interface MathElement<C> {
  * @param T the type wrapped by this wrapper.
  * @param I the type of this wrapper.
  */
-interface MathWrapper<T, I> {
+public interface MathWrapper<T, I> {
     /**
      * Unwraps [I] to [T].
      */
-    fun unwrap(): T
+    public fun unwrap(): T
 
     /**
      * Wraps [T] to [I].
      */
-    fun T.wrap(): I
+    public fun T.wrap(): I
 }
 
 /**
@@ -37,14 +37,14 @@ interface MathWrapper<T, I> {
  * @param I self type of the element. Needed for static type checking.
  * @param S the type of space.
  */
-interface SpaceElement<T, I : SpaceElement<T, I, S>, S : Space<T>> : MathElement<S>, MathWrapper<T, I> {
+public interface SpaceElement<T, I : SpaceElement<T, I, S>, S : Space<T>> : MathElement<S>, MathWrapper<T, I> {
     /**
      * Adds element to this one.
      *
      * @param b the augend.
      * @return the sum.
      */
-    operator fun plus(b: T): I = context.add(unwrap(), b).wrap()
+    public operator fun plus(b: T): I = context.add(unwrap(), b).wrap()
 
     /**
      * Subtracts element from this one.
@@ -52,7 +52,7 @@ interface SpaceElement<T, I : SpaceElement<T, I, S>, S : Space<T>> : MathElement
      * @param b the subtrahend.
      * @return the difference.
      */
-    operator fun minus(b: T): I = context.add(unwrap(), context.multiply(b, -1.0)).wrap()
+    public operator fun minus(b: T): I = context.add(unwrap(), context.multiply(b, -1.0)).wrap()
 
     /**
      * Multiplies this element by number.
@@ -60,7 +60,7 @@ interface SpaceElement<T, I : SpaceElement<T, I, S>, S : Space<T>> : MathElement
      * @param k the multiplicand.
      * @return the product.
      */
-    operator fun times(k: Number): I = context.multiply(unwrap(), k.toDouble()).wrap()
+    public operator fun times(k: Number): I = context.multiply(unwrap(), k.toDouble()).wrap()
 
     /**
      * Divides this element by number.
@@ -68,7 +68,7 @@ interface SpaceElement<T, I : SpaceElement<T, I, S>, S : Space<T>> : MathElement
      * @param k the divisor.
      * @return the quotient.
      */
-    operator fun div(k: Number): I = context.multiply(unwrap(), 1.0 / k.toDouble()).wrap()
+    public operator fun div(k: Number): I = context.multiply(unwrap(), 1.0 / k.toDouble()).wrap()
 }
 
 /**
@@ -78,14 +78,14 @@ interface SpaceElement<T, I : SpaceElement<T, I, S>, S : Space<T>> : MathElement
  * @param I self type of the element. Needed for static type checking.
  * @param R the type of space.
  */
-interface RingElement<T, I : RingElement<T, I, R>, R : Ring<T>> : SpaceElement<T, I, R> {
+public interface RingElement<T, I : RingElement<T, I, R>, R : Ring<T>> : SpaceElement<T, I, R> {
     /**
      * Multiplies this element by another one.
      *
      * @param b the multiplicand.
      * @return the product.
      */
-    operator fun times(b: T): I = context.multiply(unwrap(), b).wrap()
+    public operator fun times(b: T): I = context.multiply(unwrap(), b).wrap()
 }
 
 /**
@@ -95,7 +95,7 @@ interface RingElement<T, I : RingElement<T, I, R>, R : Ring<T>> : SpaceElement<T
  * @param I self type of the element. Needed for static type checking.
  * @param F the type of field.
  */
-interface FieldElement<T, I : FieldElement<T, I, F>, F : Field<T>> : RingElement<T, I, F> {
+public interface FieldElement<T, I : FieldElement<T, I, F>, F : Field<T>> : RingElement<T, I, F> {
     override val context: F
 
     /**
@@ -104,5 +104,5 @@ interface FieldElement<T, I : FieldElement<T, I, F>, F : Field<T>> : RingElement
      * @param b the divisor.
      * @return the quotient.
      */
-    operator fun div(b: T): I = context.divide(unwrap(), b).wrap()
+    public operator fun div(b: T): I = context.divide(unwrap(), b).wrap()
 }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/AlgebraExtensions.kt
similarity index 72%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/operations/AlgebraExtensions.kt
index 00b16dc98..657da6b4e 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/AlgebraExtensions.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/AlgebraExtensions.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 /**
  * Returns the sum of all elements in the iterable in this [Space].
@@ -7,7 +7,7 @@ package scientifik.kmath.operations
  * @param data the iterable to sum up.
  * @return the sum.
  */
-fun <T> Space<T>.sum(data: Iterable<T>): T = data.fold(zero) { left, right -> add(left, right) }
+public fun <T> Space<T>.sum(data: Iterable<T>): T = data.fold(zero) { left, right -> add(left, right) }
 
 /**
  * Returns the sum of all elements in the sequence in this [Space].
@@ -16,7 +16,7 @@ fun <T> Space<T>.sum(data: Iterable<T>): T = data.fold(zero) { left, right -> ad
  * @param data the sequence to sum up.
  * @return the sum.
  */
-fun <T> Space<T>.sum(data: Sequence<T>): T = data.fold(zero) { left, right -> add(left, right) }
+public fun <T> Space<T>.sum(data: Sequence<T>): T = data.fold(zero) { left, right -> add(left, right) }
 
 /**
  * Returns an average value of elements in the iterable in this [Space].
@@ -24,8 +24,9 @@ fun <T> Space<T>.sum(data: Sequence<T>): T = data.fold(zero) { left, right -> ad
  * @receiver the algebra that provides addition and division.
  * @param data the iterable to find average.
  * @return the average value.
+ * @author Iaroslav Postovalov
  */
-fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count()
+public fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count()
 
 /**
  * Returns an average value of elements in the sequence in this [Space].
@@ -33,8 +34,9 @@ fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count()
  * @receiver the algebra that provides addition and division.
  * @param data the sequence to find average.
  * @return the average value.
+ * @author Iaroslav Postovalov
  */
-fun <T> Space<T>.average(data: Sequence<T>): T = sum(data) / data.count()
+public fun <T> Space<T>.average(data: Sequence<T>): T = sum(data) / data.count()
 
 /**
  * Returns the sum of all elements in the iterable in provided space.
@@ -43,7 +45,7 @@ fun <T> Space<T>.average(data: Sequence<T>): T = sum(data) / data.count()
  * @param space the algebra that provides addition.
  * @return the sum.
  */
-fun <T> Iterable<T>.sumWith(space: Space<T>): T = space.sum(this)
+public fun <T> Iterable<T>.sumWith(space: Space<T>): T = space.sum(this)
 
 /**
  * Returns the sum of all elements in the sequence in provided space.
@@ -52,7 +54,7 @@ fun <T> Iterable<T>.sumWith(space: Space<T>): T = space.sum(this)
  * @param space the algebra that provides addition.
  * @return the sum.
  */
-fun <T> Sequence<T>.sumWith(space: Space<T>): T = space.sum(this)
+public fun <T> Sequence<T>.sumWith(space: Space<T>): T = space.sum(this)
 
 /**
  * Returns an average value of elements in the iterable in this [Space].
@@ -60,8 +62,9 @@ fun <T> Sequence<T>.sumWith(space: Space<T>): T = space.sum(this)
  * @receiver the iterable to find average.
  * @param space the algebra that provides addition and division.
  * @return the average value.
+ * @author Iaroslav Postovalov
  */
-fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this)
+public fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this)
 
 /**
  * Returns an average value of elements in the sequence in this [Space].
@@ -69,8 +72,9 @@ fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this)
  * @receiver the sequence to find average.
  * @param space the algebra that provides addition and division.
  * @return the average value.
+ * @author Iaroslav Postovalov
  */
-fun <T> Sequence<T>.averageWith(space: Space<T>): T = space.average(this)
+public fun <T> Sequence<T>.averageWith(space: Space<T>): T = space.average(this)
 
 //TODO optimized power operation
 
@@ -82,7 +86,7 @@ fun <T> Sequence<T>.averageWith(space: Space<T>): T = space.average(this)
  * @param power the exponent.
  * @return the base raised to the power.
  */
-fun <T> Ring<T>.power(arg: T, power: Int): T {
+public fun <T> Ring<T>.power(arg: T, power: Int): T {
     require(power >= 0) { "The power can't be negative." }
     require(power != 0 || arg != zero) { "The $zero raised to $power is not defined." }
     if (power == 0) return one
@@ -98,8 +102,9 @@ fun <T> Ring<T>.power(arg: T, power: Int): T {
  * @param arg the base.
  * @param power the exponent.
  * @return the base raised to the power.
+ * @author Iaroslav Postovalov
  */
-fun <T> Field<T>.power(arg: T, power: Int): T {
+public fun <T> Field<T>.power(arg: T, power: Int): T {
     require(power != 0 || arg != zero) { "The $zero raised to $power is not defined." }
     if (power == 0) return one
     if (power < 0) return one / (this as Ring<T>).power(arg, -power)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/BigInt.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/BigInt.kt
similarity index 58%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/BigInt.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/operations/BigInt.kt
index f03275ed9..4590c58fc 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/BigInt.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/BigInt.kt
@@ -1,23 +1,22 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
-import scientifik.kmath.operations.BigInt.Companion.BASE
-import scientifik.kmath.operations.BigInt.Companion.BASE_SIZE
-import scientifik.kmath.structures.*
-import kotlin.contracts.contract
+import kscience.kmath.operations.BigInt.Companion.BASE
+import kscience.kmath.operations.BigInt.Companion.BASE_SIZE
+import kscience.kmath.structures.*
 import kotlin.math.log2
 import kotlin.math.max
 import kotlin.math.min
 import kotlin.math.sign
 
-typealias Magnitude = UIntArray
-typealias TBase = ULong
+public typealias Magnitude = UIntArray
+public typealias TBase = ULong
 
 /**
  * Kotlin Multiplatform implementation of Big Integer numbers (KBigInteger).
  *
  * @author Robert Drynkin (https://github.com/robdrynkin) and Peter Klimai (https://github.com/pklimai)
  */
-object BigIntField : Field<BigInt> {
+public object BigIntField : Field<BigInt> {
     override val zero: BigInt = BigInt.ZERO
     override val one: BigInt = BigInt.ONE
 
@@ -28,113 +27,92 @@ object BigIntField : Field<BigInt> {
 
     override fun multiply(a: BigInt, b: BigInt): BigInt = a.times(b)
 
-    operator fun String.unaryPlus(): BigInt = this.parseBigInteger() ?: error("Can't parse $this as big integer")
+    public operator fun String.unaryPlus(): BigInt = this.parseBigInteger() ?: error("Can't parse $this as big integer")
 
-    operator fun String.unaryMinus(): BigInt =
+    public operator fun String.unaryMinus(): BigInt =
         -(this.parseBigInteger() ?: error("Can't parse $this as big integer"))
 
     override fun divide(a: BigInt, b: BigInt): BigInt = a.div(b)
 }
 
-class BigInt internal constructor(
+public class BigInt internal constructor(
     private val sign: Byte,
     private val magnitude: Magnitude
 ) : Comparable<BigInt> {
+    public override fun compareTo(other: BigInt): Int = when {
+        (sign == 0.toByte()) and (other.sign == 0.toByte()) -> 0
+        sign < other.sign -> -1
+        sign > other.sign -> 1
+        else -> sign * compareMagnitudes(magnitude, other.magnitude)
+    }
 
-    override fun compareTo(other: BigInt): Int {
-        return when {
-            (this.sign == 0.toByte()) and (other.sign == 0.toByte()) -> 0
-            this.sign < other.sign -> -1
-            this.sign > other.sign -> 1
-            else -> this.sign * compareMagnitudes(this.magnitude, other.magnitude)
+    public override fun equals(other: Any?): Boolean =
+        if (other is BigInt) compareTo(other) == 0 else error("Can't compare KBigInteger to a different type")
+
+    public override fun hashCode(): Int = magnitude.hashCode() + sign
+
+    public fun abs(): BigInt = if (sign == 0.toByte()) this else BigInt(1, magnitude)
+
+    public operator fun unaryMinus(): BigInt =
+        if (this.sign == 0.toByte()) this else BigInt((-this.sign).toByte(), this.magnitude)
+
+    public operator fun plus(b: BigInt): BigInt = when {
+        b.sign == 0.toByte() -> this
+        sign == 0.toByte() -> b
+        this == -b -> ZERO
+        sign == b.sign -> BigInt(sign, addMagnitudes(magnitude, b.magnitude))
+
+        else -> {
+            val comp = compareMagnitudes(magnitude, b.magnitude)
+
+            if (comp == 1)
+                BigInt(sign, subtractMagnitudes(magnitude, b.magnitude))
+            else
+                BigInt((-sign).toByte(), subtractMagnitudes(b.magnitude, magnitude))
         }
     }
 
-    override fun equals(other: Any?): Boolean {
-        if (other is BigInt) {
-            return this.compareTo(other) == 0
-        } else error("Can't compare KBigInteger to a different type")
-    }
+    public operator fun minus(b: BigInt): BigInt = this + (-b)
 
-    override fun hashCode(): Int {
-        return magnitude.hashCode() + this.sign
-    }
-
-    fun abs(): BigInt = if (sign == 0.toByte()) this else BigInt(1, magnitude)
-
-    operator fun unaryMinus(): BigInt {
-        return if (this.sign == 0.toByte()) this else BigInt((-this.sign).toByte(), this.magnitude)
-    }
-
-    operator fun plus(b: BigInt): BigInt {
-        return when {
-            b.sign == 0.toByte() -> this
-            this.sign == 0.toByte() -> b
-            this == -b -> ZERO
-            this.sign == b.sign -> BigInt(this.sign, addMagnitudes(this.magnitude, b.magnitude))
-            else -> {
-                val comp: Int = compareMagnitudes(this.magnitude, b.magnitude)
-
-                if (comp == 1) {
-                    BigInt(this.sign, subtractMagnitudes(this.magnitude, b.magnitude))
-                } else {
-                    BigInt((-this.sign).toByte(), subtractMagnitudes(b.magnitude, this.magnitude))
-                }
-            }
-        }
-    }
-
-    operator fun minus(b: BigInt): BigInt {
-        return this + (-b)
-    }
-
-    operator fun times(b: BigInt): BigInt {
-        return when {
-            this.sign == 0.toByte() -> ZERO
-            b.sign == 0.toByte() -> ZERO
+    public operator fun times(b: BigInt): BigInt = when {
+        this.sign == 0.toByte() -> ZERO
+        b.sign == 0.toByte() -> ZERO
 //          TODO: Karatsuba
-            else -> BigInt((this.sign * b.sign).toByte(), multiplyMagnitudes(this.magnitude, b.magnitude))
-        }
+        else -> BigInt((this.sign * b.sign).toByte(), multiplyMagnitudes(this.magnitude, b.magnitude))
     }
 
-    operator fun times(other: UInt): BigInt {
-        return when {
-            this.sign == 0.toByte() -> ZERO
-            other == 0U -> ZERO
-            else -> BigInt(this.sign, multiplyMagnitudeByUInt(this.magnitude, other))
-        }
+    public operator fun times(other: UInt): BigInt = when {
+        sign == 0.toByte() -> ZERO
+        other == 0U -> ZERO
+        else -> BigInt(sign, multiplyMagnitudeByUInt(magnitude, other))
     }
 
-    operator fun times(other: Int): BigInt {
-        return if (other > 0)
-            this * kotlin.math.abs(other).toUInt()
-        else
-            -this * kotlin.math.abs(other).toUInt()
-    }
+    public operator fun times(other: Int): BigInt = if (other > 0)
+        this * kotlin.math.abs(other).toUInt()
+    else
+        -this * kotlin.math.abs(other).toUInt()
 
-    operator fun div(other: UInt): BigInt {
-        return BigInt(this.sign, divideMagnitudeByUInt(this.magnitude, other))
-    }
+    public operator fun div(other: UInt): BigInt = BigInt(this.sign, divideMagnitudeByUInt(this.magnitude, other))
 
-    operator fun div(other: Int): BigInt {
-        return BigInt(
-            (this.sign * other.sign).toByte(),
-            divideMagnitudeByUInt(this.magnitude, kotlin.math.abs(other).toUInt())
-        )
-    }
+    public operator fun div(other: Int): BigInt = BigInt(
+        (this.sign * other.sign).toByte(),
+        divideMagnitudeByUInt(this.magnitude, kotlin.math.abs(other).toUInt())
+    )
 
     private fun division(other: BigInt): Pair<BigInt, BigInt> {
         // Long division algorithm:
         //     https://en.wikipedia.org/wiki/Division_algorithm#Integer_division_(unsigned)_with_remainder
         // TODO: Implement more effective algorithm
-        var q: BigInt = ZERO
-        var r: BigInt = ZERO
+        var q = ZERO
+        var r = ZERO
 
         val bitSize =
             (BASE_SIZE * (this.magnitude.size - 1) + log2(this.magnitude.lastOrNull()?.toFloat() ?: 0f + 1)).toInt()
+
         for (i in bitSize downTo 0) {
             r = r shl 1
             r = r or ((abs(this) shr i) and ONE)
+
             if (r >= abs(other)) {
                 r -= abs(other)
                 q += (ONE shl i)
@@ -144,99 +122,84 @@ class BigInt internal constructor(
         return Pair(BigInt((this.sign * other.sign).toByte(), q.magnitude), r)
     }
 
-    operator fun div(other: BigInt): BigInt {
-        return this.division(other).first
-    }
+    public operator fun div(other: BigInt): BigInt = division(other).first
 
-    infix fun shl(i: Int): BigInt {
+    public infix fun shl(i: Int): BigInt {
         if (this == ZERO) return ZERO
         if (i == 0) return this
-
         val fullShifts = i / BASE_SIZE + 1
         val relShift = i % BASE_SIZE
         val shiftLeft = { x: UInt -> if (relShift >= 32) 0U else x shl relShift }
         val shiftRight = { x: UInt -> if (BASE_SIZE - relShift >= 32) 0U else x shr (BASE_SIZE - relShift) }
+        val newMagnitude = Magnitude(magnitude.size + fullShifts)
 
-        val newMagnitude: Magnitude = Magnitude(this.magnitude.size + fullShifts)
-
-        for (j in this.magnitude.indices) {
+        for (j in magnitude.indices) {
             newMagnitude[j + fullShifts - 1] = shiftLeft(this.magnitude[j])
-            if (j != 0) {
+
+            if (j != 0)
                 newMagnitude[j + fullShifts - 1] = newMagnitude[j + fullShifts - 1] or shiftRight(this.magnitude[j - 1])
-            }
         }
 
-        newMagnitude[this.magnitude.size + fullShifts - 1] = shiftRight(this.magnitude.last())
-
+        newMagnitude[magnitude.size + fullShifts - 1] = shiftRight(magnitude.last())
         return BigInt(this.sign, stripLeadingZeros(newMagnitude))
     }
 
-    infix fun shr(i: Int): BigInt {
+    public infix fun shr(i: Int): BigInt {
         if (this == ZERO) return ZERO
         if (i == 0) return this
-
         val fullShifts = i / BASE_SIZE
         val relShift = i % BASE_SIZE
         val shiftRight = { x: UInt -> if (relShift >= 32) 0U else x shr relShift }
         val shiftLeft = { x: UInt -> if (BASE_SIZE - relShift >= 32) 0U else x shl (BASE_SIZE - relShift) }
-        if (this.magnitude.size - fullShifts <= 0) {
-            return ZERO
-        }
-        val newMagnitude: Magnitude = Magnitude(this.magnitude.size - fullShifts)
+        if (this.magnitude.size - fullShifts <= 0) return ZERO
+        val newMagnitude: Magnitude = Magnitude(magnitude.size - fullShifts)
 
-        for (j in fullShifts until this.magnitude.size) {
-            newMagnitude[j - fullShifts] = shiftRight(this.magnitude[j])
-            if (j != this.magnitude.size - 1) {
-                newMagnitude[j - fullShifts] = newMagnitude[j - fullShifts] or shiftLeft(this.magnitude[j + 1])
-            }
+        for (j in fullShifts until magnitude.size) {
+            newMagnitude[j - fullShifts] = shiftRight(magnitude[j])
+
+            if (j != magnitude.size - 1)
+                newMagnitude[j - fullShifts] = newMagnitude[j - fullShifts] or shiftLeft(magnitude[j + 1])
         }
 
         return BigInt(this.sign, stripLeadingZeros(newMagnitude))
     }
 
-    infix fun or(other: BigInt): BigInt {
+    public infix fun or(other: BigInt): BigInt {
         if (this == ZERO) return other
         if (other == ZERO) return this
-        val resSize = max(this.magnitude.size, other.magnitude.size)
+        val resSize = max(magnitude.size, other.magnitude.size)
         val newMagnitude: Magnitude = Magnitude(resSize)
+
         for (i in 0 until resSize) {
-            if (i < this.magnitude.size) {
-                newMagnitude[i] = newMagnitude[i] or this.magnitude[i]
-            }
-            if (i < other.magnitude.size) {
-                newMagnitude[i] = newMagnitude[i] or other.magnitude[i]
-            }
+            if (i < magnitude.size) newMagnitude[i] = newMagnitude[i] or magnitude[i]
+            if (i < other.magnitude.size) newMagnitude[i] = newMagnitude[i] or other.magnitude[i]
         }
+
         return BigInt(1, stripLeadingZeros(newMagnitude))
     }
 
-    infix fun and(other: BigInt): BigInt {
+    public infix fun and(other: BigInt): BigInt {
         if ((this == ZERO) or (other == ZERO)) return ZERO
         val resSize = min(this.magnitude.size, other.magnitude.size)
         val newMagnitude: Magnitude = Magnitude(resSize)
-        for (i in 0 until resSize) {
-            newMagnitude[i] = this.magnitude[i] and other.magnitude[i]
-        }
+        for (i in 0 until resSize) newMagnitude[i] = this.magnitude[i] and other.magnitude[i]
         return BigInt(1, stripLeadingZeros(newMagnitude))
     }
 
-    operator fun rem(other: Int): Int {
+    public operator fun rem(other: Int): Int {
         val res = this - (this / other) * other
         return if (res == ZERO) 0 else res.sign * res.magnitude[0].toInt()
     }
 
-    operator fun rem(other: BigInt): BigInt {
-        return this - (this / other) * other
-    }
+    public operator fun rem(other: BigInt): BigInt = this - (this / other) * other
 
-    fun modPow(exponent: BigInt, m: BigInt): BigInt {
-        return when {
-            exponent == ZERO -> ONE
-            exponent % 2 == 1 -> (this * modPow(exponent - ONE, m)) % m
-            else -> {
-                val sqRoot = modPow(exponent / 2, m)
-                (sqRoot * sqRoot) % m
-            }
+    public fun modPow(exponent: BigInt, m: BigInt): BigInt = when {
+        exponent == ZERO -> ONE
+        exponent % 2 == 1 -> (this * modPow(exponent - ONE, m)) % m
+
+        else -> {
+            val sqRoot = modPow(exponent / 2, m)
+            (sqRoot * sqRoot) % m
         }
     }
 
@@ -260,11 +223,11 @@ class BigInt internal constructor(
         return res
     }
 
-    companion object {
-        const val BASE: ULong = 0xffffffffUL
-        const val BASE_SIZE: Int = 32
-        val ZERO: BigInt = BigInt(0, uintArrayOf())
-        val ONE: BigInt = BigInt(1, uintArrayOf(1u))
+    public companion object {
+        public const val BASE: ULong = 0xffffffffUL
+        public const val BASE_SIZE: Int = 32
+        public val ZERO: BigInt = BigInt(0, uintArrayOf())
+        public val ONE: BigInt = BigInt(1, uintArrayOf(1u))
 
         private val hexMapping: HashMap<UInt, String> = hashMapOf(
             0U to "0", 1U to "1", 2U to "2", 3U to "3",
@@ -291,9 +254,9 @@ class BigInt internal constructor(
         }
 
         private fun addMagnitudes(mag1: Magnitude, mag2: Magnitude): Magnitude {
-            val resultLength: Int = max(mag1.size, mag2.size) + 1
+            val resultLength = max(mag1.size, mag2.size) + 1
             val result = Magnitude(resultLength)
-            var carry: TBase = 0UL
+            var carry = 0uL
 
             for (i in 0 until resultLength - 1) {
                 val res = when {
@@ -301,20 +264,22 @@ class BigInt internal constructor(
                     i >= mag2.size -> mag1[i].toULong() + carry
                     else -> mag1[i].toULong() + mag2[i].toULong() + carry
                 }
+
                 result[i] = (res and BASE).toUInt()
                 carry = (res shr BASE_SIZE)
             }
+
             result[resultLength - 1] = carry.toUInt()
             return stripLeadingZeros(result)
         }
 
         private fun subtractMagnitudes(mag1: Magnitude, mag2: Magnitude): Magnitude {
-            val resultLength: Int = mag1.size
+            val resultLength = mag1.size
             val result = Magnitude(resultLength)
             var carry = 0L
 
             for (i in 0 until resultLength) {
-                var res: Long =
+                var res =
                     if (i < mag2.size) mag1[i].toLong() - mag2[i].toLong() - carry
                     else mag1[i].toLong() - carry
 
@@ -328,9 +293,9 @@ class BigInt internal constructor(
         }
 
         private fun multiplyMagnitudeByUInt(mag: Magnitude, x: UInt): Magnitude {
-            val resultLength: Int = mag.size + 1
+            val resultLength = mag.size + 1
             val result = Magnitude(resultLength)
-            var carry: ULong = 0UL
+            var carry = 0uL
 
             for (i in mag.indices) {
                 val cur: ULong = carry + mag[i].toULong() * x.toULong()
@@ -343,16 +308,18 @@ class BigInt internal constructor(
         }
 
         private fun multiplyMagnitudes(mag1: Magnitude, mag2: Magnitude): Magnitude {
-            val resultLength: Int = mag1.size + mag2.size
+            val resultLength = mag1.size + mag2.size
             val result = Magnitude(resultLength)
 
             for (i in mag1.indices) {
-                var carry: ULong = 0UL
+                var carry = 0uL
+
                 for (j in mag2.indices) {
                     val cur: ULong = result[i + j].toULong() + mag1[i].toULong() * mag2[j].toULong() + carry
                     result[i + j] = (cur and BASE.toULong()).toUInt()
                     carry = cur shr BASE_SIZE
                 }
+
                 result[i + mag2.size] = (carry and BASE).toUInt()
             }
 
@@ -360,48 +327,46 @@ class BigInt internal constructor(
         }
 
         private fun divideMagnitudeByUInt(mag: Magnitude, x: UInt): Magnitude {
-            val resultLength: Int = mag.size
+            val resultLength = mag.size
             val result = Magnitude(resultLength)
-            var carry: ULong = 0UL
+            var carry = 0uL
 
             for (i in mag.size - 1 downTo 0) {
                 val cur: ULong = mag[i].toULong() + (carry shl BASE_SIZE)
                 result[i] = (cur / x).toUInt()
                 carry = cur % x
             }
+
             return stripLeadingZeros(result)
         }
-
     }
-
 }
 
-
 private fun stripLeadingZeros(mag: Magnitude): Magnitude {
-    if (mag.isEmpty() || mag.last() != 0U) {
-        return mag
-    }
-    var resSize: Int = mag.size - 1
+    if (mag.isEmpty() || mag.last() != 0U) return mag
+    var resSize = mag.size - 1
+
     while (mag[resSize] == 0U) {
-        if (resSize == 0)
-            break
+        if (resSize == 0) break
         resSize -= 1
     }
+
     return mag.sliceArray(IntRange(0, resSize))
 }
 
-fun abs(x: BigInt): BigInt = x.abs()
+public fun abs(x: BigInt): BigInt = x.abs()
 
 /**
  * Convert this [Int] to [BigInt]
  */
-fun Int.toBigInt(): BigInt = BigInt(sign.toByte(), uintArrayOf(kotlin.math.abs(this).toUInt()))
+public fun Int.toBigInt(): BigInt = BigInt(sign.toByte(), uintArrayOf(kotlin.math.abs(this).toUInt()))
 
 /**
  * Convert this [Long] to [BigInt]
  */
-fun Long.toBigInt(): BigInt = BigInt(
-    sign.toByte(), stripLeadingZeros(
+public fun Long.toBigInt(): BigInt = BigInt(
+    sign.toByte(),
+    stripLeadingZeros(
         uintArrayOf(
             (kotlin.math.abs(this).toULong() and BASE).toUInt(),
             ((kotlin.math.abs(this).toULong() shr BASE_SIZE) and BASE).toUInt()
@@ -412,12 +377,12 @@ fun Long.toBigInt(): BigInt = BigInt(
 /**
  * Convert UInt to [BigInt]
  */
-fun UInt.toBigInt(): BigInt = BigInt(1, uintArrayOf(this))
+public fun UInt.toBigInt(): BigInt = BigInt(1, uintArrayOf(this))
 
 /**
  * Convert ULong to [BigInt]
  */
-fun ULong.toBigInt(): BigInt = BigInt(
+public fun ULong.toBigInt(): BigInt = BigInt(
     1,
     stripLeadingZeros(
         uintArrayOf(
@@ -430,12 +395,12 @@ fun ULong.toBigInt(): BigInt = BigInt(
 /**
  * Create a [BigInt] with this array of magnitudes with protective copy
  */
-fun UIntArray.toBigInt(sign: Byte): BigInt {
+public fun UIntArray.toBigInt(sign: Byte): BigInt {
     require(sign != 0.toByte() || !isNotEmpty())
     return BigInt(sign, copyOf())
 }
 
-val hexChToInt: MutableMap<Char, Int> = hashMapOf(
+private val hexChToInt: MutableMap<Char, Int> = hashMapOf(
     '0' to 0, '1' to 1, '2' to 2, '3' to 3,
     '4' to 4, '5' to 5, '6' to 6, '7' to 7,
     '8' to 8, '9' to 9, 'A' to 10, 'B' to 11,
@@ -445,9 +410,10 @@ val hexChToInt: MutableMap<Char, Int> = hashMapOf(
 /**
  * Returns null if a valid number can not be read from a string
  */
-fun String.parseBigInteger(): BigInt? {
+public fun String.parseBigInteger(): BigInt? {
     val sign: Int
     val sPositive: String
+
     when {
         this[0] == '+' -> {
             sign = +1
@@ -462,43 +428,42 @@ fun String.parseBigInteger(): BigInt? {
             sign = +1
         }
     }
+
     var res = BigInt.ZERO
     var digitValue = BigInt.ONE
     val sPositiveUpper = sPositive.toUpperCase()
+
     if (sPositiveUpper.startsWith("0X")) {  // hex representation
         val sHex = sPositiveUpper.substring(2)
+
         for (ch in sHex.reversed()) {
             if (ch == '_') continue
             res += digitValue * (hexChToInt[ch] ?: return null)
             digitValue *= 16.toBigInt()
         }
-    } else { // decimal representation
-        for (ch in sPositiveUpper.reversed()) {
-            if (ch == '_') continue
-            if (ch !in '0'..'9') {
-                return null
-            }
-            res += digitValue * (ch.toInt() - '0'.toInt())
-            digitValue *= 10.toBigInt()
+    } else for (ch in sPositiveUpper.reversed()) {
+        // decimal representation
+        if (ch == '_') continue
+        if (ch !in '0'..'9') {
+            return null
         }
+        res += digitValue * (ch.toInt() - '0'.toInt())
+        digitValue *= 10.toBigInt()
     }
+
     return res * sign
 }
 
-inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): Buffer<BigInt> {
-    contract { callsInPlace(initializer) }
-    return boxing(size, initializer)
-}
+public inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): Buffer<BigInt> =
+    boxing(size, initializer)
 
-inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): MutableBuffer<BigInt> {
-    contract { callsInPlace(initializer) }
-    return boxing(size, initializer)
-}
+public inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInt): MutableBuffer<BigInt> =
+    boxing(size, initializer)
 
-fun NDAlgebra.Companion.bigInt(vararg shape: Int): BoxingNDRing<BigInt, BigIntField> =
+public fun NDAlgebra.Companion.bigInt(vararg shape: Int): BoxingNDRing<BigInt, BigIntField> =
     BoxingNDRing(shape, BigIntField, Buffer.Companion::bigInt)
 
-fun NDElement.Companion.bigInt(
+public fun NDElement.Companion.bigInt(
     vararg shape: Int,
     initializer: BigIntField.(IntArray) -> BigInt
 ): BufferedNDRingElement<BigInt, BigIntField> = NDAlgebra.bigInt(*shape).produce(initializer)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt
similarity index 73%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt
index 49200b5f9..c0faf5dc5 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/Complex.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/Complex.kt
@@ -1,24 +1,23 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.MemoryBuffer
-import scientifik.kmath.structures.MutableBuffer
-import scientifik.memory.MemoryReader
-import scientifik.memory.MemorySpec
-import scientifik.memory.MemoryWriter
-import kotlin.contracts.contract
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.MemoryBuffer
+import kscience.kmath.structures.MutableBuffer
+import kscience.memory.MemoryReader
+import kscience.memory.MemorySpec
+import kscience.memory.MemoryWriter
 import kotlin.math.*
 
 /**
  * This complex's conjugate.
  */
-val Complex.conjugate: Complex
+public val Complex.conjugate: Complex
     get() = Complex(re, -im)
 
 /**
  * This complex's reciprocal.
  */
-val Complex.reciprocal: Complex
+public val Complex.reciprocal: Complex
     get() {
         val scale = re * re + im * im
         return Complex(re / scale, -im / scale)
@@ -27,13 +26,13 @@ val Complex.reciprocal: Complex
 /**
  * Absolute value of complex number.
  */
-val Complex.r: Double
+public val Complex.r: Double
     get() = sqrt(re * re + im * im)
 
 /**
  * An angle between vector represented by complex number and X axis.
  */
-val Complex.theta: Double
+public val Complex.theta: Double
     get() = atan(im / re)
 
 private val PI_DIV_2 = Complex(PI / 2, 0)
@@ -41,14 +40,14 @@ private val PI_DIV_2 = Complex(PI / 2, 0)
 /**
  * A field of [Complex].
  */
-object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
+public object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
     override val zero: Complex = 0.0.toComplex()
     override val one: Complex = 1.0.toComplex()
 
     /**
      * The imaginary unit.
      */
-    val i: Complex = Complex(0.0, 1.0)
+    public val i: Complex = Complex(0.0, 1.0)
 
     override fun add(a: Complex, b: Complex): Complex = Complex(a.re + b.re, a.im + b.im)
 
@@ -116,7 +115,7 @@ object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
      * @param c the augend.
      * @return the sum.
      */
-    operator fun Double.plus(c: Complex): Complex = add(this.toComplex(), c)
+    public operator fun Double.plus(c: Complex): Complex = add(this.toComplex(), c)
 
     /**
      * Subtracts complex number from real one.
@@ -125,7 +124,7 @@ object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
      * @param c the subtrahend.
      * @return the difference.
      */
-    operator fun Double.minus(c: Complex): Complex = add(this.toComplex(), -c)
+    public operator fun Double.minus(c: Complex): Complex = add(this.toComplex(), -c)
 
     /**
      * Adds real number to complex one.
@@ -134,7 +133,7 @@ object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
      * @param d the augend.
      * @return the sum.
      */
-    operator fun Complex.plus(d: Double): Complex = d + this
+    public operator fun Complex.plus(d: Double): Complex = d + this
 
     /**
      * Subtracts real number from complex one.
@@ -143,7 +142,7 @@ object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
      * @param d the subtrahend.
      * @return the difference.
      */
-    operator fun Complex.minus(d: Double): Complex = add(this, -d.toComplex())
+    public operator fun Complex.minus(d: Double): Complex = add(this, -d.toComplex())
 
     /**
      * Multiplies real number by complex one.
@@ -152,7 +151,7 @@ object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
      * @param c the multiplicand.
      * @receiver the product.
      */
-    operator fun Double.times(c: Complex): Complex = Complex(c.re * this, c.im * this)
+    public operator fun Double.times(c: Complex): Complex = Complex(c.re * this, c.im * this)
 
     override fun norm(arg: Complex): Complex = sqrt(arg.conjugate * arg)
 
@@ -165,8 +164,9 @@ object ComplexField : ExtendedField<Complex>, Norm<Complex, Complex> {
  * @property re The real part.
  * @property im The imaginary part.
  */
-data class Complex(val re: Double, val im: Double) : FieldElement<Complex, Complex, ComplexField>, Comparable<Complex> {
-    constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble())
+public data class Complex(val re: Double, val im: Double) : FieldElement<Complex, Complex, ComplexField>,
+    Comparable<Complex> {
+    public constructor(re: Number, im: Number) : this(re.toDouble(), im.toDouble())
 
     override val context: ComplexField get() = ComplexField
 
@@ -176,7 +176,7 @@ data class Complex(val re: Double, val im: Double) : FieldElement<Complex, Compl
 
     override fun compareTo(other: Complex): Int = r.compareTo(other.r)
 
-    companion object : MemorySpec<Complex> {
+    public companion object : MemorySpec<Complex> {
         override val objectSize: Int = 16
 
         override fun MemoryReader.read(offset: Int): Complex =
@@ -195,14 +195,10 @@ data class Complex(val re: Double, val im: Double) : FieldElement<Complex, Compl
  * @receiver the real part.
  * @return the new complex number.
  */
-fun Number.toComplex(): Complex = Complex(this, 0.0)
+public fun Number.toComplex(): Complex = Complex(this, 0.0)
 
-inline fun Buffer.Companion.complex(size: Int, crossinline init: (Int) -> Complex): Buffer<Complex> {
-    contract { callsInPlace(init) }
-    return MemoryBuffer.create(Complex, size, init)
-}
+public inline fun Buffer.Companion.complex(size: Int, init: (Int) -> Complex): Buffer<Complex> =
+    MemoryBuffer.create(Complex, size, init)
 
-inline fun MutableBuffer.Companion.complex(size: Int, crossinline init: (Int) -> Complex): Buffer<Complex> {
-    contract { callsInPlace(init) }
-    return MemoryBuffer.create(Complex, size, init)
-}
+public inline fun MutableBuffer.Companion.complex(size: Int, init: (Int) -> Complex): Buffer<Complex> =
+    MemoryBuffer.create(Complex, size, init)
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt
new file mode 100644
index 000000000..a2b33a0c4
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/NumberAlgebra.kt
@@ -0,0 +1,266 @@
+package kscience.kmath.operations
+
+import kotlin.math.abs
+import kotlin.math.pow as kpow
+
+/**
+ * Advanced Number-like semifield that implements basic operations.
+ */
+public interface ExtendedFieldOperations<T> :
+    FieldOperations<T>,
+    TrigonometricOperations<T>,
+    HyperbolicOperations<T>,
+    PowerOperations<T>,
+    ExponentialOperations<T> {
+    public override fun tan(arg: T): T = sin(arg) / cos(arg)
+    public override fun tanh(arg: T): T = sinh(arg) / cosh(arg)
+
+    public override fun unaryOperation(operation: String, arg: T): T = when (operation) {
+        TrigonometricOperations.COS_OPERATION -> cos(arg)
+        TrigonometricOperations.SIN_OPERATION -> sin(arg)
+        TrigonometricOperations.TAN_OPERATION -> tan(arg)
+        TrigonometricOperations.ACOS_OPERATION -> acos(arg)
+        TrigonometricOperations.ASIN_OPERATION -> asin(arg)
+        TrigonometricOperations.ATAN_OPERATION -> atan(arg)
+        HyperbolicOperations.COSH_OPERATION -> cosh(arg)
+        HyperbolicOperations.SINH_OPERATION -> sinh(arg)
+        HyperbolicOperations.TANH_OPERATION -> tanh(arg)
+        HyperbolicOperations.ACOSH_OPERATION -> acosh(arg)
+        HyperbolicOperations.ASINH_OPERATION -> asinh(arg)
+        HyperbolicOperations.ATANH_OPERATION -> atanh(arg)
+        PowerOperations.SQRT_OPERATION -> sqrt(arg)
+        ExponentialOperations.EXP_OPERATION -> exp(arg)
+        ExponentialOperations.LN_OPERATION -> ln(arg)
+        else -> super.unaryOperation(operation, arg)
+    }
+}
+
+/**
+ * Advanced Number-like field that implements basic operations.
+ */
+public interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T> {
+    public override fun sinh(arg: T): T = (exp(arg) - exp(-arg)) / 2
+    public override fun cosh(arg: T): T = (exp(arg) + exp(-arg)) / 2
+    public override fun tanh(arg: T): T = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg))
+    public override fun asinh(arg: T): T = ln(sqrt(arg * arg + one) + arg)
+    public override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one)))
+    public override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2
+
+    public override fun rightSideNumberOperation(operation: String, left: T, right: Number): T = when (operation) {
+        PowerOperations.POW_OPERATION -> power(left, right)
+        else -> super.rightSideNumberOperation(operation, left, right)
+    }
+}
+
+/**
+ * Real field element wrapping double.
+ *
+ * @property value the [Double] value wrapped by this [Real].
+ *
+ * TODO inline does not work due to compiler bug. Waiting for fix for KT-27586
+ */
+public inline class Real(public val value: Double) : FieldElement<Double, Real, RealField> {
+    public override val context: RealField
+        get() = RealField
+
+    public override fun unwrap(): Double = value
+    public override fun Double.wrap(): Real = Real(value)
+
+    public companion object
+}
+
+/**
+ * A field for [Double] without boxing. Does not produce appropriate field element.
+ */
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public object RealField : ExtendedField<Double>, Norm<Double, Double> {
+    public override val zero: Double
+        get() = 0.0
+
+    public override val one: Double
+        get() = 1.0
+
+    public override fun binaryOperation(operation: String, left: Double, right: Double): Double = when (operation) {
+        PowerOperations.POW_OPERATION -> left pow right
+        else -> super.binaryOperation(operation, left, right)
+    }
+
+    public override inline fun add(a: Double, b: Double): Double = a + b
+    public override inline fun multiply(a: Double, k: Number): Double = a * k.toDouble()
+
+    public override inline fun multiply(a: Double, b: Double): Double = a * b
+
+    public override inline fun divide(a: Double, b: Double): Double = a / b
+
+    public override inline fun sin(arg: Double): Double = kotlin.math.sin(arg)
+    public override inline fun cos(arg: Double): Double = kotlin.math.cos(arg)
+    public override inline fun tan(arg: Double): Double = kotlin.math.tan(arg)
+    public override inline fun acos(arg: Double): Double = kotlin.math.acos(arg)
+    public override inline fun asin(arg: Double): Double = kotlin.math.asin(arg)
+    public override inline fun atan(arg: Double): Double = kotlin.math.atan(arg)
+
+    public override inline fun sinh(arg: Double): Double = kotlin.math.sinh(arg)
+    public override inline fun cosh(arg: Double): Double = kotlin.math.cosh(arg)
+    public override inline fun tanh(arg: Double): Double = kotlin.math.tanh(arg)
+    public override inline fun asinh(arg: Double): Double = kotlin.math.asinh(arg)
+    public override inline fun acosh(arg: Double): Double = kotlin.math.acosh(arg)
+    public override inline fun atanh(arg: Double): Double = kotlin.math.atanh(arg)
+
+    public override inline fun power(arg: Double, pow: Number): Double = arg.kpow(pow.toDouble())
+    public override inline fun exp(arg: Double): Double = kotlin.math.exp(arg)
+    public override inline fun ln(arg: Double): Double = kotlin.math.ln(arg)
+
+    public override inline fun norm(arg: Double): Double = abs(arg)
+
+    public override inline fun Double.unaryMinus(): Double = -this
+    public override inline fun Double.plus(b: Double): Double = this + b
+    public override inline fun Double.minus(b: Double): Double = this - b
+    public override inline fun Double.times(b: Double): Double = this * b
+    public override inline fun Double.div(b: Double): Double = this / b
+}
+
+/**
+ * A field for [Float] without boxing. Does not produce appropriate field element.
+ */
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public object FloatField : ExtendedField<Float>, Norm<Float, Float> {
+    public override val zero: Float
+        get() = 0.0f
+
+    public override val one: Float
+        get() = 1.0f
+
+    public override fun binaryOperation(operation: String, left: Float, right: Float): Float = when (operation) {
+        PowerOperations.POW_OPERATION -> left pow right
+        else -> super.binaryOperation(operation, left, right)
+    }
+
+    public override inline fun add(a: Float, b: Float): Float = a + b
+    public override inline fun multiply(a: Float, k: Number): Float = a * k.toFloat()
+
+    public override inline fun multiply(a: Float, b: Float): Float = a * b
+
+    public override inline fun divide(a: Float, b: Float): Float = a / b
+
+    public override inline fun sin(arg: Float): Float = kotlin.math.sin(arg)
+    public override inline fun cos(arg: Float): Float = kotlin.math.cos(arg)
+    public override inline fun tan(arg: Float): Float = kotlin.math.tan(arg)
+    public override inline fun acos(arg: Float): Float = kotlin.math.acos(arg)
+    public override inline fun asin(arg: Float): Float = kotlin.math.asin(arg)
+    public override inline fun atan(arg: Float): Float = kotlin.math.atan(arg)
+
+    public override inline fun sinh(arg: Float): Float = kotlin.math.sinh(arg)
+    public override inline fun cosh(arg: Float): Float = kotlin.math.cosh(arg)
+    public override inline fun tanh(arg: Float): Float = kotlin.math.tanh(arg)
+    public override inline fun asinh(arg: Float): Float = kotlin.math.asinh(arg)
+    public override inline fun acosh(arg: Float): Float = kotlin.math.acosh(arg)
+    public override inline fun atanh(arg: Float): Float = kotlin.math.atanh(arg)
+
+    public override inline fun power(arg: Float, pow: Number): Float = arg.kpow(pow.toFloat())
+    public override inline fun exp(arg: Float): Float = kotlin.math.exp(arg)
+    public override inline fun ln(arg: Float): Float = kotlin.math.ln(arg)
+
+    public override inline fun norm(arg: Float): Float = abs(arg)
+
+    public override inline fun Float.unaryMinus(): Float = -this
+    public override inline fun Float.plus(b: Float): Float = this + b
+    public override inline fun Float.minus(b: Float): Float = this - b
+    public override inline fun Float.times(b: Float): Float = this * b
+    public override inline fun Float.div(b: Float): Float = this / b
+}
+
+/**
+ * A field for [Int] without boxing. Does not produce corresponding ring element.
+ */
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public object IntRing : Ring<Int>, Norm<Int, Int> {
+    public override val zero: Int
+        get() = 0
+
+    public override val one: Int
+        get() = 1
+
+    public override inline fun add(a: Int, b: Int): Int = a + b
+    public override inline fun multiply(a: Int, k: Number): Int = k.toInt() * a
+
+    public override inline fun multiply(a: Int, b: Int): Int = a * b
+
+    public override inline fun norm(arg: Int): Int = abs(arg)
+
+    public override inline fun Int.unaryMinus(): Int = -this
+    public override inline fun Int.plus(b: Int): Int = this + b
+    public override inline fun Int.minus(b: Int): Int = this - b
+    public override inline fun Int.times(b: Int): Int = this * b
+}
+
+/**
+ * A field for [Short] without boxing. Does not produce appropriate ring element.
+ */
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public object ShortRing : Ring<Short>, Norm<Short, Short> {
+    public override val zero: Short
+        get() = 0
+
+    public override val one: Short
+        get() = 1
+
+    public override inline fun add(a: Short, b: Short): Short = (a + b).toShort()
+    public override inline fun multiply(a: Short, k: Number): Short = (a * k.toShort()).toShort()
+
+    public override inline fun multiply(a: Short, b: Short): Short = (a * b).toShort()
+
+    public override fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort()
+
+    public override inline fun Short.unaryMinus(): Short = (-this).toShort()
+    public override inline fun Short.plus(b: Short): Short = (this + b).toShort()
+    public override inline fun Short.minus(b: Short): Short = (this - b).toShort()
+    public override inline fun Short.times(b: Short): Short = (this * b).toShort()
+}
+
+/**
+ * A field for [Byte] without boxing. Does not produce appropriate ring element.
+ */
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public object ByteRing : Ring<Byte>, Norm<Byte, Byte> {
+    public override val zero: Byte
+        get() = 0
+
+    public override val one: Byte
+        get() = 1
+
+    public override inline fun add(a: Byte, b: Byte): Byte = (a + b).toByte()
+    public override inline fun multiply(a: Byte, k: Number): Byte = (a * k.toByte()).toByte()
+
+    public override inline fun multiply(a: Byte, b: Byte): Byte = (a * b).toByte()
+
+    public override fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte()
+
+    public override inline fun Byte.unaryMinus(): Byte = (-this).toByte()
+    public override inline fun Byte.plus(b: Byte): Byte = (this + b).toByte()
+    public override inline fun Byte.minus(b: Byte): Byte = (this - b).toByte()
+    public override inline fun Byte.times(b: Byte): Byte = (this * b).toByte()
+}
+
+/**
+ * A field for [Double] without boxing. Does not produce appropriate ring element.
+ */
+@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public object LongRing : Ring<Long>, Norm<Long, Long> {
+    public override val zero: Long
+        get() = 0
+
+    public override val one: Long
+        get() = 1
+
+    public override inline fun add(a: Long, b: Long): Long = a + b
+    public override inline fun multiply(a: Long, k: Number): Long = a * k.toLong()
+
+    public override inline fun multiply(a: Long, b: Long): Long = a * b
+
+    public override fun norm(arg: Long): Long = abs(arg)
+
+    public override inline fun Long.unaryMinus(): Long = (-this)
+    public override inline fun Long.plus(b: Long): Long = (this + b)
+    public override inline fun Long.minus(b: Long): Long = (this - b)
+    public override inline fun Long.times(b: Long): Long = (this * b)
+}
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/OptionalOperations.kt
similarity index 52%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/operations/OptionalOperations.kt
index 1dac649aa..f31d61ae1 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/OptionalOperations.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/operations/OptionalOperations.kt
@@ -1,234 +1,234 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 /**
  * A container for trigonometric operations for specific type.
  *
  * @param T the type of element of this structure.
  */
-interface TrigonometricOperations<T> : Algebra<T> {
+public interface TrigonometricOperations<T> : Algebra<T> {
     /**
      * Computes the sine of [arg].
      */
-    fun sin(arg: T): T
+    public fun sin(arg: T): T
 
     /**
      * Computes the cosine of [arg].
      */
-    fun cos(arg: T): T
+    public fun cos(arg: T): T
 
     /**
      * Computes the tangent of [arg].
      */
-    fun tan(arg: T): T
+    public fun tan(arg: T): T
 
     /**
      * Computes the inverse sine of [arg].
      */
-    fun asin(arg: T): T
+    public fun asin(arg: T): T
 
     /**
      * Computes the inverse cosine of [arg].
      */
-    fun acos(arg: T): T
+    public fun acos(arg: T): T
 
     /**
      * Computes the inverse tangent of [arg].
      */
-    fun atan(arg: T): T
+    public fun atan(arg: T): T
 
-    companion object {
+    public companion object {
         /**
          * The identifier of sine.
          */
-        const val SIN_OPERATION: String = "sin"
+        public const val SIN_OPERATION: String = "sin"
 
         /**
          * The identifier of cosine.
          */
-        const val COS_OPERATION: String = "cos"
+        public const val COS_OPERATION: String = "cos"
 
         /**
          * The identifier of tangent.
          */
-        const val TAN_OPERATION: String = "tan"
+        public const val TAN_OPERATION: String = "tan"
 
         /**
          * The identifier of inverse sine.
          */
-        const val ASIN_OPERATION: String = "asin"
+        public const val ASIN_OPERATION: String = "asin"
 
         /**
          * The identifier of inverse cosine.
          */
-        const val ACOS_OPERATION: String = "acos"
+        public const val ACOS_OPERATION: String = "acos"
 
         /**
          * The identifier of inverse tangent.
          */
-        const val ATAN_OPERATION: String = "atan"
+        public const val ATAN_OPERATION: String = "atan"
     }
 }
 
 /**
  * Computes the sine of [arg].
  */
-fun <T : MathElement<out TrigonometricOperations<T>>> sin(arg: T): T = arg.context.sin(arg)
+public fun <T : MathElement<out TrigonometricOperations<T>>> sin(arg: T): T = arg.context.sin(arg)
 
 /**
  * Computes the cosine of [arg].
  */
-fun <T : MathElement<out TrigonometricOperations<T>>> cos(arg: T): T = arg.context.cos(arg)
+public fun <T : MathElement<out TrigonometricOperations<T>>> cos(arg: T): T = arg.context.cos(arg)
 
 /**
  * Computes the tangent of [arg].
  */
-fun <T : MathElement<out TrigonometricOperations<T>>> tan(arg: T): T = arg.context.tan(arg)
+public fun <T : MathElement<out TrigonometricOperations<T>>> tan(arg: T): T = arg.context.tan(arg)
 
 /**
  * Computes the inverse sine of [arg].
  */
-fun <T : MathElement<out TrigonometricOperations<T>>> asin(arg: T): T = arg.context.asin(arg)
+public fun <T : MathElement<out TrigonometricOperations<T>>> asin(arg: T): T = arg.context.asin(arg)
 
 /**
  * Computes the inverse cosine of [arg].
  */
-fun <T : MathElement<out TrigonometricOperations<T>>> acos(arg: T): T = arg.context.acos(arg)
+public fun <T : MathElement<out TrigonometricOperations<T>>> acos(arg: T): T = arg.context.acos(arg)
 
 /**
  * Computes the inverse tangent of [arg].
  */
-fun <T : MathElement<out TrigonometricOperations<T>>> atan(arg: T): T = arg.context.atan(arg)
+public fun <T : MathElement<out TrigonometricOperations<T>>> atan(arg: T): T = arg.context.atan(arg)
 
 /**
  * A container for hyperbolic trigonometric operations for specific type.
  *
  * @param T the type of element of this structure.
  */
-interface HyperbolicOperations<T> : Algebra<T> {
+public interface HyperbolicOperations<T> : Algebra<T> {
     /**
      * Computes the hyperbolic sine of [arg].
      */
-    fun sinh(arg: T): T
+    public fun sinh(arg: T): T
 
     /**
      * Computes the hyperbolic cosine of [arg].
      */
-    fun cosh(arg: T): T
+    public fun cosh(arg: T): T
 
     /**
      * Computes the hyperbolic tangent of [arg].
      */
-    fun tanh(arg: T): T
+    public fun tanh(arg: T): T
 
     /**
      * Computes the inverse hyperbolic sine of [arg].
      */
-    fun asinh(arg: T): T
+    public fun asinh(arg: T): T
 
     /**
      * Computes the inverse hyperbolic cosine of [arg].
      */
-    fun acosh(arg: T): T
+    public fun acosh(arg: T): T
 
     /**
      * Computes the inverse hyperbolic tangent of [arg].
      */
-    fun atanh(arg: T): T
+    public fun atanh(arg: T): T
 
-    companion object {
+    public companion object {
         /**
          * The identifier of hyperbolic sine.
          */
-        const val SINH_OPERATION: String = "sinh"
+        public const val SINH_OPERATION: String = "sinh"
 
         /**
          * The identifier of hyperbolic cosine.
          */
-        const val COSH_OPERATION: String = "cosh"
+        public const val COSH_OPERATION: String = "cosh"
 
         /**
          * The identifier of hyperbolic tangent.
          */
-        const val TANH_OPERATION: String = "tanh"
+        public const val TANH_OPERATION: String = "tanh"
 
         /**
          * The identifier of inverse hyperbolic sine.
          */
-        const val ASINH_OPERATION: String = "asinh"
+        public const val ASINH_OPERATION: String = "asinh"
 
         /**
          * The identifier of inverse hyperbolic cosine.
          */
-        const val ACOSH_OPERATION: String = "acosh"
+        public const val ACOSH_OPERATION: String = "acosh"
 
         /**
          * The identifier of inverse hyperbolic tangent.
          */
-        const val ATANH_OPERATION: String = "atanh"
+        public const val ATANH_OPERATION: String = "atanh"
     }
 }
 
 /**
  * Computes the hyperbolic sine of [arg].
  */
-fun <T : MathElement<out HyperbolicOperations<T>>> sinh(arg: T): T = arg.context.sinh(arg)
+public fun <T : MathElement<out HyperbolicOperations<T>>> sinh(arg: T): T = arg.context.sinh(arg)
 
 /**
  * Computes the hyperbolic cosine of [arg].
  */
-fun <T : MathElement<out HyperbolicOperations<T>>> cosh(arg: T): T = arg.context.cosh(arg)
+public fun <T : MathElement<out HyperbolicOperations<T>>> cosh(arg: T): T = arg.context.cosh(arg)
 
 /**
  * Computes the hyperbolic tangent of [arg].
  */
-fun <T : MathElement<out HyperbolicOperations<T>>> tanh(arg: T): T = arg.context.tanh(arg)
+public fun <T : MathElement<out HyperbolicOperations<T>>> tanh(arg: T): T = arg.context.tanh(arg)
 
 /**
  * Computes the inverse hyperbolic sine of [arg].
  */
-fun <T : MathElement<out HyperbolicOperations<T>>> asinh(arg: T): T = arg.context.asinh(arg)
+public fun <T : MathElement<out HyperbolicOperations<T>>> asinh(arg: T): T = arg.context.asinh(arg)
 
 /**
  * Computes the inverse hyperbolic cosine of [arg].
  */
-fun <T : MathElement<out HyperbolicOperations<T>>> acosh(arg: T): T = arg.context.acosh(arg)
+public fun <T : MathElement<out HyperbolicOperations<T>>> acosh(arg: T): T = arg.context.acosh(arg)
 
 /**
  * Computes the inverse hyperbolic tangent of [arg].
  */
-fun <T : MathElement<out HyperbolicOperations<T>>> atanh(arg: T): T = arg.context.atanh(arg)
+public fun <T : MathElement<out HyperbolicOperations<T>>> atanh(arg: T): T = arg.context.atanh(arg)
 
 /**
  * A context extension to include power operations based on exponentiation.
  *
  * @param T the type of element of this structure.
  */
-interface PowerOperations<T> : Algebra<T> {
+public interface PowerOperations<T> : Algebra<T> {
     /**
      * Raises [arg] to the power [pow].
      */
-    fun power(arg: T, pow: Number): T
+    public fun power(arg: T, pow: Number): T
 
     /**
      * Computes the square root of the value [arg].
      */
-    fun sqrt(arg: T): T = power(arg, 0.5)
+    public fun sqrt(arg: T): T = power(arg, 0.5)
 
     /**
      * Raises this value to the power [pow].
      */
-    infix fun T.pow(pow: Number): T = power(this, pow)
+    public infix fun T.pow(pow: Number): T = power(this, pow)
 
-    companion object {
+    public companion object {
         /**
          * The identifier of exponentiation.
          */
-        const val POW_OPERATION: String = "pow"
+        public const val POW_OPERATION: String = "pow"
 
         /**
          * The identifier of square root.
          */
-        const val SQRT_OPERATION: String = "sqrt"
+        public const val SQRT_OPERATION: String = "sqrt"
     }
 }
 
@@ -239,56 +239,56 @@ interface PowerOperations<T> : Algebra<T> {
  * @param power the exponent.
  * @return the base raised to the power.
  */
-infix fun <T : MathElement<out PowerOperations<T>>> T.pow(power: Double): T = context.power(this, power)
+public infix fun <T : MathElement<out PowerOperations<T>>> T.pow(power: Double): T = context.power(this, power)
 
 /**
  * Computes the square root of the value [arg].
  */
-fun <T : MathElement<out PowerOperations<T>>> sqrt(arg: T): T = arg pow 0.5
+public fun <T : MathElement<out PowerOperations<T>>> sqrt(arg: T): T = arg pow 0.5
 
 /**
  * Computes the square of the value [arg].
  */
-fun <T : MathElement<out PowerOperations<T>>> sqr(arg: T): T = arg pow 2.0
+public fun <T : MathElement<out PowerOperations<T>>> sqr(arg: T): T = arg pow 2.0
 
 /**
  * A container for operations related to `exp` and `ln` functions.
  *
  * @param T the type of element of this structure.
  */
-interface ExponentialOperations<T> : Algebra<T> {
+public interface ExponentialOperations<T> : Algebra<T> {
     /**
      * Computes Euler's number `e` raised to the power of the value [arg].
      */
-    fun exp(arg: T): T
+    public fun exp(arg: T): T
 
     /**
      * Computes the natural logarithm (base `e`) of the value [arg].
      */
-    fun ln(arg: T): T
+    public fun ln(arg: T): T
 
-    companion object {
+    public companion object {
         /**
          * The identifier of exponential function.
          */
-        const val EXP_OPERATION: String = "exp"
+        public const val EXP_OPERATION: String = "exp"
 
         /**
          * The identifier of natural logarithm.
          */
-        const val LN_OPERATION: String = "ln"
+        public const val LN_OPERATION: String = "ln"
     }
 }
 
 /**
  * The identifier of exponential function.
  */
-fun <T : MathElement<out ExponentialOperations<T>>> exp(arg: T): T = arg.context.exp(arg)
+public fun <T : MathElement<out ExponentialOperations<T>>> exp(arg: T): T = arg.context.exp(arg)
 
 /**
  * The identifier of natural logarithm.
  */
-fun <T : MathElement<out ExponentialOperations<T>>> ln(arg: T): T = arg.context.ln(arg)
+public fun <T : MathElement<out ExponentialOperations<T>>> ln(arg: T): T = arg.context.ln(arg)
 
 /**
  * A container for norm functional on element.
@@ -296,14 +296,14 @@ fun <T : MathElement<out ExponentialOperations<T>>> ln(arg: T): T = arg.context.
  * @param T the type of element having norm defined.
  * @param R the type of norm.
  */
-interface Norm<in T : Any, out R> {
+public interface Norm<in T : Any, out R> {
     /**
      * Computes the norm of [arg] (i.e. absolute value or vector length).
      */
-    fun norm(arg: T): R
+    public fun norm(arg: T): R
 }
 
 /**
  * Computes the norm of [arg] (i.e. absolute value or vector length).
  */
-fun <T : MathElement<out Norm<T, R>>, R> norm(arg: T): R = arg.context.norm(arg)
+public fun <T : MathElement<out Norm<T, R>>, R> norm(arg: T): R = arg.context.norm(arg)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDField.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDField.kt
similarity index 63%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDField.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDField.kt
index be71645d1..c3c859f7a 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDField.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDField.kt
@@ -1,30 +1,30 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.FieldElement
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.FieldElement
 
-class BoxingNDField<T, F : Field<T>>(
-    override val shape: IntArray,
-    override val elementContext: F,
-    val bufferFactory: BufferFactory<T>
+public class BoxingNDField<T, F : Field<T>>(
+    public override val shape: IntArray,
+    public override val elementContext: F,
+    public val bufferFactory: BufferFactory<T>
 ) : BufferedNDField<T, F> {
-    override val zero: BufferedNDFieldElement<T, F> by lazy { produce { zero } }
-    override val one: BufferedNDFieldElement<T, F> by lazy { produce { one } }
-    override val strides: Strides = DefaultStrides(shape)
+    public override val zero: BufferedNDFieldElement<T, F> by lazy { produce { zero } }
+    public override val one: BufferedNDFieldElement<T, F> by lazy { produce { one } }
+    public override val strides: Strides = DefaultStrides(shape)
 
-    fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer<T> =
+    public fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer<T> =
         bufferFactory(size, initializer)
 
-    override fun check(vararg elements: NDBuffer<T>) {
+    public override fun check(vararg elements: NDBuffer<T>) {
         check(elements.all { it.strides == strides }) { "Element strides are not the same as context strides" }
     }
 
-    override fun produce(initializer: F.(IntArray) -> T): BufferedNDFieldElement<T, F> =
+    public override fun produce(initializer: F.(IntArray) -> T): BufferedNDFieldElement<T, F> =
         BufferedNDFieldElement(
             this,
             buildBuffer(strides.linearSize) { offset -> elementContext.initializer(strides.index(offset)) })
 
-    override fun map(arg: NDBuffer<T>, transform: F.(T) -> T): BufferedNDFieldElement<T, F> {
+    public override fun map(arg: NDBuffer<T>, transform: F.(T) -> T): BufferedNDFieldElement<T, F> {
         check(arg)
 
         return BufferedNDFieldElement(
@@ -36,7 +36,7 @@ class BoxingNDField<T, F : Field<T>>(
 
     }
 
-    override fun mapIndexed(
+    public override fun mapIndexed(
         arg: NDBuffer<T>,
         transform: F.(index: IntArray, T) -> T
     ): BufferedNDFieldElement<T, F> {
@@ -55,7 +55,7 @@ class BoxingNDField<T, F : Field<T>>(
 //        return BufferedNDFieldElement(this, buffer)
     }
 
-    override fun combine(
+    public override fun combine(
         a: NDBuffer<T>,
         b: NDBuffer<T>,
         transform: F.(T, T) -> T
@@ -66,11 +66,11 @@ class BoxingNDField<T, F : Field<T>>(
             buildBuffer(strides.linearSize) { offset -> elementContext.transform(a.buffer[offset], b.buffer[offset]) })
     }
 
-    override fun NDBuffer<T>.toElement(): FieldElement<NDBuffer<T>, *, out BufferedNDField<T, F>> =
+    public override fun NDBuffer<T>.toElement(): FieldElement<NDBuffer<T>, *, out BufferedNDField<T, F>> =
         BufferedNDFieldElement(this@BoxingNDField, buffer)
 }
 
-inline fun <T : Any, F : Field<T>, R> F.nd(
+public inline fun <T : Any, F : Field<T>, R> F.nd(
     noinline bufferFactory: BufferFactory<T>,
     vararg shape: Int,
     action: NDField<T, F, *>.() -> R
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDRing.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDRing.kt
similarity index 87%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDRing.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDRing.kt
index 91b945e79..461b0387c 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BoxingNDRing.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BoxingNDRing.kt
@@ -1,18 +1,18 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.RingElement
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.RingElement
 
-class BoxingNDRing<T, R : Ring<T>>(
+public class BoxingNDRing<T, R : Ring<T>>(
     override val shape: IntArray,
     override val elementContext: R,
-    val bufferFactory: BufferFactory<T>
+    public val bufferFactory: BufferFactory<T>
 ) : BufferedNDRing<T, R> {
     override val strides: Strides = DefaultStrides(shape)
     override val zero: BufferedNDRingElement<T, R> by lazy { produce { zero } }
     override val one: BufferedNDRingElement<T, R> by lazy { produce { one } }
 
-    fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer<T> = bufferFactory(size, initializer)
+    public fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer<T> = bufferFactory(size, initializer)
 
     override fun check(vararg elements: NDBuffer<T>) {
         require(elements.all { it.strides == strides }) { "Element strides are not the same as context strides" }
@@ -59,6 +59,7 @@ class BoxingNDRing<T, R : Ring<T>>(
         transform: R.(T, T) -> T
     ): BufferedNDRingElement<T, R> {
         check(a, b)
+
         return BufferedNDRingElement(
             this,
             buildBuffer(strides.linearSize) { offset -> elementContext.transform(a.buffer[offset], b.buffer[offset]) })
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferAccessor2D.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferAccessor2D.kt
similarity index 53%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferAccessor2D.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferAccessor2D.kt
index 2c3d69094..00fc4aef0 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferAccessor2D.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferAccessor2D.kt
@@ -1,28 +1,27 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
 import kotlin.reflect.KClass
 
 /**
  * A context that allows to operate on a [MutableBuffer] as on 2d array
  */
-class BufferAccessor2D<T : Any>(val type: KClass<T>, val rowNum: Int, val colNum: Int) {
-    operator fun Buffer<T>.get(i: Int, j: Int): T = get(i + colNum * j)
+public class BufferAccessor2D<T : Any>(public val type: KClass<T>, public val rowNum: Int, public val colNum: Int) {
+    public operator fun Buffer<T>.get(i: Int, j: Int): T = get(i + colNum * j)
 
-    operator fun MutableBuffer<T>.set(i: Int, j: Int, value: T) {
+    public operator fun MutableBuffer<T>.set(i: Int, j: Int, value: T) {
         set(i + colNum * j, value)
     }
 
-    inline fun create(init: (i: Int, j: Int) -> T): MutableBuffer<T> =
+    public inline fun create(init: (i: Int, j: Int) -> T): MutableBuffer<T> =
         MutableBuffer.auto(type, rowNum * colNum) { offset -> init(offset / colNum, offset % colNum) }
 
-    fun create(mat: Structure2D<T>): MutableBuffer<T> = create { i, j -> mat[i, j] }
+    public fun create(mat: Structure2D<T>): MutableBuffer<T> = create { i, j -> mat[i, j] }
 
     //TODO optimize wrapper
-    fun MutableBuffer<T>.collect(): Structure2D<T> =
+    public fun MutableBuffer<T>.collect(): Structure2D<T> =
         NDStructure.auto(type, rowNum, colNum) { (i, j) -> get(i, j) }.as2D()
 
-
-    inner class Row(val buffer: MutableBuffer<T>, val rowIndex: Int) : MutableBuffer<T> {
+    public inner class Row(public val buffer: MutableBuffer<T>, public val rowIndex: Int) : MutableBuffer<T> {
         override val size: Int get() = colNum
 
         override operator fun get(index: Int): T = buffer[rowIndex, index]
@@ -39,5 +38,5 @@ class BufferAccessor2D<T : Any>(val type: KClass<T>, val rowNum: Int, val colNum
     /**
      * Get row
      */
-    fun MutableBuffer<T>.row(i: Int): Row = Row(this, i)
+    public fun MutableBuffer<T>.row(i: Int): Row = Row(this, i)
 }
diff --git a/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDAlgebra.kt
new file mode 100644
index 000000000..66b4f19e1
--- /dev/null
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDAlgebra.kt
@@ -0,0 +1,41 @@
+package kscience.kmath.structures
+
+import kscience.kmath.operations.*
+
+public interface BufferedNDAlgebra<T, C> : NDAlgebra<T, C, NDBuffer<T>> {
+    public val strides: Strides
+
+    public override fun check(vararg elements: NDBuffer<T>): Unit =
+        require(elements.all { it.strides == strides }) { ("Strides mismatch") }
+
+    /**
+     * Convert any [NDStructure] to buffered structure using strides from this context.
+     * If the structure is already [NDBuffer], conversion is free. If not, it could be expensive because iteration over
+     * indices.
+     *
+     * If the argument is [NDBuffer] with different strides structure, the new element will be produced.
+     */
+    public fun NDStructure<T>.toBuffer(): NDBuffer<T> =
+        if (this is NDBuffer<T> && this.strides == this@BufferedNDAlgebra.strides)
+            this
+        else
+            produce { index -> this@toBuffer[index] }
+
+    /**
+     * Convert a buffer to element of this algebra
+     */
+    public fun NDBuffer<T>.toElement(): MathElement<out BufferedNDAlgebra<T, C>>
+}
+
+
+public interface BufferedNDSpace<T, S : Space<T>> : NDSpace<T, S, NDBuffer<T>>, BufferedNDAlgebra<T, S> {
+    public override fun NDBuffer<T>.toElement(): SpaceElement<NDBuffer<T>, *, out BufferedNDSpace<T, S>>
+}
+
+public interface BufferedNDRing<T, R : Ring<T>> : NDRing<T, R, NDBuffer<T>>, BufferedNDSpace<T, R> {
+    override fun NDBuffer<T>.toElement(): RingElement<NDBuffer<T>, *, out BufferedNDRing<T, R>>
+}
+
+public interface BufferedNDField<T, F : Field<T>> : NDField<T, F, NDBuffer<T>>, BufferedNDRing<T, F> {
+    override fun NDBuffer<T>.toElement(): FieldElement<NDBuffer<T>, *, out BufferedNDField<T, F>>
+}
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDElement.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDElement.kt
similarity index 70%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDElement.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDElement.kt
index 20e34fadd..d53702566 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDElement.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/BufferedNDElement.kt
@@ -1,11 +1,11 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.*
+import kscience.kmath.operations.*
 
 /**
  * Base class for an element with context, containing strides
  */
-abstract class BufferedNDElement<T, C> : NDBuffer<T>(), NDElement<T, C, NDBuffer<T>> {
+public abstract class BufferedNDElement<T, C> : NDBuffer<T>(), NDElement<T, C, NDBuffer<T>> {
     abstract override val context: BufferedNDAlgebra<T, C>
 
     override val strides: Strides get() = context.strides
@@ -13,7 +13,7 @@ abstract class BufferedNDElement<T, C> : NDBuffer<T>(), NDElement<T, C, NDBuffer
     override val shape: IntArray get() = context.shape
 }
 
-class BufferedNDSpaceElement<T, S : Space<T>>(
+public class BufferedNDSpaceElement<T, S : Space<T>>(
     override val context: BufferedNDSpace<T, S>,
     override val buffer: Buffer<T>
 ) : BufferedNDElement<T, S>(), SpaceElement<NDBuffer<T>, BufferedNDSpaceElement<T, S>, BufferedNDSpace<T, S>> {
@@ -26,7 +26,7 @@ class BufferedNDSpaceElement<T, S : Space<T>>(
     }
 }
 
-class BufferedNDRingElement<T, R : Ring<T>>(
+public class BufferedNDRingElement<T, R : Ring<T>>(
     override val context: BufferedNDRing<T, R>,
     override val buffer: Buffer<T>
 ) : BufferedNDElement<T, R>(), RingElement<NDBuffer<T>, BufferedNDRingElement<T, R>, BufferedNDRing<T, R>> {
@@ -38,7 +38,7 @@ class BufferedNDRingElement<T, R : Ring<T>>(
     }
 }
 
-class BufferedNDFieldElement<T, F : Field<T>>(
+public class BufferedNDFieldElement<T, F : Field<T>>(
     override val context: BufferedNDField<T, F>,
     override val buffer: Buffer<T>
 ) : BufferedNDElement<T, F>(), FieldElement<NDBuffer<T>, BufferedNDFieldElement<T, F>, BufferedNDField<T, F>> {
@@ -54,7 +54,7 @@ class BufferedNDFieldElement<T, F : Field<T>>(
 /**
  * Element by element application of any operation on elements to the whole array. Just like in numpy.
  */
-operator fun <T : Any, F : Field<T>> Function1<T, T>.invoke(ndElement: BufferedNDElement<T, F>): MathElement<out BufferedNDAlgebra<T, F>> =
+public operator fun <T : Any, F : Field<T>> Function1<T, T>.invoke(ndElement: BufferedNDElement<T, F>): MathElement<out BufferedNDAlgebra<T, F>> =
     ndElement.context.run { map(ndElement) { invoke(it) }.toElement() }
 
 /* plus and minus */
@@ -62,13 +62,13 @@ operator fun <T : Any, F : Field<T>> Function1<T, T>.invoke(ndElement: BufferedN
 /**
  * Summation operation for [BufferedNDElement] and single element
  */
-operator fun <T : Any, F : Space<T>> BufferedNDElement<T, F>.plus(arg: T): NDElement<T, F, NDBuffer<T>> =
+public operator fun <T : Any, F : Space<T>> BufferedNDElement<T, F>.plus(arg: T): NDElement<T, F, NDBuffer<T>> =
     context.map(this) { it + arg }.wrap()
 
 /**
  * Subtraction operation between [BufferedNDElement] and single element
  */
-operator fun <T : Any, F : Space<T>> BufferedNDElement<T, F>.minus(arg: T): NDElement<T, F, NDBuffer<T>> =
+public operator fun <T : Any, F : Space<T>> BufferedNDElement<T, F>.minus(arg: T): NDElement<T, F, NDBuffer<T>> =
     context.map(this) { it - arg }.wrap()
 
 /* prod and div */
@@ -76,11 +76,11 @@ operator fun <T : Any, F : Space<T>> BufferedNDElement<T, F>.minus(arg: T): NDEl
 /**
  * Product operation for [BufferedNDElement] and single element
  */
-operator fun <T : Any, F : Ring<T>> BufferedNDElement<T, F>.times(arg: T): NDElement<T, F, NDBuffer<T>> =
+public operator fun <T : Any, F : Ring<T>> BufferedNDElement<T, F>.times(arg: T): NDElement<T, F, NDBuffer<T>> =
     context.map(this) { it * arg }.wrap()
 
 /**
  * Division operation between [BufferedNDElement] and single element
  */
-operator fun <T : Any, F : Field<T>> BufferedNDElement<T, F>.div(arg: T): NDElement<T, F, NDBuffer<T>> =
+public operator fun <T : Any, F : Field<T>> BufferedNDElement<T, F>.div(arg: T): NDElement<T, F, NDBuffer<T>> =
     context.map(this) { it / arg }.wrap()
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt
similarity index 70%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt
index 1ea8ca3d5..53587e503 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Buffers.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Buffers.kt
@@ -1,8 +1,7 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.complex
-import kotlin.contracts.contract
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.complex
 import kotlin.reflect.KClass
 
 /**
@@ -10,44 +9,44 @@ import kotlin.reflect.KClass
  *
  * @param T the type of buffer.
  */
-typealias BufferFactory<T> = (Int, (Int) -> T) -> Buffer<T>
+public typealias BufferFactory<T> = (Int, (Int) -> T) -> Buffer<T>
 
 /**
  * Function that produces [MutableBuffer] from its size and function that supplies values.
  *
  * @param T the type of buffer.
  */
-typealias MutableBufferFactory<T> = (Int, (Int) -> T) -> MutableBuffer<T>
+public typealias MutableBufferFactory<T> = (Int, (Int) -> T) -> MutableBuffer<T>
 
 /**
  * A generic immutable random-access structure for both primitives and objects.
  *
  * @param T the type of elements contained in the buffer.
  */
-interface Buffer<T> {
+public interface Buffer<T> {
     /**
      * The size of this buffer.
      */
-    val size: Int
+    public val size: Int
 
     /**
      * Gets element at given index.
      */
-    operator fun get(index: Int): T
+    public operator fun get(index: Int): T
 
     /**
      * Iterates over all elements.
      */
-    operator fun iterator(): Iterator<T>
+    public operator fun iterator(): Iterator<T>
 
     /**
      * Checks content equality with another buffer.
      */
-    fun contentEquals(other: Buffer<*>): Boolean =
+    public fun contentEquals(other: Buffer<*>): Boolean =
         asSequence().mapIndexed { index, value -> value == other[index] }.all { it }
 
-    companion object {
-        inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer {
+    public companion object {
+        public inline fun real(size: Int, initializer: (Int) -> Double): RealBuffer {
             val array = DoubleArray(size) { initializer(it) }
             return RealBuffer(array)
         }
@@ -55,10 +54,11 @@ interface Buffer<T> {
         /**
          * Create a boxing buffer of given type
          */
-        inline fun <T> boxing(size: Int, initializer: (Int) -> T): Buffer<T> = ListBuffer(List(size, initializer))
+        public inline fun <T> boxing(size: Int, initializer: (Int) -> T): Buffer<T> =
+            ListBuffer(List(size, initializer))
 
         @Suppress("UNCHECKED_CAST")
-        inline fun <T : Any> auto(type: KClass<T>, size: Int, crossinline initializer: (Int) -> T): Buffer<T> {
+        public inline fun <T : Any> auto(type: KClass<T>, size: Int, crossinline initializer: (Int) -> T): Buffer<T> {
             //TODO add resolution based on Annotation or companion resolution
             return when (type) {
                 Double::class -> RealBuffer(DoubleArray(size) { initializer(it) as Double }) as Buffer<T>
@@ -74,7 +74,7 @@ interface Buffer<T> {
          * Create most appropriate immutable buffer for given type avoiding boxing wherever possible
          */
         @Suppress("UNCHECKED_CAST")
-        inline fun <reified T : Any> auto(size: Int, crossinline initializer: (Int) -> T): Buffer<T> =
+        public inline fun <reified T : Any> auto(size: Int, crossinline initializer: (Int) -> T): Buffer<T> =
             auto(T::class, size, initializer)
     }
 }
@@ -82,43 +82,43 @@ interface Buffer<T> {
 /**
  * Creates a sequence that returns all elements from this [Buffer].
  */
-fun <T> Buffer<T>.asSequence(): Sequence<T> = Sequence(::iterator)
+public fun <T> Buffer<T>.asSequence(): Sequence<T> = Sequence(::iterator)
 
 /**
  * Creates an iterable that returns all elements from this [Buffer].
  */
-fun <T> Buffer<T>.asIterable(): Iterable<T> = Iterable(::iterator)
+public fun <T> Buffer<T>.asIterable(): Iterable<T> = Iterable(::iterator)
 
 /**
  * Returns an [IntRange] of the valid indices for this [Buffer].
  */
-val Buffer<*>.indices: IntRange get() = 0 until size
+public val Buffer<*>.indices: IntRange get() = 0 until size
 
 /**
  * A generic mutable random-access structure for both primitives and objects.
  *
  * @param T the type of elements contained in the buffer.
  */
-interface MutableBuffer<T> : Buffer<T> {
+public interface MutableBuffer<T> : Buffer<T> {
     /**
      * Sets the array element at the specified [index] to the specified [value].
      */
-    operator fun set(index: Int, value: T)
+    public operator fun set(index: Int, value: T)
 
     /**
      * Returns a shallow copy of the buffer.
      */
-    fun copy(): MutableBuffer<T>
+    public fun copy(): MutableBuffer<T>
 
-    companion object {
+    public companion object {
         /**
          * Create a boxing mutable buffer of given type
          */
-        inline fun <T> boxing(size: Int, initializer: (Int) -> T): MutableBuffer<T> =
+        public inline fun <T> boxing(size: Int, initializer: (Int) -> T): MutableBuffer<T> =
             MutableListBuffer(MutableList(size, initializer))
 
         @Suppress("UNCHECKED_CAST")
-        inline fun <T : Any> auto(type: KClass<out T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> =
+        public inline fun <T : Any> auto(type: KClass<out T>, size: Int, initializer: (Int) -> T): MutableBuffer<T> =
             when (type) {
                 Double::class -> RealBuffer(DoubleArray(size) { initializer(it) as Double }) as MutableBuffer<T>
                 Short::class -> ShortBuffer(ShortArray(size) { initializer(it) as Short }) as MutableBuffer<T>
@@ -131,12 +131,11 @@ interface MutableBuffer<T> : Buffer<T> {
          * Create most appropriate mutable buffer for given type avoiding boxing wherever possible
          */
         @Suppress("UNCHECKED_CAST")
-        inline fun <reified T : Any> auto(size: Int, initializer: (Int) -> T): MutableBuffer<T> =
+        public inline fun <reified T : Any> auto(size: Int, initializer: (Int) -> T): MutableBuffer<T> =
             auto(T::class, size, initializer)
 
-        val real: MutableBufferFactory<Double> = { size: Int, initializer: (Int) -> Double ->
-            RealBuffer(DoubleArray(size) { initializer(it) })
-        }
+        public val real: MutableBufferFactory<Double> =
+            { size, initializer -> RealBuffer(DoubleArray(size) { initializer(it) }) }
     }
 }
 
@@ -146,7 +145,7 @@ interface MutableBuffer<T> : Buffer<T> {
  * @param T the type of elements contained in the buffer.
  * @property list The underlying list.
  */
-inline class ListBuffer<T>(val list: List<T>) : Buffer<T> {
+public inline class ListBuffer<T>(public val list: List<T>) : Buffer<T> {
     override val size: Int
         get() = list.size
 
@@ -157,7 +156,7 @@ inline class ListBuffer<T>(val list: List<T>) : Buffer<T> {
 /**
  * Returns an [ListBuffer] that wraps the original list.
  */
-fun <T> List<T>.asBuffer(): ListBuffer<T> = ListBuffer(this)
+public fun <T> List<T>.asBuffer(): ListBuffer<T> = ListBuffer(this)
 
 /**
  * Creates a new [ListBuffer] with the specified [size], where each element is calculated by calling the specified
@@ -166,10 +165,7 @@ fun <T> List<T>.asBuffer(): ListBuffer<T> = ListBuffer(this)
  * The function [init] is called for each array element sequentially starting from the first one.
  * It should return the value for an array element given its index.
  */
-inline fun <T> ListBuffer(size: Int, init: (Int) -> T): ListBuffer<T> {
-    contract { callsInPlace(init) }
-    return List(size, init).asBuffer()
-}
+public inline fun <T> ListBuffer(size: Int, init: (Int) -> T): ListBuffer<T> = List(size, init).asBuffer()
 
 /**
  * [MutableBuffer] implementation over [MutableList].
@@ -177,7 +173,7 @@ inline fun <T> ListBuffer(size: Int, init: (Int) -> T): ListBuffer<T> {
  * @param T the type of elements contained in the buffer.
  * @property list The underlying list.
  */
-inline class MutableListBuffer<T>(val list: MutableList<T>) : MutableBuffer<T> {
+public inline class MutableListBuffer<T>(public val list: MutableList<T>) : MutableBuffer<T> {
     override val size: Int
         get() = list.size
 
@@ -197,7 +193,7 @@ inline class MutableListBuffer<T>(val list: MutableList<T>) : MutableBuffer<T> {
  * @param T the type of elements contained in the buffer.
  * @property array The underlying array.
  */
-class ArrayBuffer<T>(private val array: Array<T>) : MutableBuffer<T> {
+public class ArrayBuffer<T>(private val array: Array<T>) : MutableBuffer<T> {
     // Can't inline because array is invariant
     override val size: Int
         get() = array.size
@@ -215,7 +211,7 @@ class ArrayBuffer<T>(private val array: Array<T>) : MutableBuffer<T> {
 /**
  * Returns an [ArrayBuffer] that wraps the original array.
  */
-fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(this)
+public fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(this)
 
 /**
  * Immutable wrapper for [MutableBuffer].
@@ -223,7 +219,7 @@ fun <T> Array<T>.asBuffer(): ArrayBuffer<T> = ArrayBuffer(this)
  * @param T the type of elements contained in the buffer.
  * @property buffer The underlying buffer.
  */
-inline class ReadOnlyBuffer<T>(val buffer: MutableBuffer<T>) : Buffer<T> {
+public inline class ReadOnlyBuffer<T>(public val buffer: MutableBuffer<T>) : Buffer<T> {
     override val size: Int get() = buffer.size
 
     override operator fun get(index: Int): T = buffer[index]
@@ -237,7 +233,7 @@ inline class ReadOnlyBuffer<T>(val buffer: MutableBuffer<T>) : Buffer<T> {
  *
  * @param T the type of elements provided by the buffer.
  */
-class VirtualBuffer<T>(override val size: Int, private val generator: (Int) -> T) : Buffer<T> {
+public class VirtualBuffer<T>(override val size: Int, private val generator: (Int) -> T) : Buffer<T> {
     override operator fun get(index: Int): T {
         if (index < 0 || index >= size) throw IndexOutOfBoundsException("Expected index from 0 to ${size - 1}, but found $index")
         return generator(index)
@@ -257,14 +253,14 @@ class VirtualBuffer<T>(override val size: Int, private val generator: (Int) -> T
 /**
  * Convert this buffer to read-only buffer.
  */
-fun <T> Buffer<T>.asReadOnly(): Buffer<T> = if (this is MutableBuffer) ReadOnlyBuffer(this) else this
+public fun <T> Buffer<T>.asReadOnly(): Buffer<T> = if (this is MutableBuffer) ReadOnlyBuffer(this) else this
 
 /**
  * Typealias for buffer transformations.
  */
-typealias BufferTransform<T, R> = (Buffer<T>) -> Buffer<R>
+public typealias BufferTransform<T, R> = (Buffer<T>) -> Buffer<R>
 
 /**
  * Typealias for buffer transformations with suspend function.
  */
-typealias SuspendBufferTransform<T, R> = suspend (Buffer<T>) -> Buffer<R>
+public typealias SuspendBufferTransform<T, R> = suspend (Buffer<T>) -> Buffer<R>
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ComplexNDField.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ComplexNDField.kt
similarity index 73%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ComplexNDField.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ComplexNDField.kt
index 5364115d4..f1f1074e5 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ComplexNDField.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ComplexNDField.kt
@@ -1,18 +1,18 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.ComplexField
-import scientifik.kmath.operations.FieldElement
-import scientifik.kmath.operations.complex
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.ComplexField
+import kscience.kmath.operations.FieldElement
+import kscience.kmath.operations.complex
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
 
-typealias ComplexNDElement = BufferedNDFieldElement<Complex, ComplexField>
+public typealias ComplexNDElement = BufferedNDFieldElement<Complex, ComplexField>
 
 /**
  * An optimized nd-field for complex numbers
  */
-class ComplexNDField(override val shape: IntArray) :
+public class ComplexNDField(override val shape: IntArray) :
     BufferedNDField<Complex, ComplexField>,
     ExtendedNDField<Complex, ComplexField, NDBuffer<Complex>> {
 
@@ -21,7 +21,7 @@ class ComplexNDField(override val shape: IntArray) :
     override val zero: ComplexNDElement by lazy { produce { zero } }
     override val one: ComplexNDElement by lazy { produce { one } }
 
-    inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Complex): Buffer<Complex> =
+    public inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Complex): Buffer<Complex> =
         Buffer.complex(size) { initializer(it) }
 
     /**
@@ -97,7 +97,7 @@ class ComplexNDField(override val shape: IntArray) :
 /**
  * Fast element production using function inlining
  */
-inline fun BufferedNDField<Complex, ComplexField>.produceInline(crossinline initializer: ComplexField.(Int) -> Complex): ComplexNDElement {
+public inline fun BufferedNDField<Complex, ComplexField>.produceInline(initializer: ComplexField.(Int) -> Complex): ComplexNDElement {
     val buffer = Buffer.complex(strides.linearSize) { offset -> ComplexField.initializer(offset) }
     return BufferedNDFieldElement(this, buffer)
 }
@@ -105,14 +105,13 @@ inline fun BufferedNDField<Complex, ComplexField>.produceInline(crossinline init
 /**
  * Map one [ComplexNDElement] using function with indices.
  */
-inline fun ComplexNDElement.mapIndexed(crossinline transform: ComplexField.(index: IntArray, Complex) -> Complex): ComplexNDElement =
+public inline fun ComplexNDElement.mapIndexed(transform: ComplexField.(index: IntArray, Complex) -> Complex): ComplexNDElement =
     context.produceInline { offset -> transform(strides.index(offset), buffer[offset]) }
 
 /**
  * Map one [ComplexNDElement] using function without indices.
  */
-inline fun ComplexNDElement.map(crossinline transform: ComplexField.(Complex) -> Complex): ComplexNDElement {
-    contract { callsInPlace(transform) }
+public inline fun ComplexNDElement.map(transform: ComplexField.(Complex) -> Complex): ComplexNDElement {
     val buffer = Buffer.complex(strides.linearSize) { offset -> ComplexField.transform(buffer[offset]) }
     return BufferedNDFieldElement(context, buffer)
 }
@@ -120,38 +119,35 @@ inline fun ComplexNDElement.map(crossinline transform: ComplexField.(Complex) ->
 /**
  * Element by element application of any operation on elements to the whole array. Just like in numpy
  */
-operator fun Function1<Complex, Complex>.invoke(ndElement: ComplexNDElement): ComplexNDElement =
+public operator fun Function1<Complex, Complex>.invoke(ndElement: ComplexNDElement): ComplexNDElement =
     ndElement.map { this@invoke(it) }
 
-
 /* plus and minus */
 
 /**
  * Summation operation for [BufferedNDElement] and single element
  */
-operator fun ComplexNDElement.plus(arg: Complex): ComplexNDElement = map { it + arg }
+public operator fun ComplexNDElement.plus(arg: Complex): ComplexNDElement = map { it + arg }
 
 /**
  * Subtraction operation between [BufferedNDElement] and single element
  */
-operator fun ComplexNDElement.minus(arg: Complex): ComplexNDElement =
-    map { it - arg }
+public operator fun ComplexNDElement.minus(arg: Complex): ComplexNDElement = map { it - arg }
 
-operator fun ComplexNDElement.plus(arg: Double): ComplexNDElement =
-    map { it + arg }
+public operator fun ComplexNDElement.plus(arg: Double): ComplexNDElement = map { it + arg }
+public operator fun ComplexNDElement.minus(arg: Double): ComplexNDElement = map { it - arg }
 
-operator fun ComplexNDElement.minus(arg: Double): ComplexNDElement =
-    map { it - arg }
+public fun NDField.Companion.complex(vararg shape: Int): ComplexNDField = ComplexNDField(shape)
 
-fun NDField.Companion.complex(vararg shape: Int): ComplexNDField = ComplexNDField(shape)
-
-fun NDElement.Companion.complex(vararg shape: Int, initializer: ComplexField.(IntArray) -> Complex): ComplexNDElement =
-    NDField.complex(*shape).produce(initializer)
+public fun NDElement.Companion.complex(
+    vararg shape: Int,
+    initializer: ComplexField.(IntArray) -> Complex
+): ComplexNDElement = NDField.complex(*shape).produce(initializer)
 
 /**
  * Produce a context for n-dimensional operations inside this real field
  */
-inline fun <R> ComplexField.nd(vararg shape: Int, action: ComplexNDField.() -> R): R {
+public inline fun <R> ComplexField.nd(vararg shape: Int, action: ComplexNDField.() -> R): R {
     contract { callsInPlace(action, InvocationKind.EXACTLY_ONCE) }
     return NDField.complex(*shape).action()
 }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ExtendedNDField.kt
similarity index 86%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ExtendedNDField.kt
index 24aa48c6b..a9fa2763b 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ExtendedNDField.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ExtendedNDField.kt
@@ -1,6 +1,6 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.ExtendedField
+import kscience.kmath.operations.ExtendedField
 
 /**
  * [ExtendedField] over [NDStructure].
@@ -9,7 +9,7 @@ import scientifik.kmath.operations.ExtendedField
  * @param N the type of ND structure.
  * @param F the extended field of structure elements.
  */
-interface ExtendedNDField<T : Any, F : ExtendedField<T>, N : NDStructure<T>> : NDField<T, F, N>, ExtendedField<N>
+public interface ExtendedNDField<T : Any, F : ExtendedField<T>, N : NDStructure<T>> : NDField<T, F, N>, ExtendedField<N>
 
 ///**
 // * NDField that supports [ExtendedField] operations on its elements
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FlaggedBuffer.kt
similarity index 65%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FlaggedBuffer.kt
index 5146c0668..e3fda0e10 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FlaggedBuffer.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FlaggedBuffer.kt
@@ -1,6 +1,5 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import kotlin.contracts.contract
 import kotlin.experimental.and
 
 /**
@@ -8,7 +7,7 @@ import kotlin.experimental.and
  *
  * @property mask bit mask value of this flag.
  */
-enum class ValueFlag(val mask: Byte) {
+public enum class ValueFlag(public val mask: Byte) {
     /**
      * Reports the value is NaN.
      */
@@ -33,23 +32,23 @@ enum class ValueFlag(val mask: Byte) {
 /**
  * A buffer with flagged values.
  */
-interface FlaggedBuffer<T> : Buffer<T> {
-    fun getFlag(index: Int): Byte
+public interface FlaggedBuffer<T> : Buffer<T> {
+    public fun getFlag(index: Int): Byte
 }
 
 /**
  * The value is valid if all flags are down
  */
-fun FlaggedBuffer<*>.isValid(index: Int): Boolean = getFlag(index) != 0.toByte()
+public fun FlaggedBuffer<*>.isValid(index: Int): Boolean = getFlag(index) != 0.toByte()
 
-fun FlaggedBuffer<*>.hasFlag(index: Int, flag: ValueFlag): Boolean = (getFlag(index) and flag.mask) != 0.toByte()
+public fun FlaggedBuffer<*>.hasFlag(index: Int, flag: ValueFlag): Boolean = (getFlag(index) and flag.mask) != 0.toByte()
 
-fun FlaggedBuffer<*>.isMissing(index: Int): Boolean = hasFlag(index, ValueFlag.MISSING)
+public fun FlaggedBuffer<*>.isMissing(index: Int): Boolean = hasFlag(index, ValueFlag.MISSING)
 
 /**
  * A real buffer which supports flags for each value like NaN or Missing
  */
-class FlaggedRealBuffer(val values: DoubleArray, val flags: ByteArray) : FlaggedBuffer<Double?>, Buffer<Double?> {
+public class FlaggedRealBuffer(public val values: DoubleArray, public val flags: ByteArray) : FlaggedBuffer<Double?>, Buffer<Double?> {
     init {
         require(values.size == flags.size) { "Values and flags must have the same dimensions" }
     }
@@ -65,9 +64,7 @@ class FlaggedRealBuffer(val values: DoubleArray, val flags: ByteArray) : Flagged
     }.iterator()
 }
 
-inline fun FlaggedRealBuffer.forEachValid(block: (Double) -> Unit) {
-    contract { callsInPlace(block) }
-
+public inline fun FlaggedRealBuffer.forEachValid(block: (Double) -> Unit) {
     indices
         .asSequence()
         .filter(::isValid)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FloatBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FloatBuffer.kt
similarity index 69%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FloatBuffer.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FloatBuffer.kt
index 3beb110cf..e96c45572 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/FloatBuffer.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/FloatBuffer.kt
@@ -1,13 +1,12 @@
-package scientifik.kmath.structures
-
-import kotlin.contracts.contract
+package kscience.kmath.structures
 
 /**
  * Specialized [MutableBuffer] implementation over [FloatArray].
  *
  * @property array the underlying array.
+ * @author Iaroslav Postovalov
  */
-inline class FloatBuffer(val array: FloatArray) : MutableBuffer<Float> {
+public inline class FloatBuffer(public val array: FloatArray) : MutableBuffer<Float> {
     override val size: Int get() = array.size
 
     override operator fun get(index: Int): Float = array[index]
@@ -29,20 +28,17 @@ inline class FloatBuffer(val array: FloatArray) : MutableBuffer<Float> {
  * The function [init] is called for each array element sequentially starting from the first one.
  * It should return the value for an buffer element given its index.
  */
-inline fun FloatBuffer(size: Int, init: (Int) -> Float): FloatBuffer {
-    contract { callsInPlace(init) }
-    return FloatBuffer(FloatArray(size) { init(it) })
-}
+public inline fun FloatBuffer(size: Int, init: (Int) -> Float): FloatBuffer = FloatBuffer(FloatArray(size) { init(it) })
 
 /**
  * Returns a new [FloatBuffer] of given elements.
  */
-fun FloatBuffer(vararg floats: Float): FloatBuffer = FloatBuffer(floats)
+public fun FloatBuffer(vararg floats: Float): FloatBuffer = FloatBuffer(floats)
 
 /**
  * Returns a [FloatArray] containing all of the elements of this [MutableBuffer].
  */
-val MutableBuffer<out Float>.array: FloatArray
+public val MutableBuffer<out Float>.array: FloatArray
     get() = (if (this is FloatBuffer) array else FloatArray(size) { get(it) })
 
 /**
@@ -51,4 +47,4 @@ val MutableBuffer<out Float>.array: FloatArray
  * @receiver the array.
  * @return the new buffer.
  */
-fun FloatArray.asBuffer(): FloatBuffer = FloatBuffer(this)
+public fun FloatArray.asBuffer(): FloatBuffer = FloatBuffer(this)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/IntBuffer.kt
similarity index 73%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/IntBuffer.kt
index f88ed7d66..0fe68803b 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/IntBuffer.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/IntBuffer.kt
@@ -1,13 +1,11 @@
-package scientifik.kmath.structures
-
-import kotlin.contracts.contract
+package kscience.kmath.structures
 
 /**
  * Specialized [MutableBuffer] implementation over [IntArray].
  *
  * @property array the underlying array.
  */
-inline class IntBuffer(val array: IntArray) : MutableBuffer<Int> {
+public inline class IntBuffer(public val array: IntArray) : MutableBuffer<Int> {
     override val size: Int get() = array.size
 
     override operator fun get(index: Int): Int = array[index]
@@ -29,17 +27,17 @@ inline class IntBuffer(val array: IntArray) : MutableBuffer<Int> {
  * The function [init] is called for each array element sequentially starting from the first one.
  * It should return the value for an buffer element given its index.
  */
-inline fun IntBuffer(size: Int, init: (Int) -> Int): IntBuffer = IntBuffer(IntArray(size) { init(it) })
+public inline fun IntBuffer(size: Int, init: (Int) -> Int): IntBuffer = IntBuffer(IntArray(size) { init(it) })
 
 /**
  * Returns a new [IntBuffer] of given elements.
  */
-fun IntBuffer(vararg ints: Int): IntBuffer = IntBuffer(ints)
+public fun IntBuffer(vararg ints: Int): IntBuffer = IntBuffer(ints)
 
 /**
  * Returns a [IntArray] containing all of the elements of this [MutableBuffer].
  */
-val MutableBuffer<out Int>.array: IntArray
+public val MutableBuffer<out Int>.array: IntArray
     get() = (if (this is IntBuffer) array else IntArray(size) { get(it) })
 
 /**
@@ -48,4 +46,4 @@ val MutableBuffer<out Int>.array: IntArray
  * @receiver the array.
  * @return the new buffer.
  */
-fun IntArray.asBuffer(): IntBuffer = IntBuffer(this)
+public fun IntArray.asBuffer(): IntBuffer = IntBuffer(this)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/LongBuffer.kt
similarity index 70%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/LongBuffer.kt
index 3a1d679c2..87853c251 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/LongBuffer.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/LongBuffer.kt
@@ -1,13 +1,11 @@
-package scientifik.kmath.structures
-
-import kotlin.contracts.contract
+package kscience.kmath.structures
 
 /**
  * Specialized [MutableBuffer] implementation over [LongArray].
  *
  * @property array the underlying array.
  */
-inline class LongBuffer(val array: LongArray) : MutableBuffer<Long> {
+public inline class LongBuffer(public val array: LongArray) : MutableBuffer<Long> {
     override val size: Int get() = array.size
 
     override operator fun get(index: Int): Long = array[index]
@@ -20,7 +18,6 @@ inline class LongBuffer(val array: LongArray) : MutableBuffer<Long> {
 
     override fun copy(): MutableBuffer<Long> =
         LongBuffer(array.copyOf())
-
 }
 
 /**
@@ -30,20 +27,17 @@ inline class LongBuffer(val array: LongArray) : MutableBuffer<Long> {
  * The function [init] is called for each array element sequentially starting from the first one.
  * It should return the value for an buffer element given its index.
  */
-inline fun LongBuffer(size: Int, init: (Int) -> Long): LongBuffer {
-    contract { callsInPlace(init) }
-    return LongBuffer(LongArray(size) { init(it) })
-}
+public inline fun LongBuffer(size: Int, init: (Int) -> Long): LongBuffer = LongBuffer(LongArray(size) { init(it) })
 
 /**
  * Returns a new [LongBuffer] of given elements.
  */
-fun LongBuffer(vararg longs: Long): LongBuffer = LongBuffer(longs)
+public fun LongBuffer(vararg longs: Long): LongBuffer = LongBuffer(longs)
 
 /**
  * Returns a [IntArray] containing all of the elements of this [MutableBuffer].
  */
-val MutableBuffer<out Long>.array: LongArray
+public val MutableBuffer<out Long>.array: LongArray
     get() = (if (this is LongBuffer) array else LongArray(size) { get(it) })
 
 /**
@@ -52,4 +46,4 @@ val MutableBuffer<out Long>.array: LongArray
  * @receiver the array.
  * @return the new buffer.
  */
-fun LongArray.asBuffer(): LongBuffer = LongBuffer(this)
+public fun LongArray.asBuffer(): LongBuffer = LongBuffer(this)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/MemoryBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt
similarity index 54%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/MemoryBuffer.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt
index 83c50b14b..b7e6a8218 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/MemoryBuffer.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/MemoryBuffer.kt
@@ -1,6 +1,6 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.memory.*
+import kscience.memory.*
 
 /**
  * A non-boxing buffer over [Memory] object.
@@ -9,7 +9,7 @@ import scientifik.memory.*
  * @property memory the underlying memory segment.
  * @property spec the spec of [T] type.
  */
-open class MemoryBuffer<T : Any>(protected val memory: Memory, protected val spec: MemorySpec<T>) : Buffer<T> {
+public 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
 
     private val reader: MemoryReader = memory.reader()
@@ -17,20 +17,17 @@ open class MemoryBuffer<T : Any>(protected val memory: Memory, protected val spe
     override operator fun get(index: Int): T = reader.read(spec, spec.objectSize * index)
     override operator fun iterator(): Iterator<T> = (0 until size).asSequence().map { get(it) }.iterator()
 
-    companion object {
-        fun <T : Any> create(spec: MemorySpec<T>, size: Int): MemoryBuffer<T> =
+    public companion object {
+        public fun <T : Any> create(spec: MemorySpec<T>, size: Int): MemoryBuffer<T> =
             MemoryBuffer(Memory.allocate(size * spec.objectSize), spec)
 
-        inline fun <T : Any> create(
+        public inline fun <T : Any> create(
             spec: MemorySpec<T>,
             size: Int,
-            crossinline initializer: (Int) -> T
-        ): MemoryBuffer<T> =
-            MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec).also { buffer ->
-                (0 until size).forEach {
-                    buffer[it] = initializer(it)
-                }
-            }
+            initializer: (Int) -> T
+        ): MemoryBuffer<T> = MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec).also { buffer ->
+            (0 until size).forEach { buffer[it] = initializer(it) }
+        }
     }
 }
 
@@ -41,7 +38,7 @@ open class MemoryBuffer<T : Any>(protected val memory: Memory, protected val spe
  * @property memory the underlying memory segment.
  * @property spec the spec of [T] type.
  */
-class MutableMemoryBuffer<T : Any>(memory: Memory, spec: MemorySpec<T>) : MemoryBuffer<T>(memory, spec),
+public class MutableMemoryBuffer<T : Any>(memory: Memory, spec: MemorySpec<T>) : MemoryBuffer<T>(memory, spec),
     MutableBuffer<T> {
 
     private val writer: MemoryWriter = memory.writer()
@@ -49,19 +46,16 @@ class MutableMemoryBuffer<T : Any>(memory: Memory, spec: MemorySpec<T>) : Memory
     override operator fun set(index: Int, value: T): Unit = writer.write(spec, spec.objectSize * index, value)
     override fun copy(): MutableBuffer<T> = MutableMemoryBuffer(memory.copy(), spec)
 
-    companion object {
-        fun <T : Any> create(spec: MemorySpec<T>, size: Int): MutableMemoryBuffer<T> =
+    public companion object {
+        public fun <T : Any> create(spec: MemorySpec<T>, size: Int): MutableMemoryBuffer<T> =
             MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec)
 
-        inline fun <T : Any> create(
+        public inline fun <T : Any> create(
             spec: MemorySpec<T>,
             size: Int,
             crossinline initializer: (Int) -> T
-        ): MutableMemoryBuffer<T> =
-            MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec).also { buffer ->
-                (0 until size).forEach {
-                    buffer[it] = initializer(it)
-                }
-            }
+        ): MutableMemoryBuffer<T> = MutableMemoryBuffer(Memory.allocate(size * spec.objectSize), spec).also { buffer ->
+            (0 until size).forEach { buffer[it] = initializer(it) }
+        }
     }
 }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDAlgebra.kt
similarity index 51%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDAlgebra.kt
index f09db3c72..28eaef2f1 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDAlgebra.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDAlgebra.kt
@@ -1,16 +1,14 @@
-package scientifik.kmath.structures
-
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.Space
+package kscience.kmath.structures
 
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.Space
 
 /**
  * An exception is thrown when the expected ans actual shape of NDArray differs
  */
-class ShapeMismatchException(val expected: IntArray, val actual: IntArray) : RuntimeException()
-
+public class ShapeMismatchException(public val expected: IntArray, public val actual: IntArray) : RuntimeException()
 
 /**
  * The base interface for all nd-algebra implementations
@@ -18,53 +16,49 @@ class ShapeMismatchException(val expected: IntArray, val actual: IntArray) : Run
  * @param C the type of the element context
  * @param N the type of the structure
  */
-interface NDAlgebra<T, C, N : NDStructure<T>> {
-    val shape: IntArray
-    val elementContext: C
+public interface NDAlgebra<T, C, N : NDStructure<T>> {
+    public val shape: IntArray
+    public val elementContext: C
 
     /**
      * Produce a new [N] structure using given initializer function
      */
-    fun produce(initializer: C.(IntArray) -> T): N
+    public fun produce(initializer: C.(IntArray) -> T): N
 
     /**
      * Map elements from one structure to another one
      */
-    fun map(arg: N, transform: C.(T) -> T): N
+    public fun map(arg: N, transform: C.(T) -> T): N
 
     /**
      * Map indexed elements
      */
-    fun mapIndexed(arg: N, transform: C.(index: IntArray, T) -> T): N
+    public fun mapIndexed(arg: N, transform: C.(index: IntArray, T) -> T): N
 
     /**
      * Combine two structures into one
      */
-    fun combine(a: N, b: N, transform: C.(T, T) -> T): N
+    public fun combine(a: N, b: N, transform: C.(T, T) -> T): N
 
     /**
      * Check if given elements are consistent with this context
      */
-    fun check(vararg elements: N) {
-        elements.forEach {
-            if (!shape.contentEquals(it.shape)) {
-                throw ShapeMismatchException(shape, it.shape)
-            }
-        }
+    public fun check(vararg elements: N): Unit = elements.forEach {
+        if (!shape.contentEquals(it.shape)) throw ShapeMismatchException(shape, it.shape)
     }
 
     /**
      * element-by-element invoke a function working on [T] on a [NDStructure]
      */
-    operator fun Function1<T, T>.invoke(structure: N): N = map(structure) { value -> this@invoke(value) }
+    public operator fun Function1<T, T>.invoke(structure: N): N = map(structure) { value -> this@invoke(value) }
 
-    companion object
+    public companion object
 }
 
 /**
  * An nd-space over element space
  */
-interface NDSpace<T, S : Space<T>, N : NDStructure<T>> : Space<N>, NDAlgebra<T, S, N> {
+public interface NDSpace<T, S : Space<T>, N : NDStructure<T>> : Space<N>, NDAlgebra<T, S, N> {
     /**
      * Element-by-element addition
      */
@@ -76,32 +70,31 @@ interface NDSpace<T, S : Space<T>, N : NDStructure<T>> : Space<N>, NDAlgebra<T,
     override fun multiply(a: N, k: Number): N = map(a) { multiply(it, k) }
 
     //TODO move to extensions after KEEP-176
-    operator fun N.plus(arg: T): N = map(this) { value -> add(arg, value) }
+    public operator fun N.plus(arg: T): N = map(this) { value -> add(arg, value) }
 
-    operator fun N.minus(arg: T): N = map(this) { value -> add(arg, -value) }
+    public operator fun N.minus(arg: T): N = map(this) { value -> add(arg, -value) }
 
-    operator fun T.plus(arg: N): N = map(arg) { value -> add(this@plus, value) }
-    operator fun T.minus(arg: N): N = map(arg) { value -> add(-this@minus, value) }
+    public operator fun T.plus(arg: N): N = map(arg) { value -> add(this@plus, value) }
+    public operator fun T.minus(arg: N): N = map(arg) { value -> add(-this@minus, value) }
 
-    companion object
+    public companion object
 }
 
 /**
  * An nd-ring over element ring
  */
-interface NDRing<T, R : Ring<T>, N : NDStructure<T>> : Ring<N>, NDSpace<T, R, N> {
-
+public interface NDRing<T, R : Ring<T>, N : NDStructure<T>> : Ring<N>, NDSpace<T, R, N> {
     /**
      * Element-by-element multiplication
      */
     override fun multiply(a: N, b: N): N = combine(a, b) { aValue, bValue -> multiply(aValue, bValue) }
 
     //TODO move to extensions after KEEP-176
-    operator fun N.times(arg: T): N = map(this) { value -> multiply(arg, value) }
+    public operator fun N.times(arg: T): N = map(this) { value -> multiply(arg, value) }
 
-    operator fun T.times(arg: N): N = map(arg) { value -> multiply(this@times, value) }
+    public operator fun T.times(arg: N): N = map(arg) { value -> multiply(this@times, value) }
 
-    companion object
+    public companion object
 }
 
 /**
@@ -111,31 +104,29 @@ interface NDRing<T, R : Ring<T>, N : NDStructure<T>> : Ring<N>, NDSpace<T, R, N>
  * @param N the type of ND structure.
  * @param F field of structure elements.
  */
-interface NDField<T, F : Field<T>, N : NDStructure<T>> : Field<N>, NDRing<T, F, N> {
-
+public interface NDField<T, F : Field<T>, N : NDStructure<T>> : Field<N>, NDRing<T, F, N> {
     /**
      * Element-by-element division
      */
     override fun divide(a: N, b: N): N = combine(a, b) { aValue, bValue -> divide(aValue, bValue) }
 
     //TODO move to extensions after KEEP-176
-    operator fun N.div(arg: T): N = map(this) { value -> divide(arg, value) }
+    public operator fun N.div(arg: T): N = map(this) { value -> divide(arg, value) }
 
-    operator fun T.div(arg: N): N = map(arg) { divide(it, this@div) }
+    public operator fun T.div(arg: N): N = map(arg) { divide(it, this@div) }
 
-    companion object {
-
-        private val realNDFieldCache = HashMap<IntArray, RealNDField>()
+    public companion object {
+        private val realNDFieldCache: MutableMap<IntArray, RealNDField> = hashMapOf()
 
         /**
          * Create a nd-field for [Double] values or pull it from cache if it was created previously
          */
-        fun real(vararg shape: Int): RealNDField = realNDFieldCache.getOrPut(shape) { RealNDField(shape) }
+        public fun real(vararg shape: Int): RealNDField = realNDFieldCache.getOrPut(shape) { RealNDField(shape) }
 
         /**
          * Create a nd-field with boxing generic buffer
          */
-        fun <T : Any, F : Field<T>> boxing(
+        public fun <T : Any, F : Field<T>> boxing(
             field: F,
             vararg shape: Int,
             bufferFactory: BufferFactory<T> = Buffer.Companion::boxing
@@ -145,7 +136,7 @@ interface NDField<T, F : Field<T>, N : NDStructure<T>> : Field<N>, NDRing<T, F,
          * Create a most suitable implementation for nd-field using reified class.
          */
         @Suppress("UNCHECKED_CAST")
-        inline fun <reified T : Any, F : Field<T>> auto(field: F, vararg shape: Int): BufferedNDField<T, F> =
+        public inline fun <reified T : Any, F : Field<T>> auto(field: F, vararg shape: Int): BufferedNDField<T, F> =
             when {
                 T::class == Double::class -> real(*shape) as BufferedNDField<T, F>
                 T::class == Complex::class -> complex(*shape) as BufferedNDField<T, F>
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDElement.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDElement.kt
similarity index 65%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDElement.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDElement.kt
index 6cc0a72c0..f2f565064 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDElement.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDElement.kt
@@ -1,9 +1,9 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.Space
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.Space
 
 /**
  * The root for all [NDStructure] based algebra elements. Does not implement algebra element root because of problems with recursive self-types
@@ -11,31 +11,30 @@ import scientifik.kmath.operations.Space
  * @param C the type of the context for the element
  * @param N the type of the underlying [NDStructure]
  */
-interface NDElement<T, C, N : NDStructure<T>> : NDStructure<T> {
+public interface NDElement<T, C, N : NDStructure<T>> : NDStructure<T> {
+    public val context: NDAlgebra<T, C, N>
 
-    val context: NDAlgebra<T, C, N>
+    public fun unwrap(): N
 
-    fun unwrap(): N
+    public fun N.wrap(): NDElement<T, C, N>
 
-    fun N.wrap(): NDElement<T, C, N>
-
-    companion object {
+    public companion object {
         /**
          * Create a optimized NDArray of doubles
          */
-        fun real(shape: IntArray, initializer: RealField.(IntArray) -> Double = { 0.0 }): RealNDElement =
+        public fun real(shape: IntArray, initializer: RealField.(IntArray) -> Double = { 0.0 }): RealNDElement =
             NDField.real(*shape).produce(initializer)
 
-        inline fun real1D(dim: Int, crossinline initializer: (Int) -> Double = { _ -> 0.0 }): RealNDElement =
+        public inline fun real1D(dim: Int, crossinline initializer: (Int) -> Double = { _ -> 0.0 }): RealNDElement =
             real(intArrayOf(dim)) { initializer(it[0]) }
 
-        inline fun real2D(
+        public inline fun real2D(
             dim1: Int,
             dim2: Int,
             crossinline initializer: (Int, Int) -> Double = { _, _ -> 0.0 }
         ): RealNDElement = real(intArrayOf(dim1, dim2)) { initializer(it[0], it[1]) }
 
-        inline fun real3D(
+        public inline fun real3D(
             dim1: Int,
             dim2: Int,
             dim3: Int,
@@ -46,7 +45,7 @@ interface NDElement<T, C, N : NDStructure<T>> : NDStructure<T> {
         /**
          * Simple boxing NDArray
          */
-        fun <T : Any, F : Field<T>> boxing(
+        public fun <T : Any, F : Field<T>> boxing(
             shape: IntArray,
             field: F,
             initializer: F.(IntArray) -> T
@@ -55,7 +54,7 @@ interface NDElement<T, C, N : NDStructure<T>> : NDStructure<T> {
             return ndField.produce(initializer)
         }
 
-        inline fun <reified T : Any, F : Field<T>> auto(
+        public inline fun <reified T : Any, F : Field<T>> auto(
             shape: IntArray,
             field: F,
             noinline initializer: F.(IntArray) -> T
@@ -66,17 +65,16 @@ interface NDElement<T, C, N : NDStructure<T>> : NDStructure<T> {
     }
 }
 
-
-fun <T, C, N : NDStructure<T>> NDElement<T, C, N>.mapIndexed(transform: C.(index: IntArray, T) -> T): NDElement<T, C, N> =
+public fun <T, C, N : NDStructure<T>> NDElement<T, C, N>.mapIndexed(transform: C.(index: IntArray, T) -> T): NDElement<T, C, N> =
     context.mapIndexed(unwrap(), transform).wrap()
 
-fun <T, C, N : NDStructure<T>> NDElement<T, C, N>.map(transform: C.(T) -> T): NDElement<T, C, N> =
+public fun <T, C, N : NDStructure<T>> NDElement<T, C, N>.map(transform: C.(T) -> T): NDElement<T, C, N> =
     context.map(unwrap(), transform).wrap()
 
 /**
  * Element by element application of any operation on elements to the whole [NDElement]
  */
-operator fun <T, C, N : NDStructure<T>> Function1<T, T>.invoke(ndElement: NDElement<T, C, N>): NDElement<T, C, N> =
+public operator fun <T, C, N : NDStructure<T>> Function1<T, T>.invoke(ndElement: NDElement<T, C, N>): NDElement<T, C, N> =
     ndElement.map { value -> this@invoke(value) }
 
 /* plus and minus */
@@ -84,13 +82,13 @@ operator fun <T, C, N : NDStructure<T>> Function1<T, T>.invoke(ndElement: NDElem
 /**
  * Summation operation for [NDElement] and single element
  */
-operator fun <T, S : Space<T>, N : NDStructure<T>> NDElement<T, S, N>.plus(arg: T): NDElement<T, S, N> =
+public operator fun <T, S : Space<T>, N : NDStructure<T>> NDElement<T, S, N>.plus(arg: T): NDElement<T, S, N> =
     map { value -> arg + value }
 
 /**
  * Subtraction operation between [NDElement] and single element
  */
-operator fun <T, S : Space<T>, N : NDStructure<T>> NDElement<T, S, N>.minus(arg: T): NDElement<T, S, N> =
+public operator fun <T, S : Space<T>, N : NDStructure<T>> NDElement<T, S, N>.minus(arg: T): NDElement<T, S, N> =
     map { value -> arg - value }
 
 /* prod and div */
@@ -98,13 +96,13 @@ operator fun <T, S : Space<T>, N : NDStructure<T>> NDElement<T, S, N>.minus(arg:
 /**
  * Product operation for [NDElement] and single element
  */
-operator fun <T, R : Ring<T>, N : NDStructure<T>> NDElement<T, R, N>.times(arg: T): NDElement<T, R, N> =
+public operator fun <T, R : Ring<T>, N : NDStructure<T>> NDElement<T, R, N>.times(arg: T): NDElement<T, R, N> =
     map { value -> arg * value }
 
 /**
  * Division operation between [NDElement] and single element
  */
-operator fun <T, F : Field<T>, N : NDStructure<T>> NDElement<T, F, N>.div(arg: T): NDElement<T, F, N> =
+public operator fun <T, F : Field<T>, N : NDStructure<T>> NDElement<T, F, N>.div(arg: T): NDElement<T, F, N> =
     map { value -> arg / value }
 
 //    /**
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDStructure.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt
similarity index 80%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDStructure.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt
index 01a692a65..4ab49c9bc 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/NDStructure.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/NDStructure.kt
@@ -1,6 +1,5 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import kotlin.contracts.contract
 import kotlin.jvm.JvmName
 import kotlin.reflect.KClass
 
@@ -11,17 +10,17 @@ import kotlin.reflect.KClass
  *
  * @param T the type of items.
  */
-interface NDStructure<T> {
+public interface NDStructure<T> {
     /**
      * The shape of structure, i.e. non-empty sequence of non-negative integers that specify sizes of dimensions of
      * this structure.
      */
-    val shape: IntArray
+    public val shape: IntArray
 
     /**
      * The count of dimensions in this structure. It should be equal to size of [shape].
      */
-    val dimension: Int get() = shape.size
+    public val dimension: Int get() = shape.size
 
     /**
      * Returns the value at the specified indices.
@@ -29,24 +28,24 @@ interface NDStructure<T> {
      * @param index the indices.
      * @return the value.
      */
-    operator fun get(index: IntArray): T
+    public operator fun get(index: IntArray): T
 
     /**
      * Returns the sequence of all the elements associated by their indices.
      *
      * @return the lazy sequence of pairs of indices to values.
      */
-    fun elements(): Sequence<Pair<IntArray, T>>
+    public fun elements(): Sequence<Pair<IntArray, T>>
 
     override fun equals(other: Any?): Boolean
 
     override fun hashCode(): Int
 
-    companion object {
+    public companion object {
         /**
          * Indicates whether some [NDStructure] is equal to another one.
          */
-        fun equals(st1: NDStructure<*>, st2: NDStructure<*>): Boolean {
+        public fun equals(st1: NDStructure<*>, st2: NDStructure<*>): Boolean {
             if (st1 === st2) return true
 
             // fast comparison of buffers if possible
@@ -67,7 +66,7 @@ interface NDStructure<T> {
          *
          * Strides should be reused if possible.
          */
-        fun <T> build(
+        public fun <T> build(
             strides: Strides,
             bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
             initializer: (IntArray) -> T
@@ -77,39 +76,39 @@ interface NDStructure<T> {
         /**
          * Inline create NDStructure with non-boxing buffer implementation if it is possible
          */
-        inline fun <reified T : Any> auto(
+        public inline fun <reified T : Any> auto(
             strides: Strides,
             crossinline initializer: (IntArray) -> T
         ): BufferNDStructure<T> =
             BufferNDStructure(strides, Buffer.auto(strides.linearSize) { i -> initializer(strides.index(i)) })
 
-        inline fun <T : Any> auto(
+        public inline fun <T : Any> auto(
             type: KClass<T>,
             strides: Strides,
             crossinline initializer: (IntArray) -> T
         ): BufferNDStructure<T> =
             BufferNDStructure(strides, Buffer.auto(type, strides.linearSize) { i -> initializer(strides.index(i)) })
 
-        fun <T> build(
+        public fun <T> build(
             shape: IntArray,
             bufferFactory: BufferFactory<T> = Buffer.Companion::boxing,
             initializer: (IntArray) -> T
         ): BufferNDStructure<T> = build(DefaultStrides(shape), bufferFactory, initializer)
 
-        inline fun <reified T : Any> auto(
+        public inline fun <reified T : Any> auto(
             shape: IntArray,
             crossinline initializer: (IntArray) -> T
         ): BufferNDStructure<T> =
             auto(DefaultStrides(shape), initializer)
 
         @JvmName("autoVarArg")
-        inline fun <reified T : Any> auto(
+        public inline fun <reified T : Any> auto(
             vararg shape: Int,
             crossinline initializer: (IntArray) -> T
         ): BufferNDStructure<T> =
             auto(DefaultStrides(shape), initializer)
 
-        inline fun <T : Any> auto(
+        public inline fun <T : Any> auto(
             type: KClass<T>,
             vararg shape: Int,
             crossinline initializer: (IntArray) -> T
@@ -124,68 +123,68 @@ interface NDStructure<T> {
  * @param index the indices.
  * @return the value.
  */
-operator fun <T> NDStructure<T>.get(vararg index: Int): T = get(index)
+public operator fun <T> NDStructure<T>.get(vararg index: Int): T = get(index)
 
 /**
  * Represents mutable [NDStructure].
  */
-interface MutableNDStructure<T> : NDStructure<T> {
+public interface MutableNDStructure<T> : NDStructure<T> {
     /**
      * Inserts an item at the specified indices.
      *
      * @param index the indices.
      * @param value the value.
      */
-    operator fun set(index: IntArray, value: T)
+    public operator fun set(index: IntArray, value: T)
 }
 
-inline fun <T> MutableNDStructure<T>.mapInPlace(action: (IntArray, T) -> T) {
-    contract { callsInPlace(action) }
+public inline fun <T> MutableNDStructure<T>.mapInPlace(action: (IntArray, T) -> T): Unit =
     elements().forEach { (index, oldValue) -> this[index] = action(index, oldValue) }
-}
 
 /**
  * A way to convert ND index to linear one and back.
  */
-interface Strides {
+public interface Strides {
     /**
      * Shape of NDstructure
      */
-    val shape: IntArray
+    public val shape: IntArray
 
     /**
      * Array strides
      */
-    val strides: List<Int>
+    public val strides: List<Int>
 
     /**
      * Get linear index from multidimensional index
      */
-    fun offset(index: IntArray): Int
+    public fun offset(index: IntArray): Int
 
     /**
      * Get multidimensional from linear
      */
-    fun index(offset: Int): IntArray
+    public fun index(offset: Int): IntArray
 
     /**
      * The size of linear buffer to accommodate all elements of ND-structure corresponding to strides
      */
-    val linearSize: Int
+    public val linearSize: Int
+
+    // TODO introduce a fast way to calculate index of the next element?
 
     /**
      * Iterate over ND indices in a natural order
      */
-    fun indices(): Sequence<IntArray> {
-        //TODO introduce a fast way to calculate index of the next element?
-        return (0 until linearSize).asSequence().map { index(it) }
-    }
+    public fun indices(): Sequence<IntArray> = (0 until linearSize).asSequence().map { index(it) }
 }
 
 /**
  * Simple implementation of [Strides].
  */
-class DefaultStrides private constructor(override val shape: IntArray) : Strides {
+public class DefaultStrides private constructor(override val shape: IntArray) : Strides {
+    override val linearSize: Int
+        get() = strides[shape.size]
+
     /**
      * Strides for memory access
      */
@@ -193,6 +192,7 @@ class DefaultStrides private constructor(override val shape: IntArray) : Strides
         sequence {
             var current = 1
             yield(1)
+
             shape.forEach {
                 current *= it
                 yield(current)
@@ -211,17 +211,16 @@ class DefaultStrides private constructor(override val shape: IntArray) : Strides
         val res = IntArray(shape.size)
         var current = offset
         var strideIndex = strides.size - 2
+
         while (strideIndex >= 0) {
             res[strideIndex] = (current / strides[strideIndex])
             current %= strides[strideIndex]
             strideIndex--
         }
+
         return res
     }
 
-    override val linearSize: Int
-        get() = strides[shape.size]
-
     override fun equals(other: Any?): Boolean {
         if (this === other) return true
         if (other !is DefaultStrides) return false
@@ -231,13 +230,14 @@ class DefaultStrides private constructor(override val shape: IntArray) : Strides
 
     override fun hashCode(): Int = shape.contentHashCode()
 
-    companion object {
+    public companion object {
         private val defaultStridesCache = HashMap<IntArray, Strides>()
 
         /**
          * Cached builder for default strides
          */
-        operator fun invoke(shape: IntArray): Strides = defaultStridesCache.getOrPut(shape) { DefaultStrides(shape) }
+        public operator fun invoke(shape: IntArray): Strides =
+            defaultStridesCache.getOrPut(shape) { DefaultStrides(shape) }
     }
 }
 
@@ -246,16 +246,16 @@ class DefaultStrides private constructor(override val shape: IntArray) : Strides
  *
  * @param T the type of items.
  */
-abstract class NDBuffer<T> : NDStructure<T> {
+public abstract class NDBuffer<T> : NDStructure<T> {
     /**
      * The underlying buffer.
      */
-    abstract val buffer: Buffer<T>
+    public abstract val buffer: Buffer<T>
 
     /**
      * The strides to access elements of [Buffer] by linear indices.
      */
-    abstract val strides: Strides
+    public abstract val strides: Strides
 
     override operator fun get(index: IntArray): T = buffer[strides.offset(index)]
 
@@ -277,7 +277,7 @@ abstract class NDBuffer<T> : NDStructure<T> {
 /**
  * Boxing generic [NDStructure]
  */
-class BufferNDStructure<T>(
+public class BufferNDStructure<T>(
     override val strides: Strides,
     override val buffer: Buffer<T>
 ) : NDBuffer<T>() {
@@ -291,13 +291,13 @@ class BufferNDStructure<T>(
 /**
  * Transform structure to a new structure using provided [BufferFactory] and optimizing if argument is [BufferNDStructure]
  */
-inline fun <T, reified R : Any> NDStructure<T>.mapToBuffer(
+public inline fun <T, reified R : Any> NDStructure<T>.mapToBuffer(
     factory: BufferFactory<R> = Buffer.Companion::auto,
     crossinline transform: (T) -> R
 ): BufferNDStructure<R> {
-    return if (this is BufferNDStructure<T>) {
+    return if (this is BufferNDStructure<T>)
         BufferNDStructure(this.strides, factory.invoke(strides.linearSize) { transform(buffer[it]) })
-    } else {
+    else {
         val strides = DefaultStrides(shape)
         BufferNDStructure(strides, factory.invoke(strides.linearSize) { transform(get(strides.index(it))) })
     }
@@ -306,7 +306,7 @@ inline fun <T, reified R : Any> NDStructure<T>.mapToBuffer(
 /**
  * Mutable ND buffer based on linear [MutableBuffer].
  */
-class MutableBufferNDStructure<T>(
+public class MutableBufferNDStructure<T>(
     override val strides: Strides,
     override val buffer: MutableBuffer<T>
 ) : NDBuffer<T>(), MutableNDStructure<T> {
@@ -320,7 +320,7 @@ class MutableBufferNDStructure<T>(
     override operator fun set(index: IntArray, value: T): Unit = buffer.set(strides.offset(index), value)
 }
 
-inline fun <reified T : Any> NDStructure<T>.combine(
+public inline fun <reified T : Any> NDStructure<T>.combine(
     struct: NDStructure<T>,
     crossinline block: (T, T) -> T
 ): NDStructure<T> {
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealBuffer.kt
similarity index 70%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBuffer.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealBuffer.kt
index 3c92fb0ce..2a03e2dd3 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBuffer.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealBuffer.kt
@@ -1,13 +1,11 @@
-package scientifik.kmath.structures
-
-import kotlin.contracts.contract
+package kscience.kmath.structures
 
 /**
  * Specialized [MutableBuffer] implementation over [DoubleArray].
  *
  * @property array the underlying array.
  */
-inline class RealBuffer(val array: DoubleArray) : MutableBuffer<Double> {
+public inline class RealBuffer(public val array: DoubleArray) : MutableBuffer<Double> {
     override val size: Int get() = array.size
 
     override operator fun get(index: Int): Double = array[index]
@@ -29,20 +27,17 @@ inline class RealBuffer(val array: DoubleArray) : MutableBuffer<Double> {
  * The function [init] is called for each array element sequentially starting from the first one.
  * It should return the value for an buffer element given its index.
  */
-inline fun RealBuffer(size: Int, init: (Int) -> Double): RealBuffer {
-    contract { callsInPlace(init) }
-    return RealBuffer(DoubleArray(size) { init(it) })
-}
+public inline fun RealBuffer(size: Int, init: (Int) -> Double): RealBuffer = RealBuffer(DoubleArray(size) { init(it) })
 
 /**
  * Returns a new [RealBuffer] of given elements.
  */
-fun RealBuffer(vararg doubles: Double): RealBuffer = RealBuffer(doubles)
+public fun RealBuffer(vararg doubles: Double): RealBuffer = RealBuffer(doubles)
 
 /**
  * Returns a [DoubleArray] containing all of the elements of this [MutableBuffer].
  */
-val MutableBuffer<out Double>.array: DoubleArray
+public val MutableBuffer<out Double>.array: DoubleArray
     get() = (if (this is RealBuffer) array else DoubleArray(size) { get(it) })
 
 /**
@@ -51,4 +46,4 @@ val MutableBuffer<out Double>.array: DoubleArray
  * @receiver the array.
  * @return the new buffer.
  */
-fun DoubleArray.asBuffer(): RealBuffer = RealBuffer(this)
+public fun DoubleArray.asBuffer(): RealBuffer = RealBuffer(this)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBufferField.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealBufferField.kt
similarity index 62%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBufferField.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealBufferField.kt
index a11826e7e..f7b2ee31e 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealBufferField.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealBufferField.kt
@@ -1,15 +1,14 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.ExtendedField
-import scientifik.kmath.operations.ExtendedFieldOperations
+import kscience.kmath.operations.ExtendedField
+import kscience.kmath.operations.ExtendedFieldOperations
 import kotlin.math.*
 
-
 /**
  * [ExtendedFieldOperations] over [RealBuffer].
  */
-object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
-    override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
+public object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
+    public override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
         require(b.size == a.size) {
             "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} "
         }
@@ -21,7 +20,7 @@ object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
         } else RealBuffer(DoubleArray(a.size) { a[it] + b[it] })
     }
 
-    override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
+    public override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
         val kValue = k.toDouble()
 
         return if (a is RealBuffer) {
@@ -30,7 +29,7 @@ object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
         } else RealBuffer(DoubleArray(a.size) { a[it] * kValue })
     }
 
-    override fun multiply(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
+    public override fun multiply(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
         require(b.size == a.size) {
             "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} "
         }
@@ -43,7 +42,7 @@ object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
             RealBuffer(DoubleArray(a.size) { a[it] * b[it] })
     }
 
-    override fun divide(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
+    public override fun divide(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
         require(b.size == a.size) {
             "The size of the first buffer ${a.size} should be the same as for second one: ${b.size} "
         }
@@ -55,84 +54,91 @@ object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
         } else RealBuffer(DoubleArray(a.size) { a[it] / b[it] })
     }
 
-    override fun sin(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun sin(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { sin(array[it]) })
     } else RealBuffer(DoubleArray(arg.size) { sin(arg[it]) })
 
-    override fun cos(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun cos(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { cos(array[it]) })
     } else RealBuffer(DoubleArray(arg.size) { cos(arg[it]) })
 
-    override fun tan(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun tan(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { tan(array[it]) })
     } else RealBuffer(DoubleArray(arg.size) { tan(arg[it]) })
 
-    override fun asin(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun asin(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { asin(array[it]) })
-    } else {
+    } else
         RealBuffer(DoubleArray(arg.size) { asin(arg[it]) })
-    }
 
-    override fun acos(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun acos(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { acos(array[it]) })
     } else
         RealBuffer(DoubleArray(arg.size) { acos(arg[it]) })
 
-    override fun atan(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun atan(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { atan(array[it]) })
     } else
         RealBuffer(DoubleArray(arg.size) { atan(arg[it]) })
 
-    override fun sinh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun sinh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { sinh(array[it]) })
-    } else RealBuffer(DoubleArray(arg.size) { sinh(arg[it]) })
+    } else
+        RealBuffer(DoubleArray(arg.size) { sinh(arg[it]) })
 
-    override fun cosh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun cosh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { cosh(array[it]) })
-    } else RealBuffer(DoubleArray(arg.size) { cosh(arg[it]) })
+    } else
+        RealBuffer(DoubleArray(arg.size) { cosh(arg[it]) })
 
-    override fun tanh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun tanh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { tanh(array[it]) })
-    } else RealBuffer(DoubleArray(arg.size) { tanh(arg[it]) })
+    } else
+        RealBuffer(DoubleArray(arg.size) { tanh(arg[it]) })
 
-    override fun asinh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun asinh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { asinh(array[it]) })
-    } else RealBuffer(DoubleArray(arg.size) { asinh(arg[it]) })
+    } else
+        RealBuffer(DoubleArray(arg.size) { asinh(arg[it]) })
 
-    override fun acosh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun acosh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { acosh(array[it]) })
-    } else RealBuffer(DoubleArray(arg.size) { acosh(arg[it]) })
+    } else
+        RealBuffer(DoubleArray(arg.size) { acosh(arg[it]) })
 
-    override fun atanh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun atanh(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { atanh(array[it]) })
-    } else RealBuffer(DoubleArray(arg.size) { atanh(arg[it]) })
+    } else
+        RealBuffer(DoubleArray(arg.size) { atanh(arg[it]) })
 
-    override fun power(arg: Buffer<Double>, pow: Number): RealBuffer = if (arg is RealBuffer) {
+    public override fun power(arg: Buffer<Double>, pow: Number): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { array[it].pow(pow.toDouble()) })
-    } else RealBuffer(DoubleArray(arg.size) { arg[it].pow(pow.toDouble()) })
+    } else
+        RealBuffer(DoubleArray(arg.size) { arg[it].pow(pow.toDouble()) })
 
-    override fun exp(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun exp(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { exp(array[it]) })
     } else RealBuffer(DoubleArray(arg.size) { exp(arg[it]) })
 
-    override fun ln(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
+    public override fun ln(arg: Buffer<Double>): RealBuffer = if (arg is RealBuffer) {
         val array = arg.array
         RealBuffer(DoubleArray(arg.size) { ln(array[it]) })
-    } else RealBuffer(DoubleArray(arg.size) { ln(arg[it]) })
+    } else
+        RealBuffer(DoubleArray(arg.size) { ln(arg[it]) })
 }
 
 /**
@@ -140,101 +146,101 @@ object RealBufferFieldOperations : ExtendedFieldOperations<Buffer<Double>> {
  *
  * @property size the size of buffers to operate on.
  */
-class RealBufferField(val size: Int) : ExtendedField<Buffer<Double>> {
-    override val zero: Buffer<Double> by lazy { RealBuffer(size) { 0.0 } }
-    override val one: Buffer<Double> by lazy { RealBuffer(size) { 1.0 } }
+public class RealBufferField(public val size: Int) : ExtendedField<Buffer<Double>> {
+    public override val zero: Buffer<Double> by lazy { RealBuffer(size) { 0.0 } }
+    public override val one: Buffer<Double> by lazy { RealBuffer(size) { 1.0 } }
 
-    override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
+    public override fun add(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
         require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
         return RealBufferFieldOperations.add(a, b)
     }
 
-    override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
+    public override fun multiply(a: Buffer<Double>, k: Number): RealBuffer {
         require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
         return RealBufferFieldOperations.multiply(a, k)
     }
 
-    override fun multiply(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
+    public override fun multiply(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
         require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
         return RealBufferFieldOperations.multiply(a, b)
     }
 
-    override fun divide(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
+    public override fun divide(a: Buffer<Double>, b: Buffer<Double>): RealBuffer {
         require(a.size == size) { "The buffer size ${a.size} does not match context size $size" }
         return RealBufferFieldOperations.divide(a, b)
     }
 
-    override fun sin(arg: Buffer<Double>): RealBuffer {
+    public override fun sin(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.sin(arg)
     }
 
-    override fun cos(arg: Buffer<Double>): RealBuffer {
+    public override fun cos(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.cos(arg)
     }
 
-    override fun tan(arg: Buffer<Double>): RealBuffer {
+    public override fun tan(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.tan(arg)
     }
 
-    override fun asin(arg: Buffer<Double>): RealBuffer {
+    public override fun asin(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.asin(arg)
     }
 
-    override fun acos(arg: Buffer<Double>): RealBuffer {
+    public override fun acos(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.acos(arg)
     }
 
-    override fun atan(arg: Buffer<Double>): RealBuffer {
+    public override fun atan(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.atan(arg)
     }
 
-    override fun sinh(arg: Buffer<Double>): RealBuffer {
+    public override fun sinh(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.sinh(arg)
     }
 
-    override fun cosh(arg: Buffer<Double>): RealBuffer {
+    public override fun cosh(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.cosh(arg)
     }
 
-    override fun tanh(arg: Buffer<Double>): RealBuffer {
+    public override fun tanh(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.tanh(arg)
     }
 
-    override fun asinh(arg: Buffer<Double>): RealBuffer {
+    public override fun asinh(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.asinh(arg)
     }
 
-    override fun acosh(arg: Buffer<Double>): RealBuffer {
+    public override fun acosh(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.acosh(arg)
     }
 
-    override fun atanh(arg: Buffer<Double>): RealBuffer {
+    public override fun atanh(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.atanh(arg)
     }
 
-    override fun power(arg: Buffer<Double>, pow: Number): RealBuffer {
+    public override fun power(arg: Buffer<Double>, pow: Number): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.power(arg, pow)
     }
 
-    override fun exp(arg: Buffer<Double>): RealBuffer {
+    public override fun exp(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.exp(arg)
     }
 
-    override fun ln(arg: Buffer<Double>): RealBuffer {
+    public override fun ln(arg: Buffer<Double>): RealBuffer {
         require(arg.size == size) { "The buffer size ${arg.size} does not match context size $size" }
         return RealBufferFieldOperations.ln(arg)
     }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealNDField.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealNDField.kt
similarity index 79%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealNDField.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealNDField.kt
index 6533f64be..ed28fb9f2 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/RealNDField.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/RealNDField.kt
@@ -1,11 +1,11 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.FieldElement
-import scientifik.kmath.operations.RealField
+import kscience.kmath.operations.FieldElement
+import kscience.kmath.operations.RealField
 
-typealias RealNDElement = BufferedNDFieldElement<Double, RealField>
+public typealias RealNDElement = BufferedNDFieldElement<Double, RealField>
 
-class RealNDField(override val shape: IntArray) :
+public class RealNDField(override val shape: IntArray) :
     BufferedNDField<Double, RealField>,
     ExtendedNDField<Double, RealField, NDBuffer<Double>> {
 
@@ -15,7 +15,7 @@ class RealNDField(override val shape: IntArray) :
     override val zero: RealNDElement by lazy { produce { zero } }
     override val one: RealNDElement by lazy { produce { one } }
 
-    inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Double): Buffer<Double> =
+    public inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Double): Buffer<Double> =
         RealBuffer(DoubleArray(size) { initializer(it) })
 
     /**
@@ -90,7 +90,7 @@ class RealNDField(override val shape: IntArray) :
 /**
  * Fast element production using function inlining
  */
-inline fun BufferedNDField<Double, RealField>.produceInline(crossinline initializer: RealField.(Int) -> Double): RealNDElement {
+public inline fun BufferedNDField<Double, RealField>.produceInline(crossinline initializer: RealField.(Int) -> Double): RealNDElement {
     val array = DoubleArray(strides.linearSize) { offset -> RealField.initializer(offset) }
     return BufferedNDFieldElement(this, RealBuffer(array))
 }
@@ -98,13 +98,13 @@ inline fun BufferedNDField<Double, RealField>.produceInline(crossinline initiali
 /**
  * Map one [RealNDElement] using function with indices.
  */
-inline fun RealNDElement.mapIndexed(crossinline transform: RealField.(index: IntArray, Double) -> Double): RealNDElement =
+public inline fun RealNDElement.mapIndexed(crossinline transform: RealField.(index: IntArray, Double) -> Double): RealNDElement =
     context.produceInline { offset -> transform(strides.index(offset), buffer[offset]) }
 
 /**
  * Map one [RealNDElement] using function without indices.
  */
-inline fun RealNDElement.map(crossinline transform: RealField.(Double) -> Double): RealNDElement {
+public inline fun RealNDElement.map(crossinline transform: RealField.(Double) -> Double): RealNDElement {
     val array = DoubleArray(strides.linearSize) { offset -> RealField.transform(buffer[offset]) }
     return BufferedNDFieldElement(context, RealBuffer(array))
 }
@@ -112,26 +112,22 @@ inline fun RealNDElement.map(crossinline transform: RealField.(Double) -> Double
 /**
  * Element by element application of any operation on elements to the whole array. Just like in numpy.
  */
-operator fun Function1<Double, Double>.invoke(ndElement: RealNDElement): RealNDElement =
+public operator fun Function1<Double, Double>.invoke(ndElement: RealNDElement): RealNDElement =
     ndElement.map { this@invoke(it) }
 
-
 /* plus and minus */
 
 /**
  * Summation operation for [BufferedNDElement] and single element
  */
-operator fun RealNDElement.plus(arg: Double): RealNDElement =
-    map { it + arg }
+public operator fun RealNDElement.plus(arg: Double): RealNDElement = map { it + arg }
 
 /**
  * Subtraction operation between [BufferedNDElement] and single element
  */
-operator fun RealNDElement.minus(arg: Double): RealNDElement =
-    map { it - arg }
+public operator fun RealNDElement.minus(arg: Double): RealNDElement = map { it - arg }
 
 /**
  * Produce a context for n-dimensional operations inside this real field
  */
-
-inline fun <R> RealField.nd(vararg shape: Int, action: RealNDField.() -> R): R = NDField.real(*shape).run(action)
+public inline fun <R> RealField.nd(vararg shape: Int, action: RealNDField.() -> R): R = NDField.real(*shape).run(action)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ShortBuffer.kt
similarity index 50%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ShortBuffer.kt
index 1feba1e6b..0d9222320 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortBuffer.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ShortBuffer.kt
@@ -1,25 +1,21 @@
-package scientifik.kmath.structures
-
-import kotlin.contracts.contract
+package kscience.kmath.structures
 
 /**
  * Specialized [MutableBuffer] implementation over [ShortArray].
  *
  * @property array the underlying array.
  */
-inline class ShortBuffer(val array: ShortArray) : MutableBuffer<Short> {
-    override val size: Int get() = array.size
+public inline class ShortBuffer(public val array: ShortArray) : MutableBuffer<Short> {
+    public override val size: Int get() = array.size
 
-    override operator fun get(index: Int): Short = array[index]
+    public override operator fun get(index: Int): Short = array[index]
 
-    override operator fun set(index: Int, value: Short) {
+    public override operator fun set(index: Int, value: Short) {
         array[index] = value
     }
 
-    override operator fun iterator(): ShortIterator = array.iterator()
-
-    override fun copy(): MutableBuffer<Short> =
-        ShortBuffer(array.copyOf())
+    public override operator fun iterator(): ShortIterator = array.iterator()
+    public override fun copy(): MutableBuffer<Short> = ShortBuffer(array.copyOf())
 }
 
 /**
@@ -29,20 +25,17 @@ inline class ShortBuffer(val array: ShortArray) : MutableBuffer<Short> {
  * The function [init] is called for each array element sequentially starting from the first one.
  * It should return the value for an buffer element given its index.
  */
-inline fun ShortBuffer(size: Int, init: (Int) -> Short): ShortBuffer {
-    contract { callsInPlace(init) }
-    return ShortBuffer(ShortArray(size) { init(it) })
-}
+public inline fun ShortBuffer(size: Int, init: (Int) -> Short): ShortBuffer = ShortBuffer(ShortArray(size) { init(it) })
 
 /**
  * Returns a new [ShortBuffer] of given elements.
  */
-fun ShortBuffer(vararg shorts: Short): ShortBuffer = ShortBuffer(shorts)
+public fun ShortBuffer(vararg shorts: Short): ShortBuffer = ShortBuffer(shorts)
 
 /**
  * Returns a [ShortArray] containing all of the elements of this [MutableBuffer].
  */
-val MutableBuffer<out Short>.array: ShortArray
+public val MutableBuffer<out Short>.array: ShortArray
     get() = (if (this is ShortBuffer) array else ShortArray(size) { get(it) })
 
 /**
@@ -51,4 +44,4 @@ val MutableBuffer<out Short>.array: ShortArray
  * @receiver the array.
  * @return the new buffer.
  */
-fun ShortArray.asBuffer(): ShortBuffer = ShortBuffer(this)
+public fun ShortArray.asBuffer(): ShortBuffer = ShortBuffer(this)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortNDRing.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ShortNDRing.kt
similarity index 74%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortNDRing.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ShortNDRing.kt
index f404a2a27..3b506a26a 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/ShortNDRing.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/ShortNDRing.kt
@@ -1,21 +1,19 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.RingElement
-import scientifik.kmath.operations.ShortRing
+import kscience.kmath.operations.RingElement
+import kscience.kmath.operations.ShortRing
 
+public typealias ShortNDElement = BufferedNDRingElement<Short, ShortRing>
 
-typealias ShortNDElement = BufferedNDRingElement<Short, ShortRing>
-
-class ShortNDRing(override val shape: IntArray) :
+public class ShortNDRing(override val shape: IntArray) :
     BufferedNDRing<Short, ShortRing> {
 
     override val strides: Strides = DefaultStrides(shape)
-
     override val elementContext: ShortRing get() = ShortRing
     override val zero: ShortNDElement by lazy { produce { zero } }
     override val one: ShortNDElement by lazy { produce { one } }
 
-    inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Short): Buffer<Short> =
+    public inline fun buildBuffer(size: Int, crossinline initializer: (Int) -> Short): Buffer<Short> =
         ShortBuffer(ShortArray(size) { initializer(it) })
 
     /**
@@ -70,15 +68,13 @@ class ShortNDRing(override val shape: IntArray) :
 /**
  * Fast element production using function inlining.
  */
-inline fun BufferedNDRing<Short, ShortRing>.produceInline(crossinline initializer: ShortRing.(Int) -> Short): ShortNDElement {
-    val array = ShortArray(strides.linearSize) { offset -> ShortRing.initializer(offset) }
-    return BufferedNDRingElement(this, ShortBuffer(array))
-}
+public inline fun BufferedNDRing<Short, ShortRing>.produceInline(crossinline initializer: ShortRing.(Int) -> Short): ShortNDElement =
+    BufferedNDRingElement(this, ShortBuffer(ShortArray(strides.linearSize) { offset -> ShortRing.initializer(offset) }))
 
 /**
  * Element by element application of any operation on elements to the whole array.
  */
-operator fun Function1<Short, Short>.invoke(ndElement: ShortNDElement): ShortNDElement =
+public operator fun Function1<Short, Short>.invoke(ndElement: ShortNDElement): ShortNDElement =
     ndElement.context.produceInline { i -> invoke(ndElement.buffer[i]) }
 
 
@@ -87,11 +83,11 @@ operator fun Function1<Short, Short>.invoke(ndElement: ShortNDElement): ShortNDE
 /**
  * Summation operation for [ShortNDElement] and single element.
  */
-operator fun ShortNDElement.plus(arg: Short): ShortNDElement =
+public operator fun ShortNDElement.plus(arg: Short): ShortNDElement =
     context.produceInline { i -> (buffer[i] + arg).toShort() }
 
 /**
  * Subtraction operation between [ShortNDElement] and single element.
  */
-operator fun ShortNDElement.minus(arg: Short): ShortNDElement =
+public operator fun ShortNDElement.minus(arg: Short): ShortNDElement =
     context.produceInline { i -> (buffer[i] - arg).toShort() }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure1D.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure1D.kt
similarity index 63%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure1D.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure1D.kt
index a796c2037..af5cc9e3f 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure1D.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure1D.kt
@@ -1,29 +1,27 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
 /**
  * A structure that is guaranteed to be one-dimensional
  */
-interface Structure1D<T> : NDStructure<T>, Buffer<T> {
-    override val dimension: Int get() = 1
+public interface Structure1D<T> : NDStructure<T>, Buffer<T> {
+    public override val dimension: Int get() = 1
 
-    override operator fun get(index: IntArray): T {
+    public override operator fun get(index: IntArray): T {
         require(index.size == 1) { "Index dimension mismatch. Expected 1 but found ${index.size}" }
         return get(index[0])
     }
 
-    override operator fun iterator(): Iterator<T> = (0 until size).asSequence().map { get(it) }.iterator()
+    public override operator fun iterator(): Iterator<T> = (0 until size).asSequence().map(::get).iterator()
 }
 
 /**
  * A 1D wrapper for nd-structure
  */
-private inline class Structure1DWrapper<T>(val structure: NDStructure<T>) : Structure1D<T> {
-
+private inline class Structure1DWrapper<T>(public val structure: NDStructure<T>) : Structure1D<T> {
     override val shape: IntArray get() = structure.shape
     override val size: Int get() = structure.shape[0]
 
     override operator fun get(index: Int): T = structure[index]
-
     override fun elements(): Sequence<Pair<IntArray, T>> = structure.elements()
 }
 
@@ -33,7 +31,6 @@ private inline class Structure1DWrapper<T>(val structure: NDStructure<T>) : Stru
  */
 private inline class Buffer1DWrapper<T>(val buffer: Buffer<T>) : Structure1D<T> {
     override val shape: IntArray get() = intArrayOf(buffer.size)
-
     override val size: Int get() = buffer.size
 
     override fun elements(): Sequence<Pair<IntArray, T>> =
@@ -45,18 +42,12 @@ private inline class Buffer1DWrapper<T>(val buffer: Buffer<T>) : Structure1D<T>
 /**
  * Represent a [NDStructure] as [Structure1D]. Throw error in case of dimension mismatch
  */
-fun <T> NDStructure<T>.as1D(): Structure1D<T> = if (shape.size == 1) {
-    if (this is NDBuffer) {
-        Buffer1DWrapper(this.buffer)
-    } else {
-        Structure1DWrapper(this)
-    }
-} else {
+public fun <T> NDStructure<T>.as1D(): Structure1D<T> = if (shape.size == 1) {
+    if (this is NDBuffer) Buffer1DWrapper(this.buffer) else Structure1DWrapper(this)
+} else
     error("Can't create 1d-structure from ${shape.size}d-structure")
-}
-
 
 /**
  * Represent this buffer as 1D structure
  */
-fun <T> Buffer<T>.asND(): Structure1D<T> = Buffer1DWrapper(this)
+public fun <T> Buffer<T>.asND(): Structure1D<T> = Buffer1DWrapper(this)
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure2D.kt b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure2D.kt
similarity index 53%
rename from kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure2D.kt
rename to kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure2D.kt
index eeb6bd3dc..25fdf3f3d 100644
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/Structure2D.kt
+++ b/kmath-core/src/commonMain/kotlin/kscience/kmath/structures/Structure2D.kt
@@ -1,38 +1,31 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
 /**
  * A structure that is guaranteed to be two-dimensional
  */
-interface Structure2D<T> : NDStructure<T> {
-    val rowNum: Int get() = shape[0]
-    val colNum: Int get() = shape[1]
+public interface Structure2D<T> : NDStructure<T> {
+    public val rowNum: Int get() = shape[0]
+    public val colNum: Int get() = shape[1]
 
-    operator fun get(i: Int, j: Int): T
+    public operator fun get(i: Int, j: Int): T
 
     override operator fun get(index: IntArray): T {
         require(index.size == 2) { "Index dimension mismatch. Expected 2 but found ${index.size}" }
         return get(index[0], index[1])
     }
 
-    val rows: Buffer<Buffer<T>>
-        get() = VirtualBuffer(rowNum) { i ->
-            VirtualBuffer(colNum) { j -> get(i, j) }
-        }
+    public val rows: Buffer<Buffer<T>>
+        get() = VirtualBuffer(rowNum) { i -> VirtualBuffer(colNum) { j -> get(i, j) } }
 
-    val columns: Buffer<Buffer<T>>
-        get() = VirtualBuffer(colNum) { j ->
-            VirtualBuffer(rowNum) { i -> get(i, j) }
-        }
+    public val columns: Buffer<Buffer<T>>
+        get() = VirtualBuffer(colNum) { j -> VirtualBuffer(rowNum) { i -> get(i, j) } }
 
     override fun elements(): Sequence<Pair<IntArray, T>> = sequence {
-        for (i in (0 until rowNum)) {
-            for (j in (0 until colNum)) {
-                yield(intArrayOf(i, j) to get(i, j))
-            }
-        }
+        for (i in (0 until rowNum))
+            for (j in (0 until colNum)) yield(intArrayOf(i, j) to get(i, j))
     }
 
-    companion object
+    public companion object
 }
 
 /**
@@ -49,10 +42,9 @@ private inline class Structure2DWrapper<T>(val structure: NDStructure<T>) : Stru
 /**
  * Represent a [NDStructure] as [Structure1D]. Throw error in case of dimension mismatch
  */
-fun <T> NDStructure<T>.as2D(): Structure2D<T> = if (shape.size == 2) {
+public fun <T> NDStructure<T>.as2D(): Structure2D<T> = if (shape.size == 2)
     Structure2DWrapper(this)
-} else {
+else
     error("Can't create 2d-structure from ${shape.size}d-structure")
-}
 
-typealias Matrix<T> = Structure2D<T>
+public typealias Matrix<T> = Structure2D<T>
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnconstrainedDomain.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnconstrainedDomain.kt
deleted file mode 100644
index 595a3dbe7..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnconstrainedDomain.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-/* 
- * Copyright 2015 Alexander Nozik.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package scientifik.kmath.domains
-
-import scientifik.kmath.linear.Point
-
-class UnconstrainedDomain(override val dimension: Int) : RealDomain {
-    override operator fun contains(point: Point<Double>): Boolean = true
-
-    override fun getLowerBound(num: Int, point: Point<Double>): Double? = Double.NEGATIVE_INFINITY
-
-    override fun getLowerBound(num: Int): Double? = Double.NEGATIVE_INFINITY
-
-    override fun getUpperBound(num: Int, point: Point<Double>): Double? = Double.POSITIVE_INFINITY
-
-    override fun getUpperBound(num: Int): Double? = Double.POSITIVE_INFINITY
-
-    override fun nearestInDomain(point: Point<Double>): Point<Double> = point
-
-    override fun volume(): Double = Double.POSITIVE_INFINITY
-}
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnivariateDomain.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnivariateDomain.kt
deleted file mode 100644
index 280dc7d66..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/domains/UnivariateDomain.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package scientifik.kmath.domains
-
-import scientifik.kmath.linear.Point
-import scientifik.kmath.structures.asBuffer
-
-inline class UnivariateDomain(val range: ClosedFloatingPointRange<Double>) : RealDomain {
-    operator fun contains(d: Double): Boolean = range.contains(d)
-
-    override operator fun contains(point: Point<Double>): Boolean {
-        require(point.size == 0)
-        return contains(point[0])
-    }
-
-    override fun nearestInDomain(point: Point<Double>): Point<Double> {
-        require(point.size == 1)
-        val value = point[0]
-        return when {
-            value in range -> point
-            value >= range.endInclusive -> doubleArrayOf(range.endInclusive).asBuffer()
-            else -> doubleArrayOf(range.start).asBuffer()
-        }
-    }
-
-    override fun getLowerBound(num: Int, point: Point<Double>): Double? {
-        require(num == 0)
-        return range.start
-    }
-
-    override fun getUpperBound(num: Int, point: Point<Double>): Double? {
-        require(num == 0)
-        return range.endInclusive
-    }
-
-    override fun getLowerBound(num: Int): Double? {
-        require(num == 0)
-        return range.start
-    }
-
-    override fun getUpperBound(num: Int): Double? {
-        require(num == 0)
-        return range.endInclusive
-    }
-
-    override fun volume(): Double = range.endInclusive - range.start
-
-    override val dimension: Int get() = 1
-}
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt
deleted file mode 100644
index fd11c246d..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/Expression.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-package scientifik.kmath.expressions
-
-import scientifik.kmath.operations.Algebra
-
-/**
- * An elementary function that could be invoked on a map of arguments
- */
-interface Expression<T> {
-    /**
-     * Calls this expression from arguments.
-     *
-     * @param arguments the map of arguments.
-     * @return the value.
-     */
-    operator fun invoke(arguments: Map<String, T>): T
-
-    companion object
-}
-
-/**
- * Create simple lazily evaluated expression inside given algebra
- */
-fun <T> Algebra<T>.expression(block: Algebra<T>.(arguments: Map<String, T>) -> T): Expression<T> =
-    object : Expression<T> {
-        override operator fun invoke(arguments: Map<String, T>): T = block(arguments)
-    }
-
-/**
- * Calls this expression from arguments.
- *
- * @param pairs the pair of arguments' names to values.
- * @return the value.
- */
-operator fun <T> Expression<T>.invoke(vararg pairs: Pair<String, T>): T = invoke(mapOf(*pairs))
-
-/**
- * A context for expression construction
- */
-interface ExpressionAlgebra<T, E> : Algebra<E> {
-    /**
-     * Introduce a variable into expression context
-     */
-    fun variable(name: String, default: T? = null): E
-
-    /**
-     * A constant expression which does not depend on arguments
-     */
-    fun const(value: T): E
-}
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt
deleted file mode 100644
index d36c31a0d..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/expressions/FunctionalExpressionAlgebra.kt
+++ /dev/null
@@ -1,169 +0,0 @@
-package scientifik.kmath.expressions
-
-import scientifik.kmath.operations.*
-
-internal class FunctionalUnaryOperation<T>(val context: Algebra<T>, val name: String, private val expr: Expression<T>) :
-    Expression<T> {
-    override operator fun invoke(arguments: Map<String, T>): T = context.unaryOperation(name, expr.invoke(arguments))
-}
-
-internal class FunctionalBinaryOperation<T>(
-    val context: Algebra<T>,
-    val name: String,
-    val first: Expression<T>,
-    val second: Expression<T>
-) : Expression<T> {
-    override operator fun invoke(arguments: Map<String, T>): T =
-        context.binaryOperation(name, first.invoke(arguments), second.invoke(arguments))
-}
-
-internal class FunctionalVariableExpression<T>(val name: String, val default: T? = null) : Expression<T> {
-    override operator fun invoke(arguments: Map<String, T>): T =
-        arguments[name] ?: default ?: error("Parameter not found: $name")
-}
-
-internal class FunctionalConstantExpression<T>(val value: T) : Expression<T> {
-    override operator fun invoke(arguments: Map<String, T>): T = value
-}
-
-internal class FunctionalConstProductExpression<T>(
-    val context: Space<T>,
-    private val expr: Expression<T>,
-    val const: Number
-) : Expression<T> {
-    override operator fun invoke(arguments: Map<String, T>): T = context.multiply(expr.invoke(arguments), const)
-}
-
-/**
- * A context class for [Expression] construction.
- *
- * @param algebra The algebra to provide for Expressions built.
- */
-abstract class FunctionalExpressionAlgebra<T, A : Algebra<T>>(val algebra: A) : ExpressionAlgebra<T, Expression<T>> {
-    /**
-     * Builds an Expression of constant expression which does not depend on arguments.
-     */
-    override fun const(value: T): Expression<T> = FunctionalConstantExpression(value)
-
-    /**
-     * Builds an Expression to access a variable.
-     */
-    override fun variable(name: String, default: T?): Expression<T> = FunctionalVariableExpression(name, default)
-
-    /**
-     * Builds an Expression of dynamic call of binary operation [operation] on [left] and [right].
-     */
-    override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
-        FunctionalBinaryOperation(algebra, operation, left, right)
-
-    /**
-     * Builds an Expression of dynamic call of unary operation with name [operation] on [arg].
-     */
-    override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
-        FunctionalUnaryOperation(algebra, operation, arg)
-}
-
-/**
- * A context class for [Expression] construction for [Space] algebras.
- */
-open class FunctionalExpressionSpace<T, A : Space<T>>(algebra: A) :
-    FunctionalExpressionAlgebra<T, A>(algebra), Space<Expression<T>> {
-    override val zero: Expression<T> get() = const(algebra.zero)
-
-    /**
-     * Builds an Expression of addition of two another expressions.
-     */
-    override fun add(a: Expression<T>, b: Expression<T>): Expression<T> =
-        binaryOperation(SpaceOperations.PLUS_OPERATION, a, b)
-
-    /**
-     * Builds an Expression of multiplication of expression by number.
-     */
-    override fun multiply(a: Expression<T>, k: Number): Expression<T> =
-        FunctionalConstProductExpression(algebra, a, k)
-
-    operator fun Expression<T>.plus(arg: T): Expression<T> = this + const(arg)
-    operator fun Expression<T>.minus(arg: T): Expression<T> = this - const(arg)
-    operator fun T.plus(arg: Expression<T>): Expression<T> = arg + this
-    operator fun T.minus(arg: Expression<T>): Expression<T> = arg - this
-
-    override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
-        super<FunctionalExpressionAlgebra>.unaryOperation(operation, arg)
-
-    override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
-        super<FunctionalExpressionAlgebra>.binaryOperation(operation, left, right)
-}
-
-open class FunctionalExpressionRing<T, A>(algebra: A) : FunctionalExpressionSpace<T, A>(algebra),
-    Ring<Expression<T>> where  A : Ring<T>, A : NumericAlgebra<T> {
-    override val one: Expression<T>
-        get() = const(algebra.one)
-
-    /**
-     * Builds an Expression of multiplication of two expressions.
-     */
-    override fun multiply(a: Expression<T>, b: Expression<T>): Expression<T> =
-        binaryOperation(RingOperations.TIMES_OPERATION, a, b)
-
-    operator fun Expression<T>.times(arg: T): Expression<T> = this * const(arg)
-    operator fun T.times(arg: Expression<T>): Expression<T> = arg * this
-
-    override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
-        super<FunctionalExpressionSpace>.unaryOperation(operation, arg)
-
-    override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
-        super<FunctionalExpressionSpace>.binaryOperation(operation, left, right)
-}
-
-open class FunctionalExpressionField<T, A>(algebra: A) :
-    FunctionalExpressionRing<T, A>(algebra),
-    Field<Expression<T>> where A : Field<T>, A : NumericAlgebra<T> {
-    /**
-     * Builds an Expression of division an expression by another one.
-     */
-    override fun divide(a: Expression<T>, b: Expression<T>): Expression<T> =
-        binaryOperation(FieldOperations.DIV_OPERATION, a, b)
-
-    operator fun Expression<T>.div(arg: T): Expression<T> = this / const(arg)
-    operator fun T.div(arg: Expression<T>): Expression<T> = arg / this
-
-    override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
-        super<FunctionalExpressionRing>.unaryOperation(operation, arg)
-
-    override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
-        super<FunctionalExpressionRing>.binaryOperation(operation, left, right)
-}
-
-open class FunctionalExpressionExtendedField<T, A>(algebra: A) :
-    FunctionalExpressionField<T, A>(algebra),
-    ExtendedField<Expression<T>> where A : ExtendedField<T>, A : NumericAlgebra<T> {
-    override fun sin(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg)
-    override fun cos(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.COS_OPERATION, arg)
-    override fun asin(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg)
-    override fun acos(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg)
-    override fun atan(arg: Expression<T>): Expression<T> = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg)
-
-    override fun power(arg: Expression<T>, pow: Number): Expression<T> =
-        binaryOperation(PowerOperations.POW_OPERATION, arg, number(pow))
-
-    override fun exp(arg: Expression<T>): Expression<T> = unaryOperation(ExponentialOperations.EXP_OPERATION, arg)
-    override fun ln(arg: Expression<T>): Expression<T> = unaryOperation(ExponentialOperations.LN_OPERATION, arg)
-
-    override fun unaryOperation(operation: String, arg: Expression<T>): Expression<T> =
-        super<FunctionalExpressionField>.unaryOperation(operation, arg)
-
-    override fun binaryOperation(operation: String, left: Expression<T>, right: Expression<T>): Expression<T> =
-        super<FunctionalExpressionField>.binaryOperation(operation, left, right)
-}
-
-inline fun <T, A : Space<T>> A.expressionInSpace(block: FunctionalExpressionSpace<T, A>.() -> Expression<T>): Expression<T> =
-    FunctionalExpressionSpace(this).block()
-
-inline fun <T, A : Ring<T>> A.expressionInRing(block: FunctionalExpressionRing<T, A>.() -> Expression<T>): Expression<T> =
-    FunctionalExpressionRing(this).block()
-
-inline fun <T, A : Field<T>> A.expressionInField(block: FunctionalExpressionField<T, A>.() -> Expression<T>): Expression<T> =
-    FunctionalExpressionField(this).block()
-
-inline fun <T, A : ExtendedField<T>> A.expressionInExtendedField(block: FunctionalExpressionExtendedField<T, A>.() -> Expression<T>): Expression<T> =
-    FunctionalExpressionExtendedField(this).block()
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/BufferMatrix.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/BufferMatrix.kt
deleted file mode 100644
index 343b8287e..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/BufferMatrix.kt
+++ /dev/null
@@ -1,118 +0,0 @@
-package scientifik.kmath.linear
-
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.structures.*
-
-/**
- * Basic implementation of Matrix space based on [NDStructure]
- */
-class BufferMatrixContext<T : Any, R : Ring<T>>(
-    override val elementContext: R,
-    private val bufferFactory: BufferFactory<T>
-) : GenericMatrixContext<T, R> {
-
-    override fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> T): BufferMatrix<T> {
-        val buffer = bufferFactory(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
-        return BufferMatrix(rows, columns, buffer)
-    }
-
-    override fun point(size: Int, initializer: (Int) -> T): Point<T> = bufferFactory(size, initializer)
-
-    companion object
-}
-
-@Suppress("OVERRIDE_BY_INLINE")
-object RealMatrixContext : GenericMatrixContext<Double, RealField> {
-
-    override val elementContext: RealField get() = RealField
-
-    override inline fun produce(rows: Int, columns: Int, initializer: (i: Int, j: Int) -> Double): Matrix<Double> {
-        val buffer = RealBuffer(rows * columns) { offset -> initializer(offset / columns, offset % columns) }
-        return BufferMatrix(rows, columns, buffer)
-    }
-
-    override inline fun point(size: Int, initializer: (Int) -> Double): Point<Double> = RealBuffer(size, initializer)
-}
-
-class BufferMatrix<T : Any>(
-    override val rowNum: Int,
-    override val colNum: Int,
-    val buffer: Buffer<out T>,
-    override val features: Set<MatrixFeature> = emptySet()
-) : FeaturedMatrix<T> {
-
-    init {
-        if (buffer.size != rowNum * colNum) {
-            error("Dimension mismatch for matrix structure")
-        }
-    }
-
-    override val shape: IntArray get() = intArrayOf(rowNum, colNum)
-
-    override fun suggestFeature(vararg features: MatrixFeature): BufferMatrix<T> =
-        BufferMatrix(rowNum, colNum, buffer, this.features + features)
-
-    override operator fun get(index: IntArray): T = get(index[0], index[1])
-
-    override operator fun get(i: Int, j: Int): T = buffer[i * colNum + j]
-
-    override fun elements(): Sequence<Pair<IntArray, T>> = sequence {
-        for (i in 0 until rowNum) for (j in 0 until colNum) yield(intArrayOf(i, j) to get(i, j))
-    }
-
-    override fun equals(other: Any?): Boolean {
-        if (this === other) return true
-        return when (other) {
-            is NDStructure<*> -> return NDStructure.equals(this, other)
-            else -> false
-        }
-    }
-
-    override fun hashCode(): Int {
-        var result = buffer.hashCode()
-        result = 31 * result + features.hashCode()
-        return result
-    }
-
-    override fun toString(): String {
-        return if (rowNum <= 5 && colNum <= 5) {
-            "Matrix(rowsNum = $rowNum, colNum = $colNum, features=$features)\n" +
-                    rows.asSequence().joinToString(prefix = "(", postfix = ")", separator = "\n ") { buffer ->
-                        buffer.asSequence().joinToString(separator = "\t") { it.toString() }
-                    }
-        } else {
-            "Matrix(rowsNum = $rowNum, colNum = $colNum, features=$features)"
-        }
-    }
-}
-
-/**
- * Optimized dot product for real matrices
- */
-infix fun BufferMatrix<Double>.dot(other: BufferMatrix<Double>): BufferMatrix<Double> {
-    require(colNum == other.rowNum) { "Matrix dot operation dimension mismatch: ($rowNum, $colNum) x (${other.rowNum}, ${other.colNum})" }
-
-    val array = DoubleArray(this.rowNum * other.colNum)
-
-    //convert to array to insure there is not memory indirection
-    fun Buffer<out Double>.unsafeArray(): DoubleArray = if (this is RealBuffer) {
-        array
-    } else {
-        DoubleArray(size) { get(it) }
-    }
-
-    val a = this.buffer.unsafeArray()
-    val b = other.buffer.unsafeArray()
-
-    for (i in (0 until rowNum)) {
-        for (j in (0 until other.colNum)) {
-            for (k in (0 until colNum)) {
-                array[i * other.colNum + j] += a[i * colNum + k] * b[k * other.colNum + j]
-            }
-        }
-    }
-
-    val buffer = RealBuffer(array)
-    return BufferMatrix(rowNum, other.colNum, buffer)
-}
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgebra.kt
deleted file mode 100644
index fb49d18ed..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/LinearAlgebra.kt
+++ /dev/null
@@ -1,28 +0,0 @@
-package scientifik.kmath.linear
-
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.Matrix
-import scientifik.kmath.structures.VirtualBuffer
-
-typealias Point<T> = Buffer<T>
-
-/**
- * A group of methods to resolve equation A dot X = B, where A and B are matrices or vectors
- */
-interface LinearSolver<T : Any> {
-    fun solve(a: Matrix<T>, b: Matrix<T>): Matrix<T>
-    fun solve(a: Matrix<T>, b: Point<T>): Point<T> = solve(a, b.asMatrix()).asPoint()
-    fun inverse(a: Matrix<T>): Matrix<T>
-}
-
-/**
- * Convert matrix to vector if it is possible
- */
-fun <T : Any> Matrix<T>.asPoint(): Point<T> =
-    if (this.colNum == 1) {
-        VirtualBuffer(rowNum) { get(it, 0) }
-    } else {
-        error("Can't convert matrix with more than one column to vector")
-    }
-
-fun <T : Any> Point<T>.asMatrix(): VirtualMatrix<T> = VirtualMatrix(size, 1) { i, _ -> get(i) }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixFeatures.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixFeatures.kt
deleted file mode 100644
index 87cfe21b0..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/linear/MatrixFeatures.kt
+++ /dev/null
@@ -1,62 +0,0 @@
-package scientifik.kmath.linear
-
-/**
- * A marker interface representing some matrix feature like diagonal, sparse, zero, etc. Features used to optimize matrix
- * operations performance in some cases.
- */
-interface MatrixFeature
-
-/**
- * The matrix with this feature is considered to have only diagonal non-null elements
- */
-object DiagonalFeature : MatrixFeature
-
-/**
- * Matrix with this feature has all zero elements
- */
-object ZeroFeature : MatrixFeature
-
-/**
- * Matrix with this feature have unit elements on diagonal and zero elements in all other places
- */
-object UnitFeature : MatrixFeature
-
-/**
- * Inverted matrix feature
- */
-interface InverseMatrixFeature<T : Any> : MatrixFeature {
-    val inverse: FeaturedMatrix<T>
-}
-
-/**
- * A determinant container
- */
-interface DeterminantFeature<T : Any> : MatrixFeature {
-    val determinant: T
-}
-
-@Suppress("FunctionName")
-fun <T : Any> DeterminantFeature(determinant: T): DeterminantFeature<T> = object : DeterminantFeature<T> {
-    override val determinant: T = determinant
-}
-
-/**
- * Lower triangular matrix
- */
-object LFeature : MatrixFeature
-
-/**
- * Upper triangular feature
- */
-object UFeature : MatrixFeature
-
-/**
- * TODO add documentation
- */
-interface LUPDecompositionFeature<T : Any> : MatrixFeature {
-    val l: FeaturedMatrix<T>
-    val u: FeaturedMatrix<T>
-    val p: FeaturedMatrix<T>
-}
-
-//TODO add sparse matrix feature
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/cumulative.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/cumulative.kt
deleted file mode 100644
index 6ac03f463..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/misc/cumulative.kt
+++ /dev/null
@@ -1,79 +0,0 @@
-package scientifik.kmath.misc
-
-import scientifik.kmath.operations.Space
-import scientifik.kmath.operations.invoke
-import kotlin.contracts.contract
-import kotlin.jvm.JvmName
-
-/**
- * Generic cumulative operation on iterator.
- *
- * @param T the type of initial iterable.
- * @param R the type of resulting iterable.
- * @param initial lazy evaluated.
- */
-inline fun <T, R> Iterator<T>.cumulative(initial: R, crossinline operation: (R, T) -> R): Iterator<R> {
-    contract { callsInPlace(operation) }
-
-    return object : Iterator<R> {
-        var state: R = initial
-
-        override fun hasNext(): Boolean = this@cumulative.hasNext()
-
-        override fun next(): R {
-            state = operation(state, this@cumulative.next())
-            return state
-        }
-    }
-}
-
-inline fun <T, R> Iterable<T>.cumulative(initial: R, crossinline operation: (R, T) -> R): Iterable<R> =
-    Iterable { this@cumulative.iterator().cumulative(initial, operation) }
-
-inline fun <T, R> Sequence<T>.cumulative(initial: R, crossinline operation: (R, T) -> R): Sequence<R> = Sequence {
-    this@cumulative.iterator().cumulative(initial, operation)
-}
-
-fun <T, R> List<T>.cumulative(initial: R, operation: (R, T) -> R): List<R> =
-    iterator().cumulative(initial, operation).asSequence().toList()
-
-//Cumulative sum
-
-/**
- * Cumulative sum with custom space
- */
-fun <T> Iterable<T>.cumulativeSum(space: Space<T>): Iterable<T> =
-    space { cumulative(zero) { element: T, sum: T -> sum + element } }
-
-@JvmName("cumulativeSumOfDouble")
-fun Iterable<Double>.cumulativeSum(): Iterable<Double> = cumulative(0.0) { element, sum -> sum + element }
-
-@JvmName("cumulativeSumOfInt")
-fun Iterable<Int>.cumulativeSum(): Iterable<Int> = cumulative(0) { element, sum -> sum + element }
-
-@JvmName("cumulativeSumOfLong")
-fun Iterable<Long>.cumulativeSum(): Iterable<Long> = cumulative(0L) { element, sum -> sum + element }
-
-fun <T> Sequence<T>.cumulativeSum(space: Space<T>): Sequence<T> =
-    space { cumulative(zero) { element: T, sum: T -> sum + element } }
-
-@JvmName("cumulativeSumOfDouble")
-fun Sequence<Double>.cumulativeSum(): Sequence<Double> = cumulative(0.0) { element, sum -> sum + element }
-
-@JvmName("cumulativeSumOfInt")
-fun Sequence<Int>.cumulativeSum(): Sequence<Int> = cumulative(0) { element, sum -> sum + element }
-
-@JvmName("cumulativeSumOfLong")
-fun Sequence<Long>.cumulativeSum(): Sequence<Long> = cumulative(0L) { element, sum -> sum + element }
-
-fun <T> List<T>.cumulativeSum(space: Space<T>): List<T> =
-    space { cumulative(zero) { element: T, sum: T -> sum + element } }
-
-@JvmName("cumulativeSumOfDouble")
-fun List<Double>.cumulativeSum(): List<Double> = cumulative(0.0) { element, sum -> sum + element }
-
-@JvmName("cumulativeSumOfInt")
-fun List<Int>.cumulativeSum(): List<Int> = cumulative(0) { element, sum -> sum + element }
-
-@JvmName("cumulativeSumOfLong")
-fun List<Long>.cumulativeSum(): List<Long> = cumulative(0L) { element, sum -> sum + element }
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt
deleted file mode 100644
index 0735a96da..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/operations/NumberAlgebra.kt
+++ /dev/null
@@ -1,270 +0,0 @@
-package scientifik.kmath.operations
-
-import scientifik.kmath.operations.RealField.pow
-import kotlin.math.abs
-import kotlin.math.pow as kpow
-
-/**
- * Advanced Number-like semifield that implements basic operations.
- */
-interface ExtendedFieldOperations<T> :
-    FieldOperations<T>,
-    TrigonometricOperations<T>,
-    HyperbolicOperations<T>,
-    PowerOperations<T>,
-    ExponentialOperations<T> {
-
-    override fun tan(arg: T): T = sin(arg) / cos(arg)
-    override fun tanh(arg: T): T = sinh(arg) / cosh(arg)
-
-    override fun unaryOperation(operation: String, arg: T): T = when (operation) {
-        TrigonometricOperations.COS_OPERATION -> cos(arg)
-        TrigonometricOperations.SIN_OPERATION -> sin(arg)
-        TrigonometricOperations.TAN_OPERATION -> tan(arg)
-        TrigonometricOperations.ACOS_OPERATION -> acos(arg)
-        TrigonometricOperations.ASIN_OPERATION -> asin(arg)
-        TrigonometricOperations.ATAN_OPERATION -> atan(arg)
-        HyperbolicOperations.COSH_OPERATION -> cosh(arg)
-        HyperbolicOperations.SINH_OPERATION -> sinh(arg)
-        HyperbolicOperations.TANH_OPERATION -> tanh(arg)
-        HyperbolicOperations.ACOSH_OPERATION -> acosh(arg)
-        HyperbolicOperations.ASINH_OPERATION -> asinh(arg)
-        HyperbolicOperations.ATANH_OPERATION -> atanh(arg)
-        PowerOperations.SQRT_OPERATION -> sqrt(arg)
-        ExponentialOperations.EXP_OPERATION -> exp(arg)
-        ExponentialOperations.LN_OPERATION -> ln(arg)
-        else -> super.unaryOperation(operation, arg)
-    }
-}
-
-
-/**
- * Advanced Number-like field that implements basic operations.
- */
-interface ExtendedField<T> : ExtendedFieldOperations<T>, Field<T> {
-    override fun sinh(arg: T): T = (exp(arg) - exp(-arg)) / 2
-    override fun cosh(arg: T): T = (exp(arg) + exp(-arg)) / 2
-    override fun tanh(arg: T): T = (exp(arg) - exp(-arg)) / (exp(-arg) + exp(arg))
-    override fun asinh(arg: T): T = ln(sqrt(arg * arg + one) + arg)
-    override fun acosh(arg: T): T = ln(arg + sqrt((arg - one) * (arg + one)))
-    override fun atanh(arg: T): T = (ln(arg + one) - ln(one - arg)) / 2
-
-    override fun rightSideNumberOperation(operation: String, left: T, right: Number): T = when (operation) {
-        PowerOperations.POW_OPERATION -> power(left, right)
-        else -> super.rightSideNumberOperation(operation, left, right)
-    }
-}
-
-/**
- * Real field element wrapping double.
- *
- * @property value the [Double] value wrapped by this [Real].
- *
- * TODO inline does not work due to compiler bug. Waiting for fix for KT-27586
- */
-inline class Real(val value: Double) : FieldElement<Double, Real, RealField> {
-    override val context: RealField
-        get() = RealField
-
-    override fun unwrap(): Double = value
-
-    override fun Double.wrap(): Real = Real(value)
-
-    companion object
-}
-
-/**
- * A field for [Double] without boxing. Does not produce appropriate field element.
- */
-@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-object RealField : ExtendedField<Double>, Norm<Double, Double> {
-    override val zero: Double
-        get() = 0.0
-
-    override val one: Double
-        get() = 1.0
-
-    override fun binaryOperation(operation: String, left: Double, right: Double): Double = when (operation) {
-        PowerOperations.POW_OPERATION -> left pow right
-        else -> super.binaryOperation(operation, left, right)
-    }
-
-    override inline fun add(a: Double, b: Double): Double = a + b
-    override inline fun multiply(a: Double, k: Number): Double = a * k.toDouble()
-
-    override inline fun multiply(a: Double, b: Double): Double = a * b
-
-    override inline fun divide(a: Double, b: Double): Double = a / b
-
-    override inline fun sin(arg: Double): Double = kotlin.math.sin(arg)
-    override inline fun cos(arg: Double): Double = kotlin.math.cos(arg)
-    override inline fun tan(arg: Double): Double = kotlin.math.tan(arg)
-    override inline fun acos(arg: Double): Double = kotlin.math.acos(arg)
-    override inline fun asin(arg: Double): Double = kotlin.math.asin(arg)
-    override inline fun atan(arg: Double): Double = kotlin.math.atan(arg)
-
-    override inline fun sinh(arg: Double): Double = kotlin.math.sinh(arg)
-    override inline fun cosh(arg: Double): Double = kotlin.math.cosh(arg)
-    override inline fun tanh(arg: Double): Double = kotlin.math.tanh(arg)
-    override inline fun asinh(arg: Double): Double = kotlin.math.asinh(arg)
-    override inline fun acosh(arg: Double): Double = kotlin.math.acosh(arg)
-    override inline fun atanh(arg: Double): Double = kotlin.math.atanh(arg)
-
-    override inline fun power(arg: Double, pow: Number): Double = arg.kpow(pow.toDouble())
-    override inline fun exp(arg: Double): Double = kotlin.math.exp(arg)
-    override inline fun ln(arg: Double): Double = kotlin.math.ln(arg)
-
-    override inline fun norm(arg: Double): Double = abs(arg)
-
-    override inline fun Double.unaryMinus(): Double = -this
-    override inline fun Double.plus(b: Double): Double = this + b
-    override inline fun Double.minus(b: Double): Double = this - b
-    override inline fun Double.times(b: Double): Double = this * b
-    override inline fun Double.div(b: Double): Double = this / b
-}
-
-/**
- * A field for [Float] without boxing. Does not produce appropriate field element.
- */
-@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-object FloatField : ExtendedField<Float>, Norm<Float, Float> {
-    override val zero: Float
-        get() = 0.0f
-
-    override val one: Float
-        get() = 1.0f
-
-    override fun binaryOperation(operation: String, left: Float, right: Float): Float = when (operation) {
-        PowerOperations.POW_OPERATION -> left pow right
-        else -> super.binaryOperation(operation, left, right)
-    }
-
-    override inline fun add(a: Float, b: Float): Float = a + b
-    override inline fun multiply(a: Float, k: Number): Float = a * k.toFloat()
-
-    override inline fun multiply(a: Float, b: Float): Float = a * b
-
-    override inline fun divide(a: Float, b: Float): Float = a / b
-
-    override inline fun sin(arg: Float): Float = kotlin.math.sin(arg)
-    override inline fun cos(arg: Float): Float = kotlin.math.cos(arg)
-    override inline fun tan(arg: Float): Float = kotlin.math.tan(arg)
-    override inline fun acos(arg: Float): Float = kotlin.math.acos(arg)
-    override inline fun asin(arg: Float): Float = kotlin.math.asin(arg)
-    override inline fun atan(arg: Float): Float = kotlin.math.atan(arg)
-
-    override inline fun sinh(arg: Float): Float = kotlin.math.sinh(arg)
-    override inline fun cosh(arg: Float): Float = kotlin.math.cosh(arg)
-    override inline fun tanh(arg: Float): Float = kotlin.math.tanh(arg)
-    override inline fun asinh(arg: Float): Float = kotlin.math.asinh(arg)
-    override inline fun acosh(arg: Float): Float = kotlin.math.acosh(arg)
-    override inline fun atanh(arg: Float): Float = kotlin.math.atanh(arg)
-
-    override inline fun power(arg: Float, pow: Number): Float = arg.kpow(pow.toFloat())
-    override inline fun exp(arg: Float): Float = kotlin.math.exp(arg)
-    override inline fun ln(arg: Float): Float = kotlin.math.ln(arg)
-
-    override inline fun norm(arg: Float): Float = abs(arg)
-
-    override inline fun Float.unaryMinus(): Float = -this
-    override inline fun Float.plus(b: Float): Float = this + b
-    override inline fun Float.minus(b: Float): Float = this - b
-    override inline fun Float.times(b: Float): Float = this * b
-    override inline fun Float.div(b: Float): Float = this / b
-}
-
-/**
- * A field for [Int] without boxing. Does not produce corresponding ring element.
- */
-@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-object IntRing : Ring<Int>, Norm<Int, Int> {
-    override val zero: Int
-        get() = 0
-
-    override val one: Int
-        get() = 1
-
-    override inline fun add(a: Int, b: Int): Int = a + b
-    override inline fun multiply(a: Int, k: Number): Int = k.toInt() * a
-
-    override inline fun multiply(a: Int, b: Int): Int = a * b
-
-    override inline fun norm(arg: Int): Int = abs(arg)
-
-    override inline fun Int.unaryMinus(): Int = -this
-    override inline fun Int.plus(b: Int): Int = this + b
-    override inline fun Int.minus(b: Int): Int = this - b
-    override inline fun Int.times(b: Int): Int = this * b
-}
-
-/**
- * A field for [Short] without boxing. Does not produce appropriate ring element.
- */
-@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-object ShortRing : Ring<Short>, Norm<Short, Short> {
-    override val zero: Short
-        get() = 0
-
-    override val one: Short
-        get() = 1
-
-    override inline fun add(a: Short, b: Short): Short = (a + b).toShort()
-    override inline fun multiply(a: Short, k: Number): Short = (a * k.toShort()).toShort()
-
-    override inline fun multiply(a: Short, b: Short): Short = (a * b).toShort()
-
-    override fun norm(arg: Short): Short = if (arg > 0) arg else (-arg).toShort()
-
-    override inline fun Short.unaryMinus(): Short = (-this).toShort()
-    override inline fun Short.plus(b: Short): Short = (this + b).toShort()
-    override inline fun Short.minus(b: Short): Short = (this - b).toShort()
-    override inline fun Short.times(b: Short): Short = (this * b).toShort()
-}
-
-/**
- * A field for [Byte] without boxing. Does not produce appropriate ring element.
- */
-@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-object ByteRing : Ring<Byte>, Norm<Byte, Byte> {
-    override val zero: Byte
-        get() = 0
-
-    override val one: Byte
-        get() = 1
-
-    override inline fun add(a: Byte, b: Byte): Byte = (a + b).toByte()
-    override inline fun multiply(a: Byte, k: Number): Byte = (a * k.toByte()).toByte()
-
-    override inline fun multiply(a: Byte, b: Byte): Byte = (a * b).toByte()
-
-    override fun norm(arg: Byte): Byte = if (arg > 0) arg else (-arg).toByte()
-
-    override inline fun Byte.unaryMinus(): Byte = (-this).toByte()
-    override inline fun Byte.plus(b: Byte): Byte = (this + b).toByte()
-    override inline fun Byte.minus(b: Byte): Byte = (this - b).toByte()
-    override inline fun Byte.times(b: Byte): Byte = (this * b).toByte()
-}
-
-/**
- * A field for [Double] without boxing. Does not produce appropriate ring element.
- */
-@Suppress("EXTENSION_SHADOWED_BY_MEMBER", "OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-object LongRing : Ring<Long>, Norm<Long, Long> {
-    override val zero: Long
-        get() = 0
-
-    override val one: Long
-        get() = 1
-
-    override inline fun add(a: Long, b: Long): Long = a + b
-    override inline fun multiply(a: Long, k: Number): Long = a * k.toLong()
-
-    override inline fun multiply(a: Long, b: Long): Long = a * b
-
-    override fun norm(arg: Long): Long = abs(arg)
-
-    override inline fun Long.unaryMinus(): Long = (-this)
-    override inline fun Long.plus(b: Long): Long = (this + b)
-    override inline fun Long.minus(b: Long): Long = (this - b)
-    override inline fun Long.times(b: Long): Long = (this * b)
-}
diff --git a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDAlgebra.kt b/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDAlgebra.kt
deleted file mode 100644
index 2c0c2021f..000000000
--- a/kmath-core/src/commonMain/kotlin/scientifik/kmath/structures/BufferedNDAlgebra.kt
+++ /dev/null
@@ -1,43 +0,0 @@
-package scientifik.kmath.structures
-
-import scientifik.kmath.operations.*
-
-interface BufferedNDAlgebra<T, C> : NDAlgebra<T, C, NDBuffer<T>> {
-    val strides: Strides
-
-    override fun check(vararg elements: NDBuffer<T>): Unit =
-        require(elements.all { it.strides == strides }) { ("Strides mismatch") }
-
-    /**
-     * Convert any [NDStructure] to buffered structure using strides from this context.
-     * If the structure is already [NDBuffer], conversion is free. If not, it could be expensive because iteration over
-     * indices.
-     *
-     * If the argument is [NDBuffer] with different strides structure, the new element will be produced.
-     */
-    fun NDStructure<T>.toBuffer(): NDBuffer<T> {
-        return if (this is NDBuffer<T> && this.strides == this@BufferedNDAlgebra.strides) {
-            this
-        } else {
-            produce { index -> get(index) }
-        }
-    }
-
-    /**
-     * Convert a buffer to element of this algebra
-     */
-    fun NDBuffer<T>.toElement(): MathElement<out BufferedNDAlgebra<T, C>>
-}
-
-
-interface BufferedNDSpace<T, S : Space<T>> : NDSpace<T, S, NDBuffer<T>>, BufferedNDAlgebra<T, S> {
-    override fun NDBuffer<T>.toElement(): SpaceElement<NDBuffer<T>, *, out BufferedNDSpace<T, S>>
-}
-
-interface BufferedNDRing<T, R : Ring<T>> : NDRing<T, R, NDBuffer<T>>, BufferedNDSpace<T, R> {
-    override fun NDBuffer<T>.toElement(): RingElement<NDBuffer<T>, *, out BufferedNDRing<T, R>>
-}
-
-interface BufferedNDField<T, F : Field<T>> : NDField<T, F, NDBuffer<T>>, BufferedNDRing<T, F> {
-    override fun NDBuffer<T>.toElement(): FieldElement<NDBuffer<T>, *, out BufferedNDField<T, F>>
-}
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/expressions/ExpressionFieldTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/expressions/ExpressionFieldTest.kt
similarity index 87%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/expressions/ExpressionFieldTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/expressions/ExpressionFieldTest.kt
index 485de08b4..1d3f520f6 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/expressions/ExpressionFieldTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/expressions/ExpressionFieldTest.kt
@@ -1,9 +1,9 @@
-package scientifik.kmath.expressions
+package kscience.kmath.expressions
 
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.ComplexField
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.invoke
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.ComplexField
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.invoke
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/linear/MatrixTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/linear/MatrixTest.kt
similarity index 91%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/linear/MatrixTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/linear/MatrixTest.kt
index 52a2f80a6..7cfa25a66 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/linear/MatrixTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/linear/MatrixTest.kt
@@ -1,8 +1,8 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.structures.Matrix
-import scientifik.kmath.structures.NDStructure
-import scientifik.kmath.structures.as2D
+import kscience.kmath.structures.Matrix
+import kscience.kmath.structures.NDStructure
+import kscience.kmath.structures.as2D
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/linear/RealLUSolverTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/linear/RealLUSolverTest.kt
similarity index 92%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/linear/RealLUSolverTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/linear/RealLUSolverTest.kt
index 9de9fb575..de07d3639 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/linear/RealLUSolverTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/linear/RealLUSolverTest.kt
@@ -1,6 +1,6 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.structures.Matrix
+import kscience.kmath.structures.Matrix
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/linear/VectorSpaceTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/linear/VectorSpaceTest.kt
similarity index 100%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/linear/VectorSpaceTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/linear/VectorSpaceTest.kt
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/misc/AutoDiffTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/misc/AutoDiffTest.kt
similarity index 51%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/misc/AutoDiffTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/misc/AutoDiffTest.kt
index c08a63ccb..3b1813185 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/misc/AutoDiffTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/misc/AutoDiffTest.kt
@@ -1,21 +1,21 @@
-package scientifik.kmath.misc
+package kscience.kmath.misc
 
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.structures.asBuffer
+import kscience.kmath.operations.RealField
+import kscience.kmath.structures.asBuffer
 import kotlin.math.PI
+import kotlin.math.pow
+import kotlin.math.sqrt
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertTrue
 
 class AutoDiffTest {
-    fun Variable(int: Int): Variable<Double> = Variable(int.toDouble())
-
-    fun deriv(body: AutoDiffField<Double, RealField>.() -> Variable<Double>): DerivationResult<Double> =
+    inline fun deriv(body: AutoDiffField<Double, RealField>.() -> Variable<Double>): DerivationResult<Double> =
         RealField.deriv(body)
 
     @Test
     fun testPlusX2() {
-        val x = Variable(3) // diff w.r.t this x at 3
+        val x = Variable(3.0) // diff w.r.t this x at 3
         val y = deriv { x + x }
         assertEquals(6.0, y.value) //    y  = x + x = 6
         assertEquals(2.0, y.deriv(x)) // dy/dx = 2
@@ -24,8 +24,8 @@ class AutoDiffTest {
     @Test
     fun testPlus() {
         // two variables
-        val x = Variable(2)
-        val y = Variable(3)
+        val x = Variable(2.0)
+        val y = Variable(3.0)
         val z = deriv { x + y }
         assertEquals(5.0, z.value) //    z  = x + y = 5
         assertEquals(1.0, z.deriv(x)) // dz/dx = 1
@@ -35,8 +35,8 @@ class AutoDiffTest {
     @Test
     fun testMinus() {
         // two variables
-        val x = Variable(7)
-        val y = Variable(3)
+        val x = Variable(7.0)
+        val y = Variable(3.0)
         val z = deriv { x - y }
         assertEquals(4.0, z.value)  //    z  = x - y = 4
         assertEquals(1.0, z.deriv(x))  // dz/dx = 1
@@ -45,7 +45,7 @@ class AutoDiffTest {
 
     @Test
     fun testMulX2() {
-        val x = Variable(3) // diff w.r.t this x at 3
+        val x = Variable(3.0) // diff w.r.t this x at 3
         val y = deriv { x * x }
         assertEquals(9.0, y.value) //    y  = x * x = 9
         assertEquals(6.0, y.deriv(x)) // dy/dx = 2 * x = 7
@@ -53,7 +53,7 @@ class AutoDiffTest {
 
     @Test
     fun testSqr() {
-        val x = Variable(3)
+        val x = Variable(3.0)
         val y = deriv { sqr(x) }
         assertEquals(9.0, y.value) //    y  = x ^ 2 = 9
         assertEquals(6.0, y.deriv(x)) // dy/dx = 2 * x = 7
@@ -61,7 +61,7 @@ class AutoDiffTest {
 
     @Test
     fun testSqrSqr() {
-        val x = Variable(2)
+        val x = Variable(2.0)
         val y = deriv { sqr(sqr(x)) }
         assertEquals(16.0, y.value) //     y = x ^ 4   = 16
         assertEquals(32.0, y.deriv(x)) // dy/dx = 4 * x^3 = 32
@@ -69,7 +69,7 @@ class AutoDiffTest {
 
     @Test
     fun testX3() {
-        val x = Variable(2) // diff w.r.t this x at 2
+        val x = Variable(2.0) // diff w.r.t this x at 2
         val y = deriv { x * x * x }
         assertEquals(8.0, y.value)  //    y  = x * x * x = 8
         assertEquals(12.0, y.deriv(x)) // dy/dx = 3 * x * x = 12
@@ -77,8 +77,8 @@ class AutoDiffTest {
 
     @Test
     fun testDiv() {
-        val x = Variable(5)
-        val y = Variable(2)
+        val x = Variable(5.0)
+        val y = Variable(2.0)
         val z = deriv { x / y }
         assertEquals(2.5, z.value)   //     z =  x / y   = 2.5
         assertEquals(0.5, z.deriv(x))   // dz/dx =  1 / y   = 0.5
@@ -87,7 +87,7 @@ class AutoDiffTest {
 
     @Test
     fun testPow3() {
-        val x = Variable(2) // diff w.r.t this x at 2
+        val x = Variable(2.0) // diff w.r.t this x at 2
         val y = deriv { pow(x, 3) }
         assertEquals(8.0, y.value)  //    y  = x ^ 3     = 8
         assertEquals(12.0, y.deriv(x)) // dy/dx = 3 * x ^ 2 = 12
@@ -95,8 +95,8 @@ class AutoDiffTest {
 
     @Test
     fun testPowFull() {
-        val x = Variable(2)
-        val y = Variable(3)
+        val x = Variable(2.0)
+        val y = Variable(3.0)
         val z = deriv { pow(x, y) }
         assertApprox(8.0, z.value)           //     z = x ^ y = 8
         assertApprox(12.0, z.deriv(x))          // dz/dx = y * x ^ (y - 1) = 12
@@ -105,7 +105,7 @@ class AutoDiffTest {
 
     @Test
     fun testFromPaper() {
-        val x = Variable(3)
+        val x = Variable(3.0)
         val y = deriv { 2 * x + x * x * x }
         assertEquals(33.0, y.value)  //     y = 2 * x + x * x * x = 33
         assertEquals(29.0, y.deriv(x))  // dy/dx = 2 + 3 * x * x = 29
@@ -113,9 +113,9 @@ class AutoDiffTest {
 
     @Test
     fun testInnerVariable() {
-        val x = Variable(1)
+        val x = Variable(1.0)
         val y = deriv {
-            Variable(1) * x
+            Variable(1.0) * x
         }
         assertEquals(1.0, y.value)          //     y = x ^ n = 1
         assertEquals(1.0, y.deriv(x)) // dy/dx = n * x ^ (n - 1) = n - 1
@@ -124,9 +124,9 @@ class AutoDiffTest {
     @Test
     fun testLongChain() {
         val n = 10_000
-        val x = Variable(1)
+        val x = Variable(1.0)
         val y = deriv {
-            var res = Variable(1)
+            var res = Variable(1.0)
             for (i in 1..n) res *= x
             res
         }
@@ -136,7 +136,7 @@ class AutoDiffTest {
 
     @Test
     fun testExample() {
-        val x = Variable(2)
+        val x = Variable(2.0)
         val y = deriv { sqr(x) + 5 * x + 3 }
         assertEquals(17.0, y.value) // the value of result (y)
         assertEquals(9.0, y.deriv(x))  // dy/dx
@@ -144,7 +144,7 @@ class AutoDiffTest {
 
     @Test
     fun testSqrt() {
-        val x = Variable(16)
+        val x = Variable(16.0)
         val y = deriv { sqrt(x) }
         assertEquals(4.0, y.value)     //     y = x ^ 1/2 = 4
         assertEquals(1.0 / 8, y.deriv(x)) // dy/dx = 1/2 / x ^ 1/4 = 1/8
@@ -152,18 +152,98 @@ class AutoDiffTest {
 
     @Test
     fun testSin() {
-        val x = Variable(PI / 6)
+        val x = Variable(PI / 6.0)
         val y = deriv { sin(x) }
-        assertApprox(0.5, y.value)           //    y = sin(PI/6) = 0.5
-        assertApprox(kotlin.math.sqrt(3.0) / 2, y.deriv(x)) // dy/dx = cos(PI/6) = sqrt(3)/2
+        assertApprox(0.5, y.value) // y = sin(PI/6) = 0.5
+        assertApprox(sqrt(3.0) / 2, y.deriv(x)) // dy/dx = cos(pi/6) = sqrt(3)/2
     }
 
     @Test
     fun testCos() {
         val x = Variable(PI / 6)
         val y = deriv { cos(x) }
-        assertApprox(kotlin.math.sqrt(3.0) / 2, y.value) //     y =  cos(PI/6) = sqrt(3)/2
-        assertApprox(-0.5, y.deriv(x))          // dy/dx = -sin(PI/6) = -0.5
+        assertApprox(sqrt(3.0) / 2, y.value) //y = cos(pi/6) = sqrt(3)/2
+        assertApprox(-0.5, y.deriv(x)) // dy/dx = -sin(pi/6) = -0.5
+    }
+
+    @Test
+    fun testTan() {
+        val x = Variable(PI / 6)
+        val y = deriv { tan(x) }
+        assertApprox(1.0 / sqrt(3.0), y.value) // y = tan(pi/6) = 1/sqrt(3)
+        assertApprox(4.0 / 3.0, y.deriv(x)) // dy/dx = sec(pi/6)^2 = 4/3
+    }
+
+    @Test
+    fun testAsin() {
+        val x = Variable(PI / 6)
+        val y = deriv { asin(x) }
+        assertApprox(kotlin.math.asin(PI / 6.0), y.value) // y = asin(pi/6)
+        assertApprox(6.0 / sqrt(36 - PI * PI), y.deriv(x)) // dy/dx = 6/sqrt(36-pi^2)
+    }
+
+    @Test
+    fun testAcos() {
+        val x = Variable(PI / 6)
+        val y = deriv { acos(x) }
+        assertApprox(kotlin.math.acos(PI / 6.0), y.value) // y = acos(pi/6)
+        assertApprox(-6.0 / sqrt(36.0 - PI * PI), y.deriv(x)) // dy/dx = -6/sqrt(36-pi^2)
+    }
+
+    @Test
+    fun testAtan() {
+        val x = Variable(PI / 6)
+        val y = deriv { atan(x) }
+        assertApprox(kotlin.math.atan(PI / 6.0), y.value) // y = atan(pi/6)
+        assertApprox(36.0 / (36.0 + PI * PI), y.deriv(x)) // dy/dx = 36/(36+pi^2)
+    }
+
+    @Test
+    fun testSinh() {
+        val x = Variable(0.0)
+        val y = deriv { sinh(x) }
+        assertApprox(kotlin.math.sinh(0.0), y.value) // y = sinh(0)
+        assertApprox(kotlin.math.cosh(0.0), y.deriv(x)) // dy/dx = cosh(0)
+    }
+
+    @Test
+    fun testCosh() {
+        val x = Variable(0.0)
+        val y = deriv { cosh(x) }
+        assertApprox(1.0, y.value) //y = cosh(0)
+        assertApprox(0.0, y.deriv(x)) // dy/dx = sinh(0)
+    }
+
+    @Test
+    fun testTanh() {
+        val x = Variable(PI / 6)
+        val y = deriv { tanh(x) }
+        assertApprox(1.0 / sqrt(3.0), y.value) // y = tanh(pi/6)
+        assertApprox(1.0 / kotlin.math.cosh(PI / 6.0).pow(2), y.deriv(x)) // dy/dx = sech(pi/6)^2
+    }
+
+    @Test
+    fun testAsinh() {
+        val x = Variable(PI / 6)
+        val y = deriv { asinh(x) }
+        assertApprox(kotlin.math.asinh(PI / 6.0), y.value) // y = asinh(pi/6)
+        assertApprox(6.0 / sqrt(36 + PI * PI), y.deriv(x)) // dy/dx = 6/sqrt(pi^2+36)
+    }
+
+    @Test
+    fun testAcosh() {
+        val x = Variable(PI / 6)
+        val y = deriv { acosh(x) }
+        assertApprox(kotlin.math.acosh(PI / 6.0), y.value) // y = acosh(pi/6)
+        assertApprox(-6.0 / sqrt(36.0 - PI * PI), y.deriv(x)) // dy/dx = -6/sqrt(36-pi^2)
+    }
+
+    @Test
+    fun testAtanh() {
+        val x = Variable(PI / 6.0)
+        val y = deriv { atanh(x) }
+        assertApprox(kotlin.math.atanh(PI / 6.0), y.value) // y = atanh(pi/6)
+        assertApprox(-36.0 / (PI * PI - 36.0), y.deriv(x)) // dy/dx = -36/(pi^2-36)
     }
 
     @Test
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/misc/CumulativeKtTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/misc/CumulativeKtTest.kt
similarity index 90%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/misc/CumulativeKtTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/misc/CumulativeKtTest.kt
index 82ea5318f..1e6d2fd5d 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/misc/CumulativeKtTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/misc/CumulativeKtTest.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.misc
+package kscience.kmath.misc
 
 import kotlin.test.Test
 import kotlin.test.assertEquals
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntAlgebraTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntAlgebraTest.kt
similarity index 94%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntAlgebraTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntAlgebraTest.kt
index d140f1017..78611e5d2 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntAlgebraTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntAlgebraTest.kt
@@ -1,6 +1,6 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
-import scientifik.kmath.operations.internal.RingVerifier
+import kscience.kmath.operations.internal.RingVerifier
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntConstructorTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntConstructorTest.kt
similarity index 93%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntConstructorTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntConstructorTest.kt
index 5e3f6d1b0..ba2582bbf 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntConstructorTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntConstructorTest.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 import kotlin.test.Test
 import kotlin.test.assertEquals
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntConversionsTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntConversionsTest.kt
similarity index 96%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntConversionsTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntConversionsTest.kt
index 41df1968d..0b433c436 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntConversionsTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntConversionsTest.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 import kotlin.test.Test
 import kotlin.test.assertEquals
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntOperationsTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntOperationsTest.kt
similarity index 99%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntOperationsTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntOperationsTest.kt
index b7f4cf43b..a3ed85c7b 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/BigIntOperationsTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/BigIntOperationsTest.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 import kotlin.test.Test
 import kotlin.test.assertEquals
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexFieldTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/ComplexFieldTest.kt
similarity index 96%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexFieldTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/ComplexFieldTest.kt
index 2c480ebea..c0b4853f4 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexFieldTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/ComplexFieldTest.kt
@@ -1,6 +1,6 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
-import scientifik.kmath.operations.internal.FieldVerifier
+import kscience.kmath.operations.internal.FieldVerifier
 import kotlin.math.PI
 import kotlin.math.abs
 import kotlin.test.Test
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/ComplexTest.kt
similarity index 96%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/ComplexTest.kt
index e8d698c70..f8b9b7262 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/ComplexTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/ComplexTest.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
 import kotlin.test.Test
 import kotlin.test.assertEquals
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/RealFieldTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/RealFieldTest.kt
similarity index 75%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/RealFieldTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/RealFieldTest.kt
index a168b4afd..5705733cf 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/RealFieldTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/RealFieldTest.kt
@@ -1,6 +1,6 @@
-package scientifik.kmath.operations
+package kscience.kmath.operations
 
-import scientifik.kmath.operations.internal.FieldVerifier
+import kscience.kmath.operations.internal.FieldVerifier
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/AlgebraicVerifier.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/AlgebraicVerifier.kt
similarity index 55%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/AlgebraicVerifier.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/AlgebraicVerifier.kt
index cb097d46e..7334c13a3 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/AlgebraicVerifier.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/AlgebraicVerifier.kt
@@ -1,6 +1,6 @@
-package scientifik.kmath.operations.internal
+package kscience.kmath.operations.internal
 
-import scientifik.kmath.operations.Algebra
+import kscience.kmath.operations.Algebra
 
 internal interface AlgebraicVerifier<T, out A> where A : Algebra<T> {
     val algebra: A
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/FieldVerifier.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/FieldVerifier.kt
similarity index 88%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/FieldVerifier.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/FieldVerifier.kt
index 973fd00b1..1ca09ab0c 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/FieldVerifier.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/FieldVerifier.kt
@@ -1,7 +1,7 @@
-package scientifik.kmath.operations.internal
+package kscience.kmath.operations.internal
 
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.invoke
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.invoke
 import kotlin.test.assertEquals
 import kotlin.test.assertNotEquals
 
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/RingVerifier.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/RingVerifier.kt
similarity index 92%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/RingVerifier.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/RingVerifier.kt
index 047a213e9..863169b9b 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/RingVerifier.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/RingVerifier.kt
@@ -1,7 +1,7 @@
-package scientifik.kmath.operations.internal
+package kscience.kmath.operations.internal
 
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.invoke
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.invoke
 import kotlin.test.assertEquals
 
 internal open class RingVerifier<T>(override val algebra: Ring<T>, a: T, b: T, c: T, x: Number) :
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/SpaceVerifier.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/SpaceVerifier.kt
similarity index 92%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/SpaceVerifier.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/SpaceVerifier.kt
index bc241c97d..4dc855829 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/operations/internal/SpaceVerifier.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/operations/internal/SpaceVerifier.kt
@@ -1,7 +1,7 @@
-package scientifik.kmath.operations.internal
+package kscience.kmath.operations.internal
 
-import scientifik.kmath.operations.Space
-import scientifik.kmath.operations.invoke
+import kscience.kmath.operations.Space
+import kscience.kmath.operations.invoke
 import kotlin.test.assertEquals
 import kotlin.test.assertNotEquals
 
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/ComplexBufferSpecTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/ComplexBufferSpecTest.kt
similarity index 68%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/ComplexBufferSpecTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/structures/ComplexBufferSpecTest.kt
index cbbe6f0f4..4837236db 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/ComplexBufferSpecTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/ComplexBufferSpecTest.kt
@@ -1,7 +1,7 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.Complex
-import scientifik.kmath.operations.complex
+import kscience.kmath.operations.Complex
+import kscience.kmath.operations.complex
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NDFieldTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NDFieldTest.kt
similarity index 87%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NDFieldTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NDFieldTest.kt
index 7abeefca6..79b56ea4a 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NDFieldTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NDFieldTest.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
 import kotlin.test.Test
 import kotlin.test.assertEquals
diff --git a/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NumberNDFieldTest.kt b/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NumberNDFieldTest.kt
similarity index 90%
rename from kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NumberNDFieldTest.kt
rename to kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NumberNDFieldTest.kt
index b7e2594ec..f5e008ef3 100644
--- a/kmath-core/src/commonTest/kotlin/scientifik/kmath/structures/NumberNDFieldTest.kt
+++ b/kmath-core/src/commonTest/kotlin/kscience/kmath/structures/NumberNDFieldTest.kt
@@ -1,8 +1,8 @@
-package scientifik.kmath.structures
+package kscience.kmath.structures
 
-import scientifik.kmath.operations.Norm
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.structures.NDElement.Companion.real2D
+import kscience.kmath.operations.Norm
+import kscience.kmath.operations.invoke
+import kscience.kmath.structures.NDElement.Companion.real2D
 import kotlin.math.abs
 import kotlin.math.pow
 import kotlin.test.Test
diff --git a/kmath-core/src/jvmMain/kotlin/kscience/kmath/operations/BigNumbers.kt b/kmath-core/src/jvmMain/kotlin/kscience/kmath/operations/BigNumbers.kt
new file mode 100644
index 000000000..2f0978237
--- /dev/null
+++ b/kmath-core/src/jvmMain/kotlin/kscience/kmath/operations/BigNumbers.kt
@@ -0,0 +1,59 @@
+package kscience.kmath.operations
+
+import java.math.BigDecimal
+import java.math.BigInteger
+import java.math.MathContext
+
+/**
+ * A field over [BigInteger].
+ */
+public object JBigIntegerField : Field<BigInteger> {
+    public override val zero: BigInteger
+        get() = BigInteger.ZERO
+
+    public override val one: BigInteger
+        get() = BigInteger.ONE
+
+    public override fun number(value: Number): BigInteger = BigInteger.valueOf(value.toLong())
+    public override fun divide(a: BigInteger, b: BigInteger): BigInteger = a.div(b)
+    public override fun add(a: BigInteger, b: BigInteger): BigInteger = a.add(b)
+    public override operator fun BigInteger.minus(b: BigInteger): BigInteger = subtract(b)
+    public override fun multiply(a: BigInteger, k: Number): BigInteger = a.multiply(k.toInt().toBigInteger())
+    public override fun multiply(a: BigInteger, b: BigInteger): BigInteger = a.multiply(b)
+    public override operator fun BigInteger.unaryMinus(): BigInteger = negate()
+}
+
+/**
+ * An abstract field over [BigDecimal].
+ *
+ * @property mathContext the [MathContext] to use.
+ */
+public abstract class JBigDecimalFieldBase internal constructor(public val mathContext: MathContext = MathContext.DECIMAL64) :
+    Field<BigDecimal>,
+    PowerOperations<BigDecimal> {
+    public override val zero: BigDecimal
+        get() = BigDecimal.ZERO
+
+    public override val one: BigDecimal
+        get() = BigDecimal.ONE
+
+    public override fun add(a: BigDecimal, b: BigDecimal): BigDecimal = a.add(b)
+    public override operator fun BigDecimal.minus(b: BigDecimal): BigDecimal = subtract(b)
+    public override fun number(value: Number): BigDecimal = BigDecimal.valueOf(value.toDouble())
+
+    public override fun multiply(a: BigDecimal, k: Number): BigDecimal =
+        a.multiply(k.toDouble().toBigDecimal(mathContext), mathContext)
+
+    public override fun multiply(a: BigDecimal, b: BigDecimal): BigDecimal = a.multiply(b, mathContext)
+    public override fun divide(a: BigDecimal, b: BigDecimal): BigDecimal = a.divide(b, mathContext)
+    public override fun power(arg: BigDecimal, pow: Number): BigDecimal = arg.pow(pow.toInt(), mathContext)
+    public override fun sqrt(arg: BigDecimal): BigDecimal = arg.sqrt(mathContext)
+    public override operator fun BigDecimal.unaryMinus(): BigDecimal = negate(mathContext)
+}
+
+/**
+ * A field over [BigDecimal].
+ */
+public class JBigDecimalField(mathContext: MathContext = MathContext.DECIMAL64) : JBigDecimalFieldBase(mathContext) {
+    public companion object : JBigDecimalFieldBase()
+}
diff --git a/kmath-core/src/jvmMain/kotlin/scientifik/kmath/operations/BigNumbers.kt b/kmath-core/src/jvmMain/kotlin/scientifik/kmath/operations/BigNumbers.kt
deleted file mode 100644
index f10ef24da..000000000
--- a/kmath-core/src/jvmMain/kotlin/scientifik/kmath/operations/BigNumbers.kt
+++ /dev/null
@@ -1,59 +0,0 @@
-package scientifik.kmath.operations
-
-import java.math.BigDecimal
-import java.math.BigInteger
-import java.math.MathContext
-
-/**
- * A field over [BigInteger].
- */
-object JBigIntegerField : Field<BigInteger> {
-    override val zero: BigInteger
-        get() = BigInteger.ZERO
-
-    override val one: BigInteger
-        get() = BigInteger.ONE
-
-    override fun number(value: Number): BigInteger = BigInteger.valueOf(value.toLong())
-    override fun divide(a: BigInteger, b: BigInteger): BigInteger = a.div(b)
-    override fun add(a: BigInteger, b: BigInteger): BigInteger = a.add(b)
-    override operator fun BigInteger.minus(b: BigInteger): BigInteger = subtract(b)
-    override fun multiply(a: BigInteger, k: Number): BigInteger = a.multiply(k.toInt().toBigInteger())
-    override fun multiply(a: BigInteger, b: BigInteger): BigInteger = a.multiply(b)
-    override operator fun BigInteger.unaryMinus(): BigInteger = negate()
-}
-
-/**
- * An abstract field over [BigDecimal].
- *
- * @property mathContext the [MathContext] to use.
- */
-abstract class JBigDecimalFieldBase internal constructor(val mathContext: MathContext = MathContext.DECIMAL64) :
-    Field<BigDecimal>,
-    PowerOperations<BigDecimal> {
-    override val zero: BigDecimal
-        get() = BigDecimal.ZERO
-
-    override val one: BigDecimal
-        get() = BigDecimal.ONE
-
-    override fun add(a: BigDecimal, b: BigDecimal): BigDecimal = a.add(b)
-    override operator fun BigDecimal.minus(b: BigDecimal): BigDecimal = subtract(b)
-    override fun number(value: Number): BigDecimal = BigDecimal.valueOf(value.toDouble())
-
-    override fun multiply(a: BigDecimal, k: Number): BigDecimal =
-        a.multiply(k.toDouble().toBigDecimal(mathContext), mathContext)
-
-    override fun multiply(a: BigDecimal, b: BigDecimal): BigDecimal = a.multiply(b, mathContext)
-    override fun divide(a: BigDecimal, b: BigDecimal): BigDecimal = a.divide(b, mathContext)
-    override fun power(arg: BigDecimal, pow: Number): BigDecimal = arg.pow(pow.toInt(), mathContext)
-    override fun sqrt(arg: BigDecimal): BigDecimal = arg.sqrt(mathContext)
-    override operator fun BigDecimal.unaryMinus(): BigDecimal = negate(mathContext)
-}
-
-/**
- * A field over [BigDecimal].
- */
-class JBigDecimalField(mathContext: MathContext = MathContext.DECIMAL64) : JBigDecimalFieldBase(mathContext) {
-    companion object : JBigDecimalFieldBase()
-}
diff --git a/kmath-coroutines/build.gradle.kts b/kmath-coroutines/build.gradle.kts
index bbbddeba3..e108c2755 100644
--- a/kmath-coroutines/build.gradle.kts
+++ b/kmath-coroutines/build.gradle.kts
@@ -1,7 +1,4 @@
-plugins {
-    id("scientifik.mpp")
-    //id("scientifik.atomic")
-}
+plugins { id("ru.mipt.npm.mpp") }
 
 kotlin.sourceSets {
     all {
@@ -15,15 +12,7 @@ kotlin.sourceSets {
     commonMain {
         dependencies {
             api(project(":kmath-core"))
-            api("org.jetbrains.kotlinx:kotlinx-coroutines-core-common:${Scientifik.coroutinesVersion}")
+            api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}")
         }
     }
-
-    jvmMain {
-        dependencies { api("org.jetbrains.kotlinx:kotlinx-coroutines-core:${Scientifik.coroutinesVersion}") }
-    }
-
-    jsMain {
-        dependencies { api("org.jetbrains.kotlinx:kotlinx-coroutines-core-js:${Scientifik.coroutinesVersion}") }
-    }
 }
diff --git a/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/BlockingIntChain.kt b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/BlockingIntChain.kt
new file mode 100644
index 000000000..6088267a2
--- /dev/null
+++ b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/BlockingIntChain.kt
@@ -0,0 +1,12 @@
+package kscience.kmath.chains
+
+/**
+ * Performance optimized chain for integer values
+ */
+public abstract class BlockingIntChain : Chain<Int> {
+    public abstract fun nextInt(): Int
+
+    override suspend fun next(): Int = nextInt()
+
+    public fun nextBlock(size: Int): IntArray = IntArray(size) { nextInt() }
+}
diff --git a/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/BlockingRealChain.kt b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/BlockingRealChain.kt
new file mode 100644
index 000000000..718b3a18b
--- /dev/null
+++ b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/BlockingRealChain.kt
@@ -0,0 +1,12 @@
+package kscience.kmath.chains
+
+/**
+ * Performance optimized chain for real values
+ */
+public abstract class BlockingRealChain : Chain<Double> {
+    public abstract fun nextDouble(): Double
+
+    override suspend fun next(): Double = nextDouble()
+
+    public fun nextBlock(size: Int): DoubleArray = DoubleArray(size) { nextDouble() }
+}
diff --git a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/Chain.kt b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/Chain.kt
similarity index 62%
rename from kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/Chain.kt
rename to kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/Chain.kt
index f0ffd13cd..8c15e52c7 100644
--- a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/Chain.kt
+++ b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/Chain.kt
@@ -14,7 +14,7 @@
  *  limitations under the License.
  */
 
-package scientifik.kmath.chains
+package kscience.kmath.chains
 
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.FlowCollector
@@ -26,47 +26,44 @@ import kotlinx.coroutines.sync.withLock
  * A not-necessary-Markov chain of some type
  * @param R - the chain element type
  */
-interface Chain<out R> : Flow<R> {
+public interface Chain<out R> : Flow<R> {
     /**
      * Generate next value, changing state if needed
      */
-    suspend fun next(): R
+    public suspend fun next(): R
 
     /**
      * Create a copy of current chain state. Consuming resulting chain does not affect initial chain
      */
-    fun fork(): Chain<R>
+    public fun fork(): Chain<R>
 
     override suspend fun collect(collector: FlowCollector<R>): Unit =
         flow { while (true) emit(next()) }.collect(collector)
 
-    companion object
+    public companion object
 }
 
-
-fun <T> Iterator<T>.asChain(): Chain<T> = SimpleChain { next() }
-fun <T> Sequence<T>.asChain(): Chain<T> = iterator().asChain()
+public fun <T> Iterator<T>.asChain(): Chain<T> = SimpleChain { next() }
+public fun <T> Sequence<T>.asChain(): Chain<T> = iterator().asChain()
 
 /**
  * A simple chain of independent tokens
  */
-class SimpleChain<out R>(private val gen: suspend () -> R) : Chain<R> {
-    override suspend fun next(): R = gen()
-    override fun fork(): Chain<R> = this
+public class SimpleChain<out R>(private val gen: suspend () -> R) : Chain<R> {
+    public override suspend fun next(): R = gen()
+    public override fun fork(): Chain<R> = this
 }
 
 /**
  * A stateless Markov chain
  */
-class MarkovChain<out R : Any>(private val seed: suspend () -> R, private val gen: suspend (R) -> R) : Chain<R> {
-
-    private val mutex = Mutex()
-
+public class MarkovChain<out R : Any>(private val seed: suspend () -> R, private val gen: suspend (R) -> R) : Chain<R> {
+    private val mutex: Mutex = Mutex()
     private var value: R? = null
 
-    fun value(): R? = value
+    public fun value(): R? = value
 
-    override suspend fun next(): R {
+    public override suspend fun next(): R {
         mutex.withLock {
             val newValue = gen(value ?: seed())
             value = newValue
@@ -74,9 +71,7 @@ class MarkovChain<out R : Any>(private val seed: suspend () -> R, private val ge
         }
     }
 
-    override fun fork(): Chain<R> {
-        return MarkovChain(seed = { value ?: seed() }, gen = gen)
-    }
+    public override fun fork(): Chain<R> = MarkovChain(seed = { value ?: seed() }, gen = gen)
 }
 
 /**
@@ -84,19 +79,18 @@ class MarkovChain<out R : Any>(private val seed: suspend () -> R, private val ge
  * @param S - the state of the chain
  * @param forkState - the function to copy current state without modifying it
  */
-class StatefulChain<S, out R>(
+public class StatefulChain<S, out R>(
     private val state: S,
     private val seed: S.() -> R,
     private val forkState: ((S) -> S),
     private val gen: suspend S.(R) -> R
 ) : Chain<R> {
     private val mutex: Mutex = Mutex()
-
     private var value: R? = null
 
-    fun value(): R? = value
+    public fun value(): R? = value
 
-    override suspend fun next(): R {
+    public override suspend fun next(): R {
         mutex.withLock {
             val newValue = state.gen(value ?: state.seed())
             value = newValue
@@ -104,25 +98,22 @@ class StatefulChain<S, out R>(
         }
     }
 
-    override fun fork(): Chain<R> = StatefulChain(forkState(state), seed, forkState, gen)
+    public override fun fork(): Chain<R> = StatefulChain(forkState(state), seed, forkState, gen)
 }
 
 /**
  * A chain that repeats the same value
  */
-class ConstantChain<out T>(val value: T) : Chain<T> {
-    override suspend fun next(): T = value
-
-    override fun fork(): Chain<T> {
-        return this
-    }
+public class ConstantChain<out T>(public val value: T) : Chain<T> {
+    public override suspend fun next(): T = value
+    public override fun fork(): Chain<T> = this
 }
 
 /**
  * Map the chain result using suspended transformation. Initial chain result can no longer be safely consumed
  * since mapped chain consumes tokens. Accepts regular transformation function
  */
-fun <T, R> Chain<T>.map(func: suspend (T) -> R): Chain<R> = object : Chain<R> {
+public fun <T, R> Chain<T>.map(func: suspend (T) -> R): Chain<R> = object : Chain<R> {
     override suspend fun next(): R = func(this@map.next())
     override fun fork(): Chain<R> = this@map.fork().map(func)
 }
@@ -130,7 +121,7 @@ fun <T, R> Chain<T>.map(func: suspend (T) -> R): Chain<R> = object : Chain<R> {
 /**
  * [block] must be a pure function or at least not use external random variables, otherwise fork could be broken
  */
-fun <T> Chain<T>.filter(block: (T) -> Boolean): Chain<T> = object : Chain<T> {
+public fun <T> Chain<T>.filter(block: (T) -> Boolean): Chain<T> = object : Chain<T> {
     override suspend fun next(): T {
         var next: T
 
@@ -146,23 +137,26 @@ fun <T> Chain<T>.filter(block: (T) -> Boolean): Chain<T> = object : Chain<T> {
 /**
  * Map the whole chain
  */
-fun <T, R> Chain<T>.collect(mapper: suspend (Chain<T>) -> R): Chain<R> = object : Chain<R> {
+public fun <T, R> Chain<T>.collect(mapper: suspend (Chain<T>) -> R): Chain<R> = object : Chain<R> {
     override suspend fun next(): R = mapper(this@collect)
     override fun fork(): Chain<R> = this@collect.fork().collect(mapper)
 }
 
-fun <T, S, R> Chain<T>.collectWithState(state: S, stateFork: (S) -> S, mapper: suspend S.(Chain<T>) -> R): Chain<R> =
-    object : Chain<R> {
-        override suspend fun next(): R = state.mapper(this@collectWithState)
+public fun <T, S, R> Chain<T>.collectWithState(
+    state: S,
+    stateFork: (S) -> S,
+    mapper: suspend S.(Chain<T>) -> R
+): Chain<R> = object : Chain<R> {
+    override suspend fun next(): R = state.mapper(this@collectWithState)
 
-        override fun fork(): Chain<R> =
-            this@collectWithState.fork().collectWithState(stateFork(state), stateFork, mapper)
-    }
+    override fun fork(): Chain<R> =
+        this@collectWithState.fork().collectWithState(stateFork(state), stateFork, mapper)
+}
 
 /**
  * Zip two chains together using given transformation
  */
-fun <T, U, R> Chain<T>.zip(other: Chain<U>, block: suspend (T, U) -> R): Chain<R> = object : Chain<R> {
+public fun <T, U, R> Chain<T>.zip(other: Chain<U>, block: suspend (T, U) -> R): Chain<R> = object : Chain<R> {
     override suspend fun next(): R = block(this@zip.next(), other.next())
     override fun fork(): Chain<R> = this@zip.fork().zip(other.fork(), block)
 }
diff --git a/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/flowExtra.kt b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/flowExtra.kt
new file mode 100644
index 000000000..6b14057fe
--- /dev/null
+++ b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/chains/flowExtra.kt
@@ -0,0 +1,26 @@
+package kscience.kmath.chains
+
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.runningReduce
+import kotlinx.coroutines.flow.scan
+import kscience.kmath.operations.Space
+import kscience.kmath.operations.SpaceOperations
+import kscience.kmath.operations.invoke
+
+@ExperimentalCoroutinesApi
+public fun <T> Flow<T>.cumulativeSum(space: SpaceOperations<T>): Flow<T> =
+    space { runningReduce { sum, element -> sum + element } }
+
+@ExperimentalCoroutinesApi
+public fun <T> Flow<T>.mean(space: Space<T>): Flow<T> = space {
+    data class Accumulator(var sum: T, var num: Int)
+
+    scan(Accumulator(zero, 0)) { sum, element ->
+        sum.apply {
+            this.sum += element
+            this.num += 1
+        }
+    }.map { it.sum / it.num }
+}
diff --git a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/coroutines/coroutinesExtra.kt b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/coroutines/coroutinesExtra.kt
similarity index 60%
rename from kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/coroutines/coroutinesExtra.kt
rename to kmath-coroutines/src/commonMain/kotlin/kscience/kmath/coroutines/coroutinesExtra.kt
index 692f89589..351207111 100644
--- a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/coroutines/coroutinesExtra.kt
+++ b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/coroutines/coroutinesExtra.kt
@@ -1,11 +1,10 @@
-package scientifik.kmath.coroutines
+package kscience.kmath.coroutines
 
 import kotlinx.coroutines.*
 import kotlinx.coroutines.channels.produce
 import kotlinx.coroutines.flow.*
-import kotlin.contracts.contract
 
-val Dispatchers.Math: CoroutineDispatcher
+public val Dispatchers.Math: CoroutineDispatcher
     get() = Default
 
 /**
@@ -15,31 +14,25 @@ internal class LazyDeferred<T>(val dispatcher: CoroutineDispatcher, val block: s
     private var deferred: Deferred<T>? = null
 
     internal fun start(scope: CoroutineScope) {
-        if (deferred == null) {
-            deferred = scope.async(dispatcher, block = block)
-        }
+        if (deferred == null) deferred = scope.async(dispatcher, block = block)
     }
 
     suspend fun await(): T = deferred?.await() ?: error("Coroutine not started")
 }
 
-class AsyncFlow<T> internal constructor(internal val deferredFlow: Flow<LazyDeferred<T>>) : Flow<T> {
-    override suspend fun collect(collector: FlowCollector<T>) {
-        deferredFlow.collect { collector.emit((it.await())) }
-    }
+public class AsyncFlow<T> internal constructor(internal val deferredFlow: Flow<LazyDeferred<T>>) : Flow<T> {
+    override suspend fun collect(collector: FlowCollector<T>): Unit = deferredFlow.collect { collector.emit((it.await())) }
 }
 
-fun <T, R> Flow<T>.async(
+public fun <T, R> Flow<T>.async(
     dispatcher: CoroutineDispatcher = Dispatchers.Default,
     block: suspend CoroutineScope.(T) -> R
 ): AsyncFlow<R> {
-    val flow = map {
-        LazyDeferred(dispatcher) { block(it) }
-    }
+    val flow = map { LazyDeferred(dispatcher) { block(it) } }
     return AsyncFlow(flow)
 }
 
-fun <T, R> AsyncFlow<T>.map(action: (T) -> R): AsyncFlow<R> =
+public fun <T, R> AsyncFlow<T>.map(action: (T) -> R): AsyncFlow<R> =
     AsyncFlow(deferredFlow.map { input ->
         //TODO add function composition
         LazyDeferred(input.dispatcher) {
@@ -48,7 +41,7 @@ fun <T, R> AsyncFlow<T>.map(action: (T) -> R): AsyncFlow<R> =
         }
     })
 
-suspend fun <T> AsyncFlow<T>.collect(concurrency: Int, collector: FlowCollector<T>) {
+public suspend fun <T> AsyncFlow<T>.collect(concurrency: Int, collector: FlowCollector<T>) {
     require(concurrency >= 1) { "Buffer size should be more than 1, but was $concurrency" }
 
     coroutineScope {
@@ -76,18 +69,14 @@ suspend fun <T> AsyncFlow<T>.collect(concurrency: Int, collector: FlowCollector<
     }
 }
 
-suspend inline fun <T> AsyncFlow<T>.collect(concurrency: Int, crossinline action: suspend (value: T) -> Unit) {
-    contract { callsInPlace(action) }
+public suspend inline fun <T> AsyncFlow<T>.collect(
+    concurrency: Int,
+    crossinline action: suspend (value: T) -> Unit
+): Unit = collect(concurrency, object : FlowCollector<T> {
+    override suspend fun emit(value: T): Unit = action(value)
+})
 
-    collect(concurrency, object : FlowCollector<T> {
-        override suspend fun emit(value: T): Unit = action(value)
-    })
-}
-
-inline fun <T, R> Flow<T>.mapParallel(
+public inline fun <T, R> Flow<T>.mapParallel(
     dispatcher: CoroutineDispatcher = Dispatchers.Default,
     crossinline transform: suspend (T) -> R
-): Flow<R> {
-    contract { callsInPlace(transform) }
-    return flatMapMerge { value -> flow { emit(transform(value)) } }.flowOn(dispatcher)
-}
+): Flow<R> = flatMapMerge { value -> flow { emit(transform(value)) } }.flowOn(dispatcher)
diff --git a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/streaming/BufferFlow.kt b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/streaming/BufferFlow.kt
similarity index 62%
rename from kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/streaming/BufferFlow.kt
rename to kmath-coroutines/src/commonMain/kotlin/kscience/kmath/streaming/BufferFlow.kt
index 9b7e82da5..328a7807c 100644
--- a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/streaming/BufferFlow.kt
+++ b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/streaming/BufferFlow.kt
@@ -1,28 +1,28 @@
-package scientifik.kmath.streaming
+package kscience.kmath.streaming
 
 import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.*
-import scientifik.kmath.chains.BlockingRealChain
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.BufferFactory
-import scientifik.kmath.structures.RealBuffer
-import scientifik.kmath.structures.asBuffer
+import kscience.kmath.chains.BlockingRealChain
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.BufferFactory
+import kscience.kmath.structures.RealBuffer
+import kscience.kmath.structures.asBuffer
 
 /**
  * Create a [Flow] from buffer
  */
-fun <T> Buffer<T>.asFlow(): Flow<T> = iterator().asFlow()
+public fun <T> Buffer<T>.asFlow(): Flow<T> = iterator().asFlow()
 
 /**
  * Flat map a [Flow] of [Buffer] into continuous [Flow] of elements
  */
 @FlowPreview
-fun <T> Flow<Buffer<out T>>.spread(): Flow<T> = flatMapConcat { it.asFlow() }
+public fun <T> Flow<Buffer<out T>>.spread(): Flow<T> = flatMapConcat { it.asFlow() }
 
 /**
  * Collect incoming flow into fixed size chunks
  */
-fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>): Flow<Buffer<T>> = flow {
+public fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>): Flow<Buffer<T>> = flow {
     require(bufferSize > 0) { "Resulting chunk size must be more than zero" }
     val list = ArrayList<T>(bufferSize)
     var counter = 0
@@ -30,6 +30,7 @@ fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>): Flow<
     this@chunked.collect { element ->
         list.add(element)
         counter++
+
         if (counter == bufferSize) {
             val buffer = bufferFactory(bufferSize) { list[it] }
             emit(buffer)
@@ -37,22 +38,19 @@ fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>): Flow<
             counter = 0
         }
     }
-    if (counter > 0) {
-        emit(bufferFactory(counter) { list[it] })
-    }
+
+    if (counter > 0) emit(bufferFactory(counter) { list[it] })
 }
 
 /**
  * Specialized flow chunker for real buffer
  */
-fun Flow<Double>.chunked(bufferSize: Int): Flow<RealBuffer> = flow {
+public fun Flow<Double>.chunked(bufferSize: Int): Flow<RealBuffer> = flow {
     require(bufferSize > 0) { "Resulting chunk size must be more than zero" }
 
     if (this@chunked is BlockingRealChain) {
-        //performance optimization for blocking primitive chain
-        while (true) {
-            emit(nextBlock(bufferSize).asBuffer())
-        }
+        // performance optimization for blocking primitive chain
+        while (true) emit(nextBlock(bufferSize).asBuffer())
     } else {
         val array = DoubleArray(bufferSize)
         var counter = 0
@@ -60,15 +58,15 @@ fun Flow<Double>.chunked(bufferSize: Int): Flow<RealBuffer> = flow {
         this@chunked.collect { element ->
             array[counter] = element
             counter++
+
             if (counter == bufferSize) {
                 val buffer = RealBuffer(array)
                 emit(buffer)
                 counter = 0
             }
         }
-        if (counter > 0) {
-            emit(RealBuffer(counter) { array[it] })
-        }
+
+        if (counter > 0) emit(RealBuffer(counter) { array[it] })
     }
 }
 
@@ -76,9 +74,10 @@ fun Flow<Double>.chunked(bufferSize: Int): Flow<RealBuffer> = flow {
  * Map a flow to a moving window buffer. The window step is one.
  * In order to get different steps, one could use skip operation.
  */
-fun <T> Flow<T>.windowed(window: Int): Flow<Buffer<T>> = flow {
+public fun <T> Flow<T>.windowed(window: Int): Flow<Buffer<T>> = flow {
     require(window > 1) { "Window size must be more than one" }
     val ringBuffer = RingBuffer.boxing<T>(window)
+
     this@windowed.collect { element ->
         ringBuffer.push(element)
         emit(ringBuffer.snapshot())
diff --git a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/streaming/RingBuffer.kt b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/streaming/RingBuffer.kt
similarity index 65%
rename from kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/streaming/RingBuffer.kt
rename to kmath-coroutines/src/commonMain/kotlin/kscience/kmath/streaming/RingBuffer.kt
index f1c0bfc6a..385bbaae2 100644
--- a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/streaming/RingBuffer.kt
+++ b/kmath-coroutines/src/commonMain/kotlin/kscience/kmath/streaming/RingBuffer.kt
@@ -1,37 +1,37 @@
-package scientifik.kmath.streaming
+package kscience.kmath.streaming
 
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.MutableBuffer
-import scientifik.kmath.structures.VirtualBuffer
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.MutableBuffer
+import kscience.kmath.structures.VirtualBuffer
 
 /**
  * Thread-safe ring buffer
  */
 @Suppress("UNCHECKED_CAST")
-class RingBuffer<T>(
+public class RingBuffer<T>(
     private val buffer: MutableBuffer<T?>,
     private var startIndex: Int = 0,
     size: Int = 0
 ) : Buffer<T> {
     private val mutex: Mutex = Mutex()
 
-    override var size: Int = size
+    public override var size: Int = size
         private set
 
-    override operator fun get(index: Int): T {
+    public override operator fun get(index: Int): T {
         require(index >= 0) { "Index must be positive" }
         require(index < size) { "Index $index is out of circular buffer size $size" }
         return buffer[startIndex.forward(index)] as T
     }
 
-    fun isFull(): Boolean = size == buffer.size
+    public fun isFull(): Boolean = size == buffer.size
 
     /**
      * Iterator could provide wrong results if buffer is changed in initialization (iteration is safe)
      */
-    override operator fun iterator(): Iterator<T> = object : AbstractIterator<T>() {
+    public override operator fun iterator(): Iterator<T> = object : AbstractIterator<T>() {
         private var count = size
         private var index = startIndex
         val copy = buffer.copy()
@@ -48,23 +48,17 @@ class RingBuffer<T>(
     /**
      * A safe snapshot operation
      */
-    suspend fun snapshot(): Buffer<T> {
+    public suspend fun snapshot(): Buffer<T> {
         mutex.withLock {
             val copy = buffer.copy()
-            return VirtualBuffer(size) { i ->
-                copy[startIndex.forward(i)] as T
-            }
+            return VirtualBuffer(size) { i -> copy[startIndex.forward(i)] as T }
         }
     }
 
-    suspend fun push(element: T) {
+    public suspend fun push(element: T) {
         mutex.withLock {
             buffer[startIndex.forward(size)] = element
-            if (isFull()) {
-                startIndex++
-            } else {
-                size++
-            }
+            if (isFull()) startIndex++ else size++
         }
     }
 
@@ -72,8 +66,8 @@ class RingBuffer<T>(
     @Suppress("NOTHING_TO_INLINE")
     private inline fun Int.forward(n: Int): Int = (this + n) % (buffer.size)
 
-    companion object {
-        inline fun <reified T : Any> build(size: Int, empty: T): RingBuffer<T> {
+    public companion object {
+        public inline fun <reified T : Any> build(size: Int, empty: T): RingBuffer<T> {
             val buffer = MutableBuffer.auto(size) { empty } as MutableBuffer<T?>
             return RingBuffer(buffer)
         }
@@ -81,7 +75,7 @@ class RingBuffer<T>(
         /**
          * Slow yet universal buffer
          */
-        fun <T> boxing(size: Int): RingBuffer<T> {
+        public fun <T> boxing(size: Int): RingBuffer<T> {
             val buffer: MutableBuffer<T?> = MutableBuffer.boxing(size) { null }
             return RingBuffer(buffer)
         }
diff --git a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/BlockingIntChain.kt b/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/BlockingIntChain.kt
deleted file mode 100644
index e9b499d71..000000000
--- a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/BlockingIntChain.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package scientifik.kmath.chains
-
-/**
- * Performance optimized chain for integer values
- */
-abstract class BlockingIntChain : Chain<Int> {
-    abstract fun nextInt(): Int
-
-    override suspend fun next(): Int = nextInt()
-
-    fun nextBlock(size: Int): IntArray = IntArray(size) { nextInt() }
-}
diff --git a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/BlockingRealChain.kt b/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/BlockingRealChain.kt
deleted file mode 100644
index ab819d327..000000000
--- a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/BlockingRealChain.kt
+++ /dev/null
@@ -1,12 +0,0 @@
-package scientifik.kmath.chains
-
-/**
- * Performance optimized chain for real values
- */
-abstract class BlockingRealChain : Chain<Double> {
-    abstract fun nextDouble(): Double
-
-    override suspend fun next(): Double = nextDouble()
-
-    fun nextBlock(size: Int): DoubleArray = DoubleArray(size) { nextDouble() }
-}
diff --git a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/flowExtra.kt b/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/flowExtra.kt
deleted file mode 100644
index 5db660c39..000000000
--- a/kmath-coroutines/src/commonMain/kotlin/scientifik/kmath/chains/flowExtra.kt
+++ /dev/null
@@ -1,27 +0,0 @@
-package scientifik.kmath.chains
-
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.scan
-import kotlinx.coroutines.flow.scanReduce
-import scientifik.kmath.operations.Space
-import scientifik.kmath.operations.SpaceOperations
-import scientifik.kmath.operations.invoke
-
-@ExperimentalCoroutinesApi
-fun <T> Flow<T>.cumulativeSum(space: SpaceOperations<T>): Flow<T> = space {
-    scanReduce { sum: T, element: T -> sum + element }
-}
-
-@ExperimentalCoroutinesApi
-fun <T> Flow<T>.mean(space: Space<T>): Flow<T> = space {
-    class Accumulator(var sum: T, var num: Int)
-
-    scan(Accumulator(zero, 0)) { sum, element ->
-        sum.apply {
-            this.sum += element
-            this.num += 1
-        }
-    }.map { it.sum / it.num }
-}
diff --git a/kmath-coroutines/src/jvmMain/kotlin/scientifik/kmath/chains/ChainExt.kt b/kmath-coroutines/src/jvmMain/kotlin/kscience/kmath/chains/ChainExt.kt
similarity index 55%
rename from kmath-coroutines/src/jvmMain/kotlin/scientifik/kmath/chains/ChainExt.kt
rename to kmath-coroutines/src/jvmMain/kotlin/kscience/kmath/chains/ChainExt.kt
index 5686b0ac0..3dfeddbac 100644
--- a/kmath-coroutines/src/jvmMain/kotlin/scientifik/kmath/chains/ChainExt.kt
+++ b/kmath-coroutines/src/jvmMain/kotlin/kscience/kmath/chains/ChainExt.kt
@@ -1,17 +1,16 @@
-package scientifik.kmath.chains
+package kscience.kmath.chains
 
 import kotlinx.coroutines.runBlocking
 
 /**
  * Represent a chain as regular iterator (uses blocking calls)
  */
-operator fun <R> Chain<R>.iterator(): Iterator<R> = object : Iterator<R> {
+public operator fun <R> Chain<R>.iterator(): Iterator<R> = object : Iterator<R> {
     override fun hasNext(): Boolean = true
-
     override fun next(): R = runBlocking { next() }
 }
 
 /**
  * Represent a chain as a sequence
  */
-fun <R> Chain<R>.asSequence(): Sequence<R> = Sequence { this@asSequence.iterator() }
\ No newline at end of file
+public fun <R> Chain<R>.asSequence(): Sequence<R> = Sequence { this@asSequence.iterator() }
diff --git a/kmath-coroutines/src/jvmMain/kotlin/kscience/kmath/structures/LazyNDStructure.kt b/kmath-coroutines/src/jvmMain/kotlin/kscience/kmath/structures/LazyNDStructure.kt
new file mode 100644
index 000000000..bb0d19c23
--- /dev/null
+++ b/kmath-coroutines/src/jvmMain/kotlin/kscience/kmath/structures/LazyNDStructure.kt
@@ -0,0 +1,56 @@
+package kscience.kmath.structures
+
+import kotlinx.coroutines.*
+import kscience.kmath.coroutines.Math
+
+public class LazyNDStructure<T>(
+    public val scope: CoroutineScope,
+    public override val shape: IntArray,
+    public val function: suspend (IntArray) -> T
+) : NDStructure<T> {
+    private val cache: MutableMap<IntArray, Deferred<T>> = hashMapOf()
+
+    public fun deferred(index: IntArray): Deferred<T> = cache.getOrPut(index) {
+        scope.async(context = Dispatchers.Math) { function(index) }
+    }
+
+    public suspend fun await(index: IntArray): T = deferred(index).await()
+    public override operator fun get(index: IntArray): T = runBlocking { deferred(index).await() }
+
+    public override fun elements(): Sequence<Pair<IntArray, T>> {
+        val strides = DefaultStrides(shape)
+        val res = runBlocking { strides.indices().toList().map { index -> index to await(index) } }
+        return res.asSequence()
+    }
+
+    public override fun equals(other: Any?): Boolean {
+        return NDStructure.equals(this, other as? NDStructure<*> ?: return false)
+    }
+
+    public override fun hashCode(): Int {
+        var result = scope.hashCode()
+        result = 31 * result + shape.contentHashCode()
+        result = 31 * result + function.hashCode()
+        result = 31 * result + cache.hashCode()
+        return result
+    }
+}
+
+public fun <T> NDStructure<T>.deferred(index: IntArray): Deferred<T> =
+    if (this is LazyNDStructure<T>) deferred(index) else CompletableDeferred(get(index))
+
+public suspend fun <T> NDStructure<T>.await(index: IntArray): T =
+    if (this is LazyNDStructure<T>) await(index) else get(index)
+
+/**
+ * PENDING would benefit from KEEP-176
+ */
+public inline fun <T, R> NDStructure<T>.mapAsyncIndexed(
+    scope: CoroutineScope,
+    crossinline function: suspend (T, index: IntArray) -> R
+): LazyNDStructure<R> = LazyNDStructure(scope, shape) { index -> function(get(index), index) }
+
+public inline fun <T, R> NDStructure<T>.mapAsync(
+    scope: CoroutineScope,
+    crossinline function: suspend (T) -> R
+): LazyNDStructure<R> = LazyNDStructure(scope, shape) { index -> function(get(index)) }
diff --git a/kmath-coroutines/src/jvmMain/kotlin/scientifik/kmath/structures/LazyNDStructure.kt b/kmath-coroutines/src/jvmMain/kotlin/scientifik/kmath/structures/LazyNDStructure.kt
deleted file mode 100644
index ff732a06b..000000000
--- a/kmath-coroutines/src/jvmMain/kotlin/scientifik/kmath/structures/LazyNDStructure.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package scientifik.kmath.structures
-
-import kotlinx.coroutines.*
-import scientifik.kmath.coroutines.Math
-
-class LazyNDStructure<T>(
-    val scope: CoroutineScope,
-    override val shape: IntArray,
-    val function: suspend (IntArray) -> T
-) : NDStructure<T> {
-    private val cache: MutableMap<IntArray, Deferred<T>> = hashMapOf()
-
-    fun deferred(index: IntArray): Deferred<T> = cache.getOrPut(index) {
-        scope.async(context = Dispatchers.Math) {
-            function(index)
-        }
-    }
-
-    suspend fun await(index: IntArray): T = deferred(index).await()
-
-    override operator fun get(index: IntArray): T = runBlocking {
-        deferred(index).await()
-    }
-
-    override fun elements(): Sequence<Pair<IntArray, T>> {
-        val strides = DefaultStrides(shape)
-        val res = runBlocking {
-            strides.indices().toList().map { index -> index to await(index) }
-        }
-        return res.asSequence()
-    }
-
-    override fun equals(other: Any?): Boolean {
-        return NDStructure.equals(this, other as? NDStructure<*> ?: return false)
-    }
-
-    override fun hashCode(): Int {
-        var result = scope.hashCode()
-        result = 31 * result + shape.contentHashCode()
-        result = 31 * result + function.hashCode()
-        result = 31 * result + cache.hashCode()
-        return result
-    }
-}
-
-fun <T> NDStructure<T>.deferred(index: IntArray): Deferred<T> =
-    if (this is LazyNDStructure<T>) this.deferred(index) else CompletableDeferred(get(index))
-
-suspend fun <T> NDStructure<T>.await(index: IntArray): T =
-    if (this is LazyNDStructure<T>) this.await(index) else get(index)
-
-/**
- * PENDING would benefit from KEEP-176
- */
-inline fun <T, R> NDStructure<T>.mapAsyncIndexed(
-    scope: CoroutineScope,
-    crossinline function: suspend (T, index: IntArray) -> R
-): LazyNDStructure<R> = LazyNDStructure(scope, shape) { index -> function(get(index), index) }
-
-inline fun <T, R> NDStructure<T>.mapAsync(
-    scope: CoroutineScope,
-    crossinline function: suspend (T) -> R
-): LazyNDStructure<R> = LazyNDStructure(scope, shape) { index -> function(get(index)) }
diff --git a/kmath-coroutines/src/jvmTest/kotlin/scientifik/kmath/streaming/BufferFlowTest.kt b/kmath-coroutines/src/jvmTest/kotlin/kscience/kmath/streaming/BufferFlowTest.kt
similarity index 86%
rename from kmath-coroutines/src/jvmTest/kotlin/scientifik/kmath/streaming/BufferFlowTest.kt
rename to kmath-coroutines/src/jvmTest/kotlin/kscience/kmath/streaming/BufferFlowTest.kt
index 427349072..a9bf38c12 100644
--- a/kmath-coroutines/src/jvmTest/kotlin/scientifik/kmath/streaming/BufferFlowTest.kt
+++ b/kmath-coroutines/src/jvmTest/kotlin/kscience/kmath/streaming/BufferFlowTest.kt
@@ -1,12 +1,12 @@
-package scientifik.kmath.streaming
+package kscience.kmath.streaming
 
 import kotlinx.coroutines.*
 import kotlinx.coroutines.flow.asFlow
 import kotlinx.coroutines.flow.collect
+import kscience.kmath.coroutines.async
+import kscience.kmath.coroutines.collect
+import kscience.kmath.coroutines.mapParallel
 import org.junit.jupiter.api.Timeout
-import scientifik.kmath.coroutines.async
-import scientifik.kmath.coroutines.collect
-import scientifik.kmath.coroutines.mapParallel
 import java.util.concurrent.Executors
 import kotlin.test.Test
 
@@ -14,7 +14,7 @@ import kotlin.test.Test
 @ExperimentalCoroutinesApi
 @InternalCoroutinesApi
 @FlowPreview
-class BufferFlowTest {
+internal class BufferFlowTest {
     val dispatcher: CoroutineDispatcher = Executors.newFixedThreadPool(4).asCoroutineDispatcher()
 
     @Test
diff --git a/kmath-coroutines/src/jvmTest/kotlin/scientifik/kmath/streaming/RingBufferTest.kt b/kmath-coroutines/src/jvmTest/kotlin/kscience/kmath/streaming/RingBufferTest.kt
similarity index 88%
rename from kmath-coroutines/src/jvmTest/kotlin/scientifik/kmath/streaming/RingBufferTest.kt
rename to kmath-coroutines/src/jvmTest/kotlin/kscience/kmath/streaming/RingBufferTest.kt
index c84ef89ef..5bb0c1d40 100644
--- a/kmath-coroutines/src/jvmTest/kotlin/scientifik/kmath/streaming/RingBufferTest.kt
+++ b/kmath-coroutines/src/jvmTest/kotlin/kscience/kmath/streaming/RingBufferTest.kt
@@ -1,12 +1,12 @@
-package scientifik.kmath.streaming
+package kscience.kmath.streaming
 
 import kotlinx.coroutines.flow.*
 import kotlinx.coroutines.runBlocking
-import scientifik.kmath.structures.asSequence
+import kscience.kmath.structures.asSequence
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-class RingBufferTest {
+internal class RingBufferTest {
     @Test
     fun push() {
         val buffer = RingBuffer.build(20, Double.NaN)
diff --git a/kmath-dimensions/build.gradle.kts b/kmath-dimensions/build.gradle.kts
index 597ce8799..0a36e4435 100644
--- a/kmath-dimensions/build.gradle.kts
+++ b/kmath-dimensions/build.gradle.kts
@@ -1,8 +1,6 @@
-plugins {
-    id("scientifik.mpp")
-}
+plugins { id("ru.mipt.npm.mpp") }
 
-description = "A proof of concept module for adding typ-safe dimensions to structures"
+description = "A proof of concept module for adding type-safe dimensions to structures"
 
 kotlin.sourceSets {
     commonMain {
diff --git a/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Dimensions.kt b/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Dimensions.kt
new file mode 100644
index 000000000..f49e1e0f0
--- /dev/null
+++ b/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Dimensions.kt
@@ -0,0 +1,33 @@
+package kscience.kmath.dimensions
+
+import kotlin.reflect.KClass
+
+/**
+ * An abstract class which is not used in runtime. Designates a size of some structure.
+ * Could be replaced later by fully inline constructs
+ */
+public interface Dimension {
+    public val dim: UInt
+
+    public companion object
+}
+
+public fun <D : Dimension> KClass<D>.dim(): UInt = Dimension.resolve(this).dim
+
+public expect fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D
+
+public expect fun Dimension.Companion.of(dim: UInt): Dimension
+
+public inline fun <reified D : Dimension> Dimension.Companion.dim(): UInt = D::class.dim()
+
+public object D1 : Dimension {
+    override val dim: UInt get() = 1U
+}
+
+public object D2 : Dimension {
+    override val dim: UInt get() = 2U
+}
+
+public object D3 : Dimension {
+    override val dim: UInt get() = 3U
+}
diff --git a/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Wrappers.kt
new file mode 100644
index 000000000..4111cb78d
--- /dev/null
+++ b/kmath-dimensions/src/commonMain/kotlin/kscience/kmath/dimensions/Wrappers.kt
@@ -0,0 +1,156 @@
+package kscience.kmath.dimensions
+
+import kscience.kmath.linear.GenericMatrixContext
+import kscience.kmath.linear.MatrixContext
+import kscience.kmath.linear.Point
+import kscience.kmath.linear.transpose
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.invoke
+import kscience.kmath.structures.Matrix
+import kscience.kmath.structures.Structure2D
+
+/**
+ * A matrix with compile-time controlled dimension
+ */
+public interface DMatrix<T, R : Dimension, C : Dimension> : Structure2D<T> {
+    public companion object {
+        /**
+         * Coerces a regular matrix to a matrix with type-safe dimensions and throws a error if coercion failed
+         */
+        public inline fun <T, reified R : Dimension, reified C : Dimension> coerce(structure: Structure2D<T>): DMatrix<T, R, C> {
+            require(structure.rowNum == Dimension.dim<R>().toInt()) {
+                "Row number mismatch: expected ${Dimension.dim<R>()} but found ${structure.rowNum}"
+            }
+
+            require(structure.colNum == Dimension.dim<C>().toInt()) {
+                "Column number mismatch: expected ${Dimension.dim<C>()} but found ${structure.colNum}"
+            }
+
+            return DMatrixWrapper(structure)
+        }
+
+        /**
+         * The same as [DMatrix.coerce] but without dimension checks. Use with caution
+         */
+        public fun <T, R : Dimension, C : Dimension> coerceUnsafe(structure: Structure2D<T>): DMatrix<T, R, C> =
+            DMatrixWrapper(structure)
+    }
+}
+
+/**
+ * An inline wrapper for a Matrix
+ */
+public inline class DMatrixWrapper<T, R : Dimension, C : Dimension>(
+    public val structure: Structure2D<T>
+) : DMatrix<T, R, C> {
+    override val shape: IntArray get() = structure.shape
+    override operator fun get(i: Int, j: Int): T = structure[i, j]
+}
+
+/**
+ * Dimension-safe point
+ */
+public interface DPoint<T, D : Dimension> : Point<T> {
+    public companion object {
+        public inline fun <T, reified D : Dimension> coerce(point: Point<T>): DPoint<T, D> {
+            require(point.size == Dimension.dim<D>().toInt()) {
+                "Vector dimension mismatch: expected ${Dimension.dim<D>()}, but found ${point.size}"
+            }
+
+            return DPointWrapper(point)
+        }
+
+        public fun <T, D : Dimension> coerceUnsafe(point: Point<T>): DPoint<T, D> = DPointWrapper(point)
+    }
+}
+
+/**
+ * Dimension-safe point wrapper
+ */
+public inline class DPointWrapper<T, D : Dimension>(public val point: Point<T>) :
+    DPoint<T, D> {
+    override val size: Int get() = point.size
+
+    override operator fun get(index: Int): T = point[index]
+
+    override operator fun iterator(): Iterator<T> = point.iterator()
+}
+
+
+/**
+ * Basic operations on dimension-safe matrices. Operates on [Matrix]
+ */
+public inline class DMatrixContext<T : Any, Ri : Ring<T>>(public val context: GenericMatrixContext<T, Ri>) {
+    public inline fun <reified R : Dimension, reified C : Dimension> Matrix<T>.coerce(): DMatrix<T, R, C> {
+        require(rowNum == Dimension.dim<R>().toInt()) {
+            "Row number mismatch: expected ${Dimension.dim<R>()} but found $rowNum"
+        }
+
+        require(colNum == Dimension.dim<C>().toInt()) {
+            "Column number mismatch: expected ${Dimension.dim<C>()} but found $colNum"
+        }
+
+        return DMatrix.coerceUnsafe(this)
+    }
+
+    /**
+     * Produce a matrix with this context and given dimensions
+     */
+    public inline fun <reified R : Dimension, reified C : Dimension> produce(noinline initializer: (i: Int, j: Int) -> T): DMatrix<T, R, C> {
+        val rows = Dimension.dim<R>()
+        val cols = Dimension.dim<C>()
+        return context.produce(rows.toInt(), cols.toInt(), initializer).coerce<R, C>()
+    }
+
+    public inline fun <reified D : Dimension> point(noinline initializer: (Int) -> T): DPoint<T, D> {
+        val size = Dimension.dim<D>()
+
+        return DPoint.coerceUnsafe(
+            context.point(
+                size.toInt(),
+                initializer
+            )
+        )
+    }
+
+    public inline infix fun <reified R1 : Dimension, reified C1 : Dimension, reified C2 : Dimension> DMatrix<T, R1, C1>.dot(
+        other: DMatrix<T, C1, C2>
+    ): DMatrix<T, R1, C2> = context { this@dot dot other }.coerce()
+
+    public inline infix fun <reified R : Dimension, reified C : Dimension> DMatrix<T, R, C>.dot(vector: DPoint<T, C>): DPoint<T, R> =
+        DPoint.coerceUnsafe(context { this@dot dot vector })
+
+    public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, R, C>.times(value: T): DMatrix<T, R, C> =
+        context { this@times.times(value) }.coerce()
+
+    public inline operator fun <reified R : Dimension, reified C : Dimension> T.times(m: DMatrix<T, R, C>): DMatrix<T, R, C> =
+        m * this
+
+    public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.plus(other: DMatrix<T, C, R>): DMatrix<T, C, R> =
+        context { this@plus + other }.coerce()
+
+    public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.minus(other: DMatrix<T, C, R>): DMatrix<T, C, R> =
+        context { this@minus + other }.coerce()
+
+    public inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.unaryMinus(): DMatrix<T, C, R> =
+        context { this@unaryMinus.unaryMinus() }.coerce()
+
+    public inline fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.transpose(): DMatrix<T, R, C> =
+        context { (this@transpose as Matrix<T>).transpose() }.coerce()
+
+    /**
+     * A square unit matrix
+     */
+    public inline fun <reified D : Dimension> one(): DMatrix<T, D, D> = produce { i, j ->
+        if (i == j) context.elementContext.one else context.elementContext.zero
+    }
+
+    public inline fun <reified R : Dimension, reified C : Dimension> zero(): DMatrix<T, R, C> = produce { _, _ ->
+        context.elementContext.zero
+    }
+
+    public companion object {
+        public val real: DMatrixContext<Double, RealField> = DMatrixContext(MatrixContext.real)
+    }
+}
diff --git a/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Dimensions.kt b/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Dimensions.kt
deleted file mode 100644
index f40483cfd..000000000
--- a/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Dimensions.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package scientifik.kmath.dimensions
-
-import kotlin.reflect.KClass
-
-/**
- * An abstract class which is not used in runtime. Designates a size of some structure.
- * Could be replaced later by fully inline constructs
- */
-interface Dimension {
-
-    val dim: UInt
-    companion object {
-
-    }
-}
-
-fun <D : Dimension> KClass<D>.dim(): UInt = Dimension.resolve(this).dim
-
-expect fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D
-
-expect fun Dimension.Companion.of(dim: UInt): Dimension
-
-inline fun <reified D : Dimension> Dimension.Companion.dim(): UInt = D::class.dim()
-
-object D1 : Dimension {
-    override val dim: UInt get() = 1U
-}
-
-object D2 : Dimension {
-    override val dim: UInt get() = 2U
-}
-
-object D3 : Dimension {
-    override val dim: UInt get() = 3U
-}
diff --git a/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Wrappers.kt b/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Wrappers.kt
deleted file mode 100644
index 7b0244bdf..000000000
--- a/kmath-dimensions/src/commonMain/kotlin/scientifik/kmath/dimensions/Wrappers.kt
+++ /dev/null
@@ -1,157 +0,0 @@
-package scientifik.kmath.dimensions
-
-import scientifik.kmath.linear.GenericMatrixContext
-import scientifik.kmath.linear.MatrixContext
-import scientifik.kmath.linear.Point
-import scientifik.kmath.linear.transpose
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.structures.Matrix
-import scientifik.kmath.structures.Structure2D
-
-/**
- * A matrix with compile-time controlled dimension
- */
-interface DMatrix<T, R : Dimension, C : Dimension> : Structure2D<T> {
-    companion object {
-        /**
-         * Coerces a regular matrix to a matrix with type-safe dimensions and throws a error if coercion failed
-         */
-        inline fun <T, reified R : Dimension, reified C : Dimension> coerce(structure: Structure2D<T>): DMatrix<T, R, C> {
-            if (structure.rowNum != Dimension.dim<R>().toInt()) {
-                error("Row number mismatch: expected ${Dimension.dim<R>()} but found ${structure.rowNum}")
-            }
-            if (structure.colNum != Dimension.dim<C>().toInt()) {
-                error("Column number mismatch: expected ${Dimension.dim<C>()} but found ${structure.colNum}")
-            }
-            return DMatrixWrapper(structure)
-        }
-
-        /**
-         * The same as [coerce] but without dimension checks. Use with caution
-         */
-        fun <T, R : Dimension, C : Dimension> coerceUnsafe(structure: Structure2D<T>): DMatrix<T, R, C> {
-            return DMatrixWrapper(structure)
-        }
-    }
-}
-
-/**
- * An inline wrapper for a Matrix
- */
-inline class DMatrixWrapper<T, R : Dimension, C : Dimension>(
-    val structure: Structure2D<T>
-) : DMatrix<T, R, C> {
-    override val shape: IntArray get() = structure.shape
-    override operator fun get(i: Int, j: Int): T = structure[i, j]
-}
-
-/**
- * Dimension-safe point
- */
-interface DPoint<T, D : Dimension> : Point<T> {
-    companion object {
-        inline fun <T, reified D : Dimension> coerce(point: Point<T>): DPoint<T, D> {
-            if (point.size != Dimension.dim<D>().toInt()) {
-                error("Vector dimension mismatch: expected ${Dimension.dim<D>()}, but found ${point.size}")
-            }
-            return DPointWrapper(point)
-        }
-
-        fun <T, D : Dimension> coerceUnsafe(point: Point<T>): DPoint<T, D> {
-            return DPointWrapper(point)
-        }
-    }
-}
-
-/**
- * Dimension-safe point wrapper
- */
-inline class DPointWrapper<T, D : Dimension>(val point: Point<T>) :
-    DPoint<T, D> {
-    override val size: Int get() = point.size
-
-    override operator fun get(index: Int): T = point[index]
-
-    override operator fun iterator(): Iterator<T> = point.iterator()
-}
-
-
-/**
- * Basic operations on dimension-safe matrices. Operates on [Matrix]
- */
-inline class DMatrixContext<T : Any, Ri : Ring<T>>(val context: GenericMatrixContext<T, Ri>) {
-
-    inline fun <reified R : Dimension, reified C : Dimension> Matrix<T>.coerce(): DMatrix<T, R, C> {
-        check(
-            rowNum == Dimension.dim<R>().toInt()
-        ) { "Row number mismatch: expected ${Dimension.dim<R>()} but found $rowNum" }
-
-        check(
-            colNum == Dimension.dim<C>().toInt()
-        ) { "Column number mismatch: expected ${Dimension.dim<C>()} but found $colNum" }
-
-        return DMatrix.coerceUnsafe(this)
-    }
-
-    /**
-     * Produce a matrix with this context and given dimensions
-     */
-    inline fun <reified R : Dimension, reified C : Dimension> produce(noinline initializer: (i: Int, j: Int) -> T): DMatrix<T, R, C> {
-        val rows = Dimension.dim<R>()
-        val cols = Dimension.dim<C>()
-        return context.produce(rows.toInt(), cols.toInt(), initializer).coerce<R, C>()
-    }
-
-    inline fun <reified D : Dimension> point(noinline initializer: (Int) -> T): DPoint<T, D> {
-        val size = Dimension.dim<D>()
-
-        return DPoint.coerceUnsafe(
-            context.point(
-                size.toInt(),
-                initializer
-            )
-        )
-    }
-
-    inline infix fun <reified R1 : Dimension, reified C1 : Dimension, reified C2 : Dimension> DMatrix<T, R1, C1>.dot(
-        other: DMatrix<T, C1, C2>
-    ): DMatrix<T, R1, C2> = context { this@dot dot other }.coerce()
-
-    inline infix fun <reified R : Dimension, reified C : Dimension> DMatrix<T, R, C>.dot(vector: DPoint<T, C>): DPoint<T, R> =
-        DPoint.coerceUnsafe(context { this@dot dot vector })
-
-    inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, R, C>.times(value: T): DMatrix<T, R, C> =
-        context { this@times.times(value) }.coerce()
-
-    inline operator fun <reified R : Dimension, reified C : Dimension> T.times(m: DMatrix<T, R, C>): DMatrix<T, R, C> =
-        m * this
-
-    inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.plus(other: DMatrix<T, C, R>): DMatrix<T, C, R> =
-        context { this@plus + other }.coerce()
-
-    inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.minus(other: DMatrix<T, C, R>): DMatrix<T, C, R> =
-        context { this@minus + other }.coerce()
-
-    inline operator fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.unaryMinus(): DMatrix<T, C, R> =
-        context { this@unaryMinus.unaryMinus() }.coerce()
-
-    inline fun <reified R : Dimension, reified C : Dimension> DMatrix<T, C, R>.transpose(): DMatrix<T, R, C> =
-        context { (this@transpose as Matrix<T>).transpose() }.coerce()
-
-    /**
-     * A square unit matrix
-     */
-    inline fun <reified D : Dimension> one(): DMatrix<T, D, D> = produce { i, j ->
-        if (i == j) context.elementContext.one else context.elementContext.zero
-    }
-
-    inline fun <reified R : Dimension, reified C : Dimension> zero(): DMatrix<T, R, C> = produce { _, _ ->
-        context.elementContext.zero
-    }
-
-    companion object {
-        val real: DMatrixContext<Double, RealField> = DMatrixContext(MatrixContext.real)
-    }
-}
diff --git a/kmath-dimensions/src/commonTest/kotlin/scientifik/dimensions/DMatrixContextTest.kt b/kmath-dimensions/src/commonTest/kotlin/scientifik/dimensions/DMatrixContextTest.kt
index 8dabdeeac..f44b16753 100644
--- a/kmath-dimensions/src/commonTest/kotlin/scientifik/dimensions/DMatrixContextTest.kt
+++ b/kmath-dimensions/src/commonTest/kotlin/scientifik/dimensions/DMatrixContextTest.kt
@@ -1,11 +1,11 @@
-package scientifik.dimensions
+package kscience.dimensions
 
-import scientifik.kmath.dimensions.D2
-import scientifik.kmath.dimensions.D3
-import scientifik.kmath.dimensions.DMatrixContext
+import kscience.kmath.dimensions.D2
+import kscience.kmath.dimensions.D3
+import kscience.kmath.dimensions.DMatrixContext
 import kotlin.test.Test
 
-class DMatrixContextTest {
+internal class DMatrixContextTest {
     @Test
     fun testDimensionSafeMatrix() {
         val res = with(DMatrixContext.real) {
@@ -26,4 +26,4 @@ class DMatrixContextTest {
             m1.transpose() + m2
         }
     }
-}
\ No newline at end of file
+}
diff --git a/kmath-dimensions/src/jsMain/kotlin/kscience/kmath/dimensions/dim.kt b/kmath-dimensions/src/jsMain/kotlin/kscience/kmath/dimensions/dim.kt
new file mode 100644
index 000000000..4230da156
--- /dev/null
+++ b/kmath-dimensions/src/jsMain/kotlin/kscience/kmath/dimensions/dim.kt
@@ -0,0 +1,18 @@
+package kscience.kmath.dimensions
+
+import kotlin.reflect.KClass
+
+private val dimensionMap: MutableMap<UInt, Dimension> = hashMapOf(1u to D1, 2u to D2, 3u to D3)
+
+@Suppress("UNCHECKED_CAST")
+public actual fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D = dimensionMap
+    .entries
+    .map(MutableMap.MutableEntry<UInt, Dimension>::value)
+    .find { it::class == type } as? D
+    ?: error("Can't resolve dimension $type")
+
+public actual fun Dimension.Companion.of(dim: UInt): Dimension = dimensionMap.getOrPut(dim) {
+    object : Dimension {
+        override val dim: UInt get() = dim
+    }
+}
diff --git a/kmath-dimensions/src/jsMain/kotlin/scientifik/kmath/dimensions/dim.kt b/kmath-dimensions/src/jsMain/kotlin/scientifik/kmath/dimensions/dim.kt
deleted file mode 100644
index bbd580629..000000000
--- a/kmath-dimensions/src/jsMain/kotlin/scientifik/kmath/dimensions/dim.kt
+++ /dev/null
@@ -1,22 +0,0 @@
-package scientifik.kmath.dimensions
-
-import kotlin.reflect.KClass
-
-private val dimensionMap = hashMapOf<UInt, Dimension>(
-    1u to D1,
-    2u to D2,
-    3u to D3
-)
-
-@Suppress("UNCHECKED_CAST")
-actual fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D {
-    return dimensionMap.entries.find { it.value::class == type }?.value as? D ?: error("Can't resolve dimension $type")
-}
-
-actual fun Dimension.Companion.of(dim: UInt): Dimension {
-    return dimensionMap.getOrPut(dim) {
-        object : Dimension {
-            override val dim: UInt get() = dim
-        }
-    }
-}
\ No newline at end of file
diff --git a/kmath-dimensions/src/jvmMain/kotlin/kscience/kmath/dimensions/dim.kt b/kmath-dimensions/src/jvmMain/kotlin/kscience/kmath/dimensions/dim.kt
new file mode 100644
index 000000000..dec3979ef
--- /dev/null
+++ b/kmath-dimensions/src/jvmMain/kotlin/kscience/kmath/dimensions/dim.kt
@@ -0,0 +1,16 @@
+package kscience.kmath.dimensions
+
+import kotlin.reflect.KClass
+
+public actual fun <D : Dimension> Dimension.Companion.resolve(type: KClass<D>): D =
+    type.objectInstance ?: error("No object instance for dimension class")
+
+public actual fun Dimension.Companion.of(dim: UInt): Dimension = when (dim) {
+    1u -> D1
+    2u -> D2
+    3u -> D3
+
+    else -> object : Dimension {
+        override val dim: UInt get() = dim
+    }
+}
\ No newline at end of file
diff --git a/kmath-dimensions/src/jvmMain/kotlin/scientifik/kmath/dimensions/dim.kt b/kmath-dimensions/src/jvmMain/kotlin/scientifik/kmath/dimensions/dim.kt
deleted file mode 100644
index e8fe8f59b..000000000
--- a/kmath-dimensions/src/jvmMain/kotlin/scientifik/kmath/dimensions/dim.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package scientifik.kmath.dimensions
-
-import kotlin.reflect.KClass
-
-actual fun <D:Dimension> Dimension.Companion.resolve(type: KClass<D>): D{
-    return type.objectInstance ?: error("No object instance for dimension class")
-}
-
-actual fun Dimension.Companion.of(dim: UInt): Dimension{
-    return when(dim){
-        1u -> D1
-        2u -> D2
-        3u -> D3
-        else -> object : Dimension {
-            override val dim: UInt get() = dim
-        }
-    }
-}
\ No newline at end of file
diff --git a/kmath-for-real/build.gradle.kts b/kmath-for-real/build.gradle.kts
index 675457ac5..2a4539c10 100644
--- a/kmath-for-real/build.gradle.kts
+++ b/kmath-for-real/build.gradle.kts
@@ -1,5 +1,5 @@
 plugins {
-    id("scientifik.mpp")
+    id("ru.mipt.npm.mpp")
 }
 
 kotlin.sourceSets.commonMain {
diff --git a/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/RealVector.kt b/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/RealVector.kt
new file mode 100644
index 000000000..ba5f8444b
--- /dev/null
+++ b/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/RealVector.kt
@@ -0,0 +1,46 @@
+package kscience.kmath.real
+
+import kscience.kmath.linear.BufferVectorSpace
+import kscience.kmath.linear.Point
+import kscience.kmath.linear.VectorSpace
+import kscience.kmath.operations.Norm
+import kscience.kmath.operations.RealField
+import kscience.kmath.operations.SpaceElement
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.RealBuffer
+import kscience.kmath.structures.asBuffer
+import kscience.kmath.structures.asIterable
+import kotlin.math.sqrt
+
+public typealias RealPoint = Point<Double>
+
+public fun DoubleArray.asVector(): RealVector = RealVector(asBuffer())
+public fun List<Double>.asVector(): RealVector = RealVector(asBuffer())
+
+public object VectorL2Norm : Norm<Point<out Number>, Double> {
+    override fun norm(arg: Point<out Number>): Double = sqrt(arg.asIterable().sumByDouble(Number::toDouble))
+}
+
+public inline class RealVector(private val point: Point<Double>) :
+    SpaceElement<RealPoint, RealVector, VectorSpace<Double, RealField>>, RealPoint {
+    public override val size: Int get() = point.size
+    public override val context: VectorSpace<Double, RealField> get() = space(point.size)
+
+    public override fun unwrap(): RealPoint = point
+    public override fun RealPoint.wrap(): RealVector = RealVector(this)
+    public override operator fun get(index: Int): Double = point[index]
+    public override operator fun iterator(): Iterator<Double> = point.iterator()
+
+    public companion object {
+        private val spaceCache: MutableMap<Int, BufferVectorSpace<Double, RealField>> = hashMapOf()
+
+        public inline operator fun invoke(dim: Int, initializer: (Int) -> Double): RealVector =
+            RealVector(RealBuffer(dim, initializer))
+
+        public operator fun invoke(vararg values: Double): RealVector = values.asVector()
+
+        public fun space(dim: Int): BufferVectorSpace<Double, RealField> = spaceCache.getOrPut(dim) {
+            BufferVectorSpace(dim, RealField) { size, init -> Buffer.real(size, init) }
+        }
+    }
+}
diff --git a/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/realBuffer.kt b/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/realBuffer.kt
new file mode 100644
index 000000000..0a2119b0d
--- /dev/null
+++ b/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/realBuffer.kt
@@ -0,0 +1,8 @@
+package kscience.kmath.real
+
+import kscience.kmath.structures.RealBuffer
+
+/**
+ * Simplified [RealBuffer] to array comparison
+ */
+public fun RealBuffer.contentEquals(vararg doubles: Double): Boolean = array.contentEquals(doubles)
diff --git a/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/realMatrix.kt b/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/realMatrix.kt
new file mode 100644
index 000000000..1860b5870
--- /dev/null
+++ b/kmath-for-real/src/commonMain/kotlin/kscience/kmath/real/realMatrix.kt
@@ -0,0 +1,157 @@
+package kscience.kmath.real
+
+import kscience.kmath.linear.MatrixContext
+import kscience.kmath.linear.RealMatrixContext.elementContext
+import kscience.kmath.linear.VirtualMatrix
+import kscience.kmath.operations.invoke
+import kscience.kmath.operations.sum
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.Matrix
+import kscience.kmath.structures.RealBuffer
+import kscience.kmath.structures.asIterable
+import kotlin.math.pow
+
+/*
+ *  Functions for convenient "numpy-like" operations with Double matrices.
+ *
+ *  Initial implementation of these functions is taken from:
+ *    https://github.com/thomasnield/numky/blob/master/src/main/kotlin/org/nield/numky/linear/DoubleOperators.kt
+ *
+ */
+
+/*
+ *  Functions that help create a real (Double) matrix
+ */
+
+public typealias RealMatrix = Matrix<Double>
+
+public fun realMatrix(rowNum: Int, colNum: Int, initializer: (i: Int, j: Int) -> Double): RealMatrix =
+    MatrixContext.real.produce(rowNum, colNum, initializer)
+
+public fun Array<DoubleArray>.toMatrix(): RealMatrix {
+    return MatrixContext.real.produce(size, this[0].size) { row, col -> this[row][col] }
+}
+
+public fun Sequence<DoubleArray>.toMatrix(): RealMatrix = toList().let {
+    MatrixContext.real.produce(it.size, it[0].size) { row, col -> it[row][col] }
+}
+
+public fun Matrix<Double>.repeatStackVertical(n: Int): RealMatrix =
+    VirtualMatrix(rowNum * n, colNum) { row, col ->
+        get(if (row == 0) 0 else row % rowNum, col)
+    }
+
+/*
+ *  Operations for matrix and real number
+ */
+
+public operator fun Matrix<Double>.times(double: Double): RealMatrix =
+    MatrixContext.real.produce(rowNum, colNum) { row, col ->
+        this[row, col] * double
+    }
+
+public operator fun Matrix<Double>.plus(double: Double): RealMatrix =
+    MatrixContext.real.produce(rowNum, colNum) { row, col ->
+        this[row, col] + double
+    }
+
+public operator fun Matrix<Double>.minus(double: Double): RealMatrix =
+    MatrixContext.real.produce(rowNum, colNum) { row, col ->
+        this[row, col] - double
+    }
+
+public operator fun Matrix<Double>.div(double: Double): RealMatrix =
+    MatrixContext.real.produce(rowNum, colNum) { row, col ->
+        this[row, col] / double
+    }
+
+public operator fun Double.times(matrix: Matrix<Double>): RealMatrix =
+    MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
+        this * matrix[row, col]
+    }
+
+public operator fun Double.plus(matrix: Matrix<Double>): RealMatrix =
+    MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
+        this + matrix[row, col]
+    }
+
+public operator fun Double.minus(matrix: Matrix<Double>): RealMatrix =
+    MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
+        this - matrix[row, col]
+    }
+
+// TODO: does this operation make sense? Should it be 'this/matrix[row, col]'?
+//operator fun Double.div(matrix: Matrix<Double>) = MatrixContext.real.produce(matrix.rowNum, matrix.colNum) {
+//    row, col -> matrix[row, col] / this
+//}
+
+/*
+ *  Per-element (!) square and power operations
+ */
+
+public fun Matrix<Double>.square(): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { row, col ->
+    this[row, col].pow(2)
+}
+
+public fun Matrix<Double>.pow(n: Int): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { i, j ->
+    this[i, j].pow(n)
+}
+
+/*
+ * Operations on two matrices (per-element!)
+ */
+
+public operator fun Matrix<Double>.times(other: Matrix<Double>): RealMatrix =
+    MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] * other[row, col] }
+
+public operator fun Matrix<Double>.plus(other: Matrix<Double>): RealMatrix =
+    MatrixContext.real.add(this, other)
+
+public operator fun Matrix<Double>.minus(other: Matrix<Double>): RealMatrix =
+    MatrixContext.real.produce(rowNum, colNum) { row, col -> this[row, col] - other[row, col] }
+
+/*
+ *  Operations on columns
+ */
+
+public inline fun Matrix<Double>.appendColumn(crossinline mapper: (Buffer<Double>) -> Double): Matrix<Double> =
+    MatrixContext.real.produce(rowNum, colNum + 1) { row, col ->
+        if (col < colNum)
+            this[row, col]
+        else
+            mapper(rows[row])
+    }
+
+public fun Matrix<Double>.extractColumns(columnRange: IntRange): RealMatrix =
+    MatrixContext.real.produce(rowNum, columnRange.count()) { row, col ->
+        this[row, columnRange.first + col]
+    }
+
+public fun Matrix<Double>.extractColumn(columnIndex: Int): RealMatrix =
+    extractColumns(columnIndex..columnIndex)
+
+public fun Matrix<Double>.sumByColumn(): RealBuffer = RealBuffer(colNum) { j ->
+    val column = columns[j]
+    elementContext { sum(column.asIterable()) }
+}
+
+public fun Matrix<Double>.minByColumn(): RealBuffer = RealBuffer(colNum) { j ->
+    columns[j].asIterable().minOrNull() ?: error("Cannot produce min on empty column")
+}
+
+public fun Matrix<Double>.maxByColumn(): RealBuffer = RealBuffer(colNum) { j ->
+    columns[j].asIterable().maxOrNull() ?: error("Cannot produce min on empty column")
+}
+
+public fun Matrix<Double>.averageByColumn(): RealBuffer = RealBuffer(colNum) { j ->
+    columns[j].asIterable().average()
+}
+
+/*
+ * Operations processing all elements
+ */
+
+public fun Matrix<Double>.sum(): Double = elements().map { (_, value) -> value }.sum()
+public fun Matrix<Double>.min(): Double? = elements().map { (_, value) -> value }.minOrNull()
+public fun Matrix<Double>.max(): Double? = elements().map { (_, value) -> value }.maxOrNull()
+public fun Matrix<Double>.average(): Double = elements().map { (_, value) -> value }.average()
diff --git a/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/RealVector.kt b/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/RealVector.kt
deleted file mode 100644
index 811b54d7c..000000000
--- a/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/RealVector.kt
+++ /dev/null
@@ -1,51 +0,0 @@
-package scientifik.kmath.real
-
-import scientifik.kmath.linear.BufferVectorSpace
-import scientifik.kmath.linear.Point
-import scientifik.kmath.linear.VectorSpace
-import scientifik.kmath.operations.Norm
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.operations.SpaceElement
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.RealBuffer
-import scientifik.kmath.structures.asBuffer
-import scientifik.kmath.structures.asIterable
-import kotlin.math.sqrt
-
-typealias RealPoint = Point<Double>
-
-fun DoubleArray.asVector(): RealVector = RealVector(this.asBuffer())
-fun List<Double>.asVector(): RealVector = RealVector(this.asBuffer())
-
-object VectorL2Norm : Norm<Point<out Number>, Double> {
-    override fun norm(arg: Point<out Number>): Double = sqrt(arg.asIterable().sumByDouble { it.toDouble() })
-}
-
-inline class RealVector(private val point: Point<Double>) :
-    SpaceElement<RealPoint, RealVector, VectorSpace<Double, RealField>>, RealPoint {
-
-    override val context: VectorSpace<Double, RealField> get() = space(point.size)
-
-    override fun unwrap(): RealPoint = point
-
-    override fun RealPoint.wrap(): RealVector = RealVector(this)
-
-    override val size: Int get() = point.size
-
-    override operator fun get(index: Int): Double = point[index]
-
-    override operator fun iterator(): Iterator<Double> = point.iterator()
-
-    companion object {
-        private val spaceCache: MutableMap<Int, BufferVectorSpace<Double, RealField>> = hashMapOf()
-
-        inline operator fun invoke(dim: Int, initializer: (Int) -> Double): RealVector =
-            RealVector(RealBuffer(dim, initializer))
-
-        operator fun invoke(vararg values: Double): RealVector = values.asVector()
-
-        fun space(dim: Int): BufferVectorSpace<Double, RealField> = spaceCache.getOrPut(dim) {
-            BufferVectorSpace(dim, RealField) { size, init -> Buffer.real(size, init) }
-        }
-    }
-}
diff --git a/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realBuffer.kt b/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realBuffer.kt
deleted file mode 100644
index 82c0e86b2..000000000
--- a/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realBuffer.kt
+++ /dev/null
@@ -1,8 +0,0 @@
-package scientifik.kmath.real
-
-import scientifik.kmath.structures.RealBuffer
-
-/**
- * Simplified [RealBuffer] to array comparison
- */
-fun RealBuffer.contentEquals(vararg doubles: Double) = array.contentEquals(doubles)
\ No newline at end of file
diff --git a/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realMatrix.kt b/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realMatrix.kt
deleted file mode 100644
index b5569cca6..000000000
--- a/kmath-for-real/src/commonMain/kotlin/scientifik/kmath/real/realMatrix.kt
+++ /dev/null
@@ -1,165 +0,0 @@
-package scientifik.kmath.real
-
-import scientifik.kmath.linear.MatrixContext
-import scientifik.kmath.linear.RealMatrixContext.elementContext
-import scientifik.kmath.linear.VirtualMatrix
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.operations.sum
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.Matrix
-import scientifik.kmath.structures.RealBuffer
-import scientifik.kmath.structures.asIterable
-import kotlin.contracts.contract
-import kotlin.math.pow
-
-/*
- *  Functions for convenient "numpy-like" operations with Double matrices.
- *
- *  Initial implementation of these functions is taken from:
- *    https://github.com/thomasnield/numky/blob/master/src/main/kotlin/org/nield/numky/linear/DoubleOperators.kt
- *
- */
-
-/*
- *  Functions that help create a real (Double) matrix
- */
-
-typealias RealMatrix = Matrix<Double>
-
-fun realMatrix(rowNum: Int, colNum: Int, initializer: (i: Int, j: Int) -> Double): RealMatrix =
-    MatrixContext.real.produce(rowNum, colNum, initializer)
-
-fun Array<DoubleArray>.toMatrix(): RealMatrix {
-    return MatrixContext.real.produce(size, this[0].size) { row, col -> this[row][col] }
-}
-
-fun Sequence<DoubleArray>.toMatrix(): RealMatrix = toList().let {
-    MatrixContext.real.produce(it.size, it[0].size) { row, col -> it[row][col] }
-}
-
-fun Matrix<Double>.repeatStackVertical(n: Int): RealMatrix =
-    VirtualMatrix(rowNum * n, colNum) { row, col ->
-        get(if (row == 0) 0 else row % rowNum, col)
-    }
-
-/*
- *  Operations for matrix and real number
- */
-
-operator fun Matrix<Double>.times(double: Double): RealMatrix =
-    MatrixContext.real.produce(rowNum, colNum) { row, col ->
-        this[row, col] * double
-    }
-
-operator fun Matrix<Double>.plus(double: Double): RealMatrix =
-    MatrixContext.real.produce(rowNum, colNum) { row, col ->
-        this[row, col] + double
-    }
-
-operator fun Matrix<Double>.minus(double: Double): RealMatrix =
-    MatrixContext.real.produce(rowNum, colNum) { row, col ->
-        this[row, col] - double
-    }
-
-operator fun Matrix<Double>.div(double: Double): RealMatrix =
-    MatrixContext.real.produce(rowNum, colNum) { row, col ->
-        this[row, col] / double
-    }
-
-operator fun Double.times(matrix: Matrix<Double>): RealMatrix =
-    MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
-        this * matrix[row, col]
-    }
-
-operator fun Double.plus(matrix: Matrix<Double>): RealMatrix =
-    MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
-        this + matrix[row, col]
-    }
-
-operator fun Double.minus(matrix: Matrix<Double>): RealMatrix =
-    MatrixContext.real.produce(matrix.rowNum, matrix.colNum) { row, col ->
-        this - matrix[row, col]
-    }
-
-// TODO: does this operation make sense? Should it be 'this/matrix[row, col]'?
-//operator fun Double.div(matrix: Matrix<Double>) = MatrixContext.real.produce(matrix.rowNum, matrix.colNum) {
-//    row, col -> matrix[row, col] / this
-//}
-
-/*
- *  Per-element (!) square and power operations
- */
-
-fun Matrix<Double>.square(): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { row, col ->
-    this[row, col].pow(2)
-}
-
-fun Matrix<Double>.pow(n: Int): RealMatrix = MatrixContext.real.produce(rowNum, colNum) { i, j ->
-    this[i, j].pow(n)
-}
-
-/*
- * Operations on two matrices (per-element!)
- */
-
-operator fun Matrix<Double>.times(other: Matrix<Double>): RealMatrix =
-    MatrixContext.real.produce(rowNum, colNum) { row, col ->
-        this[row, col] * other[row, col]
-    }
-
-operator fun Matrix<Double>.plus(other: Matrix<Double>): RealMatrix =
-    MatrixContext.real.add(this, other)
-
-operator fun Matrix<Double>.minus(other: Matrix<Double>): RealMatrix =
-    MatrixContext.real.produce(rowNum, colNum) { row, col ->
-        this[row, col] - other[row, col]
-    }
-
-/*
- *  Operations on columns
- */
-
-inline fun Matrix<Double>.appendColumn(crossinline mapper: (Buffer<Double>) -> Double): Matrix<Double> {
-    contract { callsInPlace(mapper) }
-
-    return MatrixContext.real.produce(rowNum, colNum + 1) { row, col ->
-        if (col < colNum)
-            this[row, col]
-        else
-            mapper(rows[row])
-    }
-}
-
-fun Matrix<Double>.extractColumns(columnRange: IntRange): RealMatrix =
-    MatrixContext.real.produce(rowNum, columnRange.count()) { row, col ->
-        this[row, columnRange.first + col]
-    }
-
-fun Matrix<Double>.extractColumn(columnIndex: Int): RealMatrix =
-    extractColumns(columnIndex..columnIndex)
-
-fun Matrix<Double>.sumByColumn(): RealBuffer = RealBuffer(colNum) { j ->
-    val column = columns[j]
-    elementContext { sum(column.asIterable()) }
-}
-
-fun Matrix<Double>.minByColumn(): RealBuffer = RealBuffer(colNum) { j ->
-    columns[j].asIterable().min() ?: error("Cannot produce min on empty column")
-}
-
-fun Matrix<Double>.maxByColumn(): RealBuffer = RealBuffer(colNum) { j ->
-    columns[j].asIterable().max() ?: error("Cannot produce min on empty column")
-}
-
-fun Matrix<Double>.averageByColumn(): RealBuffer = RealBuffer(colNum) { j ->
-    columns[j].asIterable().average()
-}
-
-/*
- * Operations processing all elements
- */
-
-fun Matrix<Double>.sum(): Double = elements().map { (_, value) -> value }.sum()
-fun Matrix<Double>.min(): Double? = elements().map { (_, value) -> value }.min()
-fun Matrix<Double>.max(): Double? = elements().map { (_, value) -> value }.max()
-fun Matrix<Double>.average(): Double = elements().map { (_, value) -> value }.average()
diff --git a/kmath-for-real/src/commonTest/kotlin/scientifik/kmath/linear/VectorTest.kt b/kmath-for-real/src/commonTest/kotlin/kscience/kmath/linear/VectorTest.kt
similarity index 86%
rename from kmath-for-real/src/commonTest/kotlin/scientifik/kmath/linear/VectorTest.kt
rename to kmath-for-real/src/commonTest/kotlin/kscience/kmath/linear/VectorTest.kt
index ef7f40afe..17ff4ef20 100644
--- a/kmath-for-real/src/commonTest/kotlin/scientifik/kmath/linear/VectorTest.kt
+++ b/kmath-for-real/src/commonTest/kotlin/kscience/kmath/linear/VectorTest.kt
@@ -1,11 +1,11 @@
-package scientifik.kmath.linear
+package kscience.kmath.linear
 
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.real.RealVector
+import kscience.kmath.operations.invoke
+import kscience.kmath.real.RealVector
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-class VectorTest {
+internal class VectorTest {
     @Test
     fun testSum() {
         val vector1 = RealVector(5) { it.toDouble() }
diff --git a/kmath-for-real/src/commonTest/kotlin/scientific.kmath.real/RealMatrixTest.kt b/kmath-for-real/src/commonTest/kotlin/scientific.kmath.real/RealMatrixTest.kt
index 8918fb300..859938481 100644
--- a/kmath-for-real/src/commonTest/kotlin/scientific.kmath.real/RealMatrixTest.kt
+++ b/kmath-for-real/src/commonTest/kotlin/scientific.kmath.real/RealMatrixTest.kt
@@ -1,14 +1,14 @@
 package scientific.kmath.real
 
-import scientifik.kmath.linear.VirtualMatrix
-import scientifik.kmath.linear.build
-import scientifik.kmath.real.*
-import scientifik.kmath.structures.Matrix
+import kscience.kmath.linear.VirtualMatrix
+import kscience.kmath.linear.build
+import kscience.kmath.real.*
+import kscience.kmath.structures.Matrix
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertTrue
 
-class RealMatrixTest {
+internal class RealMatrixTest {
     @Test
     fun testSum() {
         val m = realMatrix(10, 10) { i, j -> (i + j).toDouble() }
diff --git a/kmath-functions/build.gradle.kts b/kmath-functions/build.gradle.kts
index 675457ac5..2a4539c10 100644
--- a/kmath-functions/build.gradle.kts
+++ b/kmath-functions/build.gradle.kts
@@ -1,5 +1,5 @@
 plugins {
-    id("scientifik.mpp")
+    id("ru.mipt.npm.mpp")
 }
 
 kotlin.sourceSets.commonMain {
diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Piecewise.kt b/kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/Piecewise.kt
similarity index 56%
rename from kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Piecewise.kt
rename to kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/Piecewise.kt
index 16f8aa12b..a8c020c05 100644
--- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Piecewise.kt
+++ b/kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/Piecewise.kt
@@ -1,48 +1,46 @@
-package scientifik.kmath.functions
+package kscience.kmath.functions
 
-import scientifik.kmath.operations.Ring
+import kscience.kmath.operations.Ring
 
-interface Piecewise<T, R> {
-    fun findPiece(arg: T): R?
+public fun interface Piecewise<T, R> {
+    public fun findPiece(arg: T): R?
 }
 
-interface PiecewisePolynomial<T : Any> :
+public fun interface PiecewisePolynomial<T : Any> :
     Piecewise<T, Polynomial<T>>
 
 /**
  * Ordered list of pieces in piecewise function
  */
-class OrderedPiecewisePolynomial<T : Comparable<T>>(delimeter: T) :
+public class OrderedPiecewisePolynomial<T : Comparable<T>>(delimiter: T) :
     PiecewisePolynomial<T> {
-
-    private val delimiters: ArrayList<T> = arrayListOf(delimeter)
-    private val pieces: ArrayList<Polynomial<T>> = ArrayList()
+    private val delimiters: MutableList<T> = arrayListOf(delimiter)
+    private val pieces: MutableList<Polynomial<T>> = arrayListOf()
 
     /**
      * Dynamically add a piece to the "right" side (beyond maximum argument value of previous piece)
      * @param right new rightmost position. If is less then current rightmost position, a error is thrown.
      */
-    fun putRight(right: T, piece: Polynomial<T>) {
+    public fun putRight(right: T, piece: Polynomial<T>) {
         require(right > delimiters.last()) { "New delimiter should be to the right of old one" }
         delimiters.add(right)
         pieces.add(piece)
     }
 
-    fun putLeft(left: T, piece: Polynomial<T>) {
+    public fun putLeft(left: T, piece: Polynomial<T>) {
         require(left < delimiters.first()) { "New delimiter should be to the left of old one" }
         delimiters.add(0, left)
         pieces.add(0, piece)
     }
 
     override fun findPiece(arg: T): Polynomial<T>? {
-        if (arg < delimiters.first() || arg >= delimiters.last()) {
+        if (arg < delimiters.first() || arg >= delimiters.last())
             return null
-        } else {
-            for (index in 1 until delimiters.size) {
-                if (arg < delimiters[index]) {
+        else {
+            for (index in 1 until delimiters.size)
+                if (arg < delimiters[index])
                     return pieces[index - 1]
-                }
-            }
+
             error("Piece not found")
         }
     }
@@ -51,7 +49,7 @@ class OrderedPiecewisePolynomial<T : Comparable<T>>(delimeter: T) :
 /**
  * Return a value of polynomial function with given [ring] an given [arg] or null if argument is outside of piecewise definition.
  */
-fun <T : Comparable<T>, C : Ring<T>> PiecewisePolynomial<T>.value(ring: C, arg: T): T? =
+public fun <T : Comparable<T>, C : Ring<T>> PiecewisePolynomial<T>.value(ring: C, arg: T): T? =
     findPiece(arg)?.value(ring, arg)
 
-fun <T : Comparable<T>, C : Ring<T>> PiecewisePolynomial<T>.asFunction(ring: C): (T) -> T? = { value(ring, it) }
\ No newline at end of file
+public fun <T : Comparable<T>, C : Ring<T>> PiecewisePolynomial<T>.asFunction(ring: C): (T) -> T? = { value(ring, it) }
\ No newline at end of file
diff --git a/kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/Polynomial.kt
new file mode 100644
index 000000000..c513a6889
--- /dev/null
+++ b/kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/Polynomial.kt
@@ -0,0 +1,74 @@
+package kscience.kmath.functions
+
+import kscience.kmath.operations.Ring
+import kscience.kmath.operations.Space
+import kscience.kmath.operations.invoke
+import kotlin.contracts.InvocationKind
+import kotlin.contracts.contract
+import kotlin.math.max
+import kotlin.math.pow
+
+// TODO make `inline`, when KT-41771 gets fixed
+/**
+ * Polynomial coefficients without fixation on specific context they are applied to
+ * @param coefficients constant is the leftmost coefficient
+ */
+public inline class Polynomial<T : Any>(public val coefficients: List<T>)
+
+public fun <T : Any> Polynomial(vararg coefficients: T): Polynomial<T> = Polynomial(coefficients.toList())
+
+public fun Polynomial<Double>.value(): Double = coefficients.reduceIndexed { index, acc, d -> acc + d.pow(index) }
+
+public fun <T : Any, C : Ring<T>> Polynomial<T>.value(ring: C, arg: T): T = ring {
+    if (coefficients.isEmpty()) return@ring zero
+    var res = coefficients.first()
+    var powerArg = arg
+
+    for (index in 1 until coefficients.size) {
+        res += coefficients[index] * powerArg
+        // recalculating power on each step to avoid power costs on long polynomials
+        powerArg *= arg
+    }
+
+    res
+}
+
+/**
+ * Represent a polynomial as a context-dependent function
+ */
+public fun <T : Any, C : Ring<T>> Polynomial<T>.asMathFunction(): MathFunction<T, C, T> =
+    object : MathFunction<T, C, T> {
+        override fun C.invoke(arg: T): T = value(this, arg)
+    }
+
+/**
+ * Represent the polynomial as a regular context-less function
+ */
+public fun <T : Any, C : Ring<T>> Polynomial<T>.asFunction(ring: C): (T) -> T = { value(ring, it) }
+
+/**
+ * An algebra for polynomials
+ */
+public class PolynomialSpace<T : Any, C : Ring<T>>(public val ring: C) : Space<Polynomial<T>> {
+    public override val zero: Polynomial<T> = Polynomial(emptyList())
+
+    public override fun add(a: Polynomial<T>, b: Polynomial<T>): Polynomial<T> {
+        val dim = max(a.coefficients.size, b.coefficients.size)
+
+        return ring {
+            Polynomial(List(dim) { index ->
+                a.coefficients.getOrElse(index) { zero } + b.coefficients.getOrElse(index) { zero }
+            })
+        }
+    }
+
+    public override fun multiply(a: Polynomial<T>, k: Number): Polynomial<T> =
+        ring { Polynomial(List(a.coefficients.size) { index -> a.coefficients[index] * k }) }
+
+    public operator fun Polynomial<T>.invoke(arg: T): T = value(ring, arg)
+}
+
+public inline fun <T : Any, C : Ring<T>, R> C.polynomial(block: PolynomialSpace<T, C>.() -> R): R {
+    contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
+    return PolynomialSpace(this).block()
+}
diff --git a/kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/functions.kt b/kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/functions.kt
new file mode 100644
index 000000000..d780c16f3
--- /dev/null
+++ b/kmath-functions/src/commonMain/kotlin/kscience/kmath/functions/functions.kt
@@ -0,0 +1,34 @@
+package kscience.kmath.functions
+
+import kscience.kmath.operations.Algebra
+import kscience.kmath.operations.RealField
+
+// TODO make fun interface when KT-41770 is fixed
+/**
+ * A regular function that could be called only inside specific algebra context
+ * @param T source type
+ * @param C source algebra constraint
+ * @param R result type
+ */
+public /*fun*/ interface MathFunction<T, C : Algebra<T>, R> {
+    public operator fun C.invoke(arg: T): R
+}
+
+public fun <R> MathFunction<Double, RealField, R>.invoke(arg: Double): R = RealField.invoke(arg)
+
+/**
+ * A suspendable function defined in algebraic context
+ */
+// TODO make fun interface, when the new JVM IR is enabled
+public interface SuspendableMathFunction<T, C : Algebra<T>, R> {
+    public suspend operator fun C.invoke(arg: T): R
+}
+
+public suspend fun <R> SuspendableMathFunction<Double, RealField, R>.invoke(arg: Double): R = RealField.invoke(arg)
+
+/**
+ * A parametric function with parameter
+ */
+public fun interface ParametricFunction<T, P, C : Algebra<T>> {
+    public operator fun C.invoke(arg: T, parameter: P): T
+}
diff --git a/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/Interpolator.kt b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/Interpolator.kt
new file mode 100644
index 000000000..0620b4aa8
--- /dev/null
+++ b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/Interpolator.kt
@@ -0,0 +1,45 @@
+package kscience.kmath.interpolation
+
+import kscience.kmath.functions.PiecewisePolynomial
+import kscience.kmath.functions.value
+import kscience.kmath.operations.Ring
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.asBuffer
+
+public fun interface Interpolator<X, Y> {
+    public fun interpolate(points: XYPointSet<X, Y>): (X) -> Y
+}
+
+public interface PolynomialInterpolator<T : Comparable<T>> : Interpolator<T, T> {
+    public val algebra: Ring<T>
+
+    public fun getDefaultValue(): T = error("Out of bounds")
+
+    public fun interpolatePolynomials(points: XYPointSet<T, T>): PiecewisePolynomial<T>
+
+    override fun interpolate(points: XYPointSet<T, T>): (T) -> T = { x ->
+        interpolatePolynomials(points).value(algebra, x) ?: getDefaultValue()
+    }
+}
+
+public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials(
+    x: Buffer<T>,
+    y: Buffer<T>
+): PiecewisePolynomial<T> {
+    val pointSet = BufferXYPointSet(x, y)
+    return interpolatePolynomials(pointSet)
+}
+
+public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials(
+    data: Map<T, T>
+): PiecewisePolynomial<T> {
+    val pointSet = BufferXYPointSet(data.keys.toList().asBuffer(), data.values.toList().asBuffer())
+    return interpolatePolynomials(pointSet)
+}
+
+public fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials(
+    data: List<Pair<T, T>>
+): PiecewisePolynomial<T> {
+    val pointSet = BufferXYPointSet(data.map { it.first }.asBuffer(), data.map { it.second }.asBuffer())
+    return interpolatePolynomials(pointSet)
+}
diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LinearInterpolator.kt b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/LinearInterpolator.kt
similarity index 57%
rename from kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LinearInterpolator.kt
rename to kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/LinearInterpolator.kt
index a7925180d..377aa1fbe 100644
--- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LinearInterpolator.kt
+++ b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/LinearInterpolator.kt
@@ -1,16 +1,16 @@
-package scientifik.kmath.interpolation
+package kscience.kmath.interpolation
 
-import scientifik.kmath.functions.OrderedPiecewisePolynomial
-import scientifik.kmath.functions.PiecewisePolynomial
-import scientifik.kmath.functions.Polynomial
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.invoke
+import kscience.kmath.functions.OrderedPiecewisePolynomial
+import kscience.kmath.functions.PiecewisePolynomial
+import kscience.kmath.functions.Polynomial
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.invoke
 
 /**
  * Reference JVM implementation: https://github.com/apache/commons-math/blob/master/src/main/java/org/apache/commons/math4/analysis/interpolation/LinearInterpolator.java
  */
-class LinearInterpolator<T : Comparable<T>>(override val algebra: Field<T>) : PolynomialInterpolator<T> {
-    override fun interpolatePolynomials(points: XYPointSet<T, T>): PiecewisePolynomial<T> = algebra {
+public class LinearInterpolator<T : Comparable<T>>(public override val algebra: Field<T>) : PolynomialInterpolator<T> {
+    public override fun interpolatePolynomials(points: XYPointSet<T, T>): PiecewisePolynomial<T> = algebra {
         require(points.size > 0) { "Point array should not be empty" }
         insureSorted(points)
 
diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LoessInterpolator.kt b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/LoessInterpolator.kt
similarity index 98%
rename from kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LoessInterpolator.kt
rename to kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/LoessInterpolator.kt
index 6707bd8bc..6931857b1 100644
--- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/LoessInterpolator.kt
+++ b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/LoessInterpolator.kt
@@ -1,8 +1,8 @@
-package scientifik.kmath.interpolation
+package kscience.kmath.interpolation
 //
-//import scientifik.kmath.functions.PiecewisePolynomial
-//import scientifik.kmath.operations.Ring
-//import scientifik.kmath.structures.Buffer
+//import kscience.kmath.functions.PiecewisePolynomial
+//import kscience.kmath.operations.Ring
+//import kscience.kmath.structures.Buffer
 //import kotlin.math.abs
 //import kotlin.math.sqrt
 //
diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/SplineInterpolator.kt b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/SplineInterpolator.kt
similarity index 69%
rename from kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/SplineInterpolator.kt
rename to kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/SplineInterpolator.kt
index b709c4e87..6cda45f72 100644
--- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/SplineInterpolator.kt
+++ b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/SplineInterpolator.kt
@@ -1,29 +1,25 @@
-package scientifik.kmath.interpolation
+package kscience.kmath.interpolation
 
-import scientifik.kmath.functions.OrderedPiecewisePolynomial
-import scientifik.kmath.functions.PiecewisePolynomial
-import scientifik.kmath.functions.Polynomial
-import scientifik.kmath.operations.Field
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.structures.MutableBufferFactory
+import kscience.kmath.functions.OrderedPiecewisePolynomial
+import kscience.kmath.functions.PiecewisePolynomial
+import kscience.kmath.functions.Polynomial
+import kscience.kmath.operations.Field
+import kscience.kmath.operations.invoke
+import kscience.kmath.structures.MutableBufferFactory
 
 /**
  * Generic spline interpolator. Not recommended for performance critical places, use platform-specific and type specific ones.
  * Based on https://github.com/apache/commons-math/blob/eb57d6d457002a0bb5336d789a3381a24599affe/src/main/java/org/apache/commons/math4/analysis/interpolation/SplineInterpolator.java
  */
-class SplineInterpolator<T : Comparable<T>>(
-    override val algebra: Field<T>,
-    val bufferFactory: MutableBufferFactory<T>
+public class SplineInterpolator<T : Comparable<T>>(
+    public override val algebra: Field<T>,
+    public val bufferFactory: MutableBufferFactory<T>
 ) : PolynomialInterpolator<T> {
-
     //TODO possibly optimize zeroed buffers
 
-    override fun interpolatePolynomials(points: XYPointSet<T, T>): PiecewisePolynomial<T> = algebra {
-        if (points.size < 3) {
-            error("Can't use spline interpolator with less than 3 points")
-        }
+    public override fun interpolatePolynomials(points: XYPointSet<T, T>): PiecewisePolynomial<T> = algebra {
+        require(points.size >= 3) { "Can't use spline interpolator with less than 3 points" }
         insureSorted(points)
-
         // Number of intervals.  The number of data points is n + 1.
         val n = points.size - 1
         // Differences between knot points
@@ -34,6 +30,7 @@ class SplineInterpolator<T : Comparable<T>>(
         for (i in 1 until n) {
             val g = 2.0 * (points.x[i + 1] - points.x[i - 1]) - h[i - 1] * mu[i - 1]
             mu[i] = h[i] / g
+
             z[i] =
                 (3.0 * (points.y[i + 1] * h[i - 1] - points.x[i] * (points.x[i + 1] - points.x[i - 1]) + points.y[i - 1] * h[i]) / (h[i - 1] * h[i])
                         - h[i - 1] * z[i - 1]) / g
@@ -41,8 +38,9 @@ class SplineInterpolator<T : Comparable<T>>(
 
         // cubic spline coefficients --  b is linear, c quadratic, d is cubic (original y's are constants)
 
-        OrderedPiecewisePolynomial<T>(points.x[points.size - 1]).apply {
+        OrderedPiecewisePolynomial(points.x[points.size - 1]).apply {
             var cOld = zero
+
             for (j in n - 1 downTo 0) {
                 val c = z[j] - mu[j] * cOld
                 val a = points.y[j]
@@ -53,7 +51,5 @@ class SplineInterpolator<T : Comparable<T>>(
                 putLeft(points.x[j], polynomial)
             }
         }
-
     }
-
 }
diff --git a/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/XYPointSet.kt b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/XYPointSet.kt
new file mode 100644
index 000000000..2abb7742c
--- /dev/null
+++ b/kmath-functions/src/commonMain/kotlin/kscience/kmath/interpolation/XYPointSet.kt
@@ -0,0 +1,53 @@
+package kscience.kmath.interpolation
+
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.Structure2D
+
+public interface XYPointSet<X, Y> {
+    public val size: Int
+    public val x: Buffer<X>
+    public val y: Buffer<Y>
+}
+
+public interface XYZPointSet<X, Y, Z> : XYPointSet<X, Y> {
+    public val z: Buffer<Z>
+}
+
+internal fun <T : Comparable<T>> insureSorted(points: XYPointSet<T, *>) {
+    for (i in 0 until points.size - 1)
+        require(points.x[i + 1] > points.x[i]) { "Input data is not sorted at index $i" }
+}
+
+public class NDStructureColumn<T>(public val structure: Structure2D<T>, public val column: Int) : Buffer<T> {
+    public override val size: Int
+        get() = structure.rowNum
+
+    init {
+        require(column < structure.colNum) { "Column index is outside of structure column range" }
+    }
+
+    public override operator fun get(index: Int): T = structure[index, column]
+    public override operator fun iterator(): Iterator<T> = sequence { repeat(size) { yield(get(it)) } }.iterator()
+}
+
+public class BufferXYPointSet<X, Y>(
+    public override val x: Buffer<X>,
+    public override val y: Buffer<Y>
+) : XYPointSet<X, Y> {
+    public override val size: Int
+        get() = x.size
+
+    init {
+        require(x.size == y.size) { "Sizes of x and y buffers should be the same" }
+    }
+}
+
+public fun <T> Structure2D<T>.asXYPointSet(): XYPointSet<T, T> {
+    require(shape[1] == 2) { "Structure second dimension should be of size 2" }
+
+    return object : XYPointSet<T, T> {
+        override val size: Int get() = this@asXYPointSet.shape[0]
+        override val x: Buffer<T> get() = NDStructureColumn(this@asXYPointSet, 0)
+        override val y: Buffer<T> get() = NDStructureColumn(this@asXYPointSet, 1)
+    }
+}
diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Polynomial.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Polynomial.kt
deleted file mode 100644
index fcfa9f1aa..000000000
--- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/Polynomial.kt
+++ /dev/null
@@ -1,76 +0,0 @@
-package scientifik.kmath.functions
-
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.operations.Space
-import scientifik.kmath.operations.invoke
-import kotlin.contracts.InvocationKind
-import kotlin.contracts.contract
-import kotlin.math.max
-import kotlin.math.pow
-
-/**
- * Polynomial coefficients without fixation on specific context they are applied to
- * @param coefficients constant is the leftmost coefficient
- */
-inline class Polynomial<T : Any>(val coefficients: List<T>) {
-    constructor(vararg coefficients: T) : this(coefficients.toList())
-}
-
-fun Polynomial<Double>.value(): Double =
-    coefficients.reduceIndexed { index: Int, acc: Double, d: Double -> acc + d.pow(index) }
-
-fun <T : Any, C : Ring<T>> Polynomial<T>.value(ring: C, arg: T): T = ring {
-    if (coefficients.isEmpty()) return@ring zero
-    var res = coefficients.first()
-    var powerArg = arg
-
-    for (index in 1 until coefficients.size) {
-        res += coefficients[index] * powerArg
-        //recalculating power on each step to avoid power costs on long polynomials
-        powerArg *= arg
-    }
-
-    res
-}
-
-/**
- * Represent a polynomial as a context-dependent function
- */
-fun <T : Any, C : Ring<T>> Polynomial<T>.asMathFunction(): MathFunction<T, out C, T> = object :
-    MathFunction<T, C, T> {
-    override operator fun C.invoke(arg: T): T = value(this, arg)
-}
-
-/**
- * Represent the polynomial as a regular context-less function
- */
-fun <T : Any, C : Ring<T>> Polynomial<T>.asFunction(ring: C): (T) -> T = { value(ring, it) }
-
-/**
- * An algebra for polynomials
- */
-class PolynomialSpace<T : Any, C : Ring<T>>(val ring: C) : Space<Polynomial<T>> {
-
-    override fun add(a: Polynomial<T>, b: Polynomial<T>): Polynomial<T> {
-        val dim = max(a.coefficients.size, b.coefficients.size)
-
-        return ring {
-            Polynomial(List(dim) { index ->
-                a.coefficients.getOrElse(index) { zero } + b.coefficients.getOrElse(index) { zero }
-            })
-        }
-    }
-
-    override fun multiply(a: Polynomial<T>, k: Number): Polynomial<T> =
-        ring { Polynomial(List(a.coefficients.size) { index -> a.coefficients[index] * k }) }
-
-    override val zero: Polynomial<T> =
-        Polynomial(emptyList())
-
-    operator fun Polynomial<T>.invoke(arg: T): T = value(ring, arg)
-}
-
-inline fun <T : Any, C : Ring<T>, R> C.polynomial(block: PolynomialSpace<T, C>.() -> R): R {
-    contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
-    return PolynomialSpace(this).block()
-}
diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/functions.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/functions.kt
deleted file mode 100644
index 2b822b3ba..000000000
--- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/functions/functions.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package scientifik.kmath.functions
-
-import scientifik.kmath.operations.Algebra
-import scientifik.kmath.operations.RealField
-
-/**
- * A regular function that could be called only inside specific algebra context
- * @param T source type
- * @param C source algebra constraint
- * @param R result type
- */
-interface MathFunction<T, C : Algebra<T>, R> {
-    operator fun C.invoke(arg: T): R
-}
-
-fun <R> MathFunction<Double, RealField, R>.invoke(arg: Double): R = RealField.invoke(arg)
-
-/**
- * A suspendable function defined in algebraic context
- */
-interface SuspendableMathFunction<T, C : Algebra<T>, R> {
-    suspend operator fun C.invoke(arg: T): R
-}
-
-suspend fun <R> SuspendableMathFunction<Double, RealField, R>.invoke(arg: Double) = RealField.invoke(arg)
-
-
-/**
- * A parametric function with parameter
- */
-interface ParametricFunction<T, P, C : Algebra<T>> {
-    operator fun C.invoke(arg: T, parameter: P): T
-}
diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/Interpolator.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/Interpolator.kt
deleted file mode 100644
index 8d83e4198..000000000
--- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/Interpolator.kt
+++ /dev/null
@@ -1,45 +0,0 @@
-package scientifik.kmath.interpolation
-
-import scientifik.kmath.functions.PiecewisePolynomial
-import scientifik.kmath.functions.value
-import scientifik.kmath.operations.Ring
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.asBuffer
-
-interface Interpolator<X, Y> {
-    fun interpolate(points: XYPointSet<X, Y>): (X) -> Y
-}
-
-interface PolynomialInterpolator<T : Comparable<T>> : Interpolator<T, T> {
-    val algebra: Ring<T>
-
-    fun getDefaultValue(): T = error("Out of bounds")
-
-    fun interpolatePolynomials(points: XYPointSet<T, T>): PiecewisePolynomial<T>
-
-    override fun interpolate(points: XYPointSet<T, T>): (T) -> T = { x ->
-        interpolatePolynomials(points).value(algebra, x) ?: getDefaultValue()
-    }
-}
-
-fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials(
-    x: Buffer<T>,
-    y: Buffer<T>
-): PiecewisePolynomial<T> {
-    val pointSet = BufferXYPointSet(x, y)
-    return interpolatePolynomials(pointSet)
-}
-
-fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials(
-    data: Map<T, T>
-): PiecewisePolynomial<T> {
-    val pointSet = BufferXYPointSet(data.keys.toList().asBuffer(), data.values.toList().asBuffer())
-    return interpolatePolynomials(pointSet)
-}
-
-fun <T : Comparable<T>> PolynomialInterpolator<T>.interpolatePolynomials(
-    data: List<Pair<T, T>>
-): PiecewisePolynomial<T> {
-    val pointSet = BufferXYPointSet(data.map { it.first }.asBuffer(), data.map { it.second }.asBuffer())
-    return interpolatePolynomials(pointSet)
-}
\ No newline at end of file
diff --git a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/XYPointSet.kt b/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/XYPointSet.kt
deleted file mode 100644
index 56953f9fc..000000000
--- a/kmath-functions/src/commonMain/kotlin/scientifik/kmath/interpolation/XYPointSet.kt
+++ /dev/null
@@ -1,52 +0,0 @@
-package scientifik.kmath.interpolation
-
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.Structure2D
-
-interface XYPointSet<X, Y> {
-    val size: Int
-    val x: Buffer<X>
-    val y: Buffer<Y>
-}
-
-interface XYZPointSet<X, Y, Z> : XYPointSet<X, Y> {
-    val z: Buffer<Z>
-}
-
-internal fun <T : Comparable<T>> insureSorted(points: XYPointSet<T, *>) {
-    for (i in 0 until points.size - 1) require(points.x[i + 1] > points.x[i]) { "Input data is not sorted at index $i" }
-}
-
-class NDStructureColumn<T>(val structure: Structure2D<T>, val column: Int) : Buffer<T> {
-    init {
-        require(column < structure.colNum) { "Column index is outside of structure column range" }
-    }
-
-    override val size: Int get() = structure.rowNum
-
-    override operator fun get(index: Int): T = structure[index, column]
-
-    override operator fun iterator(): Iterator<T> = sequence {
-        repeat(size) {
-            yield(get(it))
-        }
-    }.iterator()
-}
-
-class BufferXYPointSet<X, Y>(override val x: Buffer<X>, override val y: Buffer<Y>) : XYPointSet<X, Y> {
-    init {
-        require(x.size == y.size) { "Sizes of x and y buffers should be the same" }
-    }
-
-    override val size: Int
-        get() = x.size
-}
-
-fun <T> Structure2D<T>.asXYPointSet(): XYPointSet<T, T> {
-    require(shape[1] == 2) { "Structure second dimension should be of size 2" }
-    return object : XYPointSet<T, T> {
-        override val size: Int get() = this@asXYPointSet.shape[0]
-        override val x: Buffer<T> get() = NDStructureColumn(this@asXYPointSet, 0)
-        override val y: Buffer<T> get() = NDStructureColumn(this@asXYPointSet, 1)
-    }
-}
\ No newline at end of file
diff --git a/kmath-functions/src/commonTest/kotlin/scientifik/kmath/interpolation/LinearInterpolatorTest.kt b/kmath-functions/src/commonTest/kotlin/kscience/kmath/interpolation/LinearInterpolatorTest.kt
similarity index 72%
rename from kmath-functions/src/commonTest/kotlin/scientifik/kmath/interpolation/LinearInterpolatorTest.kt
rename to kmath-functions/src/commonTest/kotlin/kscience/kmath/interpolation/LinearInterpolatorTest.kt
index 23acd835c..303615676 100644
--- a/kmath-functions/src/commonTest/kotlin/scientifik/kmath/interpolation/LinearInterpolatorTest.kt
+++ b/kmath-functions/src/commonTest/kotlin/kscience/kmath/interpolation/LinearInterpolatorTest.kt
@@ -1,13 +1,12 @@
-package scientifik.kmath.interpolation
+package kscience.kmath.interpolation
 
-import scientifik.kmath.functions.PiecewisePolynomial
-import scientifik.kmath.functions.asFunction
-import scientifik.kmath.operations.RealField
+import kscience.kmath.functions.PiecewisePolynomial
+import kscience.kmath.functions.asFunction
+import kscience.kmath.operations.RealField
 import kotlin.test.Test
 import kotlin.test.assertEquals
 
-
-class LinearInterpolatorTest {
+internal class LinearInterpolatorTest {
     @Test
     fun testInterpolation() {
         val data = listOf(
@@ -16,12 +15,12 @@ class LinearInterpolatorTest {
             2.0 to 3.0,
             3.0 to 4.0
         )
+
         val polynomial: PiecewisePolynomial<Double> = LinearInterpolator(RealField).interpolatePolynomials(data)
         val function = polynomial.asFunction(RealField)
-
         assertEquals(null, function(-1.0))
         assertEquals(0.5, function(0.5))
         assertEquals(2.0, function(1.5))
         assertEquals(3.0, function(2.0))
     }
-}
\ No newline at end of file
+}
diff --git a/kmath-geometry/build.gradle.kts b/kmath-geometry/build.gradle.kts
index 39aa833ad..00abcb934 100644
--- a/kmath-geometry/build.gradle.kts
+++ b/kmath-geometry/build.gradle.kts
@@ -1,9 +1,7 @@
-plugins {
-    id("scientifik.mpp")
-}
+plugins { id("ru.mipt.npm.mpp") }
 
 kotlin.sourceSets.commonMain {
     dependencies {
         api(project(":kmath-core"))
     }
-}
\ No newline at end of file
+}
diff --git a/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Euclidean2DSpace.kt b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Euclidean2DSpace.kt
new file mode 100644
index 000000000..c2a883a64
--- /dev/null
+++ b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Euclidean2DSpace.kt
@@ -0,0 +1,47 @@
+package kscience.kmath.geometry
+
+import kscience.kmath.linear.Point
+import kscience.kmath.operations.SpaceElement
+import kscience.kmath.operations.invoke
+import kotlin.math.sqrt
+
+public interface Vector2D : Point<Double>, Vector, SpaceElement<Vector2D, Vector2D, Euclidean2DSpace> {
+    public val x: Double
+    public val y: Double
+    public override val context: Euclidean2DSpace get() = Euclidean2DSpace
+    public override val size: Int get() = 2
+
+    public override operator fun get(index: Int): Double = when (index) {
+        1 -> x
+        2 -> y
+        else -> error("Accessing outside of point bounds")
+    }
+
+    public override operator fun iterator(): Iterator<Double> = listOf(x, y).iterator()
+    public override fun unwrap(): Vector2D = this
+    public override fun Vector2D.wrap(): Vector2D = this
+}
+
+public val Vector2D.r: Double
+    get() = Euclidean2DSpace { sqrt(norm()) }
+
+@Suppress("FunctionName")
+public fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y)
+
+private data class Vector2DImpl(
+    override val x: Double,
+    override val y: Double
+) : Vector2D
+
+/**
+ * 2D Euclidean space
+ */
+public object Euclidean2DSpace : GeometrySpace<Vector2D> {
+    public override val zero: Vector2D by lazy { Vector2D(0.0, 0.0) }
+
+    public fun Vector2D.norm(): Double = sqrt(x * x + y * y)
+    public override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm()
+    public override fun add(a: Vector2D, b: Vector2D): Vector2D = Vector2D(a.x + b.x, a.y + b.y)
+    public override fun multiply(a: Vector2D, k: Number): Vector2D = Vector2D(a.x * k.toDouble(), a.y * k.toDouble())
+    public override fun Vector2D.dot(other: Vector2D): Double = x * other.x + y * other.y
+}
diff --git a/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Euclidean3DSpace.kt b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Euclidean3DSpace.kt
new file mode 100644
index 000000000..e0052d791
--- /dev/null
+++ b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Euclidean3DSpace.kt
@@ -0,0 +1,53 @@
+package kscience.kmath.geometry
+
+import kscience.kmath.linear.Point
+import kscience.kmath.operations.SpaceElement
+import kscience.kmath.operations.invoke
+import kotlin.math.sqrt
+
+public interface Vector3D : Point<Double>, Vector, SpaceElement<Vector3D, Vector3D, Euclidean3DSpace> {
+    public val x: Double
+    public val y: Double
+    public val z: Double
+    public override val context: Euclidean3DSpace get() = Euclidean3DSpace
+    public override val size: Int get() = 3
+
+    public override operator fun get(index: Int): Double = when (index) {
+        1 -> x
+        2 -> y
+        3 -> z
+        else -> error("Accessing outside of point bounds")
+    }
+
+    public override operator fun iterator(): Iterator<Double> = listOf(x, y, z).iterator()
+    public override fun unwrap(): Vector3D = this
+    public override fun Vector3D.wrap(): Vector3D = this
+}
+
+@Suppress("FunctionName")
+public fun Vector3D(x: Double, y: Double, z: Double): Vector3D = Vector3DImpl(x, y, z)
+
+public val Vector3D.r: Double get() = Euclidean3DSpace { sqrt(norm()) }
+
+private data class Vector3DImpl(
+    override val x: Double,
+    override val y: Double,
+    override val z: Double
+) : Vector3D
+
+public object Euclidean3DSpace : GeometrySpace<Vector3D> {
+    public override val zero: Vector3D by lazy { Vector3D(0.0, 0.0, 0.0) }
+
+    public fun Vector3D.norm(): Double = sqrt(x * x + y * y + z * z)
+
+    public override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm()
+
+    public override fun add(a: Vector3D, b: Vector3D): Vector3D =
+        Vector3D(a.x + b.x, a.y + b.y, a.z + b.z)
+
+    public override fun multiply(a: Vector3D, k: Number): Vector3D =
+        Vector3D(a.x * k.toDouble(), a.y * k.toDouble(), a.z * k.toDouble())
+
+    public override fun Vector3D.dot(other: Vector3D): Double =
+        x * other.x + y * other.y + z * other.z
+}
diff --git a/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/GeometrySpace.kt b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/GeometrySpace.kt
new file mode 100644
index 000000000..64badacf5
--- /dev/null
+++ b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/GeometrySpace.kt
@@ -0,0 +1,17 @@
+package kscience.kmath.geometry
+
+import kscience.kmath.operations.Space
+
+public interface Vector
+
+public interface GeometrySpace<V: Vector>: Space<V> {
+    /**
+     * L2 distance
+     */
+    public fun V.distanceTo(other: V): Double
+
+    /**
+     * Scalar product
+     */
+    public infix fun V.dot(other: V): Double
+}
\ No newline at end of file
diff --git a/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Line.kt b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Line.kt
new file mode 100644
index 000000000..ec2ce31ca
--- /dev/null
+++ b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/Line.kt
@@ -0,0 +1,6 @@
+package kscience.kmath.geometry
+
+public data class Line<V : Vector>(val base: V, val direction: V)
+
+public typealias Line2D = Line<Vector2D>
+public typealias Line3D = Line<Vector3D>
diff --git a/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/ReferenceFrame.kt b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/ReferenceFrame.kt
new file mode 100644
index 000000000..f9de7b51f
--- /dev/null
+++ b/kmath-geometry/src/commonMain/kotlin/kscience/kmath/geometry/ReferenceFrame.kt
@@ -0,0 +1,3 @@
+package kscience.kmath.geometry
+
+public interface ReferenceFrame
diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean2DSpace.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean2DSpace.kt
deleted file mode 100644
index f0dc49882..000000000
--- a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean2DSpace.kt
+++ /dev/null
@@ -1,54 +0,0 @@
-package scientifik.kmath.geometry
-
-import scientifik.kmath.linear.Point
-import scientifik.kmath.operations.SpaceElement
-import scientifik.kmath.operations.invoke
-import kotlin.math.sqrt
-
-
-interface Vector2D : Point<Double>, Vector, SpaceElement<Vector2D, Vector2D, Euclidean2DSpace> {
-    val x: Double
-    val y: Double
-    override val context: Euclidean2DSpace get() = Euclidean2DSpace
-    override val size: Int get() = 2
-
-    override operator fun get(index: Int): Double = when (index) {
-        1 -> x
-        2 -> y
-        else -> error("Accessing outside of point bounds")
-    }
-
-    override operator fun iterator(): Iterator<Double> = listOf(x, y).iterator()
-    override fun unwrap(): Vector2D = this
-    override fun Vector2D.wrap(): Vector2D = this
-}
-
-val Vector2D.r: Double get() = Euclidean2DSpace { sqrt(norm()) }
-
-@Suppress("FunctionName")
-fun Vector2D(x: Double, y: Double): Vector2D = Vector2DImpl(x, y)
-
-private data class Vector2DImpl(
-    override val x: Double,
-    override val y: Double
-) : Vector2D
-
-/**
- * 2D Euclidean space
- */
-object Euclidean2DSpace : GeometrySpace<Vector2D> {
-    fun Vector2D.norm(): Double = sqrt(x * x + y * y)
-
-    override fun Vector2D.distanceTo(other: Vector2D): Double = (this - other).norm()
-
-    override fun add(a: Vector2D, b: Vector2D): Vector2D =
-        Vector2D(a.x + b.x, a.y + b.y)
-
-    override fun multiply(a: Vector2D, k: Number): Vector2D =
-        Vector2D(a.x * k.toDouble(), a.y * k.toDouble())
-
-    override val zero: Vector2D = Vector2D(0.0, 0.0)
-
-    override fun Vector2D.dot(other: Vector2D): Double =
-        x * other.x + y * other.y
-}
\ No newline at end of file
diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean3DSpace.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean3DSpace.kt
deleted file mode 100644
index 3748e58c7..000000000
--- a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Euclidean3DSpace.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-package scientifik.kmath.geometry
-
-import scientifik.kmath.linear.Point
-import scientifik.kmath.operations.SpaceElement
-import scientifik.kmath.operations.invoke
-import kotlin.math.sqrt
-
-
-interface Vector3D : Point<Double>, Vector, SpaceElement<Vector3D, Vector3D, Euclidean3DSpace> {
-    val x: Double
-    val y: Double
-    val z: Double
-    override val context: Euclidean3DSpace get() = Euclidean3DSpace
-    override val size: Int get() = 3
-
-    override operator fun get(index: Int): Double = when (index) {
-        1 -> x
-        2 -> y
-        3 -> z
-        else -> error("Accessing outside of point bounds")
-    }
-
-    override operator fun iterator(): Iterator<Double> = listOf(x, y, z).iterator()
-
-    override fun unwrap(): Vector3D = this
-
-    override fun Vector3D.wrap(): Vector3D = this
-}
-
-@Suppress("FunctionName")
-fun Vector3D(x: Double, y: Double, z: Double): Vector3D = Vector3DImpl(x, y, z)
-
-val Vector3D.r: Double get() = Euclidean3DSpace { sqrt(norm()) }
-
-private data class Vector3DImpl(
-    override val x: Double,
-    override val y: Double,
-    override val z: Double
-) : Vector3D
-
-object Euclidean3DSpace : GeometrySpace<Vector3D> {
-    override val zero: Vector3D = Vector3D(0.0, 0.0, 0.0)
-
-    fun Vector3D.norm(): Double = sqrt(x * x + y * y + z * z)
-
-    override fun Vector3D.distanceTo(other: Vector3D): Double = (this - other).norm()
-
-    override fun add(a: Vector3D, b: Vector3D): Vector3D =
-        Vector3D(a.x + b.x, a.y + b.y, a.z + b.z)
-
-    override fun multiply(a: Vector3D, k: Number): Vector3D =
-        Vector3D(a.x * k.toDouble(), a.y * k.toDouble(), a.z * k.toDouble())
-
-    override fun Vector3D.dot(other: Vector3D): Double =
-        x * other.x + y * other.y + z * other.z
-}
diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/GeometrySpace.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/GeometrySpace.kt
deleted file mode 100644
index b65a8dd3a..000000000
--- a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/GeometrySpace.kt
+++ /dev/null
@@ -1,17 +0,0 @@
-package scientifik.kmath.geometry
-
-import scientifik.kmath.operations.Space
-
-interface Vector
-
-interface GeometrySpace<V: Vector>: Space<V> {
-    /**
-     * L2 distance
-     */
-    fun V.distanceTo(other: V): Double
-
-    /**
-     * Scalar product
-     */
-    infix fun V.dot(other: V): Double
-}
\ No newline at end of file
diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Line.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Line.kt
deleted file mode 100644
index d802a103f..000000000
--- a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/Line.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package scientifik.kmath.geometry
-
-data class Line<V: Vector>(val base: V, val direction: V)
-
-typealias Line2D = Line<Vector2D>
-typealias Line3D = Line<Vector3D>
diff --git a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/ReferenceFrame.kt b/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/ReferenceFrame.kt
deleted file mode 100644
index 420e38ce2..000000000
--- a/kmath-geometry/src/commonMain/kotlin/scientifik/kmath/geometry/ReferenceFrame.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package scientifik.kmath.geometry
-
-interface ReferenceFrame {
-}
\ No newline at end of file
diff --git a/kmath-histograms/build.gradle.kts b/kmath-histograms/build.gradle.kts
index 993bfed8e..7de21ad89 100644
--- a/kmath-histograms/build.gradle.kts
+++ b/kmath-histograms/build.gradle.kts
@@ -1,10 +1,8 @@
-plugins {
-    id("scientifik.mpp")
-}
+plugins { id("ru.mipt.npm.mpp") }
 
 kotlin.sourceSets.commonMain {
     dependencies {
         api(project(":kmath-core"))
         api(project(":kmath-for-real"))
     }
-}
\ No newline at end of file
+}
diff --git a/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Counters.kt b/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Counters.kt
new file mode 100644
index 000000000..7a263a9fc
--- /dev/null
+++ b/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Counters.kt
@@ -0,0 +1,20 @@
+package kscience.kmath.histogram
+
+/*
+ * Common representation for atomic counters
+ * TODO replace with atomics
+ */
+
+public expect class LongCounter() {
+    public fun decrement()
+    public fun increment()
+    public fun reset()
+    public fun sum(): Long
+    public fun add(l: Long)
+}
+
+public expect class DoubleCounter() {
+    public fun reset()
+    public fun sum(): Double
+    public fun add(d: Double)
+}
diff --git a/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Histogram.kt b/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Histogram.kt
new file mode 100644
index 000000000..98300dada
--- /dev/null
+++ b/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/Histogram.kt
@@ -0,0 +1,53 @@
+package kscience.kmath.histogram
+
+import kscience.kmath.domains.Domain
+import kscience.kmath.linear.Point
+import kscience.kmath.structures.ArrayBuffer
+import kscience.kmath.structures.RealBuffer
+
+/**
+ * The bin in the histogram. The histogram is by definition always done in the real space
+ */
+public interface Bin<T : Any> : Domain<T> {
+    /**
+     * The value of this bin
+     */
+    public val value: Number
+    public val center: Point<T>
+}
+
+public interface Histogram<T : Any, out B : Bin<T>> : Iterable<B> {
+    /**
+     * Find existing bin, corresponding to given coordinates
+     */
+    public operator fun get(point: Point<out T>): B?
+
+    /**
+     * Dimension of the histogram
+     */
+    public val dimension: Int
+}
+
+public interface MutableHistogram<T : Any, out B : Bin<T>> : Histogram<T, B> {
+
+    /**
+     * Increment appropriate bin
+     */
+    public fun putWithWeight(point: Point<out T>, weight: Double)
+
+    public fun put(point: Point<out T>): Unit = putWithWeight(point, 1.0)
+}
+
+public fun <T : Any> MutableHistogram<T, *>.put(vararg point: T): Unit = put(ArrayBuffer(point))
+
+public fun MutableHistogram<Double, *>.put(vararg point: Number): Unit =
+    put(RealBuffer(point.map { it.toDouble() }.toDoubleArray()))
+
+public fun MutableHistogram<Double, *>.put(vararg point: Double): Unit = put(RealBuffer(point))
+public fun <T : Any> MutableHistogram<T, *>.fill(sequence: Iterable<Point<T>>): Unit = sequence.forEach { put(it) }
+
+/**
+ * Pass a sequence builder into histogram
+ */
+public fun <T : Any> MutableHistogram<T, *>.fill(block: suspend SequenceScope<Point<T>>.() -> Unit): Unit =
+    fill(sequence(block).asIterable())
diff --git a/kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/RealHistogram.kt b/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/RealHistogram.kt
similarity index 56%
rename from kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/RealHistogram.kt
rename to kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/RealHistogram.kt
index f05ae1694..c58952ab4 100644
--- a/kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/RealHistogram.kt
+++ b/kmath-histograms/src/commonMain/kotlin/kscience/kmath/histogram/RealHistogram.kt
@@ -1,15 +1,18 @@
-package scientifik.kmath.histogram
+package kscience.kmath.histogram
 
-import scientifik.kmath.linear.Point
-import scientifik.kmath.operations.SpaceOperations
-import scientifik.kmath.operations.invoke
-import scientifik.kmath.real.asVector
-import scientifik.kmath.structures.*
+import kscience.kmath.linear.Point
+import kscience.kmath.operations.SpaceOperations
+import kscience.kmath.operations.invoke
+import kscience.kmath.real.asVector
+import kscience.kmath.structures.*
 import kotlin.math.floor
 
-
-data class BinDef<T : Comparable<T>>(val space: SpaceOperations<Point<T>>, val center: Point<T>, val sizes: Point<T>) {
-    fun contains(vector: Point<out T>): Boolean {
+public data class BinDef<T : Comparable<T>>(
+    public val space: SpaceOperations<Point<T>>,
+    public val center: Point<T>,
+    public val sizes: Point<T>
+) {
+    public fun contains(vector: Point<out T>): Boolean {
         require(vector.size == center.size) { "Dimension mismatch for input vector. Expected ${center.size}, but found ${vector.size}" }
         val upper = space { center + sizes / 2.0 }
         val lower = space { center - sizes / 2.0 }
@@ -18,21 +21,20 @@ data class BinDef<T : Comparable<T>>(val space: SpaceOperations<Point<T>>, val c
 }
 
 
-class MultivariateBin<T : Comparable<T>>(val def: BinDef<T>, override val value: Number) : Bin<T> {
-    override operator fun contains(point: Point<T>): Boolean = def.contains(point)
-
-    override val dimension: Int
+public class MultivariateBin<T : Comparable<T>>(public val def: BinDef<T>, public override val value: Number) : Bin<T> {
+    public override val dimension: Int
         get() = def.center.size
 
-    override val center: Point<T>
+    public override val center: Point<T>
         get() = def.center
 
+    public override operator fun contains(point: Point<T>): Boolean = def.contains(point)
 }
 
 /**
  * Uniform multivariate histogram with fixed borders. Based on NDStructure implementation with complexity of m for bin search, where m is the number of dimensions.
  */
-class RealHistogram(
+public class RealHistogram(
     private val lower: Buffer<Double>,
     private val upper: Buffer<Double>,
     private val binNums: IntArray = IntArray(lower.size) { 20 }
@@ -40,7 +42,7 @@ class RealHistogram(
     private val strides = DefaultStrides(IntArray(binNums.size) { binNums[it] + 2 })
     private val values: NDStructure<LongCounter> = NDStructure.auto(strides) { LongCounter() }
     private val weights: NDStructure<DoubleCounter> = NDStructure.auto(strides) { DoubleCounter() }
-    override val dimension: Int get() = lower.size
+    public override val dimension: Int get() = lower.size
     private val binSize = RealBuffer(dimension) { (upper[it] - lower[it]) / binNums[it] }
 
     init {
@@ -64,7 +66,7 @@ class RealHistogram(
 
     private fun getValue(index: IntArray): Long = values[index].sum()
 
-    fun getValue(point: Buffer<out Double>): Long = getValue(getIndex(point))
+    public fun getValue(point: Buffer<out Double>): Long = getValue(getIndex(point))
 
     private fun getDef(index: IntArray): BinDef<Double> {
         val center = index.mapIndexed { axis, i ->
@@ -78,9 +80,9 @@ class RealHistogram(
         return BinDef(RealBufferFieldOperations, center, binSize)
     }
 
-    fun getDef(point: Buffer<out Double>): BinDef<Double> = getDef(getIndex(point))
+    public fun getDef(point: Buffer<out Double>): BinDef<Double> = getDef(getIndex(point))
 
-    override operator fun get(point: Buffer<out Double>): MultivariateBin<Double>? {
+    public override operator fun get(point: Buffer<out Double>): MultivariateBin<Double>? {
         val index = getIndex(point)
         return MultivariateBin(getDef(index), getValue(index))
     }
@@ -90,27 +92,27 @@ class RealHistogram(
 //        values[index].increment()
 //    }
 
-    override fun putWithWeight(point: Buffer<out Double>, weight: Double) {
+    public override fun putWithWeight(point: Buffer<out Double>, weight: Double) {
         val index = getIndex(point)
         values[index].increment()
         weights[index].add(weight)
     }
 
-    override operator fun iterator(): Iterator<MultivariateBin<Double>> = weights.elements().map { (index, value) ->
-        MultivariateBin(getDef(index), value.sum())
-    }.iterator()
+    public override operator fun iterator(): Iterator<MultivariateBin<Double>> =
+        weights.elements().map { (index, value) -> MultivariateBin(getDef(index), value.sum()) }
+            .iterator()
 
     /**
      * Convert this histogram into NDStructure containing bin values but not bin descriptions
      */
-    fun values(): NDStructure<Number> = NDStructure.auto(values.shape) { values[it].sum() }
+    public fun values(): NDStructure<Number> = NDStructure.auto(values.shape) { values[it].sum() }
 
     /**
      * Sum of weights
      */
-    fun weights(): NDStructure<Double> = NDStructure.auto(weights.shape) { weights[it].sum() }
+    public fun weights(): NDStructure<Double> = NDStructure.auto(weights.shape) { weights[it].sum() }
 
-    companion object {
+    public companion object {
         /**
          * Use it like
          * ```
@@ -120,9 +122,9 @@ class RealHistogram(
          *)
          *```
          */
-        fun fromRanges(vararg ranges: ClosedFloatingPointRange<Double>): RealHistogram = RealHistogram(
-            ranges.map { it.start }.asVector(),
-            ranges.map { it.endInclusive }.asVector()
+        public fun fromRanges(vararg ranges: ClosedFloatingPointRange<Double>): RealHistogram = RealHistogram(
+            ranges.map(ClosedFloatingPointRange<Double>::start).asVector(),
+            ranges.map(ClosedFloatingPointRange<Double>::endInclusive).asVector()
         )
 
         /**
@@ -134,10 +136,21 @@ class RealHistogram(
          *)
          *```
          */
-        fun fromRanges(vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>): RealHistogram = RealHistogram(
-            ListBuffer(ranges.map { it.first.start }),
-            ListBuffer(ranges.map { it.first.endInclusive }),
-            ranges.map { it.second }.toIntArray()
-        )
+        public fun fromRanges(vararg ranges: Pair<ClosedFloatingPointRange<Double>, Int>): RealHistogram =
+            RealHistogram(
+                ListBuffer(
+                    ranges
+                        .map(Pair<ClosedFloatingPointRange<Double>, Int>::first)
+                        .map(ClosedFloatingPointRange<Double>::start)
+                ),
+
+                ListBuffer(
+                    ranges
+                        .map(Pair<ClosedFloatingPointRange<Double>, Int>::first)
+                        .map(ClosedFloatingPointRange<Double>::endInclusive)
+                ),
+
+                ranges.map(Pair<ClosedFloatingPointRange<Double>, Int>::second).toIntArray()
+            )
     }
 }
diff --git a/kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/Counters.kt b/kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/Counters.kt
deleted file mode 100644
index 9c7de3303..000000000
--- a/kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/Counters.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package scientifik.kmath.histogram
-
-/*
- * Common representation for atomic counters
- * TODO replace with atomics
- */
-
-expect class LongCounter() {
-    fun decrement()
-    fun increment()
-    fun reset()
-    fun sum(): Long
-    fun add(l: Long)
-}
-
-expect class DoubleCounter() {
-    fun reset()
-    fun sum(): Double
-    fun add(d: Double)
-}
\ No newline at end of file
diff --git a/kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/Histogram.kt b/kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/Histogram.kt
deleted file mode 100644
index 32b6444cc..000000000
--- a/kmath-histograms/src/commonMain/kotlin/scientifik/kmath/histogram/Histogram.kt
+++ /dev/null
@@ -1,56 +0,0 @@
-package scientifik.kmath.histogram
-
-import scientifik.kmath.domains.Domain
-import scientifik.kmath.linear.Point
-import scientifik.kmath.structures.ArrayBuffer
-import scientifik.kmath.structures.RealBuffer
-
-/**
- * The bin in the histogram. The histogram is by definition always done in the real space
- */
-interface Bin<T : Any> : Domain<T> {
-    /**
-     * The value of this bin
-     */
-    val value: Number
-    val center: Point<T>
-}
-
-interface Histogram<T : Any, out B : Bin<T>> : Iterable<B> {
-
-    /**
-     * Find existing bin, corresponding to given coordinates
-     */
-    operator fun get(point: Point<out T>): B?
-
-    /**
-     * Dimension of the histogram
-     */
-    val dimension: Int
-
-}
-
-interface MutableHistogram<T : Any, out B : Bin<T>> : Histogram<T, B> {
-
-    /**
-     * Increment appropriate bin
-     */
-    fun putWithWeight(point: Point<out T>, weight: Double)
-
-    fun put(point: Point<out T>): Unit = putWithWeight(point, 1.0)
-}
-
-fun <T : Any> MutableHistogram<T, *>.put(vararg point: T): Unit = put(ArrayBuffer(point))
-
-fun MutableHistogram<Double, *>.put(vararg point: Number): Unit =
-    put(RealBuffer(point.map { it.toDouble() }.toDoubleArray()))
-
-fun MutableHistogram<Double, *>.put(vararg point: Double): Unit = put(RealBuffer(point))
-
-fun <T : Any> MutableHistogram<T, *>.fill(sequence: Iterable<Point<T>>): Unit = sequence.forEach { put(it) }
-
-/**
- * Pass a sequence builder into histogram
- */
-fun <T : Any> MutableHistogram<T, *>.fill(block: suspend SequenceScope<Point<T>>.() -> Unit): Unit =
-    fill(sequence(block).asIterable())
diff --git a/kmath-histograms/src/commonTest/kotlin/scietifik/kmath/histogram/MultivariateHistogramTest.kt b/kmath-histograms/src/commonTest/kotlin/scietifik/kmath/histogram/MultivariateHistogramTest.kt
index 5edecb5a5..87292f17e 100644
--- a/kmath-histograms/src/commonTest/kotlin/scietifik/kmath/histogram/MultivariateHistogramTest.kt
+++ b/kmath-histograms/src/commonTest/kotlin/scietifik/kmath/histogram/MultivariateHistogramTest.kt
@@ -1,16 +1,16 @@
 package scietifik.kmath.histogram
 
-import scientifik.kmath.histogram.RealHistogram
-import scientifik.kmath.histogram.fill
-import scientifik.kmath.histogram.put
-import scientifik.kmath.real.RealVector
+import kscience.kmath.histogram.RealHistogram
+import kscience.kmath.histogram.fill
+import kscience.kmath.histogram.put
+import kscience.kmath.real.RealVector
 import kotlin.random.Random
 import kotlin.test.Test
 import kotlin.test.assertEquals
 import kotlin.test.assertFalse
 import kotlin.test.assertTrue
 
-class MultivariateHistogramTest {
+internal class MultivariateHistogramTest {
     @Test
     fun testSinglePutHistogram() {
         val histogram = RealHistogram.fromRanges(
diff --git a/kmath-histograms/src/jsMain/kotlin/kscience/kmath/histogram/Counters.kt b/kmath-histograms/src/jsMain/kotlin/kscience/kmath/histogram/Counters.kt
new file mode 100644
index 000000000..d0fa1f4c2
--- /dev/null
+++ b/kmath-histograms/src/jsMain/kotlin/kscience/kmath/histogram/Counters.kt
@@ -0,0 +1,37 @@
+package kscience.kmath.histogram
+
+public actual class LongCounter {
+    private var sum: Long = 0L
+
+    public actual fun decrement() {
+        sum--
+    }
+
+    public actual fun increment() {
+        sum++
+    }
+
+    public actual fun reset() {
+        sum = 0
+    }
+
+    public actual fun sum(): Long = sum
+
+    public actual fun add(l: Long) {
+        sum += l
+    }
+}
+
+public actual class DoubleCounter {
+    private var sum: Double = 0.0
+
+    public actual fun reset() {
+        sum = 0.0
+    }
+
+    public actual fun sum(): Double = sum
+
+    public actual fun add(d: Double) {
+        sum += d
+    }
+}
diff --git a/kmath-histograms/src/jsMain/kotlin/scientifik/kmath/histogram/Counters.kt b/kmath-histograms/src/jsMain/kotlin/scientifik/kmath/histogram/Counters.kt
deleted file mode 100644
index 3765220b9..000000000
--- a/kmath-histograms/src/jsMain/kotlin/scientifik/kmath/histogram/Counters.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-package scientifik.kmath.histogram
-
-actual class LongCounter {
-    private var sum: Long = 0
-    actual fun decrement() {
-        sum--
-    }
-
-    actual fun increment() {
-        sum++
-    }
-
-    actual fun reset() {
-        sum = 0
-    }
-
-    actual fun sum(): Long = sum
-    actual fun add(l: Long) {
-        sum += l
-    }
-}
-
-actual class DoubleCounter {
-    private var sum: Double = 0.0
-    actual fun reset() {
-        sum = 0.0
-    }
-
-    actual fun sum(): Double = sum
-    actual fun add(d: Double) {
-        sum += d
-    }
-}
\ No newline at end of file
diff --git a/kmath-histograms/src/jvmMain/kotlin/kscience/kmath/histogram/Counters.kt b/kmath-histograms/src/jvmMain/kotlin/kscience/kmath/histogram/Counters.kt
new file mode 100644
index 000000000..efbd185ef
--- /dev/null
+++ b/kmath-histograms/src/jvmMain/kotlin/kscience/kmath/histogram/Counters.kt
@@ -0,0 +1,7 @@
+package kscience.kmath.histogram
+
+import java.util.concurrent.atomic.DoubleAdder
+import java.util.concurrent.atomic.LongAdder
+
+public actual typealias LongCounter = LongAdder
+public actual typealias DoubleCounter = DoubleAdder
diff --git a/kmath-histograms/src/jvmMain/kotlin/scientifik/kmath/histogram/UnivariateHistogram.kt b/kmath-histograms/src/jvmMain/kotlin/kscience/kmath/histogram/UnivariateHistogram.kt
similarity index 54%
rename from kmath-histograms/src/jvmMain/kotlin/scientifik/kmath/histogram/UnivariateHistogram.kt
rename to kmath-histograms/src/jvmMain/kotlin/kscience/kmath/histogram/UnivariateHistogram.kt
index e30a45f5a..5fada1302 100644
--- a/kmath-histograms/src/jvmMain/kotlin/scientifik/kmath/histogram/UnivariateHistogram.kt
+++ b/kmath-histograms/src/jvmMain/kotlin/kscience/kmath/histogram/UnivariateHistogram.kt
@@ -1,32 +1,33 @@
-package scientifik.kmath.histogram
+package kscience.kmath.histogram
 
-import scientifik.kmath.real.RealVector
-import scientifik.kmath.real.asVector
-import scientifik.kmath.structures.Buffer
+import kscience.kmath.real.RealVector
+import kscience.kmath.real.asVector
+import kscience.kmath.structures.Buffer
 import java.util.*
 import kotlin.math.floor
 
 //TODO move to common
 
-class UnivariateBin(val position: Double, val size: Double, val counter: LongCounter = LongCounter()) : Bin<Double> {
+public class UnivariateBin(
+    public val position: Double,
+    public val size: Double,
+    public val counter: LongCounter = LongCounter()
+) : Bin<Double> {
     //TODO add weighting
-    override val value: Number get() = counter.sum()
+    public override val value: Number get() = counter.sum()
 
-    override val center: RealVector get() = doubleArrayOf(position).asVector()
+    public override val center: RealVector get() = doubleArrayOf(position).asVector()
+    public override val dimension: Int get() = 1
 
-    operator fun contains(value: Double): Boolean = value in (position - size / 2)..(position + size / 2)
-
-    override fun contains(point: Buffer<Double>): Boolean = contains(point[0])
-
-    internal operator fun inc() = this.also { counter.increment() }
-
-    override val dimension: Int get() = 1
+    public operator fun contains(value: Double): Boolean = value in (position - size / 2)..(position + size / 2)
+    public override fun contains(point: Buffer<Double>): Boolean = contains(point[0])
+    internal operator fun inc(): UnivariateBin = this.also { counter.increment() }
 }
 
 /**
  * Univariate histogram with log(n) bin search speed
  */
-class UnivariateHistogram private constructor(private val factory: (Double) -> UnivariateBin) :
+public class UnivariateHistogram private constructor(private val factory: (Double) -> UnivariateBin) :
     MutableHistogram<Double, UnivariateBin> {
 
     private val bins: TreeMap<Double, UnivariateBin> = TreeMap()
@@ -43,19 +44,19 @@ class UnivariateHistogram private constructor(private val factory: (Double) -> U
     }
 
     private fun createBin(value: Double): UnivariateBin = factory(value).also {
-        synchronized(this) { bins.put(it.position, it) }
+        synchronized(this) { bins[it.position] = it }
     }
 
-    override operator fun get(point: Buffer<out Double>): UnivariateBin? = get(point[0])
+    public override operator fun get(point: Buffer<out Double>): UnivariateBin? = get(point[0])
 
-    override val dimension: Int get() = 1
+    public override val dimension: Int get() = 1
 
-    override operator fun iterator(): Iterator<UnivariateBin> = bins.values.iterator()
+    public override operator fun iterator(): Iterator<UnivariateBin> = bins.values.iterator()
 
     /**
      * Thread safe put operation
      */
-    fun put(value: Double) {
+    public fun put(value: Double) {
         (get(value) ?: createBin(value)).inc()
     }
 
@@ -64,13 +65,13 @@ class UnivariateHistogram private constructor(private val factory: (Double) -> U
         put(point[0])
     }
 
-    companion object {
-        fun uniform(binSize: Double, start: Double = 0.0): UnivariateHistogram = UnivariateHistogram { value ->
+    public companion object {
+        public fun uniform(binSize: Double, start: Double = 0.0): UnivariateHistogram = UnivariateHistogram { value ->
             val center = start + binSize * floor((value - start) / binSize + 0.5)
             UnivariateBin(center, binSize)
         }
 
-        fun custom(borders: DoubleArray): UnivariateHistogram {
+        public fun custom(borders: DoubleArray): UnivariateHistogram {
             val sorted = borders.sortedArray()
 
             return UnivariateHistogram { value ->
@@ -79,12 +80,14 @@ class UnivariateHistogram private constructor(private val factory: (Double) -> U
                         Double.NEGATIVE_INFINITY,
                         Double.MAX_VALUE
                     )
+
                     value > sorted.last() -> UnivariateBin(
                         Double.POSITIVE_INFINITY,
                         Double.MAX_VALUE
                     )
+
                     else -> {
-                        val index = (0 until sorted.size).first { value > sorted[it] }
+                        val index = sorted.indices.first { value > sorted[it] }
                         val left = sorted[index]
                         val right = sorted[index + 1]
                         UnivariateBin((left + right) / 2, (right - left))
@@ -95,4 +98,4 @@ class UnivariateHistogram private constructor(private val factory: (Double) -> U
     }
 }
 
-fun UnivariateHistogram.fill(sequence: Iterable<Double>) = sequence.forEach { put(it) }
+public fun UnivariateHistogram.fill(sequence: Iterable<Double>): Unit = sequence.forEach(::put)
diff --git a/kmath-histograms/src/jvmMain/kotlin/scientifik/kmath/histogram/Counters.kt b/kmath-histograms/src/jvmMain/kotlin/scientifik/kmath/histogram/Counters.kt
deleted file mode 100644
index bb3667f7d..000000000
--- a/kmath-histograms/src/jvmMain/kotlin/scientifik/kmath/histogram/Counters.kt
+++ /dev/null
@@ -1,7 +0,0 @@
-package scientifik.kmath.histogram
-
-import java.util.concurrent.atomic.DoubleAdder
-import java.util.concurrent.atomic.LongAdder
-
-actual typealias LongCounter = LongAdder
-actual typealias DoubleCounter = DoubleAdder
\ No newline at end of file
diff --git a/kmath-memory/build.gradle.kts b/kmath-memory/build.gradle.kts
index 1f34a4f17..94527a6a3 100644
--- a/kmath-memory/build.gradle.kts
+++ b/kmath-memory/build.gradle.kts
@@ -1,3 +1 @@
-plugins {
-    id("scientifik.mpp")
-}
+plugins { id("ru.mipt.npm.mpp") }
diff --git a/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt b/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt
index 177c6b46b..8de9a7a0c 100644
--- a/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt
+++ b/kmath-memory/src/commonMain/kotlin/scientifik/memory/Memory.kt
@@ -1,4 +1,4 @@
-package scientifik.memory
+package kscience.memory
 
 import kotlin.contracts.InvocationKind
 import kotlin.contracts.contract
@@ -6,84 +6,84 @@ import kotlin.contracts.contract
 /**
  * Represents a display of certain memory structure.
  */
-interface Memory {
+public interface Memory {
     /**
      * The length of this memory in bytes.
      */
-    val size: Int
+    public val size: Int
 
     /**
      * Get a projection of this memory (it reflects the changes in the parent memory block).
      */
-    fun view(offset: Int, length: Int): Memory
+    public fun view(offset: Int, length: Int): Memory
 
     /**
      * Creates an independent copy of this memory.
      */
-    fun copy(): Memory
+    public fun copy(): Memory
 
     /**
      * Gets or creates a reader of this memory.
      */
-    fun reader(): MemoryReader
+    public fun reader(): MemoryReader
 
     /**
      * Gets or creates a writer of this memory.
      */
-    fun writer(): MemoryWriter
+    public fun writer(): MemoryWriter
 
-    companion object
+    public companion object
 }
 
 /**
  * The interface to read primitive types in this memory.
  */
-interface MemoryReader {
+public interface MemoryReader {
     /**
      * The underlying memory.
      */
-    val memory: Memory
+    public val memory: Memory
 
     /**
      * Reads [Double] at certain [offset].
      */
-    fun readDouble(offset: Int): Double
+    public fun readDouble(offset: Int): Double
 
     /**
      * Reads [Float] at certain [offset].
      */
-    fun readFloat(offset: Int): Float
+    public fun readFloat(offset: Int): Float
 
     /**
      * Reads [Byte] at certain [offset].
      */
-    fun readByte(offset: Int): Byte
+    public fun readByte(offset: Int): Byte
 
     /**
      * Reads [Short] at certain [offset].
      */
-    fun readShort(offset: Int): Short
+    public fun readShort(offset: Int): Short
 
     /**
      * Reads [Int] at certain [offset].
      */
-    fun readInt(offset: Int): Int
+    public fun readInt(offset: Int): Int
 
     /**
      * Reads [Long] at certain [offset].
      */
-    fun readLong(offset: Int): Long
+    public fun readLong(offset: Int): Long
 
     /**
      * Disposes this reader if needed.
      */
-    fun release()
+    public fun release()
 }
 
 /**
  * Uses the memory for read then releases the reader.
  */
-inline fun <R> Memory.read(block: MemoryReader.() -> R): R {
+public inline fun <R> Memory.read(block: MemoryReader.() -> R): R {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     val reader = reader()
     val result = reader.block()
@@ -94,52 +94,52 @@ inline fun <R> Memory.read(block: MemoryReader.() -> R): R {
 /**
  * The interface to write primitive types into this memory.
  */
-interface MemoryWriter {
+public interface MemoryWriter {
     /**
      * The underlying memory.
      */
-    val memory: Memory
+    public val memory: Memory
 
     /**
      * Writes [Double] at certain [offset].
      */
-    fun writeDouble(offset: Int, value: Double)
+    public fun writeDouble(offset: Int, value: Double)
 
     /**
      * Writes [Float] at certain [offset].
      */
-    fun writeFloat(offset: Int, value: Float)
+    public fun writeFloat(offset: Int, value: Float)
 
     /**
      * Writes [Byte] at certain [offset].
      */
-    fun writeByte(offset: Int, value: Byte)
+    public fun writeByte(offset: Int, value: Byte)
 
     /**
      * Writes [Short] at certain [offset].
      */
-    fun writeShort(offset: Int, value: Short)
+    public fun writeShort(offset: Int, value: Short)
 
     /**
      * Writes [Int] at certain [offset].
      */
-    fun writeInt(offset: Int, value: Int)
+    public fun writeInt(offset: Int, value: Int)
 
     /**
      * Writes [Long] at certain [offset].
      */
-    fun writeLong(offset: Int, value: Long)
+    public fun writeLong(offset: Int, value: Long)
 
     /**
      * Disposes this writer if needed.
      */
-    fun release()
+    public fun release()
 }
 
 /**
  * Uses the memory for write then releases the writer.
  */
-inline fun Memory.write(block: MemoryWriter.() -> Unit) {
+public inline fun Memory.write(block: MemoryWriter.() -> Unit) {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
     writer().apply(block).release()
 }
@@ -147,10 +147,10 @@ inline fun Memory.write(block: MemoryWriter.() -> Unit) {
 /**
  * Allocates the most effective platform-specific memory.
  */
-expect fun Memory.Companion.allocate(length: Int): Memory
+public expect fun Memory.Companion.allocate(length: Int): Memory
 
 /**
  * Wraps a [Memory] around existing [ByteArray]. This operation is unsafe since the array is not copied
  * and could be mutated independently from the resulting [Memory].
  */
-expect fun Memory.Companion.wrap(array: ByteArray): Memory
+public expect fun Memory.Companion.wrap(array: ByteArray): Memory
diff --git a/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt b/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt
index 1381afbec..d2cbb32fd 100644
--- a/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt
+++ b/kmath-memory/src/commonMain/kotlin/scientifik/memory/MemorySpec.kt
@@ -1,49 +1,49 @@
-package scientifik.memory
+package kscience.memory
 
 /**
  * A specification to read or write custom objects with fixed size in bytes.
  *
  * @param T the type of object this spec manages.
  */
-interface MemorySpec<T : Any> {
+public interface MemorySpec<T : Any> {
     /**
      * Size of [T] in bytes after serialization.
      */
-    val objectSize: Int
+    public val objectSize: Int
 
     /**
      * Reads the object starting from [offset].
      */
-    fun MemoryReader.read(offset: Int): T
+    public fun MemoryReader.read(offset: Int): T
 
     // TODO consider thread safety
 
     /**
      * Writes the object [value] starting from [offset].
      */
-    fun MemoryWriter.write(offset: Int, value: T)
+    public fun MemoryWriter.write(offset: Int, value: T)
 }
 
 /**
  * Reads the object with [spec] starting from [offset].
  */
-fun <T : Any> MemoryReader.read(spec: MemorySpec<T>, offset: Int): T = with(spec) { read(offset) }
+public fun <T : Any> MemoryReader.read(spec: MemorySpec<T>, offset: Int): T = with(spec) { read(offset) }
 
 /**
  * Writes the object [value] with [spec] starting from [offset].
  */
-fun <T : Any> MemoryWriter.write(spec: MemorySpec<T>, offset: Int, value: T): Unit = with(spec) { write(offset, value) }
+public fun <T : Any> MemoryWriter.write(spec: MemorySpec<T>, offset: Int, value: T): Unit = with(spec) { write(offset, value) }
 
 /**
  * Reads array of [size] objects mapped by [spec] at certain [offset].
  */
-inline fun <reified T : Any> MemoryReader.readArray(spec: MemorySpec<T>, offset: Int, size: Int): Array<T> =
+public inline fun <reified T : Any> MemoryReader.readArray(spec: MemorySpec<T>, offset: Int, size: Int): Array<T> =
     Array(size) { i -> with(spec) { read(offset + i * objectSize) } }
 
 /**
  * Writes [array] of objects mapped by [spec] at certain [offset].
  */
-fun <T : Any> MemoryWriter.writeArray(spec: MemorySpec<T>, offset: Int, array: Array<T>): Unit =
+public fun <T : Any> MemoryWriter.writeArray(spec: MemorySpec<T>, offset: Int, array: Array<T>): Unit =
     with(spec) { array.indices.forEach { i -> write(offset + i * objectSize, array[i]) } }
 
 // TODO It is possible to add elastic MemorySpec with unknown object size
diff --git a/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt b/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt
index 974750502..d6b8841e4 100644
--- a/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt
+++ b/kmath-memory/src/jsMain/kotlin/scientifik/memory/DataViewMemory.kt
@@ -1,4 +1,4 @@
-package scientifik.memory
+package kscience.memory
 
 import org.khronos.webgl.ArrayBuffer
 import org.khronos.webgl.DataView
@@ -83,7 +83,7 @@ private class DataViewMemory(val view: DataView) : Memory {
 /**
  * Allocates memory based on a [DataView].
  */
-actual fun Memory.Companion.allocate(length: Int): Memory {
+public actual fun Memory.Companion.allocate(length: Int): Memory {
     val buffer = ArrayBuffer(length)
     return DataViewMemory(DataView(buffer, 0, length))
 }
@@ -92,7 +92,7 @@ actual fun Memory.Companion.allocate(length: Int): Memory {
  * Wraps a [Memory] around existing [ByteArray]. This operation is unsafe since the array is not copied
  * and could be mutated independently from the resulting [Memory].
  */
-actual fun Memory.Companion.wrap(array: ByteArray): Memory {
+public actual fun Memory.Companion.wrap(array: ByteArray): Memory {
     @Suppress("CAST_NEVER_SUCCEEDS") val int8Array = array as Int8Array
     return DataViewMemory(DataView(int8Array.buffer, int8Array.byteOffset, int8Array.length))
 }
diff --git a/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt b/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt
index ac8609094..c912b28ff 100644
--- a/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt
+++ b/kmath-memory/src/jvmMain/kotlin/scientifik/memory/ByteBufferMemory.kt
@@ -1,4 +1,4 @@
-package scientifik.memory
+package kscience.memory
 
 import java.io.IOException
 import java.nio.ByteBuffer
@@ -93,14 +93,14 @@ internal class ByteBufferMemory(
 /**
  * Allocates memory based on a [ByteBuffer].
  */
-actual fun Memory.Companion.allocate(length: Int): Memory =
+public actual fun Memory.Companion.allocate(length: Int): Memory =
     ByteBufferMemory(checkNotNull(ByteBuffer.allocate(length)))
 
 /**
  * Wraps a [Memory] around existing [ByteArray]. This operation is unsafe since the array is not copied
  * and could be mutated independently from the resulting [Memory].
  */
-actual fun Memory.Companion.wrap(array: ByteArray): Memory = ByteBufferMemory(checkNotNull(ByteBuffer.wrap(array)))
+public actual fun Memory.Companion.wrap(array: ByteArray): Memory = ByteBufferMemory(checkNotNull(ByteBuffer.wrap(array)))
 
 /**
  * Wraps this [ByteBuffer] to [Memory] object.
@@ -110,14 +110,14 @@ actual fun Memory.Companion.wrap(array: ByteArray): Memory = ByteBufferMemory(ch
  * @param size the size of memory to map.
  * @return the [Memory] object.
  */
-fun ByteBuffer.asMemory(startOffset: Int = 0, size: Int = limit()): Memory =
+public fun ByteBuffer.asMemory(startOffset: Int = 0, size: Int = limit()): Memory =
     ByteBufferMemory(this, startOffset, size)
 
 /**
  * Uses direct memory-mapped buffer from file to read something and close it afterwards.
  */
 @Throws(IOException::class)
-inline fun <R> Path.readAsMemory(position: Long = 0, size: Long = Files.size(this), block: Memory.() -> R): R {
+public inline fun <R> Path.readAsMemory(position: Long = 0, size: Long = Files.size(this), block: Memory.() -> R): R {
     contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
 
     return FileChannel
diff --git a/kmath-prob/build.gradle.kts b/kmath-prob/build.gradle.kts
index 6cdd301c2..4c9663e5f 100644
--- a/kmath-prob/build.gradle.kts
+++ b/kmath-prob/build.gradle.kts
@@ -1,6 +1,4 @@
-plugins {
-    id("scientifik.mpp")
-}
+plugins { id("ru.mipt.npm.mpp") }
 
 kotlin.sourceSets {
     commonMain {
@@ -8,8 +6,9 @@ kotlin.sourceSets {
             api(project(":kmath-coroutines"))
         }
     }
-    jvmMain{
-        dependencies{
+
+    jvmMain {
+        dependencies {
             api("org.apache.commons:commons-rng-sampling:1.3")
             api("org.apache.commons:commons-rng-simple:1.3")
         }
diff --git a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/Distribution.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Distribution.kt
similarity index 61%
rename from kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/Distribution.kt
rename to kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Distribution.kt
index 3b874adaa..d55a52f56 100644
--- a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/Distribution.kt
+++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Distribution.kt
@@ -1,23 +1,23 @@
-package scientifik.kmath.prob
+package kscience.kmath.prob
 
-import scientifik.kmath.chains.Chain
-import scientifik.kmath.chains.collect
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.BufferFactory
+import kscience.kmath.chains.Chain
+import kscience.kmath.chains.collect
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.BufferFactory
 
-interface Sampler<T : Any> {
-    fun sample(generator: RandomGenerator): Chain<T>
+public interface Sampler<T : Any> {
+    public fun sample(generator: RandomGenerator): Chain<T>
 }
 
 /**
  * A distribution of typed objects
  */
-interface Distribution<T : Any> : Sampler<T> {
+public interface Distribution<T : Any> : Sampler<T> {
     /**
      * A probability value for given argument [arg].
      * For continuous distributions returns PDF
      */
-    fun probability(arg: T): Double
+    public fun probability(arg: T): Double
 
     /**
      * Create a chain of samples from this distribution.
@@ -28,20 +28,20 @@ interface Distribution<T : Any> : Sampler<T> {
     /**
      * An empty companion. Distribution factories should be written as its extensions
      */
-    companion object
+    public companion object
 }
 
-interface UnivariateDistribution<T : Comparable<T>> : Distribution<T> {
+public interface UnivariateDistribution<T : Comparable<T>> : Distribution<T> {
     /**
      * Cumulative distribution for ordered parameter (CDF)
      */
-    fun cumulative(arg: T): Double
+    public fun cumulative(arg: T): Double
 }
 
 /**
  * Compute probability integral in an interval
  */
-fun <T : Comparable<T>> UnivariateDistribution<T>.integral(from: T, to: T): Double {
+public fun <T : Comparable<T>> UnivariateDistribution<T>.integral(from: T, to: T): Double {
     require(to > from)
     return cumulative(to) - cumulative(from)
 }
@@ -49,7 +49,7 @@ fun <T : Comparable<T>> UnivariateDistribution<T>.integral(from: T, to: T): Doub
 /**
  * Sample a bunch of values
  */
-fun <T : Any> Sampler<T>.sampleBuffer(
+public fun <T : Any> Sampler<T>.sampleBuffer(
     generator: RandomGenerator,
     size: Int,
     bufferFactory: BufferFactory<T> = Buffer.Companion::boxing
@@ -57,6 +57,7 @@ fun <T : Any> Sampler<T>.sampleBuffer(
     require(size > 1)
     //creating temporary storage once
     val tmp = ArrayList<T>(size)
+
     return sample(generator).collect { chain ->
         //clear list from previous run
         tmp.clear()
@@ -72,5 +73,5 @@ fun <T : Any> Sampler<T>.sampleBuffer(
 /**
  * Generate a bunch of samples from real distributions
  */
-fun Sampler<Double>.sampleBuffer(generator: RandomGenerator, size: Int) =
-    sampleBuffer(generator, size, Buffer.Companion::real)
\ No newline at end of file
+public fun Sampler<Double>.sampleBuffer(generator: RandomGenerator, size: Int): Chain<Buffer<Double>> =
+    sampleBuffer(generator, size, Buffer.Companion::real)
diff --git a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/FactorizedDistribution.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/FactorizedDistribution.kt
new file mode 100644
index 000000000..4d713fc4e
--- /dev/null
+++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/FactorizedDistribution.kt
@@ -0,0 +1,43 @@
+package kscience.kmath.prob
+
+import kscience.kmath.chains.Chain
+import kscience.kmath.chains.SimpleChain
+
+/**
+ * A multivariate distribution which takes a map of parameters
+ */
+public interface NamedDistribution<T> : Distribution<Map<String, T>>
+
+/**
+ * A multivariate distribution that has independent distributions for separate axis
+ */
+public class FactorizedDistribution<T>(public val distributions: Collection<NamedDistribution<T>>) :
+    NamedDistribution<T> {
+    override fun probability(arg: Map<String, T>): Double =
+        distributions.fold(1.0) { acc, distr -> acc * distr.probability(arg) }
+
+    override fun sample(generator: RandomGenerator): Chain<Map<String, T>> {
+        val chains = distributions.map { it.sample(generator) }
+        return SimpleChain { chains.fold(emptyMap()) { acc, chain -> acc + chain.next() } }
+    }
+}
+
+public class NamedDistributionWrapper<T : Any>(public val name: String, public val distribution: Distribution<T>) :
+    NamedDistribution<T> {
+    override fun probability(arg: Map<String, T>): Double = distribution.probability(
+        arg[name] ?: error("Argument with name $name not found in input parameters")
+    )
+
+    override fun sample(generator: RandomGenerator): Chain<Map<String, T>> {
+        val chain = distribution.sample(generator)
+        return SimpleChain { mapOf(name to chain.next()) }
+    }
+}
+
+public class DistributionBuilder<T : Any> {
+    private val distributions = ArrayList<NamedDistribution<T>>()
+
+    public infix fun String.to(distribution: Distribution<T>) {
+        distributions.add(NamedDistributionWrapper(this, distribution))
+    }
+}
diff --git a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomChain.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomChain.kt
new file mode 100644
index 000000000..b4a80f6c5
--- /dev/null
+++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomChain.kt
@@ -0,0 +1,17 @@
+package kscience.kmath.prob
+
+import kscience.kmath.chains.Chain
+
+/**
+ * A possibly stateful chain producing random values.
+ */
+public class RandomChain<out R>(
+    public val generator: RandomGenerator,
+    private val gen: suspend RandomGenerator.() -> R
+) : Chain<R> {
+    override suspend fun next(): R = generator.gen()
+
+    override fun fork(): Chain<R> = RandomChain(generator.fork(), gen)
+}
+
+public fun <R> RandomGenerator.chain(gen: suspend RandomGenerator.() -> R): RandomChain<R> = RandomChain(this, gen)
diff --git a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomGenerator.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomGenerator.kt
new file mode 100644
index 000000000..0d95d6f97
--- /dev/null
+++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/RandomGenerator.kt
@@ -0,0 +1,48 @@
+package kscience.kmath.prob
+
+import kotlin.random.Random
+
+/**
+ * A basic generator
+ */
+public interface RandomGenerator {
+    public fun nextBoolean(): Boolean
+    public fun nextDouble(): Double
+    public fun nextInt(): Int
+    public fun nextInt(until: Int): Int
+    public fun nextLong(): Long
+    public fun nextLong(until: Long): Long
+    public fun fillBytes(array: ByteArray, fromIndex: Int = 0, toIndex: Int = array.size)
+    public fun nextBytes(size: Int): ByteArray = ByteArray(size).also { fillBytes(it) }
+
+    /**
+     * Create a new generator which is independent from current generator (operations on new generator do not affect this one
+     * and vise versa). The statistical properties of new generator should be the same as for this one.
+     * For pseudo-random generator, the fork is keeping the same sequence of numbers for given call order for each run.
+     *
+     * The thread safety of this operation is not guaranteed since it could affect the state of the generator.
+     */
+    public fun fork(): RandomGenerator
+
+    public companion object {
+        public val default: DefaultGenerator by lazy { DefaultGenerator() }
+
+        public fun default(seed: Long): DefaultGenerator = DefaultGenerator(Random(seed))
+    }
+}
+
+public inline class DefaultGenerator(public val random: Random = Random) : RandomGenerator {
+    public override fun nextBoolean(): Boolean = random.nextBoolean()
+    public override fun nextDouble(): Double = random.nextDouble()
+    public override fun nextInt(): Int = random.nextInt()
+    public override fun nextInt(until: Int): Int = random.nextInt(until)
+    public override fun nextLong(): Long = random.nextLong()
+    public override fun nextLong(until: Long): Long = random.nextLong(until)
+
+    public override fun fillBytes(array: ByteArray, fromIndex: Int, toIndex: Int) {
+        random.nextBytes(array, fromIndex, toIndex)
+    }
+
+    public override fun nextBytes(size: Int): ByteArray = random.nextBytes(size)
+    public override fun fork(): RandomGenerator = RandomGenerator.default(random.nextLong())
+}
diff --git a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/SamplerAlgebra.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/SamplerAlgebra.kt
new file mode 100644
index 000000000..e363ba30b
--- /dev/null
+++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/SamplerAlgebra.kt
@@ -0,0 +1,31 @@
+package kscience.kmath.prob
+
+import kscience.kmath.chains.Chain
+import kscience.kmath.chains.ConstantChain
+import kscience.kmath.chains.map
+import kscience.kmath.chains.zip
+import kscience.kmath.operations.Space
+import kscience.kmath.operations.invoke
+
+public class BasicSampler<T : Any>(public val chainBuilder: (RandomGenerator) -> Chain<T>) : Sampler<T> {
+    public override fun sample(generator: RandomGenerator): Chain<T> = chainBuilder(generator)
+}
+
+public class ConstantSampler<T : Any>(public val value: T) : Sampler<T> {
+    public override fun sample(generator: RandomGenerator): Chain<T> = ConstantChain(value)
+}
+
+/**
+ * A space for samplers. Allows to perform simple operations on distributions
+ */
+public class SamplerSpace<T : Any>(public val space: Space<T>) : Space<Sampler<T>> {
+    public override val zero: Sampler<T> = ConstantSampler(space.zero)
+
+    public override fun add(a: Sampler<T>, b: Sampler<T>): Sampler<T> = BasicSampler { generator ->
+        a.sample(generator).zip(b.sample(generator)) { aValue, bValue -> space { aValue + bValue } }
+    }
+
+    public override fun multiply(a: Sampler<T>, k: Number): Sampler<T> = BasicSampler { generator ->
+        a.sample(generator).map { space { it * k.toDouble() } }
+    }
+}
diff --git a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/Statistic.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Statistic.kt
similarity index 52%
rename from kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/Statistic.kt
rename to kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Statistic.kt
index c82d262bf..6720a3d7f 100644
--- a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/Statistic.kt
+++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/Statistic.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.prob
+package kscience.kmath.prob
 
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.Dispatchers
@@ -6,18 +6,18 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.FlowPreview
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.scanReduce
-import scientifik.kmath.coroutines.mapParallel
-import scientifik.kmath.operations.*
-import scientifik.kmath.structures.Buffer
-import scientifik.kmath.structures.asIterable
-import scientifik.kmath.structures.asSequence
+import kotlinx.coroutines.flow.runningReduce
+import kscience.kmath.coroutines.mapParallel
+import kscience.kmath.operations.*
+import kscience.kmath.structures.Buffer
+import kscience.kmath.structures.asIterable
+import kscience.kmath.structures.asSequence
 
 /**
  * A function, that transforms a buffer of random quantities to some resulting value
  */
-interface Statistic<T, R> {
-    suspend operator fun invoke(data: Buffer<T>): R
+public interface Statistic<T, R> {
+    public suspend operator fun invoke(data: Buffer<T>): R
 }
 
 /**
@@ -26,17 +26,17 @@ interface Statistic<T, R> {
  * @param I - intermediate block type
  * @param R - result type
  */
-interface ComposableStatistic<T, I, R> : Statistic<T, R> {
+public interface ComposableStatistic<T, I, R> : Statistic<T, R> {
     //compute statistic on a single block
-    suspend fun computeIntermediate(data: Buffer<T>): I
+    public suspend fun computeIntermediate(data: Buffer<T>): I
 
     //Compose two blocks
-    suspend fun composeIntermediate(first: I, second: I): I
+    public suspend fun composeIntermediate(first: I, second: I): I
 
     //Transform block to result
-    suspend fun toResult(intermediate: I): R
+    public suspend fun toResult(intermediate: I): R
 
-    override suspend fun invoke(data: Buffer<T>): R = toResult(computeIntermediate(data))
+    public override suspend fun invoke(data: Buffer<T>): R = toResult(computeIntermediate(data))
 }
 
 @FlowPreview
@@ -46,7 +46,7 @@ private fun <T, I, R> ComposableStatistic<T, I, R>.flowIntermediate(
     dispatcher: CoroutineDispatcher = Dispatchers.Default
 ): Flow<I> = flow
     .mapParallel(dispatcher) { computeIntermediate(it) }
-    .scanReduce(::composeIntermediate)
+    .runningReduce(::composeIntermediate)
 
 
 /**
@@ -57,7 +57,7 @@ private fun <T, I, R> ComposableStatistic<T, I, R>.flowIntermediate(
  */
 @FlowPreview
 @ExperimentalCoroutinesApi
-fun <T, I, R> ComposableStatistic<T, I, R>.flow(
+public fun <T, I, R> ComposableStatistic<T, I, R>.flow(
     flow: Flow<Buffer<T>>,
     dispatcher: CoroutineDispatcher = Dispatchers.Default
 ): Flow<R> = flowIntermediate(flow, dispatcher).map(::toResult)
@@ -65,32 +65,32 @@ fun <T, I, R> ComposableStatistic<T, I, R>.flow(
 /**
  * Arithmetic mean
  */
-class Mean<T>(val space: Space<T>) : ComposableStatistic<T, Pair<T, Int>, T> {
-    override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> =
+public class Mean<T>(public val space: Space<T>) : ComposableStatistic<T, Pair<T, Int>, T> {
+    public override suspend fun computeIntermediate(data: Buffer<T>): Pair<T, Int> =
         space { sum(data.asIterable()) } to data.size
 
-    override suspend fun composeIntermediate(first: Pair<T, Int>, second: Pair<T, Int>): Pair<T, Int> =
+    public override suspend fun composeIntermediate(first: Pair<T, Int>, second: Pair<T, Int>): Pair<T, Int> =
         space { first.first + second.first } to (first.second + second.second)
 
-    override suspend fun toResult(intermediate: Pair<T, Int>): T =
+    public override suspend fun toResult(intermediate: Pair<T, Int>): T =
         space { intermediate.first / intermediate.second }
 
-    companion object {
+    public companion object {
         //TODO replace with optimized version which respects overflow
-        val real: Mean<Double> = Mean(RealField)
-        val int: Mean<Int> = Mean(IntRing)
-        val long: Mean<Long> = Mean(LongRing)
+        public val real: Mean<Double> = Mean(RealField)
+        public val int: Mean<Int> = Mean(IntRing)
+        public val long: Mean<Long> = Mean(LongRing)
     }
 }
 
 /**
  * Non-composable median
  */
-class Median<T>(private val comparator: Comparator<T>) : Statistic<T, T> {
-    override suspend fun invoke(data: Buffer<T>): T =
+public class Median<T>(private val comparator: Comparator<T>) : Statistic<T, T> {
+    public override suspend fun invoke(data: Buffer<T>): T =
         data.asSequence().sortedWith(comparator).toList()[data.size / 2] //TODO check if this is correct
 
-    companion object {
-        val real: Median<Double> = Median(Comparator { a: Double, b: Double -> a.compareTo(b) })
+    public companion object {
+        public val real: Median<Double> = Median { a: Double, b: Double -> a.compareTo(b) }
     }
 }
diff --git a/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/UniformDistribution.kt b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/UniformDistribution.kt
new file mode 100644
index 000000000..8df2c01e1
--- /dev/null
+++ b/kmath-prob/src/commonMain/kotlin/kscience/kmath/prob/UniformDistribution.kt
@@ -0,0 +1,22 @@
+package kscience.kmath.prob
+
+import kscience.kmath.chains.Chain
+import kscience.kmath.chains.SimpleChain
+
+public class UniformDistribution(public val range: ClosedFloatingPointRange<Double>) : UnivariateDistribution<Double> {
+    private val length: Double = range.endInclusive - range.start
+
+    override fun probability(arg: Double): Double = if (arg in range) 1.0 / length else 0.0
+
+    override fun sample(generator: RandomGenerator): Chain<Double> =
+        SimpleChain { range.start + generator.nextDouble() * length }
+
+    override fun cumulative(arg: Double): Double = when {
+        arg < range.start -> 0.0
+        arg >= range.endInclusive -> 1.0
+        else -> (arg - range.start) / length
+    }
+}
+
+public fun Distribution.Companion.uniform(range: ClosedFloatingPointRange<Double>): UniformDistribution =
+    UniformDistribution(range)
diff --git a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/FactorizedDistribution.kt b/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/FactorizedDistribution.kt
deleted file mode 100644
index ea526c058..000000000
--- a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/FactorizedDistribution.kt
+++ /dev/null
@@ -1,47 +0,0 @@
-package scientifik.kmath.prob
-
-import scientifik.kmath.chains.Chain
-import scientifik.kmath.chains.SimpleChain
-
-/**
- * A multivariate distribution which takes a map of parameters
- */
-interface NamedDistribution<T> : Distribution<Map<String, T>>
-
-/**
- * A multivariate distribution that has independent distributions for separate axis
- */
-class FactorizedDistribution<T>(val distributions: Collection<NamedDistribution<T>>) : NamedDistribution<T> {
-
-    override fun probability(arg: Map<String, T>): Double {
-        return distributions.fold(1.0) { acc, distr -> acc * distr.probability(arg) }
-    }
-
-    override fun sample(generator: RandomGenerator): Chain<Map<String, T>> {
-        val chains = distributions.map { it.sample(generator) }
-        return SimpleChain<Map<String, T>> {
-            chains.fold(emptyMap()) { acc, chain -> acc + chain.next() }
-        }
-    }
-}
-
-class NamedDistributionWrapper<T : Any>(val name: String, val distribution: Distribution<T>) : NamedDistribution<T> {
-    override fun probability(arg: Map<String, T>): Double = distribution.probability(
-        arg[name] ?: error("Argument with name $name not found in input parameters")
-    )
-
-    override fun sample(generator: RandomGenerator): Chain<Map<String, T>> {
-        val chain = distribution.sample(generator)
-        return SimpleChain {
-            mapOf(name to chain.next())
-        }
-    }
-}
-
-class DistributionBuilder<T: Any>{
-    private val distributions = ArrayList<NamedDistribution<T>>()
-
-    infix fun String.to(distribution: Distribution<T>){
-        distributions.add(NamedDistributionWrapper(this,distribution))
-    }
-}
\ No newline at end of file
diff --git a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/RandomChain.kt b/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/RandomChain.kt
deleted file mode 100644
index 49163c701..000000000
--- a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/RandomChain.kt
+++ /dev/null
@@ -1,14 +0,0 @@
-package scientifik.kmath.prob
-
-import scientifik.kmath.chains.Chain
-
-/**
- * A possibly stateful chain producing random values.
- */
-class RandomChain<out R>(val generator: RandomGenerator, private val gen: suspend RandomGenerator.() -> R) : Chain<R> {
-    override suspend fun next(): R = generator.gen()
-
-    override fun fork(): Chain<R> = RandomChain(generator.fork(), gen)
-}
-
-fun <R> RandomGenerator.chain(gen: suspend RandomGenerator.() -> R): RandomChain<R> = RandomChain(this, gen)
diff --git a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/RandomGenerator.kt b/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/RandomGenerator.kt
deleted file mode 100644
index 2a225fe47..000000000
--- a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/RandomGenerator.kt
+++ /dev/null
@@ -1,55 +0,0 @@
-package scientifik.kmath.prob
-
-import kotlin.random.Random
-
-/**
- * A basic generator
- */
-interface RandomGenerator {
-    fun nextBoolean(): Boolean
-
-    fun nextDouble(): Double
-    fun nextInt(): Int
-    fun nextInt(until: Int): Int
-    fun nextLong(): Long
-    fun nextLong(until: Long): Long
-
-    fun fillBytes(array: ByteArray, fromIndex: Int = 0, toIndex: Int = array.size)
-    fun nextBytes(size: Int): ByteArray = ByteArray(size).also { fillBytes(it) }
-
-    /**
-     * Create a new generator which is independent from current generator (operations on new generator do not affect this one
-     * and vise versa). The statistical properties of new generator should be the same as for this one.
-     * For pseudo-random generator, the fork is keeping the same sequence of numbers for given call order for each run.
-     *
-     * The thread safety of this operation is not guaranteed since it could affect the state of the generator.
-     */
-    fun fork(): RandomGenerator
-
-    companion object {
-        val default by lazy { DefaultGenerator() }
-
-        fun default(seed: Long) = DefaultGenerator(Random(seed))
-    }
-}
-
-inline class DefaultGenerator(val random: Random = Random) : RandomGenerator {
-    override fun nextBoolean(): Boolean = random.nextBoolean()
-
-    override fun nextDouble(): Double = random.nextDouble()
-
-    override fun nextInt(): Int = random.nextInt()
-    override fun nextInt(until: Int): Int = random.nextInt(until)
-
-    override fun nextLong(): Long = random.nextLong()
-
-    override fun nextLong(until: Long): Long = random.nextLong(until)
-
-    override fun fillBytes(array: ByteArray, fromIndex: Int, toIndex: Int) {
-        random.nextBytes(array, fromIndex, toIndex)
-    }
-
-    override fun nextBytes(size: Int): ByteArray = random.nextBytes(size)
-
-    override fun fork(): RandomGenerator = RandomGenerator.default(random.nextLong())
-}
\ No newline at end of file
diff --git a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/SamplerAlgebra.kt b/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/SamplerAlgebra.kt
deleted file mode 100644
index 02f98439e..000000000
--- a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/SamplerAlgebra.kt
+++ /dev/null
@@ -1,32 +0,0 @@
-package scientifik.kmath.prob
-
-import scientifik.kmath.chains.Chain
-import scientifik.kmath.chains.ConstantChain
-import scientifik.kmath.chains.map
-import scientifik.kmath.chains.zip
-import scientifik.kmath.operations.Space
-import scientifik.kmath.operations.invoke
-
-class BasicSampler<T : Any>(val chainBuilder: (RandomGenerator) -> Chain<T>) : Sampler<T> {
-    override fun sample(generator: RandomGenerator): Chain<T> = chainBuilder(generator)
-}
-
-class ConstantSampler<T : Any>(val value: T) : Sampler<T> {
-    override fun sample(generator: RandomGenerator): Chain<T> = ConstantChain(value)
-}
-
-/**
- * A space for samplers. Allows to perform simple operations on distributions
- */
-class SamplerSpace<T : Any>(val space: Space<T>) : Space<Sampler<T>> {
-
-    override val zero: Sampler<T> = ConstantSampler(space.zero)
-
-    override fun add(a: Sampler<T>, b: Sampler<T>): Sampler<T> = BasicSampler { generator ->
-        a.sample(generator).zip(b.sample(generator)) { aValue, bValue -> space { aValue + bValue } }
-    }
-
-    override fun multiply(a: Sampler<T>, k: Number): Sampler<T> = BasicSampler { generator ->
-        a.sample(generator).map { space { it * k.toDouble() } }
-    }
-}
diff --git a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/UniformDistribution.kt b/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/UniformDistribution.kt
deleted file mode 100644
index 9d96bff59..000000000
--- a/kmath-prob/src/commonMain/kotlin/scientifik/kmath/prob/UniformDistribution.kt
+++ /dev/null
@@ -1,34 +0,0 @@
-package scientifik.kmath.prob
-
-import scientifik.kmath.chains.Chain
-import scientifik.kmath.chains.SimpleChain
-
-class UniformDistribution(val range: ClosedFloatingPointRange<Double>) : UnivariateDistribution<Double> {
-
-    private val length = range.endInclusive - range.start
-
-    override fun probability(arg: Double): Double {
-        return if (arg in range) {
-            return 1.0 / length
-        } else {
-            0.0
-        }
-    }
-
-    override fun sample(generator: RandomGenerator): Chain<Double> {
-        return SimpleChain {
-            range.start + generator.nextDouble() * length
-        }
-    }
-
-    override fun cumulative(arg: Double): Double {
-        return when {
-            arg < range.start -> 0.0
-            arg >= range.endInclusive -> 1.0
-            else -> (arg - range.start) / length
-        }
-    }
-}
-
-fun Distribution.Companion.uniform(range: ClosedFloatingPointRange<Double>): UniformDistribution =
-    UniformDistribution(range)
\ No newline at end of file
diff --git a/kmath-prob/src/jvmMain/kotlin/kscience/kmath/prob/RandomSourceGenerator.kt b/kmath-prob/src/jvmMain/kotlin/kscience/kmath/prob/RandomSourceGenerator.kt
new file mode 100644
index 000000000..18be6f019
--- /dev/null
+++ b/kmath-prob/src/jvmMain/kotlin/kscience/kmath/prob/RandomSourceGenerator.kt
@@ -0,0 +1,58 @@
+package kscience.kmath.prob
+
+import org.apache.commons.rng.UniformRandomProvider
+import org.apache.commons.rng.simple.RandomSource
+
+public class RandomSourceGenerator(public val source: RandomSource, seed: Long?) : RandomGenerator {
+    internal val random: UniformRandomProvider = seed?.let {
+        RandomSource.create(source, seed)
+    } ?: RandomSource.create(source)
+
+    public override fun nextBoolean(): Boolean = random.nextBoolean()
+    public override fun nextDouble(): Double = random.nextDouble()
+    public override fun nextInt(): Int = random.nextInt()
+    public override fun nextInt(until: Int): Int = random.nextInt(until)
+    public override fun nextLong(): Long = random.nextLong()
+    public override fun nextLong(until: Long): Long = random.nextLong(until)
+
+    public override fun fillBytes(array: ByteArray, fromIndex: Int, toIndex: Int) {
+        require(toIndex > fromIndex)
+        random.nextBytes(array, fromIndex, toIndex - fromIndex)
+    }
+
+    public override fun fork(): RandomGenerator = RandomSourceGenerator(source, nextLong())
+}
+
+public inline class RandomGeneratorProvider(public val generator: RandomGenerator) : UniformRandomProvider {
+    public override fun nextBoolean(): Boolean = generator.nextBoolean()
+    public override fun nextFloat(): Float = generator.nextDouble().toFloat()
+
+    public override fun nextBytes(bytes: ByteArray) {
+        generator.fillBytes(bytes)
+    }
+
+    public override fun nextBytes(bytes: ByteArray, start: Int, len: Int) {
+        generator.fillBytes(bytes, start, start + len)
+    }
+
+    public override fun nextInt(): Int = generator.nextInt()
+    public override fun nextInt(n: Int): Int = generator.nextInt(n)
+    public override fun nextDouble(): Double = generator.nextDouble()
+    public override fun nextLong(): Long = generator.nextLong()
+    public override fun nextLong(n: Long): Long = generator.nextLong(n)
+}
+
+/**
+ * Represent this [RandomGenerator] as commons-rng [UniformRandomProvider] preserving and mirroring its current state.
+ * Getting new value from one of those changes the state of another.
+ */
+public fun RandomGenerator.asUniformRandomProvider(): UniformRandomProvider = if (this is RandomSourceGenerator)
+    random
+else
+    RandomGeneratorProvider(this)
+
+public fun RandomGenerator.Companion.fromSource(source: RandomSource, seed: Long? = null): RandomSourceGenerator =
+    RandomSourceGenerator(source, seed)
+
+public fun RandomGenerator.Companion.mersenneTwister(seed: Long? = null): RandomSourceGenerator =
+    fromSource(RandomSource.MT, seed)
diff --git a/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/distributions.kt b/kmath-prob/src/jvmMain/kotlin/kscience/kmath/prob/distributions.kt
similarity index 55%
rename from kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/distributions.kt
rename to kmath-prob/src/jvmMain/kotlin/kscience/kmath/prob/distributions.kt
index 412454994..ff20572cc 100644
--- a/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/distributions.kt
+++ b/kmath-prob/src/jvmMain/kotlin/kscience/kmath/prob/distributions.kt
@@ -1,47 +1,42 @@
-package scientifik.kmath.prob
+package kscience.kmath.prob
 
+import kscience.kmath.chains.BlockingIntChain
+import kscience.kmath.chains.BlockingRealChain
+import kscience.kmath.chains.Chain
 import org.apache.commons.rng.UniformRandomProvider
 import org.apache.commons.rng.sampling.distribution.*
-import scientifik.kmath.chains.BlockingIntChain
-import scientifik.kmath.chains.BlockingRealChain
-import scientifik.kmath.chains.Chain
-import java.util.*
 import kotlin.math.PI
 import kotlin.math.exp
 import kotlin.math.pow
 import kotlin.math.sqrt
 
-abstract class ContinuousSamplerDistribution : Distribution<Double> {
-
+public abstract class ContinuousSamplerDistribution : Distribution<Double> {
     private inner class ContinuousSamplerChain(val generator: RandomGenerator) : BlockingRealChain() {
         private val sampler = buildCMSampler(generator)
 
         override fun nextDouble(): Double = sampler.sample()
-
         override fun fork(): Chain<Double> = ContinuousSamplerChain(generator.fork())
     }
 
     protected abstract fun buildCMSampler(generator: RandomGenerator): ContinuousSampler
 
-    override fun sample(generator: RandomGenerator): BlockingRealChain = ContinuousSamplerChain(generator)
+    public override fun sample(generator: RandomGenerator): BlockingRealChain = ContinuousSamplerChain(generator)
 }
 
-abstract class DiscreteSamplerDistribution : Distribution<Int> {
-
+public abstract class DiscreteSamplerDistribution : Distribution<Int> {
     private inner class ContinuousSamplerChain(val generator: RandomGenerator) : BlockingIntChain() {
         private val sampler = buildSampler(generator)
 
         override fun nextInt(): Int = sampler.sample()
-
         override fun fork(): Chain<Int> = ContinuousSamplerChain(generator.fork())
     }
 
     protected abstract fun buildSampler(generator: RandomGenerator): DiscreteSampler
 
-    override fun sample(generator: RandomGenerator): BlockingIntChain = ContinuousSamplerChain(generator)
+    public override fun sample(generator: RandomGenerator): BlockingIntChain = ContinuousSamplerChain(generator)
 }
 
-enum class NormalSamplerMethod {
+public enum class NormalSamplerMethod {
     BoxMuller,
     Marsaglia,
     Ziggurat
@@ -54,20 +49,18 @@ private fun normalSampler(method: NormalSamplerMethod, provider: UniformRandomPr
         NormalSamplerMethod.Ziggurat -> ZigguratNormalizedGaussianSampler(provider)
     }
 
-fun Distribution.Companion.normal(
+public fun Distribution.Companion.normal(
     method: NormalSamplerMethod = NormalSamplerMethod.Ziggurat
 ): Distribution<Double> = object : ContinuousSamplerDistribution() {
     override fun buildCMSampler(generator: RandomGenerator): ContinuousSampler {
-        val provider: UniformRandomProvider = generator.asUniformRandomProvider()
+        val provider = generator.asUniformRandomProvider()
         return normalSampler(method, provider)
     }
 
-    override fun probability(arg: Double): Double {
-        return exp(-arg.pow(2) / 2) / sqrt(PI * 2)
-    }
+    override fun probability(arg: Double): Double = exp(-arg.pow(2) / 2) / sqrt(PI * 2)
 }
 
-fun Distribution.Companion.normal(
+public fun Distribution.Companion.normal(
     mean: Double,
     sigma: Double,
     method: NormalSamplerMethod = NormalSamplerMethod.Ziggurat
@@ -76,34 +69,27 @@ fun Distribution.Companion.normal(
     private val norm = sigma * sqrt(PI * 2)
 
     override fun buildCMSampler(generator: RandomGenerator): ContinuousSampler {
-        val provider: UniformRandomProvider = generator.asUniformRandomProvider()
+        val provider = generator.asUniformRandomProvider()
         val normalizedSampler = normalSampler(method, provider)
         return GaussianSampler(normalizedSampler, mean, sigma)
     }
 
-    override fun probability(arg: Double): Double {
-        return exp(-(arg - mean).pow(2) / 2 / sigma2) / norm
-    }
+    override fun probability(arg: Double): Double = exp(-(arg - mean).pow(2) / 2 / sigma2) / norm
 }
 
-fun Distribution.Companion.poisson(
-    lambda: Double
-): DiscreteSamplerDistribution = object : DiscreteSamplerDistribution() {
+public fun Distribution.Companion.poisson(lambda: Double): DiscreteSamplerDistribution =
+    object : DiscreteSamplerDistribution() {
+        private val computedProb: MutableMap<Int, Double> = hashMapOf(0 to exp(-lambda))
 
-    override fun buildSampler(generator: RandomGenerator): DiscreteSampler {
-        return PoissonSampler.of(generator.asUniformRandomProvider(), lambda)
-    }
+        override fun buildSampler(generator: RandomGenerator): DiscreteSampler =
+            PoissonSampler.of(generator.asUniformRandomProvider(), lambda)
 
-    private val computedProb: HashMap<Int, Double> = hashMapOf(0 to exp(-lambda))
+        override fun probability(arg: Int): Double {
+            require(arg >= 0) { "The argument must be >= 0" }
 
-    override fun probability(arg: Int): Double {
-        require(arg >= 0) { "The argument must be >= 0" }
-        return if (arg > 40) {
-            exp(-(arg - lambda).pow(2) / 2 / lambda) / sqrt(2 * PI * lambda)
-        } else {
-            computedProb.getOrPut(arg) {
-                probability(arg - 1) * lambda / arg
-            }
+            return if (arg > 40)
+                exp(-(arg - lambda).pow(2) / 2 / lambda) / sqrt(2 * PI * lambda)
+            else
+                computedProb.getOrPut(arg) { probability(arg - 1) * lambda / arg }
         }
     }
-}
diff --git a/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/RandomSourceGenerator.kt b/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/RandomSourceGenerator.kt
deleted file mode 100644
index f5a73a08b..000000000
--- a/kmath-prob/src/jvmMain/kotlin/scientifik/kmath/prob/RandomSourceGenerator.kt
+++ /dev/null
@@ -1,67 +0,0 @@
-package scientifik.kmath.prob
-
-import org.apache.commons.rng.UniformRandomProvider
-import org.apache.commons.rng.simple.RandomSource
-
-class RandomSourceGenerator(val source: RandomSource, seed: Long?) : RandomGenerator {
-    internal val random: UniformRandomProvider = seed?.let {
-        RandomSource.create(source, seed)
-    } ?: RandomSource.create(source)
-
-    override fun nextBoolean(): Boolean = random.nextBoolean()
-
-    override fun nextDouble(): Double = random.nextDouble()
-
-    override fun nextInt(): Int = random.nextInt()
-    override fun nextInt(until: Int): Int = random.nextInt(until)
-
-    override fun nextLong(): Long = random.nextLong()
-    override fun nextLong(until: Long): Long = random.nextLong(until)
-
-    override fun fillBytes(array: ByteArray, fromIndex: Int, toIndex: Int) {
-        require(toIndex > fromIndex)
-        random.nextBytes(array, fromIndex, toIndex - fromIndex)
-    }
-
-    override fun fork(): RandomGenerator = RandomSourceGenerator(source, nextLong())
-}
-
-inline class RandomGeneratorProvider(val generator: RandomGenerator) : UniformRandomProvider {
-    override fun nextBoolean(): Boolean = generator.nextBoolean()
-
-    override fun nextFloat(): Float = generator.nextDouble().toFloat()
-
-    override fun nextBytes(bytes: ByteArray) {
-        generator.fillBytes(bytes)
-    }
-
-    override fun nextBytes(bytes: ByteArray, start: Int, len: Int) {
-        generator.fillBytes(bytes, start, start + len)
-    }
-
-    override fun nextInt(): Int = generator.nextInt()
-
-    override fun nextInt(n: Int): Int = generator.nextInt(n)
-
-    override fun nextDouble(): Double = generator.nextDouble()
-
-    override fun nextLong(): Long = generator.nextLong()
-
-    override fun nextLong(n: Long): Long = generator.nextLong(n)
-}
-
-/**
- * Represent this [RandomGenerator] as commons-rng [UniformRandomProvider] preserving and mirroring its current state.
- * Getting new value from one of those changes the state of another.
- */
-fun RandomGenerator.asUniformRandomProvider(): UniformRandomProvider = if (this is RandomSourceGenerator) {
-    random
-} else {
-    RandomGeneratorProvider(this)
-}
-
-fun RandomGenerator.Companion.fromSource(source: RandomSource, seed: Long? = null): RandomSourceGenerator =
-    RandomSourceGenerator(source, seed)
-
-fun RandomGenerator.Companion.mersenneTwister(seed: Long? = null): RandomSourceGenerator =
-    fromSource(RandomSource.MT, seed)
diff --git a/kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/CommonsDistributionsTest.kt b/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/CommonsDistributionsTest.kt
similarity index 91%
rename from kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/CommonsDistributionsTest.kt
rename to kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/CommonsDistributionsTest.kt
index 7638c695e..12a00684b 100644
--- a/kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/CommonsDistributionsTest.kt
+++ b/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/CommonsDistributionsTest.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.prob
+package kscience.kmath.prob
 
 import kotlinx.coroutines.flow.take
 import kotlinx.coroutines.flow.toList
@@ -6,7 +6,7 @@ import kotlinx.coroutines.runBlocking
 import org.junit.jupiter.api.Assertions
 import org.junit.jupiter.api.Test
 
-class CommonsDistributionsTest {
+internal class CommonsDistributionsTest {
     @Test
     fun testNormalDistributionSuspend() {
         val distribution = Distribution.normal(7.0, 2.0)
@@ -24,5 +24,4 @@ class CommonsDistributionsTest {
         val sample = distribution.sample(generator).nextBlock(1000)
         Assertions.assertEquals(7.0, sample.average(), 0.1)
     }
-
-}
\ No newline at end of file
+}
diff --git a/kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/SamplerTest.kt b/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/SamplerTest.kt
similarity index 92%
rename from kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/SamplerTest.kt
rename to kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/SamplerTest.kt
index 1152f3057..3d8a4f531 100644
--- a/kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/SamplerTest.kt
+++ b/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/SamplerTest.kt
@@ -1,4 +1,4 @@
-package scientifik.kmath.prob
+package kscience.kmath.prob
 
 import kotlinx.coroutines.runBlocking
 import kotlin.test.Test
diff --git a/kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/StatisticTest.kt b/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/StatisticTest.kt
similarity index 81%
rename from kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/StatisticTest.kt
rename to kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/StatisticTest.kt
index 2613f71d5..22ca472a8 100644
--- a/kmath-prob/src/jvmTest/kotlin/scientifik/kmath/prob/StatisticTest.kt
+++ b/kmath-prob/src/jvmTest/kotlin/kscience/kmath/prob/StatisticTest.kt
@@ -1,18 +1,20 @@
-package scientifik.kmath.prob
+package kscience.kmath.prob
 
 import kotlinx.coroutines.flow.drop
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.runBlocking
 
-import scientifik.kmath.streaming.chunked
+import kscience.kmath.streaming.chunked
 import kotlin.test.Test
 
-class StatisticTest {
+internal class StatisticTest {
     //create a random number generator.
     val generator = RandomGenerator.default(1)
+
     //Create a stateless chain from generator.
     val data = generator.chain { nextDouble() }
-    //Convert a chaint to Flow and break it into chunks.
+
+    //Convert a chain to Flow and break it into chunks.
     val chunked = data.chunked(1000)
 
     @Test
@@ -22,7 +24,8 @@ class StatisticTest {
                 .flow(chunked) //create a flow with results
                 .drop(99) // Skip first 99 values and use one with total data
                 .first() //get 1e5 data samples average
+
             println(average)
         }
     }
-}
\ No newline at end of file
+}
diff --git a/kmath-viktor/build.gradle.kts b/kmath-viktor/build.gradle.kts
index 5ad0620e9..6fe8ad878 100644
--- a/kmath-viktor/build.gradle.kts
+++ b/kmath-viktor/build.gradle.kts
@@ -1,6 +1,4 @@
-plugins {
-    id("scientifik.jvm")
-}
+plugins { id("ru.mipt.npm.jvm") }
 
 description = "Binding for https://github.com/JetBrains-Research/viktor"
 
diff --git a/kmath-viktor/src/main/kotlin/kscience/kmath/viktor/ViktorBuffer.kt b/kmath-viktor/src/main/kotlin/kscience/kmath/viktor/ViktorBuffer.kt
new file mode 100644
index 000000000..5c9611758
--- /dev/null
+++ b/kmath-viktor/src/main/kotlin/kscience/kmath/viktor/ViktorBuffer.kt
@@ -0,0 +1,19 @@
+package kscience.kmath.viktor
+
+import kscience.kmath.structures.MutableBuffer
+import org.jetbrains.bio.viktor.F64FlatArray
+
+@Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE")
+public inline class ViktorBuffer(public val flatArray: F64FlatArray) : MutableBuffer<Double> {
+    public override val size: Int
+        get() = flatArray.size
+
+    public override inline fun get(index: Int): Double = flatArray[index]
+
+    public override inline fun set(index: Int, value: Double) {
+        flatArray[index] = value
+    }
+
+    public override fun copy(): MutableBuffer<Double> = ViktorBuffer(flatArray.copy().flatten())
+    public override operator fun iterator(): Iterator<Double> = flatArray.data.iterator()
+}
diff --git a/kmath-viktor/src/main/kotlin/kscience/kmath/viktor/ViktorNDStructure.kt b/kmath-viktor/src/main/kotlin/kscience/kmath/viktor/ViktorNDStructure.kt
new file mode 100644
index 000000000..2471362cb
--- /dev/null
+++ b/kmath-viktor/src/main/kotlin/kscience/kmath/viktor/ViktorNDStructure.kt
@@ -0,0 +1,88 @@
+package kscience.kmath.viktor
+
+import kscience.kmath.operations.RealField
+import kscience.kmath.structures.DefaultStrides
+import kscience.kmath.structures.MutableNDStructure
+import kscience.kmath.structures.NDField
+import kscience.kmath.structures.Strides
+import org.jetbrains.bio.viktor.F64Array
+
+@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public inline class ViktorNDStructure(public val f64Buffer: F64Array) : MutableNDStructure<Double> {
+    public override val shape: IntArray get() = f64Buffer.shape
+
+    public override inline fun get(index: IntArray): Double = f64Buffer.get(*index)
+
+    public override inline fun set(index: IntArray, value: Double) {
+        f64Buffer.set(*index, value = value)
+    }
+
+    public override fun elements(): Sequence<Pair<IntArray, Double>> =
+        DefaultStrides(shape).indices().map { it to get(it) }
+}
+
+public fun F64Array.asStructure(): ViktorNDStructure = ViktorNDStructure(this)
+
+@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public class ViktorNDField(public override val shape: IntArray) : NDField<Double, RealField, ViktorNDStructure> {
+    public override val zero: ViktorNDStructure
+        get() = F64Array.full(init = 0.0, shape = shape).asStructure()
+
+    public override val one: ViktorNDStructure
+        get() = F64Array.full(init = 1.0, shape = shape).asStructure()
+
+    public val strides: Strides = DefaultStrides(shape)
+
+    public override val elementContext: RealField get() = RealField
+
+    public override fun produce(initializer: RealField.(IntArray) -> Double): ViktorNDStructure =
+        F64Array(*shape).apply {
+            this@ViktorNDField.strides.indices().forEach { index ->
+                set(value = RealField.initializer(index), indices = index)
+            }
+        }.asStructure()
+
+    public override fun map(arg: ViktorNDStructure, transform: RealField.(Double) -> Double): ViktorNDStructure =
+        F64Array(*shape).apply {
+            this@ViktorNDField.strides.indices().forEach { index ->
+                set(value = RealField.transform(arg[index]), indices = index)
+            }
+        }.asStructure()
+
+    public override fun mapIndexed(
+        arg: ViktorNDStructure,
+        transform: RealField.(index: IntArray, Double) -> Double
+    ): ViktorNDStructure = F64Array(*shape).apply {
+        this@ViktorNDField.strides.indices().forEach { index ->
+            set(value = RealField.transform(index, arg[index]), indices = index)
+        }
+    }.asStructure()
+
+    public override fun combine(
+        a: ViktorNDStructure,
+        b: ViktorNDStructure,
+        transform: RealField.(Double, Double) -> Double
+    ): ViktorNDStructure = F64Array(*shape).apply {
+        this@ViktorNDField.strides.indices().forEach { index ->
+            set(value = RealField.transform(a[index], b[index]), indices = index)
+        }
+    }.asStructure()
+
+    public override fun add(a: ViktorNDStructure, b: ViktorNDStructure): ViktorNDStructure =
+        (a.f64Buffer + b.f64Buffer).asStructure()
+
+    public override fun multiply(a: ViktorNDStructure, k: Number): ViktorNDStructure =
+        (a.f64Buffer * k.toDouble()).asStructure()
+
+    public override inline fun ViktorNDStructure.plus(b: ViktorNDStructure): ViktorNDStructure =
+        (f64Buffer + b.f64Buffer).asStructure()
+
+    public override inline fun ViktorNDStructure.minus(b: ViktorNDStructure): ViktorNDStructure =
+        (f64Buffer - b.f64Buffer).asStructure()
+
+    public override inline fun ViktorNDStructure.times(k: Number): ViktorNDStructure =
+        (f64Buffer * k.toDouble()).asStructure()
+
+    public override inline fun ViktorNDStructure.plus(arg: Double): ViktorNDStructure =
+        (f64Buffer.plus(arg)).asStructure()
+}
\ No newline at end of file
diff --git a/kmath-viktor/src/main/kotlin/scientifik/kmath/viktor/ViktorBuffer.kt b/kmath-viktor/src/main/kotlin/scientifik/kmath/viktor/ViktorBuffer.kt
deleted file mode 100644
index 551b877a7..000000000
--- a/kmath-viktor/src/main/kotlin/scientifik/kmath/viktor/ViktorBuffer.kt
+++ /dev/null
@@ -1,20 +0,0 @@
-package scientifik.kmath.viktor
-
-import org.jetbrains.bio.viktor.F64FlatArray
-import scientifik.kmath.structures.MutableBuffer
-
-@Suppress("NOTHING_TO_INLINE", "OVERRIDE_BY_INLINE")
-inline class ViktorBuffer(val flatArray: F64FlatArray) : MutableBuffer<Double> {
-    override val size: Int get() = flatArray.size
-
-    override inline fun get(index: Int): Double = flatArray[index]
-    override inline fun set(index: Int, value: Double) {
-        flatArray[index] = value
-    }
-
-    override fun copy(): MutableBuffer<Double> {
-        return ViktorBuffer(flatArray.copy().flatten())
-    }
-
-    override operator fun iterator(): Iterator<Double> = flatArray.data.iterator()
-}
diff --git a/kmath-viktor/src/main/kotlin/scientifik/kmath/viktor/ViktorNDStructure.kt b/kmath-viktor/src/main/kotlin/scientifik/kmath/viktor/ViktorNDStructure.kt
deleted file mode 100644
index 84e927721..000000000
--- a/kmath-viktor/src/main/kotlin/scientifik/kmath/viktor/ViktorNDStructure.kt
+++ /dev/null
@@ -1,86 +0,0 @@
-package scientifik.kmath.viktor
-
-import org.jetbrains.bio.viktor.F64Array
-import scientifik.kmath.operations.RealField
-import scientifik.kmath.structures.DefaultStrides
-import scientifik.kmath.structures.MutableNDStructure
-import scientifik.kmath.structures.NDField
-
-@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-inline class ViktorNDStructure(val f64Buffer: F64Array) : MutableNDStructure<Double> {
-
-    override val shape: IntArray get() = f64Buffer.shape
-
-    override inline fun get(index: IntArray): Double = f64Buffer.get(*index)
-
-    override inline fun set(index: IntArray, value: Double) {
-        f64Buffer.set(*index, value = value)
-    }
-
-    override fun elements(): Sequence<Pair<IntArray, Double>> {
-        return DefaultStrides(shape).indices().map { it to get(it) }
-    }
-}
-
-fun F64Array.asStructure(): ViktorNDStructure = ViktorNDStructure(this)
-
-@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-class ViktorNDField(override val shape: IntArray) : NDField<Double, RealField, ViktorNDStructure> {
-    override val zero: ViktorNDStructure
-        get() = F64Array.full(init = 0.0, shape = *shape).asStructure()
-    override val one: ViktorNDStructure
-        get() = F64Array.full(init = 1.0, shape = *shape).asStructure()
-
-    val strides = DefaultStrides(shape)
-
-    override val elementContext: RealField get() = RealField
-
-    override fun produce(initializer: RealField.(IntArray) -> Double): ViktorNDStructure = F64Array(*shape).apply {
-        this@ViktorNDField.strides.indices().forEach { index ->
-            set(value = RealField.initializer(index), indices = *index)
-        }
-    }.asStructure()
-
-    override fun map(arg: ViktorNDStructure, transform: RealField.(Double) -> Double): ViktorNDStructure =
-        F64Array(*shape).apply {
-            this@ViktorNDField.strides.indices().forEach { index ->
-                set(value = RealField.transform(arg[index]), indices = *index)
-            }
-        }.asStructure()
-
-    override fun mapIndexed(
-        arg: ViktorNDStructure,
-        transform: RealField.(index: IntArray, Double) -> Double
-    ): ViktorNDStructure = F64Array(*shape).apply {
-        this@ViktorNDField.strides.indices().forEach { index ->
-            set(value = RealField.transform(index, arg[index]), indices = *index)
-        }
-    }.asStructure()
-
-    override fun combine(
-        a: ViktorNDStructure,
-        b: ViktorNDStructure,
-        transform: RealField.(Double, Double) -> Double
-    ): ViktorNDStructure = F64Array(*shape).apply {
-        this@ViktorNDField.strides.indices().forEach { index ->
-            set(value = RealField.transform(a[index], b[index]), indices = *index)
-        }
-    }.asStructure()
-
-    override fun add(a: ViktorNDStructure, b: ViktorNDStructure): ViktorNDStructure {
-        return (a.f64Buffer + b.f64Buffer).asStructure()
-    }
-
-    override fun multiply(a: ViktorNDStructure, k: Number): ViktorNDStructure =
-        (a.f64Buffer * k.toDouble()).asStructure()
-
-    override inline fun ViktorNDStructure.plus(b: ViktorNDStructure): ViktorNDStructure =
-        (f64Buffer + b.f64Buffer).asStructure()
-
-    override inline fun ViktorNDStructure.minus(b: ViktorNDStructure): ViktorNDStructure =
-        (f64Buffer - b.f64Buffer).asStructure()
-
-    override inline fun ViktorNDStructure.times(k: Number): ViktorNDStructure = (f64Buffer * k.toDouble()).asStructure()
-
-    override inline fun ViktorNDStructure.plus(arg: Double): ViktorNDStructure = (f64Buffer.plus(arg)).asStructure()
-}
\ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 9e69a4291..64d18d271 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -1,14 +1,13 @@
 pluginManagement {
-
-    val toolsVersion = "0.5.2"
+    val toolsVersion = "0.6.0"
 
     plugins {
-        id("kotlinx.benchmark") version "0.2.0-dev-8"
-        id("scientifik.mpp") version toolsVersion
-        id("scientifik.jvm") version toolsVersion
-        id("scientifik.atomic") version toolsVersion
-        id("scientifik.publish") version toolsVersion
-        kotlin("plugin.allopen") version "1.3.72"
+        id("kotlinx.benchmark") version "0.2.0-dev-20"
+        id("ru.mipt.npm.base") version toolsVersion
+        id("ru.mipt.npm.mpp") version toolsVersion
+        id("ru.mipt.npm.jvm") version toolsVersion
+        id("ru.mipt.npm.publish") version toolsVersion
+        kotlin("plugin.allopen")
     }
 
     repositories {
@@ -16,9 +15,10 @@ pluginManagement {
         jcenter()
         gradlePluginPortal()
         maven("https://dl.bintray.com/kotlin/kotlin-eap")
-        maven("https://dl.bintray.com/mipt-npm/scientifik")
+        maven("https://dl.bintray.com/mipt-npm/kscience")
         maven("https://dl.bintray.com/mipt-npm/dev")
         maven("https://dl.bintray.com/kotlin/kotlinx")
+        maven("https://dl.bintray.com/kotlin/kotlin-dev/")
     }
 }