00001
00002
00003
00004 __copyright__ = """
00005 Copyright 2008 Sean Ross-Ross
00006 """
00007 __license__ = """
00008 This file is part of SLIMpy .
00009
00010 SLIMpy is free software: you can redistribute it and/or modify
00011 it under the terms of the GNU Lesser General Public License as published by
00012 the Free Software Foundation, either version 3 of the License, or
00013 (at your option) any later version.
00014
00015 SLIMpy is distributed in the hope that it will be useful,
00016 but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00018 GNU Lesser General Public License for more details.
00019
00020 You should have received a copy of the GNU Lesser General Public License
00021 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00022 """
00023
00024 from pdb import set_trace
00025
00026
00027
00028
00029
00030 def avoid_float_err(x, lamb):
00031 """
00032 threshhold to a value close to lamb to avoid a floating point error
00033 """
00034
00035 xmax = x.max()
00036 ctr2 = 0
00037 while abs(xmax) > abs(lamb) * 10000 and xmax / 10000. > 1:
00038 r = xmax.item( )
00039 ctr2 += 1
00040 ctr = 0
00041 while r / 10000 > 1:
00042 r = r / 10
00043 ctr += 1
00044
00045 r = int(r)
00046 r -= 1
00047 newxmax = r * ( 10** ctr )
00048 x = x.thr( newxmax )
00049 xmaxold = xmax
00050 xmax = x.max( )
00051 assert xmax > lamb
00052 return x
00053
00054 def thr_project(x,lamb=None):
00055
00056 assert lamb is not None
00057 scal = x.scalar_reduction( 'project' ,lamb=lamb )
00058 return scal
00059
00060 def project( x,lamb=None ):
00061
00062 if lamb == 0:
00063 return x.space.zeros()
00064
00065 csb = x.norm(1)
00066 if csb <= lamb:
00067 return x
00068
00069 x = avoid_float_err(x, lamb)
00070
00071 x.flush()
00072
00073 sorted = x.sort( ascmode=False )
00074 tau = thr_project( sorted, lamb=lamb)
00075
00076 if tau == -1:
00077 return x.space.zeros( )
00078 projected = x.thr( tau )
00079
00080 projected.flush()
00081 return projected
00082