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=-Inf
andrights=Inf
."R+"
The non-negative orthant of the
p
-dimensional real space. Equivalent to"uniform"
type withlefts=0
andrights=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 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) == 1
andx > 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
orx1*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 ofx
(e.g."sum(x) > 1"
withabs == TRUE
is interpreted assum(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
forx1 + ... + xp > C
, andFALSE
forx1 + ... + xp < C
).const
A number, the constant the polynomial should be compared to (e.g.
2.3
forx1 + ... + xp > 2.3
).power_numers
A single integer or a vector of
p
integers.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)
forn
non-zero. For a negativex
,x^(a/b)
is defined as(-1)^a*|x|^(a/b)
ifb
is odd, orNaN
otherwise. (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_denoms
A single integer or a vector of
p
integers. (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
).coeffs
Required if
uniform == FALSE
. A vector ofp
doubles, wherecoeffs[i]
is the coefficient onx[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 the2
and3
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 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 inx3
throughx10
, andx1
andx2
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 |
checked |
A logical, |
In addition,
For
type == "simplex"
, returns in additionsimplex_tol
Tolerance used for simplex domains. Defaults to
1e-10
.
For
type == "uniform"
, returns in additionlefts
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)]
isInf
.
For
type == "polynomial"
, returns in additionrule
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
forx1 + ... + xp > C
, andFALSE
forx1 + ... + xp < C
).const
A number, the constant the polynomial should be compared to (e.g.
2.3
forx1 + ... + xp > 2.3
).abs
A logical, indicates whether one should evaluate the polynomial in
abs(x)
instead ofx
.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 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)
forn
non-zero. For a negativex
,x^(a/b)
is defined as(-1)^a*|x|^(a/b)
ifb
is odd, orNaN
otherwise.power_denoms
A single integer or a vector of
p
integers.coeffs
NULL
ifuniform == TRUE
. A vector ofp
doubles, 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)))