Nothing
########################
### Generalized Sets ###
########################
## The gset class extends 'ordinary' sets by allowing
## membership values for each element. Strictly speaking,
## a generalized set is a pair (A, mu) with support A and
## membership function mu, where mu is a mapping from
## A into 2 ^ ([0, 1] -> N). Special cases are:
## mu : A -> {0, 1} ("ordinary sets")
## mu : A -> [0, 1] ("fuzzy sets")
## mu : A -> 2 ^ {0, 1} ("multi sets")
### Basic stuff (constructors, print/summary methods)
## * gset generator
gset <-
function(support = NULL, memberships = NULL, charfun = NULL,
elements = NULL, universe = NULL, bound = NULL,
assume_numeric_memberships = TRUE)
{
Universe <- universe
if(is.null(universe))
universe <- sets_options("universe")
### some checks
if (!is.null(elements) &&
!(is.null(support) && is.null(memberships) && is.null(charfun)))
stop("'elements' needs to be specified alone.")
if (is.null(support) && !is.null(memberships))
stop("'membership' requires 'support'.")
if (is.null(universe) && !is.null(charfun))
stop("'charfun' requires 'universe' (or a default universe).")
if (!is.null(memberships) && !is.null(charfun))
stop("Need either 'memberships' and 'support', or 'charfun' and 'universe'.")
### element specification:
## split support and memberships, and proceed
if (!is.null(elements)) {
support <- unlist(elements, recursive = FALSE)
memberships <- sapply(elements, .get_memberships)
}
### universe & charfun specification:
## create memberships from charfun, and proceed
## In general, create list of memberships (i.e., fuzzy multisets)
## but assume numeric memberships if specified (and by default)
if (!is.null(universe))
universe <- if (is.interval(universe))
as.set(as.numeric(universe))
else
as.set(eval(universe))
if (!is.null(charfun)) {
if (is.charfun_generator(charfun))
charfun <- charfun()
memberships <- if (assume_numeric_memberships) {
if (.domain_is_numeric(universe))
charfun(unlist(universe))
else
vapply(universe, charfun, double(1L))
} else
lapply(universe, charfun)
support <- universe
.stop_if_memberships_are_invalid(memberships,
"Membership function invalid.\n ")
}
## handle empty set
if (is.null(support))
return(set())
### support & membership specification:
## just check memberships
if (!is.null(memberships))
.stop_if_memberships_are_invalid(memberships)
## check support against universe
if (!is.null(universe) && !set_is_subset(as.set(support), universe))
stop("Support must be a subset of the universe.")
### canonicalize memberships & create gset
.make_gset_from_support_and_memberships(support, memberships, Universe,
bound)
}
print.gset <-
function(x, ...)
{
writeLines(strwrap(format(x, ...), exdent = 1L))
invisible(x)
}
summary.gset <-
function(object, ...)
{
len <- gset_cardinality(object)
if (na <- is.na(len))
len <- length.set(object)
out <- if (len == 0L)
gettext("The empty set.")
else if (len == 1L)
gettext("A generalized set with 1 element.")
else if (na)
gettextf("A generalized set with %g elements.", len)
else
gettextf("A generalized set with cardinality %g.", len)
.structure(out, class = "summary.gset")
}
print.summary.gset <-
function(x, ...)
{
writeLines(x)
invisible(x)
}
format.gset <-
function(x, ...) {
x <- if (isTRUE(gset_is_set(x)))
.as.list(x)
else
.make_list_of_elements_from_cset(x)
.format_set_or_tuple(x, "{", "}", ...)
}
### operators
## Disable numeric subscripting (as sets are "unordered" collections of
## elements). Note that iterating via for() and lapply() still works,
## the former because this [currently, 2007-09-16] directly uses the
## internal list representation and the latter because we provide an
## as.list() method.
`[.gset` <-
function(x, i = x)
{
ind <- .lookup_elements(x, i)
gset(.as.list(x)[ind], gset_memberships(x)[ind])
}
`[[.gset` <-
function(x, i)
{
as.set(x)[[i]]
}
`[<-.gset` <-
function(x, i = x, value)
{
gset(`[<-`(.as.list(x), .lookup_elements(x, i), value),
memberships = gset_memberships(x))
}
`[[<-.gset` <-
function(x, i, value)
{
if (!is.character(i) || length(i) > 1L) i <- list(i)
if (length(lookup <- .lookup_elements(x, i)) < 1L) return(NULL)
gset(`[[<-`(.as.list(x), lookup, value),
memberships = gset_memberships(x))
}
Ops_gset <-
function(e1, e2, .Generic, .Class)
{
if (missing(e2) == 1L) {
if(!(as.character(.Generic) %in% "!"))
stop(gettextf("Unary '%s' not defined for \"%s\" objects.",
.Generic, .Class),
domain = NA)
return(gset_complement(e1))
}
if(!(as.character(.Generic)
%in% c("<", "<=", ">", ">=", "==", "!=",
"&", "|", "*", "+", "-", "^")))
stop(gettextf("Generic '%s' not defined for \"%s\" objects.",
.Generic, .Class),
domain = NA)
if(as.character(.Generic) == "^") {
if(is.gset(e1) &&
((trunc(e2) != e2) || (e2 < 1L)))
stop("Cartesian product only defined for positive integers.")
if(is.gset(e2) && (e1 != 2L))
stop("Operator not defined.")
}
switch(.Generic,
"+" = gset_sum(e1, e2),
"|" = gset_union(e1, e2),
"-" = gset_difference(e1, e2),
"&" = gset_intersection(e1, e2),
"*" = gset_cartesian(e1, e2),
"<" = gset_is_proper_subset(e1, e2),
"<=" = gset_is_subset(e1, e2),
">" = gset_is_proper_subset(e2, e1),
">=" = gset_is_subset(e2, e1),
"==" = gset_is_equal(e1, e2),
"!=" = !gset_is_equal(e1, e2),
"^" = {
if(is.gset(e2))
gset_power(e2)
else
do.call(gset_cartesian, rep.int(list(e1), e2))}
)
}
### internal stuff
.make_gset_from_list <-
function(list)
.structure(list, class = c("gset", "cset"))
.make_gset_from_support_and_memberships <-
function(support, memberships, universe = NULL, bound = NULL)
{
## simplify memberships:
if (!is.null(memberships)) {
## canonicalize (i.e., make sure that fuzzy multiset memberships
## are valid gset objects)
memberships <- .canonicalize_memberships(memberships)
## check length
if (length.set(memberships) != length.set(support))
stop("Length of support must match length of memberships.")
## for fuzzy multisets, remove elements in membership with
## zero support
if (is.list(memberships)) {
# find zero elements in list
z <- lapply(memberships,
function(i) sapply(i, `>`, 0) | sapply(i, is.na))
# empty sets should have length 0
z <- lapply(z, function(i) if (is.list(i)) 0 else i)
# filter 0 elements
memberships <-
Map(.make_gset_by_support_and_memberships,
Map("[", lapply(memberships, .as.list), z),
Map("[", lapply(memberships, gset_memberships), z))
}
## compute index of entries with 0 memberships.
z <- if (is.list(memberships))
sapply(memberships, gset_cardinality) == 0
else
memberships == 0
## all zero? return empty set.
if (!any(is.na(z)) && all(z)) return(set())
## remove entries with zero membership.
if (any(z, na.rm = TRUE)) {
support <- .as.list(support)[-which(z)]
memberships <- memberships[-which(z)]
}
}
## if gset has no or trivial membership:
if (is.null(memberships) || is.atomic(memberships) &&
!any(is.na(memberships)) && all(memberships == 1, na.rm = TRUE)) {
support <- .list_sort(.as.list(support))
## if a universe exists, return gset
if (!is.null(universe))
return(.make_gset_by_support_and_memberships(support = support,
memberships = NULL,
universe = universe))
else
return(.make_set_from_list(support))
}
## if gset has fuzzy multiset representation, but
## is really only multi or fuzzy, simplify memberships.
if (is.list(memberships)) {
tmp <- lapply(memberships, .as.list)
if (all(lengths(tmp) == 1L)) {
M <- unlist(memberships)
if (!any(is.na(M)) && all(M == 1L))
memberships <- sapply(memberships, .get_memberships)
else {
M <- sapply(memberships, .get_memberships)
if (!any(is.na(M)) && all(M == 1L))
memberships <- unlist(memberships)
}
}
}
## check memberships against bound, if any.
bd <- bound
if (is.null(bd))
bd <- sets_options("bound")
if (!is.null(bd) && (max(.multiplicities(memberships), na.rm = TRUE) > bd))
stop("Memberships must not exceed bound!")
## convert support to set. Reorder memberships accordingly, if needed.
S <- canonicalize_set_and_mapping(x = support, mapping = memberships)
## return gset.
.make_gset_by_support_and_memberships(support = S$set,
memberships = S$mapping,
universe = universe,
bound = bound)
}
.make_gset_by_support_and_memberships <-
function(support, memberships, universe = NULL, bound = NULL)
{
if (is.null(universe) && (is.null(memberships) ||
is.atomic(memberships) && !any(is.na(memberships)) &&
all(memberships == 1, na.rm = TRUE)))
.make_set_from_list(support)
else
.structure(support,
memberships = memberships,
universe = universe,
bound = bound,
class = c("gset", "cset"))
}
.stop_if_memberships_are_invalid <-
function(memberships, errmsg = NULL)
{
if (is.list(memberships)) {
for (i in memberships) {
if (is.gset(i)) {
if (!gset_is_crisp(i, na.rm = TRUE))
stop("For fuzzy multisets, the memberships must be (multi)sets.",
call. = FALSE)
if (!all(sapply(i,
function(j) (is.na(j) || is.numeric(j)) && (j >= 0) && (j <= 1)), na.rm = TRUE))
stop("For fuzzy multisets, the memberships must be multisets over the unit interval.", call. = FALSE)
}
}
} else {
if (any(memberships < 0, na.rm = TRUE))
stop(paste0(errmsg,
"Memberships must be positive."), call. = FALSE)
if (any(memberships > 1, na.rm = TRUE) && any(memberships != trunc(memberships), na.rm = TRUE))
stop(paste0(errmsg,
"Memberships must be either all integer (multisets),\n or all in the unit interval (fuzzy sets)."), call. = FALSE)
}
}
.apply_connector_to_list_of_gsets_and_support <-
function(l, support, connector, matchfun = .exact_match,
enforce_general_case = FALSE)
{
## extract memberships according to support
m <- lapply(l, .memberships_for_support, support, matchfun)
## apply connector to memberships
if (!enforce_general_case && !any(sapply(l, gset_is_fuzzy_multiset)))
## for multisets and fuzzy sets, just use normalized memberships
Reduce(connector, m)
else {
## in all other cases, expand memberships first:
## determine max. membership cardinality
is_list <- sapply(m, is.list)
FUN <- function(i) if (all(is.na(i))) 0 else max(i, na.rm = TRUE)
mlen <- max(if (any(is_list)) sapply(m[is_list], sapply,
gset_cardinality),
if (any(!is_list)) sapply(m[!is_list], FUN),
na.rm = TRUE)
## group by support, expand memberships, and apply connector
lapply(seq_along(support), function(i) {
Reduce(connector,
lapply(m, function(j) .expand_membership(j[[i]],
len = mlen)))
})
}
}
.make_gset_from_list_of_gsets_and_support_and_connector <-
function(l, support, connector, matchfun = .exact_match,
enforce_general_case = FALSE)
{
## compute memberships
memberships <-
.apply_connector_to_list_of_gsets_and_support(l, support, connector,
matchfun,
enforce_general_case)
## create resulting gset
.make_gset_from_support_and_memberships(support, memberships)
}
.make_list_of_elements_from_cset <-
function(x)
Map(.make_element_from_support_and_memberships,
.as.list(x),
.as.list(.get_memberships(x)))
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.