make_domain: Creates a list of elements that defines the domain for a...

View source: R/domain.R

make_domainR Documentation

Creates a list of elements that defines the domain for a multivariate distribution.

Description

Creates a list of elements that define the domain for a multivariate distribution.

Usage

make_domain(type, p, lefts = NULL, rights = NULL, ineqs = NULL, rule = NULL)

Arguments

type

A string, the domain type. Currently support "R", "R+", "uniform", "polynomial", "simplex". See details.

p

An integer, the dimension of the domain.

lefts

Optional, required if type == "uniform" and must have the same length as rights. A non-empty vector of numbers (may contain -Inf), the left endpoints of a domain defined as a union of intervals. It is required that lefts[i] <= rights[i] <= lefts[j] for any i < j.

rights

Optional, required if type == "uniform" and must have the same length as lefts. A non-empty vector of numbers (may contain Inf), the right endpoints of a domain defined as a union of intervals. It is required that lefts[i] <= rights[i] <= lefts[j] for any i < j.

ineqs

Optional, required if type == "polynomial". A list of lists, each sublist representing an inequality that defines the domain. Each sublist must contain fields abs (logical) and nonnegative (logical), and in addition either a single expression (string), or all of the following: uniform (logical), larger (logical), power_numers (1 or p integers), power_denoms (1 or p integers), const (a number), coeffs (1 or p numbers).

rule

Optional, required if type == "polynomial" && length(ineqs) > 1. A string containing inequality numbers, spaces, parentheses, '&' and '|' only. Used to indicate the logic operation on how to combine the domains defined by each inequality, i.e. "(1 & 2 && 3) || 4 | 5". Chained operations not separated by parentheses are only allowed for the same type of operation ('&'/'|'), i.e. "1 & 2 | 3" is not allowed; it should be either "(1 & 2) | 3" or "1 & (2 | 3)".

Details

The following types of domains are supported:

"R"

The entire p-dimensional real space. Equivalent to "uniform" type with lefts=-Inf and rights=Inf.

"R+"

The non-negative orthant of the p-dimensional real space. Equivalent to "uniform" type with lefts=0 and rights=Inf.

"uniform"

A union of finitely many disjoint intervals as a uniform domain for all components. The left endpoints should be specified through lefts and the right endpoints through rights. The intervals must be disjoint and strictly increasing, i.e. lefts[i] <= rights[i] <= lefts[j] for any i < j. E.g. lefts=c(0, 10) and rights=c(5, Inf) represents the domain ([0,5]v[10,+Inf])^p.

"simplex"

The standard p-1-simplex with all components positive and sum to 1, i.e. sum(x) == 1 and x > 0.

"polynomial"

A finite intersection/union of domains defined by comparing a constant to a polynomial with at most one term in each component and no interaction terms (e.g. x1^3+x1^2>1 or x1*x2>1 not supported). The following is supported: {x1^2 + 2*x2^(3/2) > 1} && ({3.14*x1 - 0.7*x3^3 < 1} || {-exp(3*x2) + 3.7*log(x3) + 2.4*x4^(-3/2)}).

To specify a polynomial-type domain, one should define the ineqs, and in case of more than one inequality, the logical rule to combine the domains defined by each inequality.

rule

A logical rule in infix notation, e.g. "(1 && 2 && 3) || (4 && 5) || 6", where the numbers represent the inequality numbers starting from 1. "&&" and "&" are not differentiated, and similarly for "||" and "|". Chained operations are only allowed for the same operation ("&" or "|"), so instead of "1 && 2 || 3" one should write either "(1 && 2) || 3" or "1 && (2 || 3)" to avoid ambiguity.

ineqs

A list of lists, each sublist represents one inequality, and must contain the following fields:

abs

A logical, indicates whether one should evaluate the polynomial in abs(x) instead of x (e.g. "sum(x) > 1" with abs == TRUE is interpreted as sum(abs(x)) > 1).

nonnegative

A logical, indicates whether the domain of this inequality should be restricted to the non-negative orthant.

In addition, one must in addition specify either a single string "expression" (highly recommended, detailed below), or all of the following fields (discouraged usage):

uniform

A logical, indicates whether the inequality should be uniformly applied to all components (e.g. "x>1" -> "x1>1 && ... && xp>1").

larger

A logical, indicates whether the polynomial should be larger or smaller than the constant (e.g. TRUE for x1 + ... + xp > C, and FALSE for x1 + ... + xp < C).

const

A number, the constant the polynomial should be compared to (e.g. 2.3 for x1 + ... + xp > 2.3).

power_numers

A single integer or a vector of p integers. x[i] will be raised to the power of power_numers[i] / power_denoms[i] (or without subscript if a singer integer). Note that x^(0/0) is interpreted as log(x), and x^(n/0) as exp(n*x) for n non-zero. For a negative x, x^(a/b) is defined as (-1)^a*|x|^(a/b) if b is odd, or NaN otherwise. (Example: c(2,3,5,0,-2) for x1^2+2*x2^(3/2)+3*x3^(5/3)+4*log(x4)+5*exp(-2*x)>1).

power_denoms

A single integer or a vector of p integers. (Example: c(1,2,3,0,0) for x1^2+2*x2^(3/2)+3*x3^(5/3)+4*log(x4)+5*exp(-2*x)>1).

coeffs

Required if uniform == FALSE. A vector of p doubles, where coeffs[i] is the coefficient on x[i] in the inequality.

The user is recommended to use a single expression for ease and to avoid potential errors. The user may safely skip the explanations and directly look at the examples to get a better understanding.

The expression should have the form "POLYNOMIAL SIGN CONST", where "SIGN" is one of "<", "<=", ">", ">=", and "CONST" is a single number (scientific notation allowed).

"POLYNOMIAL" must be (1) a single term (see below) in "x" with no coefficient (e.g. "x^(2/3)", "exp(3x)"), or (2) such a term surrounded by "sum()" (e.g. "sum(x^(2/3))", "sum(exp(3x))"), or (3) a sum of such terms in "x1" through "xp" (one term max for each component) with or without coefficients, separated by the plus or the minus sign (e.g.
"2.3x1^(2/3)-3.4exp(x2)+x3^(-3/5)").

For (1) and (2), the term must be in one of the following forms: "x", "x^2", "x^(-2)", "x^(2/3)", "x^(-2/3)", "log(x)", "exp(x)", "exp(2x)", "exp(2*x)", "exp(-3x)", where the 2 and 3 can be changed to any other non-zero integers.
For (3), each term should be as above but in "x1", ..., "xp" instead of "x", following an optional double number and optionally a "*" sign.

Examples: For p=10,
(1) "x^2 > 2" defines the domain abs(x1) > sqrt(2) && ... && abs(x10) > sqrt(2).
(2) "sum(x^2) > 2" defines the domain x1^2 + ... + x10^2 > 2.
(3) "2.3x3^(2/3)-3.4x4+x5^(-3/5)+3.7*x6^(-4)-1.9*log(x7)+1.3e5*exp(-3x8)}\cr \code{-2*exp(x9)+0.5exp(2*x10) <= 2" defines a domain using a polynomial in x3 through x10, and x1 and x2 are thus allowed to vary freely.

Note that ">" and ">=" are not differentiated, and so are "<" and "<=".

Value

A list containing the elements that define the domain. For all types of domains, the following are returned.

type

A string, same as the input.

p

An integer, same as the input.

p_deemed

An integer, equal to p-1 if type == "simplex" or p otherwise.

checked

A logical, TRUE. Used in other functions to test whether a list is returned by this function.

In addition,

  • For type == "simplex", returns in addition

    simplex_tol

    Tolerance used for simplex domains. Defaults to 1e-10.

  • For type == "uniform", returns in addition

    lefts

    A non-empty vector of numbers, same as the input.

    rights

    A non-empty vector of numbers, same as the input.

    left_inf

    A logical, indicates whether lefts[1] is -Inf.

    right_inf

    A logical, indicates whether rights[length(rights)] is Inf.

  • For type == "polynomial", returns in addition

    rule

    A string, same as the input if provided and valid; if not provided and length(ineqs) == 1, set to "1" by default.

    postfix_rule

    A string, rule in postfix notation (reverse Polish notation) containing numbers, " ", "&" and "|" only.

    ineqs

    A list of lists, each sublist representing one inequality containing the following fields:

    uniform

    A logical, indicates whether the inequality should be uniformly applied to all components (e.g. "x>1" -> "x1>1 && ... && xp>1").

    larger

    A logical, indicates whether the polynomial should be larger or smaller than the constant (e.g. TRUE for x1 + ... + xp > C, and FALSE for x1 + ... + xp < C).

    const

    A number, the constant the polynomial should be compared to (e.g. 2.3 for x1 + ... + xp > 2.3).

    abs

    A logical, indicates whether one should evaluate the polynomial in abs(x) instead of x.

    nonnegative

    A logical, indicates whether the domain of this inequality should be restricted to the non-negative orthant.

    power_numers

    A single integer or a vector of p integers. x[i] will be raised to the power of power_numers[i] / power_denoms[i] (or without subscript if a singer integer). Note that x^(0/0) is interpreted as log(x), and x^(n/0) as exp(n*x) for n non-zero. For a negative x, x^(a/b) is defined as (-1)^a*|x|^(a/b) if b is odd, or NaN otherwise.

    power_denoms

    A single integer or a vector of p integers.

    coeffs

    NULL if uniform == TRUE. A vector of p doubles, where coeffs[i] is the coefficient on x[i] in the inequality

Examples

p <- 30
# The 30-dimensional real space R^30
domain <- make_domain("R", p=p)

# The non-negative orthant of the 30-dimensional real space, R+^30
domain <- make_domain("R+", p=p)

# x such that sum(x^2) > 10 && sum(x^(1/3)) > 10 with x allowed to be negative
domain <- make_domain("polynomial", p=p, rule="1 && 2",
       ineqs=list(list("expression"="sum(x^2)>10", abs=FALSE, nonnegative=FALSE),
                      list("expression"="sum(x^(1/3))>10", abs=FALSE, nonnegative=FALSE)))
# Alternatively
domain2 <- make_domain("polynomial", p=p, rule="1 && 2",
       ineqs=list(list(uniform=FALSE, power_numers=2, power_denoms=1, const=10, coeffs=1,
                 larger=1, abs=FALSE, nonnegative=FALSE),
                 list(uniform=FALSE, power_numers=1, power_denoms=3, const=10, coeffs=1,
                 larger=1, abs=FALSE, nonnegative=FALSE)))


# ([0, 1] v [2,3]) ^ p
domain <- make_domain("uniform", p=p, lefts=c(0,2), rights=c(1,3))

# x such that {x1 > 1 && log(1.3) < x2 < 1 && x3 > log(1.3) && ... && xp > log(1.3)}
domain <- make_domain("polynomial", p=p, rule="1 && 2 && 3",
       ineqs=list(list("expression"="x1>1", abs=FALSE, nonnegative=TRUE),
                      list("expression"="x2<1", abs=FALSE, nonnegative=TRUE),
                      list("expression"="exp(x)>1.3", abs=FALSE, nonnegative=FALSE)))
# Alternatively
domain2 <- make_domain("polynomial", p=p, rule="1 && 2",
       ineqs=list(list(uniform=FALSE, power_numers=1, power_denoms=1, const=1,
                 coeffs=c(1,rep(0,p-1)), larger=1, abs=FALSE, nonnegative=TRUE),
                 list(uniform=FALSE, power_numers=1, power_denoms=1, const=1,
                 coeffs=c(0,1,rep(0,p-2)), larger=0, abs=FALSE, nonnegative=TRUE),
                 list(uniform=TRUE, power_numers=1, power_denoms=0, const=1.3,
                 larger=1, abs=FALSE, nonnegative=FALSE)))


# x in R_+^p such that {sum(log(x))<2 || (x1^(2/3)-1.3x2^(-3)<1 && exp(x1)+2.3*x2>2)}
domain <- make_domain("polynomial", p=p, rule="1 || (2 && 3)",
       ineqs=list(list("expression"="sum(log(x))<2", abs=FALSE, nonnegative=TRUE),
                      list("expression"="x1^(2/3)-1.3x2^(-3)<1", abs=FALSE, nonnegative=TRUE),
                      list("expression"="exp(x1)+2.3*x2^2>2", abs=FALSE, nonnegative=TRUE)))
# Alternatively
domain2 <- make_domain("polynomial", p=p, rule="1 && 2",
       ineqs=list(list(uniform=FALSE, power_numers=0, power_denoms=0, const=2,
                 coeffs=1, larger=0, abs=FALSE, nonnegative=TRUE),
                 list(uniform=FALSE, power_numers=c(2,-3,rep(1,p-2)), power_denoms=c(3,rep(1,p-1)),
                 const=1, coeffs=c(1.0,-1.3,rep(0,p-2)), larger=0, abs=FALSE, nonnegative=TRUE),
                 list(uniform=FALSE, power_numers=c(1,2,rep(1,p-2)), power_denoms=c(0,rep(1,p-1)),
                 const=2, coeffs=c(1,2.3,rep(0,p-2)), larger=1, abs=FALSE, nonnegative=TRUE)))


# x in R_+^p such that {x in R_+^p: sum_j j * xj <= 1}
domain <- make_domain("polynomial", p=p,
       ineqs=list(list("expression"=paste(paste(sapply(1:p,
                           function(j){paste(j, "x", j, sep="")}), collapse="+"), "<1"),
                     abs=FALSE, nonnegative=TRUE)))
# Alternatively
domain2 <- make_domain("polynomial", p=p,
       ineqs=list(list(uniform=FALSE, power_numers=1, power_denoms=1, const=1,
                 coeffs=1:p, larger=0, abs=FALSE, nonnegative=TRUE)))


# The (p-1)-simplex
domain <- make_domain("simplex", p=p)

# The l-1 ball {sum(|x|) < 1}
domain <- make_domain("polynomial", p=p,
       ineqs=list(list("expression"="sum(x)<1", abs=TRUE, nonnegative=FALSE)))

genscore documentation built on May 29, 2024, 9 a.m.