make_domain | R Documentation |
Creates a list of elements that define the domain for a multivariate distribution.
make_domain(type, p, lefts = NULL, rights = NULL, ineqs = NULL, rule = NULL)
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 |
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 "<="
.
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 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
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)))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.