From bb4dc7e00d4a87c4a13ed8548bac8e2624ee81b6 Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Wed, 11 Dec 2024 16:46:24 +0000 Subject: [PATCH 01/11] Fix FISTA ISTA maths in docs --- .../cil/optimisation/algorithms/FISTA.py | 41 ++++++------------- 1 file changed, 12 insertions(+), 29 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 05143e8157..4c07e2a572 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -29,11 +29,9 @@ class ISTA(Algorithm): - r"""Iterative Shrinkage-Thresholding Algorithm, see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`. + r"""Iterative Shrinkage-Thresholding Algorithm (ISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`. - Iterative Shrinkage-Thresholding Algorithm (ISTA) - - .. math:: x^{k+1} = \mathrm{prox}_{\alpha^{k} g}(x^{k} - \alpha^{k}\nabla f(x^{k})) + .. math:: x_{k+1} = \mathrm{prox}_{\alpha g}(x_{k} - \alpha\nabla f(x_{k})) is used to solve @@ -45,7 +43,7 @@ class ISTA(Algorithm): Note ---- - For a constant step size, i.e., :math:`a^{k}=a` for :math:`k\geq1`, convergence of ISTA + For a constant step size, :math:`\alpha`, convergence of ISTA is guaranteed if .. math:: \alpha\in(0, \frac{2}{L}), @@ -56,7 +54,7 @@ class ISTA(Algorithm): ---------- initial : DataContainer - Initial guess of ISTA. + Initial guess of ISTA. :math:`x_{0}` f : Function Differentiable function. If `None` is passed, the algorithm will use the ZeroFunction. g : Function or `None` @@ -236,10 +234,9 @@ class FISTA(ISTA): .. math:: \begin{cases} - y_{k} = x_{k} - \alpha\nabla f(x_{k}) \\ - x_{k+1} = \mathrm{prox}_{\alpha g}(y_{k})\\ - t_{k+1} = \frac{1+\sqrt{1+ 4t_{k}^{2}}}{2}\\ - y_{k+1} = x_{k} + \frac{t_{k}-1}{t_{k-1}}(x_{k} - x_{k-1}) + x_{k} = \mathrm{prox}_{\alpha g}(y_{k} - \alpha\nabla f(y_{k}))\\ + t_{k+1} = \frac{1+\sqrt{1+ 4t_{k}^{2}}}{2}\\ + y_{k+1} = x_{k} + \frac{t_{k}-1}{t_{k+1}}(x_{k} - x_{k-1}) \end{cases} is used to solve @@ -249,6 +246,8 @@ class FISTA(ISTA): where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha^{k}` is the :code:`step_size` per iteration. + Note that the above applies for k>0. :math:`x_{0}` and :math:`y_{0}` are initialised to `initial` and :math:t_{1}=1 + Parameters ---------- @@ -319,14 +318,14 @@ def __init__(self, initial, f, g, step_size=None, preconditioner=None, **kwargs step_size=step_size, preconditioner=preconditioner, **kwargs) def update(self): - r"""Performs a single iteration of FISTA + r"""Performs a single iteration of FISTA. For k>=1: .. math:: \begin{cases} - x_{k+1} = \mathrm{prox}_{\alpha g}(y_{k} - \alpha\nabla f(y_{k}))\\ + x_{k} = \mathrm{prox}_{\alpha g}(y_{k} - \alpha\nabla f(y_{k}))\\ t_{k+1} = \frac{1+\sqrt{1+ 4t_{k}^{2}}}{2}\\ - y_{k+1} = x_{k} + \frac{t_{k}-1}{t_{k-1}}(x_{k} - x_{k-1}) + y_{k+1} = x_{k} + \frac{t_{k}-1}{t_{k+1}}(x_{k} - x_{k-1}) \end{cases} """ @@ -349,19 +348,3 @@ def update(self): self.x.subtract(self.x_old, out=self.y) self.y.sapyb(((self.t_old-1)/self.t), self.x, 1.0, out=self.y) - - -if __name__ == "__main__": - - from cil.optimisation.functions import L2NormSquared - from cil.optimisation.algorithms import GD - from cil.framework import ImageGeometry - f = L2NormSquared() - g = L2NormSquared() - ig = ImageGeometry(3, 4, 4) - initial = ig.allocate() - fista = FISTA(initial, f, g, step_size=1443432) - print(fista.is_provably_convergent()) - - gd = GD(initial=initial, objective=f, step_size=1023123) - print(gd.is_provably_convergent()) From bc524d92ced464ed1250fb805f13999ceb01aeb2 Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Thu, 12 Dec 2024 09:16:33 +0000 Subject: [PATCH 02/11] Add maths around k>0 --- Wrappers/Python/cil/optimisation/algorithms/FISTA.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 4c07e2a572..7dd7c515d1 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -246,7 +246,7 @@ class FISTA(ISTA): where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha^{k}` is the :code:`step_size` per iteration. - Note that the above applies for k>0. :math:`x_{0}` and :math:`y_{0}` are initialised to `initial` and :math:t_{1}=1 + Note that the above applies for :math:`k>0`. :math:`x_{0}` and :math:`y_{0}` are initialised to `initial` and :math:`t_{1}=1` Parameters @@ -318,7 +318,7 @@ def __init__(self, initial, f, g, step_size=None, preconditioner=None, **kwargs step_size=step_size, preconditioner=preconditioner, **kwargs) def update(self): - r"""Performs a single iteration of FISTA. For k>=1: + r"""Performs a single iteration of FISTA. For :math:`k>0`: .. math:: From 18817e650baecbee578fff3523a181dbc28a3f7f Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Thu, 12 Dec 2024 11:53:05 +0000 Subject: [PATCH 03/11] Remove max_iteration from ista and fista examples --- Wrappers/Python/cil/optimisation/algorithms/FISTA.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 7dd7c515d1..3d1ae2a88f 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -83,7 +83,7 @@ class ISTA(Algorithm): >>> f = LeastSquares(A, b=b, c=0.5) >>> g = ZeroFunction() >>> ig = Aop.domain - >>> ista = ISTA(initial = ig.allocate(), f = f, g = g, max_iteration=10) + >>> ista = ISTA(initial = ig.allocate(), f = f, g = g) >>> ista.run() @@ -282,7 +282,7 @@ class FISTA(ISTA): >>> f = LeastSquares(A, b=b, c=0.5) >>> g = ZeroFunction() >>> ig = Aop.domain - >>> fista = FISTA(initial = ig.allocate(), f = f, g = g, max_iteration=10) + >>> fista = FISTA(initial = ig.allocate(), f = f, g = g) >>> fista.run() See also From b2829f50643c82e0af1aa08aded98d61499f2e82 Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Thu, 12 Dec 2024 16:13:43 +0000 Subject: [PATCH 04/11] remove other references to changing step size --- Wrappers/Python/cil/optimisation/algorithms/FISTA.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 3d1ae2a88f..3ee4f11960 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -243,8 +243,8 @@ class FISTA(ISTA): .. math:: \min_{x} f(x) + g(x) - where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha^{k}` - is the :code:`step_size` per iteration. + where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha` + is the :code:`step_size`. Note that the above applies for :math:`k>0`. :math:`x_{0}` and :math:`y_{0}` are initialised to `initial` and :math:`t_{1}=1` From a3d0feb6bdd1031089ad4a72d446bd5886949adf Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Thu, 12 Dec 2024 16:14:30 +0000 Subject: [PATCH 05/11] Remove double title for FISTA --- Wrappers/Python/cil/optimisation/algorithms/FISTA.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 3ee4f11960..3cb9c67e0d 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -38,7 +38,7 @@ class ISTA(Algorithm): .. math:: \min_{x} f(x) + g(x) where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha^{k}` - is the :code:`step_size` per iteration. + is the :code:`step_size`. Note ---- @@ -227,9 +227,7 @@ def calculate_objective_function_at_point(self, x): class FISTA(ISTA): - r"""Fast Iterative Shrinkage-Thresholding Algorithm, see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`. - - Fast Iterative Shrinkage-Thresholding Algorithm (FISTA) + r"""Fast Iterative Shrinkage-Thresholding Algorithm (FISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`. .. math:: From 344010c93bb1b954633ab4537f290122c2db08ab Mon Sep 17 00:00:00 2001 From: Laura Murgatroyd <60604372+lauramurgatroyd@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:15:17 +0000 Subject: [PATCH 06/11] Apply suggestions from code review Co-authored-by: Margaret Duff <43645617+MargaretDuff@users.noreply.github.com> Signed-off-by: Laura Murgatroyd <60604372+lauramurgatroyd@users.noreply.github.com> --- Wrappers/Python/cil/optimisation/algorithms/FISTA.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 3cb9c67e0d..7fa52e245b 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -244,7 +244,7 @@ class FISTA(ISTA): where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha` is the :code:`step_size`. - Note that the above applies for :math:`k>0`. :math:`x_{0}` and :math:`y_{0}` are initialised to `initial` and :math:`t_{1}=1` + Note that the above applies for :math:`k\geq 1`. :math:`x_{0}` and :math:`y_{0}` are initialised to `initial` and :math:`t_{1}=1` Parameters @@ -316,7 +316,7 @@ def __init__(self, initial, f, g, step_size=None, preconditioner=None, **kwargs step_size=step_size, preconditioner=preconditioner, **kwargs) def update(self): - r"""Performs a single iteration of FISTA. For :math:`k>0`: + r"""Performs a single iteration of FISTA. For :math:`k\geq 1`: .. math:: From d76268eb6e129bc22496ecd1e13c6c5bf7ef0922 Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Fri, 13 Dec 2024 09:41:52 +0000 Subject: [PATCH 07/11] Remove unneeded members from F/ISTA docs --- docs/source/optimisation.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/source/optimisation.rst b/docs/source/optimisation.rst index 2b6077ec4d..62c56bc0ff 100644 --- a/docs/source/optimisation.rst +++ b/docs/source/optimisation.rst @@ -96,14 +96,12 @@ ISTA ---- .. autoclass:: cil.optimisation.algorithms.ISTA :members: - :special-members: :inherited-members: run, update_objective_interval, max_iteration FISTA ----- .. autoclass:: cil.optimisation.algorithms.FISTA :members: - :special-members: :inherited-members: run, update_objective_interval, max_iteration PDHG From 33c90f869bd6fe060cc4c4a3b4c021101a4ebee1 Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Tue, 17 Dec 2024 10:53:50 +0000 Subject: [PATCH 08/11] Update description in docs --- .../cil/optimisation/algorithms/FISTA.py | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 7fa52e245b..13dfd4f777 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -29,17 +29,17 @@ class ISTA(Algorithm): - r"""Iterative Shrinkage-Thresholding Algorithm (ISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`. - - .. math:: x_{k+1} = \mathrm{prox}_{\alpha g}(x_{k} - \alpha\nabla f(x_{k})) - - is used to solve + r"""Iterative Shrinkage-Thresholding Algorithm (ISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a` is used to solve: .. math:: \min_{x} f(x) + g(x) where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha^{k}` is the :code:`step_size`. + In each update, the algorithm computes: + + .. math:: x_{k+1} = \mathrm{prox}_{\alpha g}(x_{k} - \alpha\nabla f(x_{k})) + Note ---- @@ -227,7 +227,15 @@ def calculate_objective_function_at_point(self, x): class FISTA(ISTA): - r"""Fast Iterative Shrinkage-Thresholding Algorithm (FISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`. + r"""Fast Iterative Shrinkage-Thresholding Algorithm (FISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a` is used to solve: + + .. math:: \min_{x} f(x) + g(x) + + where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha` + is the :code:`step_size`. + + + In each update the algorithm completes the following steps: .. math:: @@ -237,14 +245,7 @@ class FISTA(ISTA): y_{k+1} = x_{k} + \frac{t_{k}-1}{t_{k+1}}(x_{k} - x_{k-1}) \end{cases} - is used to solve - - .. math:: \min_{x} f(x) + g(x) - - where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha` - is the :code:`step_size`. - - Note that the above applies for :math:`k\geq 1`. :math:`x_{0}` and :math:`y_{0}` are initialised to `initial` and :math:`t_{1}=1` + Note that the above applies for :math:`k\geq 1`. For :math:`k\eq 0` :math:`x_{0}` and :math:`y_{0}` are initialised to `initial`, and :math:`t_{1}=1` Parameters From f30d8642adf8804e8e2fa44cab1c28c511e24686 Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Tue, 17 Dec 2024 11:27:34 +0000 Subject: [PATCH 09/11] Further fixes --- .../Python/cil/optimisation/algorithms/FISTA.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 13dfd4f777..35be77c56b 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -33,13 +33,14 @@ class ISTA(Algorithm): .. math:: \min_{x} f(x) + g(x) - where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha^{k}` - is the :code:`step_size`. + where :math:`f` is differentiable, and :math:`g` has a *simple* proximal operator. In each update, the algorithm computes: .. math:: x_{k+1} = \mathrm{prox}_{\alpha g}(x_{k} - \alpha\nabla f(x_{k})) + where :math:`\alpha` is the :code:`step_size`. + Note ---- @@ -229,10 +230,9 @@ class FISTA(ISTA): r"""Fast Iterative Shrinkage-Thresholding Algorithm (FISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a` is used to solve: - .. math:: \min_{x} f(x) + g(x) + .. math:: \min_{x} f(x) + g(x) - where :math:`f` is differentiable, :math:`g` has a *simple* proximal operator and :math:`\alpha` - is the :code:`step_size`. + where :math:`f` is differentiable and :math:`g` has a *simple* proximal operator. In each update the algorithm completes the following steps: @@ -245,7 +245,9 @@ class FISTA(ISTA): y_{k+1} = x_{k} + \frac{t_{k}-1}{t_{k+1}}(x_{k} - x_{k-1}) \end{cases} - Note that the above applies for :math:`k\geq 1`. For :math:`k\eq 0` :math:`x_{0}` and :math:`y_{0}` are initialised to `initial`, and :math:`t_{1}=1` + where :math:`\alpha` is the :code:`step_size`. + + Note that the above applies for :math:`k\geq 1`. For :math:`k=0` :math:`x_{0}` and :math:`y_{0}` are initialised to `initial`, and :math:`t_{1}=1` Parameters From 959d73b26c4cd0ffb1c7cc544802c13d5b80938d Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Tue, 17 Dec 2024 11:36:55 +0000 Subject: [PATCH 10/11] Further rendering issues --- Wrappers/Python/cil/optimisation/algorithms/FISTA.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 35be77c56b..3e2ccd9f2a 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -61,10 +61,10 @@ class ISTA(Algorithm): g : Function or `None` Convex function with *simple* proximal operator. If `None` is passed, the algorithm will use the ZeroFunction. step_size : positive :obj:`float` or child class of :meth:`cil.optimisation.utilities.StepSizeRule`', default = None - Step size for the gradient step of ISTA. If a float is passed, this is used as a constant step size. If a child class of :meth:`cil.optimisation.utilities.StepSizeRule`' is passed then it's method `get_step_size` is called for each update. + Step size for the gradient step of ISTA. If a float is passed, this is used as a constant step size. If a child class of :meth:`cil.optimisation.utilities.StepSizeRule` is passed then its method :meth:`get_step_size` is called for each update. The default :code:`step_size` is a constant :math:`\frac{0.99*2}{L}` or 1 if `f=None`. - preconditioner: class with a `apply` method or a function that takes an initialised CIL function as an argument and modifies a provided `gradient`. - This could be a custom `preconditioner` or one provided in :meth:`~cil.optimisation.utilities.preconditoner`. If None is passed then `self.gradient_update` will remain unmodified. + preconditioner: class with an `apply` method or a function that takes an initialised CIL function as an argument and modifies a provided `gradient`. + This could be a custom `preconditioner` or one provided in :meth:`~cil.optimisation.utilities.preconditoner`. If None is passed then `self.gradient_update` will remain unmodified. kwargs: Keyword arguments @@ -260,9 +260,9 @@ class FISTA(ISTA): g : Function or `None` Convex function with *simple* proximal operator. If `None` is passed, the algorithm will use the ZeroFunction. step_size : positive :obj:`float` or child class of :meth:`cil.optimisation.utilities.StepSizeRule`', default = None - Step size for the gradient step of ISTA. If a float is passed, this is used as a constant step size. If a child class of :meth:`cil.optimisation.utilities.StepSizeRule`' is passed then it's method `get_step_size` is called for each update. + Step size for the gradient step of ISTA. If a float is passed, this is used as a constant step size. If a child class of :meth:`cil.optimisation.utilities.StepSizeRule` is passed then it's method :meth:`get_step_size` is called for each update. The default :code:`step_size` is a constant :math:`\frac{1}{L}` or 1 if `f=None`. - preconditioner: class with a `apply` method or a function that takes an initialised CIL function as an argument and modifies a provided `gradient`. + preconditioner : class with an `apply` method or a function that takes an initialised CIL function as an argument and modifies a provided `gradient`. This could be a custom `preconditioner` or one provided in :meth:`~cil.optimisation.utilities.preconditoner`. If None is passed then `self.gradient_update` will remain unmodified. kwargs: Keyword arguments From 707a89dcf74b6f52142003e7cfaf97e336ff454a Mon Sep 17 00:00:00 2001 From: Murgatroyd Date: Tue, 17 Dec 2024 13:27:32 +0000 Subject: [PATCH 11/11] Punctuation --- Wrappers/Python/cil/optimisation/algorithms/FISTA.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py index 3e2ccd9f2a..c3ea3742a1 100644 --- a/Wrappers/Python/cil/optimisation/algorithms/FISTA.py +++ b/Wrappers/Python/cil/optimisation/algorithms/FISTA.py @@ -29,7 +29,7 @@ class ISTA(Algorithm): - r"""Iterative Shrinkage-Thresholding Algorithm (ISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a` is used to solve: + r"""Iterative Shrinkage-Thresholding Algorithm (ISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`, is used to solve: .. math:: \min_{x} f(x) + g(x) @@ -228,7 +228,7 @@ def calculate_objective_function_at_point(self, x): class FISTA(ISTA): - r"""Fast Iterative Shrinkage-Thresholding Algorithm (FISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a` is used to solve: + r"""Fast Iterative Shrinkage-Thresholding Algorithm (FISTA), see :cite:`BeckTeboulle_b`, :cite:`BeckTeboulle_a`, is used to solve: .. math:: \min_{x} f(x) + g(x) @@ -247,7 +247,7 @@ class FISTA(ISTA): where :math:`\alpha` is the :code:`step_size`. - Note that the above applies for :math:`k\geq 1`. For :math:`k=0` :math:`x_{0}` and :math:`y_{0}` are initialised to `initial`, and :math:`t_{1}=1` + Note that the above applies for :math:`k\geq 1`. For :math:`k=0`, :math:`x_{0}` and :math:`y_{0}` are initialised to `initial`, and :math:`t_{1}=1`. Parameters