Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export(baConTree)
export(fit_vlmc)
export(metropolis_vlmc)
export(rvlmc)
export(treeFromContexts)
importFrom(Brobdingnag,as.brob)
importFrom(Brobdingnag,cbrob)
importFrom(R6,R6Class)
Expand Down
6 changes: 6 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## New features

* `treeFromContexts()` has been removed. Instead, `ContextTree` now exposes an
`$activateFromContexts(contexts)` method that activates a specific tree on an
existing `ContextTree` object. It accepts the same input format as the old
function (a character vector of context paths, or a single brace-enclosed
comma-separated string).

* `baConTree` nodes now store `priorBranchingProbability` and
`posteriorBranchingProbability` in their `extra` list. These are computed
during initialisation as `prod(children sigmaPrior) / sigmaPrior` (and the
Expand Down
45 changes: 45 additions & 0 deletions R/ContextTree.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#'
#' @importFrom purrr map_chr map_lgl map map_int
#' @importFrom glue glue
#' @importFrom stringr str_split str_replace_all str_count
#' @export
ContextTree <- R6Class(
"ContextTree",
Expand Down Expand Up @@ -178,6 +179,50 @@ ContextTree <- R6Class(
})])
},

#' @description
#' Sets the active tree to match a specified set of contexts, given as a
#' character vector or a brace-enclosed comma-separated string. The contexts
#' must be compatible with the tree's existing alphabet and maximal depth.
#' @param contexts Character vector or string. A vector of context paths
#' (e.g., \code{c("*.a", "*.b.a", "*.b.b")}) or a single brace-enclosed
#' string (e.g., \code{"\{*.a, *.b.a, *.b.b\}"}).
activateFromContexts = function(contexts) {
if (length(contexts) == 1) {
raw <- str_replace_all(contexts, "\\{|\\}", "")
parts <- str_split(string = raw, pattern = ",")[[1]]
contexts <- trimws(parts)
contexts <- contexts[nzchar(contexts)]
}

if (!validate_tree_string(contexts)) {
stop("Contexts do not correspond to a full tree.")
}

context_alphabet <- setdiff(unique(unlist(str_split(contexts, "\\."))), "*")
if (!all(context_alphabet %in% private$Alphabet$symbols)) {
stop("Contexts use symbols not in the tree's alphabet.")
}

max_depth <- max(str_count(contexts, "\\."))
if (max_depth > private$maximalDepth) {
stop("Contexts require a greater depth than the tree's maximal depth.")
}

self$activateRoot()
current_depth <- 0
while (length(setdiff(self$getActiveNodes(idx = TRUE), contexts)) > 0) {
subcontexts <- substr(contexts, start = 1, stop = current_depth * 2 + 1)
for (sc in unique(subcontexts)) {
if (!sc %in% contexts) {
self$growActive(sc)
}
}
current_depth <- current_depth + 1
}

invisible(self)
},

#' @return Returns the leaf nodes of the maximal Context Tree (regardless of
#' the current active tree).
getLeaves = function(idx = TRUE) {
Expand Down
47 changes: 0 additions & 47 deletions R/treeFromContexts.R

This file was deleted.

27 changes: 16 additions & 11 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@ the order of dependence can vary with the observed past. `bacontrees` provides:
- A **Bayesian** method: `metropolis_vlmc()` (and the `baConTree` class) runs a
Metropolis-Hastings MCMC sampler to obtain a full posterior distribution over
context trees.
- Simulation utilities (`rvlmc()`) and construction helpers
(`treeFromContexts()`).
- Simulation utilities (`rvlmc()`).
- R6 classes (`ContextTree`, `baConTree`) that expose the full tree structure
for building custom algorithms.

Expand Down Expand Up @@ -101,15 +100,17 @@ head(seq1, 20)

### Building a context tree manually

`treeFromContexts()` creates a `ContextTree` whose active nodes exactly match a
supplied set of contexts.
`ContextTree$activateFromContexts()` sets the active nodes of an existing tree
to match a supplied set of contexts.

```{r treeFromContexts}
ct <- treeFromContexts(c("*.a", "*.b", "*.c.a", "*.c.b", "*.c.c"))
ct$getActiveNodes()
```{r activateFromContexts}
tree <- ContextTree$new(alphabet = c("a", "b", "c"), maximalDepth = 2)
tree$activateFromContexts(c("*.a", "*.b", "*.c.a", "*.c.b", "*.c.c"))
tree$getActiveNodes()
```

You can also create a `ContextTree` directly and manipulate it:
You can also use `$activateMaximal()` or `$activateRoot()` to switch between
the deepest and shallowest trees:

```{r ContextTree}
tree <- ContextTree$new(abc_list, maximalDepth = 3)
Expand Down Expand Up @@ -151,7 +152,7 @@ with_progress({
n_steps = 2000,
max_depth = 3,
alpha = 0.01,
context_weights = function(node) -node$getDepth() / 3,
context_weights = function(node) exp(-node$getDepth() / 3),
burnin = 200
)
})
Expand All @@ -174,7 +175,7 @@ For more control, use the `baConTree` R6 class directly.

```{r baConTree}
bt <- baConTree$new(abc_list, maximalDepth = 3, alpha = 0.01,
priorWeights = function(node) -node$getDepth() / 3)
priorWeights = function(node) exp(-node$getDepth() / 3))

with_progress(bt$runMetropolisHastings(2000))

Expand All @@ -198,6 +199,7 @@ The core data structure. Manages the maximal suffix tree, tracks which nodes are
| `$activateRoot()` | Set active tree to root-only |
| `$activateMaximal()` | Set active tree to all maximal leaves |
| `$activateByCode(code)` | Restore a previously stored tree code |
| `$activateFromContexts(contexts)` | Set active tree to match a context vector or string |
| `$growActive(path)` | Grow the active tree at a given node |
| `$pruneActive(path)` | Prune the active tree at a given node |
| `$setData(dataset)` | Attach sequence data and compute counts |
Expand All @@ -213,7 +215,10 @@ Extends `ContextTree` with Bayesian machinery.

| Method | Description |
|--------|-------------|
| `$new(data, maximalDepth, alpha, priorWeights)` | Construct a Bayesian context tree |
| `$new(data, maximalDepth, alpha, priorWeights, initialTree)` | Construct a Bayesian context tree |
| `$runMetropolisHastings(steps)` | Run the MCMC sampler |
| `$getChain()` | Retrieve the sampled chain as a data frame |
| `$activateMap()` | Set active tree to the MAP tree |
| `$sampleTree(type)` | Sample a tree from the prior or posterior |
| `$getMarginalLikelihood(log)` | Return the marginal likelihood of the data |

25 changes: 15 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ past. `bacontrees` provides:
- A **Bayesian** method: `metropolis_vlmc()` (and the `baConTree` class)
runs a Metropolis-Hastings MCMC sampler to obtain a full posterior
distribution over context trees.
- Simulation utilities (`rvlmc()`) and construction helpers
(`treeFromContexts()`).
- Simulation utilities (`rvlmc()`).
- R6 classes (`ContextTree`, `baConTree`) that expose the full tree
structure for building custom algorithms.

Expand Down Expand Up @@ -98,16 +97,18 @@ head(seq1, 20)

### Building a context tree manually

`treeFromContexts()` creates a `ContextTree` whose active nodes exactly
match a supplied set of contexts.
`ContextTree$activateFromContexts()` sets the active nodes of an
existing tree to match a supplied set of contexts.

``` r
ct <- treeFromContexts(c("*.a", "*.b", "*.c.a", "*.c.b", "*.c.c"))
ct$getActiveNodes()
tree <- ContextTree$new(alphabet = c("a", "b", "c"), maximalDepth = 2)
tree$activateFromContexts(c("*.a", "*.b", "*.c.a", "*.c.b", "*.c.c"))
tree$getActiveNodes()
#> [1] "*.c.b" "*.c.c" "*.a" "*.b" "*.c.a"
```

You can also create a `ContextTree` directly and manipulate it:
You can also use `$activateMaximal()` or `$activateRoot()` to switch
between the deepest and shallowest trees:

``` r
tree <- ContextTree$new(abc_list, maximalDepth = 3)
Expand Down Expand Up @@ -158,7 +159,7 @@ with_progress({
n_steps = 2000,
max_depth = 3,
alpha = 0.01,
context_weights = function(node) -node$getDepth() / 3,
context_weights = function(node) exp(-node$getDepth() / 3),
burnin = 200
)
})
Expand Down Expand Up @@ -187,7 +188,7 @@ For more control, use the `baConTree` R6 class directly.

``` r
bt <- baConTree$new(abc_list, maximalDepth = 3, alpha = 0.01,
priorWeights = function(node) -node$getDepth() / 3)
priorWeights = function(node) exp(-node$getDepth() / 3))

with_progress(bt$runMetropolisHastings(2000))

Expand Down Expand Up @@ -219,6 +220,7 @@ attachment.
| `$activateRoot()` | Set active tree to root-only |
| `$activateMaximal()` | Set active tree to all maximal leaves |
| `$activateByCode(code)` | Restore a previously stored tree code |
| `$activateFromContexts(contexts)` | Set active tree to match a context vector or string |
| `$growActive(path)` | Grow the active tree at a given node |
| `$pruneActive(path)` | Prune the active tree at a given node |
| `$setData(dataset)` | Attach sequence data and compute counts |
Expand All @@ -234,6 +236,9 @@ Extends `ContextTree` with Bayesian machinery.

| Method | Description |
|----|----|
| `$new(data, maximalDepth, alpha, priorWeights)` | Construct a Bayesian context tree |
| `$new(data, maximalDepth, alpha, priorWeights, initialTree)` | Construct a Bayesian context tree |
| `$runMetropolisHastings(steps)` | Run the MCMC sampler |
| `$getChain()` | Retrieve the sampled chain as a data frame |
| `$activateMap()` | Set active tree to the MAP tree |
| `$sampleTree(type)` | Sample a tree from the prior or posterior |
| `$getMarginalLikelihood(log)` | Return the marginal likelihood of the data |
22 changes: 22 additions & 0 deletions man/ContextTree.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions man/baConTree.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 0 additions & 22 deletions man/treeFromContexts.Rd

This file was deleted.

Loading
Loading