Skip to content

Commit 3009be7

Browse files
committed
weave_swarm cleanup
1 parent b29dc70 commit 3009be7

File tree

4 files changed

+23
-253
lines changed

4 files changed

+23
-253
lines changed

R/RcppExports.R

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,6 @@
11
# Generated by using Rcpp::compileAttributes() -> do not edit by hand
22
# Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393
33

4-
wilkinson_bin_to_right_ <- function(x, width) {
5-
.Call(`_ggdist_wilkinson_bin_to_right_`, x, width)
6-
}
7-
84
#' Can we place `candidate` at this position given the last placed dot and
95
#' the previous rows of dots placed so far?
106
#' @param candidate <scalar [numeric]> candidate x position
@@ -17,8 +13,10 @@ wilkinson_bin_to_right_ <- function(x, width) {
1713
#' @param reverse <scalar [logical]> are we placing dots in reverse order?
1814
#' @returns <scalar [logical]> can we place candidate here?
1915
#' @noRd
20-
can_place_candidate_ <- function(candidate, last_placed, rows, n_rows_back, y_grid, xsize, reverse) {
21-
.Call(`_ggdist_can_place_candidate_`, candidate, last_placed, rows, n_rows_back, y_grid, xsize, reverse)
16+
NULL
17+
18+
wilkinson_bin_to_right_ <- function(x, width) {
19+
.Call(`_ggdist_wilkinson_bin_to_right_`, x, width)
2220
}
2321

2422
#' Weave/swarm hybrid
@@ -29,7 +27,7 @@ can_place_candidate_ <- function(candidate, last_placed, rows, n_rows_back, y_gr
2927
#' @param side <scalar [integer]> which side to place dots on: 0 = both, 1 = above, -1 = below
3028
#' @returns <[data.frame]> data frame with columns x and y giving the new positions
3129
#' @noRd
32-
weave_swarm_new_ <- function(x, xsize, ysize, side) {
33-
.Call(`_ggdist_weave_swarm_new_`, x, xsize, ysize, side)
30+
weave_swarm_ <- function(x, xsize, ysize, side) {
31+
.Call(`_ggdist_weave_swarm_`, x, xsize, ysize, side)
3432
}
3533

R/bin_dots.R

Lines changed: 8 additions & 218 deletions
Original file line numberDiff line numberDiff line change
@@ -655,232 +655,22 @@ wilkinson_bin_from_center = function(x, width) {
655655

656656
# weave swarm -------------------------------------------------------------
657657

658-
#' Find the last value in `values` less than or equal to `target`
659-
#' @param values <[numeric]> sorted vector
660-
#' @param target <[numeric]> value to compare to
661-
#' @returns <[numeric]> last value in x less than or equal to val, or -Inf if none
662-
#' @noRd
663-
last_lte = function(values, target) {
664-
i = findInterval(target, values)
665-
if (i == 0) -Inf else values[[i]]
666-
}
667-
668-
#' Find the first value in `values` greater than `target`
669-
#' @param values <[numeric]> sorted vector
670-
#' @param target <[numeric]> value to compare to
671-
#' @returns <[numeric]> first value in x greater than val
672-
#' @noRd
673-
first_gt = function(values, target) {
674-
i = findInterval(target, values) + 1
675-
if (i > length(values)) Inf else values[[i]]
676-
}
677-
678-
#' Can we place candidate at this position given the last placed dot and
679-
#' the previous rows of dots placed so far?
680-
#' @param candidate <scalar [numeric]> candidate x position
681-
#' @param last_placed <scalar [numeric]> last placed x position in this row
682-
#' @param last_rows <[list] of [numeric]> list of previous rows of placed dots
683-
#' @param y_grid <scalar [integer]> number of previous rows in the y grid that
684-
#' could overlap with this candidate
685-
#' @param xsize <scalar [numeric]> horizontal spacing between dots
686-
#' @param reverse <scalar [logical]> are we placing dots in reverse order?
687-
#' @returns <scalar [logical]> can we place candidate here?
688-
#' @noRd
689-
can_place_candidate_old = function(candidate, last_placed, last_rows, y_grid, xsize, reverse) {
690-
if (reverse) {
691-
if (candidate > last_placed - xsize) return(FALSE)
692-
} else {
693-
if (candidate < last_placed + xsize) return(FALSE)
694-
}
695-
for (i in seq_len(y_grid - 1)) {
696-
last_row_i = last_rows[[i]]
697-
if (length(last_row_i) == 0) next
698-
699-
y_offset = i / y_grid
700-
min_x_dist = sqrt(1 - y_offset^2) * xsize
701-
last_val_lte_candidate_idx = findInterval(candidate, last_row_i)
702-
if (last_val_lte_candidate_idx > 0) {
703-
last_val_lte_candidate = last_row_i[[last_val_lte_candidate_idx]]
704-
if (candidate < last_val_lte_candidate + min_x_dist) return(FALSE)
705-
}
706-
if (last_val_lte_candidate_idx < length(last_row_i)) {
707-
first_val_gt_candidate = last_row_i[[last_val_lte_candidate_idx + 1]]
708-
if (candidate > first_val_gt_candidate - min_x_dist) return(FALSE)
709-
}
710-
}
711-
TRUE
712-
}
713-
714658
#' Weave/swarm hybrid
715659
#'
716-
#' @param x sorted x values
717-
#' @param y y values (must be constant)
718-
#' @noRd
719-
weave_swarm_old = function(x, y, xsize, ysize = xsize, side = 1) {
720-
y_grid = 4
721-
722-
both = side == 0
723-
remaining = x
724-
rows = list()
725-
if (both) rows_bottom = list()
726-
727-
place_row = function(reverse = FALSE, both = side == 0) {
728-
if (length(remaining) == 0) return()
729-
730-
kth_last_row = function(k, rows) {
731-
i = length(rows) + 1 - k
732-
if (i <= 0) numeric() else rows[[i]]
733-
}
734-
last_rows = lapply(seq_len(y_grid), kth_last_row, rows)
735-
if (both) last_rows_bottom = lapply(seq_len(y_grid), kth_last_row, rows_bottom)
736-
candidates = remaining
737-
if (reverse) candidates = rev(candidates)
738-
739-
row = numeric()
740-
if (both) row_bottom = numeric()
741-
next_remaining = numeric()
742-
last_placed = if (reverse) Inf else -Inf
743-
if (both) last_placed_bottom = last_placed
744-
745-
for (candidate in candidates) {
746-
if (can_place_candidate_old(candidate, last_placed, last_rows, y_grid, xsize, reverse)) {
747-
row = c(row, candidate)
748-
last_placed = candidate
749-
} else if (both && can_place_candidate_old(candidate, last_placed_bottom, last_rows_bottom, y_grid, xsize, reverse)) {
750-
row_bottom = c(row_bottom, candidate)
751-
last_placed_bottom = candidate
752-
} else {
753-
next_remaining = c(next_remaining, candidate)
754-
}
755-
}
756-
757-
if (reverse) {
758-
row = rev(row)
759-
if (both) row_bottom = rev(row_bottom)
760-
next_remaining = rev(next_remaining)
761-
}
762-
rows <<- c(rows, list(row))
763-
if (both) rows_bottom <<- c(rows_bottom, list(row_bottom))
764-
remaining <<- next_remaining
765-
}
766-
767-
# first row is special when both == TRUE: it is a "middle" row that is
768-
# treated as the first row (for placement purposes) on both the top and bottom sides
769-
place_row(both = FALSE)
770-
if (both) rows_bottom = rows
771-
772-
while (length(remaining) > 0) {
773-
for (i in seq_len(y_grid - 1)) place_row()
774-
for (i in seq_len(y_grid)) place_row(reverse = TRUE)
775-
place_row()
776-
}
777-
778-
row_y = function(rows, side) (seq_along(rows) - 1) / y_grid * ysize * side
779-
df = data.frame(
780-
x = unlist(rows),
781-
y = rep(row_y(rows, side = if (both) 1 else side), lengths(rows))
782-
)
783-
if (both) {
784-
df = rbind(
785-
df,
786-
data.frame(
787-
x = unlist(rows_bottom[-1]),
788-
y = rep(row_y(rows_bottom, side = -1)[-1], lengths(rows_bottom[-1]))
789-
)
790-
)
791-
}
792-
df = df[order(df$x), ]
793-
df$y = df$y + y
794-
df
795-
}
796-
797-
#' Weave/swarm hybrid
798-
#'
799-
#' @param x sorted x values
800-
#' @param y y values (must be constant)
660+
#' @param x <[numeric]> sorted x values
661+
#' @param x <[numeric]> y values (should be constant)
662+
#' @param xsize <scalar [numeric]> horizontal spacing between dots
663+
#' @param ysize <scalar [numeric]> vertical spacing between dots
664+
#' @param side <scalar [integer]> which side to place dots on: 0 = both, 1 = above, -1 = below
665+
#' @returns <[data.frame]> data frame with columns x and y giving the new positions
801666
#' @noRd
802-
weave_swarm_new = function(x, y, xsize, ysize = xsize, side = 1) {
803-
y_grid = 4
804-
805-
both = side == 0
806-
remaining = x
807-
rows = list()
808-
if (both) rows_bottom = list()
809-
810-
place_row = function(reverse = FALSE, both = side == 0) {
811-
if (length(remaining) == 0) return()
812-
813-
candidates = remaining
814-
if (reverse) candidates = rev(candidates)
815-
816-
row = numeric()
817-
if (both) row_bottom = numeric()
818-
next_remaining = numeric()
819-
last_placed = if (reverse) Inf else -Inf
820-
if (both) last_placed_bottom = last_placed
821-
822-
n_rows_back = min(y_grid, length(rows))
823-
for (candidate in candidates) {
824-
if (can_place_candidate_(candidate, last_placed, rows, n_rows_back, y_grid, xsize, reverse)) {
825-
row = c(row, candidate)
826-
last_placed = candidate
827-
} else if (both && can_place_candidate_(candidate, last_placed_bottom, rows_bottom, n_rows_back, y_grid, xsize, reverse)) {
828-
row_bottom = c(row_bottom, candidate)
829-
last_placed_bottom = candidate
830-
} else {
831-
next_remaining = c(next_remaining, candidate)
832-
}
833-
}
834-
835-
if (reverse) {
836-
row = rev(row)
837-
if (both) row_bottom = rev(row_bottom)
838-
next_remaining = rev(next_remaining)
839-
}
840-
rows <<- c(rows, list(row))
841-
if (both) rows_bottom <<- c(rows_bottom, list(row_bottom))
842-
remaining <<- next_remaining
843-
}
844-
845-
# first row is special when both == TRUE: it is a "middle" row that is
846-
# treated as the first row (for placement purposes) on both the top and bottom sides
847-
place_row(both = FALSE)
848-
if (both) rows_bottom = rows
849-
850-
while (length(remaining) > 0) {
851-
for (i in seq_len(y_grid - 1)) place_row()
852-
for (i in seq_len(y_grid)) place_row(reverse = TRUE)
853-
place_row()
854-
}
855-
856-
row_y = function(rows, side) (seq_along(rows) - 1) / y_grid * ysize * side
857-
print(seq_along(rows) - 1)
858-
df = data.frame(
859-
x = unlist(rows),
860-
y = rep(row_y(rows, side = if (both) 1 else side), lengths(rows))
861-
)
862-
if (both) {
863-
df = rbind(
864-
df,
865-
data.frame(
866-
x = unlist(rows_bottom[-1]),
867-
y = rep(row_y(rows_bottom, side = -1)[-1], lengths(rows_bottom[-1]))
868-
)
869-
)
870-
}
871-
df = df[order(df$x), ]
872-
df$y = df$y + y
873-
df
874-
}
875-
876-
weave_swarm_new2 = function(x, y, xsize, ysize = xsize, side = 1) {
877-
df = weave_swarm_new_(x, xsize, ysize, side)
667+
weave_swarm = function(x, y, xsize, ysize = xsize, side = 1) {
668+
df = weave_swarm_(x, xsize, ysize, side)
878669
df = df[order(df$x), ]
879670
df$y = df$y + y
880671
df
881672
}
882673

883-
weave_swarm = weave_swarm_new2
884674

885675
# bin nudging for overlaps ------------------------------------------------
886676

src/RcppExports.cpp

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -21,40 +21,23 @@ BEGIN_RCPP
2121
return rcpp_result_gen;
2222
END_RCPP
2323
}
24-
// can_place_candidate_
25-
bool can_place_candidate_(const double candidate, const double last_placed, std::vector<std::vector<double>>& rows, const int n_rows_back, const int y_grid, const double xsize, const bool reverse);
26-
RcppExport SEXP _ggdist_can_place_candidate_(SEXP candidateSEXP, SEXP last_placedSEXP, SEXP rowsSEXP, SEXP n_rows_backSEXP, SEXP y_gridSEXP, SEXP xsizeSEXP, SEXP reverseSEXP) {
27-
BEGIN_RCPP
28-
Rcpp::RObject rcpp_result_gen;
29-
Rcpp::traits::input_parameter< const double >::type candidate(candidateSEXP);
30-
Rcpp::traits::input_parameter< const double >::type last_placed(last_placedSEXP);
31-
Rcpp::traits::input_parameter< std::vector<std::vector<double>>& >::type rows(rowsSEXP);
32-
Rcpp::traits::input_parameter< const int >::type n_rows_back(n_rows_backSEXP);
33-
Rcpp::traits::input_parameter< const int >::type y_grid(y_gridSEXP);
34-
Rcpp::traits::input_parameter< const double >::type xsize(xsizeSEXP);
35-
Rcpp::traits::input_parameter< const bool >::type reverse(reverseSEXP);
36-
rcpp_result_gen = Rcpp::wrap(can_place_candidate_(candidate, last_placed, rows, n_rows_back, y_grid, xsize, reverse));
37-
return rcpp_result_gen;
38-
END_RCPP
39-
}
40-
// weave_swarm_new_
41-
SEXP weave_swarm_new_(std::vector<double> x, const double xsize, const double ysize, const int side);
42-
RcppExport SEXP _ggdist_weave_swarm_new_(SEXP xSEXP, SEXP xsizeSEXP, SEXP ysizeSEXP, SEXP sideSEXP) {
24+
// weave_swarm_
25+
SEXP weave_swarm_(std::vector<double> x, const double xsize, const double ysize, const int side);
26+
RcppExport SEXP _ggdist_weave_swarm_(SEXP xSEXP, SEXP xsizeSEXP, SEXP ysizeSEXP, SEXP sideSEXP) {
4327
BEGIN_RCPP
4428
Rcpp::RObject rcpp_result_gen;
4529
Rcpp::traits::input_parameter< std::vector<double> >::type x(xSEXP);
4630
Rcpp::traits::input_parameter< const double >::type xsize(xsizeSEXP);
4731
Rcpp::traits::input_parameter< const double >::type ysize(ysizeSEXP);
4832
Rcpp::traits::input_parameter< const int >::type side(sideSEXP);
49-
rcpp_result_gen = Rcpp::wrap(weave_swarm_new_(x, xsize, ysize, side));
33+
rcpp_result_gen = Rcpp::wrap(weave_swarm_(x, xsize, ysize, side));
5034
return rcpp_result_gen;
5135
END_RCPP
5236
}
5337

5438
static const R_CallMethodDef CallEntries[] = {
5539
{"_ggdist_wilkinson_bin_to_right_", (DL_FUNC) &_ggdist_wilkinson_bin_to_right_, 2},
56-
{"_ggdist_can_place_candidate_", (DL_FUNC) &_ggdist_can_place_candidate_, 7},
57-
{"_ggdist_weave_swarm_new_", (DL_FUNC) &_ggdist_weave_swarm_new_, 4},
40+
{"_ggdist_weave_swarm_", (DL_FUNC) &_ggdist_weave_swarm_, 4},
5841
{NULL, NULL, 0}
5942
};
6043

src/bin_dots.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,7 @@ IntegerVector wilkinson_bin_to_right_(const NumericVector& x, double width) {
4343
//' @param reverse <scalar [logical]> are we placing dots in reverse order?
4444
//' @returns <scalar [logical]> can we place candidate here?
4545
//' @noRd
46-
// [[Rcpp::export(rng = false)]]
47-
bool can_place_candidate_(
46+
bool can_place_candidate(
4847
const double candidate,
4948
const double last_placed,
5049
std::vector<std::vector<double>>& rows,
@@ -104,7 +103,7 @@ bool can_place_candidate_(
104103
//' @returns <[data.frame]> data frame with columns x and y giving the new positions
105104
//' @noRd
106105
// [[Rcpp::export(rng = false)]]
107-
SEXP weave_swarm_new_(
106+
SEXP weave_swarm_(
108107
std::vector<double> x,
109108
const double xsize,
110109
const double ysize,
@@ -150,10 +149,10 @@ SEXP weave_swarm_new_(
150149
}
151150
for (; i != end_index; i += increment) {
152151
double candidate = (*remaining)[i];
153-
if (can_place_candidate_(candidate, last_placed, rows, n_rows_back, y_grid, xsize, reverse)) {
152+
if (can_place_candidate(candidate, last_placed, rows, n_rows_back, y_grid, xsize, reverse)) {
154153
row->push_back(candidate);
155154
last_placed = candidate;
156-
} else if (both && can_place_candidate_(candidate, last_placed_bottom, rows_bottom, n_rows_back, y_grid, xsize, reverse)) {
155+
} else if (both && can_place_candidate(candidate, last_placed_bottom, rows_bottom, n_rows_back, y_grid, xsize, reverse)) {
157156
row_bottom->push_back(candidate);
158157
last_placed_bottom = candidate;
159158
} else {

0 commit comments

Comments
 (0)