#include "inputCouche.h"

InputCouche::InputCouche() : Couche(){
    //cout << "    Create empty PrevChange Matrix [in InputCouche()]\n";
    prevChange = SynapseMatrix();
    //cout << "    Done\n";
}

InputCouche::InputCouche(const unsigned int nbr,const Couche* next) : Couche(nbr,next){
    //cout << "    Create PrevChange Matrix [in InputCouche(const unsigned int nbr,const Couche* next)]\n";
    if(next!=NULL)
        prevChange = SynapseMatrix(getNumber(),next->getNumber());
    else
        prevChange = SynapseMatrix();
    //cout << prevChange;
    //cout << "    Done\n";
}

void InputCouche::setNextCouche(const HiddenCouche* c) throw(std::string){
    Couche::setNextCouche(c);
    prevChange = SynapseMatrix(getNumber(),c->getNumber());
}

void InputCouche::activate(const std::vector<bool> &v) throw(std::string){
    unsigned int size = v.size();
    if(size != getNumber()-1){
        throw(std::string("Wrong number of Input passed to InputCouche"));
    }
    for(unsigned int i=0 ; i<size ; ++i){
        (*this)[i].setWeight((double)v[i]);
    }
}

void InputCouche::backPropagate(const std::vector<double> deltaHidden){
    unsigned int size = deltaHidden.size();
    double change;
    if(size != getNextCouche()->getNumber()) // prend les delta de la couche cachée!
        throw(std::string("Wrong number of delta passed to InputCouche for back propagation"));
    for(unsigned int i=0; i < getNumber() ; ++i)
        for(unsigned int j=0; j < getNextCouche()->getNumber(); ++j){
            change = (deltaHidden[j] * (*this)[i].getWeight());
            synSortantes(i,j) = (getSynapse(i,j).getWeight()) + (LEARNING_RATE*change) + (MOMENTUM*getChange(i,j));
            prevChange(i,j) = change;
        }
}

double InputCouche::getChange(const unsigned int neurThisCouche,const unsigned int neurNextCouche) const throw(const unsigned int,std::string){
    return prevChange(neurThisCouche,neurNextCouche).getWeight();
}
void InputCouche::printMatrix(){
    cout << prevChange;
}

InputCouche& InputCouche::operator=(const InputCouche& c){
    if(this!=&c){
        Couche::operator=(c);
        prevChange = c.prevChange;
    }
    return (*this);
};
