diff --git a/doc/nestml_language/nestml_language_concepts.rst b/doc/nestml_language/nestml_language_concepts.rst
index efbf0539e..5d22a0a48 100644
--- a/doc/nestml_language/nestml_language_concepts.rst
+++ b/doc/nestml_language/nestml_language_concepts.rst
@@ -579,6 +579,8 @@ The following variables and constants are predefined in NESTML and can be used o
- The current simulation time (read only)
* - ``e``
- Euler's constant (2.718...)
+ * - ``pi``
+ - pi (3.14159...)
* - ``inf``
- Floating point infinity
diff --git a/pynestml/codegeneration/printers/c_variable_printer.py b/pynestml/codegeneration/printers/c_variable_printer.py
deleted file mode 100644
index 0d8e9fe28..000000000
--- a/pynestml/codegeneration/printers/c_variable_printer.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# c_variable_printer.py
-#
-# This file is part of NEST.
-#
-# Copyright (C) 2004 The NEST Initiative
-#
-# NEST is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 2 of the License, or
-# (at your option) any later version.
-#
-# NEST is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with NEST. If not, see .
-
-from pynestml.codegeneration.printers.cpp_variable_printer import CppVariablePrinter
-from pynestml.codegeneration.printers.variable_printer import VariablePrinter
-from pynestml.meta_model.ast_variable import ASTVariable
-from pynestml.symbols.predefined_variables import PredefinedVariables
-
-
-class CVariablePrinter(VariablePrinter):
-
- def print_variable(self, node: ASTVariable) -> str:
- """
- Print a variable.
- :param node: a single variable symbol or variable
- :return: a string representation
- """
- assert isinstance(node, ASTVariable)
-
- if node.get_name() == PredefinedVariables.E_CONSTANT:
- return "REAL_CONST(2.718282)"
-
- return CppVariablePrinter._print_cpp_name(node.get_complete_name())
diff --git a/pynestml/codegeneration/printers/cpp_variable_printer.py b/pynestml/codegeneration/printers/cpp_variable_printer.py
index f0615456d..2a6af847a 100644
--- a/pynestml/codegeneration/printers/cpp_variable_printer.py
+++ b/pynestml/codegeneration/printers/cpp_variable_printer.py
@@ -49,6 +49,9 @@ def print_variable(self, node: ASTVariable) -> str:
assert isinstance(node, ASTVariable)
if node.get_name() == PredefinedVariables.E_CONSTANT:
- return "numerics::e"
+ return "2.718281828459045235360287471352" # not defined in C++11 stdlib
+
+ if node.get_name() == PredefinedVariables.E_CONSTANT:
+ return "M_PI" # from
return CppVariablePrinter._print_cpp_name(node.get_complete_name())
diff --git a/pynestml/codegeneration/printers/nest_variable_printer.py b/pynestml/codegeneration/printers/nest_variable_printer.py
index 3f6fc61dd..48bbef59e 100644
--- a/pynestml/codegeneration/printers/nest_variable_printer.py
+++ b/pynestml/codegeneration/printers/nest_variable_printer.py
@@ -72,7 +72,10 @@ def print_variable(self, variable: ASTVariable) -> str:
return "((post_neuron_t*)(__target))->get_" + _name + "(_tr_t)"
if variable.get_name() == PredefinedVariables.E_CONSTANT:
- return "numerics::e"
+ return "numerics::e" # from nest::
+
+ if variable.get_name() == PredefinedVariables.PI_CONSTANT:
+ return "numerics::pi" # from nest::
if variable.get_name() == PredefinedVariables.TIME_CONSTANT:
return "get_t()"
diff --git a/pynestml/codegeneration/printers/python_stepping_function_variable_printer.py b/pynestml/codegeneration/printers/python_stepping_function_variable_printer.py
index 856bc1199..84f4f9c3c 100644
--- a/pynestml/codegeneration/printers/python_stepping_function_variable_printer.py
+++ b/pynestml/codegeneration/printers/python_stepping_function_variable_printer.py
@@ -42,6 +42,9 @@ def print_variable(self, node: ASTVariable) -> str:
if node.get_name() == PredefinedVariables.E_CONSTANT:
return "np.e"
+ if node.get_name() == PredefinedVariables.PI_CONSTANT:
+ return "np.pi"
+
symbol = node.get_scope().resolve_to_symbol(node.get_complete_name(), SymbolKind.VARIABLE)
if symbol.is_state() and not symbol.is_inline_expression:
diff --git a/pynestml/codegeneration/printers/python_variable_printer.py b/pynestml/codegeneration/printers/python_variable_printer.py
index 6f084a694..ab137efb5 100644
--- a/pynestml/codegeneration/printers/python_variable_printer.py
+++ b/pynestml/codegeneration/printers/python_variable_printer.py
@@ -74,6 +74,9 @@ def print_variable(self, variable: ASTVariable) -> str:
if variable.get_name() == PredefinedVariables.E_CONSTANT:
return "math.e"
+ if variable.get_name() == PredefinedVariables.PI_CONSTANT:
+ return "math.pi"
+
symbol = variable.get_scope().resolve_to_symbol(variable.get_complete_name(), SymbolKind.VARIABLE)
if symbol is None:
# test if variable name can be resolved to a type
diff --git a/pynestml/codegeneration/printers/spinnaker_c_variable_printer.py b/pynestml/codegeneration/printers/spinnaker_c_variable_printer.py
index e21cfaf31..867a73dbf 100644
--- a/pynestml/codegeneration/printers/spinnaker_c_variable_printer.py
+++ b/pynestml/codegeneration/printers/spinnaker_c_variable_printer.py
@@ -63,6 +63,9 @@ def print_variable(self, variable: ASTVariable) -> str:
if variable.get_name() == PredefinedVariables.E_CONSTANT:
return "REAL_CONST(2.718282)"
+ if variable.get_name() == PredefinedVariables.PI_CONSTANT:
+ return "REAL_CONST(3.14159)"
+
symbol = variable.get_scope().resolve_to_symbol(variable.get_complete_name(), SymbolKind.VARIABLE)
if symbol is None:
# test if variable name can be resolved to a type
diff --git a/pynestml/symbols/predefined_variables.py b/pynestml/symbols/predefined_variables.py
index bdab262d1..30226c71c 100644
--- a/pynestml/symbols/predefined_variables.py
+++ b/pynestml/symbols/predefined_variables.py
@@ -29,9 +29,10 @@ class PredefinedVariables:
"""
This class is used to store all predefined variables as generally available.
"""
- name2variable = {} # type: Mapping[str, VariableSymbol]
- E_CONSTANT = 'e' # type: str
- TIME_CONSTANT = 't' # type: str
+ name2variable: Mapping[str, VariableSymbol] = {}
+ E_CONSTANT: str = 'e'
+ PI_CONSTANT: str = 'pi'
+ TIME_CONSTANT: str = 't'
@classmethod
def register_variables(cls):
@@ -40,6 +41,7 @@ def register_variables(cls):
"""
cls.name2variable = {}
cls.__register_euler_constant()
+ cls.__register_pi_constant()
cls.__register_time_constant()
@classmethod
@@ -53,7 +55,6 @@ def __register_predefined_type_variables(cls):
type_symbol=PredefinedTypes.get_type(name),
variable_type=VariableType.TYPE)
cls.name2variable[name] = symbol
- return
@classmethod
def __register_euler_constant(cls):
@@ -64,7 +65,16 @@ def __register_euler_constant(cls):
is_predefined=True, type_symbol=PredefinedTypes.get_real_type(),
variable_type=VariableType.VARIABLE)
cls.name2variable[cls.E_CONSTANT] = symbol
- return
+
+ @classmethod
+ def __register_pi_constant(cls):
+ """
+ Adds the pi constant.
+ """
+ symbol = VariableSymbol(name='pi', block_type=BlockType.STATE,
+ is_predefined=True, type_symbol=PredefinedTypes.get_real_type(),
+ variable_type=VariableType.VARIABLE)
+ cls.name2variable[cls.PI_CONSTANT] = symbol
@classmethod
def __register_time_constant(cls):
@@ -75,7 +85,6 @@ def __register_time_constant(cls):
is_predefined=True, type_symbol=PredefinedTypes.get_type('ms'),
variable_type=VariableType.VARIABLE)
cls.name2variable[cls.TIME_CONSTANT] = symbol
- return
@classmethod
def get_time_constant(cls):
@@ -106,8 +115,8 @@ def get_variable(cls, name):
"""
if name in cls.name2variable.keys():
return cls.name2variable[name]
- else:
- return None
+
+ return None
@classmethod
def get_variables(cls):
diff --git a/tests/resources/ExpressionCollection.nestml b/tests/resources/ExpressionCollection.nestml
index 5f1dd0f94..f0edec72b 100644
--- a/tests/resources/ExpressionCollection.nestml
+++ b/tests/resources/ExpressionCollection.nestml
@@ -152,6 +152,9 @@ model ExpressionCollection:
testerf real = erf(0.)
testerfc real = erfc(0.)
+ test_e real = e
+ test_pi real = pi
+
equations:
#neuron aeif_cond_alpha_neuron
test0 = E_L