Example #1
0
    def test_preference(self):
        
        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(self.fm1.weighted_average()[i,j], 0.5)
                self.assertAlmostEqual(self.fm2.weighted_average()[i,j], 0.5)


        # To test the update function     
        self.fm1.update(self.a1,0.7)
        self.fm2.update(self.a1,0.7)

        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(self.fm1.weighted_average()[i,j], 0.6)
                vect_sum = wrap(0,1,arg(exp(0.7*2*pi*1j)+exp(0.5*2*pi*1j))/(2*pi)) 
                self.assertAlmostEqual(self.fm2.weighted_average()[i,j],vect_sum) 
                                      
                                      

        
        # To test the keep_peak=True 
        self.fm1.update(self.a1,0.7)
        self.fm2.update(self.a1,0.7)

        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(self.fm1.weighted_average()[i,j], 0.6)
                vect_sum =wrap(0,1,arg(exp(0.7*2*pi*1j)+exp(0.5*2*pi*1j))/(2*pi))
                self.assertAlmostEqual(self.fm2.weighted_average()[i,j],vect_sum)
                                      
        self.fm1.update(self.a2,0.7)
        self.fm2.update(self.a2,0.7)

        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(self.fm1.weighted_average()[i,j], 0.65)
                vect_sum =wrap(0,1,arg(3*exp(0.7*2*pi*1j)+exp(0.5*2*pi*1j))/(2*pi))
                self.assertAlmostEqual(self.fm2.weighted_average()[i,j],vect_sum)

        # to even test more....
        
        self.fm1.update(self.a3,0.9)
        self.fm2.update(self.a3,0.9)
        
        for i in range(3):
            self.assertAlmostEqual(self.fm1.weighted_average()[i,0], 0.65)
            self.assertAlmostEqual(self.fm1.weighted_average()[i,1], 0.7)
            vect_sum = wrap(0,1,arg(3*exp(0.7*2*pi*1j)+exp(0.5*2*pi*1j))/(2*pi))
            self.assertAlmostEqual(self.fm2.weighted_average()[i,0],vect_sum)
            vect_sum = wrap(0,1,arg(3*exp(0.7*2*pi*1j)+exp(0.5*2*pi*1j)+exp(0.9*2*pi*1j))/(2*pi))
            self.assertAlmostEqual(self.fm2.weighted_average()[i,1],vect_sum)
Example #2
0
    def vector_sum(self, d):
        """
        Return the vector sum of the distribution as a tuple (magnitude, avgbinnum).

        Each bin contributes a vector of length equal to its value, at
        a direction corresponding to the bin number.  Specifically,
        the total bin number range is mapped into a direction range
        [0,2pi].

        For a cyclic distribution, the avgbinnum will be a continuous
        measure analogous to the max_value_bin() of the distribution.
        But this quantity has more precision than max_value_bin()
        because it is computed from the entire distribution instead of
        just the peak bin.  However, it is likely to be useful only
        for uniform or very dense sampling; with sparse, non-uniform
        sampling the estimates will be biased significantly by the
        particular samples chosen.

        The avgbinnum is not meaningful when the magnitude is 0,
        because a zero-length vector has no direction.  To find out
        whether such cases occurred, you can compare the value of
        undefined_vals before and after a series of calls to this
        function.

        """
        # vectors are represented in polar form as complex numbers
        h = d._data
        r = h.values()
        theta = d._bins_to_radians(array(h.keys()))
        v_sum = innerproduct(r, exp(theta * 1j))

        magnitude = abs(v_sum)
        direction = arg(v_sum)

        if v_sum == 0:
            d.undefined_vals += 1

        direction_radians = d._radians_to_bins(direction)

        # wrap the direction because arctan2 returns principal values
        wrapped_direction = wrap(d.axis_bounds[0], d.axis_bounds[1],
                                 direction_radians)

        return (magnitude, wrapped_direction)
Example #3
0
    def vector_sum(self, d ):
        """
        Return the vector sum of the distribution as a tuple (magnitude, avgbinnum).

        Each bin contributes a vector of length equal to its value, at
        a direction corresponding to the bin number.  Specifically,
        the total bin number range is mapped into a direction range
        [0,2pi].
        
        For a cyclic distribution, the avgbinnum will be a continuous
        measure analogous to the max_value_bin() of the distribution.
        But this quantity has more precision than max_value_bin()
        because it is computed from the entire distribution instead of
        just the peak bin.  However, it is likely to be useful only
        for uniform or very dense sampling; with sparse, non-uniform
        sampling the estimates will be biased significantly by the
        particular samples chosen.

        The avgbinnum is not meaningful when the magnitude is 0,
        because a zero-length vector has no direction.  To find out
        whether such cases occurred, you can compare the value of
        undefined_vals before and after a series of calls to this
        function.

        """
        # vectors are represented in polar form as complex numbers
        h   = d._data
        r   = h.values()                                  
        theta = d._bins_to_radians(array( h.keys() ))
        v_sum = innerproduct(r, exp(theta*1j))                  

        magnitude = abs(v_sum)
        direction = arg(v_sum)

        if v_sum == 0:
            d.undefined_vals += 1

        direction_radians = d._radians_to_bins(direction)

        # wrap the direction because arctan2 returns principal values
        wrapped_direction = wrap(d.axis_bounds[0], d.axis_bounds[1], direction_radians)
        
        return (magnitude, wrapped_direction) 
    def test_preference(self):

        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(weighted_average(self.fm1)[i, j], 0.5)
                self.assertAlmostEqual(weighted_average(self.fm2)[i, j], 0.5)

        # To test the update function
        self.fm1.update(self.a1, 0.7)
        self.fm2.update(self.a1, 0.7)

        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(weighted_average(self.fm1)[i, j], 0.6)
                vect_sum = wrap(
                    0, 1,
                    arg(exp(0.7 * 2 * pi * 1j) + exp(0.5 * 2 * pi * 1j)) /
                    (2 * pi))
                self.assertAlmostEqual(
                    weighted_average(self.fm2)[i, j], vect_sum)

        # To test the keep_peak=True
        self.fm1.update(self.a1, 0.7)
        self.fm2.update(self.a1, 0.7)

        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(weighted_average(self.fm1)[i, j], 0.6)
                vect_sum = wrap(
                    0, 1,
                    arg(exp(0.7 * 2 * pi * 1j) + exp(0.5 * 2 * pi * 1j)) /
                    (2 * pi))
                self.assertAlmostEqual(
                    weighted_average(self.fm2)[i, j], vect_sum)

        self.fm1.update(self.a2, 0.7)
        self.fm2.update(self.a2, 0.7)

        for i in range(3):
            for j in range(2):
                self.assertAlmostEqual(weighted_average(self.fm1)[i, j], 0.65)
                vect_sum = wrap(
                    0, 1,
                    arg(3 * exp(0.7 * 2 * pi * 1j) + exp(0.5 * 2 * pi * 1j)) /
                    (2 * pi))
                self.assertAlmostEqual(
                    weighted_average(self.fm2)[i, j], vect_sum)

        # to even test more....

        self.fm1.update(self.a3, 0.9)
        self.fm2.update(self.a3, 0.9)

        for i in range(3):
            self.assertAlmostEqual(weighted_average(self.fm1)[i, 0], 0.65)
            self.assertAlmostEqual(weighted_average(self.fm1)[i, 1], 0.7)
            vect_sum = wrap(
                0, 1,
                arg(3 * exp(0.7 * 2 * pi * 1j) + exp(0.5 * 2 * pi * 1j)) /
                (2 * pi))
            self.assertAlmostEqual(weighted_average(self.fm2)[i, 0], vect_sum)
            vect_sum = wrap(
                0, 1,
                arg(3 * exp(0.7 * 2 * pi * 1j) + exp(0.5 * 2 * pi * 1j) +
                    exp(0.9 * 2 * pi * 1j)) / (2 * pi))
            self.assertAlmostEqual(weighted_average(self.fm2)[i, 1], vect_sum)
def get_input_params(old_compat=False):
    """

    Return iterators over list of float values for C++ LISSOM's cx,
    cy, and theta for multiple eyes, as well as sign.


    Expects log file with values held in lines like this::
    
      'Iteration: 000000  [Eye0 [Obj0 cx:02.1 cy:11.6 theta:074.0]]\n'

    or this:
    
      'Iteration: 000000  [Eye0 [Obj0 cx:23.4 cy:10.0 theta:059.6]]  [Eye1 [Obj0 cx:22.6 cy:10.5 theta:059.6]]  [Eye2 [Obj0 cx:21.7 cy:11.1 theta:059.6]]  [Eye3 [Obj0 cx:20.8 cy:11.6 theta:059.6]]\n'
      
    """
    logfile = filename_base + "log"
    print "Reading input params from %s" % logfile
    f = open(logfile, "r")

    # first iter is test in c++ lissom; use to get num eyes
    n_eyes = len(f.readline().split("Eye")[1::])

    input_params = dict([(i, dict(cx=list(), cy=list(), theta=list(), sign=list())) for i in range(n_eyes)])

    lines = f.readlines()
    for line, lineno in zip(lines, range(len(lines))):
        eyes = line.split("Eye")[1::]
        for eye, i in zip(eyes, range(n_eyes)):

            # e.g. eye='1 [Obj0 cx:-0.2 cy:13.8 theta:011.7]]  ['
            cx, cy, theta = [W.split(":")[1].split("]")[0] for W in eye.split(" ")[2:5]]

            if not old_compat:
                for X in ["cx", "cy", "theta"]:
                    input_params[i][X].append(round(float(locals()[X]), 1))
            else:  # old compat: log file with degrees etc
                input_params[i]["cx"].append(float(cx))
                input_params[i]["cy"].append(float(cy))
                input_params[i]["theta"].append(float(theta))

            del cx
            del cy
            del theta

        if len(eyes) > 1:  # CeBALERLT: not general (assuming motion just because more than 1 eye)

            ##### get sign
            X1 = complex(input_params[0]["cx"][lineno], input_params[0]["cy"][lineno])
            X2 = complex(input_params[len(eyes) - 1]["cx"][lineno], input_params[len(eyes) - 1]["cy"][lineno])

            realdir = arg(X2 - X1)

            # for 0<=realdir<2pi (instead of -pi<=realdir<pi)
            if realdir < 0:
                realdir += 2 * pi

            topo_dir = input_params[0]["theta"][lineno] + pi / 2  # dir that will be given to topographica

            # if realdir & topo_dir aren't the same, it's because
            # c lissom used sign=-1 (& the dirs will be pi apart)

            E = 0.05  # (imprecision from getting dir from 1-dp positions)
            if abs(realdir - topo_dir) < E:
                s = 1
            elif pi - E <= abs(realdir - topo_dir) < pi + E:
                s = -1
            else:
                assert False  # if using speed=0, just replace this line with s=0
                # CEBALERT: should actually handle that case!
            #####

            for i in range(n_eyes):
                input_params[i]["sign"].append(s)

    for i in input_params:
        for val in input_params[i]:
            input_params[i][val] = iter(input_params[i][val])

    return len(lines), input_params
Example #6
0
def get_input_params(old_compat=False):
    """

    Return iterators over list of float values for C++ LISSOM's cx,
    cy, and theta for multiple eyes, as well as sign.


    Expects log file with values held in lines like this::

      'Iteration: 000000  [Eye0 [Obj0 cx:02.1 cy:11.6 theta:074.0]]\n'

    or this:

      'Iteration: 000000  [Eye0 [Obj0 cx:23.4 cy:10.0 theta:059.6]]  [Eye1 [Obj0 cx:22.6 cy:10.5 theta:059.6]]  [Eye2 [Obj0 cx:21.7 cy:11.1 theta:059.6]]  [Eye3 [Obj0 cx:20.8 cy:11.6 theta:059.6]]\n'

    """
    logfile = filename_base + 'log'
    print "Reading input params from %s" % logfile
    f = open(logfile, 'r')

    # first iter is test in c++ lissom; use to get num eyes
    n_eyes = len(f.readline().split('Eye')[1::])

    input_params = dict([(i,
                          dict(cx=list(), cy=list(), theta=list(),
                               sign=list())) for i in range(n_eyes)])

    lines = f.readlines()
    for line, lineno in zip(lines, range(len(lines))):
        eyes = line.split('Eye')[1::]
        for eye, i in zip(eyes, range(n_eyes)):

            # e.g. eye='1 [Obj0 cx:-0.2 cy:13.8 theta:011.7]]  ['
            cx, cy, theta = [
                W.split(":")[1].split("]")[0] for W in eye.split(" ")[2:5]
            ]

            if not old_compat:
                for X in ['cx', 'cy', 'theta']:
                    input_params[i][X].append(round(float(locals()[X]), 1))
            else:  # old compat: log file with degrees etc
                input_params[i]['cx'].append(float(cx))
                input_params[i]['cy'].append(float(cy))
                input_params[i]['theta'].append(float(theta))

            del cx
            del cy
            del theta

        if len(
                eyes
        ) > 1:  # CeBALERLT: not general (assuming motion just because more than 1 eye)

            ##### get sign
            X1 = complex(input_params[0]['cx'][lineno],
                         input_params[0]['cy'][lineno])
            X2 = complex(input_params[len(eyes) - 1]['cx'][lineno],
                         input_params[len(eyes) - 1]['cy'][lineno])

            realdir = arg(X2 - X1)

            # for 0<=realdir<2pi (instead of -pi<=realdir<pi)
            if realdir < 0: realdir += 2 * pi

            topo_dir = input_params[0]['theta'][
                lineno] + pi / 2  # dir that will be given to topographica

            # if realdir & topo_dir aren't the same, it's because
            # c lissom used sign=-1 (& the dirs will be pi apart)

            E = 0.05  # (imprecision from getting dir from 1-dp positions)
            if abs(realdir - topo_dir) < E:
                s = 1
            elif pi - E <= abs(realdir - topo_dir) < pi + E:
                s = -1
            else:
                assert False  # if using speed=0, just replace this line with s=0
                # CEBALERT: should actually handle that case!
            #####

            for i in range(n_eyes):
                input_params[i]['sign'].append(s)

    for i in input_params:
        for val in input_params[i]:
            input_params[i][val] = iter(input_params[i][val])

    return len(lines), input_params