Dev #194

Merged
altavir merged 266 commits from dev into master 2021-01-20 17:32:32 +03:00
11 changed files with 97 additions and 12 deletions
Showing only changes of commit 9740f4cd11 - Show all commits

View File

@ -6,6 +6,8 @@ import scientifik.kmath.operations.RealField
/** /**
* A Mathematical Syntax Tree node for mathematical expressions. * A Mathematical Syntax Tree node for mathematical expressions.
*
* @author Alexander Nozik
*/ */
sealed class MST { sealed class MST {
/** /**
@ -52,6 +54,7 @@ sealed class MST {
* @receiver the algebra that provides operations. * @receiver the algebra that provides operations.
* @param node the node to evaluate. * @param node the node to evaluate.
* @return the value of expression. * @return the value of expression.
* @author Alexander Nozik
*/ */
fun <T> Algebra<T>.evaluate(node: MST): T = when (node) { fun <T> Algebra<T>.evaluate(node: MST): T = when (node) {
is MST.Numeric -> (this as? NumericAlgebra<T>)?.number(node.value) is MST.Numeric -> (this as? NumericAlgebra<T>)?.number(node.value)

View File

@ -4,6 +4,8 @@ import scientifik.kmath.operations.*
/** /**
* [Algebra] over [MST] nodes. * [Algebra] over [MST] nodes.
*
* @author Alexander Nozik
*/ */
object MstAlgebra : NumericAlgebra<MST> { object MstAlgebra : NumericAlgebra<MST> {
override fun number(value: Number): MST = MST.Numeric(value) override fun number(value: Number): MST = MST.Numeric(value)
@ -19,6 +21,8 @@ object MstAlgebra : NumericAlgebra<MST> {
/** /**
* [Space] over [MST] nodes. * [Space] over [MST] nodes.
*
* @author Alexander Nozik
*/ */
object MstSpace : Space<MST>, NumericAlgebra<MST> { object MstSpace : Space<MST>, NumericAlgebra<MST> {
override val zero: MST = number(0.0) override val zero: MST = number(0.0)
@ -36,6 +40,8 @@ object MstSpace : Space<MST>, NumericAlgebra<MST> {
/** /**
* [Ring] over [MST] nodes. * [Ring] over [MST] nodes.
*
* @author Alexander Nozik
*/ */
object MstRing : Ring<MST>, NumericAlgebra<MST> { object MstRing : Ring<MST>, NumericAlgebra<MST> {
override val zero: MST = number(0.0) override val zero: MST = number(0.0)
@ -57,6 +63,8 @@ object MstRing : Ring<MST>, NumericAlgebra<MST> {
/** /**
* [Field] over [MST] nodes. * [Field] over [MST] nodes.
*
* @author Alexander Nozik
*/ */
object MstField : Field<MST> { object MstField : Field<MST> {
override val zero: MST = number(0.0) override val zero: MST = number(0.0)
@ -77,6 +85,8 @@ object MstField : Field<MST> {
/** /**
* [ExtendedField] over [MST] nodes. * [ExtendedField] over [MST] nodes.
*
* @author Iaroslav Postovalov
*/ */
object MstExtendedField : ExtendedField<MST> { object MstExtendedField : ExtendedField<MST> {
override val zero: MST = number(0.0) override val zero: MST = number(0.0)

View File

@ -11,6 +11,7 @@ import kotlin.contracts.contract
* *
* @property algebra the algebra that provides operations. * @property algebra the algebra that provides operations.
* @property mst the [MST] node. * @property mst the [MST] node.
* @author Alexander Nozik
*/ */
class MstExpression<T>(val algebra: Algebra<T>, val mst: MST) : Expression<T> { class MstExpression<T>(val algebra: Algebra<T>, val mst: MST) : Expression<T> {
private inner class InnerAlgebra(val arguments: Map<String, T>) : NumericAlgebra<T> { private inner class InnerAlgebra(val arguments: Map<String, T>) : NumericAlgebra<T> {
@ -31,6 +32,8 @@ class MstExpression<T>(val algebra: Algebra<T>, val mst: MST) : Expression<T> {
/** /**
* Builds [MstExpression] over [Algebra]. * Builds [MstExpression] over [Algebra].
*
* @author Alexander Nozik
*/ */
inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst( inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst(
mstAlgebra: E, mstAlgebra: E,
@ -39,6 +42,8 @@ inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst(
/** /**
* Builds [MstExpression] over [Space]. * Builds [MstExpression] over [Space].
*
* @author Alexander Nozik
*/ */
inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> { inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
@ -47,6 +52,8 @@ inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MST): Mst
/** /**
* Builds [MstExpression] over [Ring]. * Builds [MstExpression] over [Ring].
*
* @author Alexander Nozik
*/ */
inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST): MstExpression<T> { inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST): MstExpression<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
@ -55,6 +62,8 @@ inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST): MstExp
/** /**
* Builds [MstExpression] over [Field]. * Builds [MstExpression] over [Field].
*
* @author Alexander Nozik
*/ */
inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MST): MstExpression<T> { inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MST): MstExpression<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
@ -63,6 +72,8 @@ inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MST): Mst
/** /**
* Builds [MstExpression] over [ExtendedField]. * Builds [MstExpression] over [ExtendedField].
*
* @author Iaroslav Postovalov
*/ */
inline fun <reified T : Any> Field<T>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> { inline fun <reified T : Any> Field<T>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
@ -71,6 +82,8 @@ inline fun <reified T : Any> Field<T>.mstInExtendedField(block: MstExtendedField
/** /**
* Builds [MstExpression] over [FunctionalExpressionSpace]. * Builds [MstExpression] over [FunctionalExpressionSpace].
*
* @author Alexander Nozik
*/ */
inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> { inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
@ -79,6 +92,8 @@ inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstIn
/** /**
* Builds [MstExpression] over [FunctionalExpressionRing]. * Builds [MstExpression] over [FunctionalExpressionRing].
*
* @author Alexander Nozik
*/ */
inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.mstInRing(block: MstRing.() -> MST): MstExpression<T> { inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.mstInRing(block: MstRing.() -> MST): MstExpression<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
@ -87,6 +102,8 @@ inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.mstInRi
/** /**
* Builds [MstExpression] over [FunctionalExpressionField]. * Builds [MstExpression] over [FunctionalExpressionField].
*
* @author Alexander Nozik
*/ */
inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A>.mstInField(block: MstField.() -> MST): MstExpression<T> { inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A>.mstInField(block: MstField.() -> MST): MstExpression<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }
@ -95,6 +112,8 @@ inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A>.mstIn
/** /**
* Builds [MstExpression] over [FunctionalExpressionExtendedField]. * Builds [MstExpression] over [FunctionalExpressionExtendedField].
*
* @author Iaroslav Postovalov
*/ */
inline fun <reified T : Any, A : ExtendedField<T>> FunctionalExpressionExtendedField<T, A>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> { inline fun <reified T : Any, A : ExtendedField<T>> FunctionalExpressionExtendedField<T, A>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) }

View File

@ -17,6 +17,8 @@ import scientifik.kmath.operations.SpaceOperations
/** /**
* TODO move to core * TODO move to core
*
* @author Alexander Nozik and Iaroslav Postovalov
*/ */
object ArithmeticsEvaluator : Grammar<MST>() { object ArithmeticsEvaluator : Grammar<MST>() {
// TODO replace with "...".toRegex() when better-parse 0.4.1 is released // TODO replace with "...".toRegex() when better-parse 0.4.1 is released
@ -85,6 +87,7 @@ object ArithmeticsEvaluator : Grammar<MST>() {
* *
* @receiver the string to parse. * @receiver the string to parse.
* @return the [MST] node. * @return the [MST] node.
* @author Alexander Nozik
*/ */
fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd(this) fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd(this)
@ -93,5 +96,6 @@ fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd
* *
* @receiver the string to parse. * @receiver the string to parse.
* @return the [MST] node. * @return the [MST] node.
* @author Alexander Nozik
*/ */
fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this) fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this)

View File

@ -11,7 +11,12 @@ import scientifik.kmath.operations.Algebra
import kotlin.reflect.KClass 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> { fun <T : Any> MST.compileWith(type: KClass<T>, algebra: Algebra<T>): Expression<T> {
fun AsmBuilder<T>.visit(node: MST) { fun AsmBuilder<T>.visit(node: MST) {
@ -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) 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) inline fun <reified T : Any> MstExpression<T>.compile(): Expression<T> = mst.compileWith(T::class, algebra)

View File

@ -20,6 +20,7 @@ import kotlin.reflect.KClass
* @property algebra the algebra the applied AsmExpressions use. * @property algebra the algebra the applied AsmExpressions use.
* @property className the unique class name of new loaded class. * @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. * @property invokeLabel0Visitor the function to apply to this object when generating invoke method, label 0.
* @author Iaroslav Postovalov
*/ */
internal class AsmBuilder<T> internal constructor( internal class AsmBuilder<T> internal constructor(
private val classOfT: KClass<*>, private val classOfT: KClass<*>,

View File

@ -2,6 +2,9 @@ package scientifik.kmath.asm.internal
import scientifik.kmath.ast.MST import scientifik.kmath.ast.MST
/**
* Represents types known in [MST], numbers and general values.
*/
internal enum class MstType { internal enum class MstType {
GENERAL, GENERAL,
NUMBER; NUMBER;

View File

@ -6,6 +6,9 @@ import org.objectweb.asm.commons.InstructionAdapter
import scientifik.kmath.ast.MST import scientifik.kmath.ast.MST
import scientifik.kmath.expressions.Expression import scientifik.kmath.expressions.Expression
import scientifik.kmath.operations.Algebra import scientifik.kmath.operations.Algebra
import scientifik.kmath.operations.FieldOperations
import scientifik.kmath.operations.RingOperations
import scientifik.kmath.operations.SpaceOperations
import java.lang.reflect.Method import java.lang.reflect.Method
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
@ -13,20 +16,27 @@ import kotlin.reflect.KClass
private val methodNameAdapters: Map<Pair<String, Int>, String> by lazy { private val methodNameAdapters: Map<Pair<String, Int>, String> by lazy {
hashMapOf( hashMapOf(
"+" to 2 to "add", SpaceOperations.PLUS_OPERATION to 2 to "add",
"*" to 2 to "multiply", RingOperations.TIMES_OPERATION to 2 to "multiply",
"/" to 2 to "divide", FieldOperations.DIV_OPERATION to 2 to "divide",
"+" to 1 to "unaryPlus", SpaceOperations.PLUS_OPERATION to 1 to "unaryPlus",
"-" to 1 to "unaryMinus", SpaceOperations.MINUS_OPERATION to 1 to "unaryMinus",
"-" to 2 to "minus" SpaceOperations.MINUS_OPERATION to 2 to "minus"
) )
} }
/**
* Returns ASM [Type] for given [KClass].
*
* @author Iaroslav Postovalov
*/
internal val KClass<*>.asm: Type internal val KClass<*>.asm: Type
get() = Type.getType(java) get() = Type.getType(java)
/** /**
* Returns singleton array with this value if the [predicate] is true, returns empty array otherwise. * 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> { internal inline fun <reified T> T.wrapToArrayIf(predicate: (T) -> Boolean): Array<T> {
contract { callsInPlace(predicate, InvocationKind.EXACTLY_ONCE) } 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]. * Creates an [InstructionAdapter] from this [MethodVisitor].
*
* @author Iaroslav Postovalov
*/ */
private fun MethodVisitor.instructionAdapter(): InstructionAdapter = InstructionAdapter(this) private fun MethodVisitor.instructionAdapter(): InstructionAdapter = InstructionAdapter(this)
/** /**
* Creates an [InstructionAdapter] from this [MethodVisitor] and applies [block] to it. * Creates an [InstructionAdapter] from this [MethodVisitor] and applies [block] to it.
*
* @author Iaroslav Postovalov
*/ */
internal inline fun MethodVisitor.instructionAdapter(block: InstructionAdapter.() -> Unit): InstructionAdapter { internal inline fun MethodVisitor.instructionAdapter(block: InstructionAdapter.() -> Unit): InstructionAdapter {
contract { callsInPlace(block, InvocationKind.EXACTLY_ONCE) } 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. * Constructs a [Label], then applies it to this visitor.
*
* @author Iaroslav Postovalov
*/ */
internal fun MethodVisitor.label(): Label = Label().also { visitLabel(it) } internal fun MethodVisitor.label(): Label = Label().also { visitLabel(it) }
@ -56,6 +72,8 @@ 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 * 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. * 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 { internal tailrec fun buildName(mst: MST, collision: Int = 0): String {
val name = "scientifik.kmath.asm.generated.AsmCompiledExpression_${mst.hashCode()}_$collision" val name = "scientifik.kmath.asm.generated.AsmCompiledExpression_${mst.hashCode()}_$collision"
@ -75,6 +93,11 @@ internal inline fun ClassWriter(flags: Int, block: ClassWriter.() -> Unit): Clas
return ClassWriter(flags).apply(block) return ClassWriter(flags).apply(block)
} }
/**
* Invokes [visitField] and applies [block] to the [FieldVisitor].
*
* @author Iaroslav Postovalov
*/
internal inline fun ClassWriter.visitField( internal inline fun ClassWriter.visitField(
access: Int, access: Int,
name: String, 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 * Checks if the target [context] for code generation contains a method with needed [name] and arity, also builds
* type expectation stack for needed arity. * type expectation stack for needed arity.
* *
* @return `true` if contains, else `false`. * @author Iaroslav Postovalov
*/ */
private fun <T> AsmBuilder<T>.buildExpectationStack( private fun <T> AsmBuilder<T>.buildExpectationStack(
context: Algebra<T>, 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 * Checks if the target [context] for code generation contains a method with needed [name] and arity and inserts
* [AsmBuilder.invokeAlgebraOperation] of this method. * [AsmBuilder.invokeAlgebraOperation] of this method.
* *
* @return `true` if contains, else `false`. * @author Iaroslav Postovalov
*/ */
private fun <T> AsmBuilder<T>.tryInvokeSpecific( private fun <T> AsmBuilder<T>.tryInvokeSpecific(
context: Algebra<T>, 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( internal inline fun <T> AsmBuilder<T>.buildAlgebraOperationCall(
context: Algebra<T>, context: Algebra<T>,

View File

@ -2,6 +2,11 @@
package scientifik.kmath.asm.internal package scientifik.kmath.asm.internal
/**
* Gets value with given [key] or throws [IllegalStateException] whenever it is not present.
*
* @author Iaroslav Postovalov
*/
@JvmOverloads @JvmOverloads
internal fun <K, V> Map<K, V>.getOrFail(key: K, default: V? = null): V = internal fun <K, V> Map<K, V>.getOrFail(key: K, default: V? = null): V =
this[key] ?: default ?: error("Parameter not found: $key") this[key] ?: default ?: error("Parameter not found: $key")

View File

@ -24,6 +24,7 @@ fun <T> Space<T>.sum(data: Sequence<T>): T = data.fold(zero) { left, right -> ad
* @receiver the algebra that provides addition and division. * @receiver the algebra that provides addition and division.
* @param data the iterable to find average. * @param data the iterable to find average.
* @return the average value. * @return the average value.
* @author Iaroslav Postovalov
*/ */
fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count() fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count()
@ -33,6 +34,7 @@ fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count()
* @receiver the algebra that provides addition and division. * @receiver the algebra that provides addition and division.
* @param data the sequence to find average. * @param data the sequence to find average.
* @return the average value. * @return the average value.
* @author Iaroslav Postovalov
*/ */
fun <T> Space<T>.average(data: Sequence<T>): T = sum(data) / data.count() fun <T> Space<T>.average(data: Sequence<T>): T = sum(data) / data.count()
@ -60,6 +62,7 @@ fun <T> Sequence<T>.sumWith(space: Space<T>): T = space.sum(this)
* @receiver the iterable to find average. * @receiver the iterable to find average.
* @param space the algebra that provides addition and division. * @param space the algebra that provides addition and division.
* @return the average value. * @return the average value.
* @author Iaroslav Postovalov
*/ */
fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this) fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this)
@ -69,6 +72,7 @@ fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this)
* @receiver the sequence to find average. * @receiver the sequence to find average.
* @param space the algebra that provides addition and division. * @param space the algebra that provides addition and division.
* @return the average value. * @return the average value.
* @author Iaroslav Postovalov
*/ */
fun <T> Sequence<T>.averageWith(space: Space<T>): T = space.average(this) fun <T> Sequence<T>.averageWith(space: Space<T>): T = space.average(this)
@ -98,6 +102,7 @@ fun <T> Ring<T>.power(arg: T, power: Int): T {
* @param arg the base. * @param arg the base.
* @param power the exponent. * @param power the exponent.
* @return the base raised to the power. * @return the base raised to the power.
* @author Iaroslav Postovalov
*/ */
fun <T> Field<T>.power(arg: T, power: Int): T { fun <T> Field<T>.power(arg: T, power: Int): T {
require(power != 0 || arg != zero) { "The $zero raised to $power is not defined." } require(power != 0 || arg != zero) { "The $zero raised to $power is not defined." }

View File

@ -6,6 +6,7 @@ import kotlin.contracts.contract
* Specialized [MutableBuffer] implementation over [FloatArray]. * Specialized [MutableBuffer] implementation over [FloatArray].
* *
* @property array the underlying array. * @property array the underlying array.
* @author Iaroslav Postovalov
*/ */
inline class FloatBuffer(val array: FloatArray) : MutableBuffer<Float> { inline class FloatBuffer(val array: FloatArray) : MutableBuffer<Float> {
override val size: Int get() = array.size override val size: Int get() = array.size