Skip to content

Commit 0e42862

Browse files
committed
Correctly handle random parameters appearing in the denominator
1 parent 4bac15e commit 0e42862

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

pynest/nest/lib/hl_api_types.py

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

10791079
def __rtruediv__(self, lhs):
1080-
rhs_inv = CreateParameter("constant", {"value": 1 / float(self.GetValue())})
1081-
return rhs_inv._binop("mul", lhs)
1080+
return self**-1 * lhs
10821081

10831082
def __pow__(self, exponent):
10841083
try:
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
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}. We expect then that there must be at least one positive and at
72+
least one negative result.
73+
"""
74+
num_neurons = 10
75+
try:
76+
n = nest.Create(
77+
"iaf_psc_alpha", num_neurons, {"V_m": nest.random.uniform(1, 2) / (1.0 - 2.0 * nest.random.uniform_int(2))}
78+
)
79+
except TypeError:
80+
pass
81+
else:
82+
V_m = n.V_m
83+
assert len(set(n.V_m)) == num_neurons
84+
assert sum(V < 0 for V in V_m) > 0
85+
assert sum(V >= 0 for V in V_m) > 0

0 commit comments

Comments
 (0)