Skip to content

Commit 4975fc7

Browse files
committed
fix dtw export
1 parent 7aeec68 commit 4975fc7

8 files changed

+127
-65
lines changed

R/RcppExports.R

+8
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,14 @@ C_temp_iqr <- function(mtx) {
145145
.Call(`_sits_C_temp_iqr`, mtx)
146146
}
147147

148+
rlang_env_unlock <- function(env) {
149+
invisible(.Call(`_sits_rlang_env_unlock`, env))
150+
}
151+
152+
rlang_env_lock <- function(env) {
153+
invisible(.Call(`_sits_rlang_env_lock`, env))
154+
}
155+
148156
sample_points_inclusion <- function(polymatrix, n_sam_pol) {
149157
.Call(`_sits_sample_points_inclusion`, polymatrix, n_sam_pol)
150158
}

R/api_som.R

+22
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,25 @@
1+
#' @title Register custom distances in the `kohonen` package environment.
2+
#' @name .som_register_custom_distances
3+
#' @keywords internal
4+
#' @noRd
5+
#' @author Felipe Carlos, \email{efelipecarlos@@gmail.com}
6+
#'
7+
#' @description This function injects custom distance functions in the
8+
#' environment of the `kohonen` package.
9+
#'
10+
.som_register_custom_distances <- function() {
11+
kohonen_namespace <- base::asNamespace("kohonen")
12+
13+
# unlock the environment
14+
rlang_env_unlock(kohonen_namespace)
15+
16+
# include custom distances in the environment
17+
base::assign("dtw", dtw, envir = kohonen_namespace)
18+
19+
# lock the environment
20+
rlang_env_lock(kohonen_namespace)
21+
}
22+
123
#' @title Label neurons
224
#' @name .som_label_neurons
325
#' @keywords internal

R/sits_som.R

+6-3
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,10 @@
5454
#' @param som_radius Radius of SOM neighborhood.
5555
#' @param mode Type of learning algorithm (default = "online").
5656
#'
57-
#' @note The sits package implements the \code{"dtw"} (Dynamic Time Warping)
58-
#' similarity measure. All other similarity measurements are from
59-
#' the \code{\link[kohonen:supersom]{kohonen::supersom (dist.fcts)}}
57+
#' @note The \code{sits} package implements the \code{"dtw"} (Dynamic Time
58+
#' Warping) similarity measure. All other similarity measurements
59+
#' come from the
60+
#' \code{\link[kohonen:supersom]{kohonen::supersom (dist.fcts)}}
6061
#' function.
6162
#'
6263
#' @return
@@ -94,6 +95,8 @@ sits_som_map <- function(data,
9495
distance = "euclidean",
9596
som_radius = 2,
9697
mode = "online") {
98+
# register custom distances
99+
.som_register_custom_distances()
97100
# set caller to show in errors
98101
.check_set_caller("sits_som_map")
99102
# verifies if kohonen package is installed

man/sits-package.Rd

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/sits_som.Rd

+4-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/RcppExports.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,26 @@ BEGIN_RCPP
447447
return rcpp_result_gen;
448448
END_RCPP
449449
}
450+
// rlang_env_unlock
451+
void rlang_env_unlock(SEXPREC* env);
452+
RcppExport SEXP _sits_rlang_env_unlock(SEXP envSEXP) {
453+
BEGIN_RCPP
454+
Rcpp::RNGScope rcpp_rngScope_gen;
455+
Rcpp::traits::input_parameter< SEXPREC* >::type env(envSEXP);
456+
rlang_env_unlock(env);
457+
return R_NilValue;
458+
END_RCPP
459+
}
460+
// rlang_env_lock
461+
void rlang_env_lock(SEXPREC* env);
462+
RcppExport SEXP _sits_rlang_env_lock(SEXP envSEXP) {
463+
BEGIN_RCPP
464+
Rcpp::RNGScope rcpp_rngScope_gen;
465+
Rcpp::traits::input_parameter< SEXPREC* >::type env(envSEXP);
466+
rlang_env_lock(env);
467+
return R_NilValue;
468+
END_RCPP
469+
}
450470
// sample_points_inclusion
451471
NumericMatrix sample_points_inclusion(const NumericMatrix& polymatrix, const int n_sam_pol);
452472
RcppExport SEXP _sits_sample_points_inclusion(SEXP polymatrixSEXP, SEXP n_sam_polSEXP) {
@@ -669,6 +689,8 @@ static const R_CallMethodDef CallEntries[] = {
669689
{"_sits_C_temp_sqr", (DL_FUNC) &_sits_C_temp_sqr, 1},
670690
{"_sits_C_temp_tqr", (DL_FUNC) &_sits_C_temp_tqr, 1},
671691
{"_sits_C_temp_iqr", (DL_FUNC) &_sits_C_temp_iqr, 1},
692+
{"_sits_rlang_env_unlock", (DL_FUNC) &_sits_rlang_env_unlock, 1},
693+
{"_sits_rlang_env_lock", (DL_FUNC) &_sits_rlang_env_lock, 1},
672694
{"_sits_sample_points_inclusion", (DL_FUNC) &_sits_sample_points_inclusion, 2},
673695
{"_sits_sample_points_crossings", (DL_FUNC) &_sits_sample_points_crossings, 2},
674696
{"_sits_sample_points_bin", (DL_FUNC) &_sits_sample_points_bin, 2},

src/kohonen_dtw.cpp

+44-59
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,38 @@
11
#include <Rcpp.h>
22

3-
#include <cstdlib>
4-
#include <vector>
5-
#include <cmath>
6-
#include <algorithm>
7-
#include <stdexcept>
8-
93
#include "./sits_types.h"
104

115
using namespace Rcpp;
126

137
/**
14-
* Compute the p-norm distance between two 1D C++ vectors.
8+
* Compute the p-norm between two time-series.
159
*
1610
* @description
17-
* The p-norm, also known as the Minkowski norm, is a generalized norm
18-
* calculation that includes several types of distances based on the value of p.
11+
* The `p-norm`, also known as the `Minkowski space`, is a generalized norm
12+
* calculation that includes several types of distances based on the value
13+
* of `p`.
1914
*
20-
* Common values of p include:
15+
* Common values of `p` include:
2116
*
22-
* - p = 1 for the Manhattan (city block) distance;
23-
* - p = 2 for the Euclidean norm (distance).
17+
* - `p = 1` for the Manhattan (city block) distance;
18+
* - `p = 2` for the Euclidean norm (distance).
2419
*
2520
* More details about p-norms can be found on Wikipedia:
2621
* https://en.wikipedia.org/wiki/Norm_(mathematics)#p-norm
2722
*
28-
* @param a A 1D vector representing the first point in an m-dimensional space.
29-
* @param b A 1D vector representing the second point in an m-dimensional space.
30-
* @param p The value of the norm to use, determining the type of distance
31-
* calculated.
23+
* @param a A `std::vector<double>` with time-series values.
24+
* @param b A `std::vector<double>` with time-series values.
25+
* @param p A `double` value of the norm to use, determining the type of
26+
* distance calculated.
27+
*
28+
* @note
29+
* Both vectors `a` and `b` must have the same length.
3230
*
33-
* @note Both vectors 'a' and 'b' must have the same number of dimensions.
34-
* @note This function was adapted from the DTW implementation found at:
35-
* https://github.com/cjekel/DTW_cpp
31+
* @note
32+
* The implementation of this DTW distance calculation was adapted from the
33+
* `DTW_cpp` single header library (https://github.com/cjekel/DTW_cpp).
3634
*
37-
* @return The p-norm distance between vectors 'a' and 'b'.
35+
* @return The `p-norm` value between vectors `a` and `b`.
3836
*/
3937
double p_norm(std::vector<double> a, std::vector<double> b, double p)
4038
{
@@ -51,34 +49,25 @@ double p_norm(std::vector<double> a, std::vector<double> b, double p)
5149
}
5250

5351
/**
54-
* Compute the Dynamic Time Warping (DTW) distance between two 2D C++ vectors.
52+
* Dynamic Time Warping (DTW) distance.
5553
*
5654
* @description
5755
* This function calculates the Dynamic Time Warping (DTW) distance between
58-
* two sequences that can have a different number of data points but must
59-
* share the same number of dimensions. An exception is thrown if the dimensions
60-
* of the input vectors do not match.
56+
* two time-series.
6157
*
62-
* For more information on DTW, visit:
63-
* https://en.wikipedia.org/wiki/Dynamic_time_warping
58+
* @param x A `std::vector<std::vector<double>>` with time-series values.
59+
* @param y A `std::vector<std::vector<double>>` with time-series values.
6460
*
65-
* @param a A 2D vector representing the first sequence
66-
* @param b A 2D vector representing the second sequence.
67-
* @param p The value of p-norm to use for distance calculation.
68-
*
69-
* @throws std::invalid_argument If the dimensions of 'a' and 'b' do not match.
61+
* @reference
62+
* Giorgino, T. (2009). Computing and Visualizing Dynamic Time Warping
63+
* Alignments in R: The dtw Package. Journal of Statistical Software, 31(7),
64+
* 1–24. https://doi.org/10.18637/jss.v031.i07
7065
*
7166
* @note
72-
* Both vectors 'a', and 'b' should be structured as follows:
73-
*
74-
* [number_of_data_points][number_of_dimensions]
75-
*
76-
* allowing the DTW distance computation to adapt to any p-norm value specified.
67+
* The implementation of this DTW distance calculation was adapted from the
68+
* `DTW_cpp` single header library (https://github.com/cjekel/DTW_cpp).
7769
*
78-
* @note The implementation of this DTW distance calculation was adapted from:
79-
* https://github.com/cjekel/DTW_cpp
80-
*
81-
* @return The DTW distance between the two input sequences.
70+
* @return DTW distance.
8271
*/
8372
double distance_dtw_op(std::vector<std::vector<double>> a,
8473
std::vector<std::vector<double>> b,
@@ -87,15 +76,6 @@ double distance_dtw_op(std::vector<std::vector<double>> a,
8776
int n = a.size();
8877
int o = b.size();
8978

90-
int a_m = a[0].size();
91-
int b_m = b[0].size();
92-
93-
if (a_m != b_m)
94-
{
95-
throw std::invalid_argument(
96-
"a and b must have the same number of dimensions!"
97-
);
98-
}
9979
std::vector<std::vector<double>> d(n, std::vector<double>(o, 0.0));
10080

10181
d[0][0] = p_norm(a[0], b[0], p);
@@ -121,22 +101,27 @@ double distance_dtw_op(std::vector<std::vector<double>> a,
121101
}
122102

123103
/**
124-
* Dynamic Time Warping (DTW) distance wrapper.
104+
* Dynamic Time Warping (DTW) distance.
125105
*
126106
* @description
127-
* This function calculates prepare data from `Kohonen` package and calculate
128-
* the DTW distance between two array of points.
107+
* This function calculates the Dynamic Time Warping (DTW) distance between
108+
* two time-series.
129109
*
130-
* @param a A 2D vector representing the first sequence.
131-
* @param b A 2D vector representing the second sequence.
132-
* @param np Number of points in vectors `a` and `b`.
133-
* @param nNA Number of NA values in the vectors `a` and `b`.
110+
* @param x A `double *` Time-series data.
111+
* @param y A `double *` Self-Organizing Maps (SOM) codebook.
112+
* @param np `int` Number of points in arrays `p1` and `p2`.
113+
* @param nNA `int` Number of `NA` values in the arrays `p1` and `p2`.
134114
*
135-
* @note The function signature was created following the `Kohonen` R package
136-
* specifications for custom distance functions.
115+
* @reference
116+
* Giorgino, T. (2009). Computing and Visualizing Dynamic Time Warping
117+
* Alignments in R: The dtw Package. Journal of Statistical Software, 31(7),
118+
* 1–24. https://doi.org/10.18637/jss.v031.i07
137119
*
120+
* @note
121+
* The implementation of this DTW distance calculation was adapted from the
122+
* `DTW_cpp` single header library (https://github.com/cjekel/DTW_cpp).
138123
*
139-
* @return The DTW distance between the two input sequences.
124+
* @return DTW distance.
140125
*/
141126
double kohonen_dtw(double *p1, double *p2, int np, int nNA)
142127
{

src/rlang.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include <Rcpp.h>
2+
3+
using namespace Rcpp;
4+
5+
/*
6+
* These functions were extracted from the `rlang` package to avoid extra
7+
* dependencies.
8+
*/
9+
#define FRAME_LOCK_MASK (1 << 14)
10+
#define UNLOCK_FRAME(e) SET_ENVFLAGS(e, ENVFLAGS(e) & (~FRAME_LOCK_MASK))
11+
12+
// [[Rcpp::export]]
13+
void rlang_env_unlock(SEXPREC* env) {
14+
UNLOCK_FRAME(env);
15+
}
16+
17+
// [[Rcpp::export]]
18+
void rlang_env_lock(SEXPREC* env) {
19+
UNLOCK_FRAME(env);
20+
}

0 commit comments

Comments
 (0)