00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 #include "invertmotorspace.h"
00101
00102 InvertMotorSpace::InvertMotorSpace( int buffersize, double cInit , bool someInternalParams )
00103 : InvertMotorController(buffersize) {
00104
00105 BNoiseGen = 0;
00106
00107 this->cInit=cInit;
00108 this->someInternalParams=someInternalParams;
00109
00110
00111 Configurable::insertCVSInfo(name, "$RCSfile: invertmotorspace.cpp,v $", "$Revision: 1.24.6.3 $");
00112 };
00113
00114 InvertMotorSpace::~InvertMotorSpace() {
00115 if(BNoiseGen) free(BNoiseGen);
00116 }
00117
00118
00119
00120 void InvertMotorSpace::init(int sensornumber, int motornumber){
00121
00122 number_motors = motornumber;
00123 number_sensors = sensornumber;
00124 A.set(number_sensors, number_motors);
00125 C.set(number_motors, number_sensors);
00126 R.set(number_motors, number_motors);
00127 H.set(number_motors, 1);
00128 B.set(number_sensors, 1);
00129
00130 BNoiseGen = new WhiteUniformNoise();
00131 BNoiseGen->init(number_sensors);
00132
00133 A.toId();
00134
00135
00136 A = A;
00137
00138 C.toId();
00139 C*= cInit;
00140 x_buffer = new Matrix[buffersize];
00141 y_buffer = new Matrix[buffersize];
00142 for (unsigned int k = 0; k < buffersize; k++) {
00143 x_buffer[k].set(number_sensors,1);
00144 y_buffer[k].set(number_motors,1);
00145 }
00146
00147 initialised = true;
00148 }
00149
00150
00151
00152 void InvertMotorSpace::step(const sensor* x_, int number_sensors,
00153 motor* y_, int number_motors){
00154 fillBuffersAndControl(x_, number_sensors, y_, number_motors);
00155 if(t>buffersize){
00156
00157 const Matrix& y_effective = y_buffer[(t-int(s4delay))%buffersize];
00158 const Matrix& x = x_buffer[t%buffersize];
00159
00160
00161 learnController(x, x_smooth, max(int(s4delay)-1,0));
00162
00163
00164 learnModel(x, y_effective);
00165 }
00166
00167 t++;
00168 };
00169
00170
00171 void InvertMotorSpace::stepNoLearning(const sensor* x, int number_sensors,
00172 motor* y, int number_motors ){
00173 fillBuffersAndControl(x, number_sensors, y, number_motors);
00174
00175 t++;
00176 };
00177
00178 void InvertMotorSpace::fillBuffersAndControl(const sensor* x_, int number_sensors,
00179 motor* y_, int number_motors){
00180 assert((unsigned)number_sensors == this->number_sensors
00181 && (unsigned)number_motors == this->number_motors);
00182
00183 Matrix x(number_sensors,1,x_);
00184
00185
00186 putInBuffer(x_buffer, x);
00187
00188
00189 x_smooth = calculateSmoothValues(x_buffer, t < s4avg ? 1 : int(s4avg));
00190
00191
00192 Matrix y = calculateControllerValues(x_smooth);
00193
00194
00195 putInBuffer(y_buffer, y);
00196
00197
00198 y.convertToBuffer(y_, number_motors);
00199 }
00200
00201
00202
00203 void InvertMotorSpace::learnController(const Matrix& x, const Matrix& x_smooth, int delay){
00204 const Matrix& y = y_buffer[t%buffersize];
00205 const Matrix& y_tm1 = y_buffer[(t-1-delay)%buffersize];
00206
00207 const Matrix xsi = x - (A * y_tm1 + B);
00208
00209
00210 const Matrix eta = (A.multTM()^-1) * ( (A^T) * xsi );
00211
00212
00213
00214
00215 const Matrix z = C * x_smooth + H;
00216 const Matrix g_prime_inv = z.map(g_s_inv);
00217 R = C * A;
00218 const Matrix mu = eta.multrowwise(g_prime_inv);
00219 const Matrix zeta = (R.multMT()^-1) * mu;
00220
00221 const Matrix v = (R^T) * zeta;
00222 const Matrix omega = zeta.multrowwise(g_prime_inv);
00223
00224
00225
00226
00227
00228
00229 const Matrix alpha = A * v;
00230 const Matrix beta = omega.multrowwise(eta).multrowwise(y) * -2;
00231
00232 const Matrix zmodel = R * y + H;
00233 Matrix C_update;
00234 Matrix H_update;
00235
00236
00237 if(zetaupdate==0){
00238
00239 C_update = (zeta * (alpha^T) + beta * (x_smooth^T)) * epsC;
00240 H_update = (beta * epsC);
00241 }else{
00242
00243 C_update = (zeta * (alpha^T) + (beta + zeta*zetaupdate) * (x_smooth^T)) * epsC;
00244 H_update = (beta + zeta*zetaupdate) * epsC;
00245 }
00246
00247 if (!logaE==0){
00248 double temp= 1/(v.multTM().val(0,0)+0.0000001)*0.01;
00249 C_update *= temp;
00250 H_update *= temp;
00251 }
00252 if (!rootE==0){
00253 double temp= 1/sqrt(v.multTM().val(0,0)+0.0000001)*0.1;
00254 C_update *= temp;
00255 H_update *= temp;
00256 }
00257
00258 C += C_update.map(squash);
00259 H += H_update.map(squash);
00260 };
00261
00262
00263 void InvertMotorSpace::learnModel(const Matrix& x, const Matrix& y){
00264 Matrix xsi = x - (A * y + B);
00265
00266 Matrix A_update;
00267 Matrix B_update;
00268 A_update=(( xsi*(y^T) ) * epsA );
00269 Matrix B_noise = noiseMatrix(B.getM(),B.getN(), *BNoiseGen, -noiseB, noiseB);
00270 B_update=( xsi * epsA + B_noise) * factorB;
00271
00272 if (!logaE==0){
00273 Matrix xsi2 = (xsi^T)*xsi;
00274 double temp= 1/(xsi2.val(0,0)+0.0000001);
00275 A_update *= temp;
00276 B_update *= temp;
00277 }
00278 if (!rootE==0){
00279 const Matrix xsi2=(xsi^T)*xsi;
00280 double temp= 1/sqrt(xsi2.val(0,0)+0.0000001);
00281 A_update *= temp;
00282 B_update *= temp;
00283 }
00284
00285 A += A_update.map(squash);
00286 B += B_update.map(squash);
00287
00288 };
00289
00290
00291
00292 Matrix InvertMotorSpace::calculateControllerValues(const Matrix& x_smooth){
00293 return (C*x_smooth+H).map(g);
00294 };
00295
00296
00297 Matrix InvertMotorSpace::calculateDelayedValues(const Matrix* buffer,
00298 int number_steps_of_delay_){
00299
00300 assert ((unsigned)number_steps_of_delay_ < buffersize);
00301 return buffer[(t - number_steps_of_delay_) % buffersize];
00302 };
00303
00304 Matrix InvertMotorSpace::calculateSmoothValues(const Matrix* buffer,
00305 int number_steps_for_averaging_){
00306
00307 assert ((int)number_steps_for_averaging_ <= buffersize);
00308
00309 Matrix result(buffer[t % buffersize]);
00310 for (int k = 1; k < number_steps_for_averaging_; k++) {
00311 result += buffer[(t - k) % buffersize];
00312 }
00313 result *= 1/((double) (number_steps_for_averaging_));
00314 return result;
00315 };
00316
00317
00318
00319 bool InvertMotorSpace::store(const char* filename){
00320
00321 FILE* f;
00322 if(!(f = fopen(filename, "w"))) return false;
00323 storeMatrix(C,f);
00324 storeMatrix(H,f);
00325 storeMatrix(A,f);
00326 storeMatrix(B,f);
00327 fclose(f);
00328 return true;
00329 }
00330
00331
00332 bool InvertMotorSpace::restore(const char* filename){
00333
00334 FILE* f;
00335 if(!(f = fopen(filename, "r"))) return false;
00336 restoreMatrix(C,f);
00337 restoreMatrix(H,f);
00338 restoreMatrix(A,f);
00339 restoreMatrix(B,f);
00340 fclose(f);
00341 t=0;
00342 return true;
00343 }
00344
00345
00346 list<Inspectable::iparamkey> InvertMotorSpace::getInternalParamNames() const{
00347 list<iparamkey> keylist;
00348 if(someInternalParams){
00349 keylist+=store4x4AndDiagonalFieldNames(A,"A");
00350 keylist+=store4x4AndDiagonalFieldNames(C,"C");
00351 keylist+=store4x4AndDiagonalFieldNames(R,"R");
00352 }else{
00353 keylist+=storeMatrixFieldNames(A,"A");
00354 keylist+=storeMatrixFieldNames(C,"C");
00355 keylist+=storeMatrixFieldNames(R,"R");
00356 }
00357 keylist+=storeVectorFieldNames(H,"H");
00358 keylist+=storeVectorFieldNames(B,"B");
00359 return keylist;
00360 }
00361
00362 list<Inspectable::iparamval> InvertMotorSpace::getInternalParams() const{
00363 list<iparamval> l;
00364 if(someInternalParams){
00365 l+=store4x4AndDiagonal(A);
00366 l+=store4x4AndDiagonal(C);
00367 l+=store4x4AndDiagonal(R);
00368 }else{
00369 l+=A.convertToList();
00370 l+=C.convertToList();
00371 l+=R.convertToList();
00372 }
00373 l+=H.convertToList();
00374 l+=B.convertToList();
00375 return l;
00376 }
00377
00378 list<Inspectable::ILayer> InvertMotorSpace::getStructuralLayers() const {
00379 list<Inspectable::ILayer> l;
00380 l+=ILayer("x","", number_sensors, 0, "Sensors");
00381 l+=ILayer("y","H", number_motors, 1,"Motors");
00382 l+=ILayer("xP","B", number_sensors, 2,"Prediction");
00383 return l;
00384 }
00385
00386 list<Inspectable::IConnection> InvertMotorSpace::getStructuralConnections() const {
00387 list<Inspectable::IConnection> l;
00388 l+=IConnection("C", "x", "y");
00389 l+=IConnection("A", "y", "xP");
00390 return l;
00391 }
00392