diff --git a/.idea/copyright/kmath.xml b/.idea/copyright/kmath.xml
deleted file mode 100644
index 1070e5d33..000000000
--- a/.idea/copyright/kmath.xml
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
-
-
-
diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml
deleted file mode 100644
index b538bdf41..000000000
--- a/.idea/copyright/profiles_settings.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/scopes/Apply_copyright.xml b/.idea/scopes/Apply_copyright.xml
deleted file mode 100644
index 0eb589133..000000000
--- a/.idea/scopes/Apply_copyright.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt
index 3f9b43f03..b4e8b7487 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/nd/AlgebraND.kt
@@ -203,7 +203,9 @@ public interface RingND> : Ring>, RingOpsND> : FieldOps>, RingOpsND,
+public interface FieldOpsND> :
+ FieldOps>,
+ RingOpsND,
ScaleOperations> {
/**
* Element-wise division.
diff --git a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt
index ca88ad42d..5f6848211 100644
--- a/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt
+++ b/kmath-core/src/commonMain/kotlin/space/kscience/kmath/operations/NumericAlgebra.kt
@@ -150,7 +150,7 @@ public interface ScaleOperations : Algebra {
* TODO to be removed and replaced by extensions after multiple receivers are there
*/
@UnstableKMathAPI
-public interface NumbersAddOps : Ring, NumericAlgebra {
+public interface NumbersAddOps : RingOps, NumericAlgebra {
/**
* Addition of element and scalar.
*
diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt
new file mode 100644
index 000000000..c72553a64
--- /dev/null
+++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorFieldOpsND.kt
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2018-2021 KMath contributors.
+ * Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
+ */
+
+package space.kscience.kmath.viktor
+
+import org.jetbrains.bio.viktor.F64Array
+import space.kscience.kmath.misc.UnstableKMathAPI
+import space.kscience.kmath.nd.*
+import space.kscience.kmath.operations.DoubleField
+import space.kscience.kmath.operations.ExtendedFieldOps
+import space.kscience.kmath.operations.NumbersAddOps
+
+@OptIn(UnstableKMathAPI::class)
+@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
+public open class ViktorFieldOpsND :
+ FieldOpsND,
+ ExtendedFieldOps> {
+
+ public val StructureND.f64Buffer: F64Array
+ get() = when (this) {
+ is ViktorStructureND -> this.f64Buffer
+ else -> produce(shape) { this@f64Buffer[it] }.f64Buffer
+ }
+
+ override val elementAlgebra: DoubleField get() = DoubleField
+
+ override fun produce(shape: IntArray, initializer: DoubleField.(IntArray) -> Double): ViktorStructureND =
+ F64Array(*shape).apply {
+ DefaultStrides(shape).indices().forEach { index ->
+ set(value = DoubleField.initializer(index), indices = index)
+ }
+ }.asStructure()
+
+ override fun StructureND.unaryMinus(): StructureND = -1 * this
+
+ override fun StructureND.map(transform: DoubleField.(Double) -> Double): ViktorStructureND =
+ F64Array(*shape).apply {
+ DefaultStrides(shape).indices().forEach { index ->
+ set(value = DoubleField.transform(this@map[index]), indices = index)
+ }
+ }.asStructure()
+
+ override fun StructureND.mapIndexed(
+ transform: DoubleField.(index: IntArray, Double) -> Double,
+ ): ViktorStructureND = F64Array(*shape).apply {
+ DefaultStrides(shape).indices().forEach { index ->
+ set(value = DoubleField.transform(index, this@mapIndexed[index]), indices = index)
+ }
+ }.asStructure()
+
+ override fun zip(
+ left: StructureND,
+ right: StructureND,
+ transform: DoubleField.(Double, Double) -> Double,
+ ): ViktorStructureND {
+ require(left.shape.contentEquals(right.shape))
+ return F64Array(*left.shape).apply {
+ DefaultStrides(left.shape).indices().forEach { index ->
+ set(value = DoubleField.transform(left[index], right[index]), indices = index)
+ }
+ }.asStructure()
+ }
+
+ override fun add(left: StructureND, right: StructureND): ViktorStructureND =
+ (left.f64Buffer + right.f64Buffer).asStructure()
+
+ override fun scale(a: StructureND, value: Double): ViktorStructureND =
+ (a.f64Buffer * value).asStructure()
+
+ override fun StructureND.plus(other: StructureND): ViktorStructureND =
+ (f64Buffer + other.f64Buffer).asStructure()
+
+ override fun StructureND.minus(other: StructureND): ViktorStructureND =
+ (f64Buffer - other.f64Buffer).asStructure()
+
+ override fun StructureND.times(k: Number): ViktorStructureND =
+ (f64Buffer * k.toDouble()).asStructure()
+
+ override fun StructureND.plus(arg: Double): ViktorStructureND =
+ (f64Buffer.plus(arg)).asStructure()
+
+ override fun sin(arg: StructureND): ViktorStructureND = arg.map { sin(it) }
+ override fun cos(arg: StructureND): ViktorStructureND = arg.map { cos(it) }
+ override fun tan(arg: StructureND): ViktorStructureND = arg.map { tan(it) }
+ override fun asin(arg: StructureND): ViktorStructureND = arg.map { asin(it) }
+ override fun acos(arg: StructureND): ViktorStructureND = arg.map { acos(it) }
+ override fun atan(arg: StructureND): ViktorStructureND = arg.map { atan(it) }
+
+ override fun power(arg: StructureND, pow: Number): ViktorStructureND = arg.map { it.pow(pow) }
+
+ override fun exp(arg: StructureND): ViktorStructureND = arg.f64Buffer.exp().asStructure()
+
+ override fun ln(arg: StructureND): ViktorStructureND = arg.f64Buffer.log().asStructure()
+
+ override fun sinh(arg: StructureND): ViktorStructureND = arg.map { sinh(it) }
+
+ override fun cosh(arg: StructureND): ViktorStructureND = arg.map { cosh(it) }
+
+ override fun asinh(arg: StructureND): ViktorStructureND = arg.map { asinh(it) }
+
+ override fun acosh(arg: StructureND): ViktorStructureND = arg.map { acosh(it) }
+
+ override fun atanh(arg: StructureND): ViktorStructureND = arg.map { atanh(it) }
+
+ public companion object : ViktorFieldOpsND()
+}
+
+public val DoubleField.viktorAlgebra: ViktorFieldOpsND get() = ViktorFieldOpsND
+
+public open class ViktorFieldND(
+ override val shape: Shape
+) : ViktorFieldOpsND(), FieldND, NumbersAddOps> {
+ override val zero: ViktorStructureND by lazy { F64Array.full(init = 0.0, shape = shape).asStructure() }
+ override val one: ViktorStructureND by lazy { F64Array.full(init = 1.0, shape = shape).asStructure() }
+
+ override fun number(value: Number): ViktorStructureND =
+ F64Array.full(init = value.toDouble(), shape = shape).asStructure()
+}
+
+public fun DoubleField.viktorAlgebra(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)
+
+public fun ViktorFieldND(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)
\ No newline at end of file
diff --git a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt
index a914542bc..0d29983f9 100644
--- a/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt
+++ b/kmath-viktor/src/main/kotlin/space/kscience/kmath/viktor/ViktorStructureND.kt
@@ -7,12 +7,8 @@ package space.kscience.kmath.viktor
import org.jetbrains.bio.viktor.F64Array
import space.kscience.kmath.misc.PerformancePitfall
-import space.kscience.kmath.misc.UnstableKMathAPI
-import space.kscience.kmath.nd.*
-import space.kscience.kmath.operations.DoubleField
-import space.kscience.kmath.operations.ExtendedField
-import space.kscience.kmath.operations.NumbersAddOps
-import space.kscience.kmath.operations.ScaleOperations
+import space.kscience.kmath.nd.DefaultStrides
+import space.kscience.kmath.nd.MutableStructureND
@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructureND {
@@ -31,96 +27,4 @@ public class ViktorStructureND(public val f64Buffer: F64Array) : MutableStructur
public fun F64Array.asStructure(): ViktorStructureND = ViktorStructureND(this)
-@OptIn(UnstableKMathAPI::class)
-@Suppress("OVERRIDE_BY_INLINE", "NOTHING_TO_INLINE")
-public class ViktorFieldND(override val shape: IntArray) : FieldND,
- NumbersAddOps>, ExtendedField>,
- ScaleOperations> {
- public val StructureND.f64Buffer: F64Array
- get() = when {
- !shape.contentEquals(this@ViktorFieldND.shape) -> throw ShapeMismatchException(
- this@ViktorFieldND.shape,
- shape
- )
- this is ViktorStructureND && this.f64Buffer.shape.contentEquals(this@ViktorFieldND.shape) -> this.f64Buffer
- else -> produce(shape) { this@f64Buffer[it] }.f64Buffer
- }
-
- override val zero: ViktorStructureND by lazy { F64Array.full(init = 0.0, shape = shape).asStructure() }
- override val one: ViktorStructureND by lazy { F64Array.full(init = 1.0, shape = shape).asStructure() }
-
- private val strides: Strides = DefaultStrides(shape)
-
- override val elementAlgebra: DoubleField get() = DoubleField
-
- override fun produce(shape: IntArray, initializer: DoubleField.(IntArray) -> Double): ViktorStructureND =
- F64Array(*shape).apply {
- this@ViktorFieldND.strides.indices().forEach { index ->
- set(value = DoubleField.initializer(index), indices = index)
- }
- }.asStructure()
-
- override fun StructureND.unaryMinus(): StructureND = -1 * this
-
- override fun StructureND.map(transform: DoubleField.(Double) -> Double): ViktorStructureND =
- F64Array(*this@ViktorFieldND.shape).apply {
- this@ViktorFieldND.strides.indices().forEach { index ->
- set(value = DoubleField.transform(this@map[index]), indices = index)
- }
- }.asStructure()
-
- override fun StructureND.mapIndexed(
- transform: DoubleField.(index: IntArray, Double) -> Double,
- ): ViktorStructureND = F64Array(*this@ViktorFieldND.shape).apply {
- this@ViktorFieldND.strides.indices().forEach { index ->
- set(value = DoubleField.transform(index, this@mapIndexed[index]), indices = index)
- }
- }.asStructure()
-
- override fun zip(
- left: StructureND,
- right: StructureND,
- transform: DoubleField.(Double, Double) -> Double,
- ): ViktorStructureND = F64Array(*shape).apply {
- this@ViktorFieldND.strides.indices().forEach { index ->
- set(value = DoubleField.transform(left[index], right[index]), indices = index)
- }
- }.asStructure()
-
- override fun add(left: StructureND, right: StructureND): ViktorStructureND =
- (left.f64Buffer + right.f64Buffer).asStructure()
-
- override fun scale(a: StructureND, value: Double): ViktorStructureND =
- (a.f64Buffer * value).asStructure()
-
- override inline fun StructureND.plus(other: StructureND): ViktorStructureND =
- (f64Buffer + other.f64Buffer).asStructure()
-
- override inline fun StructureND.minus(other: StructureND): ViktorStructureND =
- (f64Buffer - other.f64Buffer).asStructure()
-
- override inline fun StructureND.times(k: Number): ViktorStructureND =
- (f64Buffer * k.toDouble()).asStructure()
-
- override inline fun StructureND.plus(arg: Double): ViktorStructureND =
- (f64Buffer.plus(arg)).asStructure()
-
- override fun number(value: Number): ViktorStructureND =
- F64Array.full(init = value.toDouble(), shape = shape).asStructure()
-
- override fun sin(arg: StructureND): ViktorStructureND = arg.map { sin(it) }
- override fun cos(arg: StructureND): ViktorStructureND = arg.map { cos(it) }
- override fun tan(arg: StructureND): ViktorStructureND = arg.map { tan(it) }
- override fun asin(arg: StructureND): ViktorStructureND = arg.map { asin(it) }
- override fun acos(arg: StructureND): ViktorStructureND = arg.map { acos(it) }
- override fun atan(arg: StructureND): ViktorStructureND = arg.map { atan(it) }
-
- override fun power(arg: StructureND, pow: Number): ViktorStructureND = arg.map { it.pow(pow) }
-
- override fun exp(arg: StructureND): ViktorStructureND = arg.f64Buffer.exp().asStructure()
-
- override fun ln(arg: StructureND): ViktorStructureND = arg.f64Buffer.log().asStructure()
-}
-
-public fun ViktorFieldND(vararg shape: Int): ViktorFieldND = ViktorFieldND(shape)