00001 /*************************************************************************** 00002 * Copyright (C) 2005-2011 LpzRobots development team * 00003 * Georg Martius <georg dot martius at web dot de> * 00004 * Frank Guettler <guettler at informatik dot uni-leipzig dot de * 00005 * Frank Hesse <frank at nld dot ds dot mpg dot de> * 00006 * Ralf Der <ralfder at mis dot mpg dot de> * 00007 * * 00008 * This program is free software; you can redistribute it and/or modify * 00009 * it under the terms of the GNU General Public License as published by * 00010 * the Free Software Foundation; either version 2 of the License, or * 00011 * (at your option) any later version. * 00012 * * 00013 * This program is distributed in the hope that it will be useful, * 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00016 * GNU General Public License for more details. * 00017 * * 00018 * You should have received a copy of the GNU General Public License * 00019 * along with this program; if not, write to the * 00020 * Free Software Foundation, Inc., * 00021 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 00022 * * 00023 ***************************************************************************/ 00024 #ifndef __MUTUALINFORMATIONCONTROLLER_H 00025 #define __MUTUALINFORMATIONCONTROLLER_H 00026 00027 #include "abstractcontroller.h" 00028 #include "matrix.h" 00029 00030 /** 00031 * This is a controller who is passive at the moment, that means, he will not 00032 * generate any motor values. This controller calculates the mutual information 00033 * from one to the next time step. Note that many steps are necessary for a good 00034 * prediction of the mutual information. 00035 */ 00036 class MutualInformationController : public AbstractController 00037 { 00038 00039 public: 00040 00041 static const int numberSensorsPreInitialized = 10; 00042 static const int numberMotorsPreInitialized = 2; 00043 00044 /** 00045 * Constructs the mutual information controller. At this time the 00046 * controller is not yet initialized (this does the Agent). 00047 * @param sensorIntervalCount is the number of the intervals used. This 00048 * is important for generating the internal matrices. 00049 * @param minSensorValue is the minimum value the sensors can become 00050 * @param maxSensorValue is the maximum value the sensors can become 00051 * 00052 */ 00053 MutualInformationController(int sensorIntervalCount, double minSensorValue=-1, double maxSensorValue=1, bool showF =false, bool showP =false, bool showXsiF = false); 00054 virtual ~MutualInformationController() {}; 00055 00056 virtual double& getMI(int index) { 00057 if (!initialized) 00058 init(numberSensorsPreInitialized,numberMotorsPreInitialized); 00059 assert(index<sensorNumber); 00060 return MI[index]; 00061 } 00062 00063 virtual double& getH_x(int index) { 00064 if (!initialized) 00065 init(numberSensorsPreInitialized,numberMotorsPreInitialized); 00066 assert(index<sensorNumber); 00067 return H_x[index]; 00068 } 00069 00070 virtual double& getH_yx(int index) { 00071 if (!initialized) 00072 init(numberSensorsPreInitialized,numberMotorsPreInitialized); 00073 assert(index<sensorNumber); 00074 return H_yx[index]; 00075 } 00076 00077 virtual double& getH_Xsi(int index) { 00078 if (!initialized) 00079 init(numberSensorsPreInitialized,numberMotorsPreInitialized); 00080 assert(index<sensorNumber); 00081 return H_Xsi[index]; 00082 } 00083 00084 /** 00085 * we like to calculate the entropy of the xsi, therefore we need for the (self calculated) update rule 00086 * x_t+1=-a * tanh(c * x_t) the a and c, which should be set in the main.cpp. 00087 */ 00088 virtual void setAandCandCalcH_xsi(double ainit, double cinit); 00089 00090 00091 /****************************************************************************/ 00092 /* BEGIN methods of AbstractController */ 00093 /****************************************************************************/ 00094 00095 /** initialisation of the controller with the given sensor/ motornumber 00096 * Must NORMALLY be called before use. For all ControllerAdapters 00097 * call first AbstractControllerAdapter::init(sensornumber,motornumber) 00098 * if you overwrite this method 00099 */ 00100 virtual void init(int sensornumber, int motornumber, RandGen* randGen = 0); 00101 00102 /** @return Number of sensors the controller 00103 was initialised with or 0 if not initialised */ 00104 virtual int getSensorNumber() const { return sensorNumber; } 00105 00106 /** @return Number of motors the controller 00107 was initialised with or 0 if not initialised */ 00108 virtual int getMotorNumber() const { return motorNumber; } 00109 00110 /** performs one step (includes learning). 00111 Calculates motor commands from sensor inputs. 00112 @param sensors sensors inputs scaled to [-1,1] 00113 @param sensornumber length of the sensor array 00114 @param motors motors outputs. MUST have enough space for motor values! 00115 @param motornumber length of the provided motor array 00116 */ 00117 virtual void step(const sensor* sensors, int sensornumber, 00118 motor* motors, int motornumber); 00119 00120 /** performs one step without learning. 00121 @see step 00122 */ 00123 virtual void stepNoLearning(const sensor* sensors , int sensornumber, 00124 motor* motors, int motornumber); 00125 00126 /****************************************************************************/ 00127 /* END methods of AbstractController */ 00128 /****************************************************************************/ 00129 00130 00131 /****************************************************************************/ 00132 /* BEGIN methods of Inspectable */ 00133 /****************************************************************************/ 00134 00135 /** The list of the names of all internal parameters given by getInternalParams(). 00136 The naming convention is "v[i]" for vectors 00137 and "A[i][j]" for matrices, where i, j start at 0. 00138 @return: list of keys 00139 */ 00140 // virtual iparamkeylist getInternalParamNames() const; 00141 00142 /** @return: list of values 00143 */ 00144 // virtual iparamvallist getInternalParams() const; 00145 00146 /****************************************************************************/ 00147 /* END methods of Inspectable */ 00148 /****************************************************************************/ 00149 00150 /****************************************************************************/ 00151 /* BEGIN methods of Storeable */ 00152 /****************************************************************************/ 00153 00154 /** stores the object to the given file stream (binary). 00155 */ 00156 virtual bool store(FILE* f) const { return true; } 00157 00158 /** loads the object from the given file stream (binary). 00159 */ 00160 virtual bool restore(FILE* f) { return true; } 00161 00162 /****************************************************************************/ 00163 /* END methods of Storeable */ 00164 /****************************************************************************/ 00165 00166 00167 /****************************************************************************/ 00168 /* BEGIN methods of Configurable */ 00169 /****************************************************************************/ 00170 00171 // Configurable::paramval getParam(const paramkey& key) const; 00172 00173 // bool setParam(const paramkey& key, paramval val); 00174 00175 // Configurable::paramlist getParamList() const; 00176 00177 /****************************************************************************/ 00178 /* END methods of Configurable */ 00179 /****************************************************************************/ 00180 00181 00182 protected: 00183 parambool showF; 00184 parambool showP; 00185 parambool showXsiF; 00186 bool initialized; // tells wether the controller is already initialized by the agent 00187 bool useXsiCalculation; 00188 00189 double minSensorValue; 00190 double maxSensorValue; 00191 int sensorIntervalCount; 00192 int sensorNumber; 00193 int motorNumber; 00194 std::list<matrix::Matrix*> freqMatrixList; // stores the number of occurances of t-1 to t (frequency) 00195 std::list<matrix::Matrix*> probMatrixList; // stores the probability of state to state occurances of t-1 to t 00196 std::list<matrix::Matrix*> xsiFreqMatrixList; // stores the number of occurances of xsi(x) (frequency) 00197 00198 double* oldSensorStates; // stores the sensor states for previous step (t-1) 00199 int t; // indicates the step (time) 00200 00201 double* MI; // mutual information = MI(X_{t-1},X_t) 00202 double* H_x; // H(x) = H(X_{t-1}) 00203 double* H_yx; // H(X_t|X_{t-1}) 00204 double* H_Xsi; // H(Xsi) 00205 00206 // the next two variables are only used if Xsi_x is calculated 00207 double ainit; 00208 double cinit; 00209 00210 /** 00211 * Calculates the mutual information 00212 * This is made by normal formula, which 00213 * needs O(n^2) costs. 00214 */ 00215 virtual void calculateMIs(double* MI); 00216 00217 /** 00218 * Calculates the entropy of x 00219 * This is made by normal formula, which 00220 * needs O(n) costs. 00221 */ 00222 virtual void calculateH_x(double* H); 00223 00224 00225 /** 00226 * Calculates the conditional entropy of y|x 00227 * This is made by normal formula, which 00228 * needs O(n²) costs. 00229 */ 00230 virtual void calculateH_yx(double* H_yx); 00231 00232 00233 /** 00234 * Updates the xsi frequency matrix list 00235 */ 00236 virtual void updateXsiFreqMatrixList(const sensor* sensors); 00237 00238 /** 00239 * Calculates the entropy of H(Xsi) 00240 * This is made by normal formula, which 00241 * needs O(n) costs. 00242 */ 00243 virtual void calculateH_Xsi(double* H_Xsi); 00244 00245 00246 00247 /** 00248 * Updates the mutual information 00249 * This is made by a difference term, which 00250 * is added to the old MI(t-1). 00251 * This function needs the OLD MI(t-1) AND 00252 * the OLD F matrix, so update the MI with this 00253 * function first before updating the F matrix! 00254 * calculation costs: O(1) 00255 */ 00256 virtual void updateMIs(const sensor* sensors); 00257 00258 00259 00260 /** 00261 * Returns the appropiate state which belongs to the given sensorValue. 00262 */ 00263 virtual int getState(double sensorValue); 00264 00265 00266 /** 00267 * Does the pre-initialization functionality. 00268 * @param sensornumber 00269 * @param motornumber 00270 * @param randGen 00271 */ 00272 virtual void internalInit(int sensornumber, int motornumber, RandGen* randGen = 0); 00273 00274 00275 }; 00276 00277 #endif