def test_parameter_arithmetic(self): """Test parameter arithmetic""" p1 = nest.CreateParameter('constant', {'value': 3.0}) p2 = nest.CreateParameter('constant', {'value': 2.0}) self.assertEqual((p1 + p2).GetValue(), 5.0) self.assertEqual((p1 - p2).GetValue(), 1.0) self.assertEqual((p1 / p2).GetValue(), 1.5) self.assertEqual((p1 * p2).GetValue(), 6.0)
def test_power_parameter(self): """Test parameter raised to the power of an exponent""" # Negative values for value in np.linspace(-5.0, 0.0, 15): p = nest.CreateParameter('constant', {'value': value}) # Exponents must be integers for exponent in range(-15, 15): self.assertEqual((p**exponent).GetValue(), value**exponent) # Positive values for value in np.linspace(0.0, 5.0, 15): p = nest.CreateParameter('constant', {'value': value}) for exponent in np.linspace(-5.0, 5.0, 15): self.assertEqual((p**exponent).GetValue(), value**exponent)
def test_max_parameter(self): """Test max of parameter""" reference_value = 2.0 for value in np.linspace(-5.0, 5.0, 21): p = nest.CreateParameter('constant', {'value': value}) self.assertEqual( nest.math.max(p, reference_value).GetValue(), np.maximum(value, reference_value))
def test_parameter_comparison(self): """Test comparison of parameters""" p1 = nest.CreateParameter('constant', {'value': 1.0}) p2 = nest.CreateParameter('constant', {'value': 2.0}) self.assertTrue((p1 < p2).GetValue()) self.assertTrue((p1 <= p2).GetValue()) self.assertTrue((p1 == p2 - p1).GetValue()) self.assertTrue((p1 != p2).GetValue()) self.assertTrue((p2 >= p1).GetValue()) self.assertTrue((p2 > p1).GetValue()) self.assertFalse((p2 < p1).GetValue()) self.assertFalse((p2 <= p1).GetValue()) self.assertFalse((p1 == p2).GetValue()) self.assertFalse((p1 != p2 - p1).GetValue()) self.assertFalse((p1 >= p2).GetValue()) self.assertFalse((p1 > p2).GetValue())
def test_syn_spec_parameter(self): """Test parameter in syn_spec""" n = nest.Create('iaf_psc_alpha', 2) p = nest.CreateParameter('constant', {'value': 2.0}) nest.Connect(n, n, syn_spec={'weight': p}) conns = nest.GetConnections() weights = conns.get('weight') for w in weights: self.assertEqual(w, 2.0)
def test_conn_spec_parameter(self): """Test parameter in conn_spec""" p = nest.CreateParameter('constant', {'value': 1.0}) p2 = nest.CreateParameter('constant', {'value': 2.0}) rule_specs = { 'pairwise_bernoulli': [ ['p', p], ], 'fixed_outdegree': [ ['outdegree', p2], ], 'fixed_indegree': [ ['indegree', p2], ] } for rule, specs_list in rule_specs.items(): for specs in specs_list: nest.ResetKernel() n = nest.Create('iaf_psc_alpha', 2) param, p = specs nest.Connect(n, n, conn_spec={'rule': rule, param: p}) self.assertEqual(nest.num_connections, 4, f'Error with {rule}')
def test_parameter_is_spatial(self): """Test parameter is_spatial function""" constant_parameter = nest.CreateParameter('constant', {'value': 1.0}) spatial_parameters = [ nest.spatial.pos.x, nest.spatial.distance, nest.spatial.distance.x ] non_spatial_parameters = [ constant_parameter, nest.random.uniform(), nest.random.normal(), nest.random.lognormal(), nest.random.exponential() ] def apply_assert(assert_func, p): assert_func(p.is_spatial()) assert_func(nest.math.cos(p).is_spatial()) assert_func(nest.math.sin(p).is_spatial()) assert_func(nest.math.exp(p).is_spatial()) assert_func(nest.math.max(p, 1.0).is_spatial()) assert_func(nest.math.min(p, 1.0).is_spatial()) assert_func(nest.math.redraw(p, 0.0, 1.0).is_spatial()) assert_func((p + constant_parameter).is_spatial()) assert_func((constant_parameter + p).is_spatial()) assert_func( nest.logic.conditional(p, constant_parameter, constant_parameter).is_spatial()) assert_func( nest.logic.conditional(constant_parameter, p, constant_parameter).is_spatial()) assert_func( nest.logic.conditional(constant_parameter, constant_parameter, p).is_spatial()) for p in spatial_parameters: apply_assert(self.assertTrue, p) for p in non_spatial_parameters: apply_assert(self.assertFalse, p)
def __init__(self, seed, dim, L, N, spatial_distribution, distribution_params=None, open_bc=False, x0=0., y0=0.): """ Construct a test object. Parameters ---------- seed : Random seed for test dim : Dimensions (2 or 3) L : Side length of area / volume. N : Number of nodes. spatial_distribution : Name of spatial distribution to use. distribution_params : Dict with params to update. open_bc : Network with open boundary conditions x0, y0 : Location of source neuron; open_bc only Note ---- For each new distribution to be added, the following needs to be defined: self._<distribution> : function implementing distribution function spatial_distributions entry : mapping distribution name to distribution function default_params : default set of parameters for distribution """ if dim != 2 and open_bc: raise ValueError("open_bc only supported for 2D") self._seed = seed self._dimensions = dim self._L = float(L) self._N = N self._open_bc = open_bc self._x_d, self._y_d = x0, y0 if (self._dimensions == 2): if (self._open_bc): self._max_dist = self._L * math.sqrt(2) self._pdf = self._pdf_2d_obc else: self._max_dist = self._L / math.sqrt(2) self._pdf = self._pdf_2d elif (self._dimensions == 3): self._max_dist = self._L * math.sqrt(3) / 2 self._pdf = self._pdf_3d self._target_dists = None self._all_dists = None spatial_distributions = { 'constant': self._constant, 'linear': self._linear, 'exponential': self._exponential, 'gaussian': self._gauss, 'gamma': self._gamma } self._distribution = spatial_distributions[spatial_distribution] default_params = { 'constant': 1., 'linear': { 'a': -math.sqrt(2) / self._L, 'c': 1.0 }, 'exponential': { 'a': 1.0, 'c': 0.0, 'tau': -self._L / (math.sqrt(2) * math.log((.1 - 0) / 1)) }, 'gaussian': { 'p_center': 1., 'sigma': self._L / 4., 'mean': 0., 'c': 0. }, 'gamma': { 'kappa': 3., 'theta': self._L / 4. } } self._params = default_params[spatial_distribution] if distribution_params is not None: if spatial_distribution == 'constant': self._params = distribution_params else: self._params.update(distribution_params) # Pre-calculate constant variables for efficiency self._calculate_constants(spatial_distribution) if self._dimensions == 3: maskdict = { 'box': { 'lower_left': [-self._L / 2.] * 3, 'upper_right': [self._L / 2.] * 3 } } elif self._dimensions == 2 and not self._open_bc: maskdict = { 'rectangular': { 'lower_left': [-self._L / 2.] * 2, 'upper_right': [self._L / 2.] * 2 } } elif self._dimensions == 2 and self._open_bc: maskdict = { 'rectangular': { 'lower_left': [-self._L] * 2, 'upper_right': [self._L] * 2 } } if spatial_distribution == 'constant': distribution = nest.CreateParameter('constant', {'value': self._params}) elif spatial_distribution == 'linear': distribution = self._params[ 'c'] + self._params['a'] * nest.spatial.distance elif spatial_distribution == 'exponential': distribution = self._params[ 'c'] + nest.spatial_distributions.exponential( nest.spatial.distance, beta=self._params['tau']) elif spatial_distribution == 'gaussian': distribution = self._params[ 'c'] + nest.spatial_distributions.gaussian( nest.spatial.distance, mean=self._params['mean'], std=self._params['sigma']) elif spatial_distribution == 'gamma': distribution = nest.spatial_distributions.gamma( nest.spatial.distance, kappa=self._params['kappa'], theta=self._params['theta']) self._conndict = { 'rule': 'pairwise_bernoulli', 'p': distribution, 'mask': maskdict }
def __init__(self, seed, dim, L, N, kernel_name, kernel_params=None, open_bc=False, x0=0., y0=0.): ''' Construct a test object. Parameters ---------- seed : Random seed for test dim : Dimensions (2 or 3) L : Side length of area / volume. N : Number of nodes. kernel_name : Name of kernel to use. kernel_params: Dict with params to update. open_bc : Network with open boundary conditions x0, y0 : Location of source neuron; open_bc only Note ---- For each new kernel to be added, the following needs to be defined: self._<kernel> : lambda-function implementing kernel function kernels entry : mapping kernel name to kernel function default_params : default set of parameters for kernel ''' if dim != 2 and open_bc: raise ValueError("open_bc only supported for 2D") self._seed = seed self._dimensions = dim self._L = float(L) self._N = N self._open_bc = open_bc self._x_d, self._y_d = x0, y0 if (self._dimensions == 2): if (self._open_bc): self._max_dist = self._L * math.sqrt(2) else: self._max_dist = self._L / math.sqrt(2) elif (self._dimensions == 3): self._max_dist = self._L * math.sqrt(3) / 2 self._target_dists = None self._all_dists = None # kernel functions self._constant = lambda D: self._params self._linear = lambda D: self._params['c'] + self._params['a'] * D self._exponential = lambda D: (self._params['c'] + self._params['a'] * math.exp(-D / self._params['tau'])) self._gauss = lambda D: (self._params['c'] + self._params['p_center'] * math.exp(-(D - self._params['mean'])**2 / (2. * self._params['sigma']**2))) self._gamma = lambda D: (D**(self._params['kappa'] - 1) / ( self._params['theta']**self._params['kappa'] * scipy.special.gamma( self._params['kappa'])) * math.exp(-D / self._params['theta'])) kernels = { 'constant': self._constant, 'linear': self._linear, 'exponential': self._exponential, 'gaussian': self._gauss, 'gamma': self._gamma } self._kernel = kernels[kernel_name] default_params = { 'constant': 1., 'linear': { 'a': -math.sqrt(2) / self._L, 'c': 1.0 }, 'exponential': { 'a': 1.0, 'c': 0.0, 'tau': -self._L / (math.sqrt(2) * math.log((.1 - 0) / 1)) }, 'gaussian': { 'p_center': 1., 'sigma': self._L / 4., 'mean': 0., 'c': 0. }, 'gamma': { 'kappa': 3., 'theta': self._L / 4. } } self._params = default_params[kernel_name] if kernel_params is not None: if kernel_name == 'constant': self._params = kernel_params else: self._params.update(kernel_params) if self._dimensions == 3: maskdict = { 'box': { 'lower_left': [-self._L / 2.] * 3, 'upper_right': [self._L / 2.] * 3 } } elif self._dimensions == 2 and not self._open_bc: maskdict = { 'rectangular': { 'lower_left': [-self._L / 2.] * 2, 'upper_right': [self._L / 2.] * 2 } } elif self._dimensions == 2 and self._open_bc: maskdict = { 'rectangular': { 'lower_left': [-self._L] * 2, 'upper_right': [self._L] * 2 } } if kernel_name == 'constant': kernel = nest.CreateParameter('constant', {'value': self._params}) elif kernel_name == 'linear': kernel = (self._params['c'] + self._params['a'] * nest.spatial.distance) elif kernel_name == 'exponential': kernel = self._params['c'] + nest.spatial_distributions.exponential( nest.spatial.distance, beta=self._params['tau']) elif kernel_name == 'gaussian': kernel = self._params['c'] + nest.spatial_distributions.gaussian( nest.spatial.distance, mean=self._params['mean'], std=self._params['sigma']) elif kernel_name == 'gamma': kernel = nest.spatial_distributions.gamma( nest.spatial.distance, kappa=self._params['kappa'], theta=self._params['theta']) self._conndict = { 'rule': 'pairwise_bernoulli', 'p': kernel, 'mask': maskdict }
def test_sin_parameter(self): """Test sine of a parameter""" for value in np.linspace(-5.0, 5.0, 15): p = nest.CreateParameter('constant', {'value': value}) self.assertAlmostEqual(nest.math.sin(p).GetValue(), np.sin(value))
def test_exp_parameter(self): """Test exponential of a parameter""" for value in np.linspace(-5.0, 5.0, 15): p = nest.CreateParameter('constant', {'value': value}) self.assertEqual(nest.math.exp(p).GetValue(), np.exp(value))