Source code for pyrates.backend.fortran.fortran_funcs

# -*- coding: utf-8 -*-
#
#
# PyRates software framework for flexible implementation of neural
# network model_templates and simulations. See also:
# https://github.com/pyrates-neuroscience/PyRates
#
# Copyright (C) 2017-2018 the original authors (Richard Gast and
# Daniel Rose), the Max-Planck-Institute for Human Cognitive Brain
# Sciences ("MPI CBS") and contributors
#
# This program 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 3 of the License, or
# (at your option) any later version.
#
# This program 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 this program.  If not, see <https://www.gnu.org/licenses/>
#
# CITATION:
#
# Richard Gast and Daniel Rose et. al. in preparation

"""Contains fortran function definitions that may be used for PyRates model equations.
"""

from typing import Union
import numpy as np

# function definitions
######################


# sigmoid function
sigmoid = lambda x: 1./(1. + np.exp(-x))


# function for calculating the logistic function of an nd-array
[docs]def get_sigmoid_def(idx: int, out_shape: Union[tuple, str] = '', dtype: str = 'real') -> tuple: isarray = len(out_shape) > 0 fname = f"fsigmoid_{idx}" sigmoid_n = f"s = size(x)\ndo n=1,s\n {fname}(n) = 1 / (1 + exp(-x(n)))\nend do" sigmoid_0 = f"{fname} = 1 / (1 + exp(-x))" func = f""" function {fname}(x) implicit none {dtype} :: {fname}{out_shape if isarray else ''} {dtype} :: x{out_shape if isarray else ''} {"integer :: n, s" if isarray else ""} {sigmoid_n if isarray else sigmoid_0} end function {fname} """ return fname, func
# wrapper function for interpolating a 1d-array
[docs]def get_interp_def(idx: int, out_shape: Union[tuple, str] = '', dtype: str = 'real') -> tuple: fname = f"finterp_{idx}" func = f""" function {fname}(x_new,x,y) implicit none {dtype} :: {fname} {dtype} :: x(:), y(:), x_new {dtype} :: x_inc integer :: n, s s = size(x) if (x_new < x(1)) then {fname} = y(1) else if (x_new > x(s)) then {fname} = y(s) else do n = 1, s if (x(n) > x_new) exit end do if (n == 1) then {fname} = y(1) else if (n == s+1) then {fname} = y(s) else x_inc = (x_new - x(n-1)) / (x(n) - x(n-1)) {fname} = y(n) + x_inc*(y(n) - y(n-1)) end if end if end function {fname} """ return fname, func
# wrapper function for interpolating a 1d-array
[docs]def get_sign_def(idx: int, out_shape: Union[tuple, str] = '', dtype: str = 'real') -> tuple: isarray = len(out_shape) > 0 fname = f"fsign_{idx}" sign_n = f"s = size(x)\ndo n=1,s\n {fname}(n) = sign(a,x(n))\nend do" sign_0 = f"{fname} = sign(a,x)" func = f""" function {fname}(x) implicit none {dtype} :: {fname}{out_shape if isarray else ''} {dtype} :: x{out_shape if isarray else ''} {dtype} :: a {"integer :: n, s" if isarray else ""} a = 1.0 {sign_n if isarray else sign_0} end function {fname} """ return fname, func
# dictionary for backend import ############################### fortran_funcs = { 'maxi': {'call': 'max', 'func': np.maximum}, 'mini': {'call': 'min', 'func': np.minimum}, 'round': {'call': 'nint', 'func': np.round}, 'sum': {'call': 'sum', 'func': np.sum}, 'matmul': {'call': 'matmul', 'func': np.dot}, 'matvec': {'call': 'matmul', 'func': np.dot}, 'roll': {'call': 'cshift', 'func': np.roll}, 'tanh': {'call': 'tanh', 'func': np.tanh}, 'sinh': {'call': 'sinh', 'func': np.sinh}, 'cosh': {'call': 'cosh', 'func': np.cosh}, 'arctan': {'call': 'atan', 'func': np.arctan}, 'arcsin': {'call': 'asin', 'func': np.arcsin}, 'arccos': {'call': 'acos', 'func': np.arccos}, 'sin': {'call': 'sin', 'func': np.sin}, 'cos': {'call': 'cos', 'func': np.cos}, 'tan': {'call': 'tan', 'func': np.tan}, 'exp': {'call': 'exp', 'func': np.exp}, 'sigmoid': {'call': get_sigmoid_def, 'func': sigmoid}, 'interp': {'call': get_interp_def, 'func': np.interp}, 'real': {'call': 'realpart', 'func': np.real}, 'imag': {'call': 'imagpart', 'func': np.imag}, 'conj': {'call': 'conjg', 'func': np.conjugate}, 'absv': {'call': 'abs', 'func': np.abs}, 'sign': {'call': get_sign_def, 'func': np.sign}, 'log': {'call': 'log', 'func': np.log}, }