Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DoubleBuffer generator was moved to DoubleBuffer file and factory fun… #485

Open
wants to merge 8 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
name: Dokka publication

on:
push:
branches: [ master ]
workflow_dispatch:
release:
types: [ created ]

jobs:
build:
Expand All @@ -24,7 +25,7 @@ jobs:
- uses: gradle/[email protected]
with:
arguments: dokkaHtmlMultiModule --no-parallel
- uses: JamesIves/github-pages-deploy-action@4.2.5
- uses: JamesIves/github-pages-deploy-action@v4.3.0
with:
branch: gh-pages
folder: build/dokka/htmlMultiModule
2 changes: 2 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ jobs:
arguments: |
releaseAll
-Ppublishing.enabled=true
-Ppublishing.sonatype=false
-Ppublishing.space.user=${{ secrets.SPACE_APP_ID }}
-Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }}
- name: Publish Mac Artifacts
Expand All @@ -45,5 +46,6 @@ jobs:
releaseIosArm64
releaseIosX64
-Ppublishing.enabled=true
-Ppublishing.sonatype=false
-Ppublishing.space.user=${{ secrets.SPACE_APP_ID }}
-Ppublishing.space.token=${{ secrets.SPACE_APP_SECRET }}
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,9 @@ public object MstLogicAlgebra : LogicAlgebra<MST> {
override fun bindSymbolOrNull(value: String): MST = super.bindSymbolOrNull(value) ?: StringSymbol(value)

override fun const(boolean: Boolean): Symbol = if (boolean) {
LogicAlgebra.TRUE
BinaryLogic.TRUE
} else {
LogicAlgebra.FALSE
BinaryLogic.FALSE
}

override fun MST.not(): MST = MST.Unary(Boolean::not.name, this)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

package space.kscience.kmath.operations

import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.expressions.symbol

interface BinaryLogic<T : Any> {
/**
* Logic 'not'
*/
public operator fun T.not(): T

/**
* Logic 'and'
*/
public infix fun T.and(other: T): T

/**
* Logic 'or'
*/
public infix fun T.or(other: T): T

/**
* Logic 'xor'
*/
public infix fun T.xor(other: T): T

companion object {
public val TRUE: Symbol by symbol
public val FALSE: Symbol by symbol
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,13 @@

package space.kscience.kmath.operations

import space.kscience.kmath.expressions.Symbol
import space.kscience.kmath.expressions.symbol
import space.kscience.kmath.misc.UnstableKMathAPI

/**
* An algebra for generic boolean logic
*/
@UnstableKMathAPI
public interface LogicAlgebra<T : Any> : Algebra<T> {

public interface LogicAlgebra<T : Any> : Algebra<T>, BinaryLogic<T> {
/**
* Represent constant [Boolean] as [T]
*/
Expand All @@ -38,32 +35,6 @@ public interface LogicAlgebra<T : Any> : Algebra<T> {
override fun binaryOperationFunction(operation: String): (left: T, right: T) -> T = { l, r ->
binaryOperation(operation, l, r)
}

/**
* Logic 'not'
*/
public operator fun T.not(): T

/**
* Logic 'and'
*/
public infix fun T.and(other: T): T

/**
* Logic 'or'
*/
public infix fun T.or(other: T): T

/**
* Logic 'xor'
*/
public infix fun T.xor(other: T): T


public companion object {
public val TRUE: Symbol by symbol
public val FALSE: Symbol by symbol
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package space.kscience.kmath.structures

import kotlin.jvm.JvmInline
import kotlin.random.Random.Default.nextDouble
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default generator should never be used outside of tests


/**
* Specialized [MutableBuffer] implementation over [DoubleArray].
Expand Down Expand Up @@ -42,6 +43,11 @@ public value class DoubleBuffer(public val array: DoubleArray) : MutableBuffer<D
*/
public inline fun DoubleBuffer(size: Int, init: (Int) -> Double): DoubleBuffer = DoubleBuffer(DoubleArray(size) { init(it) })

/**
* A chunk of doubles of given [size].
*/
public fun nextDoubleBuffer(size: Int): DoubleBuffer = DoubleBuffer(size) { nextDouble() }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any reasons to add this to the core?


/**
* Returns a new [DoubleBuffer] of given elements.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import space.kscience.kmath.misc.UnstableKMathAPI
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.stat.RandomGenerator
import space.kscience.kmath.stat.nextBuffer
import space.kscience.kmath.structures.nextDoubleBuffer
import kotlin.native.concurrent.ThreadLocal
import kotlin.test.Test
import kotlin.test.assertEquals
Expand All @@ -35,15 +36,15 @@ internal class UniformHistogram1DTest {

@Test
fun rebinDown() = runTest {
val h1 = Histogram.uniform1D(DoubleField, 0.01).produce(generator.nextDoubleBuffer(10000))
val h1 = Histogram.uniform1D(DoubleField, 0.01).produce(nextDoubleBuffer(10000))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't see how it helps

val h2 = Histogram.uniform1D(DoubleField,0.03).produceFrom(h1)

assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt())
}

@Test
fun rebinUp() = runTest {
val h1 = Histogram.uniform1D(DoubleField, 0.03).produce(generator.nextDoubleBuffer(10000))
val h1 = Histogram.uniform1D(DoubleField, 0.03).produce(nextDoubleBuffer(10000))
val h2 = Histogram.uniform1D(DoubleField,0.01).produceFrom(h1)

assertEquals(10000, h2.bins.sumOf { it.binValue }.toInt())
Expand Down
10 changes: 10 additions & 0 deletions kmath-nd4j/src/main/kotlin/space/kscience/kmath/nd4j/arrays.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,13 @@ package space.kscience.kmath.nd4j
import space.kscience.kmath.misc.toIntExact

internal fun LongArray.toIntArray(): IntArray = IntArray(size) { this[it].toIntExact() }

internal fun LongArray.linspace(start: Long, stop: Long) = Array(this.size) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We try not to use Arrays in mathematics because they have some default overrides in Kotling StdLib. You should use Buffer and there are already BufferAlgebra.zero producers for that. There is a DoubleBuffer producer that uses step, we can add a similar one for Longs, but we need to be careful about naming.

start + it * ((stop - start) / (this.size - 1))
}

internal fun LongArray.zeros() = Array(this.size) { 0 }

internal fun LongArray.ones() = Array(this.size) { 1 }

internal fun repeat(number: Long, size: Int) = LongArray(size) { number }
43 changes: 43 additions & 0 deletions kmath-nd4j/src/test/kotlin/space/kscience/kmath/nd4j/ArraysTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2018-2021 KMath contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/

package space.kscience.kmath.nd4j

import org.junit.jupiter.api.Test
import kotlin.test.assertEquals

class ArraysTest {
@Test
fun checkLinspaceBuilder() {
val array = LongArray(3).linspace(15, 22)
assertEquals(array[0], 15)
assertEquals(array[1], 18)
assertEquals(array[2], 21)
}

@Test
fun checkZerosBuilder() {
val array = LongArray(3).zeros()
assertEquals(array[0], 0)
assertEquals(array[1], 0)
assertEquals(array[2], 0)
}

@Test
fun checkOnesBuilder() {
val array = LongArray(3).ones()
assertEquals(array[0], 1)
assertEquals(array[1], 1)
assertEquals(array[2], 1)
}

@Test
fun checkRepeatBuilder() {
val array = repeat(5, 3)
assertEquals(array[0], 5)
assertEquals(array[1], 5)
assertEquals(array[2], 5)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package space.kscience.kmath.samplers
import space.kscience.kmath.chains.BlockingDoubleChain
import space.kscience.kmath.stat.RandomGenerator
import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.kmath.structures.nextDoubleBuffer
import kotlin.math.*

/**
Expand All @@ -23,8 +24,8 @@ public object BoxMullerSampler : NormalizedGaussianSampler {
var state = Double.NaN

override fun nextBufferBlocking(size: Int): DoubleBuffer {
val xs = generator.nextDoubleBuffer(size)
val ys = generator.nextDoubleBuffer(size)
val xs = nextDoubleBuffer(size)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a mistake. You are using the default generator instead of provided one. It will give wrong results.

val ys = nextDoubleBuffer(size)

return DoubleBuffer(size) { index ->
if (state.isNaN()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package space.kscience.kmath.stat
import space.kscience.kmath.chains.BlockingDoubleChain
import space.kscience.kmath.chains.Chain
import space.kscience.kmath.structures.DoubleBuffer
import space.kscience.kmath.structures.nextDoubleBuffer

/**
* A possibly stateful chain producing random values.
Expand All @@ -31,7 +32,7 @@ public fun <R> RandomGenerator.chain(generator: suspend RandomGenerator.() -> R)
* A type-specific double chunk random chain
*/
public class UniformDoubleChain(public val generator: RandomGenerator) : BlockingDoubleChain {
override fun nextBufferBlocking(size: Int): DoubleBuffer = generator.nextDoubleBuffer(size)
override fun nextBufferBlocking(size: Int): DoubleBuffer = nextDoubleBuffer(size)
override suspend fun nextBuffer(size: Int): DoubleBuffer = nextBufferBlocking(size)

override suspend fun fork(): UniformDoubleChain = UniformDoubleChain(generator.fork())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ public interface RandomGenerator {
*/
public fun nextDouble(): Double

/**
* A chunk of doubles of given [size].
*/
public fun nextDoubleBuffer(size: Int): DoubleBuffer = DoubleBuffer(size) { nextDouble() }

/**
* Gets the next random `Int` from the random number generator.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,12 @@ public fun <T, TT : TNumber, A> TensorFlowAlgebra<T, TT, A>.sin(

public fun <T, TT : TNumber, A> TensorFlowAlgebra<T, TT, A>.cos(
arg: StructureND<T>,
): TensorFlowOutput<T, TT> where A : TrigonometricOperations<T>, A : Ring<T> = arg.operate { ops.math.cos(it) }
): TensorFlowOutput<T, TT> where A : TrigonometricOperations<T>, A : Ring<T> = arg.operate { ops.math.cos(it) }

public fun <T, TT : TNumber, A> TensorFlowAlgebra<T, TT, A>.tan(
arg: StructureND<T>,
): TensorFlowOutput<T, TT> where A : TrigonometricOperations<T>, A : Ring<T> = arg.operate { ops.math.tan(it) }

public fun <T, TT : TNumber, A> TensorFlowAlgebra<T, TT, A>.abs(
arg: StructureND<T>,
): TensorFlowOutput<T, TT> where A : TrigonometricOperations<T>, A : Ring<T> = arg.operate { ops.math.abs(it) }