| make_domain {genscore} | R 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 |
p |
An integer, the dimension of the domain. |
lefts |
Optional, required if |
rights |
Optional, required if |
ineqs |
Optional, required if |
rule |
Optional, required if |
Details
The following types of domains are supported:
"R"The entire
p-dimensional real space. Equivalent to"uniform"type withlefts=-Infandrights=Inf."R+"The non-negative orthant of the
p-dimensional real space. Equivalent to"uniform"type withlefts=0andrights=Inf."uniform"A union of finitely many disjoint intervals as a uniform domain for all components. The left endpoints should be specified through
leftsand the right endpoints throughrights. The intervals must be disjoint and strictly increasing, i.e.lefts[i] <= rights[i] <= lefts[j]for anyi < j. E.g.lefts=c(0, 10)andrights=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) == 1andx > 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>1orx1*x2>1not 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.
ruleA 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.ineqsA list of lists, each sublist represents one inequality, and must contain the following fields:
absA logical, indicates whether one should evaluate the polynomial in
abs(x)instead ofx(e.g."sum(x) > 1"withabs == TRUEis interpreted assum(abs(x)) > 1).nonnegativeA 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):uniformA logical, indicates whether the inequality should be uniformly applied to all components (e.g.
"x>1"->"x1>1 && ... && xp>1").largerA logical, indicates whether the polynomial should be larger or smaller than the constant (e.g.
TRUEforx1 + ... + xp > C, andFALSEforx1 + ... + xp < C).constA number, the constant the polynomial should be compared to (e.g.
2.3forx1 + ... + xp > 2.3).power_numersA single integer or a vector of
pintegers.x[i]will be raised to the power ofpower_numers[i] / power_denoms[i](or without subscript if a singer integer). Note thatx^(0/0)is interpreted aslog(x), andx^(n/0)asexp(n*x)fornnon-zero. For a negativex,x^(a/b)is defined as(-1)^a*|x|^(a/b)ifbis odd, orNaNotherwise. (Example:c(2,3,5,0,-2)forx1^2+2*x2^(3/2)+3*x3^(5/3)+4*log(x4)+5*exp(-2*x)>1).power_denomsA single integer or a vector of
pintegers. (Example:c(1,2,3,0,0)forx1^2+2*x2^(3/2)+3*x3^(5/3)+4*log(x4)+5*exp(-2*x)>1).coeffsRequired if
uniform == FALSE. A vector ofpdoubles, wherecoeffs[i]is the coefficient onx[i]in the inequality.
The user is recommended to use a single
expressionfor 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 the2and3can 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 domainabs(x1) > sqrt(2) && ... && abs(x10) > sqrt(2).
(2)"sum(x^2) > 2"defines the domainx1^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 inx3throughx10, andx1andx2are 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 |
checked |
A logical, |
In addition,
For
type == "simplex", returns in additionsimplex_tolTolerance used for simplex domains. Defaults to
1e-10.
For
type == "uniform", returns in additionleftsA non-empty vector of numbers, same as the input.
rightsA non-empty vector of numbers, same as the input.
left_infA logical, indicates whether
lefts[1]is-Inf.right_infA logical, indicates whether
rights[length(rights)]isInf.
For
type == "polynomial", returns in additionruleA string, same as the input if provided and valid; if not provided and
length(ineqs) == 1, set to"1"by default.postfix_ruleA string,
rulein postfix notation (reverse Polish notation) containing numbers," ","&"and"|"only.ineqsA list of lists, each sublist representing one inequality containing the following fields:
uniformA logical, indicates whether the inequality should be uniformly applied to all components (e.g.
"x>1"->"x1>1 && ... && xp>1").largerA logical, indicates whether the polynomial should be larger or smaller than the constant (e.g.
TRUEforx1 + ... + xp > C, andFALSEforx1 + ... + xp < C).constA number, the constant the polynomial should be compared to (e.g.
2.3forx1 + ... + xp > 2.3).absA logical, indicates whether one should evaluate the polynomial in
abs(x)instead ofx.nonnegativeA logical, indicates whether the domain of this inequality should be restricted to the non-negative orthant.
power_numersA single integer or a vector of
pintegers.x[i]will be raised to the power ofpower_numers[i] / power_denoms[i](or without subscript if a singer integer). Note thatx^(0/0)is interpreted aslog(x), andx^(n/0)asexp(n*x)fornnon-zero. For a negativex,x^(a/b)is defined as(-1)^a*|x|^(a/b)ifbis odd, orNaNotherwise.power_denomsA single integer or a vector of
pintegers.coeffsNULLifuniform == TRUE. A vector ofpdoubles, wherecoeffs[i]is the coefficient onx[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)))