forked from kscience/kmath
Basic support for BigInteger (#69)
This commit is contained in:
parent
7183d6ea8a
commit
651f8323f3
@ -53,6 +53,6 @@ class NDFieldBenchmark {
|
|||||||
|
|
||||||
val bufferedField = NDField.auto(RealField, dim, dim)
|
val bufferedField = NDField.auto(RealField, dim, dim)
|
||||||
val specializedField = NDField.real(dim, dim)
|
val specializedField = NDField.real(dim, dim)
|
||||||
val genericField = NDField.buffered(RealField, dim, dim)
|
val genericField = NDField.boxing(RealField, dim, dim)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -13,7 +13,7 @@ fun main(args: Array<String>) {
|
|||||||
// specialized nd-field for Double. It works as generic Double field as well
|
// specialized nd-field for Double. It works as generic Double field as well
|
||||||
val specializedField = NDField.real(dim, dim)
|
val specializedField = NDField.real(dim, dim)
|
||||||
//A generic boxing field. It should be used for objects, not primitives.
|
//A generic boxing field. It should be used for objects, not primitives.
|
||||||
val genericField = NDField.buffered(RealField, dim, dim)
|
val genericField = NDField.boxing(RealField, dim, dim)
|
||||||
|
|
||||||
|
|
||||||
val autoTime = measureTimeMillis {
|
val autoTime = measureTimeMillis {
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
package scientifik.kmath.structures
|
||||||
|
|
||||||
|
import scientifik.kmath.operations.Ring
|
||||||
|
import scientifik.kmath.operations.RingElement
|
||||||
|
|
||||||
|
class BoxingNDRing<T, R : Ring<T>>(
|
||||||
|
override val shape: IntArray,
|
||||||
|
override val elementContext: R,
|
||||||
|
val bufferFactory: BufferFactory<T>
|
||||||
|
) : BufferedNDRing<T, R> {
|
||||||
|
|
||||||
|
override val strides: Strides = DefaultStrides(shape)
|
||||||
|
|
||||||
|
fun buildBuffer(size: Int, initializer: (Int) -> T): Buffer<T> =
|
||||||
|
bufferFactory(size, initializer)
|
||||||
|
|
||||||
|
override fun check(vararg elements: NDBuffer<T>) {
|
||||||
|
if (!elements.all { it.strides == this.strides }) error("Element strides are not the same as context strides")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val zero by lazy { produce { zero } }
|
||||||
|
override val one by lazy { produce { one } }
|
||||||
|
|
||||||
|
override fun produce(initializer: R.(IntArray) -> T) =
|
||||||
|
BufferedNDRingElement(
|
||||||
|
this,
|
||||||
|
buildBuffer(strides.linearSize) { offset -> elementContext.initializer(strides.index(offset)) })
|
||||||
|
|
||||||
|
override fun map(arg: NDBuffer<T>, transform: R.(T) -> T): BufferedNDRingElement<T, R> {
|
||||||
|
check(arg)
|
||||||
|
return BufferedNDRingElement(
|
||||||
|
this,
|
||||||
|
buildBuffer(arg.strides.linearSize) { offset -> elementContext.transform(arg.buffer[offset]) })
|
||||||
|
|
||||||
|
// val buffer = arg.buffer.transform { _, value -> elementContext.transform(value) }
|
||||||
|
// return BufferedNDFieldElement(this, buffer)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun mapIndexed(
|
||||||
|
arg: NDBuffer<T>,
|
||||||
|
transform: R.(index: IntArray, T) -> T
|
||||||
|
): BufferedNDRingElement<T, R> {
|
||||||
|
check(arg)
|
||||||
|
return BufferedNDRingElement(
|
||||||
|
this,
|
||||||
|
buildBuffer(arg.strides.linearSize) { offset ->
|
||||||
|
elementContext.transform(
|
||||||
|
arg.strides.index(offset),
|
||||||
|
arg.buffer[offset]
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
// val buffer =
|
||||||
|
// arg.buffer.transform { offset, value -> elementContext.transform(arg.strides.index(offset), value) }
|
||||||
|
// return BufferedNDFieldElement(this, buffer)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun combine(
|
||||||
|
a: NDBuffer<T>,
|
||||||
|
b: NDBuffer<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]) })
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun NDBuffer<T>.toElement(): RingElement<NDBuffer<T>, *, out BufferedNDRing<T, R>> =
|
||||||
|
BufferedNDRingElement(this@BoxingNDRing, buffer)
|
||||||
|
}
|
@ -82,6 +82,8 @@ interface NDSpace<T, S : Space<T>, N : NDStructure<T>> : Space<N>, NDAlgebra<T,
|
|||||||
|
|
||||||
operator fun T.plus(arg: N) = map(arg) { value -> add(this@plus, value) }
|
operator fun T.plus(arg: N) = map(arg) { value -> add(this@plus, value) }
|
||||||
operator fun T.minus(arg: N) = map(arg) { value -> add(-this@minus, value) }
|
operator fun T.minus(arg: N) = map(arg) { value -> add(-this@minus, value) }
|
||||||
|
|
||||||
|
companion object
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,6 +100,8 @@ interface NDRing<T, R : Ring<T>, N : NDStructure<T>> : Ring<N>, NDSpace<T, R, N>
|
|||||||
operator fun N.times(arg: T) = map(this) { value -> multiply(arg, value) }
|
operator fun N.times(arg: T) = map(this) { value -> multiply(arg, value) }
|
||||||
|
|
||||||
operator fun T.times(arg: N) = map(arg) { value -> multiply(this@times, value) }
|
operator fun T.times(arg: N) = map(arg) { value -> multiply(this@times, value) }
|
||||||
|
|
||||||
|
companion object
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,7 +136,7 @@ interface NDField<T, F : Field<T>, N : NDStructure<T>> : Field<N>, NDRing<T, F,
|
|||||||
/**
|
/**
|
||||||
* Create a nd-field with boxing generic buffer
|
* Create a nd-field with boxing generic buffer
|
||||||
*/
|
*/
|
||||||
fun <T : Any, F : Field<T>> buffered(
|
fun <T : Any, F : Field<T>> boxing(
|
||||||
field: F,
|
field: F,
|
||||||
vararg shape: Int,
|
vararg shape: Int,
|
||||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing
|
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing
|
||||||
|
@ -41,7 +41,7 @@ interface NDElement<T, C, N : NDStructure<T>> : NDStructure<T> {
|
|||||||
/**
|
/**
|
||||||
* Simple boxing NDArray
|
* Simple boxing NDArray
|
||||||
*/
|
*/
|
||||||
fun <T : Any, F : Field<T>> buffered(
|
fun <T : Any, F : Field<T>> boxing(
|
||||||
shape: IntArray,
|
shape: IntArray,
|
||||||
field: F,
|
field: F,
|
||||||
initializer: F.(IntArray) -> T
|
initializer: F.(IntArray) -> T
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
package scientifik.kmath.operations
|
||||||
|
|
||||||
|
import scientifik.kmath.structures.*
|
||||||
|
import java.math.BigDecimal
|
||||||
|
import java.math.BigInteger
|
||||||
|
import java.math.MathContext
|
||||||
|
|
||||||
|
object BigIntegerRing : Ring<BigInteger> {
|
||||||
|
override val zero: BigInteger = BigInteger.ZERO
|
||||||
|
override val one: BigInteger = BigInteger.ONE
|
||||||
|
|
||||||
|
override fun add(a: BigInteger, b: BigInteger): BigInteger = a.add(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
class BigDecimalField(val mathContext: MathContext = MathContext.DECIMAL64) : Field<BigDecimal> {
|
||||||
|
override val zero: BigDecimal = BigDecimal.ZERO
|
||||||
|
override val one: BigDecimal = BigDecimal.ONE
|
||||||
|
|
||||||
|
override fun add(a: BigDecimal, b: BigDecimal): BigDecimal = a.add(b)
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
inline fun Buffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInteger): Buffer<BigInteger> =
|
||||||
|
boxing(size, initializer)
|
||||||
|
|
||||||
|
inline fun MutableBuffer.Companion.bigInt(size: Int, initializer: (Int) -> BigInteger): MutableBuffer<BigInteger> =
|
||||||
|
boxing(size, initializer)
|
||||||
|
|
||||||
|
fun NDAlgebra.Companion.bigInt(vararg shape: Int): BoxingNDRing<BigInteger, BigIntegerRing> =
|
||||||
|
BoxingNDRing(shape, BigIntegerRing, Buffer.Companion::bigInt)
|
||||||
|
|
||||||
|
fun NDElement.Companion.bigInt(
|
||||||
|
vararg shape: Int,
|
||||||
|
initializer: BigIntegerRing.(IntArray) -> BigInteger
|
||||||
|
): BufferedNDRingElement<BigInteger, BigIntegerRing> =
|
||||||
|
NDAlgebra.bigInt(*shape).produce(initializer)
|
Loading…
Reference in New Issue
Block a user