DTW method realization #517

Open
EjenY-Poltavchiny wants to merge 19 commits from mrFendel/ejeny_branch_ into dev
2 changed files with 59 additions and 8 deletions
Showing only changes of commit 051a3893ec - Show all commits

View File

@ -0,0 +1,29 @@
/*
* Copyright 2018-2023 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.series
import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.structures.asBuffer
fun main() = with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
val firstSequence: DoubleArray = doubleArrayOf(0.0, 2.0, 3.0, 1.0, 3.0, 0.1, 0.0, 1.0)
val secondSequence: DoubleArray = doubleArrayOf(1.0, 0.0, 3.0, 0.0, 0.0, 3.0, 2.0, 0.0, 2.0)
val seriesOne = firstSequence.asBuffer()
val seriesTwo = secondSequence.asBuffer()
val result = DoubleFieldOpsND.dynamicTimeWarping(seriesOne, seriesTwo)
println("Total penalty coefficient: ${result.totalCost}")
print("Alignment: ")
println(result.alignMatrix)
for ((i , j) in result.alignMatrix.indices) {
if (result.alignMatrix[i, j] > 0.0) {
print("[$i, $j] ")
}
}
}

View File

@ -6,30 +6,52 @@
package space.kscience.kmath.series package space.kscience.kmath.series
import space.kscience.kmath.nd.* import space.kscience.kmath.nd.*
import space.kscience.kmath.operations.DoubleField
import space.kscience.kmath.operations.algebra import space.kscience.kmath.operations.algebra
import space.kscience.kmath.operations.bufferAlgebra import space.kscience.kmath.operations.bufferAlgebra
import space.kscience.kmath.structures.asBuffer import space.kscience.kmath.structures.asBuffer
import space.kscience.kmath.structures.toDoubleBuffer
import kotlin.math.PI
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals
class DTWTest { class DTWTest {
@Test @Test
fun someData() { fun someData() {
val firstSequence: DoubleArray = doubleArrayOf(0.0, 2.0, 3.0, 1.0, 3.0, 0.1, 0.0, 1.0) val firstSequence: DoubleArray = doubleArrayOf(0.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 1.0)
val secondSequence: DoubleArray = doubleArrayOf(1.0, 0.0, 3.0, 0.0, 0.0, 3.0, 2.0, 0.0, 2.0) val secondSequence: DoubleArray = doubleArrayOf(0.0, 2.0, 3.0, 1.0, 2.0, 3.0, 1.0, 1.0)
val seriesOne = firstSequence.asBuffer() val seriesOne = firstSequence.asBuffer()
val seriesTwo = secondSequence.asBuffer() val seriesTwo = secondSequence.asBuffer()
val result = DoubleFieldOpsND.dynamicTimeWarping(seriesOne, seriesTwo) val result = DoubleFieldOpsND.dynamicTimeWarping(seriesOne, seriesTwo)
println("Total penalty coefficient: ${result.totalCost}") assertEquals(result.totalCost, 0.0)
print("Alignment: ") }
println(result.alignMatrix)
for ((i , j) in result.alignMatrix.indices) { @Test
if (result.alignMatrix[i, j] > 0.0) { fun pathTest() = with(Double.algebra.bufferAlgebra.seriesAlgebra()) {
print("[$i, $j] ") val s1 = series(10) { DoubleField.sin(2 * PI * it / 100)}.toDoubleBuffer()
val s2 = series(20) {sin(PI * it / 100)}.toDoubleBuffer()
val s3 = series(20) {sin(PI * it / 100 + 2 * PI)}.toDoubleBuffer()
val resS1S2 = DoubleFieldOpsND.dynamicTimeWarping(s1, s2).alignMatrix
var pathLengthS1S2 = 0
for ((i,j) in resS1S2.indices) {
if (resS1S2[i, j] > 0.0) {
++pathLengthS1S2
} }
} }
val resS1S3 = DoubleFieldOpsND.dynamicTimeWarping(s1, s3).alignMatrix
var pathLengthS1S3 = 0
for ((i,j) in resS1S3.indices) {
if (resS1S2[i, j] > 0.0) {
++pathLengthS1S3
}
}
assertEquals(pathLengthS1S3, pathLengthS1S2)
} }
} }