File: test_codestrings.py

package info (click to toggle)
brian 2.9.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,872 kB
  • sloc: python: 51,820; cpp: 2,033; makefile: 108; sh: 72
file content (109 lines) | stat: -rw-r--r-- 3,326 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import numpy as np
import pytest
import sympy
from numpy.testing import assert_equal

import brian2
from brian2 import (
    DimensionMismatchError,
    Expression,
    Hz,
    Statements,
    get_dimensions,
    ms,
    mV,
    second,
    volt,
)
from brian2.core.preferences import prefs
from brian2.utils.logger import catch_logs


def sympy_equals(expr1, expr2):
    """
    Test that whether two string expressions are equal using sympy, allowing
    e.g. for ``sympy_equals("x * x", "x ** 2") == True``.
    """
    s_expr1 = sympy.nsimplify(sympy.sympify(expr1).expand())
    s_expr2 = sympy.nsimplify(sympy.sympify(expr2).expand())
    return s_expr1 == s_expr2


@pytest.mark.codegen_independent
def test_expr_creation():
    """
    Test creating expressions.
    """
    expr = Expression("v > 5 * mV")
    assert expr.code == "v > 5 * mV"
    assert (
        "v" in expr.identifiers
        and "mV" in expr.identifiers
        and not "V" in expr.identifiers
    )
    with pytest.raises(SyntaxError):
        Expression("v 5 * mV")


@pytest.mark.codegen_independent
def test_split_stochastic():
    tau = 5 * ms
    expr = Expression("(-v + I) / tau")
    # No stochastic part
    assert expr.split_stochastic() == (expr, None)

    # No non-stochastic part -- note that it should return 0 and not None
    expr = Expression("sigma*xi/tau**.5")
    non_stochastic, stochastic = expr.split_stochastic()
    assert sympy_equals(non_stochastic.code, 0)
    assert "xi" in stochastic
    assert len(stochastic) == 1
    assert sympy_equals(stochastic["xi"].code, "sigma/tau**.5")

    expr = Expression("(-v + I) / tau + sigma*xi/tau**.5")
    non_stochastic, stochastic = expr.split_stochastic()
    assert "xi" in stochastic
    assert len(stochastic) == 1
    assert sympy_equals(non_stochastic.code, "(-v + I) / tau")
    assert sympy_equals(stochastic["xi"].code, "sigma/tau**.5")

    expr = Expression("(-v + I) / tau + sigma*xi_1/tau**.5 + xi_2*sigma2/sqrt(tau_2)")
    non_stochastic, stochastic = expr.split_stochastic()
    assert set(stochastic.keys()) == {"xi_1", "xi_2"}
    assert sympy_equals(non_stochastic.code, "(-v + I) / tau")
    assert sympy_equals(stochastic["xi_1"].code, "sigma/tau**.5")
    assert sympy_equals(stochastic["xi_2"].code, "sigma2/tau_2**.5")

    expr = Expression("-v / tau + 1 / xi")
    with pytest.raises(ValueError):
        expr.split_stochastic()


@pytest.mark.codegen_independent
def test_str_repr():
    """
    Test the string representation of expressions and statements. Assumes that
    __str__ returns the complete expression/statement string and __repr__ a
    string of the form "Expression(...)" or "Statements(...)" that can be
    evaluated.
    """
    expr_string = "(v - I)/ tau"
    expr = Expression(expr_string)

    # use sympy to check for equivalence of expressions (terms may have be
    # re-arranged by sympy)
    assert sympy_equals(expr_string, str(expr))
    assert sympy_equals(expr_string, eval(repr(expr)).code)

    # Use exact string equivalence for statements
    statement_string = "v += w"
    statement = Statements(statement_string)

    assert str(statement) == "v += w"
    assert repr(statement) == "Statements('v += w')"


if __name__ == "__main__":
    test_expr_creation()
    test_split_stochastic()
    test_str_repr()