WIP: feature/emd #521

Draft
teldufalsari wants to merge 11 commits from teldufalsari/kmath:feature/emd into dev
Showing only changes of commit 40ffa8d6fc - Show all commits

View File

@ -76,17 +76,7 @@ public class EmpiricalModeDecomposition<BA, L: Number> (
* @return [SiftingResult.NotEnoughExtrema] is returned if the signal has too few extrema to extract a mode. * @return [SiftingResult.NotEnoughExtrema] is returned if the signal has too few extrema to extract a mode.
* Success of an appropriate type (See [SiftingResult.Success] class) is returned otherwise. * Success of an appropriate type (See [SiftingResult.Success] class) is returned otherwise.
*/ */
private fun sift(signal: Series<Double>): SiftingResult = (seriesAlgebra) { private fun sift(signal: Series<Double>): SiftingResult = siftInner(signal, 1, 0)

As well as I understand, whole body of the function can be replaced with just

    private fun sift(signal: Series<Double>): SiftingResult = siftInner(signal, 1, 0)
As well as I understand, whole body of the function can be replaced with just ```kotlin private fun sift(signal: Series<Double>): SiftingResult = siftInner(signal, 1, 0) ```

Also siftInner should be marked tailrec, shouldn't it?

Also `siftInner` should be marked `tailrec`, shouldn't it?

Yeah, it is better if the function is marked tailrec. But I am not sure if compiler understands the case. So I need a bit of time for a small test.

Yeah, it is better if the function is marked `tailrec`. But I am not sure if compiler understands the case. So I need a bit of time for a small test.

It works. With tailrec it does not produce stack overflow when I run sifting with 5000 iterations per mode

It works. With `tailrec` it does not produce stack overflow when I run sifting with 5000 iterations per mode
val mean = findMean(signal) ?: return SiftingResult.NotEnoughExtrema
val protoMode = signal.zip(mean) { s, m -> s - m }
val sNumber = if (protoMode.sCondition()) 1 else 0
return when {
maxSiftIterations == 1 -> SiftingResult.MaxIterationsReached(protoMode)
sNumber >= sConditionThreshold -> SiftingResult.SNumberReached(protoMode)
relativeDifference(protoMode, signal) < siftingDelta * signal.size -> SiftingResult.DeltaReached(protoMode)
else -> siftInner(protoMode, 2, sNumber)
}
}
/** /**
* Compute a single iteration of the sifting process. * Compute a single iteration of the sifting process.
@ -96,7 +86,9 @@ public class EmpiricalModeDecomposition<BA, L: Number> (
iterationNumber: Int, iterationNumber: Int,
sNumber: Int sNumber: Int
): SiftingResult = (seriesAlgebra) { ): SiftingResult = (seriesAlgebra) {
val mean = findMean(prevMode) ?: return SiftingResult.SignalFlattened(prevMode) val mean = findMean(prevMode) ?:
return if (iterationNumber == 1) SiftingResult.NotEnoughExtrema
else SiftingResult.SignalFlattened(prevMode)
val mode = prevMode.zip(mean) { p, m -> p - m } val mode = prevMode.zip(mean) { p, m -> p - m }
val newSNumber = if (mode.sCondition()) sNumber + 1 else sNumber val newSNumber = if (mode.sCondition()) sNumber + 1 else sNumber
return when { return when {