Planned maintenance on Wednesday, 2021-01-20, 17:00-18:00. Expect some interruptions during that time

Commit 9c0dde2d authored by Pumpe, Daniel (dpumpe)'s avatar Pumpe, Daniel (dpumpe)

Merge branch 'master' of gitlab.mpcdf.mpg.de:ift/NIFTy

parents 6e2802da 76133243
......@@ -13,7 +13,7 @@ before_script:
- apt-get update
- >
apt-get install -y build-essential python python-pip python-dev git
autoconf gsl-bin libgsl-dev wget python-numpy cython
autoconf gsl-bin libgsl-dev wget python-numpy
- pip install --upgrade -r ci/requirements_base.txt
- chmod +x ci/*.sh
......
# This Makefile implements common tasks needed by developers
# A list of implemented rules can be obtained by the command "make help"
.DEFAULT_GOAL=build
.PHONY .SILENT : help
help :
echo
echo " Implemented targets:"
echo
echo " build build pypmc for python2 and python3"
echo " buildX build pypmc for pythonX only where X is one of {2,3}"
echo " build-sdist build pypmc from the dist directory (python 2 and 3)"
echo " build-sdistX build pypmc from the dist directory (pythonX, X in {2,3})"
echo " check use nosetests to test pypmc with python 2.7 and 3"
echo " checkX use nosetests to test pypmc with python 2.7 or 3,"
echo " where X is one of {2,3}"
echo " check-fast use nosetests to run only quick tests of pypmc"
echo " using nosetests-2.7 and nosetests3"
echo " check-sdist use nosetests-2.7 and nosetests3 to test the distribution"
echo " generated by 'make sdist'"
echo " check-sdistX use nosetests-2.7 or nosetests3 to test the distribution"
echo " generated by 'make sdist', where X is one of {2,3}"
echo " clean delete compiled and temporary files"
echo " coverage produce and show a code coverage report"
echo " Note: Cython modules cannot be analyzed"
echo " distcheck runs 'check', check-sdist', 'run-examples' and"
echo " opens a browser with the built documentation"
echo " doc build the html documentation using sphinx"
echo " doc-pdf build the pdf documentation using sphinx"
echo " help show this message"
echo " run-examples run all examples using python 2 and 3"
echo " sdist make a source distribution"
echo " show-todos show todo marks in the source code"
echo
.PHONY : clean
clean:
#remove build doc
rm -rf ./doc/_build
#remove .pyc files created by python 2.7
rm -f ./*.pyc
find -P . -name '*.pyc' -delete
#remove .pyc files crated by python 3
rm -rf ./__pycache__
find -P . -name __pycache__ -delete
#remove build folder in root directory
rm -rf ./build
#remove cythonized C source and object files
find -P . -name '*.c' -delete
#remove variational binaries only if command line argument specified
find -P . -name '*.so' -delete
#remove backup files
find -P . -name '*~' -delete
#remove files created by coverage
rm -f .coverage
rm -rf coverage
# remove egg info
rm -rf pypmc.egg-info
# remove downloaded seutptools
rm -f setuptools-3.3.zip
# remove dist/
rm -rf dist
.PHONY : build
build : build2
.PHONY : build2
build2 :
python2 setup.py build_ext --inplace
.PHONY :
check : check2
.PHONY : check2
check2 : build2
@ # run tests
nosetests-2.7 --processes=-1 --process-timeout=60
# run tests in parallel
mpirun -n 2 nosetests-2.7
.PHONY : check-fast
check-fast : build
nosetests-2.7 -a '!slow' --processes=-1 --process-timeout=60
nosetests3 -a '!slow' --processes=-1 --process-timeout=60
.PHONY : .build-system-default
.build-system-default :
python setup.py build_ext --inplace
.PHONY : doc
doc : .build-system-default
cd doc && make html
.PHONY : doc-pdf
doc-pdf : .build-system-default
cd doc; make latexpdf
.PHONY : run-examples
run-examples : build
cd examples ; \
for file in $$(ls) ; do \
echo running $${file} with python2 && \
python2 $${file} && \
echo running $${file} with python3 && \
python3 $${file} && \
\
# execute with mpirun if mpi4py appears in the file \
if grep -Fq 'mpi4py' $${file} ; then \
echo "$${file}" is mpi parallelized && \
echo running $${file} in parallel with python2 && \
mpirun -n 2 python2 $${file} && \
echo running $${file} in parallel with python3 && \
mpirun -n 2 python3 $${file} ; \
fi \
; \
done
.PHONY : sdist
sdist :
python setup.py sdist
.PHONY : build-sdist
build-sdist : build-sdist2 build-sdist3
./dist/pypmc*/NUL : sdist
cd dist && tar xaf *.tar.gz && cd *
.PHONY : build-sdist2
build-sdist2 : ./dist/pypmc*/NUL
cd dist/pypmc* && python2 setup.py build
.PHONY : build-sdist3
build-sdist3 : ./dist/pypmc*/NUL
cd dist/pypmc* && python3 setup.py build
.PHONY : check-sdist
check-sdist : check-sdist2 check-sdist3
.PHONY : check-sdist2
check-sdist2 : build-sdist2
cd dist/*/build/lib*2.7 && \
nosetests-2.7 --processes=-1 --process-timeout=60 && \
mpirun -n 2 nosetests-2.7
.PHONY : check-sdist3
check-sdist3 : build-sdist3
cd dist/*/build/lib*3.* && \
nosetests3 --processes=-1 --process-timeout=60 && \
mpirun -n 2 nosetests3
.PHONY : distcheck
distcheck : check check-sdist doc
@ # execute "run-examples" after all other recipes makes are done
make run-examples
xdg-open link_to_documentation
.PHONY : show-todos
grep_cmd = ack-grep -i --no-html --no-cc [^"au""sphinx.ext."]todo
show-todos :
@ # suppress errors here
@ # note that no todo found is considered as error
$(grep_cmd) doc ; \
$(grep_cmd) pypmc ; \
$(grep_cmd) examples ; echo \
.PHONY : coverage
coverage : .build-system-default
rm -rf coverage
nosetests --with-coverage --cover-package=nifty --cover-html --cover-html-dir=coverage
xdg-open coverage/index.html
Metadata-Version: 1.0
Name: ift_nifty
Version: 1.0.6
Summary: Numerical Information Field Theory
Home-page: http://www.mpa-garching.mpg.de/ift/nifty/
Author: Theo Steininger
Author-email: theos@mpa-garching.mpg.de
License: GPLv3
Description: UNKNOWN
Platform: UNKNOWN
......@@ -15,7 +15,7 @@ Summary
a versatile library designed to enable the development of signal
inference algorithms that operate regardless of the underlying spatial
grid and its resolution. Its object-oriented framework is written in
Python, although it accesses libraries written in Cython, C++, and C for
Python, although it accesses libraries written in C++ and C for
efficiency.
NIFTY offers a toolkit that abstracts discretized representations of
......@@ -38,25 +38,25 @@ certain grids, **fields** that are defined on spaces, and **operators**
that apply to fields.
- [Spaces](http://www.mpa-garching.mpg.de/ift/nifty/space.html)
- `rg_space` - *n*-dimensional regular Euclidean grid
- `lm_space` - spherical harmonics
- `gl_space` - Gauss-Legendre grid on the 2-sphere
- `hp_space` - [HEALPix](http://sourceforge.net/projects/healpix/)
- `RGSpace` - *n*-dimensional regular Euclidean grid
- `LMSpace` - spherical harmonics
- `GLSpace` - Gauss-Legendre grid on the 2-sphere
- `HPSpace` - [HEALPix](http://sourceforge.net/projects/healpix/)
grid on the 2-sphere
- [Fields](http://www.mpa-garching.mpg.de/ift/nifty/field.html)
- `field` - generic class for (discretized) fields
- `Field` - generic class for (discretized) fields
<!-- -->
field.conjugate field.dim field.norm
field.dot field.set_val field.weight
Field.conjugate Field.dim Field.norm
Field.dot Field.set_val Field.weight
- [Operators](http://www.mpa-garching.mpg.de/ift/nifty/operator.html)
- `diagonal_operator` - purely diagonal matrices in a specified
- `DiagonalOperator` - purely diagonal matrices in a specified
basis
- `projection_operator` - projections onto subsets of a specified
- `ProjectionOperator` - projections onto subsets of a specified
basis
- `propagator_operator` - information propagator in Wiener filter
- `PropagatorOperator` - information propagator in Wiener filter
theory
- (and more)
- (and more)
......@@ -71,16 +71,18 @@ Installation
- [Python](http://www.python.org/) (v2.7.x)
- [NumPy](http://www.numpy.org/)
- [Cython](http://cython.org/)
### Download
The latest release is tagged **v1.0.7** and is available as a source
package at [](https://gitlab.mpcdf.mpg.de/ift/NIFTy/tags). The current
version can be obtained by cloning the repository:
The current version of Nifty3 can be obtained by cloning the repository:
git clone https://gitlab.mpcdf.mpg.de/ift/NIFTy.git
and switching to the "master" branch:
cd NIFTy
git checkout master
### Installation on Ubuntu
This is for you if you want to install NIFTy on your personal computer
......@@ -90,53 +92,31 @@ Starting with a fresh Ubuntu installation move to a folder like
- Install basic packages like python, python-dev, gsl and others:
sudo apt-get install curl git autoconf
sudo apt-get install python-dev python-pip gsl-bin libgsl0-dev libfreetype6-dev libpng-dev libatlas-base-dev
- Using pip install numpy etc...:
sudo pip install numpy cython
sudo apt-get install curl git autoconf python-dev python-pip python-numpy
- Install pyHealpix:
git clone https://gitlab.mpcdf.mpg.de/ift/pyHealpix.git
cd pyHealpix
autoreconf -i && ./configure && make -j4 && sudo make install
autoreconf -i && ./configure --prefix=$HOME/.local && make -j4 && make install
cd ..
- Finally, NIFTy:
git clone https://gitlab.mpcdf.mpg.de/ift/NIFTy.git
cd nifty
sudo python setup.py install
cd NIFTy
git checkout master
python setup.py install --user
cd ..
### Installation on a Linux cluster
This is for you if you want to install NIFTy on a HPC machine or cluster
that is hosted by your university or institute. Most of the dependencies
will most likely already be there, but you won't have superuser
privileges. In this case, instead of:
sudo python setup.py install
use:
python setup.py install --user
or:
### Installation on Linux systems in general
python setup.py install --install-lib=/SOMEWHERE
in the instruction above. This will install the python packages into
your local user directory.
For pyHealpix, use:
git clone https://gitlab.mpcdf.mpg.de/ift/pyHealpix.git
cd pyHealpix
autoreconf -i && ./configure --prefix=$HOME/.local && make -j4 && make install
cd ..
Since all the "unconventional" packages (i.e. pyHealpix and NIFTy) listed in the
section above are installed
within the home directory of the user, the installation instructions for these
should also work on any Linux machine where you do not have root access.
In this case you have to ensure with your system administrators that the
"standard" dependencies (python, numpy, etc.) are installed system-wide.
### Installation on OS X 10.11
......@@ -147,10 +127,9 @@ MacPorts, missing ones need to be installed manually. It may also be
mentioned that one should only use one package manager, as multiple ones
may cause trouble.
- Install basic packages numpy and cython:
- Install numpy:
sudo port install py27-numpy
sudo port install py27-cython
- Install pyHealpix:
......@@ -159,24 +138,18 @@ may cause trouble.
autoreconf -i && ./configure --prefix=`python-config --prefix` && make -j4 && sudo make install
cd ..
(The third command installs the package system-wide. User-specific
installation would be preferrable, but we haven't found a simple recipe yet
how to determine the installation prefix ...)
- Install NIFTy:
git clone https://gitlab.mpcdf.mpg.de/ift/NIFTy.git
cd nifty
sudo python setup.py install
cd NIFTy
git checkout master
python setup.py install --user
cd ..
### Installation using pypi
NIFTY can be installed using [PyPI](https://pypi.python.org/pypi) and
**pip** by running the following command:
pip install ift_nifty
Alternatively, a private or user specific installation can be done by:
pip install --user ift_nifty
### Running the tests
In oder to run the tests one needs two additional packages:
......@@ -224,4 +197,4 @@ The NIFTY package is licensed under the
[1] Selig et al., "NIFTY - Numerical Information Field Theory - a
versatile Python library for signal inference", [A&A, vol. 554, id.
A26](http://dx.doi.org/10.1051/0004-6361/201321236), 2013;
[arXiv:1301.4499](http://www.arxiv.org/abs/1301.4499)
[arXiv:1301.4499](http://www.arxiv.org/abs/1301.4499)
\ No newline at end of file
#!/bin/bash
git clone -b mpi https://github.com/ultimanet/pyFFTW.git
git clone -b mpi https://github.com/fredros/pyFFTW.git
cd pyFFTW/
CC=mpicc python setup.py build_ext install
cd ..
......
numpy
cython
mpi4py
matplotlib
plotly
......
......@@ -87,7 +87,7 @@ class DomainObject(Versionable, Loggable, object):
@abc.abstractproperty
def shape(self):
""" Returns the shape of the underlying array-like object.
""" The domain-object's shape contribution to the underlying array.
Returns
-------
......
......@@ -36,6 +36,74 @@ from nifty.random import Random
class Field(Loggable, Versionable, object):
""" The discrete representation of a continuous field over multiple spaces.
In NIFTY, Fields are used to store data arrays and carry all the needed
metainformation (i.e. the domain) for operators to be able to work on them.
In addition Field has methods to work with power-spectra.
Parameters
----------
domain : DomainObject
One of the space types NIFTY supports. RGSpace, GLSpace, HPSpace,
LMSpace or PowerSpace. It might also be a FieldArray, which is
an unstructured domain.
val : scalar, numpy.ndarray, distributed_data_object, Field
The values the array should contain after init. A scalar input will
fill the whole array with this scalar. If an array is provided the
array's dimensions must match the domain's.
dtype : type
A numpy.type. Most common are int, float and complex.
distribution_strategy: optional[{'fftw', 'equal', 'not', 'freeform'}]
Specifies which distributor will be created and used.
'fftw' uses the distribution strategy of pyfftw,
'equal' tries to distribute the data as uniform as possible
'not' does not distribute the data at all
'freeform' distribute the data according to the given local data/shape
copy: boolean
Attributes
----------
val : distributed_data_object
domain : DomainObject
See Parameters.
domain_axes : tuple of tuples
Enumerates the axes of the Field
dtype : type
Contains the datatype stored in the Field.
distribution_strategy : string
Name of the used distribution_strategy.
Raise
-----
TypeError
Raised if
*the given domain contains something that is not a DomainObject
instance
*val is an array that has a different dimension than the domain
Examples
--------
>>> a = Field(RGSpace([4,5]),val=2)
>>> a.val
<distributed_data_object>
array([[2, 2, 2, 2, 2],
[2, 2, 2, 2, 2],
[2, 2, 2, 2, 2],
[2, 2, 2, 2, 2]])
>>> a.dtype
dtype('int64')
See Also
--------
distributed_data_object
"""
# ---Initialization methods---
def __init__(self, domain=None, val=None, dtype=None,
......@@ -121,6 +189,37 @@ class Field(Loggable, Versionable, object):
@classmethod
def from_random(cls, random_type, domain=None, dtype=None,
distribution_strategy=None, **kwargs):
""" Draws a random field with the given parameters.
Parameters
----------
cls : class
random_type : String
'pm1', 'normal', 'uniform' are the supported arguments for this
method.
domain : DomainObject
The domain of the output random field
dtype : type
The datatype of the output random field
distribution_strategy : all supported distribution strategies
The distribution strategy of the output random field
Returns
-------
out : Field
The output object.
See Also
--------
power_synthesise
"""
# create a initially empty field
f = cls(domain=domain, dtype=dtype,
distribution_strategy=distribution_strategy)
......@@ -143,7 +242,6 @@ class Field(Loggable, Versionable, object):
@staticmethod
def _parse_random_arguments(random_type, f, **kwargs):
if random_type == "pm1":
random_arguments = {}
......@@ -167,8 +265,57 @@ class Field(Loggable, Versionable, object):
# ---Powerspectral methods---
def power_analyze(self, spaces=None, logarithmic=False, nbin=None, binbounds=None,
decompose_power=False):
def power_analyze(self, spaces=None, logarithmic=False, nbin=None,
binbounds=None, decompose_power=True):
""" Computes the powerspectrum for a subspace of the Field.
Creates a PowerSpace for the space addressed by `spaces` with the given
binning and computes the power spectrum as a Field over this
PowerSpace. This can only be done if the subspace to be analyzed is a
harmonic space.
Parameters
----------
spaces : int *optional*
The subspace for which the powerspectrum shall be computed
(default : None).
if spaces==None : Tries to synthesize for the whole domain
logarithmic : boolean *optional*
True if the output PowerSpace should use logarithmic binning.
{default : False}
nbin : int *optional*
The number of bins the resulting PowerSpace shall have
(default : None).
if nbin==None : maximum number of bins is used
binbounds : array-like *optional*
Inner bounds of the bins (default : None).
if binbounds==None : bins are inferred. Overwrites nbins and log
decompose_power : boolean, *optional*
Whether the analysed signal-space Field is intrinsically real or
complex and if the power spectrum shall therefore be computed
for the real and the imaginary part of the Field separately
(default : True).
Raise
-----
ValueError
Raised if
*len(domain) is != 1 when spaces==None
*len(spaces) is != 1 if not None
*the analyzed space is not harmonic
Returns
-------
out : Field
The output object. It's domain is a PowerSpace and it contains
the power spectrum of 'self's field.
See Also
--------
power_synthesize, PowerSpace
"""
# check if all spaces in `self.domain` are either harmonic or
# power_space instances
for sp in self.domain:
......@@ -210,10 +357,11 @@ class Field(Loggable, Versionable, object):
self.val.get_axes_local_distribution_strategy(
self.domain_axes[space_index])
harmonic_partner = self.domain[space_index]
power_domain = PowerSpace(harmonic_partner=harmonic_partner,
harmonic_domain = self.domain[space_index]
power_domain = PowerSpace(harmonic_domain=harmonic_domain,
distribution_strategy=distribution_strategy,
logarithmic=logarithmic, nbin=nbin, binbounds=binbounds)
logarithmic=logarithmic, nbin=nbin,
binbounds=binbounds)
# extract pindex and rho from power_domain
pindex = power_domain.pindex
......@@ -221,7 +369,7 @@ class Field(Loggable, Versionable, object):
if decompose_power:
hermitian_part, anti_hermitian_part = \
harmonic_partner.hermitian_decomposition(
harmonic_domain.hermitian_decomposition(
self.val,
axes=self.domain_axes[space_index])
......@@ -303,8 +451,50 @@ class Field(Loggable, Versionable, object):
return result_obj
def power_synthesize(self, spaces=None, real_power=True,
real_signal=False, mean=None, std=None):
def power_synthesize(self, spaces=None, real_power=True, real_signal=True,
mean=None, std=None):
""" Converts a power spectrum into a random field realization.
This method draws a Gaussian random field in the harmic partner domain
of a PowerSpace.
Notes
-----
For this the spaces specified by `spaces` must be a PowerSpaces.
Parameters
----------
spaces : {tuple, int, None} *optional*
Specifies the subspace containing all the PowerSpaces which
should be converted (default : None).
if spaces==None : Tries to convert the whole domain.
real_power : boolean *optional*
Determines whether the power spectrum is treated as intrinsically
real or complex (default : True).
real_signal : boolean *optional*
True will result in a purely real signal-space field
(default : True).
mean : float *optional*
The mean of the Gaussian noise field which is used for the Field
synthetization (default : None).
if mean==None : mean will be set to 0
std : float *optional*
The standard deviation of the Gaussian noise field which is used
for the Field synthetization (default : None).
{default : None}
if std==None : std will be set to 1
Returns
-------
out : Field
The output object. A random field created with the power spectrum
stored in the `spaces` in `self`.
See Also
--------
power_analyze
"""
# check if the `spaces` input is valid
spaces = utilities.cast_axis_to_tuple(spaces, len(self.domain))
......@@ -322,8 +512,8 @@ class Field(Loggable, Versionable, object):
result_domain = list(self.domain)
for power_space_index in spaces:
power_space = self.domain[power_space_index]
harmonic_partner = power_space.harmonic_partner
result_domain[power_space_index] = harmonic_partner
harmonic_domain = power_space.harmonic_domain
result_domain[power_space_index] = harmonic_domain
# create random samples: one or two, depending on whether the
# power spectrum is real or complex
......@@ -365,8 +555,8 @@ class Field(Loggable, Versionable, object):