コード例 #1
0
    def rand_point(self, size):
        """
        Generate a random vector within the allowable region.
        :param size: norm of the vector to be generated
        :return:  a random vector within the allowable regions (class P)
        """
        if self.full:
            # if all motion is allowed, generate a completely random vector
            return P(misc.rand() - 0.5, misc.rand() - 0.5).resize(size)

        # else, generate a vector within the allowable regions

        # Draw a random angle within the accumulated allowed
        # regions total angle
        t = misc.rand() * self.width()
        total = 0

        # Find in which region this randomly generated angle falls
        for r in self.regions:
            total += r.angle()
            if total >= t:
                res = r.rand_point(
                    size)  # Generate a random vector of norm=size within the
                # randomly chosen region
                return res
        print("Apparently stuck", self.width())
        exit(1)
コード例 #2
0
    def rand_point_normal(self, direction, sigma):
        """
        Choose a random angle from a normal distribution with mean direction and standard
        deviation sigma. Rotate input direction by this angle, unless it is too large (above
        100). if so, draw a completely random direction. Note that since the normal distribution
        is not defined on an angular variable, the actual pdf we use is not truly normally
        distributed around the 0-direction (but it is close enough for our purposes).
        """
        def cdf(
            x_var
        ):  # shorthand function for cumulative distribution function with SD=sigma
            return sct.norm.cdf(x_var, scale=sigma)

        def ppf(
            x_var
        ):  # shorthand function for inverse of the cumulative distribution function
            # with SD=sigma
            return sct.norm.ppf(x_var, scale=sigma)

        intervals = []
        if self.full:
            # Truncating normal distribution cdf to fit angular variable
            intervals += [(cdf(-math.pi), cdf(math.pi))]
        else:

            for r in self.regions:
                # Rotating region sides to be centered around direction
                a1 = r.p1.rotate(-(direction.angle())).angle()
                a2 = r.p2.rotate(-(direction.angle())).angle()

                # Make sure interval boundaries are set up correctly
                if r.contains(-direction):
                    intervals += [(cdf(a1), cdf(math.pi))]
                    intervals += [(cdf(-math.pi), cdf(a2))]
                else:
                    intervals += [(cdf(a1), cdf(a2))]

        # Accumulate allowed cdf(angle) in all intervals to randomly draw from
        total = 0
        for x, y in intervals:
            total += y - x
        t = misc.rand() * total

        # Go over all intervals and translate random number t into the actual corresponding angle
        # in the accumulated cdf intervals
        for x, y in intervals:
            if t <= y - x:
                angle = ppf(x +
                            t)  # translate from x+t=cdf(angle) back to angle
                # if angle change is too large, choose random direction, else, rotate by this
                # angle.
                if angle > 100:
                    return self.rand_point(direction.norm())
                return direction.rotate(angle)
            t -= y - x
        exit(1)
コード例 #3
0
ファイル: path.py プロジェクト: AviramGelblum/Percolation
 def random_step(self, stones: PolygonSet, step_size: float, bias: P):
     last = self.last()
     directions = stones.open_directions_for_point(last, step_size)
     if not directions:
         print("walk stuck")
         exit(1)
     if misc.rand() < 0.5:
         random_directions = [
             directions.rand_point(step_size) for i in range(2)
         ]
         direction = bias.resize(step_size).closest_point(random_directions)
     else:
         direction = directions.rand_point(step_size)
     self.points.append(last + direction)
コード例 #4
0
ファイル: run.py プロジェクト: AviramGelblum/Percolation
    def step(self):
        """
        Perform one time step of the simulation.
        :return: cheerio - next load location (point P), False - signifying the simulation is not
        finished.
        """
        cfg = self.cfg
        cheerio = self.cheerio

        # Where can we currently go
        allowable = cfg.stones.open_direction_for_circle(cheerio, cfg.cheerio_radius, self.speed)
        if not allowable:
            raise SimulationError

        # Update speed
        nest_direction = (cfg.nest - cheerio).resize(self.speed)  # speed vector in the direction
        # of the nest (determined by the last data point of the load in that maze)

        # Compute two possible velocity directions:
        # 1)Align current velocity direction with some nest_direction bias (if needed)
        v1 = self.align((self.v + (nest_direction * 0.1)).resize(self.speed), allowable)
        # 2)Align nest_direction (if needed)
        v2 = self.align(nest_direction, allowable)
        if v1 and v2:  # Align can return None if original velocity and aligned velocity have
            # an angle >90 between them
            expected_steps = cfg.cheerio_radius * 4 / self.speed  # Average number of steps going
            #  in the direction of the velocity (with rolling and a small bias) - persistent
            # behavior
            if misc.rand() < 1 / expected_steps:
                self.v = v2
            else:
                self.v = v1
        elif v1:
            self.v = v1
        elif v2:
            self.v = v2
        else:
            # Both are None, move in a random (allowed) direction.
            self.v = allowable.rand_point(self.speed)
            # self.v = allowable.rand_point_normal(nest_direction, 1)

        # Move cheerio
        self.cheerio = cheerio + self.v
        return cheerio, False
コード例 #5
0
 def random_squares(self, num, size):
     while len(self.polys) < num:
         self.add(
             Polygon.square(P(misc.rand(), misc.rand()), size,
                            misc.rand() * np.pi / 2))
コード例 #6
0
 def random(cls):
     """class method/static method creating a random point."""
     return cls(misc.rand(), misc.rand())