diff --git a/R/twdtw.R b/R/twdtw.R index 8e19f9b..daa97f4 100644 --- a/R/twdtw.R +++ b/R/twdtw.R @@ -39,8 +39,10 @@ psi = .g(dist(doyy, doyx, method=dist.method)) # Weighted local cost matrix cm = weight.fun(phi, psi) - # Compute cost matris + # xm = na.omit(cbind(doyx, as.matrix(timeseries))) + # ym = na.omit(cbind(doyy, as.matrix(pattern))) + # internals = .computecost_fast(xm, ym, step.matrix) internals = .computecost(cm, step.matrix) internals$timeWeight = matrix(psi, nrow = nrow(psi)) internals$localMatrix = matrix(cm, nrow = nrow(cm)) diff --git a/R/twdtwApply.R b/R/twdtwApply.R index 0522dab..707740c 100644 --- a/R/twdtwApply.R +++ b/R/twdtwApply.R @@ -344,3 +344,148 @@ twdtwApply.twdtwRaster = function(x, y, weight.fun, dist.method, step.matrix, n, fun } +fasttwdtwApply = function(x, y, dist.method="Euclidean", step.matrix = symmetric1, n=NULL, progress = "text", ncores = 1, + span=NULL, min.length=0, breaks=NULL, from=NULL, to=NULL, by=NULL, overlap=0.5, fill = 255, filepath="", ...){ + # x = rts + # y = temporal_patterns + # dist.method="Euclidean" + # step.matrix = symmetric1 + # n=NULL + # span=NULL + # min.length=0 + # breaks=NULL + # from=NULL + # to=NULL + # by=NULL + # overlap=0.5 + # filepath="" + + if(is.twdtwTimeSeries(y)){ + y <- lapply(y@timeseries, function(yy){ + date <- index(yy) + yy <- as.data.frame(yy) + yy <- cbind(date, yy) + }) + } + + if(any(!sapply(y, function(yy) "date" %in% names(yy)))){ + stop("every patter in y must have a column called 'date'") + } + + if(is.null(breaks)) + if( !is.null(from) & !is.null(to) ){ + breaks = seq(as.Date(from), as.Date(to), by=by) + } else { + patt_range = lapply(y, function(yy) range(yy$date)) + patt_diff = trunc(sapply(patt_range, diff)/30)+1 + min_range = which.min(patt_diff) + by = patt_diff[[min_range]] + from = patt_range[[min_range]][1] + to = from + month(to) = month(to) + by + year(from) = year(range(index(x))[1]) + year(to) = year(range(index(x))[2]) + if(to C +C Institute for Geoinformatics (IFGI) C +C University of Muenster (WWU), Germany C +C C +C Earth System Science Center (CCST) C +C National Institute for Space Research (INPE), Brazil C +C C +C C +C Efficient computation of DTW cost matrix - 2015-10-16 C +C C +C This function was adpted from the C function 'computeCM' C +C implemented in the R package 'dtw' by Toni Giorgino. C +CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC +C +C XM - matrix with the time series (N,D) +C YM - matrix with the temporal profile (M,D) +C CM - Output cumulative cost matrix +C DM - Direction matrix +C VM - Starting points matrix +C SM - Matrix of step patterns +C N - Number of rows in CM, DM, and VM - time series +C M - Number of columns CM, DM, and VM - temporal profile +C D - Number of spectral dimensions including time in XM and YM +C NS - Number of rows in SM + SUBROUTINE fast_twdtw(XM, YM, CM, DM, VM, SM, N, M, D, NS) +C I/O Variables + INTEGER N, M, D, NS, SM(NS,4), DM(N+1,M), VM(N+1,M) + DOUBLE PRECISION XM(M,D), YM(N,D), CM(N+1,M) +C Internals + DOUBLE PRECISION W, CP(NS), VMIN + INTEGER I, J, IL(NS), JL(NS), K, PK, KMIN, ZERO, ONE + PARAMETER(ZERO=0,ONE=1) + REAL NAN, INF + NAN = ZERO + NAN = NAN / NAN + INF = HUGE(ZERO) + VM(1,1) = 1 +C Initialize the firt row and col of the matrices + DO 21 I = 2, N+1 + CM(I,1) = CM(I-1,1) + distance(YM, XM, N, M, D, I-1, 1) +C WRITE (*,*) 'The distance ',I,',1 is ', CM(I,1) + DM(I,1) = 3 + VM(I,1) = 1 + 21 CONTINUE + DO 31 J = 2, M + CM(2,J) = CM(2,J-1) + distance(YM, XM, N, M, D, 1, J) +C WRITE (*,*) 'The distance 2,',J,' is ', CM(2,J) + DM(1,J) = 2 + VM(1,J) = J + 31 CONTINUE +C Compute cumulative cost matrix + J = 2 + DO 32 WHILE ( J .LE. M ) +C DO 32 J = 2, M + I = 2 + DO 22 WHILE ( I .LE. N+1 ) +C DO 22 I = 2, N+1 +C Calculate local distance + CM(I,J) = distance(YM, XM, N, M, D, I-1, J) +C Initialize list of step cost + DO 10 K = 1, NS + CP(K) = NAN + 10 CONTINUE + DO 11 K = 1, NS + PK = SM(K,1) + IL(K) = I - SM(K,2) + JL(K) = J - SM(K,3) + IF ((IL(K).GT.ZERO).AND.(JL(K).GT.ZERO)) THEN + W = SM(K,4) + IF (W.EQ.-ONE) THEN + CP(PK) = CM(IL(K),JL(K)) + ELSE + CP(PK) = CP(PK) + CM(IL(K),JL(K))*W + ENDIF + ENDIF + 11 CONTINUE + KMIN = -ONE + VMIN = INF + ILMIN = -ONE + JLMIN = -ONE + DO 12 K = 1, NS + PK = SM(K,1) + IF (CP(PK).EQ.CP(PK).AND.CP(PK).LT.VMIN) THEN + KMIN = PK + VMIN = CP(PK) + ILMIN = IL(K) + JLMIN = JL(K) + ENDIF + 12 CONTINUE + IF (KMIN.GT.-ONE) THEN + CM(I,J) = VMIN + DM(I,J) = KMIN + VM(I,J) = VM(ILMIN, JLMIN) + ENDIF + I = I + 1 + 22 CONTINUE + J = J + 1 + 32 CONTINUE + 99 CONTINUE + END diff --git a/src/init.c b/src/init.c index 6121336..81ca0b2 100644 --- a/src/init.c +++ b/src/init.c @@ -11,6 +11,7 @@ extern void F77_NAME(bestmatches)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); extern void F77_NAME(computecost)(void *, void *, void *, void *, void *, void *, void *); extern void F77_NAME(computecostfast)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); +extern void F77_NAME(fast_twdtw)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); extern void F77_NAME(g)(void *, void *, void *, void *); extern void F77_NAME(tracepath)(void *, void *, void *, void *, void *, void *, void *, void *, void *, void *, void *); @@ -18,6 +19,7 @@ static const R_FortranMethodDef FortranEntries[] = { {"bestmatches", (DL_FUNC) &F77_NAME(bestmatches), 11}, {"computecost", (DL_FUNC) &F77_NAME(computecost), 7}, {"computecostfast", (DL_FUNC) &F77_NAME(computecostfast), 10}, + {"fast_twdtw", (DL_FUNC) &F77_NAME(fast_twdtw), 10}, {"g", (DL_FUNC) &F77_NAME(g), 4}, {"tracepath", (DL_FUNC) &F77_NAME(tracepath), 11}, {NULL, NULL, 0}