예제 #1
0
    def rng(self) -> tuple:
        """Gathers all random variables.

        Returns:
            declared_rng, initialize_rng, rng_method
        """
        declared_rng = """
    // Random variables"""
        initialize_rng = """
        // Random Variables"""

        rng_tpl = Template("""
$init
        for(unsigned int i = 0; i < this->size; i++) {
$draw
        }
        """)
        rng_init = ""
        rng_update = ""

        for name, var in self.parser.random_variables.items():

            if isinstance(var, parser.RandomDistributions.Uniform):
                dist = "uniform_real_distribution< double >"
                # If the arguments are fixed throughout the simulation, no need to redraw
                fixed = isinstance(var.min, (float, int)) and isinstance(
                    var.max, (float, int))
                arg1 = parser.code_generation(var.min, self.correspondences)
                arg2 = parser.code_generation(var.max, self.correspondences)

            if isinstance(var, parser.RandomDistributions.Normal):
                dist = "normal_distribution< double >"
                # If the arguments are fixed throughout the simulation, no need to redraw
                fixed = isinstance(var.mu, (float, int)) and isinstance(
                    var.sigma, (float, int))
                arg1 = parser.code_generation(var.mu, self.correspondences)
                arg2 = parser.code_generation(var.sigma, self.correspondences)

            declared_rng += Template("""
    std::vector<double> $name;
    std::$dist dist$name;
            """).substitute(name=name, dist=dist)

            initialize_rng += Template("""
        this->$name = std::vector<double>(size, 0.0);
        this->dist$name = std::$dist($arg1, $arg2);
            """).substitute(name=name, dist=dist, arg1=arg1, arg2=arg2)

            if not fixed:
                rng_init += Template("""
        this->dist$name = std::$dist($arg1, $arg2);
            """).substitute(name=name, dist=dist, arg1=arg1, arg2=arg2)

            rng_update += Template("""
            this->$name[i] = this->dist$name(this->net->rng);
            """).substitute(name=name, dist=dist)

        rng_method = rng_tpl.substitute(init=rng_init, draw=rng_update)

        return declared_rng, initialize_rng, rng_method
예제 #2
0
    def reset(self) -> str:
        """Processes the Neuron.reset() field.
        
        Returns:

            the content of the `reset()` C++ method.

        """

        tpl_reset = Template("""
        for(unsigned int idx = 0; idx< this->spikes.size(); idx++){
                int i = this->spikes[idx];
$reset
        }
        """)

        # Equation template
        tpl_eq = Template("""
            // $hr
            $lhs $op $rhs;
        """)

        # Iterate over all blocks of equations
        code = ""
        for block in self.parser.reset_equations:
            for eq in block.equations:
                code += tpl_eq.substitute(
                    lhs="this->" + eq['name'] if eq['name']
                    in self.parser.shared else "this->" + eq['name'] + "[i]",
                    op=eq['op'],
                    rhs=parser.code_generation(eq['rhs'],
                                               self.correspondences),
                    hr=eq['human-readable'])

        return tpl_reset.substitute(reset=code)
예제 #3
0
    def update(self) -> str:
        """Processes the Neuron.update() field.
        
        Returns:

            the content of the `update()` C++ method.

        """

        # Block template
        tlp_block = Template("""
        for(unsigned int i = 0; i< this->size; i++){
$update
        }
        """)

        # Equation template
        tpl_eq = Template("""
            // $hr
            $lhs $op $rhs;
        """)

        # Iterate over all blocks of equations
        code = ""
        for block in self.parser.update_equations:
            for eq in block.equations:

                # Temporary variables
                if eq['type'] == 'tmp':
                    code += tpl_eq.substitute(lhs="double " + eq['name'],
                                              op=eq['op'],
                                              rhs=parser.code_generation(
                                                  eq['rhs'],
                                                  self.correspondences),
                                              hr=eq['human-readable'])
                else:
                    code += tpl_eq.substitute(
                        lhs="this->" + eq['name']
                        if eq['name'] in self.parser.shared else "this->" +
                        eq['name'] + "[i]",
                        op=eq['op'],
                        rhs=parser.code_generation(eq['rhs'],
                                                   self.correspondences),
                        hr=eq['human-readable'])

        return tlp_block.substitute(update=code)
예제 #4
0
    def spike(self) -> str:
        """Processes the Neuron.spike() field.
        
        Returns:

            the content of the `spike()` C++ method.

        """

        tpl_spike = Template("""
        this->spikes.clear();
        for(unsigned int i = 0; i< this->size; i++){
            if ($condition){
                this->spikes.push_back(i);
            }
        }
        """)

        cond = parser.code_generation(
            self.parser.spike_condition.equation['eq'], self.correspondences)

        return tpl_spike.substitute(condition=cond)