Usage#
Espresso is a collection of individual examples, or test problems. From a users’ perspective, each test problem is a separate Python object (specifically, a subclass of espresso.EspressoProblem
) that is available to be imported:
from espresso import XrayTomography as testproblem1
from espresso import SimpleRegression as testproblem2
Then, create an instance of the class to access its functionality:
tp1 = testproblem1()
tp2 = testproblem2()
Each test problem defines one or more examples. All examples will represent the same fundamental inference problem (i.e. the same physical/conceptual scenario), but may provide access to different datasets or problem configurations — for full details, consult the problem-specific documentation. By default, the first example is loaded, but you can select a different example by passing example_number=<num>
when creating your class instance:
tp1 = testproblem1(example_number = 3)
tp2 = testproblem2(example_number = 2)
If you wish to use more than one example in your code, you will need to create multiple testproblem
instances (or re-initialise an existing one). Attempting to load a non-existent example number will raise a espresso.exceptions.InvalidExampleError
exception.
from espresso.exceptions import InvalidExampleError
from espresso import XrayTomography as xrt
iexample = 1
try:
while True:
x = xrt(example_number = iexample)
# Do stuff
# ...
# Now increment the counter and go round again
iexample += 1
except InvalidExampleError:
print("Last valid example:",iexample-1)
Your test problem instance provides access to simulation capabilities, data and other information via a standardised interface. Let’s suppose we’ve imported and instantiated some test problem <TestProblem>
(this is just a generic placeholder name – it can be any example from the list).
from espresso import <TestProblem>
tp = TestProblem()
All test problems will have at least the following attributes:
tp.model_size
– The number of unknown parameters, \(M\), i.e. the dimension of the model vector \(\mathbf{m}\).tp.starting_model
– Anumpy.ndarray
with shape \((M,)\) containing a null model or other problem-appropriate starting point that can be used to initialise (e.g.) iterative algorithms.tp.good_model
– Anumpy.ndarray
with shape \((M,)\) containing a model vector that the problem contributor would regard as one example of a ‘good’ description of the relevant system. (Problems may be non-unique, and ‘good’ may involve subjective choices; i.e. this is one good model but not necessarily the best or only good model.)tp.data_size
– The dimension, \(N\), of the data vector, \(\mathbf{d}\)tp.data
– Anumpy.ndarray
with shape \((N,)\) containing a data vector, \(\mathbf{d}\).tp.forward(model)
– A function that takes one model vector (anumpy.ndarray
of shape \((M,)\)) as input, and returns a simulated data vector (\(\mathbf{g}(\mathbf{m})\),numpy.ndarray
with shape \((N,)\)). The output fromtp.forward
can be assumed to be directly comparable to the data vectortp.data
. (For some test problems,tp.forward()
will accept an optional argumentwith_jacobian = True
; see below for more details.)
In addition, the following attributes are standardized, but optional:
tp.description
– Astr
containing a desciption/summary of the test problem.tp.covariance_matrix
– Anumpy.ndarray
with shape \((N,N)\) containing a covariance matrix, \(\mathbf{C_d}\), describing the (assumed) uncertainty on \(\mathbf{d}\).tp.inverse_covariance_matrix
– Anumpy.ndarray
with shape \((N,N)\) containing \(\mathbf{C_{d}^{-1}}\).tp.jacobian(model)
– A function that takes one model vector (anumpy.ndarray
of shape \((M,)\)) as input, and returns annumpy.ndarray
of shape \((N,M)\) containing \(\mathbf{G}\) such that \([\mathbf{G}]_{ij} = {\partial[\mathbf{g}(\mathbf{m})]_i}/{\partial [\mathbf{m}]_j}\). Problems that definetp.jacobian()
will also accept an optional argumentwith_jacobian = True
passed totp.forward()
, which then returns a \((\mathbf{g}(\mathbf{m}), \mathbf{G})\) pair. In some cases this will be computationally more efficient than callingtp.forward()
andtp.jacobian()
separately.tp.plot_model(model)
– A function to visualise a single model-like vector in some problem-appropriate manner.tp.plot_data(data, data2=None)
– A function to visualise one or two data-like vectors in a problem-appropriate manner.tp.misfit(data,data2)
– A function that returns afloat
representing a problem-appropriate measure of the disagreement between two data-like vectors (i.e. a value of 0 implies a perfect match).tp.log_likelihood(data,data2)
– A function that computes a log-likelihood function (float
) between two data-like vectors.tp.log_prior(model)
– A function that implements a prior distribution in model space, returning the log-probability (float
) for a model-like vector.
If a test problem does not implement a given attribute, attempting to use it will raise a NotImplementedError
exception (which can then be caught and handled as necessary).
All test problems will also define the following basic metadata:
tp.problem_title
tp.problem_short_description
– A few sentences summarising the problem.tp.author_names
tp.contact_name
– Primary contributor/maintainer for the Espresso test problem.tp.contact_email
tp.citations
– List of(citation, doi)
pairs for any publication(s) that directly describe the test problem;tp.linked_sites
– List of(title, address)
pairs for any related resources (e.g. links to data sources or external Github repos).
Finally, test problems may expose additional attributes beyond the scope of the Espresso API. For more details see API Reference and Test Problems Reference.