Skip to content

Commit c008841

Browse files
authored
Merge pull request #7 from SpatLyu/dev
draft metacoupling support
2 parents febfd32 + 1553956 commit c008841

11 files changed

Lines changed: 646 additions & 28 deletions

File tree

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Generated by roxygen2: do not edit by hand
22

33
export(ccd)
4+
export(metacoupling)
45
useDynLib(coupling, .registration = TRUE)

R/RcppExports.R

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ RcppCCD <- function(mat, weight, method = "standard", threads = 1L) {
55
.Call(`_coupling_RcppCCD`, mat, weight, method, threads)
66
}
77

8+
RcppMetaCoupling <- function(mat, swm_peri, swm_tele, weight, method = "standard", threads = 1L) {
9+
.Call(`_coupling_RcppMetaCoupling`, mat, swm_peri, swm_tele, weight, method, threads)
10+
}
11+

R/metacoupling.R

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#' Metacoupling Analysis
2+
#'
3+
#' @inheritParams ccd
4+
#' @param swm_peri A numeric matrix representing the **peri (local) spatial weight matrix**.
5+
#' Must be square with dimension equal to `nrow(data)`. If `NULL`, a zero matrix is used.
6+
#' @param swm_tele A numeric matrix representing the **tele (long-distance) spatial weight matrix**.
7+
#' Must be square with dimension equal to `nrow(data)`. If `NULL`, a zero matrix is used.
8+
#'
9+
#' @return A data.frame with:
10+
#' \itemize{
11+
#' \item `Intra_C`: intra-system coupling degree
12+
#' \item `Intra_D`: intra-system coordination degree
13+
#' \item `Peri_C`: peri-coupling degree
14+
#' \item `Peri_D`: peri coordination degree
15+
#' \item `Tele_C`: tele-coupling degree
16+
#' \item `Tele_D`: tele coordination degree
17+
#' }
18+
#'
19+
#' @export
20+
#'
21+
#' @details
22+
#' Full model definitions and formulas are available at:
23+
#' \url{https://github.com/stscl/coupling/discussions/8}
24+
#'
25+
#' @note
26+
#' Input values should be normalized to `[0, 1]`. Spatial weight matrices are
27+
#' typically symmetric.
28+
#'
29+
#' @examples
30+
#' set.seed(42)
31+
#' mat = matrix(runif(20), nrow = 5)
32+
#' swm1 = apply(matrix(runif(25), 5, 5), 1, \(.x) .x / sum(.x))
33+
#' swm2 = apply(matrix(runif(25), 5, 5), 1, \(.x) .x / sum(.x))
34+
#' coupling::metacoupling(mat, swm1, swm2)
35+
#'
36+
metacoupling = \(data, swm_peri = NULL, swm_tele = NULL, weight = NULL,
37+
method = c("standard", "wang", "fan"), threads = 1){
38+
mat = as.matrix(data)
39+
method = match.arg(method)
40+
if (is.null(weight)) weight = rep(1, times = ncol(mat)) / ncol(mat)
41+
if (is.null(swm_peri)) swm_peri = matrix(0, nrow(data), nrow(data))
42+
if (is.null(swm_tele)) swm_tele = matrix(0, nrow(data), nrow(data))
43+
return(RcppMetaCoupling(mat, swm_peri, swm_tele, weight, method, threads))
44+
}

_pkgdown.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@ reference:
3030
- subtitle: coupling coordination degree
3131
contents:
3232
- ccd
33+
34+
- subtitle: meta-coupling analysis
35+
contents:
36+
- metacoupling

inst/include/coupling.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939

4040
#include "coupling/numericutils.hpp"
4141
#include "coupling/ccd.hpp"
42+
#include "coupling/metacoupling.hpp"
4243

4344
// ============================================================
4445
// Convenience Converters (Inline helpers for R/C++ interop)

inst/include/coupling/ccd.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@
178178
#include <algorithm>
179179
#include <stdexcept>
180180
#include <RcppThread.h>
181+
#include "coupling/numericutils.hpp"
181182

182183
namespace coupling
183184
{
@@ -196,6 +197,7 @@ inline double ccd_c_single(
196197
const std::string& method = "standard"
197198
) {
198199
size_t p = vec.size(); // number of U values
200+
if (p <= 1) return std::numeric_limits<double>::quiet_NaN();
199201

200202
double C_val = 0.0;
201203

@@ -233,7 +235,7 @@ inline double ccd_c_single(
233235

234236
double denom = (p - 1) * p / 2.0;
235237
double term1 = 1.0 - (sum_dist / denom);
236-
if (term1 < 0) term1 = 0;
238+
// if (term1 < 0) term1 = 0;
237239

238240
double max_u = *std::max_element(vec.begin(), vec.end());
239241

0 commit comments

Comments
 (0)