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 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
|
||||
val specializedField = NDField.real(dim, dim)
|
||||
//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 {
|
||||
|
@ -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.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 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
|
||||
*/
|
||||
fun <T : Any, F : Field<T>> buffered(
|
||||
fun <T : Any, F : Field<T>> boxing(
|
||||
field: F,
|
||||
vararg shape: Int,
|
||||
bufferFactory: BufferFactory<T> = Buffer.Companion::boxing
|
||||
|
@ -41,7 +41,7 @@ interface NDElement<T, C, N : NDStructure<T>> : NDStructure<T> {
|
||||
/**
|
||||
* Simple boxing NDArray
|
||||
*/
|
||||
fun <T : Any, F : Field<T>> buffered(
|
||||
fun <T : Any, F : Field<T>> boxing(
|
||||
shape: IntArray,
|
||||
field: F,
|
||||
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