Skip to content

Commit

Permalink
MAINT: fix broken doc links
Browse files Browse the repository at this point in the history
  • Loading branch information
kohr-h committed Sep 20, 2016
1 parent 097db02 commit cf2fef8
Show file tree
Hide file tree
Showing 24 changed files with 191 additions and 192 deletions.
7 changes: 3 additions & 4 deletions doc/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'sphinx.ext.extlinks',
'sphinx.ext.intersphinx',
'numpydoc'
]
# Use newer 'imgmath' extension if possible
Expand All @@ -63,17 +64,15 @@
}


# Intersphinx to get numpy and other targets
extensions.append('sphinx.ext.intersphinx')
# Intersphinx to get Numpy and other targets
intersphinx_mapping = {
'python': ('http://docs.python.org/', None),
'numpy': ('http://docs.scipy.org/doc/numpy/', None),
'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None),
'matplotlib': ('http://matplotlib.org/', None)}

# Stop autodoc from skipping __init__


# Stop autodoc from skipping __init__
def skip(app, what, name, obj, skip, options):
if (name.startswith('__') and name.endswith('__') and
name not in ['__abstractmethods__',
Expand Down
6 changes: 3 additions & 3 deletions doc/source/dev/extend.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ Extending ODL

ODL is written to be easy to extend with new functionality and classes, and new content is welcome. With that said, not everything fits inside the main library and some ideas are better done as *extension packages*. This may give your package more freedom and allows a faster development cycle and help keep ODL from overflowing with content.

There are several ways to extend ODL, some will be listed below.
There are several ways to extend ODL, some of which are listed below.

Adding Fn spaces
----------------
The abstract spaces `FnBase` and `NtuplesBase` are the workhorses of the ODL space machinery. They are used in both the discrete :math:`R^n` case, as well as data representation for discretized function spaces such as :math:`L^2([0, 1])` in the `DiscretizedSpace` class. These are in general created through the `rn` and `uniform_discr` functions who take an ``impl`` parameter, allowing users to select the backend to use.
The abstract spaces `FnBase` and `NtuplesBase` are the workhorses of the ODL space machinery. They are used in both the discrete :math:`R^n` case, as well as data representation for discretized function spaces such as :math:`L^2([0, 1])` in the `DiscretizedSpace` class. These are in general created through the `rn` and `uniform_discr` functions who take an ``impl`` parameter, allowing users to select the backend to use.

In the core ODL package, there is only a single backend available: `NumpyFn`/`NumpyNtuples`, given by ``impl='numpy'``, which is the default choice. Users can add CUDA support by installing the add-on library odlcuda_, which contains the additional spaces ``CudaFn``/``CudaNtuples``. By using the `rn`/`uniform_discr` functions, users can then seamlessly change the backend of their spaces.

Expand All @@ -20,4 +20,4 @@ As an advanced user, you may need to add additional spaces of this type that can
* Add the following to your library's ``setup.py`` setup call: ``entry_points={'odl.space': ['odl_cuda = odlcuda.odl_plugin']``, where you replace ``odlcuda`` with the name of your plugin.

.. _odlcuda: https://github.com/odlgroup/odlcuda
.. _MPI: https://en.wikipedia.org/wiki/Message_Passing_Interface
.. _MPI: https://en.wikipedia.org/wiki/Message_Passing_Interface
17 changes: 5 additions & 12 deletions doc/source/guide/introduction/about_odl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,21 @@ The main advantages of this approach is that
ODL implements many abstract mathematical notions such as sets, vector spaces and operators. In the
following, a few are shown by example.


Set
===

A `Set` is the fundamental building block of ODL objects. It mirrors the mathematical concept of a
`set`_ in that it can tell if an object belongs to it or not:

>>> interv = odl.Interval(0, 1)
>>> interv = odl.IntervalProd(0, 1)
>>> 0.5 in interv
True
>>> 2.0 in interv
False

The most commonly used sets in ODL are `RealNumbers` (set of all `real numbers`_) and
`IntervalProd` ("Interval product", `rectangular boxes`_ of arbitrary dimension).
For the typical use cases in 1, 2 and 3 dimensions, there are convenience functions
`Interval`, `Rectangle` and `Cuboid`:

>>> rect = odl.Rectangle([0, -1], [1, 1])
>>> rect.min_pt
array([ 0., -1.])
>>> rect[0]
Interval(0.0, 1.0)


LinearSpace
Expand Down Expand Up @@ -80,7 +73,7 @@ integrability etc. on an *abstract* level since there is no obvious way to check
As linear spaces, function spaces support some interesting operations:

>>> import numpy as np
>>> space = odl.FunctionSpace(odl.Interval(0, 2))
>>> space = odl.FunctionSpace(odl.IntervalProd(0, 2))
>>> exp = space.element(np.exp)
>>> exp(np.log(2))
2.0
Expand All @@ -98,7 +91,7 @@ see the :ref:`vectorization_in_depth` guide for instructions on how to write vec
functions.

>>> import numpy as np
>>> space = odl.FunctionSpace(odl.Interval(0, 2))
>>> space = odl.FunctionSpace(odl.IntervalProd(0, 2))
>>> exp = space.element(np.exp)
>>> exp([0, 1, 2])
array([ 1. , 2.71828183, 7.3890561 ])
Expand All @@ -122,7 +115,7 @@ default in the convenience function `uniform_discr`:
>>> l2_discr.exponent
2.0
>>> l2_discr.domain
Interval(0.0, 1.0)
IntervalProd(0.0, 1.0)

Discretizations have a large number of useful functionality, for example the direct and vectorized
sampling of continuously defined functions. If we, for example, want to discretize the function
Expand Down
68 changes: 34 additions & 34 deletions doc/source/guide/introduction/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,31 @@
Getting started
###############

Welcome to the ODL getting started guide. This guide is intended to give you a simple introduction to
ODL and how to work with it. If you need help with a specific function you should look at the `odl API reference<
https://odl.readthedocs.io/odl.html>`_.
Welcome to the ODL getting started guide.
This guide is intended to give you a simple introduction to ODL and how to work with it.
If you need help with a specific function you should look at the `ODL API reference <https://odl.readthedocs.io/odl.html>`_.

The best way to get started with ODL as a user is generally to find one (or more) examples that are relevant to whatver problem you are studying.
These are available in the `examples folder on GitHub <https://github.com/odlgroup/odl/tree/master/examples>`_.
The best way to get started with ODL as a user is generally to find one (or more) examples that are relevant to whatver problem you are studying.
These are available in the `examples folder on GitHub <https://github.com/odlgroup/odl/tree/master/examples>`_.
They are mostly written to be copy-paste friendly and show how to use the respective operators, solvers and spaces in a correct manner.

Example: Solving an inverse problem
===================================
In what follows, we will give an example of the workflow one might have when solving an inverse problem as it is encountered "in real life".
In what follows, we will give an example of the workflow one might have when solving an inverse problem as it is encountered "in real life".
The problem we want to solve is

.. math::
Af = g
Where :math:`A` is the `convolution <https://en.wikipedia.org/wiki/Convolution>`_ operator

.. math::
(Af)(x) = \int f(x) k(x-y) dy
where :math:`k` is the convolution kernel, :math:`f` is the unknown solution and :math:`g` is known data.
As is typical in applications, the convolution operator may not be available in ODL (we'll pretend it's not),
where :math:`k` is the convolution kernel, :math:`f` is the unknown solution and :math:`g` is known data.
As is typical in applications, the convolution operator may not be available in ODL (we'll pretend it's not),
so we will need to implement it.

We start by finding a nice implementation of the convolution operator --
Expand All @@ -37,36 +37,36 @@ and create a wrapping `Operator` for it in ODL.
import odl
import scipy
class Convolution(odl.Operator):
"""Operator calculating the convolution of a kernel with a function.
The operator inherits from ``odl.Operator`` to be able to be used with ODL.
"""
def __init__(self, kernel):
"""Initialize a convolution operator with a known kernel."""
# Store the kernel
self.kernel = kernel
# Initialize the Operator class by calling its __init__ method.
# This sets properties such as domain and range and allows the other
# operator convenience functions to work.
odl.Operator.__init__(self, domain=kernel.space, range=kernel.space,
linear=True)
def _call(self, x):
"""Implement calling the operator by calling scipy."""
return scipy.signal.convolve(self.kernel, x, mode='same')
We can verify that our operator works by calling it on some data.
This can either come from an outside source, or from simulations.
We can verify that our operator works by calling it on some data.
This can either come from an outside source, or from simulations.
ODL also provides a nice range of standard phantoms such as the `cuboid` and `shepp_logan` phantoms:

.. code-block:: python
# Define the space the problem should be solved on.
# Define the space the problem should be solved on.
# Here the square [-1, 1] x [-1, 1] discretized on a 100x100 grid.
space = odl.uniform_discr([-1, -1], [1, 1], [100, 100])
Expand All @@ -81,7 +81,7 @@ ODL also provides a nice range of standard phantoms such as the `cuboid` and `sh
# Apply convolution to phantom to create data
g = A(phantom)
# Display the results using the show method
kernel.show('kernel')
phantom.show('phantom')
Expand All @@ -108,8 +108,8 @@ The adjoint is a generalization of the transpose of a matrix and defined as the
\langle Ax, y \rangle = \langle x, A^*y \rangle
where :math:`\langle x, y \rangle` is the inner product.
It is implemented in odl as `Operator.adjoint`.
Luckily, the convolution operator is self adjoint if the kernel is symmetric, so we can add:
It is implemented in odl as `Operator.adjoint`.
Luckily, the convolution operator is self adjoint if the kernel is symmetric, so we can add:

.. code-block:: python
Expand All @@ -126,14 +126,14 @@ With this addition we are ready to try solving the inverse problem using the `la
# Need operator norm for step length (omega)
opnorm = odl.power_method_opnorm(A)
f = space.zero()
odl.solvers.landweber(A, f, g, niter=100, omega=1/opnorm**2)
f.show('landweber')
.. image:: figures/getting_started_landweber.png

This solution is not very good, mostly due to the ill-posedness of the convolution operator.
This solution is not very good, mostly due to the ill-posedness of the convolution operator.
Other solvers like `conjugate gradient on the normal equations <https://en.wikipedia.org/wiki/Conjugate_gradient_method#Conjugate_gradient_on_the_normal_equations>`_ (`conjugate_gradient_normal`) give similar results:

.. code-block:: python
Expand All @@ -150,15 +150,15 @@ i.e. slightly change the problem such that the obtained solutions have better re
We instead study the problem

.. math::
\min_f \|Af - g\|_2^2 + a \|Bf\|_2^2,
where :math:`B` is a "roughening' operator and :math:`a` is a regularization parameter that determines how strong the regularization should be.
Basically one wants that :math:`Bf` is less smooth than :math:`f` so that the optimum solution is more smooth.
To solve it with the above solvers, we can find the first order optimality conditions

.. math::
2 A^* (Af - g) + 2 a B^* B f =0
This can be rewritten on the form :math:`Tf=b`:
Expand All @@ -167,7 +167,7 @@ This can be rewritten on the form :math:`Tf=b`:
\underbrace{(A^* A + a B^* B)}_T f = \underbrace{A^* g}_b
We first use a multiple of the `IdentityOperator` in ODL as :math:`B`,
We first use a multiple of the `IdentityOperator` in ODL as :math:`B`,
which is also known as 'classical' Tikhonov regularization.
Note that since the operator :math:`T` above is self-adjoint we can use the classical `conjugate_gradient` method instead of `conjugate_gradient_normal`.
This improves both computation time and numerical stability.
Expand All @@ -178,7 +178,7 @@ This improves both computation time and numerical stability.
a = 0.1
T = A.adjoint * A + a * B.adjoint * B
b = A.adjoint(g)
f = space.zero()
odl.solvers.conjugate_gradient(T, f, b, niter=100)
f.show('Tikhonov identity conjugate gradient')
Expand All @@ -194,7 +194,7 @@ What about letting :math:`B` be the `Gradient`?
a = 0.0001
T = A.adjoint * A + a * B.adjoint * B
b = A.adjoint(g)
f = space.zero()
odl.solvers.conjugate_gradient(T, f, b, niter=100)
f.show('Tikhonov gradient conjugate gradient')
Expand Down Expand Up @@ -222,22 +222,22 @@ e.g. `forward_backward_pd`, `chambolle_pock_solver`, etc in the ODL `examples/so
grad = odl.Gradient(space)
lin_ops = [A, grad]
a = 0.001
# Create proximals operators corresponding to the convex conjugate (cconj)
# of the l2 squared and l1 norms.
prox_cc_g = [odl.solvers.proximal_cconj_l2_squared(space, g=g),
odl.solvers.proximal_cconj_l1(grad.range, lam=a)]
# Proximal of the bound constraint 0 <= f <= 1
prox_f = odl.solvers.proximal_box_constraint(space, 0, 1)
# Find scaling constants so that the solver converges.
# See the douglas_rachford_pd documentation for more information.
opnorm_A = odl.power_method_opnorm(A, xstart=g)
opnorm_grad = odl.power_method_opnorm(grad, xstart=g)
sigma = [1 / opnorm_A**2, 1 / opnorm_grad**2]
tau = 1.0
# Solve using the Douglas-Rachford Primal-Dual method
x = space.zero()
odl.solvers.douglas_rachford_pd(x, prox_f, prox_cc_g, lin_ops,
Expand Down
19 changes: 10 additions & 9 deletions doc/source/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,15 @@ Changes
- Removed ``Interval``, ``Rectangle`` and ``Cuboid`` since they were confusing (Capitalized name but not a Cunction) and barely ever used.
Users should instead use ``IntervalProd`` in all cases. (:pull:`537`)
- The following classes have been renamed:
* `LinearSpaceVector` -> `LinearSpaceElement`
* `DiscreteLpVector` -> `DiscreteLpElement`
* `ProductSpaceVector` -> `ProductSpaceElement`
* `DiscretizedSetVector` -> `DiscretizedSetElement`
* `DiscretizedSpaceVector` -> `DiscretizedSpaceElement`
* `FunctionSetVector` -> `FunctionSetElement`
* `FunctionSpaceVector` -> `FunctionSpaceElement`
- Changed parameter style of differential operators from having a `pad_mode` and a separate `edge_order` argument that were mutually exclusive to a single `pad_mode` that covers all cases. Also Added several new pad modes to the differential operators. (:pull:`548`)
* ``LinearSpaceVector`` -> ``LinearSpaceElement``
* ``DiscreteLpVector`` -> ``DiscreteLpElement``
* ``ProductSpaceVector`` -> ``ProductSpaceElement``
* ``DiscretizedSetVector`` -> ``DiscretizedSetElement``
* ``DiscretizedSpaceVector`` -> ``DiscretizedSpaceElement``
* ``FunctionSetVector`` -> ``FunctionSetElement``
* ``FunctionSpaceVector`` -> ``FunctionSpaceElement``
- Changed parameter style of differential operators from having a ``pad_mode`` and a separate ``edge_order`` argument that were mutually exclusive to a single ``pad_mode`` that covers all cases.
Also added several new pad modes to the differential operators. (:pull:`548`)

Bugfixes
--------
Expand Down Expand Up @@ -250,7 +251,7 @@ ODL 0.2 Release Notes (2016-03-11)
This release features the Fourier transform as major addition, along with some minor improvements and fixes.

New Features
~~~~~~~~~~~~
------------

- Add ``FourierTransform`` and ``DiscreteFourierTransform``, where the latter is the fully discrete version not accounting for shift and scaling, and the former approximates the integral transform by taking shifted and scaled grids into account. (:pull:`120`)
- The ``weighting`` attribute in `FnBase` is now public and can be used to initialize a new space.
Expand Down
2 changes: 1 addition & 1 deletion odl/diagnostics/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@


def samples(*sets):
"""Generate some samples from the given sets using their `examples` method.
"""Generate samples from the given sets using their ``examples`` method.
Parameters
----------
Expand Down
2 changes: 1 addition & 1 deletion odl/discr/discr_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ def adjoint(self):

class ResizingOperatorBase(Operator):

"""Base class for `ResizingOperator` and `ResizingOperatorAdjoint`.
"""Base class for `ResizingOperator` and its adjoint.
This is an abstract class used to share code between the forward and
adjoint variants of the resizing operator.
Expand Down
2 changes: 1 addition & 1 deletion odl/discr/discretization.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,7 +525,7 @@ def examples(self):
See Also
--------
FunctionSpace.examples
odl.space.fspace.FunctionSpace.examples
"""
for name, elem in self.uspace.examples:
yield (name, self.element(elem))
Expand Down
2 changes: 1 addition & 1 deletion odl/operator/default_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ def __init__(self, multiplicand, domain=None, range=None):
Parameters
----------
multiplicand : `LinearSpaceElement` or `Number`
multiplicand : `LinearSpaceElement` or scalar
Value to multiply by.
domain : `LinearSpace` or `Field`, optional
Set to which the operator can be applied.
Expand Down
Loading

0 comments on commit cf2fef8

Please sign in to comment.