Commit 268962e3 authored by Martin Reinecke's avatar Martin Reinecke
Browse files

Merge branch 'NIFTy_5' into move_dynamic_prior

parents 4a9980ba 928858f4
......@@ -7,7 +7,7 @@ RUN apt-get update && apt-get install -y \
libfftw3-dev \
python3 python3-pip python3-dev python3-future python3-scipy cython3 \
# Documentation build dependencies
python3-sphinx python3-sphinx-rtd-theme python3-numpydoc \
python3-sphinx python3-sphinx-rtd-theme \
# Testing dependencies
python3-coverage python3-pytest python3-pytest-cov \
# Optional NIFTy dependencies
......
rm -rf docs/build docs/source/mod
sphinx-apidoc -l -e -d 2 -o docs/source/mod nifty5
sphinx-build -b html docs/source/ docs/build/
.. currentmodule:: nifty5
=============
Code Overview
......@@ -37,9 +36,12 @@ Domains
Abstract base class
-------------------
.. currentmodule:: nifty5.domains.domain
One of the fundamental building blocks of the NIFTy5 framework is the *domain*.
Its required capabilities are expressed by the abstract :class:`Domain` class.
Its required capabilities are expressed by the abstract :py:class:`Domain` class.
A domain must be able to answer the following queries:
m
- its total number of data entries (pixels), which is accessible via the
:attr:`~Domain.size` property
......@@ -51,6 +53,8 @@ A domain must be able to answer the following queries:
Unstructured domains
--------------------
.. currentmodule:: nifty5.domains.unstructured_domain
Domains can be either *structured* (i.e. there is geometrical information
associated with them, like position in space and volume factors),
or *unstructured* (meaning that the data points have no associated manifold).
......@@ -62,6 +66,8 @@ Unstructured domains can be described by instances of NIFTy's
Structured domains
------------------
.. currentmodule:: nifty5.domains.structured_domain
In contrast to unstructured domains, these domains have an assigned geometry.
NIFTy requires them to provide the volume elements of their grid cells.
The additional methods are specified in the abstract class
......@@ -81,15 +87,17 @@ The additional methods are specified in the abstract class
NIFTy comes with several concrete subclasses of :class:`StructuredDomain`:
- :class:`RGSpace` represents a regular Cartesian grid with an arbitrary
.. currentmodule:: nifty5.domains
- :class:`rg_space.RGSpace` represents a regular Cartesian grid with an arbitrary
number of dimensions, which is supposed to be periodic in each dimension.
- :class:`HPSpace` and :class:`GLSpace` describe pixelisations of the
2-sphere; their counterpart in harmonic space is :class:`LMSpace`, which
- :class:`hp_space.HPSpace` and :class:`gl_space.GLSpace` describe pixelisations of the
2-sphere; their counterpart in harmonic space is :class:`lm_space.LMSpace`, which
contains spherical harmonic coefficients.
- :class:`PowerSpace` is used to describe one-dimensional power spectra.
- :class:`power_space.PowerSpace` is used to describe one-dimensional power spectra.
Among these, :class:`RGSpace` can be harmonic or not (depending on constructor arguments), :class:`GLSpace`, :class:`HPSpace`, and :class:`PowerSpace` are
pure position domains (i.e. nonharmonic), and :class:`LMSpace` is always
Among these, :class:`rg_space.RGSpace` can be harmonic or not (depending on constructor arguments), :class:`gl_space.GLSpace`, :class:`hp_space.HPSpace`, and :class:`power_space.PowerSpace` are
pure position domains (i.e. nonharmonic), and :class:`lm_space.LMSpace` is always
harmonic.
......@@ -158,7 +166,7 @@ be extracted first, then changed, and a new field has to be created from the
result.
Fields defined on a MultiDomain
------------------------------
-------------------------------
The :class:`MultiField` class can be seen as a dictionary of individual
:class:`Field` s, each identified by a name, which is defined on a
......@@ -300,7 +308,7 @@ As an example one may consider the following combination of ``x``, which is an o
Basic operators
------------
---------------
# FIXME All this is outdated!
Basic operator classes provided by NIFTy are
......
import nifty5
import sphinx_rtd_theme
napoleon_google_docstring = False
napoleon_numpy_docstring = True
napoleon_use_ivar = True
napoleon_use_param = False
napoleon_use_keyword = False
autodoc_member_order = 'groupwise'
numpydoc_show_inherited_class_members = False
numpydoc_class_members_toctree = False
extensions = [
'sphinx.ext.autodoc', 'numpydoc', 'sphinx.ext.autosummary',
'sphinx.ext.napoleon', 'sphinx.ext.imgmath', 'sphinx.ext.viewcode'
'sphinx.ext.napoleon', # Support for NumPy and Google style docstrings
'sphinx.ext.imgmath', # Render math as images
'sphinx.ext.viewcode' # Add links to highlighted source code
]
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
napoleon_google_docstring = False
napoleon_numpy_docstring = True
napoleon_use_ivar = True
project = u'NIFTy5'
copyright = u'2013-2019, Max-Planck-Society'
author = u'Martin Reinecke'
......@@ -29,19 +21,6 @@ version = release[:-2]
language = None
exclude_patterns = []
add_module_names = False
pygments_style = 'sphinx'
todo_include_todos = True
html_theme = "sphinx_rtd_theme"
html_theme_options = {
'collapse_navigation': False,
'display_version': False,
}
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_logo = 'nifty_logo_black.png'
html_static_path = []
html_last_updated_fmt = '%b %d, %Y'
html_domain_indices = False
html_use_index = False
html_show_sourcelink = False
htmlhelp_basename = 'NIFTydoc'
......@@ -104,6 +104,7 @@ with :math:`{R}` the measurement response, which maps the continous signal field
This is called a free theory, as the information Hamiltonian
associate professor
.. math::
\mathcal{H}(d,s)= -\log \mathcal{P}(d,s)= \frac{1}{2} s^\dagger S^{-1} s + \frac{1}{2} (d-R\,s)^\dagger N^{-1} (d-R\,s) + \mathrm{const}
......@@ -179,23 +180,22 @@ NIFTy takes advantage of this formulation in several ways:
The reconstruction of a non-Gaussian signal with unknown covarinance from a non-trivial (tomographic) response is demonstrated in demos/getting_started_3.py. Here, the uncertainty of the field and the power spectrum of its generating process are probed via posterior samples provided by the MGVI algorithm.
+-------------------------------------------------+
+----------------------------------------------------+
| **Output of tomography demo getting_started_3.py** |
+----------------------------------------------------+
| .. image:: images/getting_started_3_setup.png |
| :width: 30 % |
+-------------------------------------------------+
| .. image:: images/getting_started_3_results.png |
| :width: 30 % |
+-------------------------------------------------+
| Output of tomography demo getting_started_3.py. |
| **Top row:** Non-Gaussian signal field, |
| |
+----------------------------------------------------+
| Non-Gaussian signal field, |
| data backprojected into the image domain, power |
| spectrum of underlying Gausssian process. |
| **Bottom row:** Posterior mean field signal |
+----------------------------------------------------+
| .. image:: images/getting_started_3_results.png |
| |
+----------------------------------------------------+
| Posterior mean field signal |
| reconstruction, its uncertainty, and the power |
| spectrum of the process for different posterior |
| samples in comparison to the correct one (thick |
| orange line). |
+-------------------------------------------------+
+----------------------------------------------------+
......@@ -17,6 +17,7 @@
import sys
from functools import reduce
import numpy as np
from mpi4py import MPI
......
......@@ -18,11 +18,10 @@
# Data object module for NIFTy that uses simple numpy ndarrays.
import numpy as np
from numpy import empty, empty_like, exp, full, log
from numpy import absolute, clip, cos, cosh, empty, empty_like, exp, full, log
from numpy import ndarray as data_object
from numpy import ones, sqrt, tanh, vdot, zeros
from numpy import sin, cos, tan, sinh, cosh, sinc
from numpy import absolute, sign, clip
from numpy import ones, sign, sin, sinc, sinh, sqrt, tan, tanh, vdot, zeros
from .random import Random
__all__ = ["ntask", "rank", "master", "local_shape", "data_object", "full",
......
......@@ -111,23 +111,27 @@ def _SlopePowerSpectrum(logk_space, sm, sv, im, iv):
def AmplitudeOperator(s_space, Npixdof, ceps_a, ceps_k, sm, sv, im, iv,
keys=['tau', 'phi'], zero_mode=True):
'''
''' Operator for parametrizing smooth power spectra.
Computes a smooth power spectrum.
Output is defined on a PowerSpace.
Parameters
----------
Npixdof : #pix in dof_space
ceps_a, ceps_k0 : Smoothness parameters in ceps_kernel
eg. ceps_kernel(k) = (a/(1+(k/k0)**2))**2
a = ceps_a, k0 = ceps_k0
sm, sv : slope_mean = expected exponent of power law (e.g. -4),
Npixdof : int
#pix in dof_space
ceps_a : float
Smoothness parameters in ceps_kernel eg. ceps_kernel(k) = (a/(1+(k/k0)**2))**2 a = ceps_a, k0 = ceps_k0
ceps_k0 : float
Smoothness parameters in ceps_kernel eg. ceps_kernel(k) = (a/(1+(k/k0)**2))**2 a = ceps_a, k0 = ceps_k0
sm : float
slope_mean = expected exponent of power law (e.g. -4)
sv : float
slope_variance (default=1)
im, iv : y-intercept_mean, y-intercept_variance of power_slope
im : float
y-intercept_mean
iv : float
y-intercept_variance of power_slope
'''
from ..operators.exp_transform import ExpTransform
......
......@@ -110,11 +110,11 @@ class Linearization(object):
def __truediv__(self, other):
if isinstance(other, Linearization):
return self.__mul__(other.inverse())
return self.__mul__(other.one_over())
return self.__mul__(1./other)
def __rtruediv__(self, other):
return self.inverse().__mul__(other)
return self.one_over().__mul__(other)
def __pow__(self, power):
if not np.isscalar(power):
......@@ -122,9 +122,6 @@ class Linearization(object):
return self.new(self._val**power,
makeOp(self._val**(power-1)).scale(power)(self._jac))
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):
......
......@@ -23,7 +23,6 @@ from .linear_operator import LinearOperator
class DomainTupleFieldInserter(LinearOperator):
def __init__(self, domain, new_space, index, position):
'''Writes the content of a field into one slice of a DomainTuple.
Parameters
......@@ -35,6 +34,7 @@ class DomainTupleFieldInserter(LinearOperator):
position : tuple
Slice in new_space in which the input field shall be written into.
'''
def __init__(self, domain, new_space, index, position):
self._domain = DomainTuple.make(domain)
tgt = list(self.domain)
tgt.insert(index, new_space)
......
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