Skip to content

Commit 90ad974

Browse files
authored
Merge pull request #3158 from heplesser/fix-3156
Correctly handle random parameters appearing in the denominator
2 parents 73e8762 + f1fffbf commit 90ad974

File tree

3 files changed

+88
-3
lines changed

3 files changed

+88
-3
lines changed

lib/sli/nest-init.sli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ def
413413

414414
/CreateParameter trie
415415
[/dictionarytype] /CreateParameter_D load addtotrie
416-
[/doubletype] /CreateParameter_D load addtotrie
416+
[/doubletype] { /val Set << /constant << /value val >> >> CreateParameter_D } addtotrie
417417
def
418418

419419
/GetValue [/parametertype]

pynest/nest/lib/hl_api_types.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1084,8 +1084,7 @@ def __truediv__(self, rhs):
10841084
return self._binop("div", rhs)
10851085

10861086
def __rtruediv__(self, lhs):
1087-
rhs_inv = CreateParameter("constant", {"value": 1 / float(self.GetValue())})
1088-
return rhs_inv._binop("mul", lhs)
1087+
return self**-1 * lhs
10891088

10901089
def __pow__(self, exponent):
10911090
try:
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# test_regression_issue-3156.py
4+
#
5+
# This file is part of NEST.
6+
#
7+
# Copyright (C) 2004 The NEST Initiative
8+
#
9+
# NEST is free software: you can redistribute it and/or modify
10+
# it under the terms of the GNU General Public License as published by
11+
# the Free Software Foundation, either version 2 of the License, or
12+
# (at your option) any later version.
13+
#
14+
# NEST is distributed in the hope that it will be useful,
15+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
16+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17+
# GNU General Public License for more details.
18+
#
19+
# You should have received a copy of the GNU General Public License
20+
# along with NEST. If not, see <http://www.gnu.org/licenses/>.
21+
22+
import operator as ops
23+
24+
import nest
25+
import pytest
26+
27+
"""
28+
Tests to ensure that random parameters can be used with all operators that support parameters.
29+
30+
We expect that each parameter value drawn will differ from all others.
31+
"""
32+
33+
34+
@pytest.fixture(autouse=True)
35+
def reset():
36+
nest.ResetKernel()
37+
38+
39+
num_neurons = 10
40+
operators = [ops.add, ops.sub, ops.mul, ops.truediv, ops.pow, ops.mod]
41+
42+
43+
@pytest.mark.parametrize("lhs", [1, 2, 2.0])
44+
@pytest.mark.parametrize("op", operators)
45+
def test_params_random_denominator(lhs, op):
46+
num_neurons = 10
47+
try:
48+
n = nest.Create("iaf_psc_alpha", num_neurons, {"V_m": op(lhs, nest.random.uniform(1, 2))})
49+
except TypeError:
50+
pass # operation not supported for parameter
51+
else:
52+
assert len(set(n.V_m)) == num_neurons
53+
54+
55+
@pytest.mark.parametrize("op", operators)
56+
@pytest.mark.parametrize("rhs", [1, 2, 2.0])
57+
def test_params_random_numerator(op, rhs):
58+
num_neurons = 10
59+
60+
try:
61+
n = nest.Create("iaf_psc_alpha", num_neurons, {"V_m": op(nest.random.uniform(1, 2), rhs)})
62+
except TypeError:
63+
pass # operation not supported for parameter
64+
else:
65+
assert len(set(n.V_m)) == num_neurons
66+
67+
68+
def test_random_numer_and_denom():
69+
"""
70+
For random parameters in numerator and denominator, we make the denominator uniform
71+
on the set {-1, +1}. For 50 neurons, the probability that the denominator has the same
72+
sign (either positive or negative) is 2 * 2^-50 ≈ 2e-15.
73+
"""
74+
75+
num_neurons = 50
76+
try:
77+
n = nest.Create(
78+
"iaf_psc_alpha", num_neurons, {"V_m": nest.random.uniform(1, 2) / (1.0 - 2.0 * nest.random.uniform_int(2))}
79+
)
80+
except TypeError:
81+
pass
82+
else:
83+
V_m = n.V_m
84+
assert len(set(n.V_m)) == num_neurons
85+
assert sum(V < 0 for V in V_m) > 0
86+
assert sum(V >= 0 for V in V_m) > 0

0 commit comments

Comments
 (0)