<commit_before>/* 
 *
 */

#include "IPyraNet2DLayer.h"
#include <assert.h>

template<class OutType>
IPyraNet2DLayer<OutType>::IPyraNet2DLayer() 
    : IPyraNetLayer<OutType>(),
    width(0),
    height(0),
    receptiveSize(0),
    overlap(0),
    inhibitorySize(0)
{

}

template<class OutType>
IPyraNet2DLayer<OutType>::IPyraNet2DLayer(int receptive, int inhibitory, int overlap, IPyraNetActivationFunction<OutType>* activationFunc) 
    : IPyraNetLayer<OutType>(),
    width(0),
    height(0),
    receptiveSize(receptive),
    overlap(overlap),
    inhibitorySize(inhibitory)
{
    setActivationFunction(activationFunc);
}

template<class OutType>
IPyraNet2DLayer<OutType>::~IPyraNet2DLayer() {

}

template<class OutType>
OutType IPyraNet2DLayer<OutType>::getWeightedSumInput(int dimensions, int* neuronLocation) {
    
    // sanity checks
    assert (dimensions == 2);
    assert (neuronLocation != NULL);
    assert (neuronLocation[0] >= 0 && neuronLocation[1] >= 0);
    assert (getParentLayer() != NULL);
    assert (getActivationFunction() != NULL);

    // parent layer pointer
    IPyraNetLayer<OutType>* parent = getParentLayer();

    // compute the gap
    const int gap = receptiveSize - overlap;

    // just for compliance with the article (which uses 1..n indices)
    const int u = neuronLocation[0] + 1;
    const int v = neuronLocation[1] + 1;

    OutType receptiveAccumulator = 0;
    OutType bias = biases[neuronLocation[0]][neuronLocation[1]];

    int parentLoc[2];

    int parentSize[2];
    parent->getSize(parentSize);

    // iterate through the neurons inside the receptive field of the previous layer
    //
    // ******
    // **uv**
    // ******
    //
    const int min_u = (u - 1) * gap + 1;
    const int max_u = (u - 1) * gap + receptiveSize;
    const int min_v = (v - 1) * gap + 1;
    const int max_v = (v - 1) * gap + receptiveSize;

    for (int i = min_u; i <= max_u; ++i) {

        // indices on the paper (2) go from 1 to n. Our indices go from 0 to n-1
        parentLoc[0] = i - 1;
        
        // ignore neuron indices which fall outside of the layer
        if (parentLoc[0] < 0)
            continue;

        if (parentLoc[0] > parentSize[0])
            continue;
        
        for (int j = min_v; j <= max_v; ++j) {
            
            parentLoc[1] = j - 1;

            // ignore neuron indices which fall outside of the layer
            if (parentLoc[1] < 0)
                continue;

            if (parentLoc[1] > parentSize[1])
                continue;
            
            OutType parentOutput = parent->getNeuronOutput(2, parentLoc);
            OutType weight = weights[parentLoc[0]][parentLoc[1]];

            receptiveAccumulator += parentOutput * weight;
        }
    }

    // iterate through the neurons inside the inhibitory field
    // 
    // xxxxxxxx
    // x******x
    // x**uv**x
    // x******x
    // xxxxxxxx
    //
    // the inhibitory field is 'x' and the receptive field is '*'
    OutType inhibitoryAccumulator = 0;
    const int inhibitory_min_u = min_u - inhibitorySize;
    const int inhibitory_max_u = max_u + inhibitorySize;
    const int inhibitory_min_v = min_v - inhibitorySize;
    const int inhibitory_max_v = max_v + inhibitorySize;
    
    for (int i = inhibitory_min_u; i <= inhibitory_max_u; ++i) {
        
        // indices on the paper (2) go from 1 to n. Our indices go from 0 to n-1
        parentLoc[0] = i - 1;
        
        // ignore neuron indices which fall outside of the layer
        if (parentLoc[0] < 0)
            continue;

        if (parentLoc[0] > parentSize[0])
            continue;

        for (int j = inhibitory_min_v; j <= inhibitory_max_v; ++j) {

            parentLoc[1] = j - 1;

            // ignore neuron indices which fall outside of the layer
            if (parentLoc[1] < 0)
                continue;

            if (parentLoc[1] > parentSize[1])
                continue;

            // ignore neurons in the receptive field!
            if (i >= min_u && i <= max_u)
                continue;

            if (j >= min_v && j <= max_v)
                continue;

            OutType parentOutput = parent->getNeuronOutput(2, parentLoc);
            OutType weight = weights[parentLoc[0]][parentLoc[1]];

            inhibitoryAccumulator += parentOutput * weight;
        }
    }

    return receptiveAccumulator - inhibitoryAccumulator + bias;
}

template<class OutType>
void IPyraNet2DLayer<OutType>::initWeights() {

    assert(getParentLayer() != NULL);

    IPyraNetLayer<OutType>* parent = getParentLayer();
    
    // get parent size
    int parentSize[2];
    parent->getSize(parentSize);<commit_msg>Fixed a bug which made the training crash when using inhibitory field sizes greater than 1.<commit_after>/* 
 *
 */

#include "IPyraNet2DLayer.h"
#include <assert.h>

template<class OutType>
IPyraNet2DLayer<OutType>::IPyraNet2DLayer() 
    : IPyraNetLayer<OutType>(),
    width(0),
    height(0),
    receptiveSize(0),
    overlap(0),
    inhibitorySize(0)
{

}

template<class OutType>
IPyraNet2DLayer<OutType>::IPyraNet2DLayer(int receptive, int inhibitory, int overlap, IPyraNetActivationFunction<OutType>* activationFunc) 
    : IPyraNetLayer<OutType>(),
    width(0),
    height(0),
    receptiveSize(receptive),
    overlap(overlap),
    inhibitorySize(inhibitory)
{
    setActivationFunction(activationFunc);
}

template<class OutType>
IPyraNet2DLayer<OutType>::~IPyraNet2DLayer() {

}

template<class OutType>
OutType IPyraNet2DLayer<OutType>::getWeightedSumInput(int dimensions, int* neuronLocation) {
    
    // sanity checks
    assert (dimensions == 2);
    assert (neuronLocation != NULL);
    assert (neuronLocation[0] >= 0 && neuronLocation[1] >= 0);
    assert (getParentLayer() != NULL);
    assert (getActivationFunction() != NULL);

    // parent layer pointer
    IPyraNetLayer<OutType>* parent = getParentLayer();

    // compute the gap
    const int gap = receptiveSize - overlap;

    // just for compliance with the article (which uses 1..n indices)
    const int u = neuronLocation[0] + 1;
    const int v = neuronLocation[1] + 1;

    OutType receptiveAccumulator = 0;
    OutType bias = biases[neuronLocation[0]][neuronLocation[1]];

    int parentLoc[2];

    int parentSize[2];
    parent->getSize(parentSize);

    // iterate through the neurons inside the receptive field of the previous layer
    //
    // ******
    // **uv**
    // ******
    //
    const int min_u = (u - 1) * gap + 1;
    const int max_u = (u - 1) * gap + receptiveSize;
    const int min_v = (v - 1) * gap + 1;
    const int max_v = (v - 1) * gap + receptiveSize;

    for (int i = min_u; i <= max_u; ++i) {

        // indices on the paper (2) go from 1 to n. Our indices go from 0 to n-1
        parentLoc[0] = i - 1;
        
        // ignore neuron indices which fall outside of the layer
        if (parentLoc[0] < 0)
            continue;

        if (parentLoc[0] >= parentSize[0])
            continue;
        
        for (int j = min_v; j <= max_v; ++j) {
            
            parentLoc[1] = j - 1;

            // ignore neuron indices which fall outside of the layer
            if (parentLoc[1] < 0)
                continue;

            if (parentLoc[1] >= parentSize[1])
                continue;
            
            OutType parentOutput = parent->getNeuronOutput(2, parentLoc);
            OutType weight = weights[parentLoc[0]][parentLoc[1]];

            receptiveAccumulator += parentOutput * weight;
        }
    }

    // iterate through the neurons inside the inhibitory field
    // 
    // xxxxxxxx
    // x******x
    // x**uv**x
    // x******x
    // xxxxxxxx
    //
    // the inhibitory field is 'x' and the receptive field is '*'
    OutType inhibitoryAccumulator = 0;
    const int inhibitory_min_u = min_u - inhibitorySize;
    const int inhibitory_max_u = max_u + inhibitorySize;
    const int inhibitory_min_v = min_v - inhibitorySize;
    const int inhibitory_max_v = max_v + inhibitorySize;
    
    for (int i = inhibitory_min_u; i <= inhibitory_max_u; ++i) {
        
        // indices on the paper (2) go from 1 to n. Our indices go from 0 to n-1
        parentLoc[0] = i - 1;
        
        // ignore neuron indices which fall outside of the layer
        if (parentLoc[0] < 0)
            continue;

        if (parentLoc[0] >= parentSize[0])
            continue;

        for (int j = inhibitory_min_v; j <= inhibitory_max_v; ++j) {

            parentLoc[1] = j - 1;

            // ignore neuron indices which fall outside of the layer
            if (parentLoc[1] < 0)
                continue;

            if (parentLoc[1] >= parentSize[1])
                continue;

            // ignore neurons in the receptive field!
            if (i >= min_u && i <= max_u)
                continue;

            if (j >= min_v && j <= max_v)
                continue;

            OutType parentOutput = parent->getNeuronOutput(2, parentLoc);
            OutType weight = weights[parentLoc[0]][parentLoc[1]];

            inhibitoryAccumulator += parentOutput * weight;
        }
    }

    return receptiveAccumulator - inhibitoryAccumulator + bias;
}

template<class OutType>
void IPyraNet2DLayer<OutType>::initWeights() {

    assert(getParentLayer() != NULL);

    IPyraNetLayer<OutType>* parent = getParentLayer();
    
    // get parent size
    int parentSize[2];
    parent->getSize(parentSize);
{'fraction_non_alphanumeric': 0.11653259949195596, 'fraction_numerical': 0.01640558848433531, 'mean_word_length': 2.25939979303208, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 59, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, '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': '7430521', 'n_tokens_mistral': 3122, 'n_tokens_neox': 2871, 'n_words': 796}