diff --git a/nifty5/__init__.py b/nifty5/__init__.py
index 0d93e1632737f5947b607a0d73321fa06bddf487..51804da16f061a5d90d9465bcb966752df8f2e76 100644
--- a/nifty5/__init__.py
+++ b/nifty5/__init__.py
@@ -47,8 +47,8 @@ from .operators.simple_linear_operators import (
     VdotOperator, SumReductionOperator, ConjugationOperator, Realizer,
     FieldAdapter, GeometryRemover, NullOperator)
 from .operators.energy_operators import (
-    EnergyOperator, GaussianEnergy, PoissonianEnergy, BernoulliEnergy,
-    Hamiltonian, SampledKullbachLeiblerDivergence)
+    EnergyOperator, GaussianEnergy, PoissonianEnergy, InverseGammaLikelihood,
+    BernoulliEnergy, Hamiltonian, SampledKullbachLeiblerDivergence)
 
 from .probing import probe_with_posterior_samples, probe_diagonal, \
     StatCalculator
@@ -78,6 +78,7 @@ from .library.los_response import LOSResponse
 
 from .library.wiener_filter_curvature import WienerFilterCurvature
 from .library.correlated_fields import CorrelatedField, MfCorrelatedField
+from .library.adjust_variances import make_adjust_variances
 
 from . import extra
 
diff --git a/nifty5/library/adjust_variances.py b/nifty5/library/adjust_variances.py
new file mode 100644
index 0000000000000000000000000000000000000000..c1c28ad8661ce5f9a268906234ac2cdbabc188c1
--- /dev/null
+++ b/nifty5/library/adjust_variances.py
@@ -0,0 +1,68 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Copyright(C) 2013-2018 Max-Planck-Society
+#
+# NIFTy is being developed at the Max-Planck-Institut fuer Astrophysik
+# and financially supported by the Studienstiftung des deutschen Volkes.
+
+from __future__ import absolute_import, division, print_function
+
+from ..compat import *
+from ..operators.energy_operators import Hamiltonian, InverseGammaLikelihood
+from ..operators.scaling_operator import ScalingOperator
+
+
+def make_adjust_variances(a, xi, position, samples=[], scaling=None, ic_samp=None):
+    """ Creates a Hamiltonian for constant likelihood optimizations.
+
+    Constructs a Hamiltonian to solve constant likelihood optimizations of the
+    form phi = a * xi under the constraint that phi remains constant.
+
+    Parameters
+    ----------
+    a : Operator
+        Operator which gives the amplitude when evaluated at a position
+    xi : Operator
+        Operator which gives the excitation when evaluated at a position
+    postion : Field, MultiField
+        Position of the whole problem
+    samples : Field, MultiField
+        Residual samples of the whole problem
+    scaling : Float
+        Optional rescaling of the Likelihood
+    ic_samp : Controller
+        Iteration Controller for Hamiltonian
+
+    Returns
+    -------
+    Hamiltonian
+        A Hamiltonian that can be used for further minimization
+    """
+
+    d = a*xi
+    d = (d.conjugate()*d).real
+    n = len(samples)
+    if n > 0:
+        d_eval = 0.
+        for i in range(n):
+            d_eval = d_eval + d(position + samples[i])
+        d_eval = d_eval/n
+    else:
+        d_eval = d(position)
+
+    x = (a.conjugate()*a).real
+    if scaling is not None:
+        x = ScalingOperator(scaling, x.target)(x)
+
+    return Hamiltonian(InverseGammaLikelihood(x, d_eval), ic_samp=ic_samp)
diff --git a/nifty5/linearization.py b/nifty5/linearization.py
index 30a9b57bad11b5e264a0997bde6c0e0e2bbefe10..63f154e321e6c046f572a4125aad3d42f304d0ae 100644
--- a/nifty5/linearization.py
+++ b/nifty5/linearization.py
@@ -93,6 +93,17 @@ class Linearization(object):
     def __rsub__(self, other):
         return (-self).__add__(other)
 
+    def __truediv__(self, other):
+        if isinstance(other, Linearization):
+            return self.__mul__(other.inverse())
+        return self.__mul__(1./other)
+
+    def __rtruediv__(self, other):
+        return self.inverse().__mul__(other)
+
+    def inverse(self):
+        return self.new(1./self._val, makeOp(-1./(self._val**2))(self._jac))
+
     def __mul__(self, other):
         from .sugar import makeOp
         if isinstance(other, Linearization):
@@ -170,11 +181,11 @@ class Linearization(object):
     @staticmethod
     def make_partial_var(field, constants, want_metric=False):
         from .operators.scaling_operator import ScalingOperator
-        from .operators.simple_linear_operators import NullOperator
+        from .operators.block_diagonal_operator import BlockDiagonalOperator
         if len(constants) == 0:
             return Linearization.make_var(field, want_metric)
         else:
             ops = [ScalingOperator(0. if key in constants else 1., dom)
                    for key, dom in field.domain.items()]
-            bdop = BlockDiagonalOperator(fielld.domain, tuple(ops))
+            bdop = BlockDiagonalOperator(field.domain, tuple(ops))
             return Linearization(field, bdop, want_metric=want_metric)
diff --git a/nifty5/multi_field.py b/nifty5/multi_field.py
index 10795f819a834a36687be3eec466f2d926c4dd43..324ee688579807437c749dfb925a0a503653303d 100644
--- a/nifty5/multi_field.py
+++ b/nifty5/multi_field.py
@@ -24,6 +24,7 @@ from . import utilities
 from .compat import *
 from .field import Field
 from .multi_domain import MultiDomain
+from .domain_tuple import DomainTuple
 
 
 class MultiField(object):
@@ -52,6 +53,10 @@ class MultiField(object):
     @staticmethod
     def from_dict(dict, domain=None):
         if domain is None:
+            for dd in dict.values():
+                if not isinstance(dd.domain, DomainTuple):
+                    raise TypeError('Values of dictionary need to be Fields '
+                                    'defined on DomainTuples.')
             domain = MultiDomain.make({key: v._domain
                                        for key, v in dict.items()})
         res = tuple(dict[key] if key in dict else Field(dom, 0)
@@ -61,6 +66,11 @@ class MultiField(object):
     def to_dict(self):
         return {key: val for key, val in zip(self._domain.keys(), self._val)}
 
+    def update(self, other):
+        foo = self.to_dict()
+        foo.update(other.to_dict())
+        return MultiField.from_dict(foo)
+
     def __getitem__(self, key):
         return self._val[self._domain.idx[key]]
 
diff --git a/nifty5/operators/energy_operators.py b/nifty5/operators/energy_operators.py
index a68ea92527a4850bd79976cb25eab87d2e8d9d7c..dbde8b1db46cbd7da0f3ffff6a8427c5ebcc1c11 100644
--- a/nifty5/operators/energy_operators.py
+++ b/nifty5/operators/energy_operators.py
@@ -113,6 +113,22 @@ class PoissonianEnergy(EnergyOperator):
         return res.add_metric(metric)
 
 
+class InverseGammaLikelihood(EnergyOperator):
+    def __init__(self, op, d):
+        self._op, self._d = op, d
+        self._domain = d.domain
+
+    def apply(self, x):
+        x = self._op(x)
+        res = 0.5*(x.log().sum() + (1./x).vdot(self._d))
+        if not isinstance(x, Linearization):
+            return Field.scalar(res)
+        if not x.want_metric:
+            return res
+        metric = SandwichOperator.make(x.jac, makeOp(0.5/(x.val**2)))
+        return res.add_metric(metric)
+
+
 class BernoulliEnergy(EnergyOperator):
     def __init__(self, p, d):
         self._p = p
diff --git a/test/test_energies/test_consistency.py b/test/test_energies/test_consistency.py
index 0bf29ddc76949496e21026bf3a86ab15acee1eec..91a090c75e1941fb605d9cae0ca3260e6414f7ff 100644
--- a/test/test_energies/test_consistency.py
+++ b/test/test_energies/test_consistency.py
@@ -56,6 +56,20 @@ class Energy_Tests(unittest.TestCase):
 #         energy = ift.QuadraticEnergy(s[0], ift.makeOp(s[1]), s[2])
 #         ift.extra.check_value_gradient_consistency(energy)
 
+    @expand(
+        product([
+            ift.GLSpace(15),
+            ift.RGSpace(64, distances=.789),
+            ift.RGSpace([32, 32], distances=.789)
+        ], [4, 78, 23]))
+    def testInverseGammaLikelihood(self, space, seed):
+        model = self.make_model(space_key='s1', space=space, seed=seed)['s1']
+        d = np.random.normal(10, size=space.shape)**2
+        d = ift.Field.from_global_data(space, d)
+        energy = ift.InverseGammaLikelihood(ift.exp, d)
+        ift.extra.check_value_gradient_consistency(energy, model, tol=1e-7)
+
+
     @expand(product(
         [ift.GLSpace(15),
          ift.RGSpace(64, distances=.789),
@@ -65,7 +79,6 @@ class Energy_Tests(unittest.TestCase):
     def testPoissonian(self, space, seed):
         model = self.make_model(
             space_key='s1', space=space, seed=seed)['s1']
-        model = ift.exp(model)
         d = np.random.poisson(120, size=space.shape)
         d = ift.Field.from_global_data(space, d)
         energy = ift.PoissonianEnergy(ift.exp, d)
diff --git a/test/test_multi_field.py b/test/test_multi_field.py
index 580d9ae5591842fb0c8c5af1dba133c86dbad2a6..5a964d10cfacba292e6bcadab9754c1f8d0ed419 100644
--- a/test/test_multi_field.py
+++ b/test/test_multi_field.py
@@ -56,3 +56,19 @@ class Test_Functionality(unittest.TestCase):
         f1 = op2(ift.full(dom, 1))
         for val in f1.values():
             assert_equal((val == 40).all(), True)
+
+    def test_update(self):
+        dom = ift.RGSpace(10)
+        f1 = ift.from_random('normal', domain=dom)
+        f2 = ift.from_random('normal', domain=dom)
+        f_new = ift.MultiField.from_dict({'dom1': f1, 'dom2': f2})
+        f3 = ift.from_random('normal', domain=dom)
+        f4 = ift.from_random('normal', domain=dom)
+        f5 = ift.from_random('normal', domain=dom)
+        f_old = ift.MultiField.from_dict({'dom1': f3, 'dom2': f4, 'dom3': f5})
+
+        updated = f_old.update(f_new).to_dict()
+        updated_true = f_old.to_dict()
+        updated_true.update(f_new.to_dict())
+        for key, val in updated.items():
+            assert_equal((val == updated_true[key]).all(), True)