virgil.priors
Priors that are invariant measures but not plain numpyro distributions: the
isotropic orientation priors, uniform in cos i (orbit inclination) and in
sin(lat) (a position on a sphere). Locations take Uniform, scales take
LogUniform, and longitudes and nodes are uniform in their angles. See
Which priors? for the full table and the reasons.
hierarchical_scales draws a set of scales, such as one error scale per
epoch, from a log-normal population with log-uniform hyperpriors, for use as
noise= terms tied to the parameters.
Priors that are invariant measures but not plain numpyro priors.
The Haar measure on rotations is uniform in the direction of an axis on the
sphere, which is not uniform in the angles virgil uses:
IsotropicInclination (density
∝ sin i, so cos i is uniform) is the prior on an orbit's inclination in
degrees, and IsotropicLatitude (density
∝ cos lat) that of a position on a sphere, in radians. Longitudes and nodes
are uniform in their angles, so Uniform is right for them.
hierarchical_scales gives a population
of scale factors. All are numpyro distributions that work in the priors
of fit and
numpyro_model; the isotropic priors
optimize in their flat coordinate (see
which priors).
IsotropicInclination
Bases: _InverseCDFPrior
The inclination of an isotropically oriented axis: density ∝ sin i.
The density is sin(i) / (cos(low) - cos(high)) on [low, high], so
cos i is uniform; this is the default prior on inc. Uniform(0, 180)
is not isotropic (it favours face-on orbits).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
low
|
float
|
Bounds in degrees, the unit of |
0.0
|
high
|
float
|
Bounds in degrees, the unit of |
0.0
|
Notes
Use the full range when the data distinguish i from 180 - i
(astrometry, closure phases). Use IsotropicInclination(0, 90) when only
|cos i| is identifiable, as with radial velocities alone.
Examples:
>>> import jax
>>> from virgil.priors import IsotropicInclination
>>> prior = IsotropicInclination(0.0, 90.0)
>>> samples = prior.sample(jax.random.key(0), (1000,))
>>> bool(((samples >= 0.0) & (samples <= 90.0)).all())
True
mean
property
__init__(low=0.0, high=180.0, *, validate_args=None)
icdf(q)
Quantile function: cos i is uniform, inverted near the nearer pole.
cdf(value)
log_prob(value)
IsotropicLatitude
Bases: _InverseCDFPrior
The latitude of an isotropically placed point: density ∝ cos(lat).
A point uniform on the sphere has sin(lat) uniform, so its latitude has
density cos(lat) / (sin(high) - sin(low)). Use it for the position
of a star spot (harmonix's lat argument), together with
Uniform(-pi, pi) for the longitude.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
low
|
float
|
Bounds in radians, the unit harmonix's |
-pi / 2
|
high
|
float
|
Bounds in radians, the unit harmonix's |
-pi / 2
|
Examples:
>>> import jax
>>> from virgil.priors import IsotropicLatitude
>>> samples = IsotropicLatitude().sample(jax.random.key(0), (1000,))
>>> bool((abs(samples) <= 3.1416 / 2).all())
True
mean
property
__init__(low=-np.pi / 2, high=np.pi / 2, *, validate_args=None)
icdf(q)
cdf(value)
log_prob(value)
PopulationScale
dataclass
Member index of a log-normal population of scales.
Called with the dict of sampled values, it returns the member's scale s_k;
see hierarchical_scales. In the
centred form log_prior is the
population density, which numpyro_model and fit add once per member
used as a noise term. It is a frozen dataclass, so equal members compare
(and hash) equal: repeated fits do not recompile.
name
instance-attribute
index
instance-attribute
centred = True
class-attribute
instance-attribute
__init__(name, index, centred=True)
__call__(values)
log_prior(values)
The member's population log density (zero when non-centred, where the standard normal prior on z_k carries it).
curvature_rows(values)
Mean and normalizer curvature rows of the centred population prior.
hierarchical_scales(name, n, median=None, spread=None, centred=True)
n positive scales drawn from a log-normal population.
log s_k is normal about log(median) with standard deviation
spread; both are sampled, with log-uniform priors. Use it for
nuisances that differ between epochs but share an instrument, passed as
noise terms (one dict per dataset, in order). Use every member: an
unused centred member has an improper flat prior. When to centre:
hierarchical scales.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Prefix of the parameters |
required |
n
|
int
|
Number of scales, e.g. the number of epochs. |
required |
median
|
Distribution
|
Prior on the population median (default |
None
|
spread
|
Distribution
|
Prior on the standard deviation of log s (default
|
None
|
centred
|
bool
|
Sample |
True
|
Returns:
| Name | Type | Description |
|---|---|---|
priors |
dict
|
The three priors, to merge into a |
scales |
list of PopulationScale
|
One callable per member, each mapping the sampled values to s_k. |
Examples:
>>> import numpyro.distributions as dist
>>> from virgil.priors import hierarchical_scales
>>> priors, scales = hierarchical_scales("cp_scale", 3)
>>> sorted(priors)
['cp_scale_log', 'cp_scale_median', 'cp_scale_spread']
>>> noise = [{"phi_scale": s} for s in scales]
>>> values = {"cp_scale_median": 2.0, "cp_scale_spread": 0.5,
... "cp_scale_log": np.log(np.array([1.0, 2.0, 4.0]))}
>>> round(float(scales[1](values)), 6)
2.0