/* ============================================================================== Layer.hpp Created: 21 Sep 2014 1:55:15pm Author: jens ============================================================================== */ #ifndef LAYER_HPP #define LAYER_HPP #include #include "noise.h" #include "Weights.hpp" class Layer { public: Layer(uint32_t numUnits = 0, const double *pStatesInit = nullptr) : m_numUnits(numUnits) , m_pProbs(nullptr) , m_pStates(nullptr) { setNumUnits(numUnits, pStatesInit); Noise_Init(&m_noise, 0x12345677); } virtual ~Layer() { setNumUnits(0); Noise_Free(&m_noise); } void setNumUnits(uint32_t numUnits, const double *pStatesInit = nullptr) { if (m_numUnits) { delete [] m_pProbs; delete [] m_pStates; } m_numUnits = numUnits; if (m_numUnits) { m_pProbs = new double[m_numUnits]; m_pStates = new double[m_numUnits]; probsInit(0); if (pStatesInit) { memcpy(m_pStates, pStatesInit, m_numUnits*sizeof(double)); } else { statesInit(0); } } } Layer& operator= (const Layer &rhs) { memcpy(m_pProbs, rhs.m_pProbs, m_numUnits*sizeof(double)); memcpy(m_pStates, rhs.m_pStates, m_numUnits*sizeof(double)); return *this; } Layer& operator+= (const Layer &rhs) { uint32_t i; for (i=0; i < m_numUnits; i++) { m_pStates[i] += rhs.m_pStates[i]; } return *this; } void probsInit(double value) const { uint32_t i; for (i=0; i < m_numUnits; i++) { m_pProbs[i] = value; } } void statesInit(double value) const { uint32_t i; for (i=0; i < m_numUnits; i++) { m_pStates[i] = value; } } void probsUpdate(const Layer &layer, const Weights &weights) const { uint32_t i; for (i=0; i < m_numUnits; i++) { m_pProbs[i] = logSigmoid(accum(layer, weights, i)); } } void statesScale(double kscale) const { uint32_t i; for (i=0; i < m_numUnits; i++) { m_pStates[i] *= kscale; } } void statesAssignfromProbs() { memcpy(m_pStates, m_pProbs, m_numUnits*sizeof(double)); } void statesUpdateStochastic() { uint32_t i; double sample; for (i=0; i < m_numUnits; i++) { sample = Noise_Uniform(&m_noise, 0.5); m_pStates[i] = (double)(sample <= m_pProbs[i]); } } const double *getProbs() const { return m_pProbs; } const double *getStates() const { return m_pStates; } uint32_t getNumUnits() const { return m_numUnits; } virtual double getEnergy(const Weights &weights) = 0; private: uint32_t m_numUnits; noise_gen_t m_noise; inline double logSigmoid(double x) const { return 1./(1 + exp(-x)); } protected: double *m_pProbs; double *m_pStates; virtual double accum(const Layer &layer, const Weights &weights, uint32_t index) const = 0; }; #endif // LAYER_HPP