# Copyright 2019 United Kingdom Research and Innovation# Copyright 2019 The University of Manchester## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License.## Authors:# CIL Developers, listed at: https://github.com/TomographicImaging/CIL/blob/master/NOTICE.txtfromcil.optimisation.algorithmsimportAlgorithmimportnumpyimportlogginglog=logging.getLogger(__name__)
[docs]classCGLS(Algorithm):r'''Conjugate Gradient Least Squares algorithm Problem: .. math:: \min || A x - b ||^2_2 | Parameters : :parameter operator : Linear operator for the inverse problem :parameter initial : Initial guess ( Default initial = 0) :parameter data : Acquired data to reconstruct :parameter tolerance: Tolerance/ Stopping Criterion to end CGLS algorithm Reference: https://web.stanford.edu/group/SOL/software/cgls/ '''def__init__(self,initial=None,operator=None,data=None,tolerance=1e-6,**kwargs):'''initialisation of the algorithm :param operator : Linear operator for the inverse problem :param initial : Initial guess ( Default initial = 0) :param data : Acquired data to reconstruct :param tolerance: Tolerance/ Stopping Criterion to end CGLS algorithm '''super(CGLS,self).__init__(**kwargs)ifinitialisNoneandoperatorisnotNone:initial=operator.domain_geometry().allocate(0)ifinitialisnotNoneandoperatorisnotNoneanddataisnotNone:self.set_up(initial=initial,operator=operator,data=data,tolerance=tolerance)
[docs]defset_up(self,initial,operator,data,tolerance=1e-6):'''initialisation of the algorithm :param operator: Linear operator for the inverse problem :param initial: Initial guess ( Default initial = 0) :param data: Acquired data to reconstruct :param tolerance: Tolerance/ Stopping Criterion to end CGLS algorithm '''log.info("%s setting up",self.__class__.__name__)self.x=initial.copy()self.operator=operatorself.tolerance=toleranceself.r=data-self.operator.direct(self.x)self.s=self.operator.adjoint(self.r)self.p=self.s.copy()self.q=self.operator.range_geometry().allocate()self.norms0=self.s.norm()self.norms=self.s.norm()self.gamma=self.norms0**2self.normx=self.x.norm()self.configured=Truelog.info("%s configured",self.__class__.__name__)
[docs]defflag(self):'''returns whether the tolerance has been reached'''flag=(self.norms<=self.norms0*self.tolerance)or(self.normx*self.tolerance>=1)ifflag:self.update_objective()ifself.iteration>self._iteration[-1]:print(self.verbose_output())print('Tolerance is reached: {}'.format(self.tolerance))returnflag