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) > ''' |