From 6e2b725d75bc69e1f13606138dbf4e1566503fef Mon Sep 17 00:00:00 2001 From: clinssen Date: Wed, 10 Jul 2024 14:36:05 +0200 Subject: [PATCH] add pi predefined constant (#1075) Co-authored-by: C.A.P. Linssen --- .../nestml_language_concepts.rst | 2 + .../printers/c_variable_printer.py | 41 ------------------- .../printers/cpp_variable_printer.py | 5 ++- .../printers/nest_variable_printer.py | 5 ++- ...thon_stepping_function_variable_printer.py | 3 ++ .../printers/python_variable_printer.py | 3 ++ .../printers/spinnaker_c_variable_printer.py | 3 ++ pynestml/symbols/predefined_variables.py | 25 +++++++---- tests/resources/ExpressionCollection.nestml | 3 ++ 9 files changed, 39 insertions(+), 51 deletions(-) delete mode 100644 pynestml/codegeneration/printers/c_variable_printer.py 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