Skip to content

Commit e8fbec8

Browse files
feat: Implement arrow relations for formal contexts in C++ and expand concept lattice plotting with viewer and theme options.
1 parent f8911fe commit e8fbec8

16 files changed

Lines changed: 846 additions & 186 deletions

NEWS.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
# fcaR 1.7.0
22

3+
New Functionality:
4+
5+
* **Arrow Relations:** Added `calculate_arrow_relations()` method to `FormalContext` to compute the arrow relations ($\swarrow$, $\nearrow$, $\updownarrow$) of a binary formal context using a high-performance C++ implementation based on bitsets.
6+
* **Structural Analysis:** Added new methods to `FormalContext` for advanced structural analysis based on arrow relations:
7+
* `is_distributive()`: Efficiently check if the concept lattice is distributive without computing it.
8+
* `get_irreducible_objects()` / `get_irreducible_attributes()`: Identify the core elements needed to reconstruct the lattice.
9+
* `get_core()`: Extract the smallest context that generates the same lattice.
10+
* **Optimized Reduction:** Added `reduce_arrows()` to `FormalContext`. This method clarifies and reduces a context using arrow relations, which is significantly faster than traditional methods for large contexts.
11+
* **Lattice Plotting Enhancements:**
12+
* **Grade Balancing:** New `balance_grades` algorithm to improve visual symmetry in Hasse diagrams (e.g., for $N_5$).
13+
* **Base R Viewer:** Added `viewer = "base"` to `plot()`, providing a lightweight alternative to `ggraph` with support for themes (`"standard"`, `"nord"`, `"vibrant"`, `"latex"`).
14+
* **Vertical Alignment:** Sugiyama layout now correctly aligns single-node chains vertically.
15+
16+
Improvements:
17+
18+
* **Refactored `standardize()` and `reduce()`**: These methods now use `reduce_arrows()` internally, removing the dependency on pre-calculating the concept lattice and improving performance while preserving original labels.
19+
* **C++ Layout Engine**: Updated `calculate_lattice_layout_rcpp` to support numeric (decimal) Y coordinates for smooth vertical positioning.
20+
* **Internal helpers:** Added `.print_arrows()` to handle symbol mapping for both CLI (Unicode) and LaTeX output.
21+
* **Expanded Documentation:** Updated the `lattice_properties` vignette with a detailed section on arrow relations.
22+
* **Enhanced Testing:** Added `test-arrow_relations.R` and `test-arrow_advanced.R` with comprehensive unit tests.
23+
324
# fcaR 1.6.0
425

526
New Functionality:

R/RcppExports.R

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,19 @@ bonds_mcis_cpp <- function(extents, intents, verbose = FALSE) {
8585
.Call(`_fcaR_bonds_mcis_cpp`, extents, intents, verbose)
8686
}
8787

88+
#' @title compute_arrow_relations_cpp
89+
#' @description Computes the arrow relations (swarrow, nearrow, and double arrow)
90+
#' for a binary formal context.
91+
#' @param I (IntegerMatrix) The binary incidence matrix of the formal context.
92+
#' @return An IntegerMatrix where:
93+
#' - 1: \swarrow
94+
#' - 2: \nearrow
95+
#' - 3: \updownarrow
96+
#' @noRd
97+
compute_arrow_relations_cpp <- function(I) {
98+
.Call(`_fcaR_compute_arrow_relations_cpp`, I)
99+
}
100+
88101
print_matrix <- function(I) {
89102
invisible(.Call(`_fcaR_print_matrix`, I))
90103
}
@@ -177,8 +190,8 @@ calculate_grades_rcpp <- function(concept_ids, edge_from, edge_to) {
177190
.Call(`_fcaR_calculate_grades_rcpp`, concept_ids, edge_from, edge_to)
178191
}
179192

180-
calculate_lattice_layout_rcpp <- function(concept_ids, grades, edge_from, edge_to, method) {
181-
.Call(`_fcaR_calculate_lattice_layout_rcpp`, concept_ids, grades, edge_from, edge_to, method)
193+
calculate_lattice_layout_rcpp <- function(concept_ids, layers_vec, y_coords_vec, edge_from, edge_to, method) {
194+
.Call(`_fcaR_calculate_lattice_layout_rcpp`, concept_ids, layers_vec, y_coords_vec, edge_from, edge_to, method)
182195
}
183196

184197
binary_lincbo_implications <- function(I, save_concepts = FALSE, verbose = FALSE) {

R/concept_lattice.R

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,24 @@ ConceptLattice <- R6::R6Class(
7474
#' \item \code{"attributes"}: Nodes show only their intent (attributes).
7575
#' \item \code{"empty"}: Nodes are drawn as points without labels. Recommended for very large lattices (>50 concepts).
7676
#' }
77-
#' @param ... Other parameters passed to the internal plotting function (e.g., graphical parameters for \code{ggraph}).
77+
#' @param viewer (character) The viewer to use for plotting. Options are:
78+
#' \itemize{
79+
#' \item \code{"ggraph"} (default): Use \code{ggraph} for drawing.
80+
#' \item \code{"base"}: Use R base graphics. This is a lightweight alternative that supports themes.
81+
#' }
82+
#' @param theme (character) The color theme to use for the \code{"base"} viewer. Options are: \code{"standard"}, \code{"nord"}, \code{"latex"}, \code{"vibrant"}.
83+
#' @param ... Other parameters passed to the internal plotting function (e.g., graphical parameters for \code{ggraph} or \code{base}).
7884
#'
79-
#' @return If \code{to_latex} is \code{FALSE}, it returns (invisibly) the \code{ggplot2} object representing the graph.
85+
#' @return If \code{to_latex} is \code{FALSE}, it returns (invisibly) the \code{ggplot2} object representing the graph (for \code{ggraph}) or \code{NULL} (for \code{base}).
8086
#' If \code{to_latex} is \code{TRUE}, it returns a \code{tikz_code} object containing the LaTeX code.
8187
#' @export
8288
plot = function(
8389
object_names = TRUE,
8490
to_latex = FALSE,
8591
method = c("sugiyama", "force"),
8692
mode = NULL,
93+
viewer = c("ggraph", "base"),
94+
theme = "standard",
8795
...
8896
) {
8997
# 1. Verificación de estado
@@ -111,6 +119,7 @@ ConceptLattice <- R6::R6Class(
111119
# 3. Delegación a lattice_plot
112120
# Pasamos los datos privados necesarios (matriz, objetos, atributos)
113121
method <- match.arg(method)
122+
viewer <- match.arg(viewer)
114123
lattice_plot(
115124
nodes_df = nodes_df,
116125
cover_matrix = private$covering_matrix,
@@ -125,6 +134,8 @@ ConceptLattice <- R6::R6Class(
125134
intents = intents_list,
126135
object_names = self$objects,
127136
to_latex = to_latex,
137+
viewer = viewer,
138+
theme = theme,
128139
...
129140
)
130141
},

0 commit comments

Comments
 (0)