00001
00002
00003 """
00004 general scalar functions that work on SLIMpy scalar objects or
00005 python numbers
00006 """
00007
00008 __copyright__ = """
00009 Copyright 2008 Sean Ross-Ross
00010 """
00011 __license__ = """
00012 This file is part of SLIMpy .
00013
00014 SLIMpy is free software: you can redistribute it and/or modify
00015 it under the terms of the GNU Lesser General Public License as published by
00016 the Free Software Foundation, either version 3 of the License, or
00017 (at your option) any later version.
00018
00019 SLIMpy is distributed in the hope that it will be useful,
00020 but WITHOUT ANY WARRANTY; without even the implied warranty of
00021 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00022 GNU Lesser General Public License for more details.
00023
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00026 """
00027
00028 from slimpy_base.Core.User.Structures.Scalar import *
00029 from numpy import real_if_close as numpy_real_if_close
00030
00031 from slimpy_base.Environment.InstanceManager import InstanceManager
00032 from slimpy_base.utils.RegisterType import register_slimpy_func
00033
00034
00035 __env__ = InstanceManager( )
00036
00037
00038 __all__ = [ "scalar_max",
00039 "scalar_min",
00040 "real_if_close",
00041 "scalar_value",
00042 "scalar_mean" ]
00043
00044 def generate_new_scalar( one, other, func):
00045 """
00046 generate_new_scalar( one, other, func) -> scalar
00047 """
00048 scalar = Scalar( )
00049 trg_scal = Target( scalar )
00050 src_self = Source( one )
00051
00052 other_obj = one._num_src( other )
00053
00054
00055 tag = str(func)
00056 command = general_command( tag, None, src_self,other_obj,trg_scal )
00057 command.func = func
00058
00059 if one.env['slimvars']['keep_tb_info']:
00060 stack = traceback.extract_stack( )
00061 st_list = traceback.format_list( stack[:-3] )
00062 command.tb_info = "".join(st_list)
00063
00064 compack = CommandPack([command], None, None)
00065
00066 __env__['graphmgr'].graphAppend( compack )
00067
00068 return scalar
00069
00070 def scalar_operation( one, other, func ):
00071
00072 if has_num(one) and has_num(other):
00073 return func( get_num(one), get_num(other) )
00074
00075 if is_number(other) or other is None:
00076 return one.gen_new_scal(other, func )
00077 else:
00078 return NotImplemented
00079
00080 class scalar_proxies( object ):
00081 '''
00082 class to help scalar
00083 used to prevent error on pickle function
00084 used instead of defineing functions in the module namespace
00085 '''
00086 def __init__( self, value ):
00087 self.method_name = value
00088
00089 def __call__(self , src_self,other_obj,trg_scal=None ):
00090
00091 method = getattr(self, self.method_name)
00092
00093 val = method( get_num(src_self), get_num(other_obj) )
00094 if trg_scal is None:
00095 return val
00096 else:
00097 trg_scal.set(val)
00098 return
00099
00100 def max( self, one, other ):
00101 return max( one, other )
00102
00103 def min( self, one, other ):
00104 return min( one, other )
00105
00106 def real_if_close(self,one,other):
00107 return numpy_real_if_close( one ).item( )
00108
00109 def _scalar_max( scal1, scal2 ):
00110
00111 return scalar_operation( scal1, scal2, scalar_proxies("max") )
00112
00113
00114
00115
00116
00117 @register_slimpy_func
00118 def scalar_max( *sequence ):
00119 '''
00120 scalar_max(sequence) -> value
00121 scalar_max(a, b, c, ...) -> value
00122
00123 With a single sequence argument, return its largest item.
00124 With two or more arguments, return the largest argument.
00125 '''
00126
00127 assert len(sequence)
00128 if len(sequence) == 1:
00129 sequence = sequence[0]
00130
00131 max2 = lambda scal1, scal2: _scalar_max(scal1, scal2)
00132 return reduce( max2 , sequence)
00133
00134
00135 def _scalar_min( scal1, scal2 ):
00136
00137 return scalar_operation( scal1, scal2, scalar_proxies("min") )
00138
00139
00140
00141
00142
00143 @register_slimpy_func
00144 def scalar_min( *sequence ):
00145 '''
00146 scalar_min(sequence) -> value
00147 scalar_min(a, b, c, ...) -> value
00148
00149 With a single sequence argument, return its smallest item.
00150 With two or more arguments, return the smallest argument.
00151 '''
00152
00153 assert len(sequence)
00154 if len(sequence) == 1:
00155 sequence = sequence[0]
00156
00157 min2 = lambda scal1, scal2: _scalar_min(scal1, scal2)
00158 return reduce( min2 , sequence)
00159
00160
00161
00162
00163
00164 @register_slimpy_func
00165 def real_if_close( scal ):
00166 """
00167 returns a real valued scalar if imaginary part of scal is close to 0
00168 real_if_close( scal ) -> value
00169 """
00170 return scalar_operation( scal, None, scalar_proxies("real_if_close") )
00171
00172
00173
00174
00175
00176 @register_slimpy_func
00177 def scalar_mean( sequence ):
00178 """
00179 scalar_mean( sequence ) -> value
00180 returns the mean value of sequence
00181 """
00182 length = len( sequence )
00183
00184 ssum = sum( sequence ) / length
00185
00186 return ssum
00187
00188
00189
00190
00191
00192
00193 @register_slimpy_func
00194 def scalar_value( scal ):
00195 """
00196 retuns a number if scal is either a number of a SLIMpy scalar object
00197 """
00198 if is_scalar_obj( scal ):
00199 return scal.item()
00200 else:
00201 return scal
00202
00203
00204