## ----include = FALSE---------------------------------------------------------- knitr::opts_chunk$set( collapse = TRUE, comment = "#>" ) ## ----setup-------------------------------------------------------------------- library(dist.structure) ## ----------------------------------------------------------------------------- alarm_dist <- function(k, sensor_components, master_component) { m_sensors <- length(sensor_components) stopifnot(k >= 1L, k <= m_sensors, inherits(master_component, "dist"), all(vapply(sensor_components, function(d) inherits(d, "dist"), logical(1L)))) structure( list( k = as.integer(k), m_sensors = as.integer(m_sensors), m = as.integer(m_sensors + 1L), components = c(sensor_components, list(master_component)) ), class = c("alarm_dist", "dist_structure", "univariate_dist", "continuous_dist", "dist") ) } ## ----------------------------------------------------------------------------- ncomponents.alarm_dist <- function(x) x$m component.alarm_dist <- function(x, j, ...) { stopifnot(j >= 1L, j <= x$m) x$components[[j]] } phi.alarm_dist <- function(x, state) { stopifnot(length(state) == x$m) sensor_state <- state[seq_len(x$m_sensors)] master_state <- state[x$m] as.integer(sum(sensor_state) >= x$k && master_state == 1L) } ## ----------------------------------------------------------------------------- sensors <- replicate(4, algebraic.dist::exponential(0.5), simplify = FALSE) master <- algebraic.dist::exponential(0.1) # master is most reliable alarm <- alarm_dist(k = 2L, sensors, master) validate_dist_structure(alarm) ## ----------------------------------------------------------------------------- # Number of components ncomponents(alarm) # Structure function evaluation phi(alarm, c(1, 1, 0, 0, 1)) # 2 sensors + master alive: alarms phi(alarm, c(1, 1, 1, 1, 0)) # all sensors but no master: silent # Minimal cut sets (derived from phi via the Berge transversal) min_cuts(alarm) # Critical states for component j critical_states(alarm, 5L) # the master: critical in every state where >= k sensors are alive # Reliability at uniform component reliability p reliability(alarm, 0.9) # Distribution algebra: system survival via component composition S <- algebraic.dist::surv(alarm) S(c(1, 5, 10)) # Sampling: m independent component lifetimes, combined via system_lifetime withr::with_seed(1, { x <- algebraic.dist::sampler(alarm)(1000) mean(x) }) ## ----------------------------------------------------------------------------- parallel_of_master_and_sensors <- function(sensor_components, master_component) { components <- c(sensor_components, list(master_component)) m <- length(components) obj <- coherent_dist( min_paths = list(seq_len(m - 1L), m), # all sensors as one path; master as another components = components, m = m ) class(obj) <- c("master_or_sensors_dist", class(obj)) obj }