<commit_before>"""
Projection classes.

A Projection is a connection between two Sheets, generally implemented
as a large set of ConnectionFields.

Any new Projection classes added to this directory will automatically
become available for any model.
"""

from copy import copy

import numpy as np

import param

# So all Projections are present in this package
from topo.base.projection import Projection
from topo.base.boundingregion import BoundingBox
from topo.base.sheet import activity_type
from topo.base.sheetcoords import Slice
from topo.base.cf import CFProjection,ConnectionField,\
     CFPLearningFn,CFPLF_Identity,CFPOutputFn,CFIter,ResizableCFProjection
from topo.base.patterngenerator import PatternGenerator,Constant
from topo.base.functionfamily import CoordinateMapperFn,IdentityMF
from topo.misc.util import rowcol2idx
from topo.transferfn import TransferFn,IdentityTF
from topo.learningfn import LearningFn,IdentityLF
from topo.base import patterngenerator

class CFPOF_SharedWeight(CFPOutputFn):
    """
    CFPOutputFn for use with SharedWeightCFProjections.

    Applies the single_cf_fn to the single shared CF's weights.
    """
    single_cf_fn = param.ClassSelector(TransferFn,default=IdentityTF())

    # CEBALERT: remove norm_values?
    def __call__(self, cfs, norm_values=None, **params):
        """Apply the specified single_cf_fn to every CF."""
        if type(self.single_cf_fn) is not IdentityTF:
            cf = cfs[0,0]
            self.single_cf_fn(cf.weights)

from topo.base.cf import _create_mask

class SharedWeightCF(ConnectionField):

    __slots__ = []

    def __init__(self,cf,input_sheet,x=0.0,y=0.0,template=BoundingBox(radius=0.1),
                 mask=patterngenerator.Constant(),
                 min_matrix_radius=1):
        """
        From an existing copy of ConnectionField (CF) that acts as a
        template, create a new CF that shares weights with the
        template CF.  Copies all the properties of CF to stay
        identical except the weights variable that actually contains
        the data.

        The only difference from a normal CF is that the weights of
        the CF are implemented as a numpy view into the single master
        copy of the weights stored in the CF template.
        """
        # CEBALERT: There's no call to super's __init__; see JAHACKALERT
        # below.
        template = copy(template)

        if not isinstance(template,Slice):
            template = Slice(template,input_sheet,force_odd=True,
                             min_matrix_radius=min_matrix_radius)

        # Note: if passed in, mask is shared between CFs (but not if created here)
        if not hasattr(mask,'view'):
            mask = _create_mask(patterngenerator.Constant(),
                               template.compute_bounds(input_sheet),
                               input_sheet,True,0.5)



        self._has_norm_total=np.array([0],dtype=np.int32)

        self.mask=mask
        weights_slice = self._create_input_sheet_slice(input_sheet,x,y,template,min_matrix_radius=min_matrix_radius)
        self.weights = weights_slice.submatrix(cf.weights)

        # JAHACKALERT the TransferFn cannot be applied in SharedWeightCF
        # - another inconsistency in the class tree design - there
        # should be nothing in the parent class that is ignored in its
        # children.  Probably need to extract some functionality of
        # ConnectionField into a shared abstract parent class.
        # We have agreed to make this right by adding a constant property that
        # will be set true if the learning should be active
        # The SharedWeightCFProjection class and its anccestors will
        # have this property set to false which means that the
        # learning will be deactivated

<commit_msg>Added missing _norm_total attribute in SharedWeightCF<commit_after>"""
Projection classes.

A Projection is a connection between two Sheets, generally implemented
as a large set of ConnectionFields.

Any new Projection classes added to this directory will automatically
become available for any model.
"""

from copy import copy

import numpy as np

import param

# So all Projections are present in this package
from topo.base.projection import Projection
from topo.base.boundingregion import BoundingBox
from topo.base.sheet import activity_type
from topo.base.sheetcoords import Slice
from topo.base.cf import CFProjection,ConnectionField,\
     CFPLearningFn,CFPLF_Identity,CFPOutputFn,CFIter,ResizableCFProjection
from topo.base.patterngenerator import PatternGenerator,Constant
from topo.base.functionfamily import CoordinateMapperFn,IdentityMF
from topo.misc.util import rowcol2idx
from topo.transferfn import TransferFn,IdentityTF
from topo.learningfn import LearningFn,IdentityLF
from topo.base import patterngenerator

class CFPOF_SharedWeight(CFPOutputFn):
    """
    CFPOutputFn for use with SharedWeightCFProjections.

    Applies the single_cf_fn to the single shared CF's weights.
    """
    single_cf_fn = param.ClassSelector(TransferFn,default=IdentityTF())

    # CEBALERT: remove norm_values?
    def __call__(self, cfs, norm_values=None, **params):
        """Apply the specified single_cf_fn to every CF."""
        if type(self.single_cf_fn) is not IdentityTF:
            cf = cfs[0,0]
            self.single_cf_fn(cf.weights)

from topo.base.cf import _create_mask

class SharedWeightCF(ConnectionField):

    __slots__ = []

    def __init__(self,cf,input_sheet,x=0.0,y=0.0,template=BoundingBox(radius=0.1),
                 mask=patterngenerator.Constant(),
                 min_matrix_radius=1):
        """
        From an existing copy of ConnectionField (CF) that acts as a
        template, create a new CF that shares weights with the
        template CF.  Copies all the properties of CF to stay
        identical except the weights variable that actually contains
        the data.

        The only difference from a normal CF is that the weights of
        the CF are implemented as a numpy view into the single master
        copy of the weights stored in the CF template.
        """
        # CEBALERT: There's no call to super's __init__; see JAHACKALERT
        # below.
        template = copy(template)

        if not isinstance(template,Slice):
            template = Slice(template,input_sheet,force_odd=True,
                             min_matrix_radius=min_matrix_radius)

        # Note: if passed in, mask is shared between CFs (but not if created here)
        if not hasattr(mask,'view'):
            mask = _create_mask(patterngenerator.Constant(),
                               template.compute_bounds(input_sheet),
                               input_sheet,True,0.5)



        self._has_norm_total=np.array([0],dtype=np.int32)
        self._norm_total=np.array([0.0],dtype=np.float64)

        self.mask=mask
        weights_slice = self._create_input_sheet_slice(input_sheet,x,y,template,min_matrix_radius=min_matrix_radius)
        self.weights = weights_slice.submatrix(cf.weights)

        # JAHACKALERT the TransferFn cannot be applied in SharedWeightCF
        # - another inconsistency in the class tree design - there
        # should be nothing in the parent class that is ignored in its
        # children.  Probably need to extract some functionality of
        # ConnectionField into a shared abstract parent class.
        # We have agreed to make this right by adding a constant property that
        # will be set true if the learning should be active
        # The SharedWeightCFProjection class and its anccestors will
        # have this property set to false which means that the
        # learning will be deactivated


{'fraction_non_alphanumeric': 0.06034259018946276, 'fraction_numerical': 0.004412146379444588, 'mean_word_length': 3.0799364743250397, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6116823', 'n_tokens_mistral': 2118, 'n_tokens_neox': 2037, 'n_words': 718}