Пример #1
0
 def test_split(self):
     # If this ever breaks, we should solve the problem by writing a
     # new kind of Function that turns a lambda expression into a
     # Function.  That way, it will never be simplified.
     # f = x^2 + x
     f = Function.sum(Function.power(Function.identity(),
                                     Function.constant(2)),
                      Function.identity())
     # f(-1) = 0, f(0) = 0, f(-.5) = -.25
     # The range of f on [-1,0] is [-.25,0]
     # f([-1,0]) = [-1,1]
     # f([-1,-.5]) = [-.75,.5]
     # f([-.5,0]) = [-.5,.25]
     # This will never finish, since it asks for the exact bounds
     self.assertTrue(is_bounded(f, Interval(-1,0), Interval(-1/4,0))
                     is None)
     # g = 1/2*x^3-3/2*x
     g = Function.sum(Function.product(
             Function.constant(.5),
             Function.power(Function.identity(),
                            Function.constant(3))),
         Function.product(Function.constant(-1.5),
                          Function.identity()))
     self.assertEqual(is_bounded(g, Interval(-1.5,1.5), Interval(-.9,1)),
                      False)
     # This encounters a ValueError on the first split so should
     # return None
     h = Function.quotient(Function.constant(1), Function.identity())
     self.assertTrue(is_bounded(h, Interval(-1,1), Interval(-5,5)) is None)
Пример #2
0
def recursively_generate_cubics(f, left, right, depth = 5):
    for a in approximate(f, left, right):
        if is_bounded(Function.sum(f, Function.product(
                    Function.constant(-1), a)), Interval(left, right),
                      Interval(-.008, .008)):
            return [a]
    if depth == 0:
        return []
    middle = (left + right) / 2
    return recursively_generate_cubics(f, left, middle, depth-1) + \
        recursively_generate_cubics(f, middle, right, depth-1)
Пример #3
0
    def __init__(self, t0, t1, f0, c0, c1, f1):
        self.__t0 = t0
        self.__t1 = t1
        self.__f0 = f0
        self.__c0 = c0
        self.__c1 = c1
        self.__f1 = f1

        # The specific functional form will have consequences for the
        # efficiency of interval arithmetic (and thus, slicing).

        # t' = (t-t0)/(t1-t0)
        t = Function.product(Function.sum(Function.identity(), Function.constant(-t0)),
                             Function.constant(1.0/(t1-t0)))

        omt = Function.sum(Function.constant(1), Function.product(Function.constant(-1), t))
        def term(const, f):
            return Function.sum(Function.constant(const), Function.product(t, f))
        a = -f0 + 3*c0 - 3*c1 + f1
        b = 3*f0 - 6*c0 + 3*c1
        c = -3*f0 + 3*c0
        d = f0

        WrappedFunction.__init__(self, term(d, term(c, term(b, Function.constant(a)))).weak_simplify())
Пример #4
0
 def test_depth(self):
     f = Function.sum(Function.power(Function.identity(),
                                     Function.constant(2)),
                      Function.identity())
     # This requires splitting in half
     self.assertTrue(is_bounded(f, Interval(-1,0), Interval(-3/4,1/2), 1))
     self.assertEqual(is_bounded(f, Interval(-1,0), Interval(-3/4,1/2), 0),
                      None)
     # This requires 3 levels of recursion
     self.assertTrue(is_bounded(f, Interval(-1,0), Interval(-3/8,1/8), 3))
     self.assertEqual(is_bounded(f, Interval(-1,0), Interval(-3/8,1/8), 2),
                      None)
     # This requires 8 levels of recursion
     self.assertTrue(is_bounded(f, Interval(-1,0), Interval(-65/256,1/256),
                                8))
     self.assertEqual(is_bounded(f, Interval(-1,0), Interval(-65/256,1/256),
                                 7), None)
Пример #5
0
    def test_approx(self):
        f = Function.identity()
        for a in approximate(f, 0, 1):
            self.assertTrue(isinstance(a, Function))
            self.assertTrue(isinstance(a, CubicSpline))
            # We may someday generate approximations that don't go through
            # the endpoints, and remove these tests.  Until then, they
            # help verify that the approximation formulas are correct.
            self.assertEqual(a(0.0), 0.0)
            self.assertEqual(a(1.0), 1.0)

        # (-x^2 - 1) ^ .5
        bad = Function.power(Function.sum(Function.product(
                Function.constant(-1),
                Function.power(Function.identity(), Function.constant(2))),
                                          Function.constant(-1)),
                             Function.constant(.5))
        self.assertEqual(list(approximate(bad, 0, 1)), [])
Пример #6
0
 def term(const, f):
     return Function.sum(Function.constant(const), Function.product(t, f))