Neuron.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 "Neuron.h"
00025 #include "Connection.h"
00026 
00027 namespace verve
00028 {
00029         Neuron::Neuron(unsigned int id)
00030         {
00031                 mID = id;
00032                 mFiringRate = 0;
00033                 mSynapticInputSum = 0;
00034         }
00035 
00036         Neuron::~Neuron()
00037         {
00038         }
00039 
00040         void Neuron::resetShortTermMemory()
00041         {
00042                 mFiringRate = 0;
00043                 mSynapticInputSum = 0;
00044         }
00045 
00046         void Neuron::normalizeInputWeights()
00047         {
00048                 unsigned int numDendrites = (unsigned int)mDendrites.size();
00049                 if (numDendrites < 2)
00050                 {
00051                         return;
00052                 }
00053 
00056 
00058                 //real maxMagnitude = 0;
00059 
00060                 //std::vector<Connection*>::iterator iter;
00061                 //for (iter = mDendrites.begin(); iter != mDendrites.end(); ++iter)
00062                 //{
00063                 //      if (globals::abs((*iter)->getWeight()) > maxMagnitude)
00064                 //      {
00065                 //              maxMagnitude = globals::abs((*iter)->getWeight());
00066                 //      }
00067                 //}
00068 
00075                 //if (maxMagnitude > 1)
00076                 //{
00077                 //      real inverseMagnitude = 1 / maxMagnitude;
00078 
00079                 //      for (iter = mDendrites.begin(); iter != mDendrites.end(); ++iter)
00080                 //      {
00081                 //              real weight = (*iter)->getWeight();
00082                 //              //real newWeightMagnitude = globals::scaleZeroToOne(
00083                 //              //      globals::abs(weight), 0, maxMagnitude);
00084                 //              real newWeightMagnitude = globals::abs(weight) * 
00085                 //                      inverseMagnitude;
00086 
00087                 //              if (weight < 0)
00088                 //              {
00089                 //                      (*iter)->setWeight(-newWeightMagnitude);
00090                 //              }
00091                 //              else
00092                 //              {
00093                 //                      (*iter)->setWeight(newWeightMagnitude);
00094                 //              }
00095                 //      }
00096                 //}
00097 
00098                 // METHOD 2: Scale weights to keep the sum of squared weights equal 
00099                 // to 1 (i.e. a unit circle).
00100 
00101                 // Find the sum of squared weights.
00102                 real sumOfSquaredWeights = 0;
00103 
00104                 for (unsigned int i = 0; i < numDendrites; ++i)
00105                 {
00106                         real weight = mDendrites[i]->getWeight();
00107                         sumOfSquaredWeights += (weight * weight);
00108                 }
00109 
00110                 // Don't do anything if the sum is zero (in which case the weights 
00111                 // are still all zero).
00112                 if (sumOfSquaredWeights > 0)
00113                 {
00114                         // Precompute the inverse of the square root of the sum.
00115                         real invRootSum = 1 / globals::sqrt(sumOfSquaredWeights);
00116 
00117                         // Scale the weights.  After this loop the sum of squared 
00118                         // weights should be 1.
00119                         for (unsigned int i = 0; i < numDendrites; ++i)
00120                         {
00121                                 mDendrites[i]->setWeight(mDendrites[i]->getWeight() * 
00122                                         invRootSum);
00123                         }
00124                 }
00125         }
00126 
00127         void Neuron::setFiringRate(real value)
00128         {
00129                 // If nothing has changed, quit early to save time.
00130                 if (value == mFiringRate)
00131                 {
00132                         return;
00133                 }
00134 
00135                 real deltaFiringRate = value - mFiringRate;
00136                 mFiringRate = value;
00137 
00138                 // Update post-synaptic Neurons' synaptic input sums.
00139                 unsigned int size = (unsigned int)mAxons.size();
00140                 for (unsigned int i = 0; i < size; ++i)
00141                 {
00142                         mAxons[i]->getPostNeuron()->addToSynapticInputSum(
00143                                 deltaFiringRate * mAxons[i]->getWeight());
00144                 }
00145         }
00146 
00147         void Neuron::addToSynapticInputSum(real delta)
00148         {
00149                 mSynapticInputSum += delta;
00150         }
00151 
00152         void Neuron::updateFiringRateLinear()
00153         {
00154                 // IDEA: it might speed things up to keep track of whether the 
00155                 // input sum has changed, then only update things if it has.  
00156                 // The Neuron::setFiringRate should at least avoid updating 
00157                 // post-synaptic input sums when the firing rate hasn't changed.
00158 
00159                 // Just use the linear function firing rate = input sum.
00160                 setFiringRate(mSynapticInputSum);
00161         }
00162 
00163         void Neuron::updateFiringRateLinearBoundedNegOneToOne()
00164         {
00165                 // IDEA: it might speed things up to keep track of whether the 
00166                 // input sum has changed, then only update things if it has.  
00167                 // The Neuron::setFiringRate should at least avoid updating 
00168                 // post-synaptic input sums when the firing rate hasn't changed.
00169 
00170                 // Just use the linear function firing rate = input sum.
00171                 if (mSynapticInputSum < -1)
00172                 {
00173                         setFiringRate(-1);
00174                 }
00175                 else if (mSynapticInputSum > 1)
00176                 {
00177                         setFiringRate(1);
00178                 }
00179                 else
00180                 {
00181                         setFiringRate(mSynapticInputSum);
00182                 }
00183         }
00184 
00185         void Neuron::updateFiringRateLinearBoundedZeroToOne()
00186         {
00187                 // IDEA: it might speed things up to keep track of whether the 
00188                 // input sum has changed, then only update things if it has.  
00189                 // The Neuron::setFiringRate should at least avoid updating 
00190                 // post-synaptic input sums when the firing rate hasn't changed.
00191 
00192                 // Just use the linear function firing rate = input sum.
00193                 if (mSynapticInputSum < 0)
00194                 {
00195                         setFiringRate(0);
00196                 }
00197                 else if (mSynapticInputSum > 1)
00198                 {
00199                         setFiringRate(1);
00200                 }
00201                 else
00202                 {
00203                         setFiringRate(mSynapticInputSum);
00204                 }
00205         }
00206 
00207         void Neuron::updateFiringRateSigmoid()
00208         {
00209                 // IDEA: it might speed things up to keep track of whether the 
00210                 // input sum has changed, then only update things if it has.  
00211                 // The Neuron::setFiringRate should at least avoid updating 
00212                 // post-synaptic input sums when the firing rate hasn't changed.
00213 
00214                 // Sigmoid function.  Avoid overflow.
00215                 if (mSynapticInputSum < -500)
00216                 {
00217                         setFiringRate(0);
00218                 }
00219                 else if (mSynapticInputSum > 500)
00220                 {
00221                         setFiringRate(1);
00222                 }
00223                 else
00224                 {
00225                         setFiringRate(1 / (1 + globals::exp(-mSynapticInputSum)));
00226                 }
00227         }
00228 
00229         real Neuron::getFiringRate()const
00230         {
00231                 return mFiringRate;
00232         }
00233 
00234         void Neuron::addDendrite(Connection* c)
00235         {
00236                 mDendrites.push_back(c);
00237         }
00238 
00239         unsigned int Neuron::getNumDendrites()const
00240         {
00241                 return (unsigned int)mDendrites.size();
00242         }
00243 
00244         Connection* Neuron::getDendrite(unsigned int i)
00245         {
00246                 return mDendrites.at(i);
00247         }
00248 
00249         void Neuron::addAxon(Connection* c)
00250         {
00251                 mAxons.push_back(c);
00252         }
00253 
00254         unsigned int Neuron::getNumAxons()const
00255         {
00256                 return (unsigned int)mAxons.size();
00257         }
00258 
00259         Connection* Neuron::getAxon(unsigned int i)
00260         {
00261                 return mAxons.at(i);
00262         }
00263 
00264         int Neuron::getID()const
00265         {
00266                 return mID;
00267         }
00268 }

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