00001 """
00002
00003 TODO ..
00004 Document the landweber method
00005 a bit more.
00006
00007
00008 """
00009 __copyright__ = """
00010 Copyright 2008 Sean Ross-Ross
00011 """
00012 __license__ = """
00013 This file is part of SLIMpy .
00014
00015 SLIMpy is free software: you can redistribute it and/or modify
00016 it under the terms of the GNU Lesser General Public License as published by
00017 the Free Software Foundation, either version 3 of the License, or
00018 (at your option) any later version.
00019
00020 SLIMpy is distributed in the hope that it will be useful,
00021 but WITHOUT ANY WARRANTY; without even the implied warranty of
00022 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00023 GNU Lesser General Public License for more details.
00024
00025 You should have received a copy of the GNU Lesser General Public License
00026 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00027 """
00028
00029 """
00030 You may use this code only under the conditions and terms of the
00031 license contained in the file LICENSE provided with this source
00032 code. If you do not agree to these terms you may not use this
00033 software.
00034
00035 Sean Ross-Ross
00036 """
00037
00038
00039 from slimpy_base.SLIMmath.Steppers import OneDimStep1
00040 from SLIMpy.linear_operators import Identity
00041
00042 from slimpy_contrib.ana.utils.AbstractSolver import solver
00043 from itertools import chain
00044
00045
00046 class GenThreshLandweber(solver):
00047
00048 """
00049 --latex
00050 Generalized Thresholded Landweber method using vector and linear operator commands.
00051
00052 Parameters:
00053 \\begin{description}
00054 \\item
00055 A: operator object containing a complete
00056 definition of forward operator and the adjoint operator
00057 \\item
00058 lambdaMax: maximum lambda
00059 \\item
00060 lambdaMin: minimum lambda
00061 \\item
00062 lambdaN: number of steps in iteration from lambdaMax to lambdaMin
00063 \\item
00064 InnerN: number of iterations for any lambda
00065 \\item
00066 data: vector instance
00067 \\item
00068 VERBOSE: verbose if set to True
00069 \\end{description}
00070
00071 Bugs:
00072 None so far, but keep trying.
00073 It is not fool-proof. So, you have to know what you are doing;
00074 i.e., how to use RSF.
00075 """
00076 def __init__( self, OuterN, InnerN, thresh, Update=None, x0=None ):
00077 self.OuterN = OuterN
00078 self.InnerN = InnerN
00079
00080 self.thresh = thresh
00081 self.Update = Update
00082 self.x0 = x0
00083
00084 def __repr__(self):
00085 name = self.__class__.__name__
00086 res1 = [repr( getattr(self,attr) ) for attr in ['OuterN','InnerN','thresh'] ]
00087 res2 = [ "%s=%s"%(attr,repr( getattr(self,attr) )) for attr in ['Update', 'x0'] ]
00088 res = ", ".join( chain(res1,res2) )
00089 return name + "( %(res)s )" %vars()
00090
00091 def solve(self, A, b ):
00092
00093 log = self.env['record'](2,'solver')
00094
00095 print >> log ,'Into GenThreshLandweber'
00096
00097
00098 At_b = A.adj() * b
00099
00100
00101
00102 print >> log , 'Initial guess:'
00103
00104 if self.x0 is None:
00105 x = A.domain().zeros()
00106 else:
00107 x = self.x0
00108
00109 if self.Update is None:
00110 U = Identity( A.range() )
00111 else:
00112 U = self.Update
00113
00114
00115 for i in OneDimStep1(1,self.OuterN):
00116 for j in OneDimStep1(1,self.InnerN):
00117
00118
00119 Ax = A*x
00120
00121 At_Ax = A.adj() * Ax
00122
00123 At_b_x = At_b - At_Ax
00124
00125 xTmp = U * At_b_x + x
00126
00127 thr = self.thresh.choose(data=x,coefs=At_b,i=i,OuterN=self.OuterN,j=j,InnerN=self.InnerN)
00128
00129 x = xTmp.thr(thr)
00130
00131
00132 print >> log ,'Out off GenThreshLandweber '
00133 return x
00134
00135