NDArray renamed to NDElement
This commit is contained in:
parent
75bedde1fa
commit
5cd6301f45
@ -1,12 +1,14 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
val kotlin_version = "1.3.10"
|
extra["kotlinVersion"] = "1.3.10"
|
||||||
|
|
||||||
|
val kotlinVersion: String by extra
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
|
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
|
||||||
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4+")
|
classpath("org.jfrog.buildinfo:build-info-extractor-gradle:4+")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,10 @@ class PhantomBin(val template: BinTemplate, override val value: Number) : Bin<Do
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable histogram with explicit structure for content and additional external bin description.
|
||||||
|
* Bin search is slow, but full histogram algebra is supported.
|
||||||
|
*/
|
||||||
class PhantomHistogram(
|
class PhantomHistogram(
|
||||||
val bins: Map<BinTemplate, IntArray>,
|
val bins: Map<BinTemplate, IntArray>,
|
||||||
val data: NDStructure<Double>
|
val data: NDStructure<Double>
|
||||||
|
@ -225,7 +225,7 @@ class ArrayVectorSpace<T : Any>(
|
|||||||
/**
|
/**
|
||||||
* Member of [ArrayMatrixSpace] which wraps 2-D array
|
* Member of [ArrayMatrixSpace] which wraps 2-D array
|
||||||
*/
|
*/
|
||||||
class ArrayMatrix<T : Any> internal constructor(override val context: ArrayMatrixSpace<T>, val array: NDArray<T>) : Matrix<T> {
|
class ArrayMatrix<T : Any> internal constructor(override val context: ArrayMatrixSpace<T>, val element: NDElement<T>) : Matrix<T> {
|
||||||
|
|
||||||
constructor(context: ArrayMatrixSpace<T>, initializer: (Int, Int) -> T) : this(context, context.ndField.produce { list -> initializer(list[0], list[1]) })
|
constructor(context: ArrayMatrixSpace<T>, initializer: (Int, Int) -> T) : this(context, context.ndField.produce { list -> initializer(list[0], list[1]) })
|
||||||
|
|
||||||
@ -234,32 +234,32 @@ class ArrayMatrix<T : Any> internal constructor(override val context: ArrayMatri
|
|||||||
override val columns: Int get() = context.columns
|
override val columns: Int get() = context.columns
|
||||||
|
|
||||||
override fun get(i: Int, j: Int): T {
|
override fun get(i: Int, j: Int): T {
|
||||||
return array[i, j]
|
return element[i, j]
|
||||||
}
|
}
|
||||||
|
|
||||||
override val self: ArrayMatrix<T> get() = this
|
override val self: ArrayMatrix<T> get() = this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class ArrayVector<T : Any> internal constructor(override val context: ArrayVectorSpace<T>, val array: NDArray<T>) : Vector<T> {
|
class ArrayVector<T : Any> internal constructor(override val context: ArrayVectorSpace<T>, val element: NDElement<T>) : Vector<T> {
|
||||||
|
|
||||||
constructor(context: ArrayVectorSpace<T>, initializer: (Int) -> T) : this(context, context.ndField.produce { list -> initializer(list[0]) })
|
constructor(context: ArrayVectorSpace<T>, initializer: (Int) -> T) : this(context, context.ndField.produce { list -> initializer(list[0]) })
|
||||||
|
|
||||||
init {
|
init {
|
||||||
if (context.size != array.shape[0]) {
|
if (context.size != element.shape[0]) {
|
||||||
error("Array dimension mismatch")
|
error("Array dimension mismatch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun get(index: Int): T {
|
override fun get(index: Int): T {
|
||||||
return array[index]
|
return element[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
override val self: ArrayVector<T> get() = this
|
override val self: ArrayVector<T> get() = this
|
||||||
|
|
||||||
override fun iterator(): Iterator<T> = (0 until size).map { array[it] }.iterator()
|
override fun iterator(): Iterator<T> = (0 until size).map { element[it] }.iterator()
|
||||||
|
|
||||||
override fun copy(): ArrayVector<T> = ArrayVector(context, array)
|
override fun copy(): ArrayVector<T> = ArrayVector(context, element)
|
||||||
|
|
||||||
override fun toString(): String = this.joinToString(prefix = "[", postfix = "]", separator = ", ") { it.toString() }
|
override fun toString(): String = this.joinToString(prefix = "[", postfix = "]", separator = ", ") { it.toString() }
|
||||||
}
|
}
|
||||||
|
@ -1,37 +1,40 @@
|
|||||||
package scientifik.kmath.structures
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
import scientifik.kmath.operations.*
|
import scientifik.kmath.operations.ExponentialOperations
|
||||||
|
import scientifik.kmath.operations.ExtendedField
|
||||||
|
import scientifik.kmath.operations.PowerOperations
|
||||||
|
import scientifik.kmath.operations.TrigonometricOperations
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NDField that supports [ExtendedField] operations on its elements
|
* NDField that supports [ExtendedField] operations on its elements
|
||||||
*/
|
*/
|
||||||
class ExtendedNDField<N: Any>(shape: IntArray, override val field: ExtendedField<N>) : NDField<N>(shape, field),
|
class ExtendedNDField<N: Any>(shape: IntArray, override val field: ExtendedField<N>) : NDField<N>(shape, field),
|
||||||
TrigonometricOperations<NDArray<N>>,
|
TrigonometricOperations<NDElement<N>>,
|
||||||
PowerOperations<NDArray<N>>,
|
PowerOperations<NDElement<N>>,
|
||||||
ExponentialOperations<NDArray<N>> {
|
ExponentialOperations<NDElement<N>> {
|
||||||
|
|
||||||
override fun produceStructure(initializer: (IntArray) -> N): NDStructure<N> {
|
override fun produceStructure(initializer: (IntArray) -> N): NDStructure<N> {
|
||||||
return genericNdStructure(shape, initializer)
|
return genericNdStructure(shape, initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun power(arg: NDArray<N>, pow: Double): NDArray<N> {
|
override fun power(arg: NDElement<N>, pow: Double): NDElement<N> {
|
||||||
return arg.transform { d -> with(field){power(d,pow)} }
|
return arg.transform { d -> with(field){power(d,pow)} }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun exp(arg: NDArray<N>): NDArray<N> {
|
override fun exp(arg: NDElement<N>): NDElement<N> {
|
||||||
return arg.transform { d -> with(field){exp(d)} }
|
return arg.transform { d -> with(field){exp(d)} }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun ln(arg: NDArray<N>): NDArray<N> {
|
override fun ln(arg: NDElement<N>): NDElement<N> {
|
||||||
return arg.transform { d -> with(field){ln(d)} }
|
return arg.transform { d -> with(field){ln(d)} }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sin(arg: NDArray<N>): NDArray<N> {
|
override fun sin(arg: NDElement<N>): NDElement<N> {
|
||||||
return arg.transform { d -> with(field){sin(d)} }
|
return arg.transform { d -> with(field){sin(d)} }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cos(arg: NDArray<N>): NDArray<N> {
|
override fun cos(arg: NDElement<N>): NDElement<N> {
|
||||||
return arg.transform { d -> with(field){cos(d)} }
|
return arg.transform { d -> with(field){cos(d)} }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ class ShapeMismatchException(val expected: IntArray, val actual: IntArray) : Run
|
|||||||
* @param field - operations field defined on individual array element
|
* @param field - operations field defined on individual array element
|
||||||
* @param T the type of the element contained in NDArray
|
* @param T the type of the element contained in NDArray
|
||||||
*/
|
*/
|
||||||
abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field<NDArray<T>> {
|
abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field<NDElement<T>> {
|
||||||
|
|
||||||
abstract fun produceStructure(initializer: (IntArray) -> T): NDStructure<T>
|
abstract fun produceStructure(initializer: (IntArray) -> T): NDStructure<T>
|
||||||
|
|
||||||
@ -23,17 +23,17 @@ abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field
|
|||||||
* Create new instance of NDArray using field shape and given initializer
|
* Create new instance of NDArray using field shape and given initializer
|
||||||
* The producer takes list of indices as argument and returns contained value
|
* The producer takes list of indices as argument and returns contained value
|
||||||
*/
|
*/
|
||||||
fun produce(initializer: (IntArray) -> T): NDArray<T> = NDArray(this, produceStructure(initializer))
|
fun produce(initializer: (IntArray) -> T): NDElement<T> = NDElement(this, produceStructure(initializer))
|
||||||
|
|
||||||
override val zero: NDArray<T> by lazy {
|
override val zero: NDElement<T> by lazy {
|
||||||
produce { this.field.zero }
|
produce { this.field.zero }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check the shape of given NDArray and throw exception if it does not coincide with shape of the field
|
* Check the shape of given NDArray and throw exception if it does not coincide with shape of the field
|
||||||
*/
|
*/
|
||||||
private fun checkShape(vararg arrays: NDArray<T>) {
|
private fun checkShape(vararg elements: NDElement<T>) {
|
||||||
arrays.forEach {
|
elements.forEach {
|
||||||
if (!shape.contentEquals(it.shape)) {
|
if (!shape.contentEquals(it.shape)) {
|
||||||
throw ShapeMismatchException(shape, it.shape)
|
throw ShapeMismatchException(shape, it.shape)
|
||||||
}
|
}
|
||||||
@ -43,7 +43,7 @@ abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field
|
|||||||
/**
|
/**
|
||||||
* Element-by-element addition
|
* Element-by-element addition
|
||||||
*/
|
*/
|
||||||
override fun add(a: NDArray<T>, b: NDArray<T>): NDArray<T> {
|
override fun add(a: NDElement<T>, b: NDElement<T>): NDElement<T> {
|
||||||
checkShape(a, b)
|
checkShape(a, b)
|
||||||
return produce { with(field) { a[it] + b[it] } }
|
return produce { with(field) { a[it] + b[it] } }
|
||||||
}
|
}
|
||||||
@ -51,18 +51,18 @@ abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field
|
|||||||
/**
|
/**
|
||||||
* Multiply all elements by cinstant
|
* Multiply all elements by cinstant
|
||||||
*/
|
*/
|
||||||
override fun multiply(a: NDArray<T>, k: Double): NDArray<T> {
|
override fun multiply(a: NDElement<T>, k: Double): NDElement<T> {
|
||||||
checkShape(a)
|
checkShape(a)
|
||||||
return produce { with(field) { a[it] * k } }
|
return produce { with(field) { a[it] * k } }
|
||||||
}
|
}
|
||||||
|
|
||||||
override val one: NDArray<T>
|
override val one: NDElement<T>
|
||||||
get() = produce { this.field.one }
|
get() = produce { this.field.one }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Element-by-element multiplication
|
* Element-by-element multiplication
|
||||||
*/
|
*/
|
||||||
override fun multiply(a: NDArray<T>, b: NDArray<T>): NDArray<T> {
|
override fun multiply(a: NDElement<T>, b: NDElement<T>): NDElement<T> {
|
||||||
checkShape(a)
|
checkShape(a)
|
||||||
return produce { with(field) { a[it] * b[it] } }
|
return produce { with(field) { a[it] * b[it] } }
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field
|
|||||||
/**
|
/**
|
||||||
* Element-by-element division
|
* Element-by-element division
|
||||||
*/
|
*/
|
||||||
override fun divide(a: NDArray<T>, b: NDArray<T>): NDArray<T> {
|
override fun divide(a: NDElement<T>, b: NDElement<T>): NDElement<T> {
|
||||||
checkShape(a)
|
checkShape(a)
|
||||||
return produce { with(field) { a[it] / b[it] } }
|
return produce { with(field) { a[it] / b[it] } }
|
||||||
}
|
}
|
||||||
@ -78,12 +78,12 @@ abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field
|
|||||||
/**
|
/**
|
||||||
* Reverse sum operation
|
* Reverse sum operation
|
||||||
*/
|
*/
|
||||||
operator fun <T> T.plus(arg: NDArray<T>): NDArray<T> = arg + this
|
operator fun <T> T.plus(arg: NDElement<T>): NDElement<T> = arg + this
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse minus operation
|
* Reverse minus operation
|
||||||
*/
|
*/
|
||||||
operator fun <T> T.minus(arg: NDArray<T>): NDArray<T> = arg.transform { _, value ->
|
operator fun <T> T.minus(arg: NDElement<T>): NDElement<T> = arg.transform { _, value ->
|
||||||
with(arg.context.field) {
|
with(arg.context.field) {
|
||||||
this@minus - value
|
this@minus - value
|
||||||
}
|
}
|
||||||
@ -92,12 +92,12 @@ abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field
|
|||||||
/**
|
/**
|
||||||
* Reverse product operation
|
* Reverse product operation
|
||||||
*/
|
*/
|
||||||
operator fun <T> T.times(arg: NDArray<T>): NDArray<T> = arg * this
|
operator fun <T> T.times(arg: NDElement<T>): NDElement<T> = arg * this
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reverse division operation
|
* Reverse division operation
|
||||||
*/
|
*/
|
||||||
operator fun <T> T.div(arg: NDArray<T>): NDArray<T> = arg.transform { _, value ->
|
operator fun <T> T.div(arg: NDElement<T>): NDElement<T> = arg.transform { _, value ->
|
||||||
with(arg.context.field) {
|
with(arg.context.field) {
|
||||||
this@div / value
|
this@div / value
|
||||||
}
|
}
|
||||||
@ -107,37 +107,37 @@ abstract class NDField<T>(val shape: IntArray, open val field: Field<T>) : Field
|
|||||||
/**
|
/**
|
||||||
* Immutable [NDStructure] coupled to the context. Emulates Python ndarray
|
* Immutable [NDStructure] coupled to the context. Emulates Python ndarray
|
||||||
*/
|
*/
|
||||||
class NDArray<T>(override val context: NDField<T>, private val structure: NDStructure<T>) : FieldElement<NDArray<T>, NDField<T>>, NDStructure<T> by structure {
|
class NDElement<T>(override val context: NDField<T>, private val structure: NDStructure<T>) : FieldElement<NDElement<T>, NDField<T>>, NDStructure<T> by structure {
|
||||||
|
|
||||||
//TODO ensure structure is immutable
|
//TODO ensure structure is immutable
|
||||||
|
|
||||||
override val self: NDArray<T>
|
override val self: NDElement<T>
|
||||||
get() = this
|
get() = this
|
||||||
|
|
||||||
inline fun transform(crossinline action: (IntArray, T) -> T): NDArray<T> = context.produce { action(it, get(*it)) }
|
inline fun transform(crossinline action: (IntArray, T) -> T): NDElement<T> = context.produce { action(it, get(*it)) }
|
||||||
inline fun transform(crossinline action: (T) -> T): NDArray<T> = context.produce { action(get(*it)) }
|
inline fun transform(crossinline action: (T) -> T): NDElement<T> = context.produce { action(get(*it)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Element by element application of any operation on elements to the whole array. Just like in numpy
|
* Element by element application of any operation on elements to the whole array. Just like in numpy
|
||||||
*/
|
*/
|
||||||
operator fun <T> Function1<T, T>.invoke(ndArray: NDArray<T>): NDArray<T> = ndArray.transform { _, value -> this(value) }
|
operator fun <T> Function1<T, T>.invoke(ndElement: NDElement<T>): NDElement<T> = ndElement.transform { _, value -> this(value) }
|
||||||
|
|
||||||
/* plus and minus */
|
/* plus and minus */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Summation operation for [NDArray] and single element
|
* Summation operation for [NDElement] and single element
|
||||||
*/
|
*/
|
||||||
operator fun <T> NDArray<T>.plus(arg: T): NDArray<T> = transform { _, value ->
|
operator fun <T> NDElement<T>.plus(arg: T): NDElement<T> = transform { _, value ->
|
||||||
with(context.field) {
|
with(context.field) {
|
||||||
arg + value
|
arg + value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtraction operation between [NDArray] and single element
|
* Subtraction operation between [NDElement] and single element
|
||||||
*/
|
*/
|
||||||
operator fun <T> NDArray<T>.minus(arg: T): NDArray<T> = transform { _, value ->
|
operator fun <T> NDElement<T>.minus(arg: T): NDElement<T> = transform { _, value ->
|
||||||
with(context.field) {
|
with(context.field) {
|
||||||
arg - value
|
arg - value
|
||||||
}
|
}
|
||||||
@ -146,18 +146,18 @@ operator fun <T> NDArray<T>.minus(arg: T): NDArray<T> = transform { _, value ->
|
|||||||
/* prod and div */
|
/* prod and div */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Product operation for [NDArray] and single element
|
* Product operation for [NDElement] and single element
|
||||||
*/
|
*/
|
||||||
operator fun <T> NDArray<T>.times(arg: T): NDArray<T> = transform { _, value ->
|
operator fun <T> NDElement<T>.times(arg: T): NDElement<T> = transform { _, value ->
|
||||||
with(context.field) {
|
with(context.field) {
|
||||||
arg * value
|
arg * value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Division operation between [NDArray] and single element
|
* Division operation between [NDElement] and single element
|
||||||
*/
|
*/
|
||||||
operator fun <T> NDArray<T>.div(arg: T): NDArray<T> = transform { _, value ->
|
operator fun <T> NDElement<T>.div(arg: T): NDElement<T> = transform { _, value ->
|
||||||
with(context.field) {
|
with(context.field) {
|
||||||
arg / value
|
arg / value
|
||||||
}
|
}
|
||||||
@ -173,23 +173,23 @@ object NDArrays {
|
|||||||
/**
|
/**
|
||||||
* Create a platform-optimized NDArray of doubles
|
* Create a platform-optimized NDArray of doubles
|
||||||
*/
|
*/
|
||||||
fun realNDArray(shape: IntArray, initializer: (IntArray) -> Double = { 0.0 }): NDArray<Double> {
|
fun realNDArray(shape: IntArray, initializer: (IntArray) -> Double = { 0.0 }): NDElement<Double> {
|
||||||
return ExtendedNDField(shape, DoubleField).produce(initializer)
|
return ExtendedNDField(shape, DoubleField).produce(initializer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun real1DArray(dim: Int, initializer: (Int) -> Double = { _ -> 0.0 }): NDArray<Double> {
|
fun real1DArray(dim: Int, initializer: (Int) -> Double = { _ -> 0.0 }): NDElement<Double> {
|
||||||
return realNDArray(intArrayOf(dim)) { initializer(it[0]) }
|
return realNDArray(intArrayOf(dim)) { initializer(it[0]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun real2DArray(dim1: Int, dim2: Int, initializer: (Int, Int) -> Double = { _, _ -> 0.0 }): NDArray<Double> {
|
fun real2DArray(dim1: Int, dim2: Int, initializer: (Int, Int) -> Double = { _, _ -> 0.0 }): NDElement<Double> {
|
||||||
return realNDArray(intArrayOf(dim1, dim2)) { initializer(it[0], it[1]) }
|
return realNDArray(intArrayOf(dim1, dim2)) { initializer(it[0], it[1]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun real3DArray(dim1: Int, dim2: Int, dim3: Int, initializer: (Int, Int, Int) -> Double = { _, _, _ -> 0.0 }): NDArray<Double> {
|
fun real3DArray(dim1: Int, dim2: Int, dim3: Int, initializer: (Int, Int, Int) -> Double = { _, _, _ -> 0.0 }): NDElement<Double> {
|
||||||
return realNDArray(intArrayOf(dim1, dim2, dim3)) { initializer(it[0], it[1], it[2]) }
|
return realNDArray(intArrayOf(dim1, dim2, dim3)) { initializer(it[0], it[1], it[2]) }
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun produceReal(shape: IntArray, block: ExtendedNDField<Double>.() -> NDArray<Double>) = ExtendedNDField(shape, DoubleField).run(block)
|
inline fun produceReal(shape: IntArray, block: ExtendedNDField<Double>.() -> NDElement<Double>) = ExtendedNDField(shape, DoubleField).run(block)
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Simple boxing NDField
|
// * Simple boxing NDField
|
||||||
@ -199,7 +199,7 @@ object NDArrays {
|
|||||||
/**
|
/**
|
||||||
* Simple boxing NDArray
|
* Simple boxing NDArray
|
||||||
*/
|
*/
|
||||||
fun <T : Any> create(field: Field<T>, shape: IntArray, initializer: (IntArray) -> T): NDArray<T> {
|
fun <T : Any> create(field: Field<T>, shape: IntArray, initializer: (IntArray) -> T): NDElement<T> {
|
||||||
return GenericNDField(shape, field).produce { initializer(it) }
|
return GenericNDField(shape, field).produce { initializer(it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package scientifik.kmath.structures
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
import scientifik.kmath.linear.Vector
|
|
||||||
import scientifik.kmath.linear.VectorL2Norm
|
|
||||||
import scientifik.kmath.operations.Norm
|
import scientifik.kmath.operations.Norm
|
||||||
import scientifik.kmath.structures.NDArrays.produceReal
|
import scientifik.kmath.structures.NDArrays.produceReal
|
||||||
import scientifik.kmath.structures.NDArrays.real2DArray
|
import scientifik.kmath.structures.NDArrays.real2DArray
|
||||||
@ -53,8 +51,8 @@ class NumberNDFieldTest {
|
|||||||
assertEquals(2.0, result[0,2])
|
assertEquals(2.0, result[0,2])
|
||||||
}
|
}
|
||||||
|
|
||||||
object L2Norm: Norm<NDArray<out Number>, Double> {
|
object L2Norm: Norm<NDElement<out Number>, Double> {
|
||||||
override fun norm(arg: NDArray<out Number>): Double {
|
override fun norm(arg: NDElement<out Number>): Double {
|
||||||
return kotlin.math.sqrt(arg.sumByDouble { it.second.toDouble() })
|
return kotlin.math.sqrt(arg.sumByDouble { it.second.toDouble() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user