```
"""
Basic function objects.
TransferFns: accept and modify a 2d array
ResponseFns: accept two 2d arrays and return a scalar
LearningFns: accept two 2d arrays and a scalar, return one of the arrays modified
"""
# CEBALERT: Documentation is just draft.
import numpy
import param
from imagen.transferfn import TransferFn, IdentityTF # pyflakes:ignore (API import)
[docs]class LearningFn(param.Parameterized):
"""
Abstract base class for learning functions that plug into
CFPLF_Plugin.
"""
__abstract = True
# JABALERT: Shouldn't the single_connection_learning_rate be
# omitted from the call and instead made into a class parameter?
def __call__(self,input_activity, unit_activity, weights, single_connection_learning_rate):
"""
Apply this learning function given the input and output
activities and current weights.
Must be implemented by subclasses.
"""
raise NotImplementedError
[docs]class Hebbian(LearningFn):
"""
Basic Hebbian rule; Dayan and Abbott, 2001, equation 8.3.
Increases each weight in proportion to the product of this
neuron's activity and the input activity.
Requires some form of output_fn normalization for stability.
"""
def __call__(self,input_activity, unit_activity, weights, single_connection_learning_rate):
weights += single_connection_learning_rate * unit_activity * input_activity
[docs]class IdentityLF(LearningFn):
"""
Identity function; does not modify the weights.
For speed, calling this function object is sometimes optimized
away entirely. To make this feasible, it is not allowable to
derive other classes from this object, modify it to have different
behavior, add side effects, or anything of that nature.
"""
def __call__(self,input_activity, unit_activity, weights, single_connection_learning_rate):
pass
[docs]class ResponseFn(param.Parameterized):
"""Abstract base class for response functions that plug into CFPRF_Plugin."""
__abstract = True
def __call__(self,m1,m2):
"""
Apply the response function; must be implemented by subclasses.
"""
raise NotImplementedError
[docs]class DotProduct(ResponseFn):
"""
Return the sum of the element-by-element product of two 2D
arrays.
"""
def __call__(self,m1,m2):
# CBENHANCEMENT: numpy.vdot(m1,m2)?
# Early tests indicated that
# vdot(a,b)=dot(a.ravel(),b.ravel()) but was slower. Should
# check that.
return numpy.dot(m1.ravel(),m2.ravel())
[docs]class CoordinateMapperFn(param.Parameterized):
"""Abstract base class for functions mapping from a 2D coordinate into another one."""
__abstract = True
def __call__(self,x,y):
"""
Apply the coordinate mapping function; must be implemented by subclasses.
"""
raise NotImplementedError
[docs]class IdentityMF(CoordinateMapperFn):
"""Return the x coordinate of the given coordinate."""
def __call__(self,x,y):
return x,y
```