Merge dev into master #59

Merged
altavir merged 37 commits from dev into master 2019-05-31 12:35:58 +03:00
3 changed files with 39 additions and 9 deletions
Showing only changes of commit fcab05b683 - Show all commits

View File

@ -5,6 +5,8 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import org.apache.commons.math3.transform.* import org.apache.commons.math3.transform.*
import scientifik.kmath.operations.Complex import scientifik.kmath.operations.Complex
import scientifik.kmath.streaming.chunked
import scientifik.kmath.streaming.spread
import scientifik.kmath.structures.* import scientifik.kmath.structures.*
@ -33,40 +35,40 @@ object Transformations {
fun fourier( fun fourier(
normalization: DftNormalization = DftNormalization.STANDARD, normalization: DftNormalization = DftNormalization.STANDARD,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): BufferTransform<Complex, Complex> = { ): SuspendBufferTransform<Complex, Complex> = {
FastFourierTransformer(normalization).transform(it.toArray(), direction).asBuffer() FastFourierTransformer(normalization).transform(it.toArray(), direction).asBuffer()
} }
fun realFourier( fun realFourier(
normalization: DftNormalization = DftNormalization.STANDARD, normalization: DftNormalization = DftNormalization.STANDARD,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): BufferTransform<Double, Complex> = { ): SuspendBufferTransform<Double, Complex> = {
FastFourierTransformer(normalization).transform(it.asArray(), direction).asBuffer() FastFourierTransformer(normalization).transform(it.asArray(), direction).asBuffer()
} }
fun sine( fun sine(
normalization: DstNormalization = DstNormalization.STANDARD_DST_I, normalization: DstNormalization = DstNormalization.STANDARD_DST_I,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): BufferTransform<Double, Double> = { ): SuspendBufferTransform<Double, Double> = {
FastSineTransformer(normalization).transform(it.asArray(), direction).asBuffer() FastSineTransformer(normalization).transform(it.asArray(), direction).asBuffer()
} }
fun cosine( fun cosine(
normalization: DctNormalization = DctNormalization.STANDARD_DCT_I, normalization: DctNormalization = DctNormalization.STANDARD_DCT_I,
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): BufferTransform<Double, Double> = { ): SuspendBufferTransform<Double, Double> = {
FastCosineTransformer(normalization).transform(it.asArray(), direction).asBuffer() FastCosineTransformer(normalization).transform(it.asArray(), direction).asBuffer()
} }
fun hadamard( fun hadamard(
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): BufferTransform<Double, Double> = { ): SuspendBufferTransform<Double, Double> = {
FastHadamardTransformer().transform(it.asArray(), direction).asBuffer() FastHadamardTransformer().transform(it.asArray(), direction).asBuffer()
} }
} }
/** /**
* Process given [Producer] with commons-math fft transformation * Process given [Flow] with commons-math fft transformation
*/ */
@FlowPreview @FlowPreview
fun Flow<Buffer<Complex>>.FFT( fun Flow<Buffer<Complex>>.FFT(
@ -84,5 +86,24 @@ fun Flow<Buffer<Double>>.FFT(
direction: TransformType = TransformType.FORWARD direction: TransformType = TransformType.FORWARD
): Flow<Buffer<Complex>> { ): Flow<Buffer<Complex>> {
val transform = Transformations.realFourier(normalization, direction) val transform = Transformations.realFourier(normalization, direction)
return map { transform(it) } return map(transform)
} }
/**
* Process a continous flow of real numbers in FFT splitting it in chunks of [bufferSize].
*/
@FlowPreview
@JvmName("realFFT")
fun Flow<Double>.FFT(
bufferSize: Int = Int.MAX_VALUE,
normalization: DftNormalization = DftNormalization.STANDARD,
direction: TransformType = TransformType.FORWARD
): Flow<Complex> {
return chunked(bufferSize).FFT(normalization,direction).spread()
}
/**
* Map a complex flow into real flow by taking real part of each number
*/
@FlowPreview
fun Flow<Complex>.real(): Flow<Double> = map{it.re}

View File

@ -277,4 +277,6 @@ fun <T> Buffer<T>.asReadOnly(): Buffer<T> = if (this is MutableBuffer) {
/** /**
* Typealias for buffer transformations * Typealias for buffer transformations
*/ */
typealias BufferTransform<T, R> = (Buffer<T>) -> Buffer<R> typealias BufferTransform<T, R> = (Buffer<T>) -> Buffer<R>
typealias SuspendBufferTransform<T, R> = suspend (Buffer<T>) -> Buffer<R>

View File

@ -37,6 +37,9 @@ fun <T> Flow<T>.chunked(bufferSize: Int, bufferFactory: BufferFactory<T>) = flow
counter = 0 counter = 0
} }
} }
if (counter > 0) {
emit(bufferFactory(counter) { list[it] })
}
} }
/** /**
@ -54,8 +57,12 @@ fun Flow<Double>.chunked(bufferSize: Int) = flow {
if (counter == bufferSize) { if (counter == bufferSize) {
val buffer = DoubleBuffer(array) val buffer = DoubleBuffer(array)
emit(buffer) emit(buffer)
counter = 0
} }
} }
if (counter > 0) {
emit(DoubleBuffer(counter) { array[it] })
}
} }
/** /**