diff options
| author | Edoardo Pasca <edo.paskino@gmail.com> | 2020-01-06 16:51:02 +0000 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-06 16:51:02 +0000 | 
| commit | f959a1c7f903fb31b40105f48701aadce2bd7b4c (patch) | |
| tree | 6b596f6be0c36b301662b4fbb713bfe0c1e3d88a /Wrappers/Python | |
| parent | 3d3a0958fad475c6b0493ad85459e1c04ba4ba62 (diff) | |
| download | framework-f959a1c7f903fb31b40105f48701aadce2bd7b4c.tar.gz framework-f959a1c7f903fb31b40105f48701aadce2bd7b4c.tar.bz2 framework-f959a1c7f903fb31b40105f48701aadce2bd7b4c.tar.xz framework-f959a1c7f903fb31b40105f48701aadce2bd7b4c.zip  | |
v19.10 docs (#467)
updated docstrings and documentation
Diffstat (limited to 'Wrappers/Python')
18 files changed, 232 insertions, 135 deletions
diff --git a/Wrappers/Python/ccpi/optimisation/algorithms/Algorithm.py b/Wrappers/Python/ccpi/optimisation/algorithms/Algorithm.py index 408a904..48d109e 100755 --- a/Wrappers/Python/ccpi/optimisation/algorithms/Algorithm.py +++ b/Wrappers/Python/ccpi/optimisation/algorithms/Algorithm.py @@ -30,14 +30,15 @@ class Algorithm(object):      '''Base class for iterative algorithms        provides the minimal infrastructure. +        Algorithms are iterables so can be easily run in a for loop. They will        stop as soon as the stop cryterion is met. -      The user is required to implement the set_up, __init__, update and -      and update_objective methods +      The user is required to implement the :code:`set_up`, :code:`__init__`, :code:`update` and +      and :code:`update_objective` methods -      A courtesy method run is available to run n iterations. The method accepts -      a callback function that receives the current iteration number and the actual objective -      value and can be used to trigger print to screens and other user interactions. The run +      A courtesy method :code:`run` is available to run :code:`n` iterations. The method accepts +      a :code:`callback` function that receives the current iteration number and the actual objective +      value and can be used to trigger print to screens and other user interactions. The :code:`run`        method will stop when the stopping cryterion is met.      ''' @@ -45,14 +46,15 @@ class Algorithm(object):          '''Constructor          Set the minimal number of parameters: -            iteration: current iteration number -            max_iteration: maximum number of iterations -            memopt: whether to use memory optimisation () -            timing: list to hold the times it took to run each iteration -            update_objectice_interval: the interval every which we would save the current -                                       objective. 1 means every iteration, 2 every 2 iteration -                                       and so forth. This is by default 1 and should be increased +         +         +        :param max_iteration: maximum number of iterations +        :type max_iteration: int, optional, default 0 +        :param update_objectice_interval: the interval every which we would save the current\ +                                       objective. 1 means every iteration, 2 every 2 iteration\ +                                       and so forth. This is by default 1 and should be increased\                                         when evaluating the objective is computationally expensive. +        :type update_objective_interval: int, optional, default 1          '''          self.iteration = 0          self.__max_iteration = kwargs.get('max_iteration', 0) diff --git a/Wrappers/Python/ccpi/optimisation/algorithms/CGLS.py b/Wrappers/Python/ccpi/optimisation/algorithms/CGLS.py index 57292df..53804c5 100755 --- a/Wrappers/Python/ccpi/optimisation/algorithms/CGLS.py +++ b/Wrappers/Python/ccpi/optimisation/algorithms/CGLS.py @@ -64,9 +64,9 @@ class CGLS(Algorithm):      def set_up(self, x_init, operator, data, tolerance=1e-6):          '''initialisation of the algorithm -        :param operator : Linear operator for the inverse problem -        :param x_init : Initial guess ( Default x_init = 0) -        :param data : Acquired data to reconstruct        +        :param operator: Linear operator for the inverse problem +        :param x_init: Initial guess ( Default x_init = 0) +        :param data: Acquired data to reconstruct                 :param tolerance: Tolerance/ Stopping Criterion to end CGLS algorithm          '''          print("{} setting up".format(self.__class__.__name__, )) @@ -94,6 +94,7 @@ class CGLS(Algorithm):      def update(self): +        '''single iteration'''          self.q = self.operator.direct(self.p)          delta = self.q.squared_norm() @@ -121,9 +122,11 @@ class CGLS(Algorithm):          self.loss.append(a)      def should_stop(self): +        '''stopping criterion'''          return self.flag() or self.max_iteration_stop_cryterion()      def flag(self): +        '''returns whether the tolerance has been reached'''          flag  = (self.norms <= self.norms0 * self.tolerance) or (self.normx * self.tolerance >= 1)          if flag: diff --git a/Wrappers/Python/ccpi/optimisation/algorithms/FISTA.py b/Wrappers/Python/ccpi/optimisation/algorithms/FISTA.py index 8c485b7..15a289d 100755 --- a/Wrappers/Python/ccpi/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/ccpi/optimisation/algorithms/FISTA.py @@ -40,9 +40,9 @@ class FISTA(Algorithm):      Parameters : -      :parameter x_init : Initial guess ( Default x_init = 0) -      :parameter f : Differentiable function -      :parameter g : Convex function with " simple " proximal operator +      :param x_init: Initial guess ( Default x_init = 0) +      :param f: Differentiable function +      :param g: Convex function with " simple " proximal operator      Reference: @@ -60,9 +60,11 @@ class FISTA(Algorithm):          initialisation can be done at creation time if all           proper variables are passed or later with set_up -        :param x_init : Initial guess ( Default x_init = 0) -        :param f : Differentiable function -        :param g : Convex function with " simple " proximal operator''' +        Optional parameters: + +        :param x_init: Initial guess ( Default x_init = 0) +        :param f: Differentiable function +        :param g: Convex function with " simple " proximal operator'''          super(FISTA, self).__init__(**kwargs) @@ -72,9 +74,9 @@ class FISTA(Algorithm):      def set_up(self, x_init, f, g=ZeroFunction()):          '''initialisation of the algorithm -        :param x_init : Initial guess ( Default x_init = 0) -        :param f : Differentiable function -        :param g : Convex function with " simple " proximal operator''' +        :param x_init: Initial guess ( Default x_init = 0) +        :param f: Differentiable function +        :param g: Convex function with " simple " proximal operator'''          print("{} setting up".format(self.__class__.__name__, )) diff --git a/Wrappers/Python/ccpi/optimisation/algorithms/PDHG.py b/Wrappers/Python/ccpi/optimisation/algorithms/PDHG.py index db1b8dc..8776875 100644 --- a/Wrappers/Python/ccpi/optimisation/algorithms/PDHG.py +++ b/Wrappers/Python/ccpi/optimisation/algorithms/PDHG.py @@ -34,22 +34,21 @@ class PDHG(Algorithm):      .. math::        \min_{x} f(Kx) + g(x) -    | - -    Parameters :  -        :parameter operator : Linear Operator = K -        :parameter f : Convex function with "simple" proximal of its conjugate.  -        :parameter g : Convex function with "simple" proximal  -        :parameter sigma : Step size parameter for Primal problem -        :parameter tau : Step size parameter for Dual problem +    :param operator: Linear Operator = K +    :param f: Convex function with "simple" proximal of its conjugate.  +    :param g: Convex function with "simple" proximal  +    :param sigma: Step size parameter for Primal problem +    :param tau: Step size parameter for Dual problem -        Remark: Convergence is guaranted provided that +    Remark: Convergence is guaranted provided that -        .. math:: \tau \sigma \|K\|^{2} <1 +    .. math::  +     +      \tau \sigma \|K\|^{2} <1 -    Reference : +    Reference:          (a) A. Chambolle and T. Pock (2011), "A first-order primal–dual algorithm for convex @@ -64,11 +63,14 @@ class PDHG(Algorithm):      def __init__(self, f=None, g=None, operator=None, tau=None, sigma=1.,**kwargs):          '''PDHG algorithm creator -        :param operator : Linear Operator = K -        :param f : Convex function with "simple" proximal of its conjugate.  -        :param g : Convex function with "simple" proximal  -        :param sigma : Step size parameter for Primal problem -        :param tau : Step size parameter for Dual problem''' +        Optional parameters + +        :param operator: a Linear Operator +        :param f: Convex function with "simple" proximal of its conjugate.  +        :param g: Convex function with "simple" proximal  +        :param sigma: Step size parameter for Primal problem +        :param tau: Step size parameter for Dual problem +        '''          super(PDHG, self).__init__(**kwargs) @@ -78,11 +80,11 @@ class PDHG(Algorithm):      def set_up(self, f, g, operator, tau=None, sigma=1.):          '''initialisation of the algorithm -        :param operator : Linear Operator = K -        :param f : Convex function with "simple" proximal of its conjugate.  -        :param g : Convex function with "simple" proximal  -        :param sigma : Step size parameter for Primal problem -        :param tau : Step size parameter for Dual problem''' +        :param operator: a Linear Operator +        :param f: Convex function with "simple" proximal of its conjugate.  +        :param g: Convex function with "simple" proximal  +        :param sigma: Step size parameter for Primal problem +        :param tau: Step size parameter for Dual problem'''          print("{} setting up".format(self.__class__.__name__, )) diff --git a/Wrappers/Python/ccpi/optimisation/algorithms/SIRT.py b/Wrappers/Python/ccpi/optimisation/algorithms/SIRT.py index 50398f4..a59ce5f 100644 --- a/Wrappers/Python/ccpi/optimisation/algorithms/SIRT.py +++ b/Wrappers/Python/ccpi/optimisation/algorithms/SIRT.py @@ -35,27 +35,26 @@ class SIRT(Algorithm):      .. math::   -    A x = b -    | - -    Parameters: -         -      :parameter operator : Linear operator for the inverse problem -      :parameter x_init : Initial guess -      :parameter data : Acquired data to reconstruct        -      :parameter constraint : Function proximal method -                   e.g.  x\in[0, 1], IndicatorBox to enforce box constraints -                         Default is None). +      A x = b +     +    :param x_init: Initial guess +    :param operator: Linear operator for the inverse problem +    :param data: Acquired data to reconstruct        +    :param constraint: Function proximal method +                e.g.  :math:`x\in[0, 1]`, :code:`IndicatorBox` to enforce box constraints +                        Default is :code:`None`).      '''      def __init__(self, x_init=None, operator=None, data=None, constraint=None, **kwargs):          '''SIRT algorithm creator -        :param x_init : Initial guess -        :param operator : Linear operator for the inverse problem -        :param data : Acquired data to reconstruct        -        :param constraint : Function proximal method -                   e.g.  x\in[0, 1], IndicatorBox to enforce box constraints -                         Default is None).''' +       Optional parameters: + +      :param x_init: Initial guess +      :param operator: Linear operator for the inverse problem +      :param data: Acquired data to reconstruct        +      :param constraint: Function proximal method +                   e.g.  :math:`x\in[0, 1]`, :code:`IndicatorBox` to enforce box constraints +                         Default is :code:`None`).'''          super(SIRT, self).__init__(**kwargs)          if x_init is not None and operator is not None and data is not None: @@ -64,12 +63,12 @@ class SIRT(Algorithm):      def set_up(self, x_init, operator, data, constraint=None):          '''initialisation of the algorithm -        :param operator : Linear operator for the inverse problem -        :param x_init : Initial guess -        :param data : Acquired data to reconstruct        -        :param constraint : Function proximal method -                   e.g.  x\in[0, 1], IndicatorBox to enforce box constraints -                         Default is None).''' +        :param x_init: Initial guess +        :param operator: Linear operator for the inverse problem +        :param data: Acquired data to reconstruct        +        :param constraint: Function proximal method +                   e.g.  :math:`x\in[0, 1]`, :code:`IndicatorBox` to enforce box constraints +                         Default is :code:`None`).'''          print("{} setting up".format(self.__class__.__name__, ))          self.x = x_init.copy() diff --git a/Wrappers/Python/ccpi/optimisation/functions/BlockFunction.py b/Wrappers/Python/ccpi/optimisation/functions/BlockFunction.py index ee3ad78..57592cd 100644 --- a/Wrappers/Python/ccpi/optimisation/functions/BlockFunction.py +++ b/Wrappers/Python/ccpi/optimisation/functions/BlockFunction.py @@ -52,7 +52,7 @@ class BlockFunction(Function):              :param: x (BlockDataContainer): must have as many rows as self.length -            returns ..math:: sum(f_i(x_i)) +            returns ..math:: \sum(f_i(x_i))          ''' @@ -67,7 +67,7 @@ class BlockFunction(Function):          r'''Convex conjugate of BlockFunction at x             -            .. math:: returns sum(f_i^{*}(x_i)) +            .. math:: returns \sum(f_i^{*}(x_i))          '''                 t = 0                 @@ -80,7 +80,7 @@ class BlockFunction(Function):          r'''Proximal operator of BlockFunction at x:  -                 .. math:: prox_{tau*f}(x) = sum_{i} prox_{tau*f_{i}}(x_{i})  +                 .. math:: prox_{tau*f}(x) = \sum_{i} prox_{tau*f_{i}}(x_{i})           ''' @@ -110,7 +110,7 @@ class BlockFunction(Function):          r'''Proximal operator of the convex conjugate of BlockFunction at x: -            .. math:: prox_{tau*f^{*}}(x) = sum_{i} prox_{tau*f^{*}_{i}}(x_{i})  +            .. math:: prox_{tau*f^{*}}(x) = \sum_{i} prox_{tau*f^{*}_{i}}(x_{i})           '''          if out is None: diff --git a/Wrappers/Python/ccpi/optimisation/functions/FunctionOperatorComposition.py b/Wrappers/Python/ccpi/optimisation/functions/FunctionOperatorComposition.py index 4162134..ed5c1b1 100644 --- a/Wrappers/Python/ccpi/optimisation/functions/FunctionOperatorComposition.py +++ b/Wrappers/Python/ccpi/optimisation/functions/FunctionOperatorComposition.py @@ -26,15 +26,24 @@ from ccpi.optimisation.functions import ScaledFunction  class FunctionOperatorComposition(Function): -    '''Function composition with Operator: (f o A)(x) = f(Ax) +    r'''Function composition with Operator: :math:`(f \otimes A)(x) = f(Ax)` -            : parameter A: operator -            : parameter f: function +    :param A: operator +    :type A: :code:`Operator` +    :param f: function +    :type f: :code:`Function`      '''      def __init__(self, function, operator): -         +        '''creator + +    :param A: operator +    :type A: :code:`Operator` +    :param f: function +    :type f: :code:`Function` +    ''' +          super(FunctionOperatorComposition, self).__init__()          self.function = function      diff --git a/Wrappers/Python/ccpi/optimisation/functions/IndicatorBox.py b/Wrappers/Python/ccpi/optimisation/functions/IndicatorBox.py index ac8978a..9e9e55c 100755 --- a/Wrappers/Python/ccpi/optimisation/functions/IndicatorBox.py +++ b/Wrappers/Python/ccpi/optimisation/functions/IndicatorBox.py @@ -30,20 +30,25 @@ class IndicatorBox(Function):      r'''Indicator function for box constraint        .. math::  -         f(x) = \mathbb{I}_{[a, b]} = \begin{cases} -             -                                            0, if x\in[a, b] -                                            \infty, otherwise                             -                                    \end{cases} +          +         f(x) = \mathbb{I}_{[a, b]} = \begin{cases}   +                                            0, \text{ if } x \in [a, b] \\ +                                            \infty, \text{otherwise} +                                     \end{cases}      '''      def __init__(self,lower=-numpy.inf,upper=numpy.inf): +        '''creator +        :param lower: lower bound +        :type lower: float, default = :code:`-numpy.inf` +        :param upper: upper bound +        :type upper: float, optional, default = :code:`numpy.inf`          super(IndicatorBox, self).__init__()          self.lower = lower          self.upper = upper -         +        '''      def __call__(self,x): diff --git a/Wrappers/Python/ccpi/optimisation/functions/L1Norm.py b/Wrappers/Python/ccpi/optimisation/functions/L1Norm.py index 1c2c43f..1fcfcca 100644 --- a/Wrappers/Python/ccpi/optimisation/functions/L1Norm.py +++ b/Wrappers/Python/ccpi/optimisation/functions/L1Norm.py @@ -32,13 +32,21 @@ class L1Norm(Function):      r'''L1Norm function:               Cases considered (with/without data):             -                a) .. math:: f(x) = ||x||_{1} -                b) .. math:: f(x) = ||x - b||_{1} +                a) :math:`f(x) = ||x||_{1}` +                b) :math:`f(x) = ||x - b||_{1}`      '''         def __init__(self, **kwargs): -         +        '''creator + +        Cases considered (with/without data):             +        a) :math:`f(x) = ||x||_{1}` +        b) :math:`f(x) = ||x - b||_{1}` + +        :param b: translation of the function +        :type b: :code:`DataContainer`, optional +        '''          super(L1Norm, self).__init__()          self.b = kwargs.get('b',None)          self.shinkage_operator = ShrinkageOperator() diff --git a/Wrappers/Python/ccpi/optimisation/functions/L2NormSquared.py b/Wrappers/Python/ccpi/optimisation/functions/L2NormSquared.py index f5108ba..ef7c698 100644 --- a/Wrappers/Python/ccpi/optimisation/functions/L2NormSquared.py +++ b/Wrappers/Python/ccpi/optimisation/functions/L2NormSquared.py @@ -37,7 +37,15 @@ class L2NormSquared(Function):      '''          def __init__(self, **kwargs): -                                 +        '''creator + +        Cases considered (with/without data):             +                a) .. math:: f(x) = \|x\|^{2}_{2}  +                b) .. math:: f(x) = \|\|x - b\|\|^{2}_{2} + +        :param b:  translation of the function +        :type b: :code:`DataContainer`, optional +        '''                                  super(L2NormSquared, self).__init__()          self.b = kwargs.get('b',None)  diff --git a/Wrappers/Python/ccpi/optimisation/functions/MixedL21Norm.py b/Wrappers/Python/ccpi/optimisation/functions/MixedL21Norm.py index 55e6e53..1af0e77 100755 --- a/Wrappers/Python/ccpi/optimisation/functions/MixedL21Norm.py +++ b/Wrappers/Python/ccpi/optimisation/functions/MixedL21Norm.py @@ -31,11 +31,14 @@ class MixedL21Norm(Function):      ''' -        f(x) = ||x||_{2,1} = \sum |x|_{2}                    +        .. math:: +           +          f(x) = ||x||_{2,1} = \sum |x|_{2}      '''            def __init__(self, **kwargs): - +        '''creator         +        '''          super(MixedL21Norm, self).__init__()                                self.SymTensor = kwargs.get('SymTensor',False) @@ -43,7 +46,7 @@ class MixedL21Norm(Function):          ''' Evaluates L2,1Norm at point x -            :param: x is a BlockDataContainer +            :param x: is a BlockDataContainer          '''          if not isinstance(x, BlockDataContainer): @@ -60,8 +63,9 @@ class MixedL21Norm(Function):      def convex_conjugate(self,x): -        ''' This is the Indicator function of ||\cdot||_{2, \infty} -            which is either 0 if ||x||_{2, \infty} or \infty         +        ''' This is the Indicator function of :math:`||\cdot||_{2, \infty}` which is either 0 if :math:`||x||_{2, \infty}` or :math:`\infty` + +        Notice this returns 0          '''          return 0.0 diff --git a/Wrappers/Python/ccpi/optimisation/operators/FiniteDifferenceOperator.py b/Wrappers/Python/ccpi/optimisation/operators/FiniteDifferenceOperator.py index 0dd7d4b..3c563fb 100644 --- a/Wrappers/Python/ccpi/optimisation/operators/FiniteDifferenceOperator.py +++ b/Wrappers/Python/ccpi/optimisation/operators/FiniteDifferenceOperator.py @@ -27,12 +27,14 @@ class FiniteDiff(LinearOperator):      '''Finite Difference Operator: -            Computes first-order forward/backward differences  -                     on 2D, 3D, 4D ImageData -                     under Neumann/Periodic boundary conditions +        Computes first-order forward/backward differences  +                    on 2D, 3D, 4D ImageData +                    under Neumann/Periodic boundary conditions          Order of the Gradient ( ImageGeometry may contain channels ): -                             + +        .. code:: python           +              Grad_order = ['channels', 'direction_z', 'direction_y', 'direction_x']              Grad_order = ['channels', 'direction_y', 'direction_x']              Grad_order = ['direction_z', 'direction_y', 'direction_x'] @@ -43,7 +45,18 @@ class FiniteDiff(LinearOperator):      def __init__(self, gm_domain, gm_range=None, direction=0, bnd_cond = 'Neumann'): +        '''creator +        :param gm_domain: domain of the operator +        :type gm_domain: :code:`AcquisitionGeometry` or :code:`ImageGeometry` +        :param gm_range: optional range of the operator +        :type gm_range: :code:`AcquisitionGeometry` or :code:`ImageGeometry`, optional +        :param direction: optional axis in the input :code:`DataContainer` along which to calculate the finite differences, default 0 +        :type direction: int, optional, default 0 +        :param bnd_cond: boundary condition, either :code:`Neumann` or :code:`Periodic`. +        :type bnd_cond: str, default :code:`Neumann` +         +        '''          super(FiniteDiff, self).__init__()           self.gm_domain = gm_domain diff --git a/Wrappers/Python/ccpi/optimisation/operators/GradientOperator.py b/Wrappers/Python/ccpi/optimisation/operators/GradientOperator.py index 8e07802..2ff0b20 100644 --- a/Wrappers/Python/ccpi/optimisation/operators/GradientOperator.py +++ b/Wrappers/Python/ccpi/optimisation/operators/GradientOperator.py @@ -35,7 +35,9 @@ CORRELATION_SPACECHANNEL = "SpaceChannels"  class Gradient(LinearOperator): -    """This is a class to compute the first-order forward/backward differences on ImageData + +    r'''Gradient Operator: Computes first-order forward/backward differences on  +        2D, 3D, 4D ImageData under Neumann/Periodic boundary conditions      :param gm_domain: Set up the domain of the function      :type gm_domain: `ImageGeometry` @@ -50,17 +52,17 @@ class Gradient(LinearOperator):            'Space' or 'SpaceChannels', defaults to 'Space'          * *backend* (``str``) --            'c' or 'numpy', defaults to 'c' if correlation is 'SpaceChannels' or channels = 1 -    """ +    +                                                         +        Example (2D):  -    r'''Gradient Operator: .. math:: \nabla : X -> Y            -             -            Computes first-order forward/backward differences  -                     on 2D, 3D, 4D ImageData -                     under Neumann/Periodic boundary conditions -                                                              -                Example (2D): u\in X, \nabla(u) = [\partial_{y} u, \partial_{x} u] -                              u^{*}\in Y, \nabla^{*}(u^{*}) = \partial_{y} v1 + \partial_{x} v2 +        .. math:: +          \nabla : X -> Y \\ +          u\in X, \nabla(u) = [\partial_{y} u, \partial_{x} u] \\ +          u^{*}\in Y, \nabla^{*}(u^{*}) = \partial_{y} v1 + \partial_{x} v2 +             +      '''      #kept here for backwards compatability @@ -126,7 +128,15 @@ class Gradient(LinearOperator):  class Gradient_numpy(LinearOperator):      def __init__(self, gm_domain, bnd_cond = 'Neumann', **kwargs): -         +        '''creator +         +        :param gm_domain: domain of the operator +        :type gm_domain: :code:`AcquisitionGeometry` or :code:`ImageGeometry` +        :param bnd_cond: boundary condition, either :code:`Neumann` or :code:`Periodic`. +        :type bnd_cond: str, optional, default :code:`Neumann` +        :param correlation: optional, :code:`SpaceChannel` or :code:`Space` +        :type correlation: str, optional, default :code:`Space` +        '''          super(Gradient_numpy, self).__init__()           self.gm_domain = gm_domain # Domain of Grad Operator diff --git a/Wrappers/Python/ccpi/optimisation/operators/LinearOperator.py b/Wrappers/Python/ccpi/optimisation/operators/LinearOperator.py index f4d97b8..fb09819 100755 --- a/Wrappers/Python/ccpi/optimisation/operators/LinearOperator.py +++ b/Wrappers/Python/ccpi/optimisation/operators/LinearOperator.py @@ -40,7 +40,15 @@ class LinearOperator(Operator):      @staticmethod
      def PowerMethod(operator, iterations, x_init=None):
 -        '''Power method to calculate iteratively the Lipschitz constant'''
 +        '''Power method to calculate iteratively the Lipschitz constant
 +        
 +        :param operator: input operator
 +        :type operator: :code:`LinearOperator`
 +        :param iterations: number of iterations to run
 +        :type iteration: int
 +        :param x_init: starting point for the iteration in the operator domain
 +        :returns: tuple with: L, list of L at each iteration, the data the iteration worked on.
 +        '''
          # Initialise random
          if x_init is None:
 @@ -73,11 +81,11 @@ class LinearOperator(Operator):      @staticmethod
      def dot_test(operator, domain_init=None, range_init=None, verbose=False):
 -        '''Does a dot linearity test on the operator
 +        r'''Does a dot linearity test on the operator
          Evaluates if the following equivalence holds
 -        :math: ..
 +        .. math::
            Ax\times y = y \times A^Tx
 diff --git a/Wrappers/Python/ccpi/optimisation/operators/LinearOperatorMatrix.py b/Wrappers/Python/ccpi/optimisation/operators/LinearOperatorMatrix.py index 7d18ea1..a84ea94 100644 --- a/Wrappers/Python/ccpi/optimisation/operators/LinearOperatorMatrix.py +++ b/Wrappers/Python/ccpi/optimisation/operators/LinearOperatorMatrix.py @@ -30,6 +30,10 @@ class LinearOperatorMatrix(LinearOperator):      '''Matrix wrapped into a LinearOperator'''      def __init__(self,A): +        '''creator + +        :param A: numpy ndarray representing a matrix +        '''          self.A = A          M_A, N_A = self.A.shape          self.gm_domain = VectorGeometry(N_A) diff --git a/Wrappers/Python/ccpi/optimisation/operators/ScaledOperator.py b/Wrappers/Python/ccpi/optimisation/operators/ScaledOperator.py index c5db47d..d1ad07c 100644 --- a/Wrappers/Python/ccpi/optimisation/operators/ScaledOperator.py +++ b/Wrappers/Python/ccpi/optimisation/operators/ScaledOperator.py @@ -28,9 +28,8 @@ class ScaledOperator(object):      of the result of direct and adjoint of the operator with the scalar.      For the rest it behaves like the operator it holds. -    Args: -       :param operator (Operator): a Operator or LinearOperator -       :param scalar (Number): a scalar multiplier +    :param operator: a Operator or LinearOperator +    :param scalar: a scalar multiplier      Example:         The scaled operator behaves like the following: @@ -47,18 +46,25 @@ class ScaledOperator(object):      '''      def __init__(self, operator, scalar): +        '''creator + +        :param operator: a Operator or LinearOperator +        :param scalar: a scalar multiplier +        :type scalar: float'''          super(ScaledOperator, self).__init__()          if not isinstance (scalar, Number):              raise TypeError('expected scalar: got {}'.format(type(scalar)))          self.scalar = scalar          self.operator = operator      def direct(self, x, out=None): +        '''direct method'''          if out is None:              return self.scalar * self.operator.direct(x, out=out)          else:              self.operator.direct(x, out=out)              out *= self.scalar      def adjoint(self, x, out=None): +        '''adjoint method'''          if self.operator.is_linear():              if out is None:                  return self.scalar * self.operator.adjoint(x, out=out) @@ -68,11 +74,17 @@ class ScaledOperator(object):          else:              raise TypeError('Operator is not linear')      def norm(self, **kwargs): +        '''norm of the operator'''          return numpy.abs(self.scalar) * self.operator.norm(**kwargs)      def range_geometry(self): +        '''range of the operator'''          return self.operator.range_geometry()      def domain_geometry(self): +        '''domain of the operator'''          return self.operator.domain_geometry()      def is_linear(self): +        '''returns whether the operator is linear +         +        :returns: boolean '''          return self.operator.is_linear() diff --git a/Wrappers/Python/ccpi/optimisation/operators/SymmetrizedGradientOperator.py b/Wrappers/Python/ccpi/optimisation/operators/SymmetrizedGradientOperator.py index c85abfa..d82c5c0 100644 --- a/Wrappers/Python/ccpi/optimisation/operators/SymmetrizedGradientOperator.py +++ b/Wrappers/Python/ccpi/optimisation/operators/SymmetrizedGradientOperator.py @@ -30,27 +30,35 @@ class SymmetrizedGradient(LinearOperator):      r'''Symmetrized Gradient Operator:  E: V -> W -            V : range of the Gradient Operator -            W : range of the Symmetrized Gradient           +        V : range of the Gradient Operator +        W : range of the Symmetrized Gradient           + +        Example (2D):  +         +        .. math:: +            v = (v1, v2) \\ -            Example (2D):  -            .. math:: -               v = (v1, v2),  +            Ev = 0.5 * ( \nabla\cdot v + (\nabla\cdot c)^{T} ) \\ -                           Ev = 0.5 * ( \nabla\cdot v + (\nabla\cdot c)^{T} ) -                            -                           \begin{matrix}  -                               \partial_{y} v1 & 0.5 * (\partial_{x} v1 + \partial_{y} v2) \\ -                               0.5 * (\partial_{x} v1 + \partial_{y} v2) & \partial_{x} v2  -                           \end{matrix} -              |                                                       +            \begin{matrix}  +                \partial_{y} v1 & 0.5 * (\partial_{x} v1 + \partial_{y} v2) \\ +                0.5 * (\partial_{x} v1 + \partial_{y} v2) & \partial_{x} v2  +            \end{matrix} +                                                                        '''      CORRELATION_SPACE = "Space"      CORRELATION_SPACECHANNEL = "SpaceChannels"      def __init__(self, gm_domain, bnd_cond = 'Neumann', **kwargs): +        '''creator +        :param gm_domain: domain of the operator +        :param bnd_cond: boundary condition, either :code:`Neumann` or :code:`Periodic`. +        :type bnd_cond: str, optional, default :code:`Neumann` +        :param correlation: :code:`SpaceChannel` or :code:`Channel` +        :type correlation: str, optional, default :code:`Channel` +        '''          super(SymmetrizedGradient, self).__init__()           self.gm_domain = gm_domain diff --git a/Wrappers/Python/ccpi/optimisation/operators/ZeroOperator.py b/Wrappers/Python/ccpi/optimisation/operators/ZeroOperator.py index c37e15e..f677dc2 100644 --- a/Wrappers/Python/ccpi/optimisation/operators/ZeroOperator.py +++ b/Wrappers/Python/ccpi/optimisation/operators/ZeroOperator.py @@ -27,19 +27,19 @@ from ccpi.optimisation.operators import LinearOperator  class ZeroOperator(LinearOperator): -    r'''ZeroOperator:  O: X -> Y,  maps any element of x\in X into the zero element in Y -                       O(x) = O_{Y} +    r'''ZeroOperator:  O: X -> Y,  maps any element of :math:`x\in X` into the zero element :math:`\in Y,  O(x) = O_{Y}` -                       X : gm_domain -                       Y : gm_range ( Default: Y = X ) -                        -                        -                       Note:  -                       .. math:: +        :param gm_domain: domain of the operator  +        :param gm_range: range of the operator, default: same as domain +         +         +        Note:  +         +        .. math:: -                              O^{*}: Y^{*} -> X^{*} (Adjoint) -                        -                              < O(x), y > = < x, O^{*}(y) > +                O^{*}: Y^{*} -> X^{*} \text{(Adjoint)} +         +                < O(x), y > = < x, O^{*}(y) >       '''  | 
