Esempio n. 1
0
def test_blocks():
    on_off = [[1,2],[3,4]]
    tval = np.array([0.4,1.4,2.4,3.4])
    b = blocks(on_off)
    lam = lambdify(t, b)
    assert_array_equal(lam(tval), [0, 1, 0, 1])
    b = blocks(on_off, amplitudes=[3,5])
    lam = lambdify(t, b)
    assert_array_equal(lam(tval), [0, 3, 0, 5])
Esempio n. 2
0
def test_step_function():
    # test step function
    # step function is a function of t
    s = step_function([0,4,5],[2,4,6])
    tval = np.array([-0.1,0,3.9,4,4.1,5.1])
    lam = lambdify(t, s)
    yield assert_array_equal(lam(tval), [0, 2, 2, 4, 4, 6])
    s = step_function([0,4,5],[4,2,1])
    lam = lambdify(t, s)
    yield assert_array_equal(lam(tval), [0, 4, 4, 2, 2, 1])
Esempio n. 3
0
def test_1d():
    B = gen_BrownianMotion()
    Bs = implemented_function("B", B)
    t = sympy.Symbol('t')
    expr = 3*sympy.exp(Bs(t)) + 4
    expected = 3*np.exp(B.y)+4
    ee_vec = lambdify(t, expr)
    yield assert_almost_equal(ee_vec(B.x), expected)
    # with any arbitrary symbol
    b = sympy.Symbol('b')
    expr = 3*sympy.exp(Bs(b)) + 4
    ee_vec = lambdify(b, expr)
    yield assert_almost_equal(ee_vec(B.x), expected)
Esempio n. 4
0
def test_1d():
    B = gen_BrownianMotion()
    Bs = implemented_function("B", B)
    t = sympy.Symbol('t')
    expr = 3 * sympy.exp(Bs(t)) + 4
    expected = 3 * np.exp(B.y) + 4
    ee_vec = lambdify(t, expr, "numpy")
    assert_almost_equal(ee_vec(B.x), expected)
    # with any arbitrary symbol
    b = sympy.Symbol('b')
    expr = 3 * sympy.exp(Bs(b)) + 4
    ee_vec = lambdify(b, expr, "numpy")
    assert_almost_equal(ee_vec(B.x), expected)
Esempio n. 5
0
def test_interp():
    times = [0, 4, 5.]
    values = [2., 4, 6]
    for int_func in (interp, linear_interp):
        s = int_func(times, values, np.nan)
        tval = np.array([-0.1, 0.1, 3.9, 4.1, 5.1])
        res = lambdify(t, s)(tval)
        assert_array_equal(np.isnan(res), [True, False, False, False, True])
        assert_array_almost_equal(res[1:-1], [2.05, 3.95, 4.2])
        # default is zero fill
        s = int_func(times, values)
        res = lambdify(t, s)(tval)
        assert_array_almost_equal(res, [0, 2.05, 3.95, 4.2, 0])
        # Can be some other value
        s = int_func(times, values, fill=10)
        res = lambdify(t, s)(tval)
        assert_array_almost_equal(res, [10, 2.05, 3.95, 4.2, 10])
        # If fill is None, raises error on interpolation outside bounds
        s = int_func(times, values, fill=None)
        f = lambdify(t, s)
        assert_array_almost_equal(f(tval[1:-1]), [2.05, 3.95, 4.2])
        assert_raises(ValueError, f, tval[:-1])
        # specifying kind as linear is OK
        s = linear_interp(times, values, kind='linear')
        # bounds_check should match fill
        int_func(times, values, bounds_error=False)
        int_func(times, values, fill=None, bounds_error=True)
        assert_raises(ValueError, int_func, times, values, bounds_error=True)
        # fill should match fill value
        int_func(times, values, fill=10, fill_value=10)
        int_func(times, values, fill_value=0)
        assert_raises(ValueError,
                      int_func,
                      times,
                      values,
                      fill=10,
                      fill_value=9)
        int_func(times, values, fill=np.nan, fill_value=np.nan)
        assert_raises(ValueError,
                      int_func,
                      times,
                      values,
                      fill=10,
                      fill_value=np.nan)
        assert_raises(ValueError,
                      int_func,
                      times,
                      values,
                      fill=np.nan,
                      fill_value=0)
Esempio n. 6
0
def test_blocks():
    on_off = [[1,2],[3,4]]
    tval = np.array([0.4,1.4,2.4,3.4])
    b = blocks(on_off)
    lam = lambdify(t, b)
    assert_array_equal(lam(tval), [0, 1, 0, 1])
    b = blocks(on_off, amplitudes=[3,5])
    lam = lambdify(t, b)
    assert_array_equal(lam(tval), [0, 3, 0, 5])
    # Check what happens with names
    # Default is from step function
    assert_false(re.match(r'step\d+\(t\)$', str(b)) is None)
    # Can pass in another
    b = blocks(on_off, name='funky_chicken')
    assert_equal(str(b), 'funky_chicken(t)')
Esempio n. 7
0
def test_step_function():
    # test step function
    # step function is a function of t
    s = step_function([0,4,5],[2,4,6])
    tval = np.array([-0.1,0,3.9,4,4.1,5.1])
    lam = lambdify(t, s)
    assert_array_equal(lam(tval), [0, 2, 2, 4, 4, 6])
    s = step_function([0,4,5],[4,2,1])
    lam = lambdify(t, s)
    assert_array_equal(lam(tval), [0, 4, 4, 2, 2, 1])
    # Name default
    assert_false(re.match(r'step\d+\(t\)$', str(s)) is None)
    # Name reloaded
    s = step_function([0,4,5],[4,2,1], name='goodie_goodie_yum_yum')
    assert_equal(str(s), 'goodie_goodie_yum_yum(t)')
Esempio n. 8
0
def test_step_function():
    # test step function
    # step function is a function of t
    s = step_function([0, 4, 5], [2, 4, 6])
    tval = np.array([-0.1, 0, 3.9, 4, 4.1, 5.1])
    lam = lambdify(t, s)
    assert_array_equal(lam(tval), [0, 2, 2, 4, 4, 6])
    s = step_function([0, 4, 5], [4, 2, 1])
    lam = lambdify(t, s)
    assert_array_equal(lam(tval), [0, 4, 4, 2, 2, 1])
    # Name default
    assert_false(re.match(r'step\d+\(t\)$', str(s)) is None)
    # Name reloaded
    s = step_function([0, 4, 5], [4, 2, 1], name='goodie_goodie_yum_yum')
    assert_equal(str(s), 'goodie_goodie_yum_yum(t)')
Esempio n. 9
0
def test_implemented_function():
    # Here we check if the default returned functions are anonymous - in
    # the sense that we can have more than one function with the same name
    f = implemented_function('f', lambda x: 2 * x)
    g = implemented_function('f', lambda x: np.sqrt(x))
    l1 = lambdify(x, f(x))
    l2 = lambdify(x, g(x))
    assert_equal(str(f(x)), str(g(x)))
    assert_equal(l1(3), 6)
    assert_equal(l2(3), np.sqrt(3))
    # check that we can pass in a sympy function as input
    func = sympy.Function('myfunc')
    assert_false(hasattr(func, '_imp_'))
    f = implemented_function(func, lambda x: 2 * x)
    assert_true(hasattr(func, '_imp_'))
Esempio n. 10
0
def test_blocks():
    on_off = [[1, 2], [3, 4]]
    tval = np.array([0.4, 1.4, 2.4, 3.4])
    b = blocks(on_off)
    lam = lambdify(t, b)
    assert_array_equal(lam(tval), [0, 1, 0, 1])
    b = blocks(on_off, amplitudes=[3, 5])
    lam = lambdify(t, b)
    assert_array_equal(lam(tval), [0, 3, 0, 5])
    # Check what happens with names
    # Default is from step function
    assert_false(re.match(r'step\d+\(t\)$', str(b)) is None)
    # Can pass in another
    b = blocks(on_off, name='funky_chicken')
    assert_equal(str(b), 'funky_chicken(t)')
Esempio n. 11
0
def test_implemented_function():
    # Here we check if the default returned functions are anonymous - in
    # the sense that we can have more than one function with the same name
    f = implemented_function('f', lambda x: 2*x)
    g = implemented_function('f', lambda x: np.sqrt(x))
    l1 = lambdify(x, f(x))
    l2 = lambdify(x, g(x))
    yield assert_equal(str(f(x)), str(g(x)))
    yield assert_equal(l1(3), 6)
    yield assert_equal(l2(3), np.sqrt(3))
    # check that we can pass in a sympy function as input
    func = sympy.Function('myfunc')
    yield assert_false(hasattr(func, 'alias'))
    f = implemented_function(func, lambda x: 2*x)
    yield assert_true(hasattr(func, 'alias'))
Esempio n. 12
0
def test_2d():
    B1, B2 = [gen_BrownianMotion() for _ in range(2)]
    B1s = implemented_function("B1", B1)
    B2s = implemented_function("B2", B2)
    s, t = sympy.symbols(('s', 't'))
    e = B1s(s) + B2s(t)
    ee = lambdify((s, t), e)
    assert_almost_equal(ee(B1.x, B2.x), B1.y + B2.y)
Esempio n. 13
0
def test_2d():
    B1, B2 = [gen_BrownianMotion() for _ in range(2)]
    B1s = implemented_function("B1", B1)
    B2s = implemented_function("B2", B2)
    s, t = sympy.symbols('s', 't')
    e = B1s(s)+B2s(t)
    ee = lambdify((s,t), e)
    yield assert_almost_equal(ee(B1.x, B2.x), B1.y + B2.y)
Esempio n. 14
0
def test_interp():
    times = [0,4,5.]
    values = [2.,4,6]
    for int_func in (interp, linear_interp):
        s = int_func(times, values, bounds_error=False)
        tval = np.array([-0.1,0.1,3.9,4.1,5.1])
        res = lambdify(t, s)(tval)
        assert_array_equal(np.isnan(res),
                           [True, False, False, False, True])
        assert_array_almost_equal(res[1:-1], [2.05, 3.95, 4.2])
        # specifying kind as linear is OK
        s = linear_interp(times, values, kind='linear')
Esempio n. 15
0
def lambdify_t(expr):
    ''' Return sympy function of t `expr` lambdified as function of t

    Parameters
    ----------
    expr : sympy expr

    Returns
    -------
    func : callable
       Numerical implementation of function
    '''
    return lambdify(T, expr, "numpy")
Esempio n. 16
0
def lambdify_t(expr):
    """ Return sympy function `expr` lambdified as function of t

    Parametric
    ----------
    expr : sympy expr

    Returns
    -------
    func : callable
       Numerical implementation of function
    """
    return lambdify(T, expr)
Esempio n. 17
0
def lambdify_t(expr):
    ''' Return sympy function of t `expr` lambdified as function of t

    Parameters
    ----------
    expr : sympy expr

    Returns
    -------
    func : callable
       Numerical implementation of function
    '''
    return lambdify(T, expr, "numpy")
Esempio n. 18
0
def test_interp():
    times = [0,4,5.]
    values = [2.,4,6]
    for int_func in (interp, linear_interp):
        s = int_func(times, values, np.nan)
        tval = np.array([-0.1,0.1,3.9,4.1,5.1])
        res = lambdify(t, s)(tval)
        assert_array_equal(np.isnan(res),
                           [True, False, False, False, True])
        assert_array_almost_equal(res[1:-1], [2.05, 3.95, 4.2])
        # default is zero fill
        s = int_func(times, values)
        res = lambdify(t, s)(tval)
        assert_array_almost_equal(res, [0, 2.05, 3.95, 4.2, 0])
        # Can be some other value
        s = int_func(times, values, fill=10)
        res = lambdify(t, s)(tval)
        assert_array_almost_equal(res, [10, 2.05, 3.95, 4.2, 10])
        # If fill is None, raises error on interpolation outside bounds
        s = int_func(times, values, fill=None)
        f = lambdify(t, s)
        assert_array_almost_equal(f(tval[1:-1]), [2.05, 3.95, 4.2])
        assert_raises(ValueError, f, tval[:-1])
        # specifying kind as linear is OK
        s = linear_interp(times, values, kind='linear')
        # bounds_check should match fill
        int_func(times, values, bounds_error=False)
        int_func(times, values, fill=None, bounds_error=True)
        assert_raises(ValueError, int_func, times, values, bounds_error=True)
        # fill should match fill value
        int_func(times, values, fill=10, fill_value=10)
        int_func(times, values, fill_value=0)
        assert_raises(ValueError,
                      int_func, times, values, fill=10, fill_value=9)
        int_func(times, values, fill=np.nan, fill_value=np.nan)
        assert_raises(ValueError,
                      int_func, times, values, fill=10, fill_value=np.nan)
        assert_raises(ValueError,
                      int_func, times, values, fill=np.nan, fill_value=0)
Esempio n. 19
0
def define(name, expr):
    """ Create function of t expression from arbitrary expression `expr`

    Take an arbitrarily complicated expression `expr` of 't' and make it
    an expression that is a simple function of t, of form ``'%s(t)' %
    name`` such that when it evaluates (via ``lambdify``) it has the
    right values.

    Parameters
    ----------
    expr : sympy expression
       with only 't' as a Symbol
    name : str

    Returns
    -------
    nexpr: sympy expression

    Examples
    --------
    >>> t = Term('t')
    >>> expr = t**2 + 3*t
    >>> print expr #doctest: +SYMPY_EQUAL
    3*t + t**2
    >>> newexpr = define('f', expr)
    >>> print newexpr
    f(t)
    >>> f = lambdify_t(newexpr)
    >>> f(4)
    28
    >>> 3*4+4**2
    28
    """
    # make numerical implementation of expression
    v = lambdify(T, expr, "numpy")
    # convert numerical implementation to sympy function
    f = implemented_function(name, v)
    # Return expression that is function of time
    return f(T)
Esempio n. 20
0
def define(name, expr):
    """ Create function of t expression from arbitrary expression `expr`

    Take an arbitrarily complicated expression `expr` of 't' and make it
    an expression that is a simple function of t, of form ``'%s(t)' %
    name`` such that when it evaluates (via ``lambdify``) it has the
    right values.

    Parameters
    ----------
    expr : sympy expression
       with only 't' as a Symbol
    name : str

    Returns
    -------
    nexpr: sympy expression

    Examples
    --------
    >>> t = Term('t')
    >>> expr = t**2 + 3*t
    >>> print expr #doctest: +SYMPY_EQUAL
    3*t + t**2
    >>> newexpr = define('f', expr)
    >>> print newexpr
    f(t)
    >>> f = lambdify_t(newexpr)
    >>> f(4)
    28
    >>> 3*4+4**2
    28
    """
    # make numerical implementation of expression
    v = lambdify(T, expr, "numpy")
    # convert numerical implementation to sympy function
    f = implemented_function(name, v)
    # Return expression that is function of time
    return f(T)
Esempio n. 21
0
def test_convolve_functions():
    # replicate convolution
    # This is a square wave on [0,1]
    f1 = (t > 0) * (t < 1)
    # ff1 is the numerical implementation of same
    lam_f1 = lambdify(t, f1)
    ff1 = lambda x : lam_f1(x).astype(np.int)
    # The convolution of ``f1`` with itself is a triangular wave on
    # [0,2], peaking at 1 with height 1
    tri = convolve_functions(f1, f1, [0,2], 1.0e-3, name='conv')
    yield assert_equal(str(tri), 'conv(t)')
    ftri = lambdify(t, tri)
    time, value = numerical_convolve(ff1, ff1, [0, 2], 1.0e-3)
    y = ftri(time)
    # numerical convolve about the same as ours
    yield assert_array_almost_equal(value, y)
    # peak is at 1
    yield assert_array_almost_equal(time[np.argmax(y)], 1)
    # Flip the interval and get the same result
    tri = convolve_functions(f1, f1, [2, 0], 1.0e-3)
    ftri = lambdify(t, tri)
    y = ftri(time)
    yield assert_array_almost_equal(value, y)
    # offset square wave by 1
    f2 = (t > 1) * (t < 2)
    tri = convolve_functions(f1, f2, [0,3], 1.0e-3)
    ftri = lambdify(t, tri)
    y = ftri(time)
    yield assert_array_almost_equal(time[np.argmax(y)], 2)
    # offset both by 1 and start interval at one
    tri = convolve_functions(f2, f2, [1,3], 1.0e-3)
    ftri = lambdify(t, tri)
    # get numerical version
    lam_f2 = lambdify(t, f2)
    ff2 = lambda x : lam_f2(x).astype(np.int)
    time, value = numerical_convolve(ff2, ff2, [1, 3], 1.0e-3)
    # and our version, compare
    y = ftri(time)
    yield assert_array_almost_equal(y, value)
Esempio n. 22
0
    def _setup_design(self):
        """
        Create a callable object to evaluate the design matrix
        at a given set of parameter values to be specified by
        a recarray and observed Term values, also specified
        by a recarray.
        """
        # the design expression is the differentiation of the expression
        # for the mean.  It is a list
        d = self.design_expr
        # Before evaluating, we recreate the formula
        # with numbered terms, and numbered parameters.

        # This renaming has no impact on the
        # final design matrix as the
        # callable, self._f below, is a lambda
        # that does not care about the names of the terms.

        # First, find all terms in the mean expression,
        # and rename them in the form "__t%d__" with a
        # random offset.
        # This may cause a possible problem
        # when there are parameters named something like "__t%d__".
        # Using the random offset will minimize the possibility
        # of this happening.

        # This renaming is here principally because of the intercept.

        random_offset = np.random.random_integers(low=0, high=2**30)

        terms = getterms(self.mean)

        newterms = []
        for i, t in enumerate(terms):
            newt = sympy.Symbol("__t%d__" % (i + random_offset))
            for j, _ in enumerate(d):
                d[j] = d[j].subs(t, newt)
            newterms.append(newt)

        # Next, find all parameters that remain in the design expression.
        # In a standard regression model, there will be no parameters
        # because they will all be differentiated away in computing
        # self.design_expr. In nonlinear models, parameters will remain.

        params = getparams(self.design_expr)
        newparams = []
        for i, p in enumerate(params):
            newp = make_dummy("__p%d__" % (i + random_offset))
            for j, _ in enumerate(d):
                d[j] = d[j].subs(p, newp)
            newparams.append(newp)

        # If there are any aliased functions, these need to be added
        # to the name space before sympy lambdifies the expression

        # These "aliased" functions are used for things like
        # the natural splines, etc. You can represent natural splines
        # with sympy but the expression is pretty awful.  Note that
        # ``d`` here is list giving the differentiation of the
        # expression for the mean.  self._f(...) therefore also returns
        # a list
        self._f = lambdify(newparams + newterms, d, ("numpy"))

        # The input to self.design will be a recarray of that must
        # have field names that the Formula will expect to see.
        # However, if any of self.terms are FactorTerms, then the field
        # in the recarray will not actually be in the Term.
        #
        # For example, if there is a Factor 'f' with levels ['a','b'],
        # there will be terms 'f_a' and 'f_b', though the input to
        # design will have a field named 'f'. In this sense,
        # the recarray used in the call to self.design
        # is not really made up of terms, but "preterms".

        # In this case, the callable

        preterm = []
        for t in terms:
            if not is_factor_term(t):
                preterm.append(str(t))
            else:
                preterm.append(t.factor_name)
        preterm = list(set(preterm))

        # There is also an argument for parameters that are not
        # Terms.

        self._dtypes = {
            'param': np.dtype([(str(p), np.float) for p in params]),
            'term': np.dtype([(str(t), np.float) for t in terms]),
            'preterm': np.dtype([(n, np.float) for n in preterm])
        }

        self.__terms = terms
Esempio n. 23
0
def test_convolve_functions():
    # replicate convolution
    # This is a square wave on [0,1]
    f1 = (t > 0) * (t < 1)
    # ff1 is the numerical implementation of same
    ff1 = lambdify(t, f1)
    # Time delta
    dt = 1e-3
    # The convolution of ``f1`` with itself is a triangular wave on
    # [0, 2], peaking at 1 with height 1
    tri = convolve_functions(f1, f1, [0, 2], [0, 2], dt, name='conv')
    assert_equal(str(tri), 'conv(t)')
    ftri = lambdify(t, tri)
    time, value = numerical_convolve(ff1, ff1, [0, 2], dt)
    y = ftri(time)
    # numerical convolve about the same as ours
    assert_array_almost_equal(value, y)
    # peak is at 1
    assert_array_almost_equal(time[np.argmax(y)], 1)
    # Flip the interval and get the same result
    for seq1, seq2 in (((0, 2), (2, 0)),
                       ((2, 0), (0, 2)),
                       ((2, 0), (2, 0))):
        tri = convolve_functions(f1, f1, seq1, seq2, dt)
        ftri = lambdify(t, tri)
        y = ftri(time)
        assert_array_almost_equal(value, y)
    # offset square wave by 1 - offset triangle by 1
    f2 = (t > 1) * (t < 2)
    tri = convolve_functions(f1, f2, [0, 3], [0, 3], dt)
    ftri = lambdify(t, tri)
    o1_time = np.arange(0, 3, dt)
    z1s = np.zeros((np.round(1./dt)))
    assert_array_almost_equal(ftri(o1_time), np.r_[z1s, value])
    # Same for input function
    tri = convolve_functions(f2, f1, [0, 3], [0, 3], dt)
    ftri = lambdify(t, tri)
    assert_array_almost_equal(ftri(o1_time), np.r_[z1s, value])
    # 2 seconds for both
    tri = convolve_functions(f2, f2, [0, 4], [0, 4], dt)
    ftri = lambdify(t, tri)
    o2_time = np.arange(0, 4, dt)
    assert_array_almost_equal(ftri(o2_time), np.r_[z1s, z1s, value])
    # offset by -0.5 - offset triangle by -0.5
    f3 = (t > -0.5) * (t < 0.5)
    tri = convolve_functions(f1, f3, [0, 2], [-0.5, 1.5], dt)
    ftri = lambdify(t, tri)
    o1_time = np.arange(-0.5, 1.5, dt)
    assert_array_almost_equal(ftri(o1_time), value)
    # Same for input function
    tri = convolve_functions(f3, f1, [-0.5, 1.5], [0, 2], dt)
    ftri = lambdify(t, tri)
    assert_array_almost_equal(ftri(o1_time), value)
    # -1 second for both
    tri = convolve_functions(f3, f3, [-0.5, 1.5], [-0.5, 1.5], dt)
    ftri = lambdify(t, tri)
    o2_time = np.arange(-1, 1, dt)
    assert_array_almost_equal(ftri(o2_time), value)
    # Check it's OK to be off the dt grid
    tri = convolve_functions(f1, f1, [dt/2, 2 + dt/2], [0, 2], dt, name='conv')
    ftri = lambdify(t, tri)
    assert_array_almost_equal(ftri(time), value, 3)
Esempio n. 24
0
def test_lambdify():
    # Test lambdify with implemented functions
    # first test basic (sympy) lambdify
    f = sympy.cos
    assert_equal(lambdify(x, f(x))(0), 1)
    assert_equal(lambdify(x, 1 + f(x))(0), 2)
    assert_equal(lambdify((x, y), y + f(x))(0, 1), 2)
    # make an implemented function and test
    f = implemented_function("f", lambda x: x + 100)
    assert_equal(lambdify(x, f(x))(0), 100)
    assert_equal(lambdify(x, 1 + f(x))(0), 101)
    assert_equal(lambdify((x, y), y + f(x))(0, 1), 101)
    # Error for functions with same name and different implementation
    f2 = implemented_function("f", lambda x: x + 101)
    assert_raises(ValueError, lambdify, x, f(f2(x)))
    # our lambdify, like sympy's lambdify, can also handle tuples,
    # lists, dicts as expressions
    lam = lambdify(x, (f(x), x))
    assert_equal(lam(3), (103, 3))
    lam = lambdify(x, [f(x), x])
    assert_equal(lam(3), [103, 3])
    lam = lambdify(x, [f(x), (f(x), x)])
    assert_equal(lam(3), [103, (103, 3)])
    lam = lambdify(x, {f(x): x})
    assert_equal(lam(3), {103: 3})
    lam = lambdify(x, {f(x): x})
    assert_equal(lam(3), {103: 3})
    lam = lambdify(x, {x: f(x)})
    assert_equal(lam(3), {3: 103})
Esempio n. 25
0
def test_lambdify():
    # Test lambdify with implemented functions
    # first test basic (sympy) lambdify
    f = sympy.cos
    yield assert_equal(lambdify(x, f(x))(0), 1)
    yield assert_equal(lambdify(x, 1 + f(x))(0), 2)
    yield assert_equal(lambdify((x, y), y + f(x))(0, 1), 2)
    # make an implemented function and test
    f = implemented_function("f", lambda x : x+100)
    yield assert_equal(lambdify(x, f(x))(0), 100)
    yield assert_equal(lambdify(x, 1 + f(x))(0), 101)
    yield assert_equal(lambdify((x, y), y + f(x))(0, 1), 101)
    # Error for functions with same name and different implementation
    f2 = implemented_function("f", lambda x : x+101)
    yield assert_raises(ValueError, lambdify, x, f(f2(x)))
    # our lambdify, like sympy's lambdify, can also handle tuples,
    # lists, dicts as expressions
    lam = lambdify(x, (f(x), x))
    yield assert_equal(lam(3), (103, 3))
    lam = lambdify(x, [f(x), x])
    yield assert_equal(lam(3), [103, 3])
    lam = lambdify(x, [f(x), (f(x), x)])
    yield assert_equal(lam(3), [103, (103, 3)])
    lam = lambdify(x, {f(x): x})
    yield assert_equal(lam(3), {103: 3})
    lam = lambdify(x, {f(x): x})
    yield assert_equal(lam(3), {103: 3})
    lam = lambdify(x, {x: f(x)})
    yield assert_equal(lam(3), {3: 103})
Esempio n. 26
0
def test_convolve_functions():
    # replicate convolution
    # This is a square wave on [0,1]
    f1 = (t > 0) * (t < 1)
    # ff1 is the numerical implementation of same
    ff1 = lambdify(t, f1)
    # Time delta
    dt = 1e-3
    # The convolution of ``f1`` with itself is a triangular wave on
    # [0, 2], peaking at 1 with height 1
    tri = convolve_functions(f1, f1, [0, 2], [0, 2], dt, name='conv')
    assert_equal(str(tri), 'conv(t)')
    ftri = lambdify(t, tri)
    time, value = numerical_convolve(ff1, ff1, [0, 2], dt)
    y = ftri(time)
    # numerical convolve about the same as ours
    assert_array_almost_equal(value, y)
    # peak is at 1
    assert_array_almost_equal(time[np.argmax(y)], 1)
    # Flip the interval and get the same result
    for seq1, seq2 in (((0, 2), (2, 0)), ((2, 0), (0, 2)), ((2, 0), (2, 0))):
        tri = convolve_functions(f1, f1, seq1, seq2, dt)
        ftri = lambdify(t, tri)
        y = ftri(time)
        assert_array_almost_equal(value, y)
    # offset square wave by 1 - offset triangle by 1
    f2 = (t > 1) * (t < 2)
    tri = convolve_functions(f1, f2, [0, 3], [0, 3], dt)
    ftri = lambdify(t, tri)
    o1_time = np.arange(0, 3, dt)
    z1s = np.zeros((np.round(1. / dt)))
    assert_array_almost_equal(ftri(o1_time), np.r_[z1s, value])
    # Same for input function
    tri = convolve_functions(f2, f1, [0, 3], [0, 3], dt)
    ftri = lambdify(t, tri)
    assert_array_almost_equal(ftri(o1_time), np.r_[z1s, value])
    # 2 seconds for both
    tri = convolve_functions(f2, f2, [0, 4], [0, 4], dt)
    ftri = lambdify(t, tri)
    o2_time = np.arange(0, 4, dt)
    assert_array_almost_equal(ftri(o2_time), np.r_[z1s, z1s, value])
    # offset by -0.5 - offset triangle by -0.5
    f3 = (t > -0.5) * (t < 0.5)
    tri = convolve_functions(f1, f3, [0, 2], [-0.5, 1.5], dt)
    ftri = lambdify(t, tri)
    o1_time = np.arange(-0.5, 1.5, dt)
    assert_array_almost_equal(ftri(o1_time), value)
    # Same for input function
    tri = convolve_functions(f3, f1, [-0.5, 1.5], [0, 2], dt)
    ftri = lambdify(t, tri)
    assert_array_almost_equal(ftri(o1_time), value)
    # -1 second for both
    tri = convolve_functions(f3, f3, [-0.5, 1.5], [-0.5, 1.5], dt)
    ftri = lambdify(t, tri)
    o2_time = np.arange(-1, 1, dt)
    assert_array_almost_equal(ftri(o2_time), value)
    # Check it's OK to be off the dt grid
    tri = convolve_functions(f1,
                             f1, [dt / 2, 2 + dt / 2], [0, 2],
                             dt,
                             name='conv')
    ftri = lambdify(t, tri)
    assert_array_almost_equal(ftri(time), value, 3)
Esempio n. 27
0
    def _setup_design(self):
        """
        Create a callable object to evaluate the design matrix
        at a given set of parameter values to be specified by
        a recarray and observed Term values, also specified
        by a recarray.
        """
        # the design expression is the differentiation of the expression
        # for the mean.  It is a list
        d = self.design_expr
        # Before evaluating, we recreate the formula
        # with numbered terms, and numbered parameters.

        # This renaming has no impact on the
        # final design matrix as the
        # callable, self._f below, is a lambda
        # that does not care about the names of the terms.

        # First, find all terms in the mean expression,
        # and rename them in the form "__t%d__" with a
        # random offset.
        # This may cause a possible problem
        # when there are parameters named something like "__t%d__".
        # Using the random offset will minimize the possibility
        # of this happening.

        # This renaming is here principally because of the intercept.

        random_offset = np.random.random_integers(low=0, high=2**30)

        terms = getterms(self.mean)

        newterms = []
        for i, t in enumerate(terms):
            newt = sympy.Symbol("__t%d__" % (i + random_offset))
            for j, _ in enumerate(d):
                d[j] = d[j].subs(t, newt)
            newterms.append(newt)

        # Next, find all parameters that remain in the design expression.
        # In a standard regression model, there will be no parameters
        # because they will all be differentiated away in computing
        # self.design_expr. In nonlinear models, parameters will remain.

        params = getparams(self.design_expr)
        newparams = []
        for i, p in enumerate(params):
            newp = make_dummy("__p%d__" % (i + random_offset))
            for j, _ in enumerate(d):
                d[j] = d[j].subs(p, newp)
            newparams.append(newp)

        # If there are any aliased functions, these need to be added
        # to the name space before sympy lambdifies the expression

        # These "aliased" functions are used for things like
        # the natural splines, etc. You can represent natural splines
        # with sympy but the expression is pretty awful.  Note that
        # ``d`` here is list giving the differentiation of the
        # expression for the mean.  self._f(...) therefore also returns
        # a list
        self._f = lambdify(newparams + newterms, d, ("numpy"))

        # The input to self.design will be a recarray of that must 
        # have field names that the Formula will expect to see.
        # However, if any of self.terms are FactorTerms, then the field
        # in the recarray will not actually be in the Term.
        # 
        # For example, if there is a Factor 'f' with levels ['a','b'],
        # there will be terms 'f_a' and 'f_b', though the input to
        # design will have a field named 'f'. In this sense,
        # the recarray used in the call to self.design
        # is not really made up of terms, but "preterms".

        # In this case, the callable

        preterm = []
        for t in terms:
            if not is_factor_term(t):
                preterm.append(str(t))
            else:
                preterm.append(t.factor_name)
        preterm = list(set(preterm))

        # There is also an argument for parameters that are not
        # Terms. 

        self._dtypes = {'param':np.dtype([(str(p), np.float) for p in params]),
                        'term':np.dtype([(str(t), np.float) for t in terms]),
                        'preterm':np.dtype([(n, np.float) for n in preterm])}

        self.__terms = terms