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
00047
#ifndef TMat_maths_impl_H
00048
#define TMat_maths_impl_H
00049
00050
#include <algorithm>
00051
00052
namespace PLearn {
00053
using namespace std;
00054
00055
template <
class T>
00056 T
max(
const TVec<T>& vec)
00057 {
00058
#ifdef BOUNDCHECK
00059
if(vec.
length()==0)
00060
PLERROR(
"IN max(const NumericVec& vec) TVec has zero length()");
00061
#endif
00062
T* pv = vec.
data();
00063 T maxval = *pv++;
00064
int n = vec.
length();
00065
while(--n)
00066 {
00067
if(*pv>maxval)
00068 maxval = *pv;
00069 ++pv;
00070 }
00071
return maxval;
00072 }
00073
00075
template <
class T>
00076 void softmax(
const TVec<T>& x,
const TVec<T>& y)
00077 {
00078
int n =
x.length();
00079
if (n>0)
00080 {
00081 T* yp = y.
data();
00082 T* xp =
x.data();
00083 T maxx =
max(
x);
00084
real s = 0;
00085
for (
int i=0;i<n;i++)
00086 s += (yp[i] =
safeexp(xp[i]-maxx));
00087
if (s == 0)
PLERROR(
"trying to divide by 0 in softmax");
00088 s = 1.0 / s;
00089
for (
int i=0;i<n;i++)
00090 yp[i] *= s;
00091 }
00092 }
00093
00094
00095
template <
class T>
00096 void log_softmax(
const TVec<T> &x,
TVec<T> &y)
00097 {
00098
if (
x.length() > 0) {
00099 y <<
x;
00100 y -=
max(
x);
00101 y -=
logadd(y);
00102 }
00103 }
00104
00106
template <
class T>
00107 void exp(
const TVec<T>& x,
TVec<T>& y)
00108 {
00109 y.
resize(
x.length());
00110
int n =
x.length();
00111 T* xp =
x.data();
00112 T* yp = y.
data();
00113
while(n--)
00114 *yp++ =
exp(*xp++);
00115 }
00116
00118
template<
class T>
00119 T
sumsquare(
const TVec<T>& x)
00120 {
00121 T* v =
x.data();
00122 T res =
square(v[0]);
00123
int l =
x.length();
00124
for(
int i=1; i<l; i++)
00125 res +=
square(v[i]);
00126
return res;
00127 }
00128
00130
template<
class T>
00131 T
sumabs(
const TVec<T>& x)
00132 {
00133 T* v =
x.data();
00134 T res = (T)(fabs((
real)v[0]));
00135
int l =
x.length();
00136
for(
int i=1; i<l; i++)
00137 res += (T)(fabs((
real)v[i]));
00138
return res;
00139 }
00140
00142
template<
class T>
00143 void squareElements(
const TVec<T>& x)
00144 {
00145 T* ptr =
x.data();
00146
int l =
x.length();
00147
while(l--)
00148 {
00149 *ptr *= *ptr;
00150 ++ptr;
00151 }
00152 }
00153
00155
template<
class T>
00156 void squareElements(
const TMat<T>& m)
00157 {
00158
if (m.
size()==0)
return;
00159
if(m.
isCompact()) {
00160
typename TMat<T>::compact_iterator it = m.
compact_begin();
00161
typename TMat<T>::compact_iterator itend = m.
compact_end();
00162
for(; it != itend; ++it)
00163 *it =
square(*it);
00164 }
else {
00165
typename TMat<T>::iterator it = m.
begin();
00166
typename TMat<T>::iterator itend = m.
end();
00167
for(; it != itend; ++it)
00168 *it =
square(*it);
00169 }
00170 }
00171
00173
template<
class T>
00174 T
sumsquare(
const TMat<T>& m)
00175 {
00176
if (m.
size()==0)
return 0;
00177
if(m.
isCompact())
00178 {
00179
typename TMat<T>::compact_iterator it = m.
compact_begin();
00180
typename TMat<T>::compact_iterator itend = m.
compact_end();
00181 T res =
square(*it);
00182 ++it;
00183
for(; it!=itend; ++it)
00184 res +=
square(*it);
00185
return res;
00186 }
00187
else
00188 {
00189
typename TMat<T>::iterator it = m.
begin();
00190
typename TMat<T>::iterator itend = m.
end();
00191 T res =
square(*it);
00192 ++it;
00193
for(; it!=itend; ++it)
00194 res +=
square(*it);
00195
return res;
00196 }
00197 }
00198
00199
00201
template<
class T>
00202 T
sumabs(
const TMat<T>& m)
00203 {
00204
if (m.
size()==0)
return 0;
00205
if(m.
isCompact())
00206 {
00207
typename TMat<T>::compact_iterator it = m.
compact_begin();
00208
typename TMat<T>::compact_iterator itend = m.
compact_end();
00209 T res = fabs(*it);
00210 ++it;
00211
for(; it!=itend; ++it)
00212 res += fabs(*it);
00213
return res;
00214 }
00215
else
00216 {
00217
typename TMat<T>::iterator it = m.
begin();
00218
typename TMat<T>::iterator itend = m.
end();
00219 T res = fabs(*it);
00220 ++it;
00221
for(; it!=itend; ++it)
00222 res += fabs(*it);
00223
return res;
00224 }
00225 }
00226
00227
00229
template <
class T>
00230 inline void multiply(
const TVec<T>& source1, T source2,
TVec<T>& destination)
00231 {
00232
int n=source1.
length();
00233
if (n!=destination.
length())
00234 destination.
resize(n);
00235 T* s1=source1.
data();
00236 T* d=destination.
data();
00237
for (
int i=0;i<n;i++)
00238 d[i] = s1[i]*source2;
00239 }
00240
00241
00242
00243
00244
template<
class T>
00245 T
sum(
const TVec<T>& vec,
bool ignore_missing=
false)
00246 {
00247
double res = 0.0;
00248 T* v = vec.
data();
00249
for(
int i=0; i<vec.
length(); i++)
00250 {
00251
if (!
is_missing(v[i])) res += v[i];
00252
else if (!ignore_missing)
return MISSING_VALUE;
00253 }
00254
return T(res);
00255 }
00256
00260
template<
class T>
00261 T
sum_of_log(
const TVec<T>& vec)
00262 {
00263
double res = 0.0;
00264 T* v = vec.
data();
00265
for(
int i=0; i<vec.
length(); i++)
00266 res +=
log(v[i]);
00267
return T(res);
00268 }
00269
00270
template<
class T>
00271 T
product(
const TVec<T>& vec)
00272 {
00273
double res = 1.0;
00274 T* v = vec.
data();
00275
for(
int i=0; i<vec.
length(); i++)
00276 res *= v[i];
00277
return T(res);
00278 }
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00300
template<
class T>
00301 T
mean(
const TVec<T>& vec,
bool ignore_missing=
false)
00302 {
00303
#ifdef BOUNDCHECK
00304
if(vec.
length()==0)
00305
PLERROR(
"IN T mean(const TVec<T>& vec) vec has zero length");
00306
#endif
00307
double res = 0.0;
00308
int n = 0;
00309 T* v = vec.
data();
00310
for(
int i=0; i<vec.
length(); i++)
00311 {
00312
if (!
is_missing(v[i]))
00313 {
00314 res += v[i];
00315 n++;
00316 }
00317
else if (!ignore_missing)
return MISSING_VALUE;
00318 }
00319
00320
if (n == 0)
return MISSING_VALUE;
00321
return T(res/
double(n));
00322 }
00323
00324
template<
class T>
00325 T
harmonic_mean(
const TVec<T>& vec,
bool ignore_missing=
false)
00326 {
00327
#ifdef BOUNDCHECK
00328
if(vec.
length()==0)
00329
PLERROR(
"IN T mean(const TVec<T>& vec) vec has zero length");
00330
#endif
00331
double res = 0.0;
00332
int n = 0;
00333 T* v = vec.
data();
00334
for(
int i=0; i<vec.
length(); i++)
00335 {
00336
if (!
is_missing(v[i]))
00337 {
00338 res += 1.0/v[i];
00339 n++;
00340 }
00341
else if (!ignore_missing)
return MISSING_VALUE;
00342 }
00343
00344
if (n == 0)
return MISSING_VALUE;
00345
return T(
double(n)/res);
00346 }
00347
00348
template<
class T>
00349 T
avgdev(
const TVec<T>& vec, T meanval)
00350 {
00351
#ifdef BOUNDCHECK
00352
if(vec.
length()==0)
00353
PLERROR(
"IN T avgdev(const TVec<T>& vec, T meanval) vec has zero length");
00354
#endif
00355
double res = 0.0;
00356 T* v = vec.
data();
00357
for(
int i=0; i<vec.
length(); i++)
00358 res += fabs(v[i]-meanval);
00359
return res/vec.
length();
00360 }
00361
00362
template<
class T>
00363 T
geometric_mean(
const TVec<T>& vec)
00364 {
00365
#ifdef BOUNDCHECK
00366
if(vec.
length()==0)
00367
PLERROR(
"IN T geometric_mean(const TVec<T>& vec) vec has zero length");
00368
#endif
00369
double res = 0.0;
00370 T* v = vec.
data();
00371
for(
int i=0; i<vec.
length(); i++)
00372 {
00373 T vi = v[i];
00374
if (vi<=0)
00375
PLERROR(
"geometric_mean(TVec<T>): argument %g <=0 at position [%d]",
00376 vi,i);
00377 res += v[i];
00378 }
00379
return T(
exp(res/vec.
length()));
00380 }
00381
00382
template<
class T>
00383 T
weighted_mean(
const TVec<T>& vec,
const TVec<T>& weights,
bool ignore_missing=
false)
00384 {
00385
#ifdef BOUNDCHECK
00386
if(vec.
length()!=weights.
length() || vec.
length() == 0)
00387
PLERROR(
"IN T weighted_mean(const TVec<T>& vec, const TVec<T>& weights) vec and weights must have equal (non-zero) lengths");
00388
#endif
00389
double res = 0.0;
00390 T sum_weights = 0.0;
00391 T* v = vec.
data();
00392 T* w = weights.
data();
00393
for(
int i=0; i<vec.
length(); i++)
00394 {
00395
if (!
is_missing(v[i]) && !
is_missing(w[i]))
00396 {
00397 res += v[i] * w[i];
00398 sum_weights += w[i];
00399 }
00400
else if (!ignore_missing)
return MISSING_VALUE;
00401 }
00402
if (sum_weights == 0)
00403
PLERROR(
"IN T weighted_mean: sum(weights) == 0");
00404
return T(res/sum_weights);
00405 }
00406
00407
template<
class T>
00408 T
variance(
const TVec<T>& vec, T meanval)
00409 {
00410
#ifdef BOUNDCHECK
00411
if(vec.
length()<=1)
00412
PLERROR(
"IN T variance(const TVec<T>& vec, T meanval) vec length must be more than one");
00413
#endif
00414
double res = 0.0;
00415 T* v = vec.
data();
00416
for(
int i=0; i<vec.
length(); i++)
00417 {
00418
double diff = v[i]-meanval;
00419 res += diff*diff;
00420 }
00421
return res/(vec.
length()-1);
00422 }
00423
00424
template<
class T>
00425 T
covariance(
const TVec<T>& vec1,
const TVec<T>& vec2, T mean1, T mean2)
00426 {
00427
#ifdef BOUNDCHECK
00428
if(vec1.
length()<=1)
00429
PLERROR(
"IN T covariance(const TVec<T>& vec1, const TVec<T>& vec2, T mean1, T mean2) vec1's length must be more than one");
00430
if(vec2.
length()<=1)
00431
PLERROR(
"IN T covariance(const TVec<T>& vec1, const TVec<T>& vec2, T mean1, T mean2) vec2's length must be more than one");
00432
#endif
00433
if(vec1.
length() != vec2.
length())
00434
PLERROR(
"IN T covariance(const TVec<T>& vec1, const TVec<T>& vec2, T mean1, T mean2) the lengths of vec1 and vec2 must be same");
00435
int length = vec1.
length();
00436
double res = 0.0;
00437 T* v1 = vec1.
data();
00438 T* v2 = vec2.
data();
00439
for(
int i=0; i<length; i++)
00440 {
00441
double temp = (v1[i]-mean1)*(v2[i]-mean2);
00442 res += temp;
00443 }
00444
return res/(length - 1);
00445 }
00446
00447
template<
class T>
00448 T
weighted_variance(
const TVec<T>& vec,
const TVec<T>& weights, T no_weighted_mean, T weighted_mean)
00449 {
00450
#ifdef BOUNDCHECK
00451
if(vec.
length()!=weights.
length() || vec.
length()==0)
00452
PLERROR(
"IN T weighted_variance(const TVec<T>& vec, const TVec<T>& weights, T no_weighted_mean, T weighted_mean) vec and weights must have equal (non-zero) lengths");
00453
#endif
00454
double res = 0.0;
00455 T* v = vec.
data();
00456 T* w = weights.
data();
00457
for(
int i=0; i<vec.
length(); i++)
00458 res += v[i] * v[i] * w[i];
00459 T sum_weights =
sum(weights);
00460
if (sum_weights == 0)
00461
PLERROR(
"IN T weighted_variance(const TVec<T>& vec, const TVec<T>& weights, T no_weighted_mean, T weighted_mean) sum(weights) == 0");
00462
return (res/sum_weights - no_weighted_mean * (2*
weighted_mean - no_weighted_mean))*vec.
length()/(vec.
length()-1);
00463 }
00464
00465
template<
class T>
00466 TVec<T> histogram(
const TVec<T>& vec, T minval, T maxval,
int nbins)
00467 {
00468
TVec<T> histo(nbins);
00469 T deltaval = maxval-minval + 1e-6;
00470
for(
int i=0; i<vec.
length(); i++)
00471 {
00472 T
val = vec[i];
00473
int binpos =
int((
val-minval)/deltaval*nbins);
00474
if(binpos>=0 && binpos<nbins)
00475 histo[binpos]++;
00476 }
00477
return histo;
00478 }
00479
00480
00481
template<
class T>
00482 T
min(
const TVec<T>& vec)
00483 {
00484
#ifdef BOUNDCHECK
00485
if(vec.
length()==0)
00486
PLERROR(
"IN T min(const TVec<T>& vec) vec has zero length");
00487
#endif
00488
T* v = vec.
data();
00489 T minval = v[0];
00490
for(
int i=1; i<vec.
length(); i++)
00491
if(v[i]<minval)
00492 minval = v[i];
00493
return minval;
00494 }
00495
00496
template<
class T>
00497 T
maxabs(
const TVec<T>& vec)
00498 {
00499
#ifdef BOUNDCHECK
00500
if(vec.
length()==0)
00501
PLERROR(
"IN T maxabs(const TVec<T>& vec) vec has zero length");
00502
#endif
00503
T* v = vec.
data();
00504 T maxval = fabs(v[0]);
00505
for(
int i=1; i<vec.
length(); i++)
00506 {
00507 T a=fabs(v[i]);
00508
if(a>maxval)
00509 maxval = a;
00510 }
00511
return maxval;
00512 }
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
template<
class T>
00533 T
minabs(
const TVec<T>& vec,
int index =
int())
00534 {
00535
#ifdef BOUNDCHECK
00536
if(vec.
length()==0)
00537
PLERROR(
"IN T minabs(const TVec<T>& vec) vec has zero length");
00538
#endif
00539
T* v = vec.
data();
00540 T minval = fabs(v[0]);
00541
for(
int i=1; i<vec.
length(); i++)
00542 {
00543 T a=fabs(v[i]);
00544
if(a<minval)
00545 {
00546 index = i;
00547 minval = a;
00548 }
00549 }
00550
00551
return minval;
00552 }
00553
00554
00555
template<
class T>
00556 int argmax(
const TVec<T>& vec)
00557 {
00558
#ifdef BOUNDCHECK
00559
if(vec.
length()==0)
00560
PLERROR(
"IN int argmax(const TVec<T>& vec) vec has zero length");
00561
#endif
00562
T* v = vec.
data();
00563
int indexmax = 0;
00564 T maxval = v[0];
00565
for(
int i=1; i<vec.
length(); i++)
00566
if(v[i]>maxval)
00567 {
00568 maxval = v[i];
00569 indexmax = i;
00570 }
00571
return indexmax;
00572 }
00573
00574
template<
class T>
00575 int argmax(
const TVec<T>& vec,
bool ignore_missing)
00576 {
00577
#ifdef BOUNDCHECK
00578
if(vec.
length()==0)
00579
PLERROR(
"IN int argmax(const TVec<T>& vec) vec has zero length");
00580
#endif
00581
T* v = vec.
data();
00582
int indexmax = -1;
00583 T maxval =
MISSING_VALUE;
00584
00585
for(
int i=0; i<vec.
length(); i++)
00586 {
00587
if(
is_missing(v[i]) )
00588 {
00589
if(ignore_missing)
continue;
00590
else PLERROR(
"argmax(const TVec<T>& vec, bool ignore_missing) encountered a MISSING_VALUE\n"
00591
"at index %d and ignore_missing is false.", i);
00592 }
00593
00594
if( indexmax == -1 ||
00595 v[i] > maxval )
00596 {
00597 maxval = v[i];
00598 indexmax = i;
00599 }
00600 }
00601
return indexmax;
00602 }
00603
00604
00605
template<
class T>
00606 int argmin(
const TVec<T>& vec)
00607 {
00608
#ifdef BOUNDCHECK
00609
if(vec.
length()==0)
00610
PLERROR(
"IN int argmin(const TVec<T>& vec) vec has zero length");
00611
#endif
00612
T* v = vec.
data();
00613
int indexmin = 0;
00614 T minval = v[0];
00615
for(
int i=1; i<vec.
length(); i++)
00616
if(v[i]<minval)
00617 {
00618 minval = v[i];
00619 indexmin = i;
00620 }
00621
return indexmin;
00622 }
00623
00624
template<
class T>
00625 int argmin(
const TVec<T>& vec,
bool ignore_missing)
00626 {
00627
#ifdef BOUNDCHECK
00628
if(vec.
length()==0)
00629
PLERROR(
"IN int argmin(const TVec<T>& vec) vec has zero length");
00630
#endif
00631
T* v = vec.
data();
00632
int indexmin = -1;
00633 T minval =
MISSING_VALUE;
00634
00635
for(
int i=0; i<vec.
length(); i++)
00636 {
00637
if(
is_missing(v[i]) )
00638 {
00639
if(ignore_missing)
continue;
00640
else PLERROR(
"argmin(const TVec<T>& vec, bool ignore_missing) encountered a MISSING_VALUE\n"
00641
"at index %d and ignore_missing is false.", i);
00642 }
00643
00644
if( indexmin == -1 ||
00645 v[i] < minval )
00646 {
00647 minval = v[i];
00648 indexmin = i;
00649 }
00650 }
00651
return indexmin;
00652 }
00653
00654
00655
00656
template<
class T>
00657 T
pownorm(
const TVec<T>& vec,
double n)
00658 {
00659
double result = 0.0;
00660 T* v = vec.
data();
00661
if(n==1.0)
00662 {
00663
for(
int i=0; i<vec.
length(); i++)
00664 {
00665 T
val = v[i];
00666
if(
val>=0)
00667 result +=
val;
00668
else
00669 result -=
val;
00670 }
00671 }
00672
else if(n==2.0)
00673 {
00674
for(
int i=0; i<vec.
length(); i++)
00675 {
00676 T
val = v[i];
00677 result +=
val*
val;
00678 }
00679 }
00680
else if(n==0)
00681 { result = vec.
length(); }
00682
else
00683 {
00684
for(
int i=0; i<vec.
length(); i++)
00685 result +=
mypow(fabs(v[i]),n);
00686 }
00687
return result;
00688 }
00689
00690
template<
class T>
00691 inline T
pownorm(
const TVec<T>& vec) {
return pownorm(vec,T(2.0)); }
00692
00693
template<
class T>
00694 T
norm(
const TVec<T>& vec,
double n)
00695 {
00696
if(n==T(1.0))
00697
return pownorm(vec, T(1.0));
00698
else if(n==T(2.0))
00699
return sqrt(
pownorm(vec,T(2.0)));
00700
else
00701
return mypow(
pownorm(vec,n), T(1.0)/n);
00702 }
00703
00704
template<
class T>
00705 inline T
norm(
const TVec<T>& vec) {
return norm(vec,T(2.0)); }
00706
00707
template<
class T>
00708 void normalize(
const TVec<T>& vec,
double n)
00709 { vec /=
norm(vec,n); }
00710
00711
template<
class T>
00712 T
powdistance(
const TVec<T>& vec1,
const TVec<T>& vec2,
double n)
00713 {
00714
static T result, diff;
00715
#ifdef BOUNDCHECK
00716
if(vec1.
length() != vec2.
length())
00717
PLERROR(
"In weighted_powdistance: vec1, vec2 should have the same length");
00718
#endif
00719
result = 0.0;
00720 T* v1 = vec1.
data();
00721 T* v2 = vec2.
data();
00722
int length = vec1.
length();
00723
if(n==1.0)
00724 {
00725
for(
int i=0; i<length; i++)
00726 {
00727 diff = *v1++ - *v2++;
00728
if(diff>=0)
00729 result += diff;
00730
else
00731 result -= diff;
00732 }
00733 }
00734
else if(n==2.0)
00735 {
00736
for(
int i=0; i<length; i++)
00737 {
00738 diff = *v1++ - *v2++;
00739 result += diff*diff;
00740 }
00741 }
00742
else
00743 {
00744
for(
int i=0; i<length; i++)
00745 {
00746 diff = *v1++ - *v2++;
00747
if(diff<0)
00748 diff = -diff;
00749 result +=
mypow(diff,n);
00750 }
00751 }
00752
return result;
00753 }
00754
00755
template<
class T>
00756 inline T
powdistance(
const TVec<T>& vec1,
const TVec<T>& vec2)
00757 {
return powdistance(vec1, vec2, 2.0); }
00758
00759
template<
class T>
00760 T
dist(
const TVec<T>& vec1,
const TVec<T>& vec2,
double n)
00761 {
00762
if(n==T(1.0))
00763
return powdistance(vec1, vec2, T(1.0));
00764
else if(n==T(2.0))
00765
return sqrt(
powdistance(vec1, vec2, T(2.0)));
00766
else
00767
return mypow(
powdistance(vec1, vec2, n), T(1.0)/n);
00768 }
00769
00770
template<
class T>
00771 inline T
L2distance(
const TVec<T>& vec1,
const TVec<T>& vec2)
00772 {
return dist(vec1, vec2, 2.0); }
00773
00774
template<
class T>
00775 inline T
L1distance(
const TVec<T>& vec1,
const TVec<T>& vec2)
00776 {
return dist(vec1, vec2, 1.0); }
00777
00778
00779
template<
class T>
00780 T
weighted_powdistance(
const TVec<T>& vec1,
const TVec<T>& vec2,
double n,
const TVec<T>& weights)
00781 {
00782
#ifdef BOUNDCHECK
00783
if(vec1.
length() != weights.
length() || vec2.
length()!=weights.
length())
00784
PLERROR(
"In weighted_powdistance: vec1, vec2 and weights vector should have the same length");
00785
#endif
00786
T result = 0.0;
00787 T* v1 = vec1.
data();
00788 T* v2 = vec2.
data();
00789 T* w = weights.
data();
00790
int length = vec1.
length();
00791
if(n==1.0)
00792 {
00793
for(
int i=0; i<length; i++)
00794 {
00795 T diff = w[i]*(v1[i]-v2[i]);
00796
if(diff>=0)
00797 result += diff;
00798
else
00799 result -= diff;
00800 }
00801 }
00802
else if(n==2.0)
00803 {
00804
for(
int i=0; i<length; i++)
00805 {
00806 T diff = w[i]*(v1[i]-v2[i]);
00807 result += diff*diff;
00808 }
00809 }
00810
else
00811 {
00812
for(
int i=0; i<length; i++)
00813 {
00814 T diff = w[i]*(v1[i]-v2[i]);
00815
if(diff<0)
00816 diff = -diff;
00817 result +=
mypow(diff,n);
00818 }
00819 }
00820
return result;
00821 }
00822
00823
template<
class T>
00824 T
weighted_distance(
const TVec<T>& vec1,
const TVec<T>& vec2,
double n,
const TVec<T>& weights)
00825 {
00826
if(n==1.0)
00827
return weighted_powdistance(vec1, vec2, 1.0, weights);
00828
else if(n==2.0)
00829
return sqrt(
weighted_powdistance(vec1, vec2, 2.0, weights));
00830
else
00831
return mypow(
weighted_powdistance(vec1, vec2, n, weights), 1.0/n);
00832 }
00833
00834
00835
template<
class T>
00836 void operator-=(
const TVec<T>& vec1,
const TVec<T>& vec2)
00837 {
00838 T* v1 = vec1.
data();
00839 T* v2 = vec2.
data();
00840
for(
int i=0; i<vec1.
length(); i++)
00841 v1[i] -= v2[i];
00842 }
00843
00844
template<
class T>
00845 void operator*=(
const TVec<T>& vec1,
const TVec<T>& vec2)
00846 {
00847 T* v1 = vec1.
data();
00848 T* v2 = vec2.
data();
00849
for(
int i=0; i<vec1.
length(); i++)
00850 v1[i] *= v2[i];
00851 }
00852
00853
template<
class T>
00854 inline void operator/=(
const TVec<T>& vec, T scalar)
00855 { vec *= T(1.0)/scalar; }
00856
00857
template<
class T>
00858 inline void operator/=(
const TVec<T>& vec,
int scalar)
00859 { vec /= T(scalar); }
00860
00861
template<
class T>
00862 void compute_log(
const TVec<T>& src,
const TVec<T>& dest)
00863 {
00864
#ifdef BOUNDCHECK
00865
if(src.
length()!=dest.
length())
00866
PLERROR(
"In log, src and dest vectors must have the same length");
00867
#endif
00868
T* ps = src.
data();
00869 T* pd = dest.
data();
00870
int n = src.
length();
00871
for(
int i=0; i<n; i++)
00872 *pd++ =
log(*ps++);
00873 }
00874
00875
template<
class T>
00876 inline TVec<T> log(
const TVec<T>& src)
00877 {
TVec<T> dest(src.
length());
compute_log(src,dest);
return dest; }
00878
00879
template<
class T>
00880 void compute_sqrt(
const TVec<T>& src,
const TVec<T>& dest)
00881 {
00882
#ifdef BOUNDCHECK
00883
if(src.
length()!=dest.
length())
00884
PLERROR(
"In sqrt, src and dest vectors must have the same length");
00885
#endif
00886
T* ps = src.
data();
00887 T* pd = dest.
data();
00888
int n = src.
length();
00889
for(
int i=0; i<n; i++)
00890 *pd++ =
sqrt(*ps++);
00891 }
00892
00893
template<
class T>
00894 inline TVec<T> sqrt(
const TVec<T>& src)
00895 {
TVec<T> dest(src.
length());
compute_sqrt(src,dest);
return dest; }
00896
00897
template<
class T>
00898 void compute_safelog(
const TVec<T>& src,
const TVec<T>& dest)
00899 {
00900
#ifdef BOUNDCHECK
00901
if(src.
length()!=dest.
length())
00902
PLERROR(
"In safelog, src and dest vectors must have the same length");
00903
#endif
00904
T* ps = src.
data();
00905 T* pd = dest.
data();
00906
int n = src.
length();
00907
for(
int i=0; i<n; i++)
00908 *pd++ =
safelog(*ps++);
00909 }
00910
00911
template<
class T>
00912 inline TVec<T> safelog(
const TVec<T>& src)
00913 {
TVec<T> dest(src.
length());
compute_safelog(src,dest);
return dest; }
00914
00915
template<
class T>
00916 void operator/=(
const TVec<T>& vec1,
const TVec<T>& vec2)
00917 {
00918 T* v1 = vec1.
data();
00919 T* v2 = vec2.
data();
00920
for(
int i=0; i<vec1.
length(); i++)
00921 v1[i] /= v2[i];
00922 }
00923
00924
template<
class T>
00925 void compute_tanh(
const TVec<T>& src,
const TVec<T>& dest)
00926 {
00927
#ifdef BOUNDCHECK
00928
if(src.
length()!=dest.
length())
00929
PLERROR(
"In tanh, src and dest vectors must have the same length");
00930
#endif
00931
T* ps = src.
data();
00932 T* pd = dest.
data();
00933
int n = src.
length();
00934
for(
int i=0; i<n; i++)
00935 *pd++ =
tanh(*ps++);
00936 }
00937
00938
template<
class T>
00939 void bprop_tanh(
const TVec<T>& tanh_x,
const TVec<T>& d_tanh_x,
TVec<T>& d_x)
00940 {
00941
#ifdef BOUNDCHECK
00942
if(tanh_x.
length()!=d_tanh_x.
length())
00943
PLERROR(
"In bprop_tanh, src and dest vectors must have the same length");
00944
#endif
00945
int n = tanh_x.
length();
00946
if (n != d_x.
length()) d_x.
resize(n);
00947 T* y = tanh_x.
data();
00948 T* dy = d_tanh_x.
data();
00949 T* dx = d_x.
data();
00950
for(
int i=0; i<n; i++)
00951 {
00952
real yi = *y++;
00953 *dx++ = *dy++ * (1 - yi*yi);
00954 }
00955 }
00956
00957
template<
class T>
00958 inline TVec<T> tanh(
const TVec<T>& src)
00959 {
TVec<T> dest(src.
length());
compute_tanh(src,dest);
return dest; }
00960
00961
00962
template<
class T>
00963 void compute_fasttanh(
const TVec<T>& src,
const TVec<T>& dest)
00964 {
00965
#ifdef BOUNDCHECK
00966
if(src.
length()!=dest.
length())
00967
PLERROR(
"In fasttanh, src and dest vectors must have the same length");
00968
#endif
00969
T* ps = src.
data();
00970 T* pd = dest.
data();
00971
int n = src.
length();
00972
for(
int i=0; i<n; i++)
00973 *pd++ =
fasttanh(*ps++);
00974 }
00975
00976
template<
class T>
00977 inline TVec<T> fasttanh(
const TVec<T>& src)
00978 {
TVec<T> dest(src.
length());
compute_fasttanh(src,dest);
return dest; }
00979
00980
template<
class T>
00981 void compute_sigmoid(
const TVec<T>& src,
const TVec<T>& dest)
00982 {
00983
#ifdef BOUNDCHECK
00984
if(src.
length()!=dest.
length())
00985
PLERROR(
"In sigmoid, src and dest vectors must have the same length");
00986
#endif
00987
T* ps = src.
data();
00988 T* pd = dest.
data();
00989
int n = src.
length();
00990
for(
int i=0; i<n; i++)
00991 *pd++ =
sigmoid(*ps++);
00992 }
00993
00994
template<
class T>
00995 inline TVec<T> sigmoid(
const TVec<T>& src)
00996 {
TVec<T> dest(src.
length());
compute_sigmoid(src,dest);
return dest; }
00997
00998
00999
template<
class T>
01000 void compute_fastsigmoid(
const TVec<T>& src,
const TVec<T>& dest)
01001 {
01002
#ifdef BOUNDCHECK
01003
if(src.
length()!=dest.
length())
01004
PLERROR(
"In fastsigmoid, src and dest vectors must have the same length");
01005
#endif
01006
T* ps = src.
data();
01007 T* pd = dest.
data();
01008
int n = src.
length();
01009
for(
int i=0; i<n; i++)
01010 *pd++ =
fastsigmoid(*ps++);
01011 }
01012
01013
template<
class T>
01014 inline TVec<T> fastsigmoid(
const TVec<T>& src)
01015 {
TVec<T> dest(src.
length());
compute_fastsigmoid(src,dest);
return dest; }
01016
01017
template<
class T>
01018 void compute_inverse_sigmoid(
const TVec<T>& src,
const TVec<T>& dest)
01019 {
01020
#ifdef BOUNDCHECK
01021
if(src.
length()!=dest.
length())
01022
PLERROR(
"In inverse_sigmoid, src and dest vectors must have the same length");
01023
#endif
01024
T* ps = src.
data();
01025 T* pd = dest.
data();
01026
int n = src.
length();
01027
for(
int i=0; i<n; i++)
01028 *pd++ =
inverse_sigmoid(*ps++);
01029 }
01030
01031
template<
class T>
01032 inline TVec<T> inverse_sigmoid(
const TVec<T>& src)
01033 {
TVec<T> dest(src.
length());
compute_inverse_sigmoid(src,dest);
return dest; }
01034
01035
01036
template<
class T>
01037 void negateElements(
const TVec<T>& vec)
01038 {
01039 T* v = vec.
data();
01040
for(
int i=0; i<vec.
length(); i++)
01041 v[i] = -v[i];
01042 }
01043
01044
template<
class T>
01045 void invertElements(
const TVec<T>& vec)
01046 {
01047 T* v = vec.
data();
01048
for(
int i=0; i<vec.
length(); i++)
01049 v[i] = 1.0/v[i];
01050 }
01051
01052
template<
class T>
01053 TVec<T> inverted(
const TVec<T>& vec)
01054 {
01055
TVec<T> ret(vec.
length());
01056 T* v = vec.
data();
01057
for(
int i=0; i<vec.
length(); i++)
01058 ret[i] = 1.0/v[i];
01059
return ret;
01060 }
01061
01062
01063
template<
class T>
01064 void operator+=(
const TVec<T>& vec, T scalar)
01065 {
01066 T* v = vec.
data();
01067
for(
int i=0; i<vec.
length(); i++)
01068 v[i] += scalar;
01069 }
01070
01071
template<
class T>
01072 void operator-=(
const TVec<T>& vec, T scalar)
01073 { vec += -scalar; }
01074
01075
template<
class T>
01076 TVec<T> operator-(
TVec<T> vec)
01077 {
01078
TVec<T> opposite(vec.
length());
01079 T *v=vec.
data();
01080 T *o=opposite.
data();
01081
for (
int i=0;i<vec.
length();i++)
01082 o[i] = - v[i];
01083
return opposite;
01084 }
01085
01086
template<
class T>
01087 T
dot(
const TVec<T>& vec1,
const TVec<T>& vec2)
01088 {
01089
#ifdef BOUNDCHECK
01090
if(vec1.
length()!=vec2.
length())
01091
PLERROR(
"In T operator*(const TVec<T>& vec1, const TVec<T>& vec2) (dot product) the 2 vecs must have the same length.");
01092
#endif
01093
01094 T res = 0;
01095 T* v1 = vec1.
data();
01096 T* v2 = vec2.
data();
01097
for(
int i=0; i<vec1.
length(); i++)
01098 res += v1[i]*v2[i];
01099
return res;
01100 }
01101
01107
template<
class V,
class T,
class U>
01108 V
dot(
const TVec<T>& vec1,
const TVec<U>& vec2)
01109 {
01110
#ifdef BOUNDCHECK
01111
if(vec1.
length()!=vec2.
length())
01112
PLERROR(
"In T operator*(const TVec<T>& vec1, const TVec<T>& vec2) (dot product) the 2 vecs must have the same length.");
01113
#endif
01114
01115 V res = 0;
01116 T* v1 = vec1.
data();
01117 U* v2 = vec2.
data();
01118
for(
int i=0; i<vec1.
length(); i++)
01119 res += v1[i]*v2[i];
01120
return res;
01121 }
01122
01123
template<
class T>
01124 T
dot(
const TMat<T>& m1,
const TMat<T>& m2)
01125 {
01126
#ifdef BOUNDCHECK
01127
if(m1.
size()!=m2.
size())
01128
PLERROR(
"In T operator*(const TMat<T>& m1, const TVec<T>& vec2) (dot product) the 2 matrices must have the same number of elements.");
01129
#endif
01130
01131 T res = 0;
01132 T* v1 = m1.
data();
01133 T* v2 = m2.
data();
01134
if (m1.
isCompact() && m2.
isCompact())
01135
for(
int i=0; i<m1.
size(); i++)
01136 res += v1[i]*v2[i];
01137
else
01138 {
01139
TMatElementIterator<T> p1 = m1.
begin();
01140
TMatElementIterator<T> p2 = m2.
begin();
01141
for (
int i=0; i<m1.
size(); i++,++p1,++p2)
01142 res += *p1 * *p2;
01143 }
01144
return res;
01145 }
01146
01147
template<
class T>
01148 TVec<T> operator-(
const TVec<T>& v1,
const TVec<T>& v2)
01149 {
01150
if (v1.
length() != v2.
length())
01151
PLERROR(
"TVec<T> - TVec<T>: different lengths %d and %d",
01152 v1.
length(), v2.
length());
01153
TVec<T> v(v1.
length());
01154 v << v1;
01155 v-=v2;
01156
return v;
01157 }
01158
01159
template<
class T>
01160 TVec<T> operator-(T v1,
const TVec<T>& v2)
01161 {
01162
TVec<T> v(v2.
length());
01163 v = -v2;
01164 v += v1;
01165
return v;
01166 }
01167
01168
template<
class T>
01169 TVec<T> operator-(
const TVec<T>& v1, T v2)
01170 {
01171
TVec<T> v(v1.
length());
01172
substract(v1,v2,v);
01173
return v;
01174 }
01175
01176
template<
class T>
01177 TVec<T> operator+(
const TVec<T>& v1,
const TVec<T>& v2)
01178 {
01179
if (v1.
length() != v2.
length())
01180
PLERROR(
"TVec<T> + TVec<T>: different lengths %d and %d",
01181 v1.
length(), v2.
length());
01182
TVec<T> v(v1.
length());
01183 v << v1;
01184 v+=v2;
01185
return v;
01186 }
01187
01188
template<
class T>
01189 TVec<T> operator+(T v1,
const TVec<T>& v2)
01190 {
01191
TVec<T> v(v2.
length());
01192
add(v2,v1,v);
01193
return v;
01194 }
01195
01196
template<
class T>
01197 TVec<T> operator+(
const TVec<T>& v1, T v2)
01198 {
01199
TVec<T> v(v1.
length());
01200
add(v1,v2,v);
01201
return v;
01202 }
01203
01204
template<
class T>
01205 TVec<T> operator%(
const TVec<T>& v1,
const TVec<T>& v2)
01206 {
01207
if (v1.
length() != v2.
length())
01208
PLERROR(
"TVec<T> + TVec<T>: different lengths %d and %d",
01209 v1.
length(), v2.
length());
01210
TVec<T> v(v1.
length());
01211 v << v1;
01212 v*=v2;
01213
return v;
01214 }
01215
01216
template<
class T>
01217 TVec<T> operator*(T scalar,
const TVec<T>& v)
01218 {
01219
TVec<T> result(v.
length());
01220
multiply(v,scalar,result);
01221
return result;
01222 }
01223
01224
template<
class T>
01225 TVec<T> operator*(
const TVec<T>& v1, T v2)
01226 {
01227
TVec<T> v(v1.
length());
01228
multiply(v1,v2,v);
01229
return v;
01230 }
01231
01232
template<
class T>
01233 TVec<T> operator/(
const TVec<T>& v1,
const TVec<T>& v2)
01234 {
01235
if (v1.
length() != v2.
length())
01236
PLERROR(
"TVec<T> + TVec<T>: different lengths %d and %d",
01237 v1.
length(), v2.
length());
01238
TVec<T> v(v1.
length());
01239 v << v1;
01240 v/=v2;
01241
return v;
01242 }
01243
01244
template<
class T>
01245 TVec<T> operator/(T v1,
const TVec<T>& v2)
01246 {
01247
int n=v2.
length();
01248
TVec<T> v(n);
01249 T* s2=v2.
data();
01250 T* d=v.
data();
01251
for (
int i=0;i<n;i++)
01252 d[i] = v1/s2[i];
01253
return v;
01254 }
01255
01256
01257
template<
class T1,
class T2>
01258 TVec<T1> operator/(
const TVec<T1>& v1, T2 scalar)
01259 {
01260
TVec<T1> v(v1.
length());
01261
multiply(v1,T1(1.0)/(T1)scalar,v);
01262
return v;
01263 }
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
template<
class T>
01282 T
logadd(
const TVec<T>& vec)
01283 {
01284
int l = vec.
length();
01285
if(l==0)
01286
return LOG_INIT;
01287
01288 T *p_x = vec.
data();
01289 T
sum = *p_x++;
01290
for (
int i=1; i<l; i++, p_x++)
01291
sum =
logadd(
sum, *p_x);
01292
return sum;
01293 }
01294
01295
template<
class T>
01296 T
output_margin(
const TVec<T>& class_scores,
int correct_class)
01297 {
01298 T maxother = -FLT_MAX;
01299
for(
int i=0; i<class_scores.
length(); i++)
01300 {
01301
if(i!=correct_class && class_scores[i]>maxother)
01302 maxother = class_scores[i];
01303 }
01304
return class_scores[correct_class]-maxother;
01305 }
01306
01307
template<
class T>
01308 void fill_one_hot(
const TVec<T>& vec,
int hotpos, T coldvalue, T hotvalue)
01309 {
01310
#ifdef BOUNDCHECK
01311
if(!vec)
01312
PLERROR(
"In fill_one_hot given vec must have the correct size");
01313
if(hotpos<0 || (vec.
length()==1 && hotpos>1) || (vec.
length()>1 && hotpos>=vec.
length()))
01314
PLERROR(
"In fill_one_hot given hotpos out of vec range");
01315
#endif
01316
if(vec.
length()==1)
01317 vec[0] = (hotpos==0 ?coldvalue :hotvalue);
01318
else
01319 {
01320 vec.
fill(coldvalue);
01321 vec[hotpos] = hotvalue;
01322 }
01323 }
01324
01325
template<
class T>
01326 TVec<T> one_hot(
int length,
int hotpos, T coldvalue, T hotvalue)
01327 {
01328
TVec<T> result(length);
01329
fill_one_hot(result, hotpos, coldvalue, hotvalue);
01330
return result;
01331 }
01332
01333
template<
class T>
01334 TVec<T> square(
const TVec<T>& vec)
01335 {
01336
int n = vec.
length();
01337
TVec<T> result(n);
01338 T* v = vec.
data();
01339 T* r = result.
data();
01340
for(
int i=0; i<n; i++)
01341 r[i] = v[i]*v[i];
01342
return result;
01343 }
01344
01345
template<
class T>
01346 TVec<T> squareroot(
const TVec<T>& vec)
01347 {
01348
int n = vec.
length();
01349
TVec<T> result(n);
01350 T* v = vec.
data();
01351 T* r = result.
data();
01352
for(
int i=0; i<n; i++)
01353 r[i] =
sqrt(v[i]);
01354
return result;
01355 }
01356
01357
template<
class T>
01358 TVec<T> remove_missing(
const TVec<T>& vec)
01359 {
01360
int n = vec.
length();
01361
int n_non_missing = 0;
01362
TVec<T> result(n);
01363 T* v = vec.
data();
01364 T* r = result.
data();
01365
for(
int i=0; i<n; i++) {
01366
if (!
is_missing(v[i]))
01367 r[n_non_missing++] = v[i];
01368 }
01369 result.
resize(n_non_missing);
01370
return result;
01371 }
01372
01375
template<
class T,
class U,
class V>
01376 TVec<U> apply(
const TVec<T>& vec, U (*func)(V))
01377 {
01378
TVec<U> destination(vec.
length());
01379
apply(vec,destination,func);
01380
return destination;
01381 }
01382
01384
template<
class T,
class U>
01385 void apply(
const TVec<T>& source,
TVec<U>& destination, U (*func)(T))
01386 {
01387
int n=source.
length();
01388
if (n!=destination.
length())
01389
PLERROR(
"apply: source(%d) and destination(%d) TVec<T>'s must have same length",
01390 n,destination.
length());
01391 T* s = source.
data();
01392 U* d = destination.
data();
01393
for(
int i=0; i<n; i++)
01394 d[i]=func(s[i]);
01395 }
01396
01399
template<
class T,
class U,
class V>
01400 void apply(
const TVec<T>& src1,
const TVec<U>& src2,
TVec<V>& dest,
01401 V (*func)(T,U))
01402 {
01403
int n=src1.
length();
01404
if (n!=dest.
length() || n!=src2.
length())
01405
PLERROR(
"apply: src1, src2 and destination TVec<T>'s must have same length");
01406 T* s1 = src1.
data();
01407 U* s2 = src2.
data();
01408 V* d = dest.
data();
01409
for(
int i=0; i<n; i++)
01410 d[i]=func(s1[i],s2[i]);
01411 }
01412
01413
01414
01415
01416
01417
template<
class T>
01418 void multiply(
const TVec<T>& source1,
const TVec<T>& source2,
TVec<T>& destination)
01419 {
01420
int n=source1.
length();
01421
if (n!=source2.
length())
01422
PLERROR(
"multiply: two sources (l=%d and %d) must have same length",
01423 n,source2.
length());
01424
if (n!=destination.
length())
01425 destination.
resize(n);
01426 T* s1=source1.
data();
01427 T* s2=source2.
data();
01428 T* d=destination.
data();
01429
for (
int i=0;i<n;i++)
01430 d[i] = s1[i]*s2[i];
01431 }
01432
01433
01434
template<
class T>
01435 void multiplyAdd(
const TVec<T>& source1,
const TVec<T>& source2,
01436 T source3,
TVec<T>& destination)
01437 {
01438
int n=source1.
length();
01439
if (n!=source2.
length())
01440
PLERROR(
"multiply: two sources (l=%d and %d) must have same length",
01441 n,source2.
length());
01442
if (n!=destination.
length())
01443 destination.
resize(n);
01444 T* s1=source1.
data();
01445 T* s2=source2.
data();
01446 T* d=destination.
data();
01447
for (
int i=0;i<n;i++)
01448 d[i] = s1[i]+s2[i]*source3;
01449 }
01450
01451
01452
template<
class T>
01453 void multiplyScaledAdd(
const TVec<T>& source, T a, T b,
TVec<T>& destination)
01454 {
01455
int n=source.
length();
01456
if (n!=destination.
length())
01457
PLERROR(
"multiply: source and destination (l=%d and %d) must have same length",
01458 n,destination.
length());
01459 T* s=source.
data();
01460 T* d=destination.
data();
01461
for (
int i=0;i<n;i++)
01462 d[i] = a*d[i] + b*s[i];
01463 }
01464
01465
01466
template<
class T>
01467 void add(
const TVec<T>& source1,
const TVec<T>& source2,
TVec<T>& destination)
01468 {
01469
int n=source1.
length();
01470
if (n!=source2.
length())
01471
PLERROR(
"add: two sources (l=%d and %d) must have same length",
01472 n,source2.
length());
01473
if (n!=destination.
length())
01474 destination.
resize(n);
01475 T* s1=source1.
data();
01476 T* s2=source2.
data();
01477 T* d=destination.
data();
01478
for (
int i=0;i<n;i++)
01479 d[i] = s1[i]+s2[i];
01480 }
01481
01482
01483
template<
class T>
01484 void add(
const TVec<T>& source1, T source2,
TVec<T>& destination)
01485 {
01486
int n=source1.
length();
01487
if (n!=destination.
length())
01488 destination.
resize(n);
01489 T* s1=source1.
data();
01490 T* d=destination.
data();
01491
for (
int i=0;i<n;i++)
01492 d[i] = s1[i]+source2;
01493 }
01494
01495
template<
class T>
01496 inline void substract(
const TVec<T>& source1, T source2,
TVec<T>& destination)
01497 {
add(source1,-source2,destination); }
01498
01499
01500
template<
class T>
01501 void substract(
const TVec<T>& source1,
const TVec<T>& source2,
TVec<T>& destination)
01502 {
01503
int n=source1.
length();
01504
if (n!=source2.
length())
01505
PLERROR(
"substract: two sources (l=%d and %d) must have same length",
01506 n,source2.
length());
01507
if (n!=destination.
length())
01508 destination.
resize(n);
01509 T* s1=source1.
data();
01510 T* s2=source2.
data();
01511 T* d=destination.
data();
01512
for (
int i=0;i<n;i++)
01513 d[i] = s1[i]-s2[i];
01514 }
01515
01516
template<
class T>
01517 inline void divide(
const TVec<T>& source1, T source2,
TVec<T>& destination)
01518 {
multiply(source1,1.0/source2,destination); }
01519
01520
01521
template<
class T>
01522 void divide(
const TVec<T>& source1,
const TVec<T>& source2,
TVec<T>& destination)
01523 {
01524
int n=source1.
length();
01525
if (n!=source2.
length())
01526
PLERROR(
"divide: two sources (l=%d and %d) must have same length",
01527 n,source2.
length());
01528
if (n!=destination.
length())
01529 destination.
resize(n);
01530 T* s1=source1.
data();
01531 T* s2=source2.
data();
01532 T* d=destination.
data();
01533
for (
int i=0;i<n;i++)
01534 d[i] = s1[i]/s2[i];
01535 }
01536
01537
01538
template<
class T>
01539 void divide(T source1,
const TVec<T>& source2,
TVec<T>& destination)
01540 {
01541
int n=source2.
length();
01542
if (n!=destination.
length())
01543 destination.
resize(n);
01544 T* s2=source2.
data();
01545 T* d=destination.
data();
01546
for (
int i=0;i<n;i++)
01547 d[i] = source1/s2[i];
01548 }
01549
01550
01551
template<
class T>
01552 void max(
const TVec<T>& source1,
const TVec<T>& source2,
TVec<T>& destination)
01553 {
01554
int n=source1.
length();
01555
if (n!=source2.
length())
01556
PLERROR(
"max: two sources (l=%d and %d) must have same length",
01557 n,source2.
length());
01558
if (n!=destination.
length())
01559 destination.
resize(n);
01560 T* s1=source1.
data();
01561 T* s2=source2.
data();
01562 T* d=destination.
data();
01563
for (
int i=0;i<n;i++)
01564 d[i] =
MAX(s1[i],s2[i]);
01565 }
01566
01567
01568
template<
class T>
01569 void max(
const TVec<T>& source1, T source2,
TVec<T>& destination)
01570 {
01571
int n=source1.
length();
01572
if (n!=destination.
length())
01573 destination.
resize(n);
01574 T* s1=source1.
data();
01575 T* d=destination.
data();
01576
for (
int i=0;i<n;i++)
01577 d[i] =
MAX(s1[i],source2);
01578 }
01579
01580
01581
01582
template<
class T>
01583 void min(
const TVec<T>& source1,
const TVec<T>& source2,
TVec<T>& destination)
01584 {
01585
int n=source1.
length();
01586
if (n!=source2.
length())
01587
PLERROR(
"min: two sources (l=%d and %d) must have same length",
01588 n,source2.
length());
01589
if (n!=destination.
length())
01590 destination.
resize(n);
01591 T* s1=source1.
data();
01592 T* s2=source2.
data();
01593 T* d=destination.
data();
01594
for (
int i=0;i<n;i++)
01595 d[i] =
MIN(s1[i],s2[i]);
01596 }
01597
01598
01599
template<
class T>
01600 void min(
const TVec<T>& source1, T source2,
TVec<T>& destination)
01601 {
01602
int n=source1.
length();
01603
if (n!=destination.
length())
01604 destination.
resize(n);
01605 T* s1=source1.
data();
01606 T* d=destination.
data();
01607
for (
int i=0;i<n;i++)
01608 d[i] =
MIN(s1[i],source2);
01609 }
01610
01611
01612
template<
class T>
01613 TVec<T> softmax(
const TVec<T>& x)
01614 {
01615
TVec<T> y(
x.length());
01616
softmax(
x,y);
01617
return y;
01618 }
01619
01620
template<
class T>
01621 void tanh(
const TVec<T>& x,
TVec<T>& y)
01622 {
01623
int n =
x.length();
01624
#ifdef BOUNDCHECK
01625
if (y.
length()!=n)
01626
PLERROR(
"tanh(TVec<T>,TVec<T>), second argument of length %d, first of length %d, should be =",
01627 n,y.
length());
01628
#endif
01629
if (n>0)
01630 {
01631 T* yp = y.
data();
01632 T* xp =
x.data();
01633
for (
int i=0;i<n;i++)
01634 yp[i] =
tanh(xp[i]);
01635 }
01636 }
01637
01638
template<
class T>
01639 TVec<T> exp(
TVec<T> vec) {
return apply(vec,
safeexp); }
01640
01641
01642
template<
class T>
01643 TVec<T> nonZeroIndices(
TVec<T> v)
01644 {
01645
int n=v.
length();
01646
TVec<T> indices(n);
01647
int ni=0;
01648 T*
val = v.
data();
01649 T* indx= indices.
data();
01650
for (
int i=0;i<n;i++)
01651
if (
val[i]!=0)
01652 indx[ni++]=i;
01653 indices.
resize(ni);
01654
return indices;
01655 }
01656
01657
01658
template<
class T>
01659 TVec<T> nonZeroIndices(
TVec<bool> v)
01660 {
01661
int n=v.
length();
01662
TVec<T> indices(n);
01663
int ni=0;
01664
bool*
val = v.
data();
01665 T* indx= indices.
data();
01666
for (
int i=0;i<n;i++)
01667
if (
val[i])
01668 indx[ni++]=i;
01669 indices.
resize(ni);
01670
return indices;
01671 }
01672
01673
01674
01675
template<
class T>
01676 void complement_indices(
TVec<T>& indices,
int n,
01677
TVec<T>& complement_indices,
01678
TVec<T>& buffer)
01679 {
01680
int ni=indices.
length();
01681 T* ind = indices.
data();
01682 T* cind =
complement_indices.data();
01683 buffer.
resize(n);
01684 buffer.
fill(0);
01685 T* buf=buffer.
data();
01686
for (
int i=0;i<ni;i++)
01687 buf[(
int)ind[i]]=1.0;
01688
for (
int i=0,j=0;i<n;i++)
01689
if (buf[i]==0.0)
01690 cind[j++]=i;
01691 }
01692
01693
01694
template<
class T>
01695 void equals(
const TVec<T>& src, T v,
TVec<T>& dest)
01696 {
01697 T* s=src.
data();
01698 T* d=dest.
data();
01699
int n=src.
length();
01700
#ifdef BOUNDCHECK
01701
if (n!=dest.
length())
01702
PLERROR(
"equals(TVec<T>(%d),T,TVec<T>(%d)) args of unequal lengths",
01703 n,dest.
length());
01704
#endif
01705
for (
int i=0;i<n;i++)
01706
if (s[i]==v) d[i]=1.0;
else d[i]=0.0;
01707 }
01708
01709
01710
template<
class T>
01711 void isLargerThan(
const TVec<T>& first,
const TVec<T>& second,
TVec<T>& dest)
01712 {
01713 T* f=first.
data();
01714 T* s=second.
data();
01715 T* d=dest.
data();
01716
int n=first.
length();
01717
if(n!=second.
length() || n!=dest.
length())
01718
PLERROR(
"isLargerThan(TVec<T>(%d), TVec<T>(%d), TVec<T>(%d)) args of unequal length",
01719 n, second.
length(), dest.
length());
01720
for (
int i=0; i<n; i++)
01721 d[i] = f[i] > s[i];
01722 }
01723
01724
01725
template<
class T>
01726 void isLargerThanOrEqualTo(
const TVec<T>& first,
const TVec<T>& second,
TVec<T>& dest)
01727 {
01728 T* f=first.
data();
01729 T* s=second.
data();
01730 T* d=dest.
data();
01731
int n=first.
length();
01732
if(n!=second.
length() || n!=dest.
length())
01733
PLERROR(
"isLargerThan(TVec<T>(%d), TVec<T>(%d), TVec<T>(%d)) args of unequal length",
01734 n, second.
length(), dest.
length());
01735
for (
int i=0; i<n; i++)
01736 d[i] = f[i] >= s[i];
01737 }
01738
01739
01740
template<
class T>
01741 void isSmallerThan(
const TVec<T>& first,
const TVec<T>& second,
TVec<T>& dest)
01742 {
01743 T* f=first.
data();
01744 T* s=second.
data();
01745 T* d=dest.
data();
01746
int n=first.
length();
01747
if(n!=second.
length() || n!=dest.
length())
01748
PLERROR(
"isLargerThan(TVec<T>(%d), TVec<T>(%d), TVec<T>(%d)) args of unequal length",
01749 n, second.
length(), dest.
length());
01750
for (
int i=0; i<n; i++)
01751 d[i] = f[i] < s[i];
01752 }
01753
01754
01755
template<
class T>
01756 void isSmallerThanOrEqualTo(
const TVec<T>& first,
const TVec<T>& second,
TVec<T>& dest)
01757 {
01758 T* f=first.
data();
01759 T* s=second.
data();
01760 T* d=dest.
data();
01761
int n=first.
length();
01762
if(n!=second.
length() || n!=dest.
length())
01763
PLERROR(
"isLargerThan(TVec<T>(%d), TVec<T>(%d), TVec<T>(%d)) args of unequal length",
01764 n, second.
length(), dest.
length());
01765
for (
int i=0; i<n; i++)
01766 d[i] = f[i] <= s[i];
01767 }
01768
01769
01770
template<
class T>
01771 void ifThenElse(
const TVec<T>& if_vec,
const TVec<T>& then_vec,
const TVec<T>& else_vec,
TVec<T>& dest)
01772 {
01773 T* i_=if_vec.
data();
01774 T* t_=then_vec.
data();
01775 T* e_=else_vec.
data();
01776 T* d_=dest.
data();
01777
int n=if_vec.
length();
01778
if (n!=then_vec.
length() || n!=else_vec.
length())
01779
PLERROR(
"ifThenElse(TVec<T>(%d), TVec<T>(%d), TVec<T>(%d), TVec<T>(%d)) args of unequal lengths",
01780 n, then_vec.
length(), else_vec.
length(), dest.
length());
01781
for (
int i=0;i<n;i++)
01782 d_[i] = i_[i] ? t_[i] : e_[i];
01783 }
01784
01785
01786
template<
class T>
01787 int vec_counts(
const TVec<T>& src, T value)
01788 {
01789
int len = src.
length();
01790
int n = 0;
01791 T *p = src.
data();
01792
for (
int i=0; i<len; i++, p++)
01793
if (*p == value)
01794 n++;
01795
return n;
01796 }
01797
01798
01799
template<
class T>
01800 int vec_find(
const TVec<T>& src, T f)
01801 {
01802
int len = src.
length();
01803 T *p = src.
data();
01804
for (
int i=0; i<len; i++, p++)
01805
if (*p == f)
01806
return(i);
01807
return -1;
01808 }
01809
01810
01811
template<
class T>
01812 T
estimatedCumProb(T x,
TVec<T> bins)
01813 {
01814
const int nbins = bins.
length()-1;
01815
if (nbins<1)
PLERROR(
"estimatedCumProb:: there should be at least two elements in the bins vector");
01816
01817
const T one_over_nbins = 1.0/(T)(nbins+0.5);
01818
01819
int k =
binary_search(bins,
x);
01820
01821
if (
k == -1)
01822
return 0.25*one_over_nbins;
01823
else if (
k == nbins-1)
01824
return 1.0 - 0.25*one_over_nbins;
01825
else if (bins[
k] != bins[
k+1])
01826
return one_over_nbins*(0.25 +
k + (
x-bins[
k])/(bins[
k+1]-bins[
k]));
01827
else
01828
return one_over_nbins*(0.75 +
k);
01829 }
01830
01831
01832
01833
template<
class T>
01834 int positionOfkthOrderedElement(
const TVec<T>& vec,
int k)
01835 {
01836
#ifdef BOUNDCHECK
01837
if(k<0 || k>=vec.
length())
01838
PLERROR(
"In positionOfkthOrderedElement, k out of bounds");
01839
#endif
01840
01841 T* v = vec.
data();
01842
01843 T minval = -FLT_MAX;
01844
int pos = -1;
01845
int l=0;
01846
01847
while(l<=
k)
01848 {
01849
int nelements_equal_to_newminval = 0;
01850 T newminval = FLT_MAX;
01851
for(
int i=0; i<vec.
length(); i++)
01852 {
01853
if(v[i]>minval)
01854 {
01855
if(v[i]<newminval)
01856 {
01857 newminval = v[i];
01858 nelements_equal_to_newminval = 1;
01859 pos = i;
01860 }
01861
else if(v[i]==newminval)
01862 nelements_equal_to_newminval++;
01863 }
01864 }
01865 l += nelements_equal_to_newminval;
01866 minval = newminval;
01867 }
01868
01869
return pos;
01870 }
01871
01874
template<
class T>
01875 inline T
kthOrderedElement(
const TVec<T>& vec,
int k)
01876 {
return vec[
positionOfkthOrderedElement(vec,
k)]; }
01877
01879
template<
class T>
01880 inline T
median(
const TVec<T>& vec)
01881 {
return kthOrderedElement(vec, (vec.
length()-1)/2); }
01882
01883
01884
01885
01886
01889
template<
class T>
01890 T
selectAndOrder(
const TVec<T>& vec,
int pos)
01891 {
01892
if (pos<0 || pos>=vec.
length())
PLERROR(
"Bad position (%d)", pos);
01893
01894
int l=0;
01895
int h=vec.
length()-1;
01896 T* v = vec.
data();
01897
01898
while (l<h)
01899 {
01900 T p = v[(l+h)/2];
01901
int x = l;
01902
int y = h;
01903
01904
do
01905 {
01906
while (v[
x]<p)
x++;
01907
while (p<v[y]) y--;
01908
if (
x<=y)
01909 {
01910
PLearn::swap(v[
x],v[y]);
01911
x++;
01912 y--;
01913 }
01914 }
while (
x<=y);
01915
01916
if (pos>=
x) l=
x;
01917
else h=
x-1;
01918 }
01919
01920
return v[l];
01921 }
01922
01927
template<
class T>
01928 TVec<T> getQuantiles(
const TVec<T>& vec,
int q)
01929 {
01930
int l = vec.
length();
01931 T* v = vec.
data();
01932
TVec<T> w(q+1);
01933 T linvq = T(l)/q;
01934
for(
int i=0;i<q;i++) w[i] = v[
int(linvq*i)];
01935 w[q]=v[l-1];
01936
return w;
01937 }
01938
01941
template<
class T>
01942 TVec<T> nonZero(
const TVec<T>& vec)
01943 {
01944 T *v =vec.
data();
01945
int n=0;
01946
for(
int i=0;i<vec.
length(); i++)
if (v[i]!=0) n++;
01947
TVec<T> w(n);
01948
int j=0;
01949
for(
int i=0;i<vec.
length(); i++)
if (v[i]!=0) w[j++]=v[i];
01950
return(w);
01951 }
01952
01955
template<
class T>
01956 TVec<T> positiveValues(
const TVec<T>& vec)
01957 {
01958 T *v =vec.
data();
01959
int n=0;
01960
for(
int i=0;i<vec.
length(); i++)
if (v[i]>0) n++;
01961
TVec<T> w(n);
01962
int j=0;
01963
for(
int i=0;i<vec.
length(); i++)
if (v[i]>0) w[j++]=v[i];
01964
return(w);
01965 }
01966
01971
template<
class T>
01972 int positionOfClosestElement(
const TVec<T>& vec,
const T& value,
bool is_sorted_vec=
false)
01973 {
01974 T* v = vec.
data();
01975
if (is_sorted_vec)
01976 {
01977
int pos =
binary_search(vec, value);
01978
if (pos == -1)
return 0;
01979
else if (pos == vec.
length()-1)
return pos;
01980 T dist1 = fabs(v[pos]-value);
01981 T dist2 = fabs(v[pos+1]-value);
01982
if (dist1 <= dist2)
return pos;
01983
else return pos+1;
01984 }
01985
else
01986 {
01987
int pos_of_closest = 0;
01988 T dist_to_closest = fabs(v[0]-value);
01989
for(
int i=1; i<vec.
length(); i++)
01990 {
01991 T
dist = fabs(v[i]-value);
01992
if(
dist<dist_to_closest)
01993 {
01994 pos_of_closest = i;
01995 dist_to_closest =
dist;
01996 }
01997 }
01998
return pos_of_closest;
01999 }
02000 }
02001
02002
02009
template <
class T>
02010 void projectOnOrthogonalSubspace(
const TVec<T>& vec,
const TMat<T>& orthonormal_subspace)
02011 {
02012
for (
int i=0;i<orthonormal_subspace.
length();i++)
02013 {
02014
TVec<T> vi = orthonormal_subspace(i);
02015 T dp =
dot(vec,vi);
02016
multiplyAcc(vec, vi,-dp);
02017 }
02018 }
02019
02020
template<
class T>
02021 void operator*=(
const TVec<T>& vec, T factor)
02022 {
02023 T* p = vec.
data();
02024
int l = vec.
length();
02025
for (
int i=0;i<l;i++)
02026 *p++ *= factor;
02027 }
02028
02030
template<
class T>
02031 inline void operator+=(
const TVec<T>& vec1,
const TVec<T>& vec2)
02032 {
02033 T* v1 = vec1.
data();
02034 T* v2 = vec2.
data();
02035
int l = vec1.
length();
02036
for(
int i=0; i<l; i++)
02037 *v1++ += *v2++;
02038 }
02039
02040
02042
template<
class T>
02043 void multiplyAcc(
const TVec<T>& vec,
const TVec<T>& x, T scale)
02044 {
02045
int n=
x.length();
02046
if (vec.
length()!=n)
02047
PLERROR(
"TVec::multiplyAcc this has length_=%d and x has length_=%d", vec.
length(),n);
02048 T* p=vec.
data();
02049 T* xp=
x.data();
02050
for (
int i=0;i<n;i++)
02051 *p++ += scale * *xp++;
02052 }
02053
02055
template<
class T>
02056 void exponentialMovingAverageUpdate(
const TVec<T>& vec,
const TVec<T>& x, T alpha)
02057 {
02058
int n=
x.length();
02059
if (vec.
length()!=n)
02060
PLERROR(
"TVec::exponentialMovingAverageUpdate length_=%d and x has length_=%d",
02061 vec.
length(),n);
02062 T* p=vec.
data();
02063 T* xp=
x.data();
02064 T one_minus_alpha = 1-alpha;
02065
for (
int i=0;i<n;i++)
02066 p[i] = one_minus_alpha*p[i] + alpha*xp[i];
02067 }
02068
02070
template<
class T>
02071 void exponentialMovingVarianceUpdate(
const TVec<T>& vec,
const TVec<T>& x,
const TVec<T>& mu, T alpha)
02072 {
02073
int n=
x.length();
02074
if (vec.
length()!=n || vec.
length()!=mu.
length())
02075
PLERROR(
"TVec::exponentialVarianceAverageUpdate length_=%d and"
02076
"x has length_=%d, mu has length() %d",
02077 vec.
length(),n,mu.
length());
02078 T* p=vec.
data();
02079 T* xp=
x.data();
02080 T* mp=mu.
data();
02081 T one_minus_alpha = 1-alpha;
02082
for (
int i=0;i<n;i++)
02083 {
02084 T dif = (xp[i]-mp[i]);
02085 p[i] = one_minus_alpha*p[i] + alpha*dif*dif;
02086 }
02087 }
02088
02089
02091
template<
class T>
02092 void exponentialMovingSquareUpdate(
const TVec<T>& vec,
const TVec<T>& x, T alpha)
02093 {
02094
int n=
x.length();
02095
if (vec.
length()!=n)
02096
PLERROR(
"TVec::exponentialMovingAverageUpdate length_=%d and x has length_=%d",
02097 vec.
length(),n);
02098 T* p=vec.
data();
02099 T* xp=
x.data();
02100 T one_minus_alpha = 1-alpha;
02101
for (
int i=0;i<n;i++)
02102 {
02103 T xpi = xp[i];
02104 p[i] = one_minus_alpha*p[i] + alpha*xpi*xpi;
02105 }
02106 }
02107
02109
template<
class T>
02110 void multiplyAcc(
const TVec<T>& vec,
const TVec<T>& x,
const TVec<T>& y)
02111 {
02112
int n=
x.length();
02113
if (vec.
length()!=n || y.
length()!=n)
02114
PLERROR(
"TVec::multiplyAcc, this+=x*y: length_=%d, x.length_=%d, y.length_=%d",
02115 vec.
length(),n,y.
length());
02116 T* p=vec.
data();
02117 T* xp=
x.data();
02118 T* yp=y.
data();
02119
for (
int i=0;i<n;i++)
02120 p[i] += xp[i] * yp[i];
02121 }
02122
02124
template<
class T>
02125 void squareMultiplyAcc(
const TVec<T>& vec,
const TVec<T>& x, T scale)
02126 {
02127
int n=
x.length();
02128
if (vec.
length()!=n)
02129
PLERROR(
"TVec::squareMultiplyAcc this has length_=%d and x has length_=%d", vec.
length(),n);
02130 T* p=vec.
data();
02131 T* xp=
x.data();
02132
for (
int i=0;i<n;i++)
02133 {
02134 T xpi = xp[i];
02135 p[i] += scale * xpi * xpi;
02136 }
02137 }
02138
02140
template<
class T>
02141 void squareAcc(
const TVec<T>& vec,
const TVec<T>& x)
02142 {
02143
int n=
x.length();
02144
if (vec.
length()!=n)
02145
PLERROR(
"TVec::squareAcc this has length_=%d and x has length_=%d", vec.
length(),n);
02146 T* p=vec.
data();
02147 T* xp=
x.data();
02148
for (
int i=0;i<n;i++)
02149 {
02150 T xpi = xp[i];
02151 p[i] += xpi * xpi;
02152 }
02153 }
02154
02156
template<
class T>
02157 void squareSubtract(
const TVec<T>& vec,
const TVec<T>& x)
02158 {
02159
int n=
x.length();
02160
if (vec.
length()!=n)
02161
PLERROR(
"TVec::squareDiff this has length_=%d and x has length_=%d", vec.
length(),n);
02162 T* p=vec.
data();
02163 T* xp=
x.data();
02164
for (
int i=0;i<n;i++)
02165 {
02166 T xpi = xp[i];
02167 p[i] -= xpi * xpi;
02168 }
02169 }
02170
02172
template<
class T>
02173 void diffSquareMultiplyAcc(
const TVec<T>& vec,
const TVec<T>& x,
const TVec<T>& y, T scale)
02174 {
02175
int n=
x.length();
02176
if (vec.
length()!=n || y.
length()!=n)
02177
PLERROR(
"TVec::diffSquareMultiplyAcc this.length_=%d, x.length_=%d, y.length_=%d",
02178 vec.
length(),n,y.
length());
02179 T* p=vec.
data();
02180 T* xp=
x.data();
02181 T* yp=y.
data();
02182
for (
int i=0;i<n;i++)
02183 {
02184 T diff = xp[i]-yp[i];
02185 p[i] += scale * diff * diff;
02186 }
02187 }
02188
02190
template<
class T>
02191 void diffSquareMultiplyScaledAcc(
const TVec<T>& vec,
const TVec<T>& x,
const TVec<T>& y, T fact1, T fact2)
02192 {
02193
int n=
x.length();
02194
if (vec.
length()!=n || y.
length()!=n)
02195
PLERROR(
"TVec::diffSquareMultiplyAcc this.length_=%d, x.length_=%d, y.length_=%d",
02196 vec.
length(),n,y.
length());
02197 T* p=vec.
data();
02198 T* xp=
x.data();
02199 T* yp=y.
data();
02200
for (
int i=0;i<n;i++)
02201 {
02202 T diff = xp[i]-yp[i];
02203 p[i] = fact1 * p[i] + fact2 * diff * diff;
02204 }
02205 }
02206
02208
template <
class T>
02209 void product(
const TVec<T>& result,
const TMat<T>& m,
const TVec<T>& v)
02210 {
02211
int l=m.
width();
02212
if (l!=v.
length() || m.
length()!=result.
length())
02213
PLERROR(
"product(TVec, TMat,TVec), incompatible arguments %dx%d times %d -> %d",
02214 m.
length(),m.
width(), v.
length(),result.
length());
02215 T *rp = result.
data();
02216 T *vp = v.
data();
02217
for (
int i=0;i<result.
length();i++)
02218 {
02219
const T* mi = m[i];
02220 T s = 0;
02221
for (
int j=0;j<l;j++)
02222 s += mi[j] * vp[j];
02223 rp[i] = s;
02224 }
02225 }
02226
02228
template <
class T>
02229 void productAcc(
const TVec<T>& vec,
const TMat<T>& m,
const TVec<T>& v)
02230 {
02231
int l = m.
length();
02232
int w = m.
width();
02233
#ifdef BOUNDCHECK
02234
if (w!=v.
length() || l!=vec.
length())
02235
PLERROR(
"TVec::productAcc(TMat,TVec), incompatible arguments %dx%d times %d -> %d",
02236 m.
length(),m.
width(), v.
length(),vec.
length());
02237
#endif
02238
T* rp = vec.
data();
02239 T* mp = m.
data();
02240 T* vdata = v.
data();
02241
int deltam = m.
mod()-m.
width();
02242
for (
int i=0;i<l;i++)
02243 {
02244 T *vp = vdata;
02245 T s = *rp;
02246
for (
int j=0;j<w;j++)
02247 s += *mp++ * *vp++;
02248 *rp++ = s;
02249 mp += deltam;
02250 }
02251 }
02252
02256
template <
class T>
02257 void transposeProduct(
const TVec<T>& result,
const TMat<T>& m,
const TVec<T>& v)
02258 {
02259
int l=m.
length();
02260
if (l!=v.
length() || m.
width()!=result.
length())
02261
PLERROR(
"TVec::transposeProduct(TMat,TVec), incompatible arguments %dx%d' times %d -> %d",
02262 m.
length(),m.
width(), v.
length(),result.
length());
02263 T *rp = result.
data();
02264 T *vp = v.
data();
02265 result.
clear();
02266
for (
int j=0;j<l;j++)
02267 {
02268
const T* mj = m[j];
02269 T vj = vp[j];
02270
for (
int i=0;i<result.
length();i++)
02271 rp[i] += mj[i] * vj;
02272 }
02273 }
02274
02276
template <
class T>
02277 void transposeProductAcc(
const TVec<T>& result,
const TMat<T>& m,
const TVec<T>& v)
02278 {
02279
int l=m.
length();
02280
int w=m.
width();
02281
if (l!=v.
length() || w!=result.
length())
02282
PLERROR(
"TVec::transposeProductAcc(TMat,TVec), incompatible arguments %dx%d' times %d -> %d",
02283 m.
length(),m.
width(), v.
length(),result.
length());
02284 T* vecdata = result.
data();
02285 T* vp = v.
data();
02286 T* mp = m.
data();
02287
int deltam = m.
mod()-m.
width();
02288
for (
int j=0;j<l;j++)
02289 {
02290 T vj = *vp++;
02291
02292
02293
02294
02295
02296
02297
02298
02299
if(vj!=0)
02300 {
02301
if(vj==1)
02302 {
02303 T* rp = vecdata;
02304
for (
int i=0;i<w;i++)
02305 *rp++ += *mp++;
02306 mp += deltam;
02307 }
02308
else
02309 {
02310 T* rp = vecdata;
02311
for (
int i=0;i<w;i++)
02312 *rp++ += vj * *mp++;
02313 mp += deltam;
02314 }
02315 }
02316
else mp += w + deltam;
02317 }
02318 }
02319
02321
template <
class T>
02322 void transposeProductAcc(
const TVec<T>& result,
const TMat<T>& m,
const TVec<T>& v, T alpha)
02323 {
02324
int l=m.
length();
02325
int w=m.
width();
02326
if (l!=v.
length() || w!=result.
length())
02327
PLERROR(
"TVec::transposeProductAcc(TMat,TVec), incompatible arguments %dx%d' times %d -> %d",
02328 m.
length(),m.
width(), v.
length(),result.
length());
02329 T* vecdata = result.
data();
02330 T* vp = v.
data();
02331 T* mp = m.
data();
02332
int deltam = m.
mod()-m.
width();
02333
for (
int j=0;j<l;j++)
02334 {
02335 T vj = *vp++;
02336
02337
02338
02339
02340
02341
02342
02343
02344
if(vj!=0)
02345 {
02346
if(vj==1)
02347 {
02348 T* rp = vecdata;
02349
for (
int i=0;i<w;i++)
02350 *rp++ += alpha * *mp++;
02351 mp += deltam;
02352 }
02353
else
02354 {
02355 T* rp = vecdata;
02356
for (
int i=0;i<w;i++)
02357 *rp++ += alpha * vj * *mp++;
02358 mp += deltam;
02359 }
02360 }
02361
else mp += w + deltam;
02362 }
02363 }
02364
02365
template <
class T>
02366 void compressedTransposeProductAcc(
const TVec<T>& result,
const TMat<T>& m,
char* comprbufvec)
02367 {
02368 cout<<
"using kasjdlkadja"<<
endl;
02369
union {
double d;
char c[8]; } uni;
02370
int l=m.
length(),n, idx=0;
02371
unsigned char mode;
02372 cout<<
"l="<<l<<
endl;
02373
for(
int i=0;i<l;i++)
02374 cout<<i<<
":"<<char(comprbufvec[i])<<
endl;
02375
while(l>0)
02376 {
02377
read_compr_mode_and_size_ptr(comprbufvec,
mode, n);
02378
if(
mode==0 ||
mode==1)
02379 {
02380 idx+=n;
02381 cout<<
"0x"<<n<<
" ";
02382 l-=n;
02383
if(
mode==1)
02384 {
02385 --l;
02386 result+=m(idx++);
02387 cout<<
"1 ";
02388 }
02389 }
02390
else if(
mode==2)
02391 {
02392
while(n--)
02393 {
02394 cout<<double(*comprbufvec)<<
" "<<
endl;
02395 result+= m(idx++) * double(*comprbufvec++);
02396
02397 --l;
02398 }
02399 }
02400
else if(
mode==3)
02401 {
02402
while(n--)
02403 {
02404 memcpy(uni.c,comprbufvec,
sizeof(
double));
02405 cout<<double(uni.d)<<
" "<<
endl;
02406 comprbufvec+=8;
02407 result+= m(idx++) * uni.d;
02408 --l;
02409 }
02410 }
02411
else
02412
PLERROR(
"BUG IN binread_compressed: mode is only 2 bits, so how can it be other than 0,1,2,3 ?");
02413 }
02414
02415
if(l!=0)
02416
PLERROR(
"In compressed_dot_product : l is not 0 at exit of function, wrong data?");
02417 }
02418
02420
template<
class T>
02421 void diagonalizedFactorsProduct(
TMat<T>& result,
const TMat<T>& U,
const TVec<T> d,
const TMat<T> V,
bool accumulate=
false)
02422 {
02423
#ifdef BOUNDCHECK
02424
if (result.
length()!=U.
length() || result.
width()!=V.
width() || U.
width()!=d.
length() || V.
length()!=d.
length())
02425
PLERROR(
"diagonalizedFactorsProduct: incompatible arguments: (%dx%d)*(%d)*(%dx%d) --> (%dx%d)",
02426 U.
length(),U.
width(),d.
length(),V.
length(),V.
width(),result.
length(),result.
width());
02427
#endif
02428
int n1=U.
length();
02429
int n2=U.
width();
02430
int n3=V.
width();
02431 T *r_ij = result.
data();
02432
for (
int i=0;i<n1;i++)
02433 {
02434 T *u_i = U[i];
02435
for (
int j=0;j<n3;j++,r_ij++)
02436 {
02437 T* d_k = d.
data();
02438 T res=0;
02439
for (
int k=0;
k<n2;
k++,d_k++)
02440 res += *d_k * u_i[
k] * V(
k,j);
02441
if (accumulate)
02442 *r_ij += res;
02443
else
02444 *r_ij = res;
02445 }
02446 }
02447 }
02448
02454
template<
class T>
02455 void diagonalizedFactorsProductBprop(
const TMat<T>& dCdresult,
const TMat<T>& U,
const TVec<T> d,
02456
const TMat<T> V,
TMat<T>& dCdU,
TVec<T>& dCdd,
TMat<T>& dCdV)
02457 {
02458
#ifdef BOUNDCHECK
02459
if (dCdU.
length()!=U.
length() || dCdU.
width()!=U.
width() || dCdd.
length()!=d.
length()
02460 || dCdV.
length()!=V.
length() || dCdV.
width()!=V.
width() ||
02461 U.
width()!=d.
length() || V.
length()!=d.
length())
02462
PLERROR(
"diagonalizedFactorsProductBprop: incompatible arguments");
02463
#endif
02464
int n1=U.
length();
02465
int n2=U.
width();
02466
int n3=V.
width();
02467 T *dCdr_ij = dCdresult.
data();
02468
for (
int i=0;i<n1;i++)
02469 {
02470 T *u_i = U[i];
02471 T *dCdu_i = dCdU[i];
02472
for (
int j=0;j<n3;j++,dCdr_ij++)
02473 {
02474 T dcdr = *dCdr_ij;
02475 T* d_k = d.
data();
02476 T* dCdd_k = dCdd.
data();
02477
for (
int k=0;
k<n2;
k++,d_k++,dCdd_k++)
02478 {
02479 T dk = *d_k;
02480 T u_ik = u_i[
k];
02481 T v_kj = V(
k,j);
02482 dCdu_i[
k] += dcdr * dk * v_kj;
02483 *dCdd_k += dcdr * u_ik * v_kj;
02484 dCdV(
k,j) += dk * u_ik * dcdr;
02485 }
02486 }
02487 }
02488 }
02489
02491
template<
class T>
02492 void diagonalizedFactorsProductTranspose(
TMat<T>& result,
const TMat<T>& U,
const TVec<T> d,
const TMat<T> V,
bool accumulate=
false)
02493 {
02494
#ifdef BOUNDCHECK
02495
if (result.
length()!=U.
length() || result.
width()!=V.
length() || U.
width()!=d.
length() || V.
width()!=d.
length())
02496
PLERROR(
"diagonalizedFactorsProductTranspose: incompatible arguments: (%dx%d)*(%d)*(%dx%d)' --> (%dx%d)",
02497 U.
length(),U.
width(),d.
length(),V.
length(),V.
width(),result.
length(),result.
width());
02498
#endif
02499
int n1=U.
length();
02500
int n2=U.
width();
02501
int n3=V.
length();
02502 T *r_ij = result.
data();
02503
for (
int i=0;i<n1;i++)
02504 {
02505 T *u_i = U[i];
02506
for (
int j=0;j<n3;j++,r_ij++)
02507 {
02508 T* d_k = d.
data();
02509 T* v_j = V[j];
02510 T res=0;
02511
for (
int k=0;
k<n2;
k++,d_k++)
02512 res += *d_k * u_i[
k] * v_j[
k];
02513
if (accumulate)
02514 *r_ij += res;
02515
else
02516 *r_ij = res;
02517 }
02518 }
02519 }
02520
02521
02522
02523
02524
02525
02526
template<
class T>
02527 void diagonalizedFactorsProductTransposeBprop(
const TMat<T>& dCdresult,
const TMat<T>& U,
02528
const TVec<T> d,
const TMat<T> V,
TMat<T>& dCdU,
02529
TVec<T>& dCdd,
TMat<T>& dCdV)
02530 {
02531
#ifdef BOUNDCHECK
02532
if (dCdU.
length()!=U.
length() || dCdU.
width()!=U.
width() || dCdd.
length()!=d.
length()
02533 || dCdV.
length()!=V.
length() || dCdV.
width()!=V.
width() ||
02534 U.
width()!=d.
length() || V.
width()!=d.
length())
02535
PLERROR(
"diagonalizedFactorsProductTransposeBprop: incompatible arguments");
02536
#endif
02537
int n1=U.
length();
02538
int n2=U.
width();
02539
int n3=V.
length();
02540 T *dCdr_ij = dCdresult.
data();
02541
for (
int i=0;i<n1;i++)
02542 {
02543 T *u_i = U[i];
02544 T *dCdu_i = dCdU[i];
02545
for (
int j=0;j<n3;j++,dCdr_ij++)
02546 {
02547 T* d_k = d.
data();
02548 T* dCdd_k = dCdd.
data();
02549 T* v_j = V[j];
02550 T* dCdv_j = dCdV[j];
02551
for (
int k=0;
k<n2;
k++,d_k++,dCdd_k++)
02552 {
02553 T dcdr = *dCdr_ij;
02554 T dk = *d_k;
02555 T v_jk = v_j[
k];
02556 T u_ik = u_i[
k];
02557 dCdu_i[
k] += dcdr * dk * v_jk;
02558 *dCdd_k += dcdr * u_ik * v_jk;
02559 dCdv_j[
k] += dcdr * dk * u_ik;
02560 }
02561 }
02562 }
02563 }
02564
02566
template<
class T>
02567 void diagonalizedFactorsTransposeProduct(
TMat<T>& result,
const TMat<T>& U,
const TVec<T> d,
const TMat<T> V,
bool accumulate=
false)
02568 {
02569
#ifdef BOUNDCHECK
02570
if (result.
length()!=U.
width() || result.
width()!=V.
width() || U.
length()!=d.
length() || V.
length()!=d.
length())
02571
PLERROR(
"diagonalizedFactorsTransposeProduct: incompatible arguments: (%dx%d)'*(%d)*(%dx%d) --> (%dx%d)",
02572 U.
length(),U.
width(),d.
length(),V.
length(),V.
width(),result.
length(),result.
width());
02573
#endif
02574
int n1=U.
width();
02575
int n2=U.
length();
02576
int n3=V.
width();
02577
if (!accumulate)
02578 result.
clear();
02579 T* d_k = d.
data();
02580
for (
int k=0;
k<n2;
k++,d_k++)
02581 {
02582 T *u_k = U[
k];
02583 T *v_k = V[
k];
02584 T *r_ij = result.
data();
02585
for (
int i=0;i<n1;i++)
02586 {
02587 T u_ki = u_k[i];
02588
for (
int j=0;j<n3;j++,r_ij++)
02589 *r_ij += *d_k * u_ki * v_k[j];
02590 }
02591 }
02592 }
02593
02594
02595
02596
02597
02598
02599
template<
class T>
02600 void diagonalizedFactorsTransposeProductBprop(
const TMat<T>& dCdresult,
const TMat<T>& U,
02601
const TVec<T> d,
const TMat<T> V,
TMat<T>& dCdU,
02602
TVec<T>& dCdd,
TMat<T>& dCdV)
02603 {
02604
#ifdef BOUNDCHECK
02605
if (dCdU.
length()!=U.
length() || dCdU.
width()!=U.
width() || dCdd.
length()!=d.
length()
02606 || dCdV.
length()!=V.
length() || dCdV.
width()!=V.
width() ||
02607 U.
length()!=d.
length() || V.
length()!=d.
length())
02608
PLERROR(
"diagonalizedFactorsTransposeProductBprop: incompatible arguments");
02609
#endif
02610
int n1=U.
width();
02611
int n2=U.
length();
02612
int n3=V.
width();
02613 T* d_k = d.
data();
02614 T* dCdd_k = dCdd.
data();
02615
for (
int k=0;
k<n2;
k++,d_k++,dCdd_k++)
02616 {
02617 T dk = *d_k;
02618 T *u_k = U[
k];
02619 T *dCdu_k = dCdU[
k];
02620 T *v_k = V[
k];
02621 T *dCdv_k = dCdV[
k];
02622 T *dCdr_ij = dCdresult.
data();
02623
for (
int i=0;i<n1;i++)
02624 {
02625 T u_ki = u_k[i];
02626 T& dCdu_ki = dCdu_k[i];
02627
for (
int j=0;j<n3;j++,dCdr_ij++)
02628 {
02629 T dcdr = *dCdr_ij;
02630 T v_kj = v_k[j];
02631 dCdu_ki += dcdr * dk * v_kj;
02632 *dCdd_k += dcdr * u_ki * v_kj;
02633 dCdv_k[j] += dcdr * dk * u_ki;
02634 }
02635 }
02636 }
02637 }
02638
02640
template<
class T>
02641 void diagonalizedFactorsTransposeProductTranspose(
TMat<T>& result,
const TMat<T>& U,
const TVec<T> d,
const TMat<T> V,
bool accumulate=
false)
02642 {
02643
#ifdef BOUNDCHECK
02644
if (result.
length()!=U.
width() || result.
width()!=V.
length() || U.
length()!=d.
length() || V.
width()!=d.
length())
02645
PLERROR(
"diagonalizedFactorsTransposeProductTranspose: incompatible arguments: (%dx%d)'*(%d)*(%dx%d)' --> (%dx%d)",
02646 U.
length(),U.
width(),d.
length(),V.
length(),V.
width(),result.
length(),result.
width());
02647
#endif
02648
int n1=U.
width();
02649
int n2=U.
length();
02650
int n3=V.
length();
02651
if (!accumulate)
02652 result.
clear();
02653 T* d_k = d.
data();
02654
for (
int k=0;
k<n2;
k++,d_k++)
02655 {
02656 T *u_k = U[
k];
02657 T *r_ij = result.
data();
02658
for (
int i=0;i<n1;i++)
02659 {
02660 T u_ki = u_k[i];
02661
for (
int j=0;j<n3;j++,r_ij++)
02662 *r_ij += *d_k * u_ki * V(j,
k);
02663 }
02664 }
02665 }
02666
02667
02668
02669
02670
02671
02672
template<
class T>
02673 void diagonalizedFactorsTransposeProductTransposeBprop(
const TMat<T>& dCdresult,
const TMat<T>& U,
02674
const TVec<T> d,
const TMat<T> V,
TMat<T>& dCdU,
02675
TVec<T>& dCdd,
TMat<T>& dCdV)
02676 {
02677
#ifdef BOUNDCHECK
02678
if (dCdU.
length()!=U.
length() || dCdU.
width()!=U.
width() || dCdd.
length()!=d.
length()
02679 || dCdV.
length()!=V.
length() || dCdV.
width()!=V.
width() ||
02680 U.
length()!=d.
length() || V.
width()!=d.
length())
02681
PLERROR(
"diagonalizedFactorsTransposeProductTransposeBprop: incompatible arguments");
02682
#endif
02683
int n1=U.
width();
02684
int n2=U.
length();
02685
int n3=V.
length();
02686 T* d_k = d.
data();
02687 T* dCdd_k = dCdd.
data();
02688
for (
int k=0;
k<n2;
k++,d_k++,dCdd_k++)
02689 {
02690 T dk = *d_k;
02691 T *u_k = U[
k];
02692 T *dCdu_k = dCdU[
k];
02693 T *dCdr_ij = dCdresult.
data();
02694
for (
int i=0;i<n1;i++)
02695 {
02696 T u_ki = u_k[i];
02697 T& dCdu_ki = dCdu_k[i];
02698
for (
int j=0;j<n3;j++,dCdr_ij++)
02699 {
02700 T dcdr = *dCdr_ij;
02701 T v_jk = V(j,
k);
02702 dCdu_ki += dcdr * dk * v_jk;
02703 *dCdd_k += dcdr * u_ki * v_jk;
02704 dCdV(j,
k) += dcdr * dk * u_ki;
02705 }
02706 }
02707 }
02708 }
02709
02710
02711
02713
template<
class T>
02714 T
matRowDotVec(
const TMat<T>& mat,
int i,
const TVec<T> v)
02715 {
02716
#ifdef BOUNDCHECK
02717
if (v.
length()!=mat.
width())
02718
PLERROR(
"dotRow(%d,v), v.length_=%d != matrix width_=%d",
02719 i,v.
length(),mat.
width());
02720
#endif
02721
T s = 0;
02722 T* rowi = mat.
rowdata(i);
02723 T* v_=v.
data();
02724
for (
int j=0;j<mat.
width();j++)
02725 s += rowi[j] * v_[j];
02726
return s;
02727 }
02728
02730
template<
class T>
02731 T
matColumnDotVec(
const TMat<T>& mat,
int j,
const TVec<T> v)
02732 {
02733
#ifdef BOUNDCHECK
02734
if (v.
length()!=mat.
length())
02735
PLERROR(
"dotColumn(%d,v), v.length_=%d != matrix length_=%d",
02736 j,v.
length(),mat.
length());
02737
#endif
02738
T s = 0;
02739 T* colj = mat.
data()+j;
02740 T* v_=v.
data();
02741
for (
int i=0;i<mat.
length();i++, colj+=mat.
mod())
02742 s += *colj * v_[i];
02743
return s;
02744 }
02745
02747
template<
class T>
02748 void matRowsDots(
TVec<T> v,
const TMat<T>& A,
const TMat<T>& B)
02749 {
02750
#ifdef BOUNDCHECK
02751
if (A.
length()!=v.
length())
02752
PLERROR(
"matRowDotsVec(v,A,B): v.length_=%d != A.length_=%d",
02753 v.
length(),A.
length());
02754
if (A.
length()!=B.
length())
02755
PLERROR(
"matRowDotsVec(v,A,B): A.length_=%d != B.length_=%d",
02756 A.
length(),B.
length());
02757
if (A.
width()!=B.
width())
02758
PLERROR(
"matRowDotsVec(v,A,B): A.width_=%d != B.width_=%d",
02759 A.
width(),B.
width());
02760
#endif
02761
int l=A.
length(), w=A.
width();
02762 T* vi = v.
data();
02763
for (
int i=0;i<l;i++)
02764 {
02765 T s = 0;
02766 T* Aij = A[i];
02767 T* Bij = B[i];
02768
for (
int j=0;j<w;j++)
02769 s += *Aij++ * *Bij++;
02770 *vi++ = s;
02771 }
02772 }
02773
02775
template<
class T>
02776 void matRowsDotsAcc(
TVec<T> v,
const TMat<T>& A,
const TMat<T>& B)
02777 {
02778
#ifdef BOUNDCHECK
02779
if (A.
length()!=v.
length())
02780
PLERROR(
"matRowDotsVec(v,A,B): v.length_=%d != A.length_=%d",
02781 v.
length(),A.
length());
02782
if (A.
length()!=B.
length())
02783
PLERROR(
"matRowDotsVec(v,A,B): A.length_=%d != B.length_=%d",
02784 A.
length(),B.
length());
02785
if (A.
width()!=B.
width())
02786
PLERROR(
"matRowDotsVec(v,A,B): A.width_=%d != B.width_=%d",
02787 A.
width(),B.
width());
02788
#endif
02789
int l=A.
length(), w=A.
width();
02790 T* vi = v.
data();
02791
for (
int i=0;i<l;i++)
02792 {
02793 T s = 0;
02794 T* Aij = A[i];
02795 T* Bij = B[i];
02796
for (
int j=0;j<w;j++)
02797 s += *Aij++ * *Bij++;
02798 *vi++ += s;
02799 }
02800 }
02801
02804
template<
class T>
02805 void fillItSymmetric(
const TMat<T>& mat) {
02806
int m = mat.
mod();
02807 T* mat_data_to_fill;
02808 T* mat_data_to_copy;
02809
for (
int i = 0; i < mat.
length(); i++) {
02810 mat_data_to_fill = mat[i];
02811 mat_data_to_copy = &mat[0][i];
02812
for (
int j = 0; j < i; j++) {
02813 *(mat_data_to_fill++) = *mat_data_to_copy;
02814 mat_data_to_copy += m;
02815 }
02816 }
02817 }
02818
02819
template<
class T>
02820 void makeItSymmetric(
const TMat<T>& mat, T max_dif)
02821 {
02822
if (!mat.
isSquare())
02823
PLERROR(
"at void makeItSymmetric, the matrix is not even square\n");
02824 T dif;
02825 T value;
02826
bool warning_flag =
false;
02827
for (
int i=0; i<mat.
length()-1 ; i++)
02828
for (
int j=i+1; j<mat.
width(); j++)
02829 {
02830 dif = std::abs(mat[i][j] - mat[j][i]);
02831
if (dif > max_dif)
02832 {
02833 max_dif = dif;
02834 warning_flag =
true;
02835 }
02836 value = (mat[i][j] + mat[j][i])/2;
02837 mat[i][j] = value; mat[j][i] = value;
02838 }
02839
if (warning_flag)
02840
PLWARNING(
"At void makeItSymmetric, the maximum difference %f is not affordable\n", max_dif);
02841 }
02842
02843
02844
02845
template<
class T>
02846 void product(
const TMat<T>& mat,
const TVec<T>& x,
TVec<T>& y)
02847 {
02848
#ifdef BOUNDCHECK
02849
if (mat.
length()!=y.
length() || mat.
width()!=
x.length())
02850
PLERROR(
"TMat(%d,%d)::product(TVec& x(%d),TVec& y(%d)), incompatible arguments",
02851 mat.
length(),mat.
width(),
x.length(),y.
length());
02852
#endif
02853
T* x_=
x.data();
02854 T* y_=y.
data();
02855
for (
int i=0;i<mat.
length();i++)
02856 {
02857 T* Ai = mat[i];
02858 T yi = 0;
02859
for (
int j=0;j<mat.width();j++)
02860 yi += Ai[j] * x_[j];
02861 y_[i]=yi;
02862 }
02863 }
02864
02865
02866
template<
class T>
02867 void product(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
02868 {
02869
#ifdef BOUNDCHECK
02870
if (m1.
width()!=m2.
length() || mat.
length()!=m1.
length() || mat.
width()!=m2.
width())
02871
PLERROR(
"product(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d",
02872 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
02873
#endif
02874
int n=m1.
length();
02875
int m=m1.
width();
02876
int l=m2.
width();
02877
for (
int i=0;i<n;i++)
02878 {
02879
const T* m1i = m1[i];
02880 T* mi = mat[i];
02881
for (
int j=0;j<l;j++)
02882 {
02883 T s=0;
02884
const T* m2kj = m2.
data()+j;
02885
for (
int k=0;
k<m;
k++,m2kj+=m2.
mod())
02886 s += m1i[
k] * (*m2kj);
02887 mi[j] = s;
02888 }
02889 }
02890 }
02891
02892
02893
template<
class T>
02894 void productAcc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
02895 {
02896
#ifdef BOUNDCHECK
02897
if (m1.
width()!=m2.
length() || mat.
length()!=m1.
length() || mat.
width()!=m2.
width())
02898
PLERROR(
"productAcc(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d",
02899 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
02900
#endif
02901
int n=m1.
length();
02902
int m=m1.
width();
02903
int l=m2.
width();
02904
for (
int i=0;i<n;i++)
02905 {
02906
const T* m1i = m1[i];
02907 T* mi = mat[i];
02908
for (
int j=0;j<l;j++)
02909 {
02910 T s=0;
02911 T* m2kj = m2.
data()+j;
02912
for (
int k=0;
k<m;
k++,m2kj+=m2.
mod())
02913 s += m1i[
k] * (*m2kj);
02914 mi[j] += s;
02915 }
02916 }
02917 }
02918
02919
02920
template<
class T>
02921 void product2Acc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
02922 {
02923
#ifdef BOUNDCHECK
02924
if (m1.
width()!=m2.
length() || mat.
length()!=m1.
length() || mat.
width()!=m2.
width())
02925
PLERROR(
"product2Acc(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d",
02926 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
02927
#endif
02928
int n=m1.
length();
02929
int m=m1.
width();
02930
int l=m2.
width();
02931
for (
int i=0;i<n;i++)
02932 {
02933
const T* m1i = m1[i];
02934 T* mi = mat[i];
02935
for (
int j=0;j<l;j++)
02936 {
02937 T s=0;
02938 T* m2kj = m2.
data()+j;
02939
for (
int k=0;
k<m;
k++,m2kj+=m2.
mod())
02940 s += m1i[
k] * (*m2kj) * (*m2kj);
02941 mi[j] += s;
02942 }
02943 }
02944 }
02945
02946
02947
template<
class T>
02948 void squareProductAcc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
02949 {
02950
#ifdef BOUNDCHECK
02951
if (m1.
width()!=m2.
length() || mat.
length()!=m1.
length() || mat.
width()!=m2.
width())
02952
PLERROR(
"squareProductAcc(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d",
02953 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
02954
#endif
02955
int n=m1.
length();
02956
int m=m1.
width();
02957
int l=m2.
width();
02958
for (
int i=0;i<n;i++)
02959 {
02960
const T* m1i = m1[i];
02961 T* mi = mat[i];
02962
for (
int j=0;j<l;j++)
02963 {
02964 T s=0;
02965 T* m2kj = m2.
data()+j;
02966
for (
int k=0;
k<m;
k++,m2kj+=m2.
mod())
02967 {
02968 T m1ik=m1i[
k];
02969 s += m1ik*m1ik * (*m2kj);
02970 }
02971 mi[j] += s;
02972 }
02973 }
02974 }
02975
02976
02977
02978
template<
class T>
02979 void externalProduct(
const TMat<T>& mat,
const TVec<T>& v1,
const TVec<T>& v2)
02980 {
02981
#ifdef BOUNDCHECK
02982
if (v1.
length()!=mat.
length() || mat.
width()!=v2.
length())
02983
PLERROR(
"externalProduct(Vec,Vec), incompatible arguments %dx%d= %d times %d",
02984 mat.
length(),mat.
width(),v1.
length(), v2.
length());
02985
#endif
02986
const T* v_1=v1.
data();
02987
const T* v_2=v2.
data();
02988
for (
int i=0;i<mat.
length();i++)
02989 {
02990 T* mi = mat[i];
02991 T v1i = v_1[i];
02992
for (
int j=0;j<mat.width();j++)
02993 mi[j] = v1i * v_2[j];
02994 }
02995 }
02996
02997
02998
template<
class T>
02999 void externalProductAcc(
const TMat<T>& mat,
const TVec<T>& v1,
const TVec<T>& v2)
03000 {
03001
#ifdef BOUNDCHECK
03002
if (v1.
length()!=mat.
length() || mat.
width()!=v2.
length())
03003
PLERROR(
"externalProductAcc(Vec,Vec), incompatible arguments %dx%d= %d times %d",
03004 mat.
length(),mat.
width(),v1.
length(), v2.
length());
03005
#endif
03006
03007 T* v_1=v1.
data();
03008 T* v_2=v2.
data();
03009 T* mp = mat.
data();
03010
int l = mat.
length();
03011
int w = mat.
width();
03012
03013
if(mat.
isCompact())
03014 {
03015 T* pv1 = v_1;
03016
for(
int i=0; i<l; i++)
03017 {
03018 T* pv2 = v_2;
03019 T
val = *pv1++;
03020
for(
int j=0; j<w; j++)
03021 *mp++ +=
val * *pv2++;
03022 }
03023 }
03024
else
03025 {
03026 cerr <<
"!";
03027
for (
int i=0;i<l;i++)
03028 {
03029 T* mi = mat[i];
03030 T v1i = v_1[i];
03031
for (
int j=0;j<w;j++)
03032 mi[j] += v1i * v_2[j];
03033 }
03034 }
03035 }
03036
03037
03038
template<
class T>
03039 void externalProductScaleAcc(
const TMat<T>& mat,
const TVec<T>& v1,
const TVec<T>& v2, T gamma)
03040 {
03041
#ifdef BOUNDCHECK
03042
if (v1.
length()!=mat.
length() || mat.
width()!=v2.
length())
03043
PLERROR(
"externalProductScaleAcc(Vec,Vec), incompatible arguments %dx%d= %d times %d",
03044 mat.
length(),mat.
width(),v1.
length(), v2.
length());
03045
#endif
03046
const T* v_1=v1.
data();
03047
const T* v_2=v2.
data();
03048
for (
int i=0;i<mat.
length();i++)
03049 {
03050 T* mi = mat[i];
03051 T v1i = v_1[i];
03052
for (
int j=0;j<mat.width();j++)
03053 mi[j] += gamma * v1i * v_2[j];
03054 }
03055 }
03056
03057
03058
template<
class T>
03059 void externalProductScaleAcc(
const TMat<T>& mat,
const TVec<T>& v1,
const TVec<T>& v2, T gamma, T alpha)
03060 {
03061
#ifdef BOUNDCHECK
03062
if (v1.
length()!=mat.
length() || mat.
width()!=v2.
length())
03063
PLERROR(
"externalProductScaleAcc(Vec,Vec), incompatible arguments %dx%d= %d times %d",
03064 mat.
length(),mat.
width(),v1.
length(), v2.
length());
03065
#endif
03066
const T* v_1=v1.
data();
03067
const T* v_2=v2.
data();
03068
for (
int i=0;i<mat.
length();i++)
03069 {
03070 T* mi = mat[i];
03071 T v1i = v_1[i];
03072
for (
int j=0;j<mat.width();j++)
03073 mi[j] = alpha*mi[j] + gamma * v1i * v_2[j];
03074 }
03075 }
03076
03077
03078
template<
class T>
03079 void productTranspose(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03080 {
03081
#ifdef BOUNDCHECK
03082
if (m1.
width()!=m2.
width() || mat.
length()!=m1.
length() || mat.
width()!=m2.
length())
03083
PLERROR(
"productTranspose(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d'",
03084 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
03085
#endif
03086
int n=m1.
length();
03087
int m=m1.
width();
03088
int l=m2.
length();
03089
for (
int i=0;i<n;i++)
03090 {
03091
const T* m1i = m1[i];
03092 T* mi = mat[i];
03093
for (
int j=0;j<l;j++)
03094 {
03095 T s=0;
03096
const T* m2j = m2[j];
03097
for (
int k=0;
k<m;
k++)
03098 s += m1i[
k] * m2j[
k];
03099 mi[j] = s;
03100 }
03101 }
03102 }
03103
03104
03105
template<
class T>
03106 void squareProductTranspose(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03107 {
03108
#ifdef BOUNDCHECK
03109
if (m1.
width()!=m2.
width() || mat.
length()!=m1.
length() || mat.
width()!=m2.
length())
03110
PLERROR(
"squareProductTranspose(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d'",
03111 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
03112
#endif
03113
int n=m1.
length();
03114
int m=m1.
width();
03115
int l=m2.
length();
03116
for (
int i=0;i<n;i++)
03117 {
03118
const T* m1i = m1[i];
03119 T* mi = mat[i];
03120
for (
int j=0;j<l;j++)
03121 {
03122 T s=0;
03123
const T* m2j = m2[j];
03124
for (
int k=0;
k<m;
k++)
03125 {
03126 T m1ik=m1i[
k];
03127 s += m1ik*m1ik * m2j[
k];
03128 }
03129 mi[j] = s;
03130 }
03131 }
03132 }
03133
03134
03135
template<
class T>
03136 void product2Transpose(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03137 {
03138
#ifdef BOUNDCHECK
03139
if (m1.
width()!=m2.
width() || mat.
length()!=m1.
length() || mat.
width()!=m2.
length())
03140
PLERROR(
"product2Transpose(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d'",
03141 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
03142
#endif
03143
int n=m1.
length();
03144
int m=m1.
width();
03145
int l=m2.
length();
03146
for (
int i=0;i<n;i++)
03147 {
03148
const T* m1i = m1[i];
03149 T* mi = mat[i];
03150
for (
int j=0;j<l;j++)
03151 {
03152 T s=0;
03153
const T* m2j = m2[j];
03154
for (
int k=0;
k<m;
k++)
03155 {
03156 T m2jk=m2j[
k];
03157 s += m1i[
k] * m2jk*m2jk;
03158 }
03159 mi[j] = s;
03160 }
03161 }
03162 }
03163
03164
03165
template<
class T>
03166 void productTransposeAcc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03167 {
03168
#ifdef BOUNDCHECK
03169
if (m1.
width()!=m2.
width() || mat.
length()!=m1.
length() || mat.
width()!=m2.
length())
03170
PLERROR(
"productTransposeAcc(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d'",
03171 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
03172
#endif
03173
int n=m1.
length();
03174
int m=m1.
width();
03175
int l=m2.
length();
03176
for (
int i=0;i<n;i++)
03177 {
03178
const T* m1i = m1[i];
03179 T* mi = mat[i];
03180
for (
int j=0;j<l;j++)
03181 {
03182 T s=0;
03183
const T* m2j = m2[j];
03184
for (
int k=0;
k<m;
k++)
03185 s += m1i[
k] * m2j[
k];
03186 mi[j] += s;
03187 }
03188 }
03189 }
03190
03191
03192
template<
class T>
03193 void product2TransposeAcc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03194 {
03195
#ifdef BOUNDCHECK
03196
if (m1.
width()!=m2.
width() || mat.
length()!=m1.
length() || mat.
width()!=m2.
length())
03197
PLERROR(
"product2TransposeAcc(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d'",
03198 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
03199
#endif
03200
int n=m1.
length();
03201
int m=m1.
width();
03202
int l=m2.
length();
03203
for (
int i=0;i<n;i++)
03204 {
03205
const T* m1i = m1[i];
03206 T* mi = mat[i];
03207
for (
int j=0;j<l;j++)
03208 {
03209 T s=0;
03210
const T* m2j = m2[j];
03211
for (
int k=0;
k<m;
k++)
03212 {
03213 T m2jk=m2j[
k];
03214 s += m1i[
k] * m2jk*m2jk;
03215 }
03216 mi[j] += s;
03217 }
03218 }
03219 }
03220
03221
03222
template<
class T>
03223 void squareProductTransposeAcc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03224 {
03225
#ifdef BOUNDCHECK
03226
if (m1.
width()!=m2.
width() || mat.
length()!=m1.
length() || mat.
width()!=m2.
length())
03227
PLERROR(
"squareProductTransposeAcc(Mat,Mat), incompatible arguments %dx%d= %dx%d times %dx%d'",
03228 mat.
length(),mat.
width(),m1.
length(),m1.
width(), m2.
length(),m2.
width());
03229
#endif
03230
int n=m1.
length();
03231
int m=m1.
width();
03232
int l=m2.
length();
03233
for (
int i=0;i<n;i++)
03234 {
03235
const T* m1i = m1[i];
03236 T* mi = mat[i];
03237
for (
int j=0;j<l;j++)
03238 {
03239 T s=0;
03240
const T* m2j = m2[j];
03241
for (
int k=0;
k<m;
k++)
03242 {
03243 T m1ik=m1i[
k];
03244 s += m1ik*m1ik * m2j[
k];
03245 }
03246 mi[j] += s;
03247 }
03248 }
03249 }
03250
03251
03252
template<
class T>
03253 void transposeProduct(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03254 {
03255
int n=m1.
width();
03256
int m=m1.
length();
03257
int l=m2.
width();
03258
#ifdef BOUNDCHECK
03259
if (m!=m2.
length() || mat.
length()!=n || mat.
width()!=l)
03260
PLERROR(
"transposeProduct(Mat,Mat), incompatible arguments "
03261
"%dx%d' times %dx%d into %dx%d",
03262 m1.
length(),m1.
width(), m2.
length(),m2.
width(), mat.
length(), mat.
width());
03263
#endif
03264
mat.
clear();
03265
for (
int i=0;i<n;i++)
03266 {
03267 T* m1ki = m1.
data()+i;
03268 T* mi = mat[i];
03269
for (
int k=0;
k<m;
k++,m1ki+=m1.
mod())
03270 {
03271
const T* m2k = m2[
k];
03272 T m1_ki = *m1ki;
03273
for (
int j=0;j<l;j++)
03274 mi[j] += m1_ki * m2k[j];
03275 }
03276 }
03277 }
03278
03279
03280
template<
class T>
03281 void transposeProduct2(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03282 {
03283
int n=m1.
width();
03284
int m=m1.
length();
03285
int l=m2.
width();
03286
#ifdef BOUNDCHECK
03287
if (m!=m2.
length() || mat.
length()!=n || mat.
width()!=l)
03288
PLERROR(
"transposeProduct2(Mat,Mat), incompatible arguments "
03289
"%dx%d' times %dx%d into %dx%d",
03290 m1.
length(),m1.
width(), m2.
length(),m2.
width(), mat.
length(), mat.
width());
03291
#endif
03292
mat.
clear();
03293
for (
int i=0;i<n;i++)
03294 {
03295 T* m1ki = m1.
data()+i;
03296 T* mi = mat[i];
03297
for (
int k=0;
k<m;
k++,m1ki+=m1.
mod())
03298 {
03299
const T* m2k = m2[
k];
03300 T m1_ki = *m1ki;
03301
for (
int j=0;j<l;j++)
03302 {
03303 T m2kj=m2k[j];
03304 mi[j] += m1_ki * m2kj*m2kj;
03305 }
03306 }
03307 }
03308 }
03309
03310
03311
template<
class T>
03312 void transposeProductAcc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03313 {
03314
int n=m1.
width();
03315
int m=m1.
length();
03316
int l=m2.
width();
03317
#ifdef BOUNDCHECK
03318
if (m!=m2.
length() || mat.
length()!=n || mat.
width()!=l)
03319
PLERROR(
"transposeProductAcc(Mat,Mat), incompatible arguments "
03320
"%dx%d' times %dx%d into %dx%d",
03321 m1.
length(),m1.
width(), m2.
length(),m2.
width(), mat.
length(), mat.
width());
03322
#endif
03323
for (
int i=0;i<n;i++)
03324 {
03325 T* m1ki = m1.
data()+i;
03326 T* mi = mat[i];
03327
for (
int k=0;
k<m;
k++,m1ki+=m1.
mod())
03328 {
03329
const T* m2k = m2[
k];
03330 T m1_ki = *m1ki;
03331
for (
int j=0;j<l;j++)
03332 mi[j] += m1_ki * m2k[j];
03333 }
03334 }
03335 }
03336
03337
03338
template<
class T>
03339 void transposeProduct2Acc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03340 {
03341
int n=m1.
width();
03342
int m=m1.
length();
03343
int l=m2.
width();
03344
#ifdef BOUNDCHECK
03345
if (m!=m2.
length() || mat.
length()!=n || mat.
width()!=l)
03346
PLERROR(
"transposeProduct2Acc(Mat,Mat), incompatible arguments "
03347
"%dx%d' times %dx%d into %dx%d",
03348 m1.
length(),m1.
width(), m2.
length(),m2.
width(), mat.
length(), mat.
width());
03349
#endif
03350
for (
int i=0;i<n;i++)
03351 {
03352 T* m1ki = m1.
data()+i;
03353 T* mi = mat[i];
03354
for (
int k=0;
k<m;
k++,m1ki+=m1.
mod())
03355 {
03356
const T* m2k = m2[
k];
03357 T m1_ki = *m1ki;
03358
for (
int j=0;j<l;j++)
03359 {
03360 T m2kj = m2k[j];
03361 mi[j] += m1_ki * m2kj * m2kj;
03362 }
03363 }
03364 }
03365 }
03366
03367
03368
template<
class T>
03369 void transposeTransposeProduct(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03370 {
03371
#ifdef BOUNDCHECK
03372
if (m1.
length()!=m2.
width())
03373
PLERROR(
"transposeTransposeProduct(Mat,Mat), incompatible arguments %dx%d' times %dx%d'",
03374 m1.
length(),m1.
width(), m2.
length(),m2.
width());
03375
#endif
03376
int n=m1.
width();
03377
int m=m1.
length();
03378
int l=m2.
length();
03379
for (
int i=0;i<n;i++)
03380 {
03381 T* m1ki0 = m1.
data()+i;
03382 T* mi = mat[i];
03383
for (
int j=0;j<l;j++)
03384 {
03385 T s=0;
03386
const T* m2j = m2[j];
03387 T* m1ki = m1ki0;
03388
for (
int k=0;
k<m;
k++,m1ki+=m1.
mod())
03389 s += (*m1ki) * m2j[
k];
03390 mi[j] = s;
03391 }
03392 }
03393 }
03394
03395
03396
template<
class T>
03397 void transposeTransposeProductAcc(
const TMat<T>& mat,
const TMat<T>& m1,
const TMat<T>& m2)
03398 {
03399
if (m1.
length()!=m2.
width())
03400
PLERROR(
"transposeTransposeProductAcc(Mat,Mat), incompatible arguments %dx%d' times %dx%d",
03401 m1.
length(),m1.
width(), m2.
length(),m2.
width());
03402
int n=m1.
width();
03403
int m=m1.
length();
03404
int l=m2.
width();
03405
for (
int i=0;i<n;i++)
03406 {
03407 T* m1ki0 = m1.
data()+i;
03408 T* mi = mat[i];
03409
for (
int j=0;j<l;j++)
03410 {
03411 T s=0;
03412
const T* m2j = m2[j];
03413 T* m1ki = m1ki0;
03414
for (
int k=0;
k<m;
k++,m1ki+=m1.
mod())
03415 s += (*m1ki) * m2j[
k];
03416 mi[j] += s;
03417 }
03418 }
03419 }
03420
03421
template<
class T>
03422 T
trace(
const TMat<T>& mat)
03423 {
03424
if (!mat.
isSquare())
03425
PLERROR(
"In trace()\nThe matrix must be square." );
03426 T tr = mat.
firstElement();
03427
for (
int i = 1; i < mat.
length(); i++ )
03428 tr += mat(i,i);
03429
return tr;
03430 }
03431
03433
template<
class T>
03434 void regularizeMatrix(
const TMat<T>& mat, T tolerance)
03435 {
03436
static T reg;
03437
static T*
k;
03438
static int shift;
03439 reg = tolerance *
trace(mat);
03440
k = mat.
data();
03441 shift = mat.
mod() + 1;
03442
for (
int i = 0; i < mat.
length(); i++) {
03443 *
k += reg;
03444
k += shift;
03445 }
03446 }
03447
03448
03449
template<
class T>
03450 void makeRowsSumTo1(
const TMat<T>& mat)
03451 {
03452
for (
int i = 0; i < mat.
length(); i++)
03453 {
03454
TVec<T> row_i = mat(i);
03455
divide(row_i,
sum(row_i), row_i);
03456 }
03457 }
03458
03459
03460
03461
template<
class T>
03462 void multiply(
const TMat<T>& result,
const TMat<T>& x, T scale)
03463 {
03464
#ifdef BOUNDCHECK
03465
if (result.
length()!=
x.length() || result.
width()!=
x.width())
03466
PLERROR(
"multiply incompatible dimensions: %dx%d <- %dx%d",
03467 result.
length(),result.
width(),
x.length(),
x.width());
03468
#endif
03469
if(result.
isCompact() &&
x.isCompact())
03470 {
03471
typename TMat<T>::compact_iterator itm = result.
compact_begin();
03472
typename TMat<T>::compact_iterator itmend = result.
compact_end();
03473
typename TMat<T>::compact_iterator itx =
x.compact_begin();
03474
for(; itm!=itmend; ++itm, ++itx)
03475 *itm = *itx * scale;
03476 }
03477
else
03478 {
03479
typename TMat<T>::iterator itm = result.
begin();
03480
typename TMat<T>::iterator itmend = result.
end();
03481
typename TMat<T>::iterator itx =
x.begin();
03482
for(; itm!=itmend; ++itm, ++itx)
03483 *itm = *itx * scale;
03484 }
03485 }
03486
03487
template<
class T>
03488 inline TMat<T> operator*(
const TMat<T>& m,
const T& scalar)
03489 {
03490
TMat<T> result(m.
length(),m.
width());
03491
multiply(result, m, scalar);
03492
return result;
03493 }
03494
03495
template<
class T>
03496 inline TMat<T> operator*(
const T& scalar,
const TMat<T>& m)
03497 {
return m * scalar;}
03498
03499
03500
template<
class T>
03501 inline TMat<T> operator/(
const TMat<T>& m,
const T& scalar)
03502 {
return m * (T(1)/scalar); }
03503
03504
03505
template<
class T>
03506 void multiplyAcc(
const TMat<T>& mat,
const TMat<T>& x, T scale)
03507 {
03508
#ifdef BOUNDCHECK
03509
if (mat.
length()!=
x.length() || mat.
width()!=
x.width())
03510
PLERROR(
"multiplyAcc incompatible dimensions: %dx%d <- %dx%d",
03511 mat.
length(),mat.
width(),
x.length(),
x.width());
03512
#endif
03513
if(mat.
isCompact() &&
x.isCompact())
03514 {
03515
typename TMat<T>::compact_iterator itm = mat.
compact_begin();
03516
typename TMat<T>::compact_iterator itmend = mat.
compact_end();
03517
typename TMat<T>::compact_iterator itx =
x.compact_begin();
03518
for(; itm!=itmend; ++itm, ++itx)
03519 *itm += *itx * scale;
03520 }
03521
else
03522 {
03523
typename TMat<T>::iterator itm = mat.
begin();
03524
typename TMat<T>::iterator itmend = mat.
end();
03525
typename TMat<T>::iterator itx =
x.begin();
03526
for(; itm!=itmend; ++itm, ++itx)
03527 *itm += *itx * scale;
03528 }
03529 }
03530
03531
03532
template<
class T>
03533 void multiplyAcc(
const TMat<T>& mat,
const TMat<T>& x,
const TMat<T>& y)
03534 {
03535
int n=mat.
length()*mat.
width();
03536
if (mat.
length()!=
x.length() || mat.
width()!=
x.width() || y.
length()!=mat.
length() || y.
width()!=mat.
width())
03537
PLERROR(
"multiplyAcc this has size=%dx%d, x is %dx%d, y is %dx%d",
03538 mat.
length(),mat.
width(),
x.length(),
x.width(),y.
length(),y.
width());
03539 T* p=mat.
data();
03540 T* xp=
x.data();
03541 T* yp=y.
data();
03542
for (
int i=0;i<n;i++)
03543 p[i] += xp[i] * yp[i];
03544 }
03545
03546
03547
template<
class T>
03548 void squareMultiplyAcc(
const TMat<T>& mat,
const TMat<T>& x, T scale)
03549 {
03550
int n=
x.length()*
x.width();
03551
if (mat.
length()*mat.
width()!=n)
03552
PLERROR(
"squareMultiplyAcc this has size=%d and x has size=%d",
03553 mat.
width()*mat.
length(),n);
03554 T* p=mat.
data();
03555 T* xp=
x.data();
03556
for (
int i=0;i<n;i++)
03557 {
03558 T xpi = xp[i];
03559 p[i] += scale * xpi * xpi;
03560 }
03561 }
03562
03563
03564
template<
class T>
03565 void diffSquareMultiplyAcc(
const TMat<T>& mat,
const TMat<T>& x,
const TMat<T>& y, T scale)
03566 {
03567
int n=
x.length()*
x.width();
03568
if (mat.
length()*mat.
width()!=n)
03569
PLERROR(
"diffSquareMultiplyAcc this has size=%d and x has size=%d",
03570 mat.
width()*mat.
length(),n);
03571 T* p=mat.
data();
03572 T* xp=
x.data();
03573 T* yp=y.
data();
03574
for (
int i=0;i<n;i++)
03575 {
03576 T diff = (xp[i]-yp[i]);
03577 p[i] += scale * diff * diff;
03578 }
03579 }
03580
03581
03582
03583
template<
class T>
03584 TVec<T> selectAndOrder(
const TMat<T>& mat,
int pos,
int colnum=0)
03585 {
03586
#ifdef BOUNDCHECK
03587
if (colnum<0 || colnum>=mat.
width())
PLERROR(
"Bad column number (%d)", colnum);
03588
if (pos<0 || pos>=mat.
length())
PLERROR(
"Bad position (%d)", pos);
03589
#endif
03590
03591
int l=0;
03592
int h=mat.
length()-1;
03593
TMat<T> v = mat.
column(colnum);
03594
03595
while (l<h)
03596 {
03597 T p = v((l+h)/2,0);
03598
int x = l;
03599
int y = h;
03600
03601
do
03602 {
03603
while (v(
x,0)<p)
x++;
03604
while (p<v(y,0)) y--;
03605
if (
x<=y)
03606 {
03607 mat.
swapRows(
x,y);
03608
x++;
03609 y--;
03610 }
03611 }
while (
x<=y);
03612
03613
if (pos>=
x) l=
x;
03614
else h=
x-1;
03615 }
03616
03617
return mat(l);
03618 }
03619
03620
03621
03622
template<
class T>
03623 void addToDiagonal(
const TMat<T>& mat, T lambda)
03624 {
03625 T *d = mat.
data();
03626
for (
int i=0;i<mat.
length();i++,d+=mat.
mod()+1) *d+=lambda;
03627 }
03628
03629
03630
03631
03632
03633
template<
class T>
03634 void addToDiagonal(
const TMat<T>& mat,
const TVec<T>& lambda)
03635 {
03636
#ifdef BOUNDCHECK
03637
if (lambda.
length()!=mat.
length())
03638
PLERROR(
"Mat(%d)::addToDiagonal(Vec(%d)) inconsistent lengths",
03639 mat.
length(), lambda.
length());
03640
#endif
03641
T *l = lambda.
data();
03642 T *d = mat.
data();
03643
for (
int i=0;i<mat.
length();i++,d+=mat.
mod()+1,l++) *d += *l;
03644 }
03645
03646
03647
template<
class T>
03648 void diag(
const TMat<T>& mat,
const TVec<T>& d)
03649 {
03650 T* d_ = d.
data();
03651
for (
int i=0;i<mat.
length();i++)
03652 d_[i] = mat(i,i);
03653 }
03654
03655
template<
class T>
03656 TVec<T> diag(
const TMat<T>& mat)
03657 {
03658
TVec<T> d(mat.
length());
03659
diag(mat, d);
03660
return d;
03661 }
03662
03663
template<
class T>
03664 void diagonalOfSquare(
const TMat<T>& mat,
const TVec<T>& d)
03665 {
03666 T* d_=d.
data();
03667
for (
int i=0;i<mat.
length();i++)
03668 d_[i]=
pownorm(mat(i));
03669 }
03670
03671
03672
template<
class T>
03673 void projectOnOrthogonalSubspace(
const TMat<T>& mat,
TMat<T> orthonormal_subspace)
03674 {
03675
for (
int i=0;i<mat.
length();i++)
03676 {
03677
TVec<T> row_i = mat(i);
03678
projectOnOrthogonalSubspace(row_i, orthonormal_subspace);
03679 }
03680 }
03681
03682
03683
template<
class T>
03684 void averageAcrossRowsAndColumns(
const TMat<T>& mat,
TVec<T>& avg_across_rows,
TVec<T>& avg_across_columns,
bool ignored)
03685 {
03686 avg_across_rows.
resize(mat.
width());
03687 avg_across_columns.
resize(mat.
length());
03688 avg_across_rows.
clear();
03689 avg_across_columns.
clear();
03690 T* row_i=mat.
data();
03691
for (
int i=0;i<mat.
length();i++)
03692 {
03693 T& avg_cols_i=avg_across_columns[i];
03694 T* avg_rows = avg_across_rows.
data();
03695
for (
int j=0;j<mat.
width();j++)
03696 {
03697 T row_ij=row_i[j];
03698 avg_cols_i += row_ij;
03699 avg_rows[j] += row_ij;
03700 }
03701 row_i+=mat.
mod();
03702 }
03703 avg_across_rows /= mat.
length();
03704 avg_across_columns /= mat.
width();
03705 }
03706
03707
03708
template<
class T>
03709 void addToRows(
const TMat<T>& mat,
const TVec<T> row,
bool ignored)
03710 {
03711
for (
int i=0;i<mat.
length();i++)
03712 {
03713
TVec<T> row_i = mat(i);
03714 row_i += row;
03715 }
03716 }
03717
03718
03719
template<
class T>
03720 void addToColumns(
const TMat<T>& mat,
const TVec<T> col,
bool ignored)
03721 {
03722 T* row_i=mat.
data();
03723
for (
int i=0;i<mat.
length();i++)
03724 {
03725 T col_i=col[i];
03726
for (
int j=0;j<mat.
width();j++)
03727 row_i[j] += col_i;
03728 row_i+=mat.
mod();
03729 }
03730 }
03731
03732
template<
class T>
03733 void substractFromRows(
const TMat<T>& mat,
const TVec<T> row,
bool ignored)
03734 {
03735
for (
int i=0;i<mat.
length();i++)
03736 {
03737
TVec<T> row_i = mat(i);
03738 row_i -= row;
03739 }
03740 }
03741
03742
03743
03744
03745
template<
class T>
03746 void substractFromColumns(
const TMat<T>& mat,
const TVec<T> col,
bool ignored)
03747 {
03748 T* row_i=mat.
data();
03749
for (
int i=0;i<mat.
length();i++)
03750 {
03751 T col_i=col[i];
03752
for (
int j=0;j<mat.
width();j++)
03753 row_i[j] -= col_i;
03754 row_i+=mat.
mod();
03755 }
03756 }
03757
03758
03759
template<
class T>
03760 void addToMat(
const TMat<T>& mat, T scalar,
bool ignored)
03761 { mat += scalar; }
03762
03763
03764
03765
03766
template<
class T>
03767 T
sum(
const TMat<T>& mat,
bool ignore_missing=
false)
03768 {
03769
double res = 0.0;
03770 T* m_i = mat.
data();
03771
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03772 {
03773
for(
int j=0; j<mat.
width(); j++)
03774 {
03775
if (!
is_missing(m_i[j])) res += m_i[j];
03776
else if (!ignore_missing)
return MISSING_VALUE;
03777 }
03778 }
03779
return T(res);
03780 }
03781
03782
template<
class T>
03783 T
product(
const TMat<T>& mat)
03784 {
03785
double res = 1.0;
03786 T* m_i = mat.
data();
03787
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03788
for(
int j=0; j<mat.
width(); j++)
03789 res *= m_i[j];
03790
return T(res);
03791 }
03792
03793
template<
class T>
03794 T
sum_of_squares(
const TMat<T>& mat)
03795 {
03796
double res = 0.0;
03797 T* m_i = mat.
data();
03798
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03799
for(
int j=0; j<mat.
width(); j++)
03800 {
03801 T v = m_i[j];
03802 res += v*v;
03803 }
03804
return T(res);
03805 }
03806
03807
template<
class T>
03808 T
mean(
const TMat<T>& mat)
03809 {
03810
#ifdef BOUNDCHECK
03811
if(mat.
length()==0 || mat.
width()==0)
03812
PLERROR(
"IN T mean(const TMat<T>& mat) mat has 0 size");
03813
#endif
03814
double res = 0.0;
03815 T* m_i = mat.
data();
03816
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03817
for(
int j=0; j<mat.
width(); j++)
03818 res += m_i[j];
03819
return T(res/(mat.
length()*mat.
width()));
03820 }
03821
03822
template<
class T>
03823 T
geometric_mean(
const TMat<T>& mat)
03824 {
03825
#ifdef BOUNDCHECK
03826
if(mat.
length()==0 || mat.
width()==0)
03827
PLERROR(
"IN T geometric_mean(const TMat<T>& mat) mat has 0 size");
03828
#endif
03829
double res = 0.0;
03830 T* m_i = mat.
data();
03831
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03832
for(
int j=0; j<mat.
width(); j++)
03833 {
03834 T mij = m_i[j];
03835
if (mij<=0)
03836
PLERROR(
"geometric_mean(TMat<T>): argument %g <=0 at position (%d,%d)",
03837 mij,i,j);
03838 res +=
log(m_i[j]);
03839 }
03840
return T(
exp(res/(mat.
length()*mat.
width())));
03841 }
03842
03843
template<
class T>
03844 T
variance(
const TMat<T>& mat, T meanval)
03845 {
03846
#ifdef BOUNDCHECK
03847
if(mat.
length()==0 || mat.
width()==0)
03848
PLERROR(
"IN T variance(const TMat<T>& mat, T meanval) mat has 0 size");
03849
#endif
03850
double res = 0.0;
03851 T* m_i = mat.
data();
03852
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03853
for(
int j=0; j<mat.
width(); j++)
03854 {
03855
double diff = m_i[j]-meanval;
03856 res += diff*diff;
03857 }
03858
return res/(mat.
length()*mat.
width()-1);
03859 }
03860
03861
template<
class T>
03862 T
correlation(
const TMat<T>& mat)
03863 {
03864
int n = mat.
length();
03865
#ifdef BOUNDCHECK
03866
if(n==0 || mat.
width()==0)
03867
PLERROR(
"In T correlation(const TMat<T>& mat) mat has 0 size");
03868
#endif
03869
if (mat.
width() != 2)
03870
PLERROR(
"In T correlation(const TMat<T>& mat), mat width (%d) must be 2", mat.
width());
03871
03872
double s_x=0, s_y=0, s_xy=0, s_x2=0, s_y2=0;
03873
for (
int i=0; i<n; i++)
03874 {
03875 T
x = mat(i,0);
03876 T y = mat(i,1);
03877 s_x +=
x;
03878 s_x2 +=
x*
x;
03879 s_y += y;
03880 s_y2 += y*y;
03881 s_xy +=
x*y;
03882 }
03883
03884
return (n*s_xy - s_x*s_y)/
sqrt((n*s_x2 - s_x*s_x)*(n*s_y2 - s_y*s_y));
03885 }
03886
03887
template<
class T>
03888 T
correlation(
const TVec<T>& x,
const TVec<T>& y)
03889 {
03890
int n =
x.length();
03891
#ifdef BOUNDCHECK
03892
if(n==0 || y.
length()==0)
03893
PLERROR(
"In T correlation(const TVec<T>& x, const TVec<T>& y), one Vec has 0 size");
03894
#endif
03895
if (n != y.
length())
03896
PLERROR(
"In T correlation(const TVec<T>& x, const TVec<T>& y), both Vec must have same length (%d != %d)", n, y.
length());
03897
03898
double s_x=0, s_y=0, s_xy=0, s_x2=0, s_y2=0;
03899
for (
int i=0; i<n; i++)
03900 {
03901 T x_val =
x[i];
03902 T y_val = y[i];
03903 s_x += x_val;
03904 s_x2 += x_val*x_val;
03905 s_y += y_val;
03906 s_y2 += y_val*y_val;
03907 s_xy += x_val*y_val;
03908 }
03909
03910
return (n*s_xy - s_x*s_y)/
sqrt((n*s_x2 - s_x*s_x)*(n*s_y2 - s_y*s_y));
03911 }
03912
03913
template<
class T>
03914 T
min(
const TMat<T>& mat)
03915 {
03916
#ifdef BOUNDCHECK
03917
if(mat.
length()==0 || mat.
width()==0)
03918
PLERROR(
"IN T min(const TMat<T>& mat) mat has 0 size");
03919
#endif
03920
T* m_i = mat.
data();
03921
double minval = m_i[0];
03922
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03923
for(
int j=0; j<mat.
width(); j++)
03924
if(m_i[j]<minval)
03925 minval = m_i[j];
03926
return minval;
03927 }
03928
03929
template<
class T>
03930 T
max(
const TMat<T>& mat)
03931 {
03932
#ifdef BOUNDCHECK
03933
if(mat.
length()==0 || mat.
width()==0)
03934
PLERROR(
"IN T max(const TMat<T>& mat) mat has 0 size");
03935
#endif
03936
T* m_i = mat.
data();
03937
double maxval = m_i[0];
03938
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03939
for(
int j=0; j<mat.
width(); j++)
03940
if(m_i[j]>maxval)
03941 maxval = m_i[j];
03942
return maxval;
03943 }
03944
03946
template<
class T>
03947 void argmin(
const TMat<T>& mat,
int& mini,
int& minj)
03948 {
03949
#ifdef BOUNDCHECK
03950
if(mat.
length()==0 || mat.
width()==0)
03951
PLERROR(
"IN void argmin(const TMat<T>& mat, int& mini, iny& minj) mat has 0 size");
03952
#endif
03953
T* m_i = mat.
data();
03954 mini=0;
03955 minj=0;
03956
double minval = m_i[0];
03957
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03958
for(
int j=0; j<mat.
width(); j++)
03959
if(m_i[j]<minval)
03960 {
03961 minval = m_i[j];
03962 mini = i;
03963 minj = j;
03964 }
03965 }
03966
03967
03968
template<
class T>
03969 void argmax(
const TMat<T>& mat,
int& maxi,
int& maxj)
03970 {
03971
#ifdef BOUNDCHECK
03972
if(mat.
length()==0 || mat.
width()==0)
03973
PLERROR(
"IN void argmax(const TMat<T>& mat, int& maxi, iny& maxj) mat has 0 size");
03974
#endif
03975
T* m_i = mat.
data();
03976 maxi=0;
03977 maxj=0;
03978
double maxval = m_i[0];
03979
for(
int i=0; i<mat.
length(); i++, m_i+=mat.
mod())
03980
for(
int j=0; j<mat.
width(); j++)
03981
if(m_i[j]>maxval)
03982 {
03983 maxval = m_i[j];
03984 maxi = i;
03985 maxj = j;
03986 }
03987 }
03988
03990
template<
class T>
03991 int argmin(
const TMat<T>& m)
03992 {
03993
int imin, jmin;
03994
argmin(m,imin,jmin);
03995
return (imin*m.
width()+jmin);
03996 }
03997
03999
template<
class T>
04000 int argmax(
const TMat<T>& m)
04001 {
04002
int imax, jmax;
04003
argmax(m,imax,jmax);
04004
return (imax*m.
width()+jmax);
04005 }
04006
04012
template<
class T>
04013 void rowSum(
const TMat<T>& mat,
const TMat<T>& singlecolumn)
04014 {
04015
#ifdef BOUNDCHECK
04016
if(singlecolumn.
length()!=mat.
length() || singlecolumn.
width() != 1)
04017
PLERROR(
"IN void rowSum(const TMat<T>& mat, TMat<T>& singlecolumn) singlecolumn must be a mat.length() x 1 matrix");
04018
#endif
04019
for(
int i=0; i<mat.
length(); i++)
04020 singlecolumn(i,0) =
sum(mat(i));
04021 }
04022
04023
04024
template<
class T>
04025 void rowSum(
const TMat<T>& mat,
const TVec<T>& colvec)
04026 {
04027
#ifdef BOUNDCHECK
04028
if(colvec.
length()!=mat.
length())
04029
PLERROR(
"IN void rowSum(const TMat<T>& mat, const TVec<T>& colvec) colvec must have same length as mat");
04030
#endif
04031
for(
int i=0; i<mat.
length(); i++)
04032 colvec[i] =
sum(mat(i));
04033 }
04034
04035
template<
class T>
04036 void rowMean(
const TMat<T>& mat,
const TMat<T>& singlecolumn)
04037 {
04038
#ifdef BOUNDCHECK
04039
if(singlecolumn.
length()!=mat.
length() || singlecolumn.
width()!=1 || mat.
width()==0)
04040
PLERROR(
"IN void rowMean(const TMat<T>& mat, TMat<T>& singlecolumn) singlecolumn must be a mat.length() x 1 matrix, and mat must have non-zero width");
04041
#endif
04042
for(
int i=0; i<mat.
length(); i++)
04043 singlecolumn(i,0) =
mean(mat(i));
04044 }
04045
04046
template<
class T>
04047 void rowVariance(
const TMat<T>& mat,
const TMat<T>& singlecolumn,
const TMat<T>& rowmean)
04048 {
04049
#ifdef BOUNDCHECK
04050
if(singlecolumn.
length()!=mat.
length() || singlecolumn.
width()!=1 || rowmean.
length()!=mat.
length() || rowmean.
width()!=1 || mat.
width()==0)
04051
PLERROR(
"IN void rowVariance(const TMat<T>& mat, TMat<T>& singlecolumn, const TMat<T>& rowmean) singlecolumn and rowmean must be mat.length() x 1 matrices, mat must have non-zero width");
04052
#endif
04053
for(
int i=0; i<mat.
length(); i++)
04054 singlecolumn(i,0) =
variance(mat(i),rowmean(i,0));
04055 }
04056
04057
template<
class T>
04058 void rowSumOfSquares(
const TMat<T>& mat,
const TMat<T>& singlecolumn)
04059 {
04060
#ifdef BOUNDCHECK
04061
if(singlecolumn.
length()!=mat.
length() || singlecolumn.
width()!=1)
04062
PLERROR(
"IN void rowSumOfSquares(const TMat<T>& mat, TMat<T>& singlecolumn) singlecolumn must be a mat.length() x 1 matrix");
04063
#endif
04064
for (
int i=0;i<mat.
length();i++)
04065 {
04066 T ss=0;
04067 T* mi=mat[i];
04068
for (
int j=0;j<mat.width();j++) { T mij=mi[j]; ss+=mij*mij; }
04069 singlecolumn(i,0)=ss;
04070 }
04071 }
04072
04073
template<
class T>
04074 void rowMax(
const TMat<T>& mat,
const TMat<T>& singlecolumn)
04075 {
04076
#ifdef BOUNDCHECK
04077
if(singlecolumn.
length()!=mat.
length() || singlecolumn.
width()!=1 || mat.
width()==0)
04078
PLERROR(
"IN void rowMax(const TMat<T>& mat, TMat<T>& singlecolumn) singlecolumn must be a mat.length() x 1 matrix, and mat must have non-zero width");
04079
#endif
04080
for(
int i=0; i<mat.
length(); i++)
04081 singlecolumn(i,0) =
max(mat(i));
04082 }
04083
04084
template<
class T>
04085 void rowMax(
const TMat<T>& mat,
const TVec<T>& colvec)
04086 {
04087
#ifdef BOUNDCHECK
04088
if(colvec.
length()!=mat.
length())
04089
PLERROR(
"IN void rowSum(const TMat<T>& mat, const TVec<T>& colvec) colvec must have same length as mat");
04090
#endif
04091
for(
int i=0; i<mat.
length(); i++)
04092 colvec[i] =
max(mat(i));
04093 }
04094
04095
template<
class T>
04096 void rowMin(
const TMat<T>& mat,
const TMat<T>& singlecolumn)
04097 {
04098
#ifdef BOUNDCHECK
04099
if(singlecolumn.
length()!=mat.
length() || singlecolumn.
width()!=1 || mat.
width()==0)
04100
PLERROR(
"IN void rowMin(const TMat<T>& mat, TMat<T>& singlecolumn) singlecolumn must be a mat.length() x 1 matrix, and mat must have non-zero width");
04101
#endif
04102
for(
int i=0; i<mat.
length(); i++)
04103 singlecolumn(i,0) =
min(mat(i));
04104 }
04105
04106
04107
template<
class T>
04108 void rowMin(
const TMat<T>& mat,
const TVec<T>& colvec)
04109 {
04110
#ifdef BOUNDCHECK
04111
if(colvec.
length()!=mat.
length())
04112
PLERROR(
"IN void rowSum(const TMat<T>& mat, const TVec<T>& colvec) colvec must have same length as mat");
04113
#endif
04114
for(
int i=0; i<mat.
length(); i++)
04115 colvec[i] =
min(mat(i));
04116 }
04117
04118
template<
class T>
04119 void rowArgmax(
const TMat<T>& mat,
const TMat<T>& singlecolumn)
04120 {
04121
#ifdef BOUNDCHECK
04122
if(singlecolumn.
length()!=mat.
length() || singlecolumn.
width()!=1 || mat.
width()==0)
04123
PLERROR(
"IN void rowMax(const TMat<T>& mat, TMat<T>& singlecolumn) singlecolumn must be a mat.length() x 1 matrix, and mat must have non-zero width");
04124
#endif
04125
for(
int i=0; i<mat.
length(); i++)
04126 singlecolumn(i,0) =
argmax(mat(i));
04127 }
04128
04129
template<
class T>
04130 void rowArgmin(
const TMat<T>& mat,
const TMat<T>& singlecolumn)
04131 {
04132
#ifdef BOUNDCHECK
04133
if(singlecolumn.
length()!=mat.
length() || singlecolumn.
width()!=1 || mat.
width()==0)
04134
PLERROR(
"IN void rowMax(const TMat<T>& mat, TMat<T>& singlecolumn) singlecolumn must be a mat.length() x 1 matrix, and mat must have non-zero width");
04135
#endif
04136
for(
int i=0; i<mat.
length(); i++)
04137 singlecolumn(i,0) =
argmin(mat(i));
04138 }
04139
04145
template<
class T>
04146 void columnSum(
const TMat<T>& mat,
TVec<T>& result)
04147 {
04148
#ifdef BOUNDCHECK
04149
if(result.
length()!=mat.
width())
04150
PLERROR(
"IN void columnSum(const TMat<T>& mat, TVec<T>& result) the length of result must equal the width of mat");
04151
#endif
04152
int l = mat.
length();
04153 result << mat(0);
04154
for(
int j=1; j<l; j++)
04155 result += mat(j);
04156 }
04157
04158
template<
class T>
04159 void columnSumOfSquares(
const TMat<T>& mat,
TVec<T>& result)
04160 {
04161
#ifdef BOUNDCHECK
04162
if(result.
length()!=mat.
width())
04163
PLERROR(
"IN void columnSumOfSquares(const TMat<T>& mat, TVec<T>& result) the length of result must equal the width of mat");
04164
#endif
04165
for(
int j=0; j<mat.
width(); j++)
04166 result[j] =
sum_of_squares(mat.
column(j));
04167 }
04168
04169
template<
class T>
04170 void columnMean(
const TMat<T>& mat,
TVec<T>& result)
04171 {
04172
#ifdef BOUNDCHECK
04173
if(result.
length()!=mat.
width() || mat.
length()==0)
04174
PLERROR(
"IN void columnMean(const TMat<T>& mat, TVec<T>& result) the length of result must equal the width of mat and mat must have non-zero length");
04175
#endif
04176
columnSum(mat,result);
04177 result /=
real(mat.
length());
04178 }
04179
04180
template<
class T>
04181 void columnWeightedMean(
const TMat<T>& mat,
TVec<T>& result)
04182 {
04183
#ifdef BOUNDCHECK
04184
if(result.
length()!=mat.
width()-1 || mat.
length()<=1)
04185
PLERROR(
"IN void columnWeightedMean(const TMat<T>& mat, TVec<T>& result) the length of result must equal the width - 1 of mat and mat must have at least 1 length");
04186
#endif
04187
TVec<T> column_j_vec(mat.
length()), weights_vec(mat.
length());
04188
TMat<T> column_j_mat(mat.
length(), 1), weights_mat(mat.
length(), 1);
04189
for(
int j=0; j<mat.
width()-1; j++){
04190 column_j_mat = mat.
column(j);
04191 weights_mat = mat.
column(mat.
width()-1);
04192 column_j_vec = column_j_mat.
toVecCopy();
04193 weights_vec = weights_mat.toVecCopy();
04194 result[j] =
weighted_mean(column_j_vec, weights_vec);
04195 }
04196 }
04197
04198
template<
class T>
04199 void columnVariance(
const TMat<T>& mat,
TVec<T>& result,
const TVec<T>& columnmean)
04200 {
04201
#ifdef BOUNDCHECK
04202
if(result.
length()!=mat.
width() || columnmean.
length()!=mat.
width() || mat.
length()==0)
04203
PLERROR(
"IN void columnVariance(const TMat<T>& mat, TVec<T>& result, const TVec<T>& columnmean) the length of result and columnmean must equal the width of mat and mat must have non-zero length");
04204
#endif
04205
for(
int j=0; j<mat.
width(); j++)
04206 result[j] =
variance(mat.
column(j),columnmean[j]);
04207 }
04208
04209
template<
class T>
04210 void columnWeightedVariance(
const TMat<T>& mat,
TVec<T>& result,
const TVec<T>& column_weighted_mean)
04211 {
04212
#ifdef BOUNDCHECK
04213
if(result.
length()!=mat.
width()-1 || column_weighted_mean.
length()!=mat.
width()-1 || mat.
length()<=1)
04214
PLERROR(
"IN void columnWeightedVariance(const TMat<T>& mat, TVec<T>& result, const TVec<T>& column_weighted_mean) the length of result and column_weighted_mean must equal the width - 1 of mat and mat must have at least 1 length");
04215
#endif
04216
T column_no_weighted_mean_j;
04217
TVec<T> column_j_vec(mat.
length()), weights_vec(mat.
length());
04218
TMat<T> column_j_mat(mat.
length(), 1), weights_mat(mat.
length(), 1);
04219
for(
int j=0; j<mat.
width()-1; j++){
04220 column_j_mat = mat.
column(j);
04221 weights_mat = mat.
column(mat.
width()-1);
04222 column_j_vec = column_j_mat.
toVecCopy();
04223 weights_vec = weights_mat.toVecCopy();
04224 column_no_weighted_mean_j =
mean(mat.
column(j));
04225 result[j] =
weighted_variance(column_j_vec, weights_vec, column_no_weighted_mean_j, column_weighted_mean[j]);
04226 }
04227 }
04228
04229
template<
class T>
04230 void columnMax(
const TMat<T>& mat,
TVec<T>& result)
04231 {
04232
#ifdef BOUNDCHECK
04233
if(result.
length()!=mat.
width() || mat.
length()==0)
04234
PLERROR(
"IN void columnMax(const TMat<T>& mat, TVec<T>& result) the length of result must equal the width of mat and mat must have non-zero length");
04235
#endif
04236
for(
int j=0; j<mat.
width(); j++)
04237 result[j] =
max(mat.
column(j));
04238 }
04239
04240
template<
class T>
04241 void columnMin(
const TMat<T>& mat,
TVec<T>& result)
04242 {
04243
#ifdef BOUNDCHECK
04244
if(result.
length()!=mat.
width() || mat.
length()==0)
04245
PLERROR(
"IN void columnMax(const TMat<T>& mat, TVec<T>& result) the length of result must equal the width of mat and mat must have non-zero length");
04246
#endif
04247
for(
int j=0; j<mat.
width(); j++)
04248 result[j] =
min(mat.
column(j));
04249 }
04250
04251
template<
class T>
04252 void columnArgmax(
const TMat<T>& mat,
TVec<T>& result)
04253 {
04254
#ifdef BOUNDCHECK
04255
if(result.
length()!=mat.
width() || mat.
length()==0)
04256
PLERROR(
"IN void columnMax(const TMat<T>& mat, TVec<T>& result) the length of result must equal the width of mat and mat must have non-zero length");
04257
#endif
04258
int imax, jmax;
04259
for(
int j=0; j<mat.
width(); j++)
04260 {
04261
argmax(mat.
column(j), imax, jmax);
04262 result[j] = imax;
04263 }
04264 }
04265
04266
template<
class T>
04267 void columnArgmin(
const TMat<T>& mat,
TVec<T>& result)
04268 {
04269
#ifdef BOUNDCHECK
04270
if(result.
length()!=mat.
width() || mat.
length()==0)
04271
PLERROR(
"IN void columnMax(const TMat<T>& mat, TVec<T>& result) the length of result must equal the width of mat and mat must have non-zero length");
04272
#endif
04273
int imin, jmin;
04274
for(
int j=0; j<mat.
width(); j++)
04275 {
04276
argmin(mat.
column(j), imin, jmin);
04277 result[j] = imin;
04278 }
04279 }
04280
04281
template<
class T>
04282 T
mahalanobis_distance(
const TVec<T>& input,
const TVec<T>& meanvec,
const
04283
TMat<T>& inversecovmat)
04284 {
04285
TVec<T> diff = input-meanvec;
04286
return dot(diff,
product(inversecovmat,diff));
04287 }
04288
04290
template<
class T>
04291 inline void computeMean(
const TMat<T>& m,
TVec<T>& meanvec) {
columnMean(m,meanvec); }
04292
04294
template<
class T>
04295 void computeMeanAndVariance(
const TMat<T>& m,
TVec<T>& meanvec,
TVec<T>& variancevec)
04296 {
04297
columnMean(m,meanvec);
04298
columnVariance(m,variancevec,meanvec);
04299 }
04300
04301
template<
class T>
04302 void computeCovar(
const TMat<T>& m,
const TVec<T>& meanvec,
TMat<T>& covarmat)
04303 {
04304
int n = m.
width();
04305 covarmat.
resize(n,n);
04306
transposeProduct(covarmat,m,m);
04307 covarmat /= T(m.
length());
04308
externalProductScaleAcc(covarmat,meanvec,meanvec,T(-1));
04309 }
04310
04311
template<
class T>
04312 void computeMeanAndCovar(
const TMat<T>& m,
TVec<T>& meanvec,
TMat<T>& covarmat)
04313 {
04314
int n = m.
width();
04315 meanvec.
resize(n);
04316 covarmat.
resize(n,n);
04317
columnMean(m,meanvec);
04318
04319
transposeProduct(covarmat,m,m);
04320 covarmat /= T(m.
length());
04321
externalProductScaleAcc(covarmat,meanvec,meanvec,T(-1));
04322
04323
04324
04325
04326
04327
04328
04329 }
04330
04332
template<
class T>
04333 void computeMeanAndStddev(
const TMat<T>& m,
TVec<T>& meanvec,
TVec<T>& stddevvec)
04334 {
04335
columnMean(m,meanvec);
04336
columnVariance(m,stddevvec,meanvec);
04337
for(
int i=0; i<stddevvec.
length(); i++)
04338 stddevvec[i] =
sqrt(stddevvec[i]);
04339 }
04340
04341
04344
template<
class T>
04345 void computeColumnsMeanAndStddev(
const TMat<T>& m,
TMat<T>& meanvec,
TMat<T>& stddevvec)
04346 {
04347
rowMean(m,meanvec);
04348
rowVariance(m,stddevvec,meanvec);
04349
for(
int i=0; i<stddevvec.
length(); i++)
04350 stddevvec[i][0] =
sqrt(stddevvec[i][0]);
04351 }
04352
04354
template<
class T>
04355 void normalize(
TMat<T>& m)
04356 {
04357
TVec<T> meanvec(m.
width());
04358
TVec<T> stddevvec(m.
width());
04359
computeMeanAndStddev(m,meanvec,stddevvec);
04360 m -= meanvec;
04361 m /= stddevvec;
04362 }
04363
04365
template<
class T>
04366 void normalizeRows(
const TMat<T>& m)
04367 {
04368
int l = m.
length();
04369
for(
int i=0; i<l; i++)
04370 {
04371
TVec<T> v = m(i);
04372 v /=
sum(v);
04373 }
04374 }
04375
04377
template<
class T>
04378 void normalizeColumns(
const TMat<T>& m)
04379 {
04380
int w = m.
width();
04381
for(
int j=0; j<w; j++)
04382 {
04383
TMat<T> v = m.
column(j);
04384 v /=
sum(v);
04385 }
04386 }
04387
04389
template<
class T>
04390 void normalize(
TMat<T>& m,
double n)
04391 {
04392
for(
int i=0; i<m.
length(); i++)
04393 {
04394
TVec<T> m_i = m(i);
04395
normalize(m_i,n);
04396 }
04397 }
04398
04399
template<
class T>
04400 void operator+=(
const TMat<T>& m, T scalar)
04401 {
04402 T* m_i = m.
data();
04403
for(
int i=0; i<m.
length(); i++, m_i+=m.
mod())
04404
for(
int j=0; j<m.
width(); j++)
04405 m_i[j] += scalar;
04406 }
04407
04408
template<
class T>
04409 void operator*=(
const TMat<T>& m, T scalar)
04410 {
04411 T* m_i = m.
data();
04412
for(
int i=0; i<m.
length(); i++, m_i+=m.
mod())
04413
for(
int j=0; j<m.
width(); j++)
04414 m_i[j] *= scalar;
04415 }
04416
04417
template<
class T>
04418 inline void operator-=(
const TMat<T>& m, T scalar) { m += (-scalar); }
04419
04420
template<
class T>
04421 inline void operator/=(
const TMat<T>& m, T scalar) { m *= (T(1)/scalar); }
04422
04423
template<
class T>
04424 inline void operator/=(
const TMat<T>& m,
int scalar) { m *= (T(1)/scalar); }
04425
04426
04428
template<
class T>
04429 void operator+=(
const TMat<T>& m,
const TVec<T>& v)
04430 {
04431
#ifdef BOUNDCHECK
04432
if(m.
width()!=v.
length())
04433
PLERROR(
"IN operator+=(const TMat<T>& m, const TVec<T>& v) v must be as long as m is wide");
04434
#endif
04435
T* m_i = m.
data();
04436 T* vv = v.
data();
04437
for(
int i=0; i<m.
length(); i++, m_i+=m.
mod())
04438
for(
int j=0; j<m.
width(); j++)
04439 m_i[j] += vv[j];
04440 }
04441
04443
template<
class T>
04444 void operator-=(
const TMat<T>& m,
const TVec<T>& v)
04445 {
04446
#ifdef BOUNDCHECK
04447
if(m.
width()!=v.
length())
04448
PLERROR(
"IN operator-=(const TMat<T>& m, const TVec<T>& v) v must be as long as m is wide");
04449
#endif
04450
T* m_i = m.
data();
04451 T* vv = v.
data();
04452
for(
int i=0; i<m.
length(); i++, m_i+=m.
mod())
04453
for(
int j=0; j<m.
width(); j++)
04454 m_i[j] -= vv[j];
04455 }
04456
04458
template<
class T>
04459 void operator*=(
const TMat<T>& m,
const TVec<T>& v)
04460 {
04461
#ifdef BOUNDCHECK
04462
if(m.
width()!=v.
length())
04463
PLERROR(
"IN operator*=(const TMat<T>& m, const TVec<T>& v) v must be as long as m is wide");
04464
#endif
04465
T* m_i = m.
data();
04466 T* vv = v.
data();
04467
for(
int i=0; i<m.
length(); i++, m_i+=m.
mod())
04468
for(
int j=0; j<m.
width(); j++)
04469 m_i[j] *= vv[j];
04470 }
04471
04473
template<
class T>
04474 void operator*=(
const TMat<T>& m1,
const TMat<T>& m2)
04475 {
04476
int n=m1.
length();
04477
int l=m1.
width();
04478
#ifdef BOUNDCHECK
04479
if(l!=m2.
width() || n!=m2.
length())
04480
PLERROR(
"IN operator*=(const TMat<T>& m1(%d,%d), const TMat<T>& m2(%d,%d)) sizes differ",
04481 m1.
length(),m1.
width(),m2.
length(),m2.
width());
04482
#endif
04483
T* m1_i = m1.
data();
04484 T* m2_i = m2.
data();
04485
for(
int i=0; i<n; i++, m1_i+=m1.
mod(),m2_i+=m2.
mod())
04486
for(
int j=0; j<l; j++)
04487 m1_i[j] *= m2_i[j];
04488 }
04489
04491
template<
class T>
04492 void operator/=(
const TMat<T>& m,
const TVec<T>& v)
04493 {
04494
#ifdef BOUNDCHECK
04495
if(m.
width()!=v.
length())
04496
PLERROR(
"IN operator/=(const TMat<T>& m, const TVec<T>& v) v must be as long as m is wide");
04497
#endif
04498
T* m_i = m.
data();
04499 T* vv = v.
data();
04500
for(
int i=0; i<m.
length(); i++, m_i+=m.
mod())
04501
for(
int j=0; j<m.
width(); j++)
04502 m_i[j] /= vv[j];
04503 }
04504
04506
template<
class T>
04507 void operator/=(
const TMat<T>& m1,
const TMat<T>& m2)
04508 {
04509
int n=m1.
length();
04510
int l=m1.
width();
04511
#ifdef BOUNDCHECK
04512
if(l!=m2.
width() || n!=m2.
length())
04513
PLERROR(
"IN operator/=(const TMat<T>& m1(%d,%d), const TMat<T>& m2(%d,%d)) sizes differ",
04514 m1.
length(),m1.
width(),m2.
length(),m2.
width());
04515
#endif
04516
T* m1_i = m1.
data();
04517 T* m2_i = m2.
data();
04518
for(
int i=0; i<n; i++, m1_i+=m1.
mod(),m2_i+=m2.
mod())
04519
for(
int j=0; j<l; j++)
04520 m1_i[j] /= m2_i[j];
04521 }
04522
04523
template<
class T>
04524 void operator+=(
const TMat<T>& m1,
const TMat<T>& m2)
04525 {
04526
int n=m1.
length();
04527
int l=m1.
width();
04528
#ifdef BOUNDCHECK
04529
if(m1.
width()!=m2.
width() || m1.
length()!=m2.
length())
04530
PLERROR(
"IN operator+=(const TMat<T>& m1(%d,%d), const TMat<T>& m2(%d,%d)): m1 and m2 must have same dimensions",
04531 m1.
length(),m1.
width(),m2.
length(),m2.
width());
04532
#endif
04533
T* m1_i = m1.
data();
04534 T* m2_i = m2.
data();
04535
for(
int i=0; i<n; i++, m1_i+=m1.
mod(),m2_i+=m2.
mod())
04536
for(
int j=0; j<l; j++)
04537 m1_i[j] += m2_i[j];
04538 }
04539
04540
template<
class T>
04541 void operator-=(
const TMat<T>& m1,
const TMat<T>& m2)
04542 {
04543
int n=m1.
length();
04544
int l=m1.
width();
04545
#ifdef BOUNDCHECK
04546
if(m1.
width()!=m2.
width() || m1.
length()!=m2.
length())
04547
PLERROR(
"IN operator+=(const TMat<T>& m1(%d,%d), const TMat<T>& m2(%d,%d)): m1 and m2 must have same dimensions",
04548 m1.
length(),m1.
width(),m2.
length(),m2.
width());
04549
#endif
04550
T* m1_i = m1.
data();
04551 T* m2_i = m2.
data();
04552
for(
int i=0; i<n; i++, m1_i+=m1.
mod(),m2_i+=m2.
mod())
04553
for(
int j=0; j<l; j++)
04554 m1_i[j] -= m2_i[j];
04555 }
04556
04557
template<
class T>
04558 TMat<T> operator-(
const TMat<T>& m1,
const TMat<T>& m2)
04559 {
04560
TMat<T> result(m1.
length(), m1.
width());
04561
substract(m1,m2,result);
04562
return result;
04563 }
04564
04565
template<
class T>
04566 TMat<T> operator+(
const TMat<T>& m1,
const TMat<T>& m2)
04567 {
04568
TMat<T> result(m1.
length(), m1.
width());
04569
add(m1,m2,result);
04570
return result;
04571 }
04572
04573
template<
class T>
04574 void substract(
const TMat<T>& m1,
const TMat<T>& m2,
TMat<T>& destination)
04575 {
04576
#ifdef BOUNDCHECK
04577
if(m1.
width()!=m2.
width() || m1.
length()!=m2.
length()
04578 || m1.
width()!=destination.
width() || m1.
length()!=destination.
length())
04579
PLERROR(
"IN substract(m1(%d,%d), m2(%d,%d), dest(%d,%d)): args must have same dimensions",
04580 m1.
length(),m1.
width(),m2.
length(),m2.
width(),destination.
length(),
04581 destination.
width());
04582
#endif
04583
T* m1_i = m1.
data();
04584 T* m2_i = m2.
data();
04585 T* d_i = destination.
data();
04586
int m1_mod = m1.
mod();
04587
int m2_mod = m2.
mod();
04588
int d_mod = destination.
mod();
04589
int w = m1.
width();
04590
for (
int i=0;i<m1.
length();i++,m1_i+=m1_mod,m2_i+=m2_mod,d_i+=d_mod)
04591
for (
int j=0;j<w;j++)
04592 d_i[j] = m1_i[j] - m2_i[j];
04593 }
04594
04595
template<
class T>
04596 void add(
const TMat<T>& m1,
const TMat<T>& m2,
TMat<T>& destination)
04597 {
04598
#ifdef BOUNDCHECK
04599
if(m1.
width()!=m2.
width() || m1.
length()!=m2.
length()
04600 || m1.
width()!=destination.
width() || m1.
length()!=destination.
length())
04601
PLERROR(
"IN substract(m1(%d,%d), m2(%d,%d), dest(%d,%d)): args must have same dimensions",
04602 m1.
length(),m1.
width(),m2.
length(),m2.
width(),destination.
length(),
04603 destination.
width());
04604
#endif
04605
T* m1_i = m1.
data();
04606 T* m2_i = m2.
data();
04607 T* d_i = destination.
data();
04608
int m1_mod = m1.
mod();
04609
int m2_mod = m2.
mod();
04610
int d_mod = destination.
mod();
04611
int w = m1.
width();
04612
for (
int i=0;i<m1.
length();i++,m1_i+=m1_mod,m2_i+=m2_mod,d_i+=d_mod)
04613
for (
int j=0;j<w;j++)
04614 d_i[j] = m1_i[j] + m2_i[j];
04615 }
04616
04618
template<
class T>
04619 TMat<T> operator-(
const TMat<T>& m)
04620 {
04621
TMat<T> opposite(m.
length(),m.
width());
04622 T *m_i=m.
data();
04623 T *o_i=opposite.
data();
04624
for (
int i=0;i<m.
length();i++,m_i+=m.
mod(),o_i+=opposite.
mod())
04625
for (
int j=0;j<m.
width();j++)
04626 o_i[j] = - m_i[j];
04627
return opposite;
04628 }
04629
04631
template<
class T>
04632 void negateElements(
const TMat<T>& m)
04633 {
04634 T* m_i = m.
data();
04635
for(
int i=0; i<m.
length(); i++, m_i+=m.
mod())
04636
for(
int j=0; j<m.
width(); j++)
04637 m_i[j] = -m_i[j];
04638 }
04639
04641
template<
class T>
04642 void invertElements(
const TMat<T>& m)
04643 {
04644 T* m_i = m.
data();
04645
for(
int i=0; i<m.
length(); i++, m_i+=m.
mod())
04646
for(
int j=0; j<m.
width(); j++)
04647 m_i[j] = 1.0/m_i[j];
04648 }
04649
04650
04651
04652
template<
class T>
04653 TMat<T> leftPseudoInverse(
TMat<T>& m)
04654 {
04655
TMat<T> inv(m.
width(), m.
length());
04656
leftPseudoInverse(m,inv);
04657
return inv;
04658 }
04659
04660
04661
04662
template<
class T>
04663 void leftPseudoInverse(
const TMat<T>& m,
TMat<T>& inv)
04664 {
04665
if (m.
length()==m.
width())
04666
inverse(m,inv);
04667
if (m.
length()<m.
width())
04668
PLERROR(
"leftPseudoInverse: matrix length(%d) must be >= width(%d)",
04669 m.
length(), m.
width());
04670
PLERROR(
"SVD not implemented yet");
04671 }
04672
04673
04674
04675
template<
class T>
04676 TMat<T> rightPseudoInverse(
TMat<T>& m)
04677 {
04678
TMat<T> inv(m.
width(), m.
length());
04679
rightPseudoInverse(m,inv);
04680
return inv;
04681 }
04682
04683
04684
04685
template<
class T>
04686 void rightPseudoInverse(
const TMat<T>& m,
TMat<T>& inv)
04687 {
04688
if (m.
length()==m.
width())
04689
inverse(m,inv);
04690
if (m.
length()>m.
width())
04691
PLERROR(
"rightPseudoInverse: matrix length(%d) must be <= width(%d)",
04692 m.
length(), m.
width());
04693
PLERROR(
"SVD not implemented yet");
04694 }
04695
04696
04697
04698
template<
class T>
04699 TMat<T> inverse(
TMat<T>& m)
04700 {
04701
TMat<T> inv(m.
length(),m.
length());
04702
inverse(m,inv);
04703
return inv;
04704 }
04705
04706
04707
04708
template<
class T>
04709 void inverse(
const TMat<T>& m,
TMat<T>& inv)
04710 {
04711
int n=m.
length();
04712
if (m.
width()!=n)
04713
PLERROR(
"inverse(TMat<T>,TMat<T>): argument(%d,%d) must be square matrix",
04714 m.
width(), n);
04715 inv.
resize(n,n);
04716
if (n==1)
04717 inv.
data()[0]=1.0/m.
data()[0];
04718
else
04719
PLERROR(
"matrix inverse not implemented yet");
04720 }
04721
04722
04723
04724
04725
04726
04727
04728
04729
04730
04731
template<
class T>
04732 void solveLinearSystemByCholesky(
const TMat<T>& A,
const TMat<T>& B,
TMat<T>& X,
TMat<T>* pL=0,
TVec<T>* py=0)
04733 {
04734
int n=A.
length();
04735
int m=X.
width();
04736
if (X.
length()!=n || A.
width()!=n || B.
length()!=n || B.
width()!=m)
04737
PLERROR(
"solveLinearSystemByCholesky: A(%d,%d) * X(%d,%d) == B(%d,%d), incompatible",
04738 n,A.
width(),X.
length(),m,B.
length(),B.
width());
04739
TMat<T>* L;
04740
TVec<T>* y;
04741
if (pL) L=pL;
else L =
new TMat<T>(n,n);
04742
if (py) y=py;
else y =
new TVec<T>(n);
04743
choleskyDecomposition(A,*L);
04744
choleskySolve(*L,B,X,*y);
04745
if (!pL)
delete L;
04746
if (!py)
delete y;
04747 }
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757
04758
04759
template<
class T>
04760 void solveTransposeLinearSystemByCholesky(
const TMat<T>& A,
const TMat<T>& B,
TMat<T>& X,
TMat<T>* pL=0,
TVec<T>* py=0)
04761 {
04762
int n=X.
length();
04763
int m=X.
width();
04764
if (A.
length()!=m || A.
width()!=m || B.
length()!=n || B.
width()!=m)
04765
PLERROR(
"solveTransposeLinearSystemByCholesky: X(%d,%d) * A(%d,%d) == B(%d,%d), incompatible",
04766 n,m,A.
length(),A.
width(),B.
length(),B.
width());
04767
TMat<T>* L;
04768
TVec<T>* y;
04769
if (pL) L=pL;
else L =
new TMat<T>(m,m);
04770
if (py) y=py;
else y =
new TVec<T>(m);
04771
choleskyDecomposition(A,*L);
04772
for (
int i=0;i<n;i++)
04773
choleskySolve(*L,B(i),X(i),*y);
04774
if (!pL)
delete L;
04775
if (!py)
delete y;
04776 }
04777
04778
04779
04780
04781
04782
04783
04784
04785
04786
04787
04788
04789
04790
04791
04792
04793
template<
class T>
04794 void choleskyDecomposition(
const TMat<T>& A,
TMat<T>& L)
04795 {
04796
int n = A.
length();
04797
if (n!=A.
width())
04798
PLERROR(
"choleskyDecomposition: non-square matrix %dx%d\n",n,A.
width());
04799 L.
resize(n,n);
04800
int i,j,
k;
04801 T
sum;
04802
bool restart=
false;
04803
do
04804 {
04805 restart=
false;
04806
for (i=0;i<n;i++)
04807 {
04808
const T* Ai = A[i];
04809 T* Li = L[i];
04810 T Lii=0;
04811
for (j=i;j<n;j++)
04812 {
04813 T* Lj = L[j];
04814
for (
sum=Ai[j],
k=i-1;
k>=0;
k--)
sum -= Li[
k] * Lj[
k];
04815
if (i==j)
04816 {
04817
if (
sum <= 0.0)
04818 {
04819 T eps = -1.1*
sum;
04820
if (
sum==0) eps=1e-8;
04821
PLWARNING(
"Cholesky decomposition would fail: add %g to diagonal",eps);
04822 T* Aii=A.data();
04823
int addm=A.mod()+1;
04824
for (
int ii=0;ii<n;ii++,Aii+=addm) *Aii += eps;
04825 restart=
true;
04826
break;
04827 }
04828 Lii =
sqrt(
sum);
04829 }
04830
else Lj[i] =
sum/Lii;
04831 }
04832
if (restart)
break;
04833 Li[i] = Lii;
04834 }
04835 }
04836
while (restart);
04837
04838 }
04839
04840
04841
04842
04843
04844
04845
04846
04847
04848
04849
04850
04851
04852
04853
04854
04855
04856
04857
04858
04859
04860
04861
template<
class T>
04862 void bpropCholeskyDecomposition(
const TMat<T>& A,
const TMat<T>& L,
04863
TMat<T>& dC_dA,
TMat<T>& dC_dL)
04864 {
04865
int n = A.
length();
04866
if (dC_dA)
04867 dC_dA.
resize(n,n);
04868
int i,j,
k;
04869
for (i=n-1;i>=0;i--)
04870 {
04871
const T* Li = L[i];
04872 T* dC_dLi = dC_dL[i];
04873 T* dC_dAi = dC_dA[i];
04874 T invLii = 1.0/Li[i];
04875
for (j=n-1;j>i;j--)
04876 {
04877
const T* Lj = L[j];
04878 T* dC_dLj = dC_dL[j];
04879 T dC_dLji = dC_dLj[i];
04880 dC_dLi[i] -= dC_dLji * Lj[i] * invLii;
04881 dC_dAi[j] += dC_dLji * invLii;
04882
for (
k=0;
k<i;
k++)
04883 {
04884 dC_dLi[
k] -= dC_dLji * Lj[
k] * invLii;
04885 dC_dLj[
k] -= dC_dLji * Li[
k] * invLii;
04886 }
04887 }
04888 T dC_dLii = dC_dLi[i];
04889 dC_dAi[i] += 0.5 * dC_dLii * invLii;
04890
for (
k=0;
k<i;
k++)
04891 dC_dLi[
k] -= dC_dLii * Li[
k] * invLii;
04892 }
04893 }
04894
04895
04896
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908
04909
04910
04911
04912
04913
04914
template<
class T>
04915 void choleskySolve(
const TMat<T>& L,
TVec<T> b,
TVec<T> x,
TVec<T>& y)
04916 {
04917
int i,
k;
04918 T
sum;
04919
int n = L.
length();
04920
if (L.
width()!=n)
04921
PLERROR(
"choleskySolve: matrix L (%d x %d) is not square!",
04922 n, L.
width());
04923
if (b.
length()!=n ||
x.length()!=n)
04924
PLERROR(
"choleskySolve: RHS vector b(%d) or unknown x(%d) incompatiable with L(%d,%d)",
04925 b.
length(),
x.length(),n,n);
04926
04927 T* bp = b.
data();
04928 T* xp =
x.data();
04929 T* yp = y.
data();
04930
04931
04932
04933
04934
for (i=0;i<n;i++)
04935 {
04936
const T* Li = L[i];
04937
for (
sum=bp[i],
k=i-1;
k>=0;
k--)
sum -= Li[
k] * yp[
k];
04938 yp[i] =
sum / Li[i];
04939 }
04940
04941
04942
04943
for (i=n-1;i>=0;i--)
04944 {
04945
for (
sum=yp[i],
k=i+1;
k<n;
k++)
sum -= L[
k][i] * xp[
k];
04946 xp[i] =
sum / L[i][i];
04947 }
04948 }
04949
04950
04951
04952
template<
class T>
04953 void choleskySolve(
const TMat<T>& L,
const TMat<T>& B,
TMat<T>& X,
TVec<T>& y)
04954 {
04955
int i,
k;
04956 T
sum;
04957
int n = L.
length();
04958
int m = X.
width();
04959
if (L.
width()!=n)
04960
PLERROR(
"choleskySolve: matrix L (%d x %d) is not square!",
04961 n, L.
width());
04962
if (B.
length()!=n || B.
width() !=m)
04963
PLERROR(
"choleskySolve: RHS matrix B(%d,%d) instead of (%d,%d) like X",
04964 B.
length(),B.
width(), n, m);
04965
if (X.
length()!=n)
04966
PLERROR(
"choleskySolve: X(%d,%d) not compatible with L(%d,%d)",
04967 X.
length(),m,n,n);
04968
if (y.
length()!=n)
04969
PLERROR(
"choleskySolve: y(%d) not compatible with L(%d,%d)",
04970 y.
length(),n,n);
04971
int bmod = B.
mod();
04972
int xmod = X.
mod();
04973
04974
for (
int j=0;j<m;j++)
04975 {
04976 T* bp = B.
data()+j;
04977 T* yp = y.
data();
04978
04979
04980
04981
for (i=0;i<n;i++,bp+=bmod)
04982 {
04983
const T* Li = L[i];
04984
for (
sum = *bp,
k=i-1;
k>=0;
k--)
sum -= Li[
k] * yp[
k];
04985 yp[i] =
sum / Li[i];
04986 }
04987
04988
04989
04990
for (i=n-1;i>=0;i--)
04991 {
04992
sum=yp[i];
04993
if (i+1<n)
04994 {
04995 T* xp = &X(i+1,j);
04996
for (
k=i+1;
k<n;
k++,xp+=xmod)
sum -= L[
k][i] * *xp;
04997 }
04998 X(i,j) =
sum / L[i][i];
04999 }
05000 }
05001 }
05002
05003
05004
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015
05016
05017
05018
05019
05020
05021
05022
05023
05024
05025
05026
template<
class T>
05027 void bpropCholeskySolve(
const TMat<T>& L,
const TVec<T>& x,
const TVec<T>& y,
05028
TMat<T>& dC_dL,
TVec<T>& dC_db,
TVec<T>& dC_dx)
05029 {
05030
int n = L.
length();
05031
int i,
k;
05032
TVec<T> dC_dy(n);
05033
const T *xp =
x.data();
05034
const T *yp = y.
data();
05035 T *dC_dbp = dC_db.
data();
05036 T *dC_dxp = dC_dx.
data();
05037 T* dC_dyp = dC_dy.
data();
05038
05039
05040
for (i=0;i<n;i++)
05041 {
05042
const T* Li = L[i];
05043 T invLii = 1.0 / Li[i];
05044 dC_dyp[i] = dC_dxp[i] * invLii;
05045 T dC_dxi = dC_dxp[i];
05046 dC_dL[i][i] -= dC_dxp[i] * xp[i] * invLii;
05047
for (
k=i+1;
k<n;
k++)
05048 {
05049 dC_dxp[
k] -= dC_dxi * L[
k][i] * invLii;
05050 dC_dL[
k][i] -= dC_dxi * xp[
k] * invLii;
05051 }
05052 }
05053
05054
05055
for (i=n-1;i>=0;i--)
05056 {
05057
const T* Li = L[i];
05058 T* dC_dLi = dC_dL[i];
05059 T invLii = 1.0 / Li[i];
05060 T dC_dyi = dC_dyp[i];
05061 T dC_dyi_over_Lii = dC_dyi * invLii;
05062 dC_dbp[i] += dC_dyi_over_Lii;
05063 dC_dLi[i] -= dC_dyi_over_Lii * yp[i];
05064
for (
k=0;
k<i;
k++)
05065 {
05066 dC_dyp[
k] -= dC_dyi_over_Lii * Li[
k];
05067 dC_dLi[
k] -= dC_dyi_over_Lii * yp[
k];
05068 }
05069 };
05070 }
05071
05072
05073
05074
05075
05076
05077
05078
05079
05080
05081
05082
05083
05084
05085
05086
05087
05088
05089
05090
05091
05092
05093
template<
class T>
05094 real choleskyInvert(
const TMat<T>& A,
TMat<T>& Ainv)
05095 {
05096
int n= A.
length();
05097
TMat<T> L(n,n);
05098 Ainv.
resize(n,n);
05099
05100
choleskyDecomposition(A,L);
05101
05102
05103
real logdet =
log(fabs(L(0,0)));
05104
for(
int i=1; i<n; i++)
05105 logdet +=
log(fabs(L(i,i)));
05106 logdet *= 2;
05107
05108
05109
05110
int i,j;
05111 T *Lii = L.
data();
05112
for (i=0;i<n;i++,Lii+=1+n)
05113 *Lii = 1.0 / *Lii;
05114
05115
for (j=0;j<n;j++)
05116 {
05117 T *Linv_xj = L[j];
05118
for (i=j+1;i<n;i++)
05119 {
05120 T
sum=0.0;
05121 T* Li = L[i];
05122
int k;
05123
for (
k=j;
k<i;
k++)
sum -= Li[
k] * Linv_xj[
k];
05124 Linv_xj[i] =
sum * Li[i];
05125 }
05126 }
05127
05128
05129
05130
for (j=0;j<n;j++)
05131 {
05132 T* Linv_xj = L[j];
05133
for (i=n-1;i>=j;i--)
05134 {
05135 T
sum = Linv_xj[i];
05136
int k;
05137
for (
k=i+1;
k<n;
k++)
05138
sum -= L[
k][i] * Ainv[
k][j];
05139 Ainv[i][j] =
sum * L[i][i];
05140 }
05141
for (i=j-1;i>=0;i--)
05142 Ainv[i][j] = Ainv[j][i];
05143 };
05144
05145
return logdet;
05146 }
05147
05148
05149
05150
template<
class T>
05151 TVec<T> choleskySolve(
const TMat<T>& A,
const TVec<T>& b)
05152 {
05153
int n = A.
length();
05154
TMat<T> L(n,n);
05155
TVec<T> x(n);
05156
choleskyDecomposition(A,L);
05157
choleskySolve(L,b,
x);
05158
return x;
05159 }
05160
05161
05162
05163
template<
class T>
05164 TMat<T> choleskyInvert(
const TMat<T>& A)
05165 {
05166
int n=A.
length();
05167
TMat<T> Ainv(n,n);
05168
choleskyInvert(A,Ainv);
05169
return Ainv;
05170 }
05171
05172
template<
class T>
05173 void LU_decomposition(
TMat<T>& A,
TVec<T>& Trow,
int& detsign,
TVec<T>* p=0)
05174 {
05175
int n=A.
length();
05176
if (n!=A.
width())
05177
PLERROR(
"LU_decomposition: matrix A(%d,%d) should be square", n,A.
width());
05178
TVec<T>* pivot = (p==0)?
new TVec<T>(n):p;
05179 T* pv = pivot->
data();
05180 detsign = 1;
05181
for (
int i=0;i<n;i++)
05182 {
05183 T max_abs =
maxabs(A(i));
05184
if (max_abs==0)
05185
PLERROR(
"LU_decomposition: %d-th row has only zeros",i);
05186 pv[i] = 1.0 / max_abs;
05187 }
05188
int mod = A.
mod();
05189
for (
int j=0;j<n;j++)
05190 {
05191
for (
int i=0;i<j;i++)
05192 {
05193 T* Ai = A[i];
05194 T* Akj = A.
data()+j;
05195 T Uij = Ai[j];
05196
for (
int k=0;
k<i;
k++,Akj+=mod)
05197 Uij -= Ai[
k] * *Akj;
05198 Ai[j] = Uij;
05199 }
05200 T max_abs = 0;
05201
int maxi = 0;
05202
for (
int i=j;i<n;i++)
05203 {
05204 T* Ai = A[i];
05205 T* Akj = A.
data()+j;
05206 T Lij = Ai[j];
05207
for (
int k=0;
k<j;
k++,Akj+=mod)
05208 Lij -= Ai[
k] * *Akj;
05209 Ai[j] = Lij;
05210 T piv = fabs(Lij) * pv[i];
05211
if (piv >= max_abs)
05212 {
05213 maxi = i;
05214 max_abs = piv;
05215 }
05216 }
05217
if (j!=maxi)
05218
05219 {
05220 A.
swapRows(j,maxi);
05221 pv[maxi]=pv[j];
05222 detsign = -detsign;
05223 }
05224 Trow[j] = maxi;
05225 T& Ajj = A(j,j);
05226
if (Ajj==0) Ajj=1e-20;
05227
if (j<n-1)
05228 {
05229 T denom = 1.0/Ajj;
05230 T* Aij = &A(j+1,j);
05231
for (
int i=j+1;i<n;i++, Aij+=mod)
05232 *Aij *= denom;
05233 }
05234 }
05235
if (p!=0)
delete pivot;
05236 }
05237
05238
05239
template<
class T>
05240 T
det(
const TMat<T>& A)
05241 {
05242
int n = A.
length();
05243
if (n!=A.
width())
05244
PLERROR(
"det(const TMat<T>& A): A(%d,%d) is not square!",n,A.
width());
05245
for (
int i=0;i<n;i++)
05246 {
05247 T max_abs =
maxabs(A(i));
05248
if (max_abs==0)
05249
return 0.0;
05250 }
05251
TMat<T> LU(A.
copy());
05252
TVec<T> Trow(n);
05253
TVec<T> p(n);
05254
int detsign;
05255
LU_decomposition(LU, Trow, detsign);
05256
return det(LU,detsign);
05257 }
05258
05259
05260
05261
template<
class T>
05262 T
det(
const TMat<T>& LU,
int detsign)
05263 {
05264 T determinant = detsign;
05265
int mod = LU.
mod();
05266
int n = LU.
width();
05267
if (n!=LU.
width())
05268
PLERROR(
"det(const TMat<T>& LU, int detsign): LU(%d,%d) is not square!",n,LU.
width());
05269 T* LUii = LU.
data();
05270
for (
int i=0;i<n;i++, LUii+=1+mod)
05271 determinant *= *LUii;
05272
return determinant;
05273 }
05274
05275
05276
template<
class T>
05277 void equals(
const TMat<T>& src, T v,
TMat<T>& dest)
05278 {
05279
int l=src.
length();
05280
int w=src.
width();
05281
#ifdef BOUNDCHECK
05282
if (l!=dest.
length() || w!=dest.
width())
05283
PLERROR(
"equals(TMat<T>(%d,%d),T,TMat<T>(%d,%d)) args of unequal dimensions",
05284 src.
length(),src.
width(),dest.
length(),dest.
width());
05285
#endif
05286
for (
int i=0;i<l;i++)
05287 {
05288
const T* s=src[i];
05289 T* d=dest[i];
05290
for (
int j=0;j<w;j++)
05291
if (s[j]==v) d[j]=1.0;
else d[j]=0.0;
05292 }
05293 }
05294
05295
05296
template<
class T>
05297 void transpose(
const TMat<T> src,
TMat<T> dest)
05298 {
05299
int l=src.
length();
05300
int w=src.
width();
05301
#ifdef BOUNDCHECK
05302
if (w!=dest.
length() || l!=dest.
width())
05303
PLERROR(
"tranpose(TMat<T>(%d,%d),T,TMat<T>(%d,%d)) args of unequal dimensions",
05304 src.
length(),src.
width(),dest.
length(),dest.
width());
05305
#endif
05306
int dmod=dest.
mod();
05307
for (
int i=0;i<l;i++)
05308 {
05309
const T* si=src[i];
05310 T* dji= &dest(0,i);
05311
for (
int j=0;j<w;j++,dji+=dmod)
05312 *dji = si[j];
05313 }
05314 }
05315
05316
05317
template<
class T>
05318 TMat<T> transpose(
const TMat<T>& src)
05319 {
05320
TMat<T> res(src.
width(),src.
length());
05321
transpose(src,res);
05322
return res;
05323 }
05324
05325
05326
template<
class T>
05327 void apply(T (*func)(
const TVec<T>&),
const TMat<T>& m,
TMat<T>& dest)
05328 {
05329
if (dest.
length()!=m.
length())
05330
PLERROR(
"apply: m.length_=%d, dest.length_=%d",
05331 m.
length(),dest.
length());
05332
for (
int i=0;i<m.
length();i++)
05333 dest(i,0)=func(m(i));
05334 }
05335
05336
template<
class T>
05337 void apply(T (*func)(
const TVec<T>&,
const TVec<T>&),
const TMat<T>& m1,
const TMat<T>& m2,
05338
TMat<T>& dest)
05339 {
05340
if (dest.
length()!=m1.
length() || m1.
length()!=m2.
length())
05341
PLERROR(
"apply: m1.length_=%d, m2.length_=%d, dest.length_=%d",
05342 m1.
length(),m2.
length(),dest.
length());
05343
for (
int i=0;i<m1.
length();i++)
05344 dest(i,0)=func(m1(i),m2(i));
05345 }
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
template<
class T>
05359 void linearRegressionNoBias(
TMat<T> inputs,
TMat<T> outputs, T weight_decay,
05360
TMat<T> weights)
05361 {
05362
int inputsize = inputs.
width();
05363
int outputsize = outputs.
width();
05364
int l = inputs.
length();
05365
if(outputs.
length()!=l)
05366
PLERROR(
"In linearRegressionNoBias: inputs and outputs should have the same length");
05367
if(weights.
length()!=inputsize || weights.
width()!=outputsize)
05368
PLERROR(
"In linearRegressionNoBias: weights should be a (inputsize x outputsize) matrix (%d x %d)",inputsize,outputsize);
05369
TMat<T> XtX(inputsize,inputsize);
05370
transposeProduct(XtX, inputs,inputs);
05371
TMat<T> XtY(inputsize,outputsize);
05372
transposeProduct(XtY, inputs,outputs);
05373
for(
int i=0; i<inputsize; i++)
05374 XtX(i,i) += weight_decay;
05375
solveLinearSystemByCholesky(XtX,XtY,weights);
05376 }
05377
05378
05379
05380
05381
05382
05383
05384
05385
05386
05387
05388
05389
05390
05391
05392
template<
class T>
05393 void linearRegression(
TMat<T> inputs,
TMat<T> outputs, T weight_decay,
05394
TMat<T> theta_t)
05395 {
05396
int l = inputs.
length();
05397
int n_inputs = inputs.
width();
05398
int n_outputs = outputs.
width();
05399
if (outputs.
length()!=l)
05400
PLERROR(
"linearRegression: inputs.length_=%d while outputs.length_=%d",
05401 l,outputs.
length());
05402
if (theta_t.
length()!=n_inputs+1 || theta_t.
width()!=n_outputs)
05403
PLERROR(
"linearRegression: theta_t(%d,%d) should be (n_inputs(%d)+1)xn_outputs(%d)",
05404 theta_t.
length(),theta_t.
width(),n_inputs,n_outputs);
05405
05406
int n=n_inputs+1;
05407
05408
TMat<T> XtX(n,n);
05409
TMat<T> XtY(n,n_outputs);
05410
05411
05412
05413
05414
int xmod=inputs.
mod();
05415
int ymod=outputs.
mod();
05416 T *xt = inputs.
data();
05417 T *yt = outputs.
data();
05418 XtX(0,0) = l;
05419
for (
int t=0;t<l;t++,xt+=xmod,yt+=ymod)
05420 {
05421 T* xx0 = XtX.
data();
05422 T* xy0 = XtY.
data();
05423
for (
int j=0;j<n_outputs;j++)
05424 xy0[j] += yt[j];
05425 T *xxi = xx0+n;
05426 T *xyi = xy0+n_outputs;
05427
for (
int i=0;i<n_inputs;i++,xxi+=n,xyi+=n_outputs)
05428 {
05429 T xti = xt[i];
05430 xxi[0]+=xti;
05431 T *xxip=xxi+1;
05432
for (
int j=0;j<i;j++)
05433 xxip[j] += xti*xt[j];
05434 xxip[i]+=xti*xti;
05435
for (
int j=0;j<n_outputs;j++)
05436 xyi[j] += xti * yt[j];
05437 }
05438 }
05439
05440 T* xx = XtX.
data();
05441 T* xxi = xx+n;
05442
for (
int i=1;i<n;i++,xxi+=n)
05443 {
05444 T *xx_i=xx+i;
05445
for (
int j=0;j<i;j++,xx_i+=n)
05446 *xx_i = xxi[j];
05447 }
05448
05449
05450 T* xxii = &XtX(1,1);
05451
for (
int i=0;i<n_inputs;i++,xxii+=1+n)
05452 *xxii += weight_decay;
05453
05454
05455
solveLinearSystemByCholesky(XtX,XtY,theta_t);
05456 }
05457
05458
05459
05460
05461
05462
05463
05464
template<
class T>
05465 void linearRegression(
TVec<T> inputs,
TVec<T> outputs, T weight_decay,
TVec<T> theta_t)
05466 {
05467
int npts = inputs.
length();
05468
05469
if (outputs.
length()!=npts)
05470
PLERROR(
"linearRegression: inputs.length_=%d while outputs.length_=%d",
05471 inputs.
length(),outputs.
length());
05472
if (theta_t.
length()!=2)
05473
PLERROR(
"linearRegression: theta_t(%d) should be 2", theta_t.
length());
05474
05475 T sum_x = 0, sum_y = 0, sum_xy = 0, sum_x2 = 0, sum2_x = 0, sum2_y = 0;
05476
05477
for (
int i = 0; i < npts; ++i) {
05478 sum_x += inputs[i];
05479 sum_y += outputs[i];
05480 sum_xy += inputs[i] * outputs[i];
05481 sum_x2 += inputs[i] * inputs[i];
05482 }
05483 sum2_x = sum_x * sum_x;
05484 sum2_y = sum_y * sum_y;
05485
05486
05487 theta_t[1] = (sum_xy - (sum_x * sum_y) / npts) / (sum_x2 + weight_decay - sum2_x / npts);
05488
05489 theta_t[0] = (sum_y - theta_t[1] * sum_x) / npts;
05490 }
05491
05492
05493
template<
class T>
05494 TMat<T> smooth(
TMat<T> data,
int windowsize)
05495 {
05496
TVec<T> sumvec(data.
width());
05497
TMat<T> result(data.
length(), data.
width());
05498
int currentwindowsize = windowsize/2;
05499
for(
int k=0;
k<currentwindowsize;
k++)
05500 sumvec += data(
k);
05501 result(0) << sumvec;
05502
05503
TVec<T> res0 = result(0);
05504 res0 /= (T)currentwindowsize;
05505 result(0) << res0;
05506
05507
for(
int i=0; i<data.length(); i++)
05508 {
05509
int lowi = i-(windowsize-1)/2;
05510
int highi = i+windowsize/2;
05511
if(lowi-1>=0)
05512 {
05513 sumvec -= data(lowi-1);
05514 currentwindowsize--;
05515 }
05516
if(highi<data.length())
05517 {
05518 sumvec += data(highi);
05519 currentwindowsize++;
05520 }
05521 result(i) << sumvec;
05522
05523
TVec<T> resi = result(i);
05524 resi /= (T)currentwindowsize;
05525 result(i) << resi;
05526 }
05527
05528
05529
return result;
05530 }
05531
05532
05533
template<
class T>
05534 TMat<T> square(
const TMat<T>& m)
05535 {
05536
TMat<T> res(m.
length(), m.
width());
05537
for(
int i=0; i<m.
length(); i++)
05538
for(
int j=0; j<m.
width(); j++)
05539 res(i,j) =
square(m(i,j));
05540
return res;
05541 }
05542
05543
template<
class T>
05544 TMat<T> sqrt(
const TMat<T>& m)
05545 {
05546
TMat<T> res(m.
length(), m.
width());
05547
for(
int i=0; i<m.
length(); i++)
05548
for(
int j=0; j<m.
width(); j++)
05549 res(i,j) =
sqrt(m(i,j));
05550
return res;
05551 }
05552
05553
template<
class T>
05554 inline void affineMatrixInitialize(
TMat<T> W,
bool output_on_columns=
true,
real scale=1.0)
05555 {
05556
int n_inputs = output_on_columns?W.
width():W.
length();
05557
real delta = scale/n_inputs;
05558
fill_random_uniform(W,-delta,delta);
05559 W(0).
clear();
05560 }
05561
05562
template<
class T>
05563 TMat<T> grep(
TMat<T> data,
int col,
TVec<T> values,
bool exclude=
false)
05564 {
05565
TMat<T> result(data.
length(),data.
width());
05566
int length=0;
05567
05568
for(
int i=0; i<data.
length(); i++)
05569 {
05570
bool contains = values.
contains(data(i,col));
05571
if( (!exclude && contains) || (exclude && !contains) )
05572 result(length++) << data(i);
05573 }
05574 result.
resize(length,result.
width());
05575 result.
compact();
05576
return result;
05577 }
05578
05579
05580
template<
class T>
05581 void convolve(
TMat<T> m,
TMat<T> mask,
TMat<T> result)
05582 {
05583
if(result.
length() != m.
length()-mask.
length()+1 || result.
width() != m.
width()-mask.
width()+1)
05584
PLERROR(
"In convolve(TMat<T> m, TMat<T> mask, TMat<T> result), result does not have the appropriate dimensions");
05585 T
sum;
05586
for(
int i=0; i<result.
length(); i++)
05587
for(
int j=0; j<result.
width(); j++)
05588 {
05589 T* maskptr = mask.
data();
05590 T* mptr = m[i]+j;
05591
sum = 0.0;
05592
for(
int l=0; l<mask.
length(); l++, maskptr += mask.
mod(), mptr += m.mod())
05593
for(
int c=0; c<mask.
width(); c++)
05594
sum += maskptr[c] * mptr[c];
05595 result(i,j) =
sum;
05596 }
05597 }
05598
05599
template<
class T>
05600 void subsample(
TMat<T> m,
int thesubsamplefactor,
TMat<T> result)
05601 {
05602 T
sum;
05603
int norm = thesubsamplefactor * thesubsamplefactor;
05604
for(
int i=0; i<result.
length(); i++)
05605
for(
int j=0; j<result.
width(); j++)
05606 {
05607 T* mptr = m[thesubsamplefactor*i]+thesubsamplefactor*j;
05608
sum = 0.0;
05609
for(
int l=0; l<thesubsamplefactor; l++, mptr += m.mod())
05610
for(
int c=0; c<thesubsamplefactor; c++)
05611
sum += mptr[c];
05612 result(i,j) =
sum/
norm;
05613 }
05614 }
05615
05616
05617
template<
class T>
05618 void classification_confusion_matrix(
TMat<T> outputs,
TMat<T> target_classes,
TMat<T> confusion_matrix)
05619 {
05620
int argmax, target;
05621 T v_max, tmp;
05622
05623
for (
int i=0; i<outputs.
length(); i++) {
05624
05625 v_max = outputs(i,0);
05626
argmax = 0;
05627
for (
int j=1; j<outputs.width(); ++j) {
05628 tmp = outputs(i,j);
05629
if (tmp > v_max) {
05630
argmax = j;
05631 v_max = tmp;
05632 }
05633 }
05634
05635 target = (
int) target_classes(i,0);
05636 confusion_matrix(
argmax, target) ++;
05637 }
05638 }
05639
05653
template<
class T>
05654 int GramSchmidtOrthogonalization(
TMat<T> A, T tolerance=1e-6)
05655 {
05656
int n_basis = 0;
05657
for (
int i=0;i<A.
length();i++)
05658 {
05659
TVec<T> Ai=A(i);
05660
if (n_basis!=i)
05661 {
05662
TVec<T> Ab = A(n_basis);
05663 Ab << Ai;
05664 Ai=Ab;
05665 }
05666
if (i>0)
05667
projectOnOrthogonalSubspace(Ai, A.subMatRows(0,n_basis));
05668 T normAi =
norm(Ai);
05669
if (normAi>1e-6)
05670 {
05671
if (normAi!=1)
05672 Ai/=normAi;
05673 n_basis++;
05674 }
05675
05676 }
05677
return n_basis;
05678 }
05679
05681
05683
template<
class T>
05684 inline TVec<T> product(
const TMat<T>& m,
const TVec<T>& v)
05685 {
TVec<T> res(m.
length());
product(res, m,v);
return res; }
05686
05688
template<
class T>
05689 inline TVec<T> transposeProduct(
const TMat<T>& m,
const TVec<T>& v)
05690 {
TVec<T> res(m.
width());
transposeProduct(res, m,v);
return res; }
05691
05693
template<
class T>
05694 inline TMat<T> product(
const TMat<T>& m1,
const TMat<T>& m2)
05695 {
TMat<T> res(m1.
length(),m2.
width());
product(res, m1,m2);
return res; }
05696
05698
template<
class T>
05699 inline TMat<T> transposeProduct(
const TMat<T>& m1,
const TMat<T>& m2)
05700 {
TMat<T> res(m1.
width(),m2.
width());
transposeProduct(res, m1,m2);
return res; }
05701
05703
template<
class T>
05704 inline TMat<T> productTranspose(
const TMat<T>& m1,
const TMat<T>& m2)
05705 {
TMat<T> res(m1.
length(),m2.
length());
productTranspose(res, m1,m2);
return res; }
05706
05708
template<
class T>
05709 inline TMat<T> operator+(
const TMat<T>& m,
const TVec<T>& v)
05710 {
TMat<T> res = m.
copy(); res+=v;
return res; }
05711
05713
template<
class T>
05714 inline TMat<T> operator-(
const TMat<T>& m,
const TVec<T>& v)
05715 {
TMat<T> res = m.
copy(); res-=v;
return res; }
05716
05718
template<
class T>
05719 inline TMat<T> operator*(
const TMat<T>& m,
const TVec<T>& v)
05720 {
TMat<T> res = m.
copy(); res*=v;
return res; }
05721
05723
template<
class T>
05724 inline TMat<T> operator/(
const TMat<T>& m,
const TVec<T>& v)
05725 {
TMat<T> res = m.
copy(); res/=v;
return res; }
05726
05728
template<
class T>
05729 inline TMat<T> operator/(
const TMat<T>& m1,
const TMat<T>& m2)
05730 {
TMat<T> res = m1.
copy(); res/=m2;
return res; }
05731
05732
template<
class T>
05733 inline void choleskySolve(
const TMat<T>& L,
TVec<T> b,
TVec<T> x)
05734 {
TVec<T> y;
choleskySolve(L,b,
x,y); }
05735
05737
template<
class T>
05738 inline TMat<T> grep(
TMat<T> data,
int col, T value,
bool exclude=
false)
05739 {
return grep(data,col,
TVec<T>(1,value),exclude); }
05740
05741
template<
class T>
05742 void addIfNonMissing(
const TVec<T>& source,
const TVec<int>& nnonmissing,
TVec<T> destination)
05743 {
05744
#ifdef BOUNDCHECK
05745
if (source.
length()!=nnonmissing.
length() || source.
length()!=destination.
length())
05746
PLERROR(
"addIfNonMissing: all arguments should have the same length, got %d,%d,%d\n",
05747 source.
length(),nnonmissing.
length(),destination.
length());
05748
#endif
05749
T* s=source.
data();
05750 T* d=destination.
data();
05751
int* n=nnonmissing.
data();
05752
int size=source.
length();
05753
for (
int i=0;i<size;i++)
05754
if (finite(s[i]))
05755 {
05756 d[i] += s[i];
05757 n[i]++;
05758 }
05759 }
05760
05761
template<
class T>
05762 void addXandX2IfNonMissing(
const TVec<T>& source,
const TVec<int>& nnonmissing,
TVec<T> somme,
TVec<T> somme2)
05763 {
05764
#ifdef BOUNDCHECK
05765
if (source.
length()!=nnonmissing.
length() || source.
length()!=somme.
length() || source.
length()!=somme2.
length())
05766
PLERROR(
"addIfNonMissing: all arguments should have the same length, got %d,%d,%d,%d\n",
05767 source.
length(),nnonmissing.
length(),somme.
length(),somme2.
length());
05768
#endif
05769
T* s=source.
data();
05770 T* s1=somme.
data();
05771 T* s2=somme.
data();
05772
int* n=nnonmissing.
data();
05773
int size=source.
length();
05774
for (
int i=0;i<size;i++)
05775
if (finite(s[i]))
05776 {
05777 s1[i] += s[i];
05778 s2[i] += s[i]*s[i];
05779 n[i]++;
05780 }
05781 }
05782
05783 }
05784
05785
05786
05787 SET_HASH_FUNCTION(
PLearn::TVec<T>, T, v,
sumsquare(v))
05788 SET_HASH_WITH_FUNCTION(PLearn::Vec, v, sumsquare(v))
05789
05790
05791
05792
05793
05794
05795
05796
05797
05798
05799
05800
05801
05802
05803
05804
05805 #endif