This OpenMOLE plugin brings Dynamic Time Warp [DTW] metrics so they can be used in OpenMOLE.
A typical example is to compare two time series during a calibration process, one being measured, the other one generated by a simulation. In the course of simulation, you might be willing to calibrate the simulation so the resulting load curves are similar. Yet what does "similar" means here? Dynamic Time Warp, among other methods, is a way to compare load curves and accept time shifts between two curves better than with a Mean Squarred Error [MSE] or equivalent.
This plugin only wraps the existing Java code from: https://github.com/rmaestre/FastDTW
And wraps it as an osgi plugin so it can be loaded into OpenMOLE
- download the last release
- in the GUI of OpenMOLE, load the plugin that's all folks.
The typical usage from OpenMOLE ScalaTask is:
val simulatedCurve = Val[Array[Double]]
val refCurve = Val[Array[Double]]
val diffDWT = Val[Double]
val diffMSE = Val[Double]
val compareSeriesTask = ScalaTask("""
import ch.resear.samthiriot.openmole.plugins.dtw.DTW
val diffDWT = DTW.getFastWarpDistBetween(simulatedCurve, refCurve)
val diffMSE = DTW.getMSE(simulatedCurve, refCurve)
""") set (
inputs += simulatedCurve,
inputs += refCurve,
outputs += diffDWT,
outputs += diffMSE,
plugins += pluginsOf[ch.resear.samthiriot.openmole.plugins.dtw.DTW],
simulatedCurve := Array(0.0,0.0,0.1,0.2,0.5,0.3,0.1,0.0,0.0),
refCurve := Array(0.0,0.1,0.2,0.5,0.3,0.1,0.0,0.0,0.0)
)
compareSeriesTask hook DisplayHook()
The available metrics are:
- Dynamic Time Warping:
DTW.getWarpDistBetween(Array[Double],Array[Double]):Double
- Fast Dynamic Time Warping:
DTW.getFastWarpDistBetween(Array[Double],Array[Double]):Double
- Mean Squared Error:
DTW.getMSE(Array[Double],Array[Double]):Double
- Squared Mean Squared Error:
DTW.getRMSE(Array[Double],Array[Double]):Double
- Mean absolute error:
DTW.getMAE(Array[Double],Array[Double]):Double
- Get the MSE difference between curves after normalization:
DTW.getMSEBetweenNormalized(Array[Double],Array[Double]):Double
In case you want to execute that as part of an optimization method, remember you can chain your simulation and a task comparing the series. In the next example, model
might export series, and compareSeriesTask
might compute the difference between the simulated serie and the expected one, and return o1
and o2
as aggregate goals to minimize:
NSGA2Evolution(
[...]
objective = Seq(o1, o2),
evaluation = model -- compareSeriesTask
[...]
)