Skip to content

Commit

Permalink
Replace all the remaining references to "static equations" by "subexp…
Browse files Browse the repository at this point in the history
…ressions" for consistency
  • Loading branch information
Marcel Stimberg committed Feb 28, 2014
1 parent cf12698 commit 16f90a6
Show file tree
Hide file tree
Showing 8 changed files with 53 additions and 52 deletions.
53 changes: 27 additions & 26 deletions brian2/equations/equations.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
# this might get refactored into objects, for example)
PARAMETER = 'parameter'
DIFFERENTIAL_EQUATION = 'differential equation'
STATIC_EQUATION = 'static equation'
SUBEXPRESSION = 'subexpression'


# Definitions of equation structure for parsing with pyparsing
Expand Down Expand Up @@ -80,7 +80,7 @@
# Static equation:
# x = 2 * y : volt (flags)
STATIC_EQ = Group(IDENTIFIER + Suppress('=') + EXPRESSION + Suppress(':') +
UNIT + Optional(FLAGS)).setResultsName(STATIC_EQUATION)
UNIT + Optional(FLAGS)).setResultsName(SUBEXPRESSION)

# Differential equation
# dx/dt = -x / tau : volt
Expand Down Expand Up @@ -254,7 +254,7 @@ class SingleEquation(object):
Parameters
----------
type : {PARAMETER, DIFFERENTIAL_EQUATION, STATIC_EQUATION}
type : {PARAMETER, DIFFERENTIAL_EQUATION, SUBEXPRESSION}
The type of the equation.
varname : str
The variable that is defined by this equation.
Expand Down Expand Up @@ -285,7 +285,7 @@ def __init__(self, type, varname, unit, is_bool=False, expr=None,
else:
self.flags = flags

# will be set later in the sort_static_equations method of Equations
# will be set later in the sort_subexpressions method of Equations
self.update_order = -1


Expand All @@ -297,7 +297,7 @@ def _latex(self, *args):
if self.type == DIFFERENTIAL_EQUATION:
return (r'\frac{\mathrm{d}' + sympy.latex(self.varname) + r'}{\mathrm{d}t} = ' +
sympy.latex(str_to_sympy(self.expr.code)))
elif self.type == STATIC_EQUATION:
elif self.type == SUBEXPRESSION:
return (sympy.latex(self.varname) + ' = ' +
sympy.latex(str_to_sympy(self.expr.code)))
elif self.type == PARAMETER:
Expand Down Expand Up @@ -464,8 +464,8 @@ def __init__(self, eqns, **kwds):
else:
uses_xi = eq.varname

# rearrange static equations
self._sort_static_equations()
# rearrange subexpressions
self._sort_subexpressions()

def __iter__(self):
return iter(self._equations)
Expand Down Expand Up @@ -549,14 +549,14 @@ def check_identifiers(self):
def _get_substituted_expressions(self):
'''
Return a list of ``(varname, expr)`` tuples, containing all
differential equations with all the static equation variables
differential equations with all the subexpression variables
substituted with the respective expressions.
Returns
-------
expr_tuples : list of (str, `CodeString`)
A list of ``(varname, expr)`` tuples, where ``expr`` is a
`CodeString` object with all static equation variables substituted
`CodeString` object with all subexpression variables substituted
with the respective expression.
'''
subst_exprs = []
Expand All @@ -570,7 +570,7 @@ def _get_substituted_expressions(self):
new_str_expr = sympy_to_str(new_sympy_expr)
expr = Expression(new_str_expr)

if eq.type == STATIC_EQUATION:
if eq.type == SUBEXPRESSION:
substitutions.update({sympy.Symbol(eq.varname, real=True): expr.sympy_expr})
elif eq.type == DIFFERENTIAL_EQUATION:
# a differential equation that we have to check
Expand Down Expand Up @@ -635,9 +635,9 @@ def _get_stochastic_type(self):

eq_expressions = property(lambda self: [(varname, eq.expr) for
varname, eq in self.iteritems()
if eq.type in (STATIC_EQUATION,
if eq.type in (SUBEXPRESSION,
DIFFERENTIAL_EQUATION)],
doc='A list of (variable name, expression) '
doc='A list of (variable name, expression) '
'tuples of all equations.')

substituted_expressions = property(_get_substituted_expressions)
Expand All @@ -651,13 +651,14 @@ def _get_stochastic_type(self):
if eq.type == DIFFERENTIAL_EQUATION]),
doc='All differential equation names.')

static_eq_names = property(lambda self: set([eq.varname for eq in self.ordered
if eq.type == STATIC_EQUATION]),
doc='All static equation names.')
subexpr_names = property(lambda self: set([eq.varname for eq in self.ordered
if eq.type == SUBEXPRESSION]),
doc='All subexpression names.')

eq_names = property(lambda self: set([eq.varname for eq in self.ordered
if eq.type in (DIFFERENTIAL_EQUATION, STATIC_EQUATION)]),
doc='All (static and differential) equation names.')
if eq.type in (DIFFERENTIAL_EQUATION,
SUBEXPRESSION)]),
doc='All equation names (including subexpressions).')

parameter_names = property(lambda self: set([eq.varname for eq in self.ordered
if eq.type == PARAMETER]),
Expand All @@ -683,22 +684,22 @@ def _get_stochastic_type(self):

stochastic_type = property(fget=_get_stochastic_type)

def _sort_static_equations(self):
def _sort_subexpressions(self):
'''
Sorts the static equations in a way that resolves their dependencies
upon each other. After this method has been run, the static equations
Sorts the subexpressions in a way that resolves their dependencies
upon each other. After this method has been run, the subexpressions
returned by the ``ordered`` property are in the order in which
they should be updated
'''

# Get a dictionary of all the dependencies on other static equations,
# Get a dictionary of all the dependencies on other subexpressions,
# i.e. ignore dependencies on parameters and differential equations
static_deps = {}
for eq in self._equations.itervalues():
if eq.type == STATIC_EQUATION:
if eq.type == SUBEXPRESSION:
static_deps[eq.varname] = [dep for dep in eq.identifiers if
dep in self._equations and
self._equations[dep].type == STATIC_EQUATION]
self._equations[dep].type == SUBEXPRESSION]

try:
sorted_eqs = topsort(static_deps)
Expand All @@ -710,7 +711,7 @@ def _sort_static_equations(self):
for order, static_variable in enumerate(sorted_eqs):
self._equations[static_variable].update_order = order

# Sort differential equations and parameters after static equations
# Sort differential equations and parameters after subexpressions
for eq in self._equations.itervalues():
if eq.type == DIFFERENTIAL_EQUATION:
eq.update_order = len(sorted_eqs)
Expand Down Expand Up @@ -760,7 +761,7 @@ def check_units(self, group, run_namespace=None, level=0):
if eq.type == DIFFERENTIAL_EQUATION:
check_unit(str(eq.expr), self.units[var] / second,
all_variables)
elif eq.type == STATIC_EQUATION:
elif eq.type == SUBEXPRESSION:
check_unit(str(eq.expr), self.units[var],
all_variables)
else:
Expand All @@ -775,7 +776,7 @@ def check_flags(self, allowed_flags):
----------
allowed_flags : dict
A dictionary mapping equation types (PARAMETER,
DIFFERENTIAL_EQUATION, STATIC_EQUATION) to a list of strings (the
DIFFERENTIAL_EQUATION, SUBEXPRESSION) to a list of strings (the
allowed flags for that equation type)
Notes
Expand Down
8 changes: 4 additions & 4 deletions brian2/groups/neurongroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sympy

from brian2.equations.equations import (Equations, DIFFERENTIAL_EQUATION,
STATIC_EQUATION, PARAMETER)
SUBEXPRESSION, PARAMETER)
from brian2.equations.refractory import add_refractoriness
from brian2.stateupdaters.base import StateUpdateMethod
from brian2.codegen.codeobject import check_code_units
Expand Down Expand Up @@ -249,7 +249,7 @@ def __init__(self, N, model, method=None,
# Check flags
model.check_flags({DIFFERENTIAL_EQUATION: ('unless refractory',),
PARAMETER: ('constant', 'scalar'),
STATIC_EQUATION: ('scalar',)})
SUBEXPRESSION: ('scalar',)})

# add refractoriness
if refractory is not False:
Expand Down Expand Up @@ -381,7 +381,7 @@ def _create_variables(self, dtype=None):
constant=constant, is_bool=eq.is_bool,
scalar=scalar,
index=index)
elif eq.type == STATIC_EQUATION:
elif eq.type == SUBEXPRESSION:
self.variables.add_subexpression(eq.varname, unit=eq.unit,
expr=str(eq.expr),
is_bool=eq.is_bool,
Expand All @@ -402,7 +402,7 @@ def _create_variables(self, dtype=None):

# Check scalar subexpressions
for eq in self.equations.itervalues():
if eq.type == STATIC_EQUATION and 'scalar' in eq.flags:
if eq.type == SUBEXPRESSION and 'scalar' in eq.flags:
var = self.variables[eq.varname]
for identifier in var.identifiers:
if identifier in self.variables:
Expand Down
2 changes: 1 addition & 1 deletion brian2/stateupdaters/explicit.py
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ def __call__(self, eqs, variables=None):

# Execute the statement by appropriately replacing the functions f
# and g and the variable x for every equation in the model.
# We use the model equations where the static equations have
# We use the model equations where the subexpressions have
# already been substituted into the model equations.
for var, expr in eqs.substituted_expressions:
RHS = self._generate_RHS(eqs, var, eq_variables, intermediate_vars,
Expand Down
8 changes: 4 additions & 4 deletions brian2/synapses/synapses.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from brian2.codegen.codeobject import create_runner_codeobj
from brian2.devices.device import get_device
from brian2.equations.equations import (Equations, SingleEquation,
DIFFERENTIAL_EQUATION, STATIC_EQUATION,
DIFFERENTIAL_EQUATION, SUBEXPRESSION,
PARAMETER)
from brian2.groups.group import Group, CodeRunner, dtype_dictionary
from brian2.stateupdaters.base import StateUpdateMethod
Expand Down Expand Up @@ -421,7 +421,7 @@ def __init__(self, source, target=None, model=None, pre=None, post=None,

# Check flags
model.check_flags({DIFFERENTIAL_EQUATION: ['event-driven'],
STATIC_EQUATION: ['summed', 'scalar'],
SUBEXPRESSION: ['summed', 'scalar'],
PARAMETER: ['constant', 'scalar']})

# Separate the equations into event-driven and continuously updated
Expand Down Expand Up @@ -698,7 +698,7 @@ def _create_variables(self, dtype=None):
dtype=dtype[eq.varname],
constant=constant,
is_bool=eq.is_bool)
elif eq.type == STATIC_EQUATION:
elif eq.type == SUBEXPRESSION:
if 'summed' in eq.flags:
# Give a special name to the subexpression for summed
# variables to avoid confusion with the pre/postsynaptic
Expand Down Expand Up @@ -732,7 +732,7 @@ def _create_variables(self, dtype=None):

# Check scalar subexpressions
for eq in self.equations.itervalues():
if eq.type == STATIC_EQUATION and 'scalar' in eq.flags:
if eq.type == SUBEXPRESSION and 'scalar' in eq.flags:
var = self.variables[eq.varname]
for identifier in var.identifiers:
if identifier in self.variables:
Expand Down
16 changes: 8 additions & 8 deletions brian2/tests/test_equations.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
check_identifier_units,
parse_string_equations,
SingleEquation,
DIFFERENTIAL_EQUATION, STATIC_EQUATION,
DIFFERENTIAL_EQUATION, SUBEXPRESSION,
PARAMETER,
EquationError)
from brian2.equations.refractory import check_identifier_refractory
Expand Down Expand Up @@ -131,7 +131,7 @@ def test_parse_equations():
assert len(eqs.keys()) == 5
assert 'v' in eqs and eqs['v'].type == DIFFERENTIAL_EQUATION
assert 'ge' in eqs and eqs['ge'].type == DIFFERENTIAL_EQUATION
assert 'I' in eqs and eqs['I'].type == STATIC_EQUATION
assert 'I' in eqs and eqs['I'].type == SUBEXPRESSION
assert 'f' in eqs and eqs['f'].type == PARAMETER
assert 'b' in eqs and eqs['b'].type == PARAMETER
assert not eqs['f'].is_bool and eqs['b'].is_bool
Expand Down Expand Up @@ -222,7 +222,7 @@ def test_construction_errors():

eqs = [SingleEquation(DIFFERENTIAL_EQUATION, 'v', volt,
expr=Expression('-v / tau')),
SingleEquation(STATIC_EQUATION, 'v', volt,
SingleEquation(SUBEXPRESSION, 'v', volt,
expr=Expression('2 * t/second * volt'))
]
assert_raises(EquationError, lambda: Equations(eqs))
Expand All @@ -236,7 +236,7 @@ def test_construction_errors():
lambda: Equations('d1a/dt = -1a / tau : volt'))
assert_raises(ValueError, lambda: Equations('d_x/dt = -_x / tau : volt'))

# xi in a static equation
# xi in a subexpression
assert_raises(EquationError,
lambda: Equations('''dv/dt = -(v + I) / (5 * ms) : volt
I = second**-1*xi**-2*volt : volt'''))
Expand All @@ -251,10 +251,10 @@ def test_construction_errors():
eqs.check_flags({DIFFERENTIAL_EQUATION: ['flag']}) # allow this flag
assert_raises(ValueError, lambda: eqs.check_flags({DIFFERENTIAL_EQUATION: []}))
assert_raises(ValueError, lambda: eqs.check_flags({}))
assert_raises(ValueError, lambda: eqs.check_flags({STATIC_EQUATION: ['flag']}))
assert_raises(ValueError, lambda: eqs.check_flags({SUBEXPRESSION: ['flag']}))
assert_raises(ValueError, lambda: eqs.check_flags({DIFFERENTIAL_EQUATION: ['otherflag']}))

# Circular static equations
# Circular subexpression
assert_raises(ValueError, lambda: Equations('''dv/dt = -(v + w) / (10 * ms) : 1
w = 2 * x : 1
x = 3 * w : 1'''))
Expand Down Expand Up @@ -287,7 +287,7 @@ def __init__(self, unit):
assert_raises(DimensionMismatchError,
lambda: eqs.check_units(group))

# inconsistent unit for a static equation
# inconsistent unit for a subexpression
eqs = Equations('''dv/dt = -v / (5 * ms) : volt
I = 2 * v : amp''')
group = SimpleGroup(variables={'v': S(volt),
Expand Down Expand Up @@ -322,7 +322,7 @@ def test_properties():
[eq.varname for eq in eqs.ordered] == ['f', 'I', 'v', 'freq'])
assert eqs.names == set(['v', 'I', 'f', 'freq'])
assert eqs.parameter_names == set(['freq'])
assert eqs.static_eq_names == set(['I', 'f'])
assert eqs.subexpr_names == set(['I', 'f'])
units = eqs.units
assert set(units.keys()) == set(['v', 'I', 'f', 'freq'])
assert units['v'] == volt
Expand Down
4 changes: 2 additions & 2 deletions brian2/tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ def test_math_functions():
numpy_result = func(test_array)

# Calculate the result in a somewhat complicated way by using a
# static equation in a NeuronGroup
# subexpression in a NeuronGroup
clock = Clock()
if func.__name__ == 'absolute':
# we want to use the name abs instead of absolute
Expand Down Expand Up @@ -87,7 +87,7 @@ def test_math_functions():
numpy_result = func(test_array, scalar)

# Calculate the result in a somewhat complicated way by using a
# static equation in a NeuronGroup
# subexpression in a NeuronGroup
clock = Clock()
G = NeuronGroup(len(test_array),
'''func = variable {op} scalar : 1
Expand Down
10 changes: 5 additions & 5 deletions brian2/tests/test_stateupdaters.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,14 +302,14 @@ def test_determination():
# reset to state before the test
StateUpdateMethod.stateupdaters = before

def test_static_equations():
def test_subexpressions():
'''
Make sure that the integration of a (non-stochastic) differential equation
does not depend on whether it's formulated using static equations.
does not depend on whether it's formulated using subexpressions.
'''
# no static equation
# no subexpression
eqs1 = 'dv/dt = (-v + sin(2*pi*100*Hz*t)) / (10*ms) : 1'
# same with static equation
# same with subexpression
eqs2 = '''dv/dt = I / (10*ms) : 1
I = -v + sin(2*pi*100*Hz*t): 1'''

Expand All @@ -335,4 +335,4 @@ def test_static_equations():
test_integrator_code()
test_priority()
test_registration()
test_static_equations()
test_subexpressions()
4 changes: 2 additions & 2 deletions docs_sphinx/user/equations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Equations are defined by multiline strings.

An Equation is a set of single lines in a string:
(1) ``dx/dt = f : unit`` (differential equation)
(2) ``x = f : unit`` (static equation)
(2) ``x = f : unit`` (subexpression)
(3) ``x : unit`` (parameter)

The equations may be defined on multiple lines (no explicit line continuation with ``\`` is necessary).
Expand Down Expand Up @@ -65,7 +65,7 @@ There are additional constraints:
* An event-driven variable cannot be used by any other equation that is not
also event-driven.
* An event-driven equation cannot depend on a differential equation that is not
event-driven (directly, or indirectly through static equations). It can depend
event-driven (directly, or indirectly through subexpressions). It can depend
on a constant parameter. An open question is whether we should also allow it
to depend on a parameter not defined as constant (I would say no).

Expand Down

0 comments on commit 16f90a6

Please sign in to comment.