00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "cluster.h"
00021 #include "liboutputfunctions.h"
00022 #include "configurationhelper.h"
00023 #include <exception>
00024
00025 namespace farsa {
00026
00027 Cluster::Cluster( unsigned int numNeurons, QString name )
00028 : Updatable(name), inputdata(numNeurons,true), outputdata(numNeurons,true), stateDelegates() {
00029
00030 setDelegateFor<Cluster, &Cluster::inputs>( "inputs" );
00031 setDelegateFor<Cluster, &Cluster::outputs>( "outputs" );
00032 this->numneurons = numNeurons;
00033 inputdataptr = &inputdata;
00034 inputdata.zeroing();
00035 outputdataptr = &outputdata;
00036 outputdata.zeroing();
00037 accOff = true;
00038 setNeedReset( false );
00039
00040 setOutFunction(new SigmoidFunction( 1.0 ));
00041 }
00042
00043 Cluster::Cluster( ConfigurationParameters& params, QString prefix ) :
00044 Updatable(params, prefix), stateDelegates()
00045 {
00046
00047 setDelegateFor<Cluster, &Cluster::inputs>( "inputs" );
00048 setDelegateFor<Cluster, &Cluster::outputs>( "outputs" );
00049 numneurons = ConfigurationHelper::getInt( params, prefix + "numNeurons", 1 );
00050
00051 inputdata = DoubleVector(numneurons, true );
00052 inputdataptr = &inputdata;
00053 inputdata.zeroing();
00054 outputdata = DoubleVector(numneurons, true );
00055 outputdataptr = &outputdata;
00056 outputdata.zeroing();
00057
00058 accOff = !ConfigurationHelper::getBool( params, prefix + "accumulate" );
00059
00060 QString vectorSizeErrorTmpl( "The number of elements of the %1 vector in configuration file (%1) is different from the number of neurons (%2)");
00061
00062 QVector<double> vect = ConfigurationHelper::getVector( params, prefix + "inputs" );
00063 #ifdef FARSA_DEBUG
00064 if ( !vect.isEmpty() && vect.size() != (int)numneurons ) {
00065 qWarning() << vectorSizeErrorTmpl.arg( "inputs" ).arg( vect.size() ).arg( numneurons );
00066 }
00067 #endif
00068 inputdataptr->copyValues( vect );
00069
00070
00071 vect = ConfigurationHelper::getVector( params, prefix + "outputs" );
00072 #ifdef FARSA_DEBUG
00073 if ( !vect.isEmpty() && vect.size() != (int)numneurons ) {
00074 qWarning() << vectorSizeErrorTmpl.arg( "outputs" ).arg( vect.size() ).arg( numneurons );
00075 }
00076 #endif
00077 outputdataptr->copyValues( vect );
00078
00079
00080 try {
00081 setOutFunction(params.getObjectFromGroup<OutputFunction>( prefix + "OutFunction", true ));
00082 } catch( std::exception& ) {
00083
00084 setOutFunction(new SigmoidFunction( 1.0 ));
00085 }
00086 setNeedReset( false );
00087 }
00088
00089 Cluster::~Cluster() {
00090
00091 }
00092
00093 void Cluster::setOutFunction( OutputFunction *up ) {
00094 updater.reset(up);
00095 updater->setCluster( this );
00096 }
00097
00098 void Cluster::setInput( unsigned int neuron, double value ) {
00099 (*inputdataptr)[neuron] = value;
00100 }
00101
00102 void Cluster::setInputs( const DoubleVector& inputs ) {
00103 inputdataptr->copyValues( inputs );
00104 }
00105
00106 void Cluster::setAllInputs( double value ) {
00107 inputdataptr->setAll( value );
00108 setNeedReset( false );
00109 }
00110
00111 void Cluster::resetInputs() {
00112 inputdataptr->zeroing();
00113 setNeedReset( false );
00114 }
00115
00116 double Cluster::getInput( unsigned int neuron ) const {
00117 return (*inputdataptr)[neuron];
00118 }
00119
00120 void Cluster::setOutput( unsigned int neuron, double value ) {
00121 (*outputdataptr)[neuron] = value;
00122 }
00123
00124 void Cluster::setOutputs( const DoubleVector& outputs ) {
00125 outputdataptr->copyValues( outputs );
00126 }
00127
00128 double Cluster::getOutput( unsigned int neuron ) const {
00129 return (*outputdataptr)[neuron];
00130 }
00131
00132 void Cluster::save(ConfigurationParameters& params, QString prefix)
00133 {
00134 Updatable::save( params, prefix );
00135 params.startObjectParameters(prefix, "Cluster", this);
00136 params.createParameter(prefix, "numNeurons", QString::number(numneurons));
00137 params.createParameter(prefix, "accumulate", (isAccumulate() ? "True" : "False"));
00138
00139 QStringList list;
00140 for (unsigned int i = 0; i < inputdataptr->size(); i++) {
00141 list.push_back(QString::number((*inputdataptr)[i]));
00142 }
00143 params.createParameter(prefix, "inputs", list.join(" "));
00144
00145 list.clear();
00146 for (unsigned int i = 0; i < outputdataptr->size(); i++) {
00147 list.push_back(QString::number((*outputdataptr)[i]));
00148 }
00149 params.createParameter(prefix, "outputs", list.join(" "));
00150
00151 updater->save( params, params.createSubGroup(prefix, "OutFunction") );
00152 }
00153
00154 void Cluster::describe( QString type ) {
00155 Updatable::describe( type );
00156 Descriptor d = addTypeDescription( type, "A Cluster of neurons" );
00157 d.describeInt( "numNeurons" ).limits( 1, INT_MAX ).props( IsMandatory ).help( "The number of neurons contained by the Cluster" );
00158 d.describeBool( "accumulate" ).def( false ).help( "If true new inputs will be added to the previous values" );
00159 d.describeReal( "inputs" ).props( IsList ).help( "The input values of the neurons" );
00160 d.describeReal( "outputs" ).props( IsList ).help( "The output values of the neurons" );
00161 d.describeObject( "OutFunction" ).type( "OutputFunction" ).help( "The output function used to calculate the output values" );
00162 }
00163
00164 }