Commit 1fb9abd8 authored by Philipp Arras's avatar Philipp Arras
Browse files

Unify naming

Likelihood -> Likelihood energy
Prior -> Prior energy
parent 2cbf787a
...@@ -82,14 +82,15 @@ comparison to MGVI can be found in `demos/variational_inference_visualized.py`. ...@@ -82,14 +82,15 @@ comparison to MGVI can be found in `demos/variational_inference_visualized.py`.
For further details see (<https://arxiv.org/abs/2105.10470>). For further details see (<https://arxiv.org/abs/2105.10470>).
LikelihoodOperator LikelihoodEnergyOperator
------------------ ------------------------
A new subclass of `EnergyOperator` was introduced and all `EnergyOperator`s A new subclass of `EnergyOperator` was introduced and all `EnergyOperator`s that
that are likelihoods are now `LikelihoodOperator`s. A `LikelihoodOperator` are likelihoods are now `LikelihoodEnergyOperator`s. A
has to implement the function `get_transformation`, which returns a `LikelihoodEnergyOperator` has to implement the function `get_transformation`,
coordinate transformation in which the Fisher metric of the likelihood becomes which returns a coordinate transformation in which the Fisher metric of the
the identity matrix. This is needed for the `GeoMetricKL` algorithm. likelihood becomes the identity matrix. This is needed for the `GeoMetricKL`
algorithm.
Changes since NIFTy 5 Changes since NIFTy 5
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2020 Max-Planck-Society # Copyright(C) 2013-2021 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik. # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
...@@ -64,16 +64,16 @@ def main(): ...@@ -64,16 +64,16 @@ def main():
data = ift.random.current_rng().binomial(1, tmp) data = ift.random.current_rng().binomial(1, tmp)
data = ift.Field.from_raw(R.target, data) data = ift.Field.from_raw(R.target, data)
# Compute likelihood and Hamiltonian # Compute likelihood energy and Hamiltonian
position = ift.from_random(harmonic_space, 'normal') position = ift.from_random(harmonic_space, 'normal')
likelihood = ift.BernoulliEnergy(data) @ p likelihood_energy = ift.BernoulliEnergy(data) @ p
ic_newton = ift.DeltaEnergyController( ic_newton = ift.DeltaEnergyController(
name='Newton', iteration_limit=100, tol_rel_deltaE=1e-8) name='Newton', iteration_limit=100, tol_rel_deltaE=1e-8)
minimizer = ift.NewtonCG(ic_newton) minimizer = ift.NewtonCG(ic_newton)
ic_sampling = ift.GradientNormController(iteration_limit=100) ic_sampling = ift.GradientNormController(iteration_limit=100)
# Minimize the Hamiltonian # Minimize the Hamiltonian
H = ift.StandardHamiltonian(likelihood, ic_sampling) H = ift.StandardHamiltonian(likelihood_energy, ic_sampling)
H = ift.EnergyAdapter(position, H, want_metric=True) H = ift.EnergyAdapter(position, H, want_metric=True)
# minimizer = ift.L_BFGS(ic_newton) # minimizer = ift.L_BFGS(ic_newton)
H, convergence = minimizer(H) H, convergence = minimizer(H)
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2020 Max-Planck-Society # Copyright(C) 2013-2021 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik. # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
...@@ -85,14 +85,14 @@ def main(): ...@@ -85,14 +85,14 @@ def main():
# Define instrumental response # Define instrumental response
R = GR(M) R = GR(M)
# Generate mock data and define likelihood operator # Generate mock data and define likelihood energy operator
d_space = R.target[0] d_space = R.target[0]
lamb = R(sky) lamb = R(sky)
mock_position = ift.from_random(domain, 'normal') mock_position = ift.from_random(domain, 'normal')
data = lamb(mock_position) data = lamb(mock_position)
data = ift.random.current_rng().poisson(data.val.astype(np.float64)) data = ift.random.current_rng().poisson(data.val.astype(np.float64))
data = ift.Field.from_raw(d_space, data) data = ift.Field.from_raw(d_space, data)
likelihood = ift.PoissonianEnergy(data) @ lamb likelihood_energy = ift.PoissonianEnergy(data) @ lamb
# Settings for minimization # Settings for minimization
ic_newton = ift.DeltaEnergyController( ic_newton = ift.DeltaEnergyController(
...@@ -100,7 +100,7 @@ def main(): ...@@ -100,7 +100,7 @@ def main():
minimizer = ift.NewtonCG(ic_newton) minimizer = ift.NewtonCG(ic_newton)
# Compute MAP solution by minimizing the information Hamiltonian # Compute MAP solution by minimizing the information Hamiltonian
H = ift.StandardHamiltonian(likelihood) H = ift.StandardHamiltonian(likelihood_energy)
initial_position = ift.from_random(domain, 'normal') initial_position = ift.from_random(domain, 'normal')
H = ift.EnergyAdapter(initial_position, H, want_metric=True) H = ift.EnergyAdapter(initial_position, H, want_metric=True)
H, convergence = minimizer(H) H, convergence = minimizer(H)
......
...@@ -106,10 +106,10 @@ def main(): ...@@ -106,10 +106,10 @@ def main():
deltaE=0.5, iteration_limit=15, convergence_level=2) deltaE=0.5, iteration_limit=15, convergence_level=2)
minimizer_sampling = ift.NewtonCG(ic_sampling_nl) minimizer_sampling = ift.NewtonCG(ic_sampling_nl)
# Set up likelihood and information Hamiltonian # Set up likelihood energy and information Hamiltonian
likelihood = (ift.GaussianEnergy(mean=data, inverse_covariance=N.inverse) @ likelihood_energy = (ift.GaussianEnergy(mean=data, inverse_covariance=N.inverse) @
signal_response) signal_response)
H = ift.StandardHamiltonian(likelihood, ic_sampling) H = ift.StandardHamiltonian(likelihood_energy, ic_sampling)
initial_mean = ift.MultiField.full(H.domain, 0.) initial_mean = ift.MultiField.full(H.domain, 0.)
mean = initial_mean mean = initial_mean
......
...@@ -124,9 +124,9 @@ def main(): ...@@ -124,9 +124,9 @@ def main():
# number of samples used to estimate the KL # number of samples used to estimate the KL
N_samples = 20 N_samples = 20
# Set up likelihood and information Hamiltonian # Set up likelihood energy and information Hamiltonian
likelihood = ift.GaussianEnergy(mean=data, inverse_covariance=N.inverse) @ signal_response likelihood_energy = ift.GaussianEnergy(mean=data, inverse_covariance=N.inverse) @ signal_response
H = ift.StandardHamiltonian(likelihood, ic_sampling) H = ift.StandardHamiltonian(likelihood_energy, ic_sampling)
# Begin minimization # Begin minimization
initial_mean = ift.MultiField.full(H.domain, 0.) initial_mean = ift.MultiField.full(H.domain, 0.)
......
...@@ -84,9 +84,9 @@ if __name__ == "__main__": ...@@ -84,9 +84,9 @@ if __name__ == "__main__":
# Number of samples used to estimate the KL # Number of samples used to estimate the KL
n_samples = 5 n_samples = 5
# Set up likelihood and information Hamiltonian # Set up likelihood energy and information Hamiltonian
likelihood = ift.PoissonianEnergy(data) @ signal likelihood_energy = ift.PoissonianEnergy(data) @ signal
ham = ift.StandardHamiltonian(likelihood, ic_sampling) ham = ift.StandardHamiltonian(likelihood_energy, ic_sampling)
# Start minimization # Start minimization
initial_mean = ift.MultiField.full(ham.domain, 0.) initial_mean = ift.MultiField.full(ham.domain, 0.)
......
...@@ -57,12 +57,12 @@ if __name__ == "__main__": ...@@ -57,12 +57,12 @@ if __name__ == "__main__":
d_space = R.target[0] d_space = R.target[0]
lamb = R(sky) lamb = R(sky)
# Generate simulated signal and data and build log-likelihood # Generate simulated signal and data and build likelihood energy
mock_position = ift.from_random(sky.domain, "normal") mock_position = ift.from_random(sky.domain, "normal")
data = ift.random.current_rng().poisson(lamb(mock_position).val) data = ift.random.current_rng().poisson(lamb(mock_position).val)
data = ift.makeField(d_space, data) data = ift.makeField(d_space, data)
loglikelihood = ift.PoissonianEnergy(data) @ lamb likelihood_energy = ift.PoissonianEnergy(data) @ lamb
H = ift.StandardHamiltonian(loglikelihood) H = ift.StandardHamiltonian(likelihood_energy)
# Settings for minimization # Settings for minimization
IC = ift.StochasticAbsDeltaEnergyController(5, iteration_limit=200, IC = ift.StochasticAbsDeltaEnergyController(5, iteration_limit=200,
......
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2020 Max-Planck-Society # Copyright(C) 2013-2021 Max-Planck-Society
# Author: Philipp Arras # Author: Philipp Arras
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik. # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
...@@ -104,8 +104,8 @@ def main(): ...@@ -104,8 +104,8 @@ def main():
N = ift.DiagonalOperator(ift.makeField(d_space, var)) N = ift.DiagonalOperator(ift.makeField(d_space, var))
IC = ift.DeltaEnergyController(tol_rel_deltaE=1e-12, iteration_limit=200) IC = ift.DeltaEnergyController(tol_rel_deltaE=1e-12, iteration_limit=200)
likelihood = ift.GaussianEnergy(d, N) @ R likelihood_energy = ift.GaussianEnergy(d, N) @ R
Ham = ift.StandardHamiltonian(likelihood, IC) Ham = ift.StandardHamiltonian(likelihood_energy, IC)
H = ift.EnergyAdapter(params, Ham, want_metric=True) H = ift.EnergyAdapter(params, Ham, want_metric=True)
# Minimize # Minimize
......
...@@ -378,11 +378,11 @@ compute the negative log-likelihood of the problem in standardized coordinates ...@@ -378,11 +378,11 @@ compute the negative log-likelihood of the problem in standardized coordinates
at a given position in parameter space. at a given position in parameter space.
Finally, the :class:`~operators.energy_operators.StandardHamiltonian` Finally, the :class:`~operators.energy_operators.StandardHamiltonian`
can be constructed from the likelihood, represented by a can be constructed from the likelihood, represented by a
:class:`~operators.energy_operators.LikelihoodOperator` instance. :class:`~operators.energy_operators.LikelihoodEnergyOperator` instance.
Several commonly used forms of the likelihoods are already provided in Several commonly used forms of the likelihoods are already provided in
NIFTy, such as :class:`~operators.energy_operators.GaussianEnergy`, NIFTy, such as :class:`~operators.energy_operators.GaussianEnergy`,
:class:`~operators.energy_operators.PoissonianEnergy`, :class:`~operators.energy_operators.PoissonianEnergy`,
:class:`~operators.energy_operators.InverseGammaLikelihood` or :class:`~operators.energy_operators.InverseGammaEnergy` or
:class:`~operators.energy_operators.BernoulliEnergy`, but the user :class:`~operators.energy_operators.BernoulliEnergy`, but the user
is free to implement any likelihood customized to the problem at hand. is free to implement any likelihood customized to the problem at hand.
The demo code `demos/getting_started_3.py` illustrates how to set up an energy The demo code `demos/getting_started_3.py` illustrates how to set up an energy
......
...@@ -48,7 +48,7 @@ from .operators.simple_linear_operators import ( ...@@ -48,7 +48,7 @@ from .operators.simple_linear_operators import (
from .operators.matrix_product_operator import MatrixProductOperator from .operators.matrix_product_operator import MatrixProductOperator
from .operators.value_inserter import ValueInserter from .operators.value_inserter import ValueInserter
from .operators.energy_operators import ( from .operators.energy_operators import (
EnergyOperator, GaussianEnergy, PoissonianEnergy, InverseGammaLikelihood, EnergyOperator, GaussianEnergy, PoissonianEnergy, InverseGammaEnergy,
BernoulliEnergy, StandardHamiltonian, AveragedEnergy, QuadraticFormOperator, BernoulliEnergy, StandardHamiltonian, AveragedEnergy, QuadraticFormOperator,
Squared2NormOperator, StudentTEnergy, VariableCovarianceGaussianEnergy) Squared2NormOperator, StudentTEnergy, VariableCovarianceGaussianEnergy)
from .operators.convolution_operators import FuncConvolutionOperator from .operators.convolution_operators import FuncConvolutionOperator
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# #
# Copyright(C) 2013-2019 Max-Planck-Society # Copyright(C) 2013-2021 Max-Planck-Society
# #
# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik. # NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik.
from ..minimization.energy_adapter import EnergyAdapter from ..minimization.energy_adapter import EnergyAdapter
from ..multi_field import MultiField from ..multi_field import MultiField
from ..operators.energy_operators import (InverseGammaLikelihood, from ..operators.energy_operators import (InverseGammaEnergy,
StandardHamiltonian) StandardHamiltonian)
from ..operators.scaling_operator import ScalingOperator from ..operators.scaling_operator import ScalingOperator
from ..operators.simple_linear_operators import ducktape from ..operators.simple_linear_operators import ducktape
...@@ -74,7 +74,7 @@ def make_adjust_variances_hamiltonian(a, ...@@ -74,7 +74,7 @@ def make_adjust_variances_hamiltonian(a,
if scaling is not None: if scaling is not None:
x = ScalingOperator(x.target, scaling)(x) x = ScalingOperator(x.target, scaling)(x)
return StandardHamiltonian(InverseGammaLikelihood(d_eval/2.)(x), return StandardHamiltonian(InverseGammaEnergy(d_eval/2.)(x),
ic_samp=ic_samp) ic_samp=ic_samp)
......
...@@ -83,19 +83,19 @@ class EnergyOperator(Operator): ...@@ -83,19 +83,19 @@ class EnergyOperator(Operator):
_target = DomainTuple.scalar_domain() _target = DomainTuple.scalar_domain()
class LikelihoodOperator(EnergyOperator): class LikelihoodEnergyOperator(EnergyOperator):
"""Represent a log-likelihood. """Represent a negative log-likelihood.
The input to the Operator are the parameters of the likelihood. Unlike a The input to the Operator are the parameters of the negative log-likelihood.
general `EnergyOperator`, the metric of a `LikelihoodOperator` is the Unlike a general `EnergyOperator`, the metric of a
Fisher information metric of the likelihood. `LikelihoodEnergyOperator` is the Fisher information metric of the
likelihood.
""" """
def get_metric_at(self, x): def get_metric_at(self, x):
"""Computes the Fisher information metric for a `LikelihoodOperator` """Compute the Fisher information metric for a `LikelihoodEnergyOperator`
at `x` using the Jacobian of the coordinate transformation given by at `x` using the Jacobian of the coordinate transformation given by
:func:`~nifty7.operators.operator.Operator.get_transformation`. :func:`~nifty7.operators.operator.Operator.get_transformation`. """
"""
dtp, f = self.get_transformation() dtp, f = self.get_transformation()
ch = None ch = None
if dtp is not None: if dtp is not None:
...@@ -152,7 +152,7 @@ class QuadraticFormOperator(EnergyOperator): ...@@ -152,7 +152,7 @@ class QuadraticFormOperator(EnergyOperator):
return x.new(res, VdotOperator(self._op(x.val))) return x.new(res, VdotOperator(self._op(x.val)))
class VariableCovarianceGaussianEnergy(LikelihoodOperator): class VariableCovarianceGaussianEnergy(LikelihoodEnergyOperator):
"""Computes the negative log pdf of a Gaussian with unknown covariance. """Computes the negative log pdf of a Gaussian with unknown covariance.
The covariance is assumed to be diagonal. The covariance is assumed to be diagonal.
...@@ -249,7 +249,7 @@ class VariableCovarianceGaussianEnergy(LikelihoodOperator): ...@@ -249,7 +249,7 @@ class VariableCovarianceGaussianEnergy(LikelihoodOperator):
return self._dt, f return self._dt, f
class _SpecialGammaEnergy(LikelihoodOperator): class _SpecialGammaEnergy(LikelihoodEnergyOperator):
def __init__(self, residual): def __init__(self, residual):
self._domain = DomainTuple.make(residual.domain) self._domain = DomainTuple.make(residual.domain)
self._resi = residual self._resi = residual
...@@ -272,7 +272,7 @@ class _SpecialGammaEnergy(LikelihoodOperator): ...@@ -272,7 +272,7 @@ class _SpecialGammaEnergy(LikelihoodOperator):
return self._dt, sc*ScalingOperator(self._domain, 1.).log() return self._dt, sc*ScalingOperator(self._domain, 1.).log()
class GaussianEnergy(LikelihoodOperator): class GaussianEnergy(LikelihoodEnergyOperator):
"""Computes a negative-log Gaussian. """Computes a negative-log Gaussian.
Represents up to constants in :math:`m`: Represents up to constants in :math:`m`:
...@@ -370,7 +370,7 @@ class GaussianEnergy(LikelihoodOperator): ...@@ -370,7 +370,7 @@ class GaussianEnergy(LikelihoodOperator):
return f'GaussianEnergy {dom}' return f'GaussianEnergy {dom}'
class PoissonianEnergy(LikelihoodOperator): class PoissonianEnergy(LikelihoodEnergyOperator):
"""Computes likelihood Hamiltonians of expected count field constrained by """Computes likelihood Hamiltonians of expected count field constrained by
Poissonian count data. Poissonian count data.
...@@ -408,7 +408,7 @@ class PoissonianEnergy(LikelihoodOperator): ...@@ -408,7 +408,7 @@ class PoissonianEnergy(LikelihoodOperator):
return np.float64, 2.*ScalingOperator(self._domain, 1.).sqrt() return np.float64, 2.*ScalingOperator(self._domain, 1.).sqrt()
class InverseGammaLikelihood(LikelihoodOperator): class InverseGammaEnergy(LikelihoodEnergyOperator):
"""Computes the negative log-likelihood of the inverse gamma distribution. """Computes the negative log-likelihood of the inverse gamma distribution.
It negative log-pdf(x) is given by It negative log-pdf(x) is given by
...@@ -457,7 +457,7 @@ class InverseGammaLikelihood(LikelihoodOperator): ...@@ -457,7 +457,7 @@ class InverseGammaLikelihood(LikelihoodOperator):
return self._sampling_dtype, res return self._sampling_dtype, res
class StudentTEnergy(LikelihoodOperator): class StudentTEnergy(LikelihoodEnergyOperator):
"""Computes likelihood energy corresponding to Student's t-distribution. """Computes likelihood energy corresponding to Student's t-distribution.
.. math :: .. math ::
...@@ -495,7 +495,7 @@ class StudentTEnergy(LikelihoodOperator): ...@@ -495,7 +495,7 @@ class StudentTEnergy(LikelihoodOperator):
return np.float64, makeOp(((th+1)/(th+3)).sqrt()) return np.float64, makeOp(((th+1)/(th+3)).sqrt())
class BernoulliEnergy(LikelihoodOperator): class BernoulliEnergy(LikelihoodEnergyOperator):
"""Computes likelihood energy of expected event frequency constrained by """Computes likelihood energy of expected event frequency constrained by
event data. event data.
...@@ -585,8 +585,8 @@ class StandardHamiltonian(EnergyOperator): ...@@ -585,8 +585,8 @@ class StandardHamiltonian(EnergyOperator):
return (lhx+prx).add_metric(met) return (lhx+prx).add_metric(met)
def __repr__(self): def __repr__(self):
subs = 'Likelihood:\n{}'.format(utilities.indent(self._lh.__repr__())) subs = 'Likelihood energy:\n{}'.format(utilities.indent(self._lh.__repr__()))
subs += '\nPrior:\n{}'.format(self._prior) subs += '\nPrior energy:\n{}'.format(self._prior)
return 'StandardHamiltonian:\n' + utilities.indent(subs) return 'StandardHamiltonian:\n' + utilities.indent(subs)
def _simplify_for_constant_input_nontrivial(self, c_inp): def _simplify_for_constant_input_nontrivial(self, c_inp):
......
...@@ -111,7 +111,7 @@ class Operator(metaclass=NiftyMeta): ...@@ -111,7 +111,7 @@ class Operator(metaclass=NiftyMeta):
"""The coordinate transformation that maps into a coordinate system in """The coordinate transformation that maps into a coordinate system in
which the metric of a likelihood is the Euclidean metric. It is `None`, which the metric of a likelihood is the Euclidean metric. It is `None`,
except for instances of except for instances of
:class:`~nifty7.operators.energy_operators.LikelihoodOperator` or :class:`~nifty7.operators.energy_operators.LikelihoodEnergyOperator` or
(nested) sums thereof. (nested) sums thereof.
Returns Returns
......
...@@ -39,7 +39,7 @@ from .plot import Plot ...@@ -39,7 +39,7 @@ from .plot import Plot
__all__ = ['PS_field', 'power_analyze', 'create_power_operator', __all__ = ['PS_field', 'power_analyze', 'create_power_operator',
'density_estimator', 'create_harmonic_smoothing_operator', 'density_estimator', 'create_harmonic_smoothing_operator',
'from_random', 'full', 'makeField', 'is_fieldlike', 'from_random', 'full', 'makeField', 'is_fieldlike',
'is_linearization', 'is_operator', 'makeDomain', 'is_likelihood', 'is_linearization', 'is_operator', 'makeDomain', 'is_likelihood_energy',
'get_signal_variance', 'makeOp', 'domain_union', 'get_signal_variance', 'makeOp', 'domain_union',
'get_default_codomain', 'single_plot', 'exec_time', 'get_default_codomain', 'single_plot', 'exec_time',
'calculate_position'] + list(pointwise.ptw_dict.keys()) 'calculate_position'] + list(pointwise.ptw_dict.keys())
...@@ -591,8 +591,8 @@ def calculate_position(operator, output): ...@@ -591,8 +591,8 @@ def calculate_position(operator, output):
return pos return pos
def is_likelihood(obj): def is_likelihood_energy(obj):
"""Checks if object is likelihood-like. """Checks if object behaves like a likelihood energy.
""" """
return isinstance(obj, Operator) and obj.get_transformation() is not None return isinstance(obj, Operator) and obj.get_transformation() is not None
......
...@@ -103,7 +103,7 @@ def test_inverse_gamma(field): ...@@ -103,7 +103,7 @@ def test_inverse_gamma(field):
space = field.domain space = field.domain
d = ift.random.current_rng().normal(10, size=space.shape)**2 d = ift.random.current_rng().normal(10, size=space.shape)**2
d = ift.Field(space, d) d = ift.Field(space, d)
energy = ift.InverseGammaLikelihood(d) energy = ift.InverseGammaEnergy(d)
ift.extra.check_operator(energy, field, tol=1e-10) ift.extra.check_operator(energy, field, tol=1e-10)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment