1 """
2 Simple functions operating on a matrix, potentially modifying it.
3
4 These are useful for neuron output functions, normalization of
5 matrices, etc.
6
7 All of these function objects (callable objects) should work for
8 Numpy array arguments of arbitrary shape. Some may also work for
9 scalars.
10
11 $Id: basic.py 8029 2008-02-19 15:16:24Z ceball $
12 """
13 __version__='$Revision: 8029 $'
14
15
16 import numpy, numpy.random
17 import numpy.oldnumeric as Numeric
18 import copy
19 import topo
20
21 from numpy import exp,zeros,ones
22 from numpy.oldnumeric import dot, exp
23 from math import ceil
24
25
26 from topo.base.sheet import activity_type
27 from topo.base.arrayutils import clip_lower
28 from topo.base.arrayutils import L2norm, norm, array_argmax
29 from topo.base.functionfamilies import OutputFn
30 from topo.base.parameterclasses import Parameter,Number,ListParameter,\
31 BooleanParameter, StringParameter, ClassSelectorParameter
32 from topo.base.parameterizedobject import ParameterizedObject
33 from topo.base.patterngenerator import PatternGenerator,Constant
34 from topo.base.boundingregion import BoundingBox
35 from topo.patterns.basic import Gaussian
36
37
38 from topo.base.functionfamilies import IdentityOF,PipelineOF
39
40 Pipeline = PipelineOF
41
42
43
44
46 """
47 Piecewise-linear OutputFn with lower and upper thresholds.
48
49 Values below the lower_threshold are set to zero, those above
50 the upper threshold are set to 1.0, and those in between are
51 scaled linearly.
52 """
53 lower_bound = Number(default=0.0,softbounds=(0.0,1.0))
54 upper_bound = Number(default=1.0,softbounds=(0.0,1.0))
55
61
62
63
65 """
66 Sigmoidal (logistic) output function: 1/(1+exp-(r*x+k)).
67
68 As defined in Jochen Triesch, ICANN 2005, LNCS 3696 pp. 65-70.
69 The parameters control the growth rate (r) and the x position (k)
70 of the exponential.
71
72 This function is a special case of the GeneralizedLogistic
73 function, with parameters r=r, l=0, u=1, m=-k/2r, and b=1. See
74 Richards, F.J. (1959), A flexible growth function for empirical
75 use. J. Experimental Botany 10: 290--300, 1959.
76 http://en.wikipedia.org/wiki/Generalised_logistic_curve
77 """
78
79 r = Number(default=1,doc="Parameter controlling the growth rate")
80 k = Number(default=0,doc="Parameter controlling the x-postion")
81
83 x_orig = copy.copy(x)
84 x *= 0.0
85 x += 1.0 / (1.0 + exp(-(self.r*x_orig+self.k)))
86
87
88
90
91 """
92 Naka-Rushton curve.
93
94 From Naka, K. and Rushton, W. (1996), S-potentials from luminosity
95 units in the retina of fish (Cyprinidae). J. Physiology 185:587-599.
96
97 The Naka-Rushton curve has been shown to be a good approximation
98 of constrast gain control in cortical neurons. The input of the
99 curve is usually contrast, but under the assumption that the
100 firing rate of a model neuron is directly proportional to the
101 contrast, it can be used as an OutputFn for a Sheet.
102
103 The parameter c50 corresponds to the contrast at which the half of
104 the maximal output is reached. For a Sheet OutputFn this translates
105 to the input for which a neuron will respond with activity 0.5.
106 """
107
108 c50 = Number(default=0.1, doc="""
109 The input of the neuron at which it responds at half of its maximal firing rate (1.0).""")
110
111 e = Number(default=1.0,doc="""The exponent of the input x.""")
112
113
115
116
117 x_orig = copy.copy(x)
118 x *= 0
119 x += pow(x_orig,self.e) / (pow(x_orig,self.e) + pow(self.c50,self.e))
120
121
122
124 """
125 The generalized logistic curve (Richards' curve): y = l + (u /(1 + b * exp(-r*(x-2*m))^(1/b))).
126
127 The logistic curve is a flexible function for specifying a
128 nonlinear growth curve using five parameters:
129
130 * l: the lower asymptote
131 * u: the upper asymptote minus l
132 * m: the time of maximum growth
133 * r: the growth rate
134 * b: affects near which asymptote maximum growth occurs
135
136 From Richards, F.J. (1959), A flexible growth function for empirical
137 use. J. Experimental Botany 10: 290--300.
138 http://en.wikipedia.org/wiki/Generalised_logistic_curve
139 """
140
141
142
143
144
145
146
147 l = Number(default=1,doc="Parameter controlling the lower asymptote.")
148 u = Number(default=1,doc="Parameter controlling the upper asymptote (upper asymptote minus lower asymptote.")
149 m = Number(default=1,doc="Parameter controlling the time of maximum growth.")
150 r = Number(default=1,doc="Parameter controlling the growth rate.")
151 b = Number(default=1,doc="Parameter which affects near which asymptote maximum growth occurs.")
152
154 x_orig = copy.copy(x)
155 x *= 0.0
156 x += self.l + ( self.u /(1 + self.b*exp(-self.r *(x_orig - 2*self.m))**(1 / self.b)) )
157
158
159
161 """
162 OutputFn that divides an array by its L1 norm.
163
164 This operation ensures that the sum of the absolute values of the
165 array is equal to the specified norm_value, rescaling each value
166 to make this true. The array is unchanged if the sum of absolute
167 values is zero. For arrays of non-negative values where at least
168 one is non-zero, this operation is equivalent to a divisive sum
169 normalization.
170 """
171 norm_value = Number(default=1.0)
172
174 """L1-normalize the input array, if it has a nonzero sum."""
175 current_sum = 1.0*Numeric.sum(abs(x.ravel()))
176 if current_sum != 0:
177 factor = (self.norm_value/current_sum)
178 x *= factor
179
180
181
183 """
184 OutputFn to divide an array by its Euclidean length (aka its L2 norm).
185
186 For a given array interpreted as a flattened vector, keeps the
187 Euclidean length of the vector at a specified norm_value.
188 """
189 norm_value = Number(default=1.0)
190
192 tot = 1.0*L2norm(x.ravel())
193 if tot != 0:
194 factor = (self.norm_value/tot)
195 x *= factor
196
197
198
200 """
201 OutputFn to divide an array by its L-infinity norm
202 (i.e. the maximum absolute value of its elements).
203
204 For a given array interpreted as a flattened vector, scales the
205 elements divisively so that the maximum absolute value is the
206 specified norm_value.
207
208 The L-infinity norm is also known as the divisive infinity norm
209 and Chebyshev norm.
210 """
211 norm_value = Number(default=1.0)
212
214 tot = 1.0*max(abs(x.ravel()))
215 if tot != 0:
216 factor = (self.norm_value/tot)
217 x *= factor
218
219
220
222 """
223 OutputFn to divide an array by its Lp-Norm, where p is specified.
224
225 For a parameter p and a given array interpreted as a flattened
226 vector, keeps the Lp-norm of the vector at a specified norm_value.
227 Faster versions are provided separately for the typical L1-norm
228 and L2-norm cases. Defaults to be the same as an L2-norm, i.e.,
229 DivisiveNormalizeL2.
230 """
231 p = Number(default=2)
232 norm_value = Number(default=1.0)
233
235 tot = 1.0*norm(x.ravel(),self.p)
236 if tot != 0:
237 factor = (self.norm_value/tot)
238 x *=factor
239
240
241
243 """
244 Output function that applies a half-wave rectification (clips at zero)
245 and then squares the values.
246 """
247 lower_bound = Number(default=0.0,softbounds=(0.0,1.0))
248
252
253
254
256 """
257 Output function that applies a half-wave rectification (clips at zero)
258
259 """
260 lower_bound = Number(default=0.0,softbounds=(0.0,1.0))
261
264
265
266
268 """Output function that applies a squaring nonlinearity."""
269
272
273
274
276 """
277 Forces all values below a threshold to zero, and above it to 1.0.
278 """
279 threshold = Number(default=0.25, doc="Decision point for determining binary value.")
280
282 above_threshold = x>=self.threshold
283 x *= 0.0
284 x += above_threshold
285
286
287
288
289
290
292 """
293 Combine the supplied pattern with one generated using a
294 PatternGenerator.
295
296 Useful for operations like adding noise or masking out lesioned
297 items or around the edges of non-rectangular shapes.
298 """
299 generator = ClassSelectorParameter(PatternGenerator,
300 default=Constant(), doc="""
301 Pattern to combine with the supplied matrix.""")
302
303 operator = Parameter(numpy.multiply,precedence=0.98,doc="""
304 Binary Numeric function used to combine the two patterns.
305
306 Any binary Numeric array "ufunc" returning the same type of
307 array as the operands and supporting the reduce operator is
308 allowed here. See topo.patterns.basic.Composite.operator for
309 more details.
310 """)
311