Dev #194

Merged
altavir merged 266 commits from dev into master 2021-01-20 17:32:32 +03:00
35 changed files with 285 additions and 71 deletions
Showing only changes of commit 5032523bbf - Show all commits

1
.space.kts Normal file
View File

@ -0,0 +1 @@
job("Build") { gradlew("openjdk:11", "build") }

View File

@ -2,7 +2,7 @@
## [Unreleased] ## [Unreleased]
### Added ### Added
- Better trigonometric and hyperbolic functions for `AutoDiffField` (https://github.com/mipt-npm/kmath/pull/140).
### Changed ### Changed
### Deprecated ### Deprecated
@ -10,7 +10,7 @@
### Removed ### Removed
### Fixed ### Fixed
- `symbol` method in `MstExtendedField` (https://github.com/mipt-npm/kmath/pull/140)
### Security ### Security
## [0.1.4] ## [0.1.4]

View File

@ -5,7 +5,6 @@ plugins {
} }
val kmathVersion by extra("0.1.4") val kmathVersion by extra("0.1.4")
val bintrayRepo by extra("scientifik") val bintrayRepo by extra("scientifik")
val githubProject by extra("kmath") val githubProject by extra("kmath")
@ -18,6 +17,14 @@ allprojects {
group = "kscience.kmath" group = "kscience.kmath"
version = kmathVersion version = kmathVersion
afterEvaluate {
extensions.findByType<KotlinProjectExtension>()?.run {
sourceSets.all {
languageSettings.useExperimentalAnnotation("kotlin.contracts.ExperimentalContracts")
}
}
}
} }
subprojects { if (name.startsWith("kmath")) apply(plugin = "ru.mipt.npm.publish") } subprojects { if (name.startsWith("kmath")) apply(plugin = "ru.mipt.npm.publish") }

View File

@ -3,7 +3,6 @@ package scientifik.kmath.structures
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import scientifik.kmath.operations.RealField import scientifik.kmath.operations.RealField
import scientifik.kmath.operations.invoke import scientifik.kmath.operations.invoke
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.system.measureTimeMillis import kotlin.system.measureTimeMillis

View File

@ -1,4 +1,6 @@
plugins { id("ru.mipt.npm.mpp") } plugins {
id("ru.mipt.npm.mpp")
}
kotlin.sourceSets { kotlin.sourceSets {
commonMain { commonMain {

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
*/ */
public sealed class MST { public sealed class MST {
/** /**
@ -48,6 +50,7 @@ public 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
*/ */
public fun <T> Algebra<T>.evaluate(node: MST): T = when (node) { public 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

@ -38,7 +38,8 @@ public object MstSpace : Space<MST>, NumericAlgebra<MST> {
* [Ring] over [MST] nodes. * [Ring] over [MST] nodes.
*/ */
public object MstRing : Ring<MST>, NumericAlgebra<MST> { public object MstRing : Ring<MST>, NumericAlgebra<MST> {
override val zero: MST = number(0.0) override val zero: MST
get() = MstSpace.zero
override val one: MST = number(1.0) override val one: MST = number(1.0)
override fun number(value: Number): MST = MstSpace.number(value) override fun number(value: Number): MST = MstSpace.number(value)
@ -59,8 +60,11 @@ public object MstRing : Ring<MST>, NumericAlgebra<MST> {
* [Field] over [MST] nodes. * [Field] over [MST] nodes.
*/ */
public object MstField : Field<MST> { public object MstField : Field<MST> {
public override val zero: MST = number(0.0) public override val zero: MST
public override val one: MST = number(1.0) get() = MstRing.zero
public override val one: MST
get() = MstRing.one
public override fun symbol(value: String): MST = MstRing.symbol(value) public override fun symbol(value: String): MST = MstRing.symbol(value)
public override fun number(value: Number): MST = MstRing.number(value) public override fun number(value: Number): MST = MstRing.number(value)
@ -79,14 +83,25 @@ public object MstField : Field<MST> {
* [ExtendedField] over [MST] nodes. * [ExtendedField] over [MST] nodes.
*/ */
public object MstExtendedField : ExtendedField<MST> { public object MstExtendedField : ExtendedField<MST> {
override val zero: MST = number(0.0) override val zero: MST
override val one: MST = number(1.0) get() = MstField.zero
override val one: MST
get() = MstField.one
override fun symbol(value: String): MST = MstField.symbol(value)
override fun sin(arg: MST): MST = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg) override fun sin(arg: MST): MST = unaryOperation(TrigonometricOperations.SIN_OPERATION, arg)
override fun cos(arg: MST): MST = unaryOperation(TrigonometricOperations.COS_OPERATION, arg) override fun cos(arg: MST): MST = unaryOperation(TrigonometricOperations.COS_OPERATION, arg)
override fun tan(arg: MST): MST = unaryOperation(TrigonometricOperations.TAN_OPERATION, arg)
override fun asin(arg: MST): MST = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg) override fun asin(arg: MST): MST = unaryOperation(TrigonometricOperations.ASIN_OPERATION, arg)
override fun acos(arg: MST): MST = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg) override fun acos(arg: MST): MST = unaryOperation(TrigonometricOperations.ACOS_OPERATION, arg)
override fun atan(arg: MST): MST = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg) override fun atan(arg: MST): MST = unaryOperation(TrigonometricOperations.ATAN_OPERATION, arg)
override fun sinh(arg: MST): MST = unaryOperation(HyperbolicOperations.SINH_OPERATION, arg)
override fun cosh(arg: MST): MST = unaryOperation(HyperbolicOperations.COSH_OPERATION, arg)
override fun tanh(arg: MST): MST = unaryOperation(HyperbolicOperations.TANH_OPERATION, arg)
override fun asinh(arg: MST): MST = unaryOperation(HyperbolicOperations.ASINH_OPERATION, arg)
override fun acosh(arg: MST): MST = unaryOperation(HyperbolicOperations.ACOSH_OPERATION, arg)
override fun atanh(arg: MST): MST = unaryOperation(HyperbolicOperations.ATANH_OPERATION, arg)
override fun add(a: MST, b: MST): MST = MstField.add(a, b) override fun add(a: MST, b: MST): MST = MstField.add(a, b)
override fun multiply(a: MST, k: Number): MST = MstField.multiply(a, k) override fun multiply(a: MST, k: Number): MST = MstField.multiply(a, k)
override fun multiply(a: MST, b: MST): MST = MstField.multiply(a, b) override fun multiply(a: MST, b: MST): MST = MstField.multiply(a, b)

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
*/ */
public class MstExpression<T>(public val algebra: Algebra<T>, public val mst: MST) : Expression<T> { public class MstExpression<T>(public val algebra: Algebra<T>, public 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 @@ public class MstExpression<T>(public val algebra: Algebra<T>, public val mst: MS
/** /**
* Builds [MstExpression] over [Algebra]. * Builds [MstExpression] over [Algebra].
*
* @author Alexander Nozik
*/ */
public inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst( public inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst(
mstAlgebra: E, mstAlgebra: E,
@ -39,6 +42,8 @@ public inline fun <reified T : Any, A : Algebra<T>, E : Algebra<MST>> A.mst(
/** /**
* Builds [MstExpression] over [Space]. * Builds [MstExpression] over [Space].
*
* @author Alexander Nozik
*/ */
public inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> { public 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 @@ public inline fun <reified T : Any> Space<T>.mstInSpace(block: MstSpace.() -> MS
/** /**
* Builds [MstExpression] over [Ring]. * Builds [MstExpression] over [Ring].
*
* @author Alexander Nozik
*/ */
public inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST): MstExpression<T> { public 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 @@ public inline fun <reified T : Any> Ring<T>.mstInRing(block: MstRing.() -> MST):
/** /**
* Builds [MstExpression] over [Field]. * Builds [MstExpression] over [Field].
*
* @author Alexander Nozik
*/ */
public inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MST): MstExpression<T> { public 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 @@ public inline fun <reified T : Any> Field<T>.mstInField(block: MstField.() -> MS
/** /**
* Builds [MstExpression] over [ExtendedField]. * Builds [MstExpression] over [ExtendedField].
*
* @author Iaroslav Postovalov
*/ */
public inline fun <reified T : Any> Field<T>.mstInExtendedField(block: MstExtendedField.() -> MST): MstExpression<T> { public 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 @@ public inline fun <reified T : Any> Field<T>.mstInExtendedField(block: MstExtend
/** /**
* Builds [MstExpression] over [FunctionalExpressionSpace]. * Builds [MstExpression] over [FunctionalExpressionSpace].
*
* @author Alexander Nozik
*/ */
public inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A>.mstInSpace(block: MstSpace.() -> MST): MstExpression<T> { public 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 @@ public inline fun <reified T : Any, A : Space<T>> FunctionalExpressionSpace<T, A
/** /**
* Builds [MstExpression] over [FunctionalExpressionRing]. * Builds [MstExpression] over [FunctionalExpressionRing].
*
* @author Alexander Nozik
*/ */
public inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.mstInRing(block: MstRing.() -> MST): MstExpression<T> { public 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 @@ public inline fun <reified T : Any, A : Ring<T>> FunctionalExpressionRing<T, A>.
/** /**
* Builds [MstExpression] over [FunctionalExpressionField]. * Builds [MstExpression] over [FunctionalExpressionField].
*
* @author Alexander Nozik
*/ */
public inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A>.mstInField(block: MstField.() -> MST): MstExpression<T> { public 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 @@ public inline fun <reified T : Any, A : Field<T>> FunctionalExpressionField<T, A
/** /**
* Builds [MstExpression] over [FunctionalExpressionExtendedField]. * Builds [MstExpression] over [FunctionalExpressionExtendedField].
*
* @author Iaroslav Postovalov
*/ */
public inline fun <reified T : Any, A : ExtendedField<T>> FunctionalExpressionExtendedField<T, A>.mstInExtendedField( public inline fun <reified T : Any, A : ExtendedField<T>> FunctionalExpressionExtendedField<T, A>.mstInExtendedField(
block: MstExtendedField.() -> MST block: MstExtendedField.() -> MST

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
*/ */
public object ArithmeticsEvaluator : Grammar<MST>() { public 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 @@ public 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
*/ */
public fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd(this) public fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryParseToEnd(this)
@ -93,5 +96,6 @@ public fun String.tryParseMath(): ParseResult<MST> = ArithmeticsEvaluator.tryPar
* *
* @receiver the string to parse. * @receiver the string to parse.
* @return the [MST] node. * @return the [MST] node.
* @author Alexander Nozik
*/ */
public fun String.parseMath(): MST = ArithmeticsEvaluator.parseToEnd(this) public 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
*/ */
public fun <T : Any> MST.compileWith(type: KClass<T>, algebra: Algebra<T>): Expression<T> { public 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 @@ public fun <T : Any> MST.compileWith(type: KClass<T>, algebra: Algebra<T>): Expr
} }
/** /**
* Compile an [MST] to ASM using given algebra * Compiles an [MST] to ASM using given algebra.
*
* @author Alexander Nozik.
*/ */
public inline fun <reified T : Any> Algebra<T>.expression(mst: MST): Expression<T> = mst.compileWith(T::class, this) public 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.
*/ */
public inline fun <reified T : Any> MstExpression<T>.compile(): Expression<T> = mst.compileWith(T::class, algebra) public 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,28 +6,37 @@ 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.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.reflect.KClass 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) }
@ -36,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) }
@ -49,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) }
@ -57,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"
@ -76,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,
@ -105,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>,
@ -137,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>,
@ -161,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

@ -1,4 +1,6 @@
plugins { id("ru.mipt.npm.jvm") } plugins {
id("ru.mipt.npm.jvm")
}
description = "Commons math binding for kmath" description = "Commons math binding for kmath"
dependencies { dependencies {

View File

@ -4,7 +4,6 @@ import scientifik.kmath.operations.ExtendedField
import scientifik.kmath.operations.Field import scientifik.kmath.operations.Field
import scientifik.kmath.operations.Ring import scientifik.kmath.operations.Ring
import scientifik.kmath.operations.Space import scientifik.kmath.operations.Space
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract

View File

@ -4,7 +4,6 @@ import scientifik.kmath.operations.Ring
import scientifik.kmath.structures.Matrix import scientifik.kmath.structures.Matrix
import scientifik.kmath.structures.Structure2D import scientifik.kmath.structures.Structure2D
import scientifik.kmath.structures.asBuffer import scientifik.kmath.structures.asBuffer
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.math.sqrt import kotlin.math.sqrt

View File

@ -6,7 +6,6 @@ import scientifik.kmath.operations.Field
import scientifik.kmath.operations.invoke import scientifik.kmath.operations.invoke
import scientifik.kmath.operations.sum import scientifik.kmath.operations.sum
import scientifik.kmath.structures.asBuffer import scientifik.kmath.structures.asBuffer
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract
@ -209,3 +208,40 @@ public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.sin(x: Variable<T
// cos(x) // cos(x)
public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.cos(x: Variable<T>): Variable<T> = public fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.cos(x: Variable<T>): Variable<T> =
derive(variable { cos(x.value) }) { z -> x.d -= z.d * sin(x.value) } derive(variable { cos(x.value) }) { z -> x.d -= z.d * sin(x.value) }
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.tan(x: Variable<T>): Variable<T> =
derive(variable { tan(x.value) }) { z ->
val c = cos(x.value)
x.d += z.d / (c * c)
}
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.asin(x: Variable<T>): Variable<T> =
derive(variable { asin(x.value) }) { z -> x.d += z.d / sqrt(one - x.value * x.value) }
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.acos(x: Variable<T>): Variable<T> =
derive(variable { acos(x.value) }) { z -> x.d -= z.d / sqrt(one - x.value * x.value) }
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.atan(x: Variable<T>): Variable<T> =
derive(variable { atan(x.value) }) { z -> x.d += z.d / (one + x.value * x.value) }
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.sinh(x: Variable<T>): Variable<T> =
derive(variable { sin(x.value) }) { z -> x.d += z.d * cosh(x.value) }
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.cosh(x: Variable<T>): Variable<T> =
derive(variable { cos(x.value) }) { z -> x.d += z.d * sinh(x.value) }
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.tanh(x: Variable<T>): Variable<T> =
derive(variable { tan(x.value) }) { z ->
val c = cosh(x.value)
x.d += z.d / (c * c)
}
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.asinh(x: Variable<T>): Variable<T> =
derive(variable { asinh(x.value) }) { z -> x.d += z.d / sqrt(one + x.value * x.value) }
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.acosh(x: Variable<T>): Variable<T> =
derive(variable { acosh(x.value) }) { z -> x.d += z.d / (sqrt((x.value - one) * (x.value + one))) }
fun <T : Any, F : ExtendedField<T>> AutoDiffField<T, F>.atanh(x: Variable<T>): Variable<T> =
derive(variable { atanh(x.value) }) { z -> x.d += z.d / (one - x.value * x.value) }

View File

@ -24,6 +24,7 @@ public fun <T> Space<T>.sum(data: Sequence<T>): T = data.fold(zero) { left, righ
* @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
*/ */
public fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count() public fun <T> Space<T>.average(data: Iterable<T>): T = sum(data) / data.count()
@ -33,6 +34,7 @@ public 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
*/ */
public fun <T> Space<T>.average(data: Sequence<T>): T = sum(data) / data.count() public fun <T> Space<T>.average(data: Sequence<T>): T = sum(data) / data.count()
@ -60,6 +62,7 @@ public 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
*/ */
public fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this) public fun <T> Iterable<T>.averageWith(space: Space<T>): T = space.average(this)
@ -69,6 +72,7 @@ public 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
*/ */
public fun <T> Sequence<T>.averageWith(space: Space<T>): T = space.average(this) public fun <T> Sequence<T>.averageWith(space: Space<T>): T = space.average(this)
@ -98,6 +102,7 @@ public 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
*/ */
public fun <T> Field<T>.power(arg: T, power: Int): T { public 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 scientifik.kmath.structures.MutableBuffer
import scientifik.memory.MemoryReader import scientifik.memory.MemoryReader
import scientifik.memory.MemorySpec import scientifik.memory.MemorySpec
import scientifik.memory.MemoryWriter import scientifik.memory.MemoryWriter
import kotlin.contracts.contract
import kotlin.math.* import kotlin.math.*
/** /**

View File

@ -2,6 +2,7 @@ package scientifik.kmath.structures
import scientifik.kmath.operations.Complex import scientifik.kmath.operations.Complex
import scientifik.kmath.operations.complex import scientifik.kmath.operations.complex
import kotlin.contracts.contract
import kotlin.reflect.KClass import kotlin.reflect.KClass
/** /**

View File

@ -1,5 +1,6 @@
package scientifik.kmath.structures package scientifik.kmath.structures
import kotlin.contracts.contract
import kotlin.experimental.and import kotlin.experimental.and
/** /**

View File

@ -1,12 +1,12 @@
package scientifik.kmath.structures package scientifik.kmath.structures
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract 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
*/ */
public inline class FloatBuffer(public val array: FloatArray) : MutableBuffer<Float> { public inline class FloatBuffer(public val array: FloatArray) : MutableBuffer<Float> {
override val size: Int get() = array.size override val size: Int get() = array.size

View File

@ -1,5 +1,7 @@
package scientifik.kmath.structures package scientifik.kmath.structures
import kotlin.contracts.contract
/** /**
* Specialized [MutableBuffer] implementation over [IntArray]. * Specialized [MutableBuffer] implementation over [IntArray].
* *

View File

@ -1,6 +1,5 @@
package scientifik.kmath.structures package scientifik.kmath.structures
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
/** /**

View File

@ -1,5 +1,7 @@
package scientifik.kmath.structures package scientifik.kmath.structures
import kotlin.contracts.contract
/** /**
* Specialized [MutableBuffer] implementation over [DoubleArray]. * Specialized [MutableBuffer] implementation over [DoubleArray].
* *

View File

@ -1,5 +1,7 @@
package scientifik.kmath.structures package scientifik.kmath.structures
import kotlin.contracts.contract
/** /**
* Specialized [MutableBuffer] implementation over [ShortArray]. * Specialized [MutableBuffer] implementation over [ShortArray].
* *

View File

@ -1,11 +1,9 @@
package scientifik.kmath.linear package scientifik.kmath.linear
import scientifik.kmath.structures.Matrix import scientifik.kmath.structures.Matrix
import kotlin.contracts.ExperimentalContracts
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ExperimentalContracts
class RealLUSolverTest { class RealLUSolverTest {
@Test @Test

View File

@ -3,19 +3,19 @@ package scientifik.kmath.misc
import scientifik.kmath.operations.RealField import scientifik.kmath.operations.RealField
import scientifik.kmath.structures.asBuffer import scientifik.kmath.structures.asBuffer
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.pow
import kotlin.math.sqrt
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertTrue import kotlin.test.assertTrue
class AutoDiffTest { class AutoDiffTest {
fun Variable(int: Int): Variable<Double> = Variable(int.toDouble()) inline fun deriv(body: AutoDiffField<Double, RealField>.() -> Variable<Double>): DerivationResult<Double> =
fun deriv(body: AutoDiffField<Double, RealField>.() -> Variable<Double>): DerivationResult<Double> =
RealField.deriv(body) RealField.deriv(body)
@Test @Test
fun testPlusX2() { fun testPlusX2() {
val x = Variable(3) // diff w.r.t this x at 3 val x = Variable(3.0) // diff w.r.t this x at 3
val y = deriv { x + x } val y = deriv { x + x }
assertEquals(6.0, y.value) // y = x + x = 6 assertEquals(6.0, y.value) // y = x + x = 6
assertEquals(2.0, y.deriv(x)) // dy/dx = 2 assertEquals(2.0, y.deriv(x)) // dy/dx = 2
@ -24,8 +24,8 @@ class AutoDiffTest {
@Test @Test
fun testPlus() { fun testPlus() {
// two variables // two variables
val x = Variable(2) val x = Variable(2.0)
val y = Variable(3) val y = Variable(3.0)
val z = deriv { x + y } val z = deriv { x + y }
assertEquals(5.0, z.value) // z = x + y = 5 assertEquals(5.0, z.value) // z = x + y = 5
assertEquals(1.0, z.deriv(x)) // dz/dx = 1 assertEquals(1.0, z.deriv(x)) // dz/dx = 1
@ -35,8 +35,8 @@ class AutoDiffTest {
@Test @Test
fun testMinus() { fun testMinus() {
// two variables // two variables
val x = Variable(7) val x = Variable(7.0)
val y = Variable(3) val y = Variable(3.0)
val z = deriv { x - y } val z = deriv { x - y }
assertEquals(4.0, z.value) // z = x - y = 4 assertEquals(4.0, z.value) // z = x - y = 4
assertEquals(1.0, z.deriv(x)) // dz/dx = 1 assertEquals(1.0, z.deriv(x)) // dz/dx = 1
@ -45,7 +45,7 @@ class AutoDiffTest {
@Test @Test
fun testMulX2() { fun testMulX2() {
val x = Variable(3) // diff w.r.t this x at 3 val x = Variable(3.0) // diff w.r.t this x at 3
val y = deriv { x * x } val y = deriv { x * x }
assertEquals(9.0, y.value) // y = x * x = 9 assertEquals(9.0, y.value) // y = x * x = 9
assertEquals(6.0, y.deriv(x)) // dy/dx = 2 * x = 7 assertEquals(6.0, y.deriv(x)) // dy/dx = 2 * x = 7
@ -53,7 +53,7 @@ class AutoDiffTest {
@Test @Test
fun testSqr() { fun testSqr() {
val x = Variable(3) val x = Variable(3.0)
val y = deriv { sqr(x) } val y = deriv { sqr(x) }
assertEquals(9.0, y.value) // y = x ^ 2 = 9 assertEquals(9.0, y.value) // y = x ^ 2 = 9
assertEquals(6.0, y.deriv(x)) // dy/dx = 2 * x = 7 assertEquals(6.0, y.deriv(x)) // dy/dx = 2 * x = 7
@ -61,7 +61,7 @@ class AutoDiffTest {
@Test @Test
fun testSqrSqr() { fun testSqrSqr() {
val x = Variable(2) val x = Variable(2.0)
val y = deriv { sqr(sqr(x)) } val y = deriv { sqr(sqr(x)) }
assertEquals(16.0, y.value) // y = x ^ 4 = 16 assertEquals(16.0, y.value) // y = x ^ 4 = 16
assertEquals(32.0, y.deriv(x)) // dy/dx = 4 * x^3 = 32 assertEquals(32.0, y.deriv(x)) // dy/dx = 4 * x^3 = 32
@ -69,7 +69,7 @@ class AutoDiffTest {
@Test @Test
fun testX3() { fun testX3() {
val x = Variable(2) // diff w.r.t this x at 2 val x = Variable(2.0) // diff w.r.t this x at 2
val y = deriv { x * x * x } val y = deriv { x * x * x }
assertEquals(8.0, y.value) // y = x * x * x = 8 assertEquals(8.0, y.value) // y = x * x * x = 8
assertEquals(12.0, y.deriv(x)) // dy/dx = 3 * x * x = 12 assertEquals(12.0, y.deriv(x)) // dy/dx = 3 * x * x = 12
@ -77,8 +77,8 @@ class AutoDiffTest {
@Test @Test
fun testDiv() { fun testDiv() {
val x = Variable(5) val x = Variable(5.0)
val y = Variable(2) val y = Variable(2.0)
val z = deriv { x / y } val z = deriv { x / y }
assertEquals(2.5, z.value) // z = x / y = 2.5 assertEquals(2.5, z.value) // z = x / y = 2.5
assertEquals(0.5, z.deriv(x)) // dz/dx = 1 / y = 0.5 assertEquals(0.5, z.deriv(x)) // dz/dx = 1 / y = 0.5
@ -87,7 +87,7 @@ class AutoDiffTest {
@Test @Test
fun testPow3() { fun testPow3() {
val x = Variable(2) // diff w.r.t this x at 2 val x = Variable(2.0) // diff w.r.t this x at 2
val y = deriv { pow(x, 3) } val y = deriv { pow(x, 3) }
assertEquals(8.0, y.value) // y = x ^ 3 = 8 assertEquals(8.0, y.value) // y = x ^ 3 = 8
assertEquals(12.0, y.deriv(x)) // dy/dx = 3 * x ^ 2 = 12 assertEquals(12.0, y.deriv(x)) // dy/dx = 3 * x ^ 2 = 12
@ -95,8 +95,8 @@ class AutoDiffTest {
@Test @Test
fun testPowFull() { fun testPowFull() {
val x = Variable(2) val x = Variable(2.0)
val y = Variable(3) val y = Variable(3.0)
val z = deriv { pow(x, y) } val z = deriv { pow(x, y) }
assertApprox(8.0, z.value) // z = x ^ y = 8 assertApprox(8.0, z.value) // z = x ^ y = 8
assertApprox(12.0, z.deriv(x)) // dz/dx = y * x ^ (y - 1) = 12 assertApprox(12.0, z.deriv(x)) // dz/dx = y * x ^ (y - 1) = 12
@ -105,7 +105,7 @@ class AutoDiffTest {
@Test @Test
fun testFromPaper() { fun testFromPaper() {
val x = Variable(3) val x = Variable(3.0)
val y = deriv { 2 * x + x * x * x } val y = deriv { 2 * x + x * x * x }
assertEquals(33.0, y.value) // y = 2 * x + x * x * x = 33 assertEquals(33.0, y.value) // y = 2 * x + x * x * x = 33
assertEquals(29.0, y.deriv(x)) // dy/dx = 2 + 3 * x * x = 29 assertEquals(29.0, y.deriv(x)) // dy/dx = 2 + 3 * x * x = 29
@ -113,9 +113,9 @@ class AutoDiffTest {
@Test @Test
fun testInnerVariable() { fun testInnerVariable() {
val x = Variable(1) val x = Variable(1.0)
val y = deriv { val y = deriv {
Variable(1) * x Variable(1.0) * x
} }
assertEquals(1.0, y.value) // y = x ^ n = 1 assertEquals(1.0, y.value) // y = x ^ n = 1
assertEquals(1.0, y.deriv(x)) // dy/dx = n * x ^ (n - 1) = n - 1 assertEquals(1.0, y.deriv(x)) // dy/dx = n * x ^ (n - 1) = n - 1
@ -124,9 +124,9 @@ class AutoDiffTest {
@Test @Test
fun testLongChain() { fun testLongChain() {
val n = 10_000 val n = 10_000
val x = Variable(1) val x = Variable(1.0)
val y = deriv { val y = deriv {
var res = Variable(1) var res = Variable(1.0)
for (i in 1..n) res *= x for (i in 1..n) res *= x
res res
} }
@ -136,7 +136,7 @@ class AutoDiffTest {
@Test @Test
fun testExample() { fun testExample() {
val x = Variable(2) val x = Variable(2.0)
val y = deriv { sqr(x) + 5 * x + 3 } val y = deriv { sqr(x) + 5 * x + 3 }
assertEquals(17.0, y.value) // the value of result (y) assertEquals(17.0, y.value) // the value of result (y)
assertEquals(9.0, y.deriv(x)) // dy/dx assertEquals(9.0, y.deriv(x)) // dy/dx
@ -144,7 +144,7 @@ class AutoDiffTest {
@Test @Test
fun testSqrt() { fun testSqrt() {
val x = Variable(16) val x = Variable(16.0)
val y = deriv { sqrt(x) } val y = deriv { sqrt(x) }
assertEquals(4.0, y.value) // y = x ^ 1/2 = 4 assertEquals(4.0, y.value) // y = x ^ 1/2 = 4
assertEquals(1.0 / 8, y.deriv(x)) // dy/dx = 1/2 / x ^ 1/4 = 1/8 assertEquals(1.0 / 8, y.deriv(x)) // dy/dx = 1/2 / x ^ 1/4 = 1/8
@ -152,18 +152,98 @@ class AutoDiffTest {
@Test @Test
fun testSin() { fun testSin() {
val x = Variable(PI / 6) val x = Variable(PI / 6.0)
val y = deriv { sin(x) } val y = deriv { sin(x) }
assertApprox(0.5, y.value) // y = sin(PI/6) = 0.5 assertApprox(0.5, y.value) // y = sin(PI/6) = 0.5
assertApprox(kotlin.math.sqrt(3.0) / 2, y.deriv(x)) // dy/dx = cos(PI/6) = sqrt(3)/2 assertApprox(sqrt(3.0) / 2, y.deriv(x)) // dy/dx = cos(pi/6) = sqrt(3)/2
} }
@Test @Test
fun testCos() { fun testCos() {
val x = Variable(PI / 6) val x = Variable(PI / 6)
val y = deriv { cos(x) } val y = deriv { cos(x) }
assertApprox(kotlin.math.sqrt(3.0) / 2, y.value) // y = cos(PI/6) = sqrt(3)/2 assertApprox(sqrt(3.0) / 2, y.value) //y = cos(pi/6) = sqrt(3)/2
assertApprox(-0.5, y.deriv(x)) // dy/dx = -sin(PI/6) = -0.5 assertApprox(-0.5, y.deriv(x)) // dy/dx = -sin(pi/6) = -0.5
}
@Test
fun testTan() {
val x = Variable(PI / 6)
val y = deriv { tan(x) }
assertApprox(1.0 / sqrt(3.0), y.value) // y = tan(pi/6) = 1/sqrt(3)
assertApprox(4.0 / 3.0, y.deriv(x)) // dy/dx = sec(pi/6)^2 = 4/3
}
@Test
fun testAsin() {
val x = Variable(PI / 6)
val y = deriv { asin(x) }
assertApprox(kotlin.math.asin(PI / 6.0), y.value) // y = asin(pi/6)
assertApprox(6.0 / sqrt(36 - PI * PI), y.deriv(x)) // dy/dx = 6/sqrt(36-pi^2)
}
@Test
fun testAcos() {
val x = Variable(PI / 6)
val y = deriv { acos(x) }
assertApprox(kotlin.math.acos(PI / 6.0), y.value) // y = acos(pi/6)
assertApprox(-6.0 / sqrt(36.0 - PI * PI), y.deriv(x)) // dy/dx = -6/sqrt(36-pi^2)
}
@Test
fun testAtan() {
val x = Variable(PI / 6)
val y = deriv { atan(x) }
assertApprox(kotlin.math.atan(PI / 6.0), y.value) // y = atan(pi/6)
assertApprox(36.0 / (36.0 + PI * PI), y.deriv(x)) // dy/dx = 36/(36+pi^2)
}
@Test
fun testSinh() {
val x = Variable(0.0)
val y = deriv { sinh(x) }
assertApprox(kotlin.math.sinh(0.0), y.value) // y = sinh(0)
assertApprox(kotlin.math.cosh(0.0), y.deriv(x)) // dy/dx = cosh(0)
}
@Test
fun testCosh() {
val x = Variable(0.0)
val y = deriv { cosh(x) }
assertApprox(1.0, y.value) //y = cosh(0)
assertApprox(0.0, y.deriv(x)) // dy/dx = sinh(0)
}
@Test
fun testTanh() {
val x = Variable(PI / 6)
val y = deriv { tanh(x) }
assertApprox(1.0 / sqrt(3.0), y.value) // y = tanh(pi/6)
assertApprox(1.0 / kotlin.math.cosh(PI / 6.0).pow(2), y.deriv(x)) // dy/dx = sech(pi/6)^2
}
@Test
fun testAsinh() {
val x = Variable(PI / 6)
val y = deriv { asinh(x) }
assertApprox(kotlin.math.asinh(PI / 6.0), y.value) // y = asinh(pi/6)
assertApprox(6.0 / sqrt(36 + PI * PI), y.deriv(x)) // dy/dx = 6/sqrt(pi^2+36)
}
@Test
fun testAcosh() {
val x = Variable(PI / 6)
val y = deriv { acosh(x) }
assertApprox(kotlin.math.acosh(PI / 6.0), y.value) // y = acosh(pi/6)
assertApprox(-6.0 / sqrt(36.0 - PI * PI), y.deriv(x)) // dy/dx = -6/sqrt(36-pi^2)
}
@Test
fun testAtanh() {
val x = Variable(PI / 6.0)
val y = deriv { atanh(x) }
assertApprox(kotlin.math.atanh(PI / 6.0), y.value) // y = atanh(pi/6)
assertApprox(-36.0 / (PI * PI - 36.0), y.deriv(x)) // dy/dx = -36/(pi^2-36)
} }
@Test @Test

View File

@ -1,4 +1,6 @@
plugins { id("ru.mipt.npm.mpp") } plugins {
id("ru.mipt.npm.mpp")
}
kotlin.sourceSets.commonMain { kotlin.sourceSets.commonMain {
dependencies { dependencies {

View File

@ -9,7 +9,6 @@ import scientifik.kmath.structures.Buffer
import scientifik.kmath.structures.Matrix import scientifik.kmath.structures.Matrix
import scientifik.kmath.structures.RealBuffer import scientifik.kmath.structures.RealBuffer
import scientifik.kmath.structures.asIterable import scientifik.kmath.structures.asIterable
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.contract import kotlin.contracts.contract
import kotlin.math.pow import kotlin.math.pow

View File

@ -1,4 +1,6 @@
plugins { id("ru.mipt.npm.mpp") } plugins {
id("ru.mipt.npm.mpp")
}
kotlin.sourceSets.commonMain { kotlin.sourceSets.commonMain {
dependencies { dependencies {

View File

@ -4,9 +4,6 @@ import scientifik.kmath.domains.Domain
import scientifik.kmath.linear.Point import scientifik.kmath.linear.Point
import scientifik.kmath.structures.ArrayBuffer import scientifik.kmath.structures.ArrayBuffer
import scientifik.kmath.structures.RealBuffer import scientifik.kmath.structures.RealBuffer
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
/** /**
* The bin in the histogram. The histogram is by definition always done in the real space * The bin in the histogram. The histogram is by definition always done in the real space

View File

@ -6,7 +6,6 @@ import java.nio.channels.FileChannel
import java.nio.file.Files import java.nio.file.Files
import java.nio.file.Path import java.nio.file.Path
import java.nio.file.StandardOpenOption import java.nio.file.StandardOpenOption
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind
import kotlin.contracts.contract import kotlin.contracts.contract

View File

@ -13,8 +13,4 @@ kotlin.sourceSets {
api("org.apache.commons:commons-rng-simple:1.3") api("org.apache.commons:commons-rng-simple:1.3")
} }
} }
jvmTest {
languageSettings.useExperimentalAnnotation("kotlinx.coroutines.FlowPreview")
}
} }