Projection.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002 * Verve                                                                 *
00003 * Copyright (C) 2004-2006                                               *
00004 * Tyler Streeter  tylerstreeter@gmail.com                               *
00005 * All rights reserved.                                                  *
00006 * Web: http://verve-agents.sourceforge.net                              *
00007 *                                                                       *
00008 * This library is free software; you can redistribute it and/or         *
00009 * modify it under the terms of EITHER:                                  *
00010 *   (1) The GNU Lesser General Public License as published by the Free  *
00011 *       Software Foundation; either version 2.1 of the License, or (at  *
00012 *       your option) any later version. The text of the GNU Lesser      *
00013 *       General Public License is included with this library in the     *
00014 *       file license-LGPL.txt.                                          *
00015 *   (2) The BSD-style license that is included with this library in     *
00016 *       the file license-BSD.txt.                                       *
00017 *                                                                       *
00018 * This library is distributed in the hope that it will be useful,       *
00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
00021 * license-LGPL.txt and license-BSD.txt for more details.                *
00022 ************************************************************************/
00023 
00024 #include "Projection.h"
00025 #include "Population.h"
00026 #include "Neuron.h"
00027 #include "Connection.h"
00028 
00029 namespace verve
00030 {
00031         Projection::Projection()
00032         {
00033                 mInitialWeightMethod = IDEAL_NOISE;
00034 
00035         }
00036 
00037         Projection::~Projection()
00038         {
00039                 clear();
00040         }
00041 
00042         void Projection::init(Population* pop1, Population* pop2, 
00043                 InitialWeightMethod initWeightMethod, real maxInputPopActivationSum)
00044         {
00045                 mInitialWeightMethod = initWeightMethod;
00046                 mMaxInputPopActivationSum = maxInputPopActivationSum;
00047                 clear();
00048 
00049                 // Allocate room for the new Connections.  This should run a lot 
00050                 // faster than allocating them one at a time.
00051                 unsigned int numConnections = (unsigned int)pop1->getNumNeurons() 
00052                         * (unsigned int)pop2->getNumNeurons();
00053                 mConnections.reserve(numConnections);
00054 
00055                 unsigned int size = (unsigned int)pop1->getNumNeurons();
00056                 for (unsigned int i = 0; i < size; ++i)
00057                 {
00058                         createConnections(pop1->getNeuron(i), pop2);
00059                 }
00060 
00061                 setInitialConnectionWeights();
00062                 storeTargetNeuronReferences(pop2);
00063         }
00064 
00065         void Projection::init(Population* pop, Neuron* neuron, 
00066                 InitialWeightMethod initWeightMethod, real maxInputPopActivationSum)
00067         {
00068                 mInitialWeightMethod = initWeightMethod;
00069                 mMaxInputPopActivationSum = maxInputPopActivationSum;
00070                 clear();
00071 
00072                 // Allocate room for the new Connections.  This should run a lot 
00073                 // faster than allocating them one at a time.
00074                 mConnections.reserve(pop->getNumNeurons());
00075 
00076                 unsigned int size = (unsigned int)pop->getNumNeurons();
00077                 for (unsigned int i = 0; i < size; ++i)
00078                 {
00079                         connectNeurons(pop->getNeuron(i), neuron);
00080                 }
00081 
00082                 setInitialConnectionWeights();
00083                 storeTargetNeuronReferences(neuron);
00084         }
00085 
00086         void Projection::init(Neuron* neuron, Population* pop, 
00087                 InitialWeightMethod initWeightMethod, real maxInputPopActivationSum)
00088         {
00089                 mInitialWeightMethod = initWeightMethod;
00090                 mMaxInputPopActivationSum = maxInputPopActivationSum;
00091                 clear();
00092 
00093                 // Allocate room for the new Connections.  This should run a lot 
00094                 // faster than allocating them one at a time.
00095                 mConnections.reserve(pop->getNumNeurons());
00096 
00097                 createConnections(neuron, pop);
00098 
00099                 setInitialConnectionWeights();
00100                 storeTargetNeuronReferences(pop);
00101         }
00102 
00103         void Projection::clear()
00104         {
00105                 while (!mConnections.empty())
00106                 {
00107                         delete mConnections.back();
00108                         mConnections.pop_back();
00109                 }
00110 
00111                 // Do this to change the allocated size to zero.
00112                 mConnections.clear();
00113 
00114                 // Empty the list of Neuron pointers.  The actual Neurons will get 
00115                 // deleted elsewhere.
00116                 mTargetNeurons.clear();
00117         }
00118 
00119         void Projection::resetShortTermMemory()
00120         {
00121                 unsigned int size = (unsigned int)mConnections.size();
00122                 for (unsigned int i = 0; i < size; ++i)
00123                 {
00124                         mConnections[i]->resetShortTermMemory();
00125                 }
00126         }
00127 
00128         void Projection::addPreNeuron(Neuron* neuron)
00129         {
00130                 unsigned int numTargetNeurons = (unsigned int)mTargetNeurons.size();
00131 
00132                 // Allocate room for the new Connections.  This should run a lot 
00133                 // faster than allocating them one at a time.
00134                 mConnections.reserve(mConnections.size() + numTargetNeurons);
00135 
00136                 for (unsigned int i = 0; i < numTargetNeurons; ++i)
00137                 {
00138                         connectNeurons(neuron, mTargetNeurons[i]);
00139                         setInitialConnectionWeight(mConnections.back());
00140                 }
00141         }
00142 
00143         unsigned int Projection::getNumConnections()const
00144         {
00145                 return (unsigned int)mConnections.size();
00146         }
00147 
00148         Connection* Projection::getConnection(unsigned int i)
00149         {
00150                 return mConnections.at(i);
00151         }
00152 
00153         //void Projection::applyUniformNoise(real min, real max)
00154         //{
00155         //      unsigned int size = (unsigned int)mConnections.size();
00156         //      for (unsigned int i = 0; i < size; ++i)
00157         //      {
00158         //              mConnections[i]->addToWeight(globals::randomRealUniform(min, 
00159         //                      max));
00160         //      }
00161         //}
00162 
00163         //void Projection::applyGaussianNoise(real variance)
00164         //{
00165         //      unsigned int size = (unsigned int)mConnections.size();
00166         //      for (unsigned int i = 0; i < size; ++i)
00167         //      {
00168         //              mConnections[i]->addToWeight(globals::randomRealGauss(variance));
00169         //      }
00170         //}
00171 
00172         //void Projection::applyIdealInitialNoise()
00173         //{
00174         //      unsigned int size = (unsigned int)mConnections.size();
00175         //      for (unsigned int i = 0; i < size; ++i)
00176         //      {
00177         //              mConnections[i]->applyIdealInitialNoise();
00178         //      }
00179         //}
00180 
00181         void Projection::setInitialConnectionWeights()
00182         {
00183                 unsigned int size = (unsigned int)mConnections.size();
00184                 for (unsigned int i = 0; i < size; ++i)
00185                 {
00186                         setInitialConnectionWeight(mConnections[i]);
00187                 }
00188         }
00189 
00190         void Projection::setInitialConnectionWeight(Connection* c)
00191         {
00192                 switch(mInitialWeightMethod)
00193                 {
00194                         case IDEAL_NOISE:
00195                         {
00196                                 // Apply noise with variance inversely proportional to 
00197                                 // the Connection's postsynaptic Neuron's maximum amount 
00198                                 // of presynaptic input.  (This is similar to the method 
00199                                 // that applies Gaussian noise to the weight with variance 
00200                                 // equal to the inverse of the number of dendrites 
00201                                 // connected to the postsynaptic Neuron; but this method 
00202                                 // assumes that all presynaptic input activations could 
00203                                 // be 1 at the same time.)
00204                                 real variance = 1 / mMaxInputPopActivationSum;
00205                                 c->setWeight(globals::randomRealGauss(variance));
00206                                 break;
00207                         }
00208                         case WEIGHTS_NEAR_0:
00209                         {
00210                                 // Use variance proportional to the inverse of the max 
00211                                 // input activation, but make it a very small amount.  We 
00212                                 // want a little random noise, but not much.
00213                                 real variance = (real)0.001 / mMaxInputPopActivationSum;
00214                                 c->setWeight(globals::randomRealGauss(variance));
00215                                 break;
00216                         }
00217                         case WEIGHTS_NEAR_1:
00218                         {
00219                                 // Use variance proportional to the inverse of the max 
00220                                 // input activation, but make it a very small amount.  We 
00221                                 // want a little random noise, but not much.
00222                                 real variance = (real)0.001 / mMaxInputPopActivationSum;
00223                                 c->setWeight(globals::randomRealGauss(1 + variance));
00224                                 break;
00225                         }
00226                         default:
00227                                 assert(false);
00228                                 break;
00229                 }
00230         }
00231 
00232         void Projection::createConnections(Neuron* neuron, Population* pop)
00233         {
00234                 unsigned int size = (unsigned int)pop->getNumNeurons();
00235                 for (unsigned int i = 0; i < size; ++i)
00236                 {
00237                         connectNeurons(neuron, pop->getNeuron(i));
00238                 }
00239         }
00240 
00241         void Projection::storeTargetNeuronReferences(Population* pop)
00242         {
00243                 unsigned int size = pop->getNumNeurons();
00244                 for (unsigned int i = 0; i < size; ++i)
00245                 {
00246                         storeTargetNeuronReferences(pop->getNeuron(i));
00247                 }
00248         }
00249 
00250         void Projection::storeTargetNeuronReferences(Neuron* neuron)
00251         {
00252                 mTargetNeurons.push_back(neuron);
00253         }
00254 
00255         void Projection::connectNeurons(Neuron* neuron1, Neuron* neuron2)
00256         {
00257                 Connection* c = new Connection(neuron1, neuron2);
00258 
00259                 // Tell the pre-synaptic Neuron that this connection is one of its 
00260                 // axons.
00261                 neuron1->addAxon(c);
00262 
00263                 // Tell the post-synaptic Neuron that this connection is one of its 
00264                 // dendrites.
00265                 neuron2->addDendrite(c);
00266 
00267                 mConnections.push_back(c);
00268         }
00269 }

Generated on Tue Jan 24 21:46:37 2006 for Verve by  doxygen 1.4.6-NO