diff --git a/.Rbuildignore b/.Rbuildignore index b7364c9..3f92db2 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -4,3 +4,4 @@ ^_pkgdown\.yml$ ^docs$ ^pkgdown$ +^cran-comments\.md$ diff --git a/.github/workflows/rhub.yaml b/.github/workflows/rhub.yaml new file mode 100644 index 0000000..74ec7b0 --- /dev/null +++ b/.github/workflows/rhub.yaml @@ -0,0 +1,95 @@ +# R-hub's generic GitHub Actions workflow file. It's canonical location is at +# https://github.com/r-hub/actions/blob/v1/workflows/rhub.yaml +# You can update this file to a newer version using the rhub2 package: +# +# rhub::rhub_setup() +# +# It is unlikely that you need to modify this file manually. + +name: R-hub +run-name: "${{ github.event.inputs.id }}: ${{ github.event.inputs.name || format('Manually run by {0}', github.triggering_actor) }}" + +on: + workflow_dispatch: + inputs: + config: + description: 'A comma separated list of R-hub platforms to use.' + type: string + default: 'linux,windows,macos' + name: + description: 'Run name. You can leave this empty now.' + type: string + id: + description: 'Unique ID. You can leave this empty now.' + type: string + +jobs: + + setup: + runs-on: ubuntu-latest + outputs: + containers: ${{ steps.rhub-setup.outputs.containers }} + platforms: ${{ steps.rhub-setup.outputs.platforms }} + + steps: + # NO NEED TO CHECKOUT HERE + - uses: r-hub/actions/setup@v1 + with: + config: ${{ github.event.inputs.config }} + id: rhub-setup + + linux-containers: + needs: setup + if: ${{ needs.setup.outputs.containers != '[]' }} + runs-on: ubuntu-latest + name: ${{ matrix.config.label }} + strategy: + fail-fast: false + matrix: + config: ${{ fromJson(needs.setup.outputs.containers) }} + container: + image: ${{ matrix.config.container }} + + steps: + - uses: r-hub/actions/checkout@v1 + - uses: r-hub/actions/platform-info@v1 + with: + token: ${{ secrets.RHUB_TOKEN }} + job-config: ${{ matrix.config.job-config }} + - uses: r-hub/actions/setup-deps@v1 + with: + token: ${{ secrets.RHUB_TOKEN }} + job-config: ${{ matrix.config.job-config }} + - uses: r-hub/actions/run-check@v1 + with: + token: ${{ secrets.RHUB_TOKEN }} + job-config: ${{ matrix.config.job-config }} + + other-platforms: + needs: setup + if: ${{ needs.setup.outputs.platforms != '[]' }} + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.label }} + strategy: + fail-fast: false + matrix: + config: ${{ fromJson(needs.setup.outputs.platforms) }} + + steps: + - uses: r-hub/actions/checkout@v1 + - uses: r-hub/actions/setup-r@v1 + with: + job-config: ${{ matrix.config.job-config }} + token: ${{ secrets.RHUB_TOKEN }} + - uses: r-hub/actions/platform-info@v1 + with: + token: ${{ secrets.RHUB_TOKEN }} + job-config: ${{ matrix.config.job-config }} + - uses: r-hub/actions/setup-deps@v1 + with: + job-config: ${{ matrix.config.job-config }} + token: ${{ secrets.RHUB_TOKEN }} + - uses: r-hub/actions/run-check@v1 + with: + job-config: ${{ matrix.config.job-config }} + token: ${{ secrets.RHUB_TOKEN }} diff --git a/DESCRIPTION b/DESCRIPTION index e1b2677..697e77c 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: coupling -Title: Coupling Coordination Analysis -Version: 0.0.0.9000 +Title: Analysis of Coupling Coordination Degree +Version: 0.1 Authors@R: person(given = "Wenbo", family = "Lyu", email = "lyu.geosocial@gmail.com", @@ -17,7 +17,10 @@ LinkingTo: Rcpp, RcppThread Suggests: + infoxtr, + pc, Rcpp, RcppThread, + spEDM Config/roxygen2/markdown: TRUE Config/roxygen2/version: 8.0.0 diff --git a/NEWS.md b/NEWS.md new file mode 100644 index 0000000..33ebd9b --- /dev/null +++ b/NEWS.md @@ -0,0 +1,3 @@ +# coupling 0.1 + +* Initial CRAN submission. diff --git a/README.md b/README.md index 92357a5..953b9b0 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ coupling website: https://stscl.github.io/coupling/ -***Coupling** Coordination Analysis* +*Analysis of Coupling Coordination Degree* *coupling* is an R package for coupling coordination analysis based on coupling coordination degree (CCD) models. It incorporates metacoupling frameworks to characterize cross-scale linkages, flows, and feedbacks within and among coupled systems. diff --git a/_pkgdown.yml b/_pkgdown.yml index 36d1273..15cd5bd 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -18,7 +18,7 @@ navbar: home: title: | - ccd | Coupling Coordination Analysis + coupling | Analysis of Coupling Coordination Degree authors: Wenbo Lyu: href: https://spatlyu.github.io/ diff --git a/cran-comments.md b/cran-comments.md new file mode 100644 index 0000000..858617d --- /dev/null +++ b/cran-comments.md @@ -0,0 +1,5 @@ +## R CMD check results + +0 errors | 0 warnings | 1 note + +* This is a new release. diff --git a/inst/CITATION b/inst/CITATION new file mode 100644 index 0000000..f553ffb --- /dev/null +++ b/inst/CITATION @@ -0,0 +1,10 @@ +citHeader("To cite package coupling in publications, please use:") + +bibentry( + bibtype = "Manual", + title = "{coupling: Analysis of Coupling Coordination Degree}", + author = "Wenbo Lyu", + year = "2026", + note = "R package version 0.1", + doi = "10.32614/CRAN.package.coupling" +) diff --git a/inst/include/coupling/ccd.hpp b/inst/include/coupling/ccd.hpp index d978cb8..d2c18ac 100644 --- a/inst/include/coupling/ccd.hpp +++ b/inst/include/coupling/ccd.hpp @@ -295,6 +295,10 @@ inline std::vector ccd_c( if (n_units == 0) return {}; std::vector result(n_units, 0.0); + + if (threads == 0) threads = 1; + size_t hw = std::thread::hardware_concurrency(); + if (hw > 0) threads = std::min(threads, hw); if (threads <= 1) { for (size_t i = 0; i < n_units; ++i) { diff --git a/inst/include/coupling/metacoupling.hpp b/inst/include/coupling/metacoupling.hpp index 5e0b639..a409503 100644 --- a/inst/include/coupling/metacoupling.hpp +++ b/inst/include/coupling/metacoupling.hpp @@ -312,6 +312,13 @@ inline std::vector> metacoupling_c( result[1][s] = peri_sum; result[2][s] = tele_sum; }; + + // ============================================================ + // Check for available threads + // ============================================================ + if (threads == 0) threads = 1; + size_t hw = std::thread::hardware_concurrency(); + if (hw > 0) threads = std::min(threads, hw); // ============================================================ // Parallel or serial execution @@ -357,6 +364,13 @@ inline std::vector> metacoupling( size_t full_perm = 1ULL << p; + // ============================================================ + // Check for available threads + // ============================================================ + if (threads == 0) threads = 1; + size_t hw = std::thread::hardware_concurrency(); + if (hw > 0) threads = std::min(threads, hw); + // ============================================================ // Step 1: reuse existing C computation // ============================================================ @@ -399,11 +413,7 @@ inline std::vector> metacoupling( return sum_t / static_cast(count); }; - // ============================================================ - // Step 3: assemble results - // ============================================================ - for (size_t s = 0; s < n_units; ++s) { - + auto worker4D = [&](size_t s) { // ---- intra ---- double C_intra = C_res[0][s]; double T_intra = compute_T_intra(s); @@ -442,6 +452,17 @@ inline std::vector> metacoupling( result[4][s] = C_tele; result[5][s] = std::sqrt(C_tele * tele_T_sum); + }; + + // ============================================================ + // Step 3: assemble results + // ============================================================ + if (threads <= 1) { + for (size_t s = 0; s < n_units; ++s) { + worker4D(s); + } + } else { + RcppThread::parallelFor(0, n_units, worker4D, threads); } return result;