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
#include "VarArray.h"
00042
#include "NaryVariable.h"
00043
#include <plearn/display/DisplayUtils.h>
00044
#include "VarArrayElementVariable.h"
00045
00046
namespace PLearn {
00047
using namespace std;
00048
00049 VarArray::VarArray()
00050 :
Array<
Var>(0,10)
00051 {}
00052
00053 VarArray::VarArray(
int n,
int n_extra)
00054 :
Array<
Var>(n,n_extra)
00055 {}
00056
00057 VarArray::VarArray(
int n,
int initial_length,
int n_extra)
00058 :
Array<
Var>(n,n_extra)
00059 {
00060
iterator array =
data();
00061
for (
int i=0;i<n;i++)
00062 array[i]=
Var(initial_length);
00063 }
00064
00065 VarArray::VarArray(
int n,
int initial_length,
int initial_width,
int n_extra)
00066 :
Array<
Var>(n,n_extra)
00067 {
00068
iterator array =
data();
00069
for (
int i=0;i<n;i++)
00070 array[i]=
Var(initial_length,initial_width);
00071 }
00072
00073 VarArray::VarArray(
const Var& v)
00074 :
Array<
Var>(1,10)
00075 { (*this)[0] = v; }
00076
00077 VarArray::VarArray(
const Var& v1,
const Var& v2)
00078 :
Array<
Var>(2,10)
00079 {
00080 (*this)[0] = v1;
00081 (*this)[1] = v2;
00082 }
00083
00084 VarArray::VarArray(
Variable* v)
00085 :
Array<
Var>(1,10)
00086 { (*this)[0] =
Var(v); }
00087
00088 VarArray::VarArray(
Variable* v1,
Variable* v2)
00089 :
Array<
Var>(2,10)
00090 {
00091 (*this)[0] =
Var(v1);
00092 (*this)[1] = Var(v2);
00093 }
00094
00095
00096
00097
00098
extern void varDeepCopyField(
Var& field, CopiesMap& copies);
00099
00100 void VarArray::makeDeepCopyFromShallowCopy(map<const void*, void*>& copies)
00101 {
00102
for(
int i=0; i<
size(); i++)
00103
varDeepCopyField((*
this)[i], copies);
00104 }
00105
00106
00107 void VarArray::copyValuesFrom(
const VarArray& from)
00108 {
00109
if (
size()!=from.
size())
00110
PLERROR(
"VarArray::copyValuesFrom(a): a does not have the same size (%d) as this (%d)\n",
00111 from.
size(),
size());
00112
for (
int i=0;i<
size();i++)
00113 (*this)[i]->value << from[i]->value;
00114 }
00115
00116
00117
00118 void VarArray::copyFrom(
const Vec& datavec)
00119 {
00120
copyFrom(datavec.
data(),datavec.
length());
00121 }
00122
00123 void VarArray::copyFrom(
const real* data,
int n)
00124 {
00125
iterator array = this->
data();
00126
int ncopied=0;
00127
for(
int i=0; i<
size(); i++)
00128 {
00129
Var& v = array[i];
00130
if (!v.
isNull())
00131 {
00132
real* value = v->valuedata;
00133
int vlength = v->nelems();
00134
if(ncopied+vlength>n)
00135
PLERROR(
"IN VarArray::copyFrom total length of all Vars in the array exceeds length of argument");
00136
for(
int j=0; j<vlength; j++)
00137 value[j] = *data++;
00138 ncopied += vlength;
00139 }
00140 }
00141
if(ncopied!=n)
00142
PLERROR(
"IN VarArray::copyFrom total length of all Vars in the array (%d) differs from length of argument (%d)",
00143 ncopied,n);
00144 }
00145
00146 void VarArray::makeSharedValue(
real* data,
int n)
00147 {
00148
iterator array = this->
data();
00149
int ncopied=0;
00150
for(
int i=0; i<
size(); i++)
00151 {
00152
Var& v = array[i];
00153
if (!v.
isNull())
00154 {
00155
int vlength = v->nelems();
00156 v->makeSharedValue(data,vlength);
00157 data += vlength;
00158 ncopied += vlength;
00159 }
00160 }
00161
if(ncopied!=n)
00162
PLERROR(
"IN VarArray::makeSharedValue total length of all Vars in the array (%d) differs from length of argument (%d)",
00163 ncopied,n);
00164 }
00165
00166 void VarArray::makeSharedValue(
PP<
Storage<real> > storage,
int offset_)
00167 {
00168
iterator array =
data();
00169
int ncopied=0;
00170
for(
int i=0; i<
size(); i++)
00171 {
00172
Var& v = array[i];
00173
if (!v.
isNull())
00174 {
00175
int vlength = v->nelems();
00176 v->makeSharedValue(storage,offset_+ncopied);
00177 ncopied += vlength;
00178 }
00179 }
00180 }
00181
00182 void VarArray::makeSharedGradient(
Vec& v,
int offset_)
00183 {
00184
makeSharedGradient( v.
storage, v.
offset_+offset_);
00185 }
00186
00187 void VarArray::makeSharedRValue(
Vec& v,
int offset_)
00188 {
00189
makeSharedRValue( v.
storage, v.
offset_+offset_);
00190 }
00191
00192 void VarArray::makeSharedGradient(
PP<
Storage<real> > storage,
int offset_)
00193 {
00194
iterator array =
data();
00195
int ncopied=0;
00196
for(
int i=0; i<
size(); i++)
00197 {
00198
Var& v = array[i];
00199
if (!v.
isNull())
00200 {
00201
int vlength = v->nelems();
00202 v->makeSharedGradient(storage,offset_+ncopied);
00203 ncopied += vlength;
00204 }
00205 }
00206 }
00207
00208 void VarArray::makeSharedValue(
Vec& v,
int offset_)
00209 {
00210
if (v.
length() <
nelems()+offset_)
00211
PLERROR(
"VarArray::makeSharedValue(Vec,int): vector too short (%d < %d + %d)",
00212 v.
length(),
nelems(),offset_);
00213
makeSharedValue(v.
storage,offset_);
00214 }
00215
00216 void VarArray::makeSharedGradient(
real* data,
int n)
00217 {
00218
iterator array = this->
data();
00219
int ncopied=0;
00220
for(
int i=0; i<
size(); i++)
00221 {
00222
Var& v = array[i];
00223
if (!v.
isNull())
00224 {
00225
int vlength = v->nelems();
00226 v->makeSharedGradient(data,vlength);
00227 data += vlength;
00228 ncopied += vlength;
00229 }
00230 }
00231
if(ncopied!=n)
00232
PLERROR(
"IN VarArray::makeSharedGradient total length of all Vars in the array (%d) differs from length of argument (%d)",
00233 ncopied,n);
00234 }
00235
00236 void VarArray::copyTo(
const Vec& datavec)
const
00237
{
00238
copyTo(datavec.
data(), datavec.
length());
00239 }
00240
00241 void VarArray::accumulateTo(
const Vec& datavec)
const
00242
{
00243
accumulateTo(datavec.
data(), datavec.
length());
00244 }
00245
00246 void VarArray::copyTo(
real* data,
int n)
const
00247
{
00248
iterator array = this->
data();
00249
int ncopied=0;
00250
for(
int i=0; i<
size(); i++)
00251 {
00252
Var& v = array[i];
00253
if (!v.
isNull())
00254 {
00255
real* value = v->valuedata;
00256
int vlength = v->nelems();
00257
if(ncopied+vlength>n)
00258
PLERROR(
"IN VarArray::copyTo total length of all Vars in the array exceeds length of argument");
00259
for(
int j=0; j<vlength; j++)
00260 *data++ = value[j];
00261 ncopied += vlength;
00262 }
00263 }
00264
if(ncopied!=n)
00265
PLERROR(
"IN VarArray::copyTo total length of all Vars in the array differs from length of argument");
00266 }
00267
00268 void VarArray::accumulateTo(
real* data,
int n)
const
00269
{
00270
iterator array = this->
data();
00271
int ncopied=0;
00272
for(
int i=0; i<
size(); i++)
00273 {
00274
Var& v = array[i];
00275
if (!v.
isNull())
00276 {
00277
real* value = v->valuedata;
00278
int vlength = v->nelems();
00279
if(ncopied+vlength>n)
00280
PLERROR(
"IN VarArray::copyTo total length of all Vars in the array exceeds length of argument");
00281
for(
int j=0; j<vlength; j++)
00282 *data++ += value[j];
00283 ncopied += vlength;
00284 }
00285 }
00286
if(ncopied!=n)
00287
PLERROR(
"IN VarArray::copyTo total length of all Vars in the array differs from length of argument");
00288 }
00289
00290 void VarArray::copyGradientFrom(
const Vec& datavec)
00291 {
00292
copyGradientFrom(datavec.
data(),datavec.
length());
00293 }
00294
00295 void VarArray::copyGradientFrom(
const Array<Vec>& datavec)
00296 {
00297
iterator array = this->
data();
00298
if (
size()!=datavec.
size())
00299
PLERROR(
"VarArray::copyGradientFrom has argument of size %d, expected %d",datavec.
size(),
size());
00300
for(
int i=0; i<
size(); i++)
00301 {
00302
Var& v = array[i];
00303
real* data = datavec[i].
data();
00304
int n = datavec[i].length();
00305
if (!v.
isNull())
00306 {
00307
real* value = v->gradientdata;
00308
int vlength = v->nelems();
00309
if(vlength!=n)
00310
PLERROR(
"IN VarArray::copyGradientFrom length of -th Var in the array differs from length of %d-th argument",i,i);
00311
for(
int j=0; j<vlength; j++)
00312 value[j] = *data++;
00313 }
00314 }
00315 }
00316
00317 void VarArray::copyGradientTo(
const Array<Vec>& datavec)
00318 {
00319
iterator array = this->
data();
00320
for(
int i=0; i<
size(); i++)
00321 {
00322
Var& v = array[i];
00323
real* data = datavec[i].
data();
00324
int n = datavec[i].length();
00325
if (!v.
isNull())
00326 {
00327
real* value = v->gradientdata;
00328
int vlength = v->nelems();
00329
if(vlength!=n)
00330
PLERROR(
"IN VarArray::copyGradientFrom length of -th Var in the array differs from length of %d-th argument",i,i);
00331
for(
int j=0; j<vlength; j++)
00332 *data++ = value[j];
00333 }
00334 }
00335 }
00336
00337 void VarArray::accumulateGradientFrom(
const Vec& datavec)
00338 {
00339
accumulateGradientFrom(datavec.
data(),datavec.
length());
00340 }
00341
00342 void VarArray::copyGradientFrom(
const real* data,
int n)
00343 {
00344
iterator array = this->
data();
00345
int ncopied=0;
00346
for(
int i=0; i<
size(); i++)
00347 {
00348
Var& v = array[i];
00349
if (!v.
isNull())
00350 {
00351
real* value = v->gradientdata;
00352
int vlength = v->nelems();
00353
if(ncopied+vlength>n)
00354
PLERROR(
"IN VarArray::copyGradientFrom total length of all Vars in the array exceeds length of argument");
00355
for(
int j=0; j<vlength; j++)
00356 value[j] = *data++;
00357 ncopied += vlength;
00358 }
00359 }
00360
if(ncopied!=n)
00361
PLERROR(
"IN VarArray::copyGradientFrom total length of all Vars in the array differs from length of argument");
00362 }
00363
00364 void VarArray::accumulateGradientFrom(
const real* data,
int n)
00365 {
00366
iterator array = this->
data();
00367
int ncopied=0;
00368
for(
int i=0; i<
size(); i++)
00369 {
00370
Var& v = array[i];
00371
if (!v.
isNull())
00372 {
00373
real* value = v->gradientdata;
00374
int vlength = v->nelems();
00375
if(ncopied+vlength>n)
00376
PLERROR(
"IN VarArray::accumulateGradientFrom total length of all Vars in the array exceeds length of argument");
00377
for(
int j=0; j<vlength; j++)
00378 value[j] += *data++;
00379 ncopied += vlength;
00380 }
00381 }
00382
if(ncopied!=n)
00383
PLERROR(
"IN VarArray::accumulateGradientFrom total length of all Vars in the array differs from length of argument");
00384 }
00385
00386 void VarArray::copyGradientTo(
const Vec& datavec)
00387 {
00388
copyGradientTo(datavec.
data(), datavec.
length());
00389 }
00390
00391 void VarArray::copyGradientTo(
real* data,
int n)
00392 {
00393
iterator array = this->
data();
00394
int ncopied=0;
00395
for(
int i=0; i<
size(); i++)
00396 {
00397
Var& v = array[i];
00398
if (!v.
isNull())
00399 {
00400
real* value = v->gradientdata;
00401
int vlength = v->nelems();
00402
if(ncopied+vlength>n)
00403
PLERROR(
"IN VarArray::copyGradientTo total length of all Vars in the array exceeds length of argument");
00404
for(
int j=0; j<vlength; j++)
00405 *data++ = value[j];
00406 ncopied += vlength;
00407 }
00408 }
00409
if(ncopied!=n)
00410
PLERROR(
"IN VarArray::copyGradientTo total length of all Vars in the array differs from length of argument");
00411 }
00412
00413 void VarArray::accumulateGradientTo(
const Vec& datavec)
00414 {
00415
accumulateGradientTo(datavec.
data(), datavec.
length());
00416 }
00417
00418 void VarArray::accumulateGradientTo(
real* data,
int n)
00419 {
00420
iterator array = this->
data();
00421
int ncopied=0;
00422
for(
int i=0; i<
size(); i++)
00423 {
00424
Var& v = array[i];
00425
if (!v.
isNull())
00426 {
00427
real* value = v->gradientdata;
00428
int vlength = v->nelems();
00429
if(ncopied+vlength>n)
00430
PLERROR(
"IN VarArray::accumulateGradientTo total length of all Vars in the array exceeds length of argument");
00431
for(
int j=0; j<vlength; j++)
00432 *data++ += value[j];
00433 ncopied += vlength;
00434 }
00435 }
00436
if(ncopied!=n)
00437
PLERROR(
"IN VarArray::accumulateGradientTo total length of all Vars in the array differs from length of argument");
00438 }
00439
00440 void VarArray::copyMinValueTo(
const Vec& datavec)
00441 {
00442
copyMinValueTo(datavec.
data(), datavec.
length());
00443 }
00444
00445 void VarArray::copyMinValueTo(
real* data,
int n)
00446 {
00447
iterator array = this->
data();
00448
int ncopied=0;
00449
for(
int i=0; i<
size(); i++)
00450 {
00451
Var& v = array[i];
00452
if (!v.
isNull())
00453 {
00454
real value = v->min_value;
00455
int vlength = v->nelems();
00456
if(ncopied+vlength>n)
00457
PLERROR(
"IN VarArray::copyMinValueTo total length of all Vars in the array exceeds length of argument");
00458
for(
int j=0; j<vlength; j++)
00459 *data++ = value;
00460 ncopied += vlength;
00461 }
00462 }
00463
if(ncopied!=n)
00464
PLERROR(
"IN VarArray::copyMinValueTo total length of all Vars in the array differs from length of argument");
00465 }
00466
00467 void VarArray::copyMaxValueTo(
const Vec& datavec)
00468 {
00469
copyMaxValueTo(datavec.
data(), datavec.
length());
00470 }
00471
00472 void VarArray::copyMaxValueTo(
real* data,
int n)
00473 {
00474
iterator array = this->
data();
00475
int ncopied=0;
00476
for(
int i=0; i<
size(); i++)
00477 {
00478
Var& v = array[i];
00479
if (!v.
isNull())
00480 {
00481
real value = v->max_value;
00482
int vlength = v->nelems();
00483
if(ncopied+vlength>n)
00484
PLERROR(
"IN VarArray::copyMaxValueTo total length of all Vars in the array exceeds length of argument");
00485
for(
int j=0; j<vlength; j++)
00486 *data++ = value;
00487 ncopied += vlength;
00488 }
00489 }
00490
if(ncopied!=n)
00491
PLERROR(
"IN VarArray::copyMaxValueTo total length of all Vars in the array differs from length of argument");
00492 }
00493
00494 void VarArray::makeSharedRValue(
PP<
Storage<real> > storage,
int offset_)
00495 {
00496
iterator array =
data();
00497
int ncopied=0;
00498
for(
int i=0; i<
size(); i++)
00499 {
00500
Var& v = array[i];
00501
if (!v.
isNull())
00502 {
00503 v->resizeRValue();
00504
int vlength = v->nelems();
00505 v->makeSharedRValue(storage,offset_+ncopied);
00506 ncopied += vlength;
00507 }
00508 }
00509 }
00510
00511 void VarArray::copyRValueTo(
real* data,
int n)
00512 {
00513
iterator array = this->
data();
00514
int ncopied=0;
00515
for(
int i=0; i<
size(); i++)
00516 {
00517
Var& v = array[i];
00518
if (!v.
isNull())
00519 {
00520
real* value = v->rvaluedata;
00521
if (!value)
00522
PLERROR(
"VarArray::copyRValueTo: empty Var in the array (number %d)",i);
00523
int vlength = v->nelems();
00524
if(ncopied+vlength>n)
00525
PLERROR(
"IN VarArray::copyRValueTo total length of all Vars in the array exceeds length of argument");
00526
for(
int j=0; j<vlength; j++)
00527 *data++ = value[j];
00528 ncopied += vlength;
00529 }
00530 }
00531
if(ncopied!=n)
00532
PLERROR(
"IN VarArray::copyRValueTo total length of all Vars in the array differs from length of argument");
00533 }
00534
00535 void VarArray::copyRValueFrom(
const real* data,
int n)
00536 {
00537
iterator array = this->
data();
00538
int ncopied=0;
00539
for(
int i=0; i<
size(); i++)
00540 {
00541
Var& v = array[i];
00542
if (!v.
isNull())
00543 {
00544 v->resizeRValue();
00545
real* value = v->rvaluedata;
00546
int vlength = v->nelems();
00547
if(ncopied+vlength>n)
00548
PLERROR(
"IN VarArray::copyRValueFrom total length of all Vars in the array exceeds length of argument");
00549
for(
int j=0; j<vlength; j++)
00550 value[j] = *data++;
00551 ncopied += vlength;
00552 }
00553 }
00554
if(ncopied!=n)
00555
PLERROR(
"IN VarArray::copyRValueFrom total length of all Vars in the array differs from length of argument");
00556 }
00557
00558 void VarArray::copyRValueTo(
const Vec& datavec)
00559 {
00560
copyRValueTo(datavec.
data(), datavec.
length());
00561 }
00562
00563 void VarArray::copyRValueFrom(
const Vec& datavec)
00564 {
00565
copyRValueFrom(datavec.
data(),datavec.
length());
00566 }
00567
00568 int VarArray::nelems()
const
00569
{
00570
iterator array =
data();
00571
int totallength = 0;
00572
for(
int i=0; i<
size(); i++)
00573
if (!array[i].
isNull())
00574 totallength += array[i]->nelems();
00575
return totallength;
00576 }
00577
00578 void VarArray::resizeRValue()
00579 {
00580
iterator array =
data();
00581
for(
int i=0; i<
size(); i++)
00582
if (!array[i].
isNull())
00583 array[i]->resizeRValue();
00584 }
00585
00586 int VarArray::sumOfLengths()
const
00587
{
00588
iterator array =
data();
00589
int totallength = 0;
00590
for(
int i=0; i<
size(); i++)
00591
if (!array[i].
isNull())
00592 totallength += array[i]->
length();
00593
return totallength;
00594 }
00595
00596 int VarArray::sumOfWidths()
const
00597
{
00598
iterator array =
data();
00599
int totalwidth = 0;
00600
for(
int i=0; i<
size(); i++)
00601
if (!array[i].
isNull())
00602 totalwidth += array[i]->
width();
00603
return totalwidth;
00604 }
00605
00606 int VarArray::maxWidth()
const
00607
{
00608
iterator array =
data();
00609
int maxwidth = 0;
00610
for(
int i=0; i<
size(); i++)
00611
if (!array[i].
isNull())
00612 {
00613
int w = array[i]->
width();
00614
if (w>maxwidth)
00615 maxwidth=w;
00616 }
00617
return maxwidth;
00618 }
00619
00620 int VarArray::maxLength()
const
00621
{
00622
iterator array =
data();
00623
int maxlength = 0;
00624
for(
int i=0; i<
size(); i++)
00625
if (!array[i].
isNull())
00626 {
00627
int l = array[i]->
length();
00628
if (l>maxlength)
00629 maxlength=l;
00630 }
00631
return maxlength;
00632 }
00633
00634 VarArray VarArray::nonNull()
const
00635
{
00636
VarArray results(0,
size());
00637
00638
iterator array =
data();
00639
for(
int i=0; i<
size(); i++)
00640
if (!array[i].
isNull())
00641 results.
append(array[i]);
00642
00643
return results;
00644 }
00645 VarArray& VarArray::subVarArray(
int start,
int len)
const
00646
{
00647
int max_position=start+len-1;
00648
if (max_position>
size())
00649
PLERROR(
"Error in :subVarArray(int start,int len), start+len>=nelems");
00650
VarArray* results=
new VarArray(0, len);
00651
00652
iterator array =
data();
00653
for(
int i=start; i<start+len; i++)
00654
if (!array[i].
isNull())
00655 results->
append(array[i]);
00656
00657
return *results;
00658 }
00659 void VarArray::copyFrom(
int start,
int len,
const VarArray& from)
00660 {
00661
int max_position=start+len-1;
00662
if (max_position>
size())
00663
PLERROR(
"VarArray is to short");
00664
iterator array =
data();
00665
for(
int i=0; i<len; i++)
00666
if (!from[i].
isNull())
00667 array[i+start]=from[i];
00668 }
00669 void VarArray::setMark()
const
00670
{
00671
iterator array =
data();
00672
for(
int i=0; i<
size(); i++)
00673
if (!array[i].
isNull())
00674 array[i]->setMark();
00675 }
00676
00677 void VarArray::clearMark()
const
00678
{
00679
iterator array =
data();
00680
for(
int i=0; i<
size(); i++)
00681
if (!array[i].
isNull())
00682 array[i]->clearMark();
00683 }
00684
00685 void VarArray::markPath()
const
00686
{
00687
iterator array =
data();
00688
for(
int i=0; i<
size(); i++)
00689
if (!array[i].
isNull()){
00690 array[i]->markPath();
00691
00692 }
00693 }
00694
00695 void VarArray::buildPath(
VarArray& path)
const
00696
{
00697
iterator array =
data();
00698
for(
int i=0; i<
size(); i++)
00699
if (!array[i].
isNull())
00700 array[i]->buildPath(path);
00701 }
00702
00703 void VarArray::fprop()
00704 {
00705
iterator array =
data();
00706
for(
int i=0; i<
size(); i++)
00707 {
00708
if (!array[i].
isNull())
00709 array[i]->fprop();
00710 }
00711 }
00712
00713 void VarArray::sizeprop()
00714 {
00715
iterator array =
data();
00716
for(
int i=0; i<
size(); i++)
00717
if (!array[i].
isNull())
00718 array[i]->sizeprop();
00719 }
00720
00721 void VarArray::sizefprop()
00722 {
00723
iterator array =
data();
00724
for(
int i=0; i<
size(); i++)
00725
if (!array[i].
isNull())
00726 array[i]->sizefprop();
00727 }
00728
00729 void VarArray::bprop()
00730 {
00731
iterator array =
data();
00732
for(
int i=
size()-1; i>=0; i--)
00733
if (!array[i].
isNull())
00734 array[i]->bprop();
00735 }
00736
00737 void VarArray::bbprop()
00738 {
00739
iterator array =
data();
00740
for(
int i=
size()-1; i>=0; i--)
00741
if (!array[i].
isNull())
00742 array[i]->bbprop();
00743 }
00744
00745 void VarArray::rfprop()
00746 {
00747
iterator array =
data();
00748
for(
int i=0; i<
size(); i++)
00749
if (!array[i].
isNull())
00750 array[i]->rfprop();
00751 }
00752
00753
00754
00755 void VarArray::fbprop()
00756 {
00757
iterator array =
data();
00758
for(
int i=0; i<
size()-1; i++)
00759
if (!array[i].
isNull())
00760 array[i]->fprop();
00761
00762
if (
size() > 0) {
00763
last()->fbprop();
00764
00765
#ifdef BOUNDCHECK
00766
if (
last()->gradient.hasMissing())
00767
PLERROR(
"VarArray::fbprop has NaN gradient");
00768
#endif
00769
for(
int i=
size()-2; i>=0; i--)
00770
if (!array[i].
isNull())
00771 {
00772
#ifdef BOUNDCHECK
00773
if (array[i]->gradient.hasMissing())
00774
PLERROR(
"VarArray::fbprop has NaN gradient");
00775
#endif
00776
array[i]->bprop();
00777 }
00778 }
00779 }
00780
00781 void VarArray::fbbprop()
00782 {
00783
iterator array =
data();
00784
for(
int i=0; i<
size()-1; i++)
00785
if (!array[i].
isNull())
00786 array[i]->fprop();
00787
00788
if (
size() > 0) {
00789
last()->fbbprop();
00790
00791
for(
int i=
size()-2; i>=0; i--)
00792
if (!array[i].
isNull())
00793 {
00794 array[i]->bprop();
00795 array[i]->bbprop();
00796 }
00797 }
00798 }
00799
00800
00801 void VarArray::symbolicBprop()
00802 {
00803
iterator array =
data();
00804
for(
int i=
size()-1; i>=0; i--)
00805
if (!array[i].
isNull())
00806 array[i]->symbolicBprop();
00807 }
00808
00809 VarArray VarArray::symbolicGradient()
00810 {
00811
iterator array =
data();
00812
VarArray symbolic_gradients(
size());
00813
for(
int i=0; i<
size(); i++)
00814
if (!array[i].
isNull())
00815 symbolic_gradients[i] = array[i]->g;
00816
return symbolic_gradients;
00817 }
00818
00819 void VarArray::clearSymbolicGradient()
00820 {
00821
iterator array =
data();
00822
for(
int i=0; i<
size(); i++)
00823
if (!array[i].
isNull())
00824 array[i]->clearSymbolicGradient();
00825 }
00826
00827 void VarArray::fillGradient(
real value)
00828 {
00829
iterator array =
data();
00830
for(
int i=0; i<
size(); i++)
00831
if (!array[i].
isNull())
00832 array[i]->fillGradient(value);
00833 }
00834
00835 void VarArray::clearGradient()
00836 {
00837
iterator array =
data();
00838
for(
int i=0; i<
size(); i++)
00839
if (!array[i].
isNull())
00840 array[i]->clearGradient();
00841 }
00842
00843 void VarArray::clearDiagHessian()
00844 {
00845
iterator array =
data();
00846
for(
int i=0; i<
size(); i++)
00847
if (!array[i].
isNull())
00848 array[i]->clearDiagHessian();
00849 }
00850
00851
00852 void VarArray::setDontBpropHere(
bool val)
00853 {
00854
iterator array =
data();
00855
for(
int i=0; i<
size(); i++)
00856
if (!array[i].
isNull())
00857 array[i]->setDontBpropHere(
val);
00858 }
00859
00860 bool VarArray::update(
real step_size,
Vec direction,
real coeff,
real b)
00861 {
00862
bool hit =
false;
00863
int pos=0;
00864
iterator array =
data();
00865
for(
int i=0; i<
size(); pos+=array[i++]->nelems())
00866
if (!array[i].isNull())
00867 hit = hit ||
00868 array[i]->update(step_size,direction.
subVec(pos,array[i]->nelems()), coeff, b);
00869
return hit;
00870 }
00871
00872 bool VarArray::update(
Vec step_sizes,
Vec direction,
Vec coeffs)
00873 {
00874
bool hit =
false;
00875
int pos = 0;
00876
iterator array =
data();
00877
for (
int i=0; i<
size(); pos+=array[i++]->nelems()) {
00878
if (!array[i].isNull()) {
00879 hit = hit ||
00880 array[i]->update(
00881 step_sizes.
subVec(pos, array[i]->nelems()),
00882 direction.
subVec(pos, array[i]->
nelems()),
00883 coeffs[i]);
00884 }
00885 }
00886
return hit;
00887 }
00888
00889 bool VarArray::update(
Vec step_sizes,
Vec direction,
real coeff,
real b)
00890 {
00891
bool hit =
false;
00892
int pos = 0;
00893
iterator array =
data();
00894
for (
int i=0; i<
size(); pos+=array[i++]->nelems()) {
00895
if (!array[i].isNull()) {
00896 hit = hit ||
00897 array[i]->update(
00898 step_sizes.
subVec(pos, array[i]->nelems()),
00899 direction.
subVec(pos, array[i]->
nelems()),
00900 coeff, b);
00901 }
00902 }
00903
return hit;
00904 }
00905
00906 real VarArray::maxUpdate(
Vec direction)
00907 {
00908
real max_step_size = FLT_MAX;
00909
int pos=0;
00910
iterator array =
data();
00911
for(
int i=0; i<
size(); pos+=array[i++]->nelems())
00912
if (!array[i].isNull())
00913 max_step_size =
MIN(max_step_size,
00914 array[i]->
maxUpdate(direction.
subVec(pos,array[i]->nelems())));
00915
return max_step_size;
00916 }
00917
00918 bool VarArray::update(
real step_size)
00919 {
00920
bool hit =
false;
00921
iterator array =
data();
00922
for(
int i=0; i<
size(); i++)
00923
if (!array[i].
isNull())
00924 hit = hit || array[i]->update(step_size);
00925
return hit;
00926 }
00927
00928 bool VarArray::update(
Vec new_value)
00929 {
00930
bool hit =
false;
00931
int pos=0;
00932
iterator array =
data();
00933
for(
int i=0; i<
size(); pos+=array[i++]->nelems())
00934
if (!array[i].isNull())
00935 hit = hit ||
00936 array[i]->update(new_value.
subVec(pos,array[i]->nelems()));
00937
return hit;
00938 }
00939
00940 void VarArray::read(istream& in)
00941 {
00942
iterator array =
data();
00943
for(
int i=0; i<
size(); i++)
00944
if (!array[i].
isNull())
00945 array[i]->read(in);
00946 }
00947
00948 void VarArray::write(ostream& out)
const
00949
{
00950
iterator array =
data();
00951
for(
int i=0; i<
size(); i++)
00952
if (!array[i].
isNull())
00953 array[i]->write(out);
00954 }
00955
00956 Var VarArray::operator[](
Var index)
00957 {
00958
return new VarArrayElementVariable(*
this, index);
00959 }
00960
00961 VarArray VarArray::sources()
const
00962
{
00963
VarArray a;
00964
iterator array =
data();
00965
for(
int i=0; i<
size(); i++)
00966
if (!array[i].
isNull())
00967 a &= array[i]->sources();
00968
return a;
00969 }
00970
00971 VarArray VarArray::ancestors()
const
00972
{
00973
VarArray a;
00974
iterator array =
data();
00975
for(
int i=0; i<
size(); i++)
00976
if (!array[i].
isNull())
00977 a &= array[i]->ancestors();
00978
return a;
00979 }
00980
00981 void VarArray::unmarkAncestors()
const
00982
{
00983
iterator array =
data();
00984
for(
int i=0; i<
size(); i++)
00985
if (!array[i].
isNull())
00986 array[i]->unmarkAncestors();
00987 }
00988
00989 VarArray VarArray::parents()
const
00990
{
00991
setMark();
00992
VarArray all_parents;
00993
VarArray parents_i;
00994
iterator array =
data();
00995
for(
int i=0; i<
size(); i++)
00996
if (!array[i].
isNull())
00997 {
00998 parents_i = array[i]->parents();
00999
if(parents_i.
size()>0)
01000 {
01001 parents_i.
setMark();
01002 all_parents.
append(parents_i);
01003 }
01004 }
01005
clearMark();
01006 all_parents.
clearMark();
01007
return all_parents;
01008 }
01009 void VarArray::printNames()const
01010 {
01011
for(
int i=0;i<this->
size();i++)
01012 cout<<i<<
" : "<<(*this)[i]->getName()<<
endl;
01013 }
01014
01017
01018 VarArray propagationPath(
const VarArray& inputs,
const VarArray& outputs)
01019 {
01020
if(outputs.
size()==0)
01021
return VarArray(0,0);
01022
01023
VarArray proppath;
01024 inputs.
setMark();
01025 outputs.
markPath();
01026 inputs.
clearMark();
01027 outputs.
buildPath(proppath);
01028
01029
return proppath;
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054 VarArray propagationPath(
const VarArray& outputs)
01055 {
01056
if(outputs.
size()==0)
01057
return VarArray(0,0);
01058
VarArray all_sources = outputs.
sources();
01059 outputs.
unmarkAncestors();
01060
return propagationPath(all_sources,outputs);
01061 }
01062
01063
01064 VarArray propagationPathToParentsOfPath(
const VarArray& inputs,
const VarArray& outputs)
01065 {
01066
VarArray parents =
nonInputParentsOfPath(inputs, outputs);
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
if(parents.
size()==0)
01077
return VarArray(0,0);
01078
return propagationPath(parents);
01079 }
01080
01081
01082 VarArray nonInputParentsOfPath(
VarArray inputs,
VarArray outputs)
01083 {
01084
01085
VarArray proppath =
propagationPath(inputs, outputs);
01086 inputs.
setMark();
01087
VarArray non_input_parents = proppath.
parents();
01088 inputs.
clearMark();
01089
01090
return non_input_parents;
01091 }
01092
01093
01094 VarArray allSources(
const VarArray& v)
01095 {
01096
VarArray result;
01097 v.
unmarkAncestors();
01098 result = v.
sources();
01099 v.
unmarkAncestors();
01100
return result;
01101 }
01102
01103
01104 VarArray operator-(
const VarArray& a,
const VarArray& b)
01105 {
01106
VarArray result;
01107
int i,j;
01108
for(i=0; i<a.
size(); i++)
01109 {
01110
Var v = a[i];
01111
for(j=0; j<b.
size(); j++)
01112
if(b[j]==v)
01113
break;
01114
if(j>=b.
size())
01115 result.
append(v);
01116 }
01117
return result;
01118 }
01119
01120
01121 VarArray nonInputSources(
const VarArray& inputs,
const VarArray& outputs)
01122 {
01123
VarArray result;
01124 outputs.
unmarkAncestors();
01125 inputs.
setMark();
01126 result = outputs.
sources();
01127 outputs.
unmarkAncestors();
01128
return result;
01129 }
01130
01131 void operator<<(VarArray& ar, const Array<Vec>& values)
01132 {
01133
int n = ar.
size();
01134
if(values.size()!=n)
01135
PLERROR(
"In operator<<(VarArray&, const Array<Vec>&) sizes of arrays differ (VarArray:%d Array<Vec>:%d)",ar.size(),values.size());
01136
for(
int k=0;
k<n;
k++)
01137 {
01138
Vec& ar_v = ar[
k]->value;
01139
Vec& v = values[
k];
01140
if(ar_v.
size() != v.
size())
01141
PLERROR(
"In operator<<(VarArray&, const Array<Vec>&) sizes of vector %d differ (in VarArray:%d, in Array<Vec>:%d)",ar_v.
size(),v.
size());
01142 ar_v << v;
01143 }
01144 }
01145
01146 void operator>>(
VarArray& ar,
const Array<Vec>& values)
01147 {
01148
int n = ar.
size();
01149
if(values.
size()!=n)
01150
PLERROR(
"In operator<<(VarArray&, const Array<Vec>&) sizes of arrays differ (VarArray:%d Array<Vec>:%d)",ar.
size(),values.
size());
01151
for(
int k=0;
k<n;
k++)
01152 {
01153
Vec& ar_v = ar[
k]->value;
01154
Vec& v = values[
k];
01155
if(ar_v.
size() != v.
size())
01156
PLERROR(
"In operator<<(VarArray&, const Array<Vec>&) sizes of vector %d differ (in VarArray:%d, in Array<Vec>:%d)",ar_v.
size(),v.
size());
01157 ar_v >> v;
01158 }
01159 }
01160
01161 void printInfo(
VarArray& a) { a.
printInfo(); }
01162
01163 void printInfo(
VarArray inputs,
const Var& output,
bool show_gradients)
01164 {
01165 inputs.
setMark();
01166 output->markPath();
01167
VarArray proppath;
01168 output->buildPath(proppath);
01169
if (show_gradients)
01170 {
01171
01172 proppath.
fbprop();
01173 }
01174
else
01175 proppath.
fprop();
01176 proppath.
printInfo(show_gradients);
01177 }
01178
01179 }
01180