00001 """
00002
00003 scalar class complements vector class
00004
00005 """
00006
00007 __copyright__ = """
00008 Copyright 2008 Sean Ross-Ross
00009 """
00010 __license__ = """
00011 This file is part of SLIMpy .
00012
00013 SLIMpy is free software: you can redistribute it and/or modify
00014 it under the terms of the GNU Lesser General Public License as published by
00015 the Free Software Foundation, either version 3 of the License, or
00016 (at your option) any later version.
00017
00018 SLIMpy is distributed in the hope that it will be useful,
00019 but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00021 GNU Lesser General Public License for more details.
00022
00023 You should have received a copy of the GNU Lesser General Public License
00024 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00025 """
00026
00027
00028 from slimpy_base.Environment.InstanceManager import InstanceManager
00029 from numpy import inf
00030 from numpy import int32, float32, float64, complex64
00031 from os.path import join
00032 from re import compile as re_compile
00033 from string import Template
00034 from subprocess import Popen, PIPE
00035
00036
00037 __env__ = InstanceManager()
00038
00039 SFATTR = lambda :join( __env__['slimvars']['RSFBIN'], 'sfattr' )
00040
00041 ATTRMD = lambda **kw: Template( "${attr} < ${file} want=${want} lval=${lval} " ).substitute( **kw )
00042 PROJCMD = lambda **kw: Template( "${project} < ${file} lambda=${lamb}" ).substitute( **kw )
00043
00044 SFPROJECT = lambda :join( __env__['slimvars']['RSFBIN'], 'sfproject' )
00045
00046
00047 class Scalar( object ):
00048 '''
00049 Scalar object contains class methods to work on rsf data
00050 '''
00051
00052 env = InstanceManager()
00053
00054 re_float = re_compile( '[-+]?\d*\.\d*' )
00055
00056 @classmethod
00057 def get_command( cls, cmd ):
00058 '@deprecated: '
00059 if hasattr( cls, cmd ):
00060 return cls(cmd)
00061 else:
00062 raise TypeError('No Scalar command "%s" in RSF ' %cmd)
00063
00064 def __init__(self, cmd):
00065 if not hasattr(self, cmd):
00066 raise TypeError('No Scalar command "%s" in RSF ' %cmd)
00067 self._command_name = cmd
00068
00069 def __call__(self, container, scalar, *args, **kw):
00070 '''
00071 only non classmethod calls methoc given by self._command_name
00072 '''
00073 if not hasattr(self, "_command_name"):
00074 raise AttributeError("scalar class not initialized")
00075
00076 cmd = self._command_name
00077 attr = getattr( self, cmd )
00078 container.node_copy( 'localhost' )
00079 attr( container, scalar, *args, **kw )
00080
00081
00082 def __str__(self):
00083 return "rsf scalar method %s" %self._command_name
00084
00085 def __repr__(self):
00086 return self.__str__( )
00087
00088 @staticmethod
00089 def rms( container, scalar ):
00090 """ Returns the root mean square"""
00091 num = Scalar.attr( container, scalar, want='rms' )
00092 scalar.set( num )
00093
00094 @staticmethod
00095 def max( container, scalar ):
00096 """ Returns the maximum value"""
00097 num = Scalar.attr( container, scalar, want='max' )
00098 scalar.set( num )
00099
00100
00101 @staticmethod
00102 def min( container, scalar ):
00103 """ Returns the minimum value"""
00104 num = Scalar.attr( container, scalar, want='min' )
00105 scalar.set( num )
00106
00107 @staticmethod
00108 def mean( container, scalar ):
00109 """ Returns the mean value"""
00110 num = Scalar.attr( container, scalar, want='mean' )
00111 scalar.set( num )
00112
00113 @staticmethod
00114 def var( container, scalar):
00115 """ Returns the variance"""
00116 num = Scalar.attr( container, scalar, want='var' )
00117 scalar.set( num )
00118
00119 @staticmethod
00120 def sdt( container, scalar ):
00121 """ Returns the root"""
00122 num = Scalar.attr( container, scalar, want='std' )
00123 scalar.set( num )
00124
00125 @staticmethod
00126 def norm( container, scalar, lval=2 ):
00127 """ Returns the lval norm of the vector """
00128 is_inf = lval == inf or (isinstance(lval, str) and lval.lower() == 'inf')
00129
00130 if is_inf :
00131 a1 = Scalar.attr( container, scalar, want='max' )
00132 a2 = Scalar.attr( container, scalar, want='min' )
00133
00134 num = max( abs(a1), abs(a2) )
00135 else:
00136
00137 num = Scalar.attr( container, scalar, want='norm', lval=lval )
00138
00139 scalar.set( num )
00140
00141
00142 @staticmethod
00143 def attr_make_number(atr):
00144 '''
00145 call eval on atr if result is tuple make complex
00146 @param atr: string
00147 @type atr:str
00148 '''
00149
00150 num = eval( atr )
00151 if isinstance(num, tuple):
00152 num = complex( *num )
00153 return num
00154
00155 @staticmethod
00156 def attr( container, scalar, want='norm', lval=2 ):
00157
00158 """
00159 fetches various attributes of the vector.
00160 vector will be flushed prior to the operation.
00161 TODO: make it so that the vector does not flush automatically.
00162 """
00163
00164
00165 command = ATTRMD( attr=SFATTR(),
00166 file=container.get_data( 'localhost' ),
00167 want=want,
00168 lval=lval )
00169
00170 print >> __env__['record']( 1 ,'cmd'), command
00171 p0 = Popen( command, shell=True ,stdout=PIPE,stderr=PIPE)
00172 err = p0.wait()
00173 if err:
00174 lines = p0.stderr.read()
00175 p0.stderr.close()
00176 p0.stdout.close()
00177 raise IOError(err,command +'\n'+ lines)
00178 output = p0.stdout.read()
00179 p0.stderr.close()
00180 p0.stdout.close()
00181
00182 n = output.split( '=' )[-1].split( 'at' )[0]
00183
00184 return Scalar.attr_make_number( n )
00185
00186 @staticmethod
00187 def project( container, scalar, lamb=None):
00188 '''
00189 returns threshold value that will
00190 threshold the vector to a 1-norm of lamb
00191 '''
00192 if lamb is None:
00193 raise TypeError( 'Must specify "lamb=" value' )
00194
00195 command = PROJCMD( project=SFPROJECT(),
00196 file=container.get_data( 'localhost' ),
00197 lamb=lamb,
00198 )
00199
00200 p0 = Popen( command, shell=True ,stdout=PIPE,stderr=PIPE)
00201 err = p0.wait()
00202 if err:
00203 lines = p0.stderr.read()
00204 p0.stderr.close()
00205 p0.stdout.close()
00206 raise IOError(err,command +'\n'+ lines)
00207 n = p0.stdout.read()
00208 p0.stderr.close()
00209 p0.stdout.close()
00210
00211 assert 'tau=' in n
00212
00213 num = n.split('=')[-1].strip()
00214 scalar.set( float( num ) )
00215
00216 @staticmethod
00217 def getitem( container, scalar, item):
00218 "get item-th element from the vector"
00219 if not isinstance( item, int ):
00220 raise TypeError, "getitem got %(item)s expected int"
00221
00222
00223 print >> __env__['record']( 1 ,'cmd' ), "getitem( %s )" %(item)
00224
00225 item = container.readbin( start=item, len=1 )[0]
00226
00227 l = lambda x : ( ( x == int32 and int ) or
00228 ( x == float32 and float ) or
00229 ( x == float64 and float ) or
00230 ( x == complex64 and complex ) )
00231
00232
00233 t = l( type( item ) )
00234
00235
00236
00237 num = t( item )
00238 scalar.set( num )
00239
00240 return
00241