commit-gnuradio
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commit-gnuradio] r5582 - in grc/branches/jblum_work: notes src


From: jblum
Subject: [Commit-gnuradio] r5582 - in grc/branches/jblum_work: notes src
Date: Thu, 31 May 2007 12:37:02 -0600 (MDT)

Author: jblum
Date: 2007-05-31 12:37:02 -0600 (Thu, 31 May 2007)
New Revision: 5582

Modified:
   grc/branches/jblum_work/notes/notes.txt
   grc/branches/jblum_work/src/Constants.py
   grc/branches/jblum_work/src/DataType.py
   grc/branches/jblum_work/src/MathExprParser.py
Log:
improved casting in math expression parser

Modified: grc/branches/jblum_work/notes/notes.txt
===================================================================
--- grc/branches/jblum_work/notes/notes.txt     2007-05-31 13:19:20 UTC (rev 
5581)
+++ grc/branches/jblum_work/notes/notes.txt     2007-05-31 18:37:02 UTC (rev 
5582)
@@ -21,6 +21,8 @@
 -include dtd in saved flow graphs
 -immediate display of tool tips in entry boxes
 -help window for functions in the math expression parser
+-function to import taps from a file
+-fm demod example with expansion of wfm_recv block
 
 ############   wxPython Features:      ####################
 -dump wx running graph to png?
@@ -37,7 +39,6 @@
 ############   Uninteresting Features: ####################
 -add the concept of a current working directory
 -auto param to usrp diagnose dialog
--add a trim option for dangling sockets
 -use popen3 once it works in cygwin
 -arrow like images for socket, to replace in/out strings
 -min/max in DataTypes can be other data types

Modified: grc/branches/jblum_work/src/Constants.py
===================================================================
--- grc/branches/jblum_work/src/Constants.py    2007-05-31 13:19:20 UTC (rev 
5581)
+++ grc/branches/jblum_work/src/Constants.py    2007-05-31 18:37:02 UTC (rev 
5582)
@@ -152,7 +152,7 @@
 #      A state is recorded for each change to the flow graph, the size 
dictates how many states we can record 
 
######################################################################################################
 
-"""    The size of the state saving cache in the gFloGraph (for undo/redo 
functionality)       """
+"""    The size of the state saving cache in the flow graph (for undo/redo 
functionality)      """
 STATE_CACHE_SIZE = 42
 
 
######################################################################################################

Modified: grc/branches/jblum_work/src/DataType.py
===================================================================
--- grc/branches/jblum_work/src/DataType.py     2007-05-31 13:19:20 UTC (rev 
5581)
+++ grc/branches/jblum_work/src/DataType.py     2007-05-31 18:37:02 UTC (rev 
5582)
@@ -82,12 +82,11 @@
        base_type = 'number'
        def parse(self):
                ''' Evaluate the math expressions in the data type.     '''
-               elements = MathExprParser.eval_expr(DataType.parse(self))
-               if len(elements) == 1: num = elements[0]
-               else: raise SyntaxError('Expected a single number.')
+               num = MathExprParser.eval_expr(DataType.parse(self))
                parsed = self.parser(num)       
                self.verify_bounds(parsed)
                return parsed
+
 class Int(Number):
        ''' The integer data type.      '''
        type = 'int'
@@ -120,7 +119,7 @@
        num_bytes = gr.sizeof_gr_complex
        def parser(self, value):
                ''' Return the value as complex.        '''
-               return complex(value)
+               return MathExprParser.verify_complex(value)
        
 
#############################################################################################
  
 #      Special Types
@@ -271,6 +270,7 @@
        def parse(self):
                '''     Verify that the length of the vector is within bounds.  
'''
                elements = MathExprParser.eval_expr(DataType.parse(self))
+               if type(elements) != type(list()): elements = [elements]        
#ensure that elements is a list         
                self.verify_bounds(len(elements))
                return map(lambda v: self.parser(v), elements)
 

Modified: grc/branches/jblum_work/src/MathExprParser.py
===================================================================
--- grc/branches/jblum_work/src/MathExprParser.py       2007-05-31 13:19:20 UTC 
(rev 5581)
+++ grc/branches/jblum_work/src/MathExprParser.py       2007-05-31 18:37:02 UTC 
(rev 5582)
@@ -19,25 +19,22 @@
 """
        MathExprParser.py 
        Josh Blum
-       Take a sting containing numbers, floats, complex 
-       and operators and parse it into a single answer.
+       This file provides:
+       eval_expr for evaluating string expressions,
+       verify_complex, verify_float, verify_int for casting numbers. 
 """
 
 import math,cmath
 from gnuradio import gr
 
-def _number(value='0'):
-       ''' The parser method used for numeric entries. '''
-       return complex(value)
-
 _ORDER_OF_OPS = ('^-', '^', '*', '/', '-', '+')
 
 _WHITESPACE = (' ', '\t', '')
 
 _CONSTANTS = { #constans must be lower case
-       'pi' : _number(cmath.pi),
-       'e' : _number(cmath.e),
-       'j' : _number(1j),
+       'pi' : complex(cmath.pi),
+       'e' : complex(cmath.e),
+       'j' : complex(1j),
        
        'hamming' : gr.firdes.WIN_HAMMING,      #filter windows
        'hann' : gr.firdes.WIN_HANN,
@@ -50,17 +47,24 @@
 ##     Complex mathematical functions 
 #########################################################
 
+def verify_complex(num):
+       ''' Verify that the number is indeed a number.
+               Raise an exception if number cannot be cast to a complex.
+               Return the value as a complex.  '''
+       try: c_num = complex(num)       #ensure that the num can be complex
+       except: raise ValueError('"%s" is not a number.'%(num,))
+       return c_num
+
 def verify_float(num):
-       ''' Verify that the complex number has no imaginary part.
+       ''' Verify that the number has no imaginary part.
                Raise an exception if the imaginary part is non zero.
                Return the value as a float.    '''
-       try: c_num = complex(num)       #ensure that the num can be complex
-       except ValueError: raise ValueError('"%s" is not a number.'%(num,))
-       if num.imag != 0: raise ValueError('Expected a float but found 
"%s".'%(c_num,))
+       c_num = verify_complex(num)     #ensure that the num can be complex
+       if c_num.imag != 0: raise ValueError('Expected a float but found 
"%s".'%(c_num,))
        return float(c_num.real)
 
 def verify_int(num):
-       ''' Verify that the complex number has no imaginary part.
+       ''' Verify that the number has no imaginary part.
                Verify that the complex number has no decimal part.
                Otherwise raise an exception.
                Return the value as a int       '''
@@ -73,15 +77,15 @@
        sum = 0
        for arg in args: 
                if _is_list(arg): sum = sum + _complex_abs_v(*arg)
-               else: sum = sum + arg.real*arg.real + arg.imag*arg.imag
-       return _number(sum**0.5)
+               else: sum = sum + complex(arg).real*complex(arg).real + 
complex(arg).imag*complex(arg).imag
+       return complex(sum**0.5)
 
 def _complex_real_v(*args):
        ''' Get the real part of a number or vector.    '''
        result = list()
        for arg in args: 
                if _is_list(arg): result.append(_complex_real_v(*arg))
-               else: result.append(_number(arg.real))
+               else: result.append(complex(complex(arg).real))
        return result
 
 def _complex_imag_v(*args):
@@ -89,7 +93,7 @@
        result = list()
        for arg in args:  
                if _is_list(arg): result.append(_complex_imag_v(*arg))
-               else: result.append(_number(arg.real))
+               else: result.append(complex(complex(arg).imag))
        return result
 
 def _complex_conj_v(*args):
@@ -97,12 +101,12 @@
        result = list()
        for arg in args:  
                if _is_list(arg): result.append(_complex_conj_v(*arg))
-               else: result.append(_number(arg.conjugate()))
+               else: result.append(complex(complex(arg).conjugate()))
        return result
 
 def _complex_arg(arg):
        ''' Get the angle of the complex number (radians).      '''
-       return _number(math.atan2(arg.imag, arg.real))
+       return complex(math.atan2(complex(arg).imag, complex(arg).real))
 
 def _handle_filter(filter, *filter_args):
        ''' Pass the filter arguments to the filter function. 
@@ -130,7 +134,10 @@
        for i,arg in enumerate(filter_args):
                if i in floats: filter_args[i] = verify_float(arg)
                if i in ints: filter_args[i] = verify_int(arg)  
-       return list(filter(*filter_args))
+       taps = list(filter(*filter_args))
+       # convert all taps to complex #
+       for i,tap in enumerate(taps): taps[i] = complex(tap)
+       return taps 
 
 _FUNCTIONS = {
        'pow' : lambda b, p: b**p,
@@ -174,52 +181,13 @@
        'root_raised_cosine' : lambda *args: 
_handle_filter(gr.firdes.root_raised_cosine, *args),
        'window' : lambda *args: _handle_filter(gr.firdes.window, *args),
        
-       'floor' : lambda f: _number(math.floor(verify_float(f))),
-       'ceil' : lambda f: _number(math.ceil(verify_float(f))),
-       'radians' : lambda f: _number(math.radians(verify_float(f))),
-       'degrees' : lambda f: _number(math.degrees(verify_float(f))),
-       'fmod' : lambda f1, f2: _number(math.fmod(verify_float(f1), 
verify_float(f2))),
+       'floor' : lambda f: complex(math.floor(verify_float(f))),
+       'ceil' : lambda f: complex(math.ceil(verify_float(f))),
+       'radians' : lambda f: complex(math.radians(verify_float(f))),
+       'degrees' : lambda f: complex(math.degrees(verify_float(f))),
+       'fmod' : lambda f1, f2: complex(math.fmod(verify_float(f1), 
verify_float(f2))),
 }
 
-def _handle_operation(op, arg1, arg2):
-       ''' Handle basic operations specified in the order of operations.
-               All calculations are complex, some vector operations are 
supported.
-               Return the number/list representing the result. '''
-       if op not in _ORDER_OF_OPS: raise NameError('Unknown operator: 
"%s".'%(op))     
-       arg1_is_list = _is_list(arg1)
-       arg2_is_list = _is_list(arg2)
-       # addition and subtraction of vectors #
-       if arg1_is_list and arg2_is_list and \
-               len(arg1) == len(arg2) and op in ('+', '-'):
-               result = list()
-               for i,arg1_elem in enumerate(arg1):
-                       arg2_elem = arg2[i]
-                       result.append(_handle_operation(op, arg1_elem, 
arg2_elem))
-               return result
-       # scalar times vector #
-       if not arg1_is_list and arg2_is_list and op == '*':
-               return map(lambda elem: _handle_operation(op, arg1, elem), arg2)
-       # vector times/divided scalar #
-       if arg1_is_list and not arg2_is_list and op in ('*', '/'):
-               return map(lambda elem: _handle_operation(op, elem, arg2), arg1)
-       # non vectored operations #
-       if not arg1_is_list and not arg2_is_list and \
-               type(_number()) == type(arg1) == type(arg2):    #non vector 
operations
-               if op == '^-':
-                       return arg1**(-1*arg2)
-               elif op == '^':
-                       return arg1**arg2
-               elif op == '*':
-                       return arg1 * arg2
-               elif op == '/':
-                       try: return arg1 / arg2
-                       except ZeroDivisionError: raise 
ZeroDivisionError('Cannot divide "%s" by 0.'%(arg1,))
-               elif op == '+':
-                       return arg1 + arg2
-               elif op == '-':
-                       return arg1 - arg2
-       raise ArithmeticError('Operation of "%s" cannot be performed on "%s", 
"%s".'%(op, arg1, arg2))
-
 #########################################################
 ##     Boolean tests for special characters and symbols
 #########################################################
@@ -231,7 +199,7 @@
 def _is_constant(symbol): return symbol in _CONSTANTS.keys()
 
 def _is_number(symbol):        
-       try: _number(symbol)
+       try: complex(symbol)
        except: return False
        return True
        
@@ -266,6 +234,49 @@
        }[bracket]
        
 #########################################################
+##     Symbolic operations
+#########################################################              
+       
+def _handle_operation(op, arg1, arg2):
+       ''' Handle basic operations specified in the order of operations.
+               All calculations are complex, some vector operations are 
supported.
+               Return the number/list representing the result. '''
+       if op not in _ORDER_OF_OPS: raise NameError('Unknown operator: 
"%s".'%(op))     
+       arg1_is_list = _is_list(arg1)
+       arg2_is_list = _is_list(arg2)
+       # addition and subtraction of vectors #
+       if arg1_is_list and arg2_is_list and \
+               len(arg1) == len(arg2) and op in ('+', '-'):
+               result = list()
+               for i,arg1_elem in enumerate(arg1):
+                       arg2_elem = arg2[i]
+                       result.append(_handle_operation(op, arg1_elem, 
arg2_elem))
+               return result
+       # scalar times vector #
+       if not arg1_is_list and arg2_is_list and op == '*':
+               return map(lambda elem: _handle_operation(op, arg1, elem), arg2)
+       # vector times/divided scalar #
+       if arg1_is_list and not arg2_is_list and op in ('*', '/'):
+               return map(lambda elem: _handle_operation(op, elem, arg2), arg1)
+       # non vectored operations #
+       if not arg1_is_list and not arg2_is_list and \
+               _is_number(arg1) and _is_number(arg2):  #non vector operations
+               if op == '^-':
+                       return arg1**(-1*arg2)
+               elif op == '^':
+                       return arg1**arg2
+               elif op == '*':
+                       return arg1 * arg2
+               elif op == '/':
+                       try: return arg1 / arg2
+                       except ZeroDivisionError: raise 
ZeroDivisionError('Cannot divide "%s" by 0.'%(arg1,))
+               elif op == '+':
+                       return arg1 + arg2
+               elif op == '-':
+                       return arg1 - arg2
+       raise ArithmeticError('Operation of "%s" cannot be performed on "%s", 
"%s".'%(op, arg1, arg2))  
+       
+#########################################################
 ##     Evaluate the expression string 
 #########################################################      
 
@@ -342,7 +353,7 @@
                # substitute in values for constants #
                elif _is_constant(element): nested_elements[i] = 
_CONSTANTS[element]
                # substitute in values for numbers #
-               elif _is_number(element): nested_elements[i] = _number(element) 
        
+               elif _is_number(element): nested_elements[i] = complex(element) 
        
        # handle functions #
        for function in _FUNCTIONS.keys():
                while function in nested_elements:
@@ -384,7 +395,7 @@
                elif _is_comma(element) and _is_comma(last_element):
                        raise SyntaxError('Commas must be separated by 
non-commas.')
                last_element = element
-       if len(vector) == 1 and not _is_comma(last_element) and not 
_is_list(vector[0]): return vector[0]       #return single number
+       if len(vector) == 1 and not _is_comma(last_element): return vector[0]   
#return single number
        return vector   #otherwise return vector
 
 def eval_expr(expr_str):
@@ -398,7 +409,6 @@
        nested_elements = _nest_elements(rectified_elements)
        #print "nested", nested_elements
        simplified = _simplify_nested_elements(nested_elements)
-       if not _is_list(simplified): simplified = [simplified]  #keep it in 
list form
        return simplified
        
 if __name__ == '__main__':





reply via email to

[Prev in Thread] Current Thread [Next in Thread]