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_IMPL_H
00048
#define TMAT_IMPL_H
00049
00050
#include "TMat_decl.h"
00051
#include "TMatElementIterator_impl.h"
00052
#include "TMatRowsIterator_impl.h"
00053
#include "TMatRowsAsArraysIterator_impl.h"
00054
#include "TMatColRowsIterator_impl.h"
00055
00056
namespace PLearn {
00057
using namespace std;
00058
00059
00060
00061
00062
00063
00064
00068
template <
class T>
00069 TVec<T>::TVec(
const T& start,
const T& stop,
const T& step)
00070 :length_(0), offset_(0)
00071 {
00072
00073 T
val;
00074
int n=0;
00075
for(
val=start;
val<=stop;
val+=step)
00076 ++n;
00077
00078
if(n)
00079 {
00080
resize(n);
00081
iterator it =
begin();
00082
iterator itend =
end();
00083
for(
val=start; it!=itend; ++it,
val+=step)
00084 *it =
val;
00085 }
00086 }
00087
00088
00090
template <
class T>
00091 TMat<T> TVec<T>::toMat(
int newlength,
int newwidth)
const
00092
{
00093
TMat<T> tm;
00094 tm.
offset_ =
offset_;
00095 tm.
mod_ = newwidth;
00096 tm.
width_ = newwidth;
00097 tm.
length_ = newlength;
00098 tm.
storage =
storage;
00099
return tm;
00100 }
00101
00102
00103
template <
class T>
00104 void TVec<T>::input(istream& in)
const
00105
{
00106 T* v =
data();
00107
for(
int i=0; i<
length(); i++)
00108 {
00109
if(!(in>>v[i]))
00110
PLERROR(
"In TVec::input error encountered while reading vector");
00111
00112 }
00113 }
00114
00115
template <
class T>
00116 void TVec<T>::print(ostream& out)
const
00117
{
00118
if(
storage && 0 <
length())
00119 {
00120 out.setf(ios::fmtflags(0),ios::floatfield);
00121 T* v =
data();
00122
for(
int i=0; i<
length(); i++)
00123 out << setiosflags(ios::left) << setprecision(7) << setw(11) << v[i] <<
' ';
00124 out.flush();
00125 }
00126 }
00127
00128
template <
class T>
00129 void TVec<T>::print(ostream& out,
const string& separator)
const
00130
{
00131 out.setf(ios::fmtflags(0),ios::floatfield);
00132 T* v =
data();
00133
for(
int i=0; i<
length()-1; i++)
00134 out << v[i] << separator;
00135 out << v[
length()-1];
00136 out.flush();
00137 }
00138
00139
template <
class T>
00140 void TVec<T>::printcol(ostream& out)
const
00141
{
00142 T* v =
data();
00143
for(
int i=0; i<
length(); i++)
00144 out << v[i] <<
"\n";
00145 out.flush();
00146 }
00147
00148
00149
00150
00151
00152
00153
00154
00160
template<
class T,
class I>
00161 void selectElements(
const TVec<T>& source,
const TVec<I>& indices,
TVec<T>& destination)
00162 {
00163
int ni = indices.
length();
00164
if (ni!=destination.
length())
00165
PLERROR(
"select(Vec,Vec,Vec): last 2 arguments have lengths %d != %d",
00166 indices.
length(),destination.
length());
00167 I* indx = indices.
data();
00168 T* dest = destination.
data();
00169 T* src = source.
data();
00170
#ifdef BOUNDCHECK
00171
int n=source.
length();
00172
#endif
00173
for (
int i=0;i<ni;i++)
00174 {
00175
int pos =
int(indx[i]);
00176
#ifdef BOUNDCHECK
00177
if (pos<0 || pos>=n)
00178
PLERROR(
"select(Vec,Vec,Vec) indices[%d]=%d out of bounds (0,%d)",
00179 i,pos,n-1);
00180
#endif
00181
dest[i] = src[pos];
00182 }
00183 }
00184
00186
template<
class T>
00187 void elementsEqualTo(
const TVec<T>& source,
const T& value,
const TVec<T>& destination)
00188 {
00189
#ifdef BOUNDCHECK
00190
if (source.
length()!=destination.
length())
00191
PLERROR(
"elementsEqualTo(Vec(%d),%f,Vec(%d)): incompatible dimensions",
00192 source.
length(),value,destination.
length());
00193
#endif
00194
T* src=source.
data();
00195 T* dst=destination.
data();
00196
for (
int i=0;i<destination.
length();i++)
00197
if (src[i]==value) dst[i]=1.0;
00198
else dst[i]=0.0;
00199 }
00200
00201
template<
class T>
00202 TVec<T> concat(
const TVec<T>& v1,
const TVec<T>& v2)
00203 {
00204
TVec<T> result(v1.
length()+v2.
length());
00205
for(
int i=0; i<v1.
length(); i++)
00206 result[i] = v1[i];
00207
for(
int i=0; i<v2.
length(); i++)
00208 result[i+v1.length()] = v2[i];
00209
return result;
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00237
template<
class T>
00238 TVec<T> removeElement(
const TVec<T>& v,
int elemnum)
00239 {
00240
if(elemnum==0)
00241
return v.
subVec(1,v.
length()-1);
00242
else if(elemnum==v.
length()-1)
00243
return v.
subVec(0,v.
length()-1);
00244
else
00245
return concat(v.
subVec(0,elemnum),
00246 v.
subVec(elemnum+1,v.
length()-(elemnum+1)));
00247 }
00248
00249
00250
00251
00252
00253
00254
template <
class T>
00255 TMat<T>::TMat<T>(
int the_length,
int the_width,
const TVec<T>& v)
00256 : offset_(v.offset()), mod_(the_width), length_(the_length), width_(the_width), storage(v.storage)
00257 {
00258
if(length()*width()!=v.length())
00259
PLERROR(
"In Mat constructor from Vec: length()*width() of matrix must be equal to length() of Vec");
00260 }
00261
00262
00263
template <
class T>
00264 TVec<T> TMat<T>::toVecCopy()
const
00265
{
00266
TVec<T> v(
length()*
width());
00267 v << *
this;
00268
return v;
00269 }
00270
00273
00274
template <
class T>
00275 TVec<T> TMat<T>::toVec()
const
00276
{
00277
if(
length()>1 &&
width()<
mod())
00278
PLERROR(
"In Mat::toVec internal structure of this Mat makes it impossible to build a Vec that would view exactly the same data. Consider using toVecCopy() instead!");
00279
00280
TVec<T> v;
00281 v.
offset_ =
offset_;
00282 v.
length_ =
length()*
width();
00283 v.
storage =
storage;
00284
return v;
00285 }
00286
00287
template <
class T>
00288 int TMat<T>::findRow(
const TVec<T>& row)
const
00289
{
00290
for(
int i=0; i<
length(); i++)
00291
if( (*this)(i)==row )
00292
return i;
00293
return -1;
00294 }
00295
00296
template <
class T>
00297 void TMat<T>::appendRow(
const TVec<T>& newrow)
00298 {
00299
#ifdef BOUNDCHECK
00300
if(newrow.
length()!=
width() &&
width() > 0)
00301
PLERROR(
"In TMat::appendRow newrow vector should be as long as the matrix is wide (%d != %d)", newrow.
length(),
width());
00302
#endif
00303
if (
storage) {
00304
resize(
length()+1, newrow.
length(),
storage->length());
00305 }
else {
00306
00307
resize(
length()+1, newrow.
length());
00308 }
00309 (*this)(
length()-1) << newrow;
00310 }
00311
00312
00313
00314
template <
class T>
00315 void TMat<T>::print(ostream& out)
const
00316
{
00317 out.flags(ios::left);
00318
for(
int i=0; i<
length(); i++)
00319 {
00320
const T* m_i =
rowdata(i);
00321
for(
int j=0; j<
width(); j++)
00322 out << setw(11) << m_i[j] <<
' ';
00323 out <<
"\n";
00324 }
00325 out.flush();
00326 }
00327
00328
template <
class T>
00329 void TMat<T>::input(istream& in)
const
00330
{
00331
for(
int i=0; i<
length(); i++)
00332 {
00333 T* v =
rowdata(i);
00334
for (
int j=0;j<
width();j++)
00335 {
00336
if(!(in>>v[j]))
00337
PLERROR(
"In TMat<T>::input error encountered while reading matrix");
00338 }
00339 }
00340 }
00341
00342
00343
00344
00345
template<
class T>
00346 void TMat<T>::makeDeepCopyFromShallowCopy(map<const void*, void*>& copies)
00347 {
00348
deepCopyField(
storage, copies);
00349 }
00350
00351
template<
class T>
00352 TMat<T> TMat<T>::deepCopy(map<const void*, void*>& copies)
const
00353
{
00354
00355
TMat<T> deep_copy = *
this;
00356
00357 deep_copy.
makeDeepCopyFromShallowCopy(copies);
00358
00359
return deep_copy;
00360 }
00361
00362
00363
00364
template<
class T>
00365 TMatElementIterator<T> TMat<T>::begin()
const
00366
{
return TMatElementIterator<T>(
data(),
width_,
mod_); }
00367
00368
template<
class T>
00369 TMatElementIterator<T> TMat<T>::end()
const
00370
{
return TMatElementIterator<T>(
data()+
length_*
mod_,
width_, mod_); }
00371
00372
00373
template<
class T>
00374 TMatRowsIterator<T> TMat<T>::rows_begin() {
00375
return TMatRowsIterator<T>(
data(),
width_,
mod_);
00376 }
00377
00378
template<
class T>
00379 TMatRowsIterator<T> TMat<T>::rows_end() {
00380
return TMatRowsIterator<T>(
data()+
length_*
mod_,
width_, mod_);
00381 }
00382
00383
00384
template<
class T>
00385 TMatRowsAsArraysIterator<T> TMat<T>::rows_as_arrays_begin() {
00386
return TMatRowsAsArraysIterator<T>(
data(),
width_,
mod_);
00387 }
00388
00389
template<
class T>
00390 TMatRowsAsArraysIterator<T> TMat<T>::rows_as_arrays_end() {
00391
return TMatRowsAsArraysIterator<T>(
data()+
length_*
mod_,
width_, mod_);
00392 }
00393
00394
template<
class T>
00395 TMatColRowsIterator<T> TMat<T>::col_begin(
int column) {
00396
return TMatColRowsIterator<T>(
data() + column,
mod_);
00397 }
00398
00399
template<
class T>
00400 TMatColRowsIterator<T> TMat<T>::col_end(
int column) {
00401
return TMatColRowsIterator<T>(
data()+
length_*
mod_+column,
mod_);
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
template <
class T,
class I>
00418 void selectRows(
const TMat<T>& source,
const TVec<I>& row_indices,
TMat<T>& destination)
00419 {
00420
int ni = row_indices.
length();
00421
if (ni!=destination.
length())
00422
PLERROR(
"selectRows(Mat,Vec,Mat): last 2 arguments have lengths %d != %d",
00423 ni,destination.
length());
00424 I* indx = row_indices.
data();
00425
#ifdef BOUNDCHECK
00426
int n=source.
length();
00427
#endif
00428
for (
int i=0;i<ni;i++)
00429 {
00430
int pos =
int(indx[i]);
00431
#ifdef BOUNDCHECK
00432
if (pos<0 || pos>=n)
00433
PLERROR(
"selectRows(Mat,Vec,Mat) indices[%d]=%d out of bounds (0,%d)",
00434 i,pos,n-1);
00435
#endif
00436
destination(i) << source(pos);
00437 }
00438 }
00439
00440
00441
00442
00443
00444
template <
class T,
class I>
00445 void selectColumns(
const TMat<T>& source,
const TVec<I>& column_indices,
TMat<T>& destination)
00446 {
00447
int ni = column_indices.
length();
00448
if (ni!=destination.
width())
00449
PLERROR(
"selectColums(Mat,Vec,Mat): last 2 arguments have dimensions %d != %d",
00450 ni,destination.
width());
00451 I* indx = column_indices.
data();
00452
#ifdef BOUNDCHECK
00453
int n=source.
width();
00454
#endif
00455
for (
int i=0;i<ni;i++)
00456 {
00457
int pos =
int(indx[i]);
00458
#ifdef BOUNDCHECK
00459
if (pos<0 || pos>=n)
00460
PLERROR(
"selectColumns(Mat,Vec,Mat) indices[%d]=%d out of bounds (0,%d)",
00461 i,pos,n-1);
00462
#endif
00463
destination.
column(i) << source.
column(pos);
00464 }
00465 }
00466
00467
00468
00469
00470
00471
00472
template <
class T,
class I>
00473 void select(
const TMat<T>& source,
const TVec<I>& row_indices,
const TVec<I>& column_indices,
TMat<T>& destination)
00474 {
00475
int rni = row_indices.
length();
00476
int cni = column_indices.
length();
00477
if (rni!=destination.
length() || cni!=destination.
width())
00478
PLERROR(
"select(Mat(%d,%d),Vec(%d),Vec(%d),Mat(%d,%d)): arguments have incompatible dimensions",
00479 source.
length(),source.
width(),rni,cni,destination.
length(),destination.
width());
00480 I* rindx = row_indices.
data();
00481 I* cindx = column_indices.
data();
00482
#ifdef BOUNDCHECK
00483
int nr=source.
length();
00484
int nc=source.
width();
00485
#endif
00486
for (
int i=0;i<rni;i++)
00487 {
00488
int ri=(
int)rindx[i];
00489
#ifdef BOUNDCHECK
00490
if (ri<0 || ri>=nr)
00491
PLERROR(
"select(Mat,Vec,Vec,Mat) row_indices[%d]=%d out of bounds (0,%d)",
00492 i,ri,nr-1);
00493
#endif
00494
T* dest_row = destination[i];
00495 T* src_row = source[ri];
00496
for (
int j=0;j<cni;j++)
00497 {
00498
int cj = (
int)cindx[j];
00499
#ifdef BOUNDCHECK
00500
if (cj<0 || cj>=nc)
00501
PLERROR(
"select(Mat,Vec,Vec,Mat) col_indices[%d]=%d out of bounds (0,%d)",
00502 i,cj,nc-1);
00503
#endif
00504
dest_row[j] = src_row[cj];
00505 }
00506 }
00507 }
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
template<
class T>
00554 TMat<T> removeRow(
const TMat<T>& m,
int rownum)
00555 {
00556
if(rownum==0)
00557
return m.
subMatRows(1,m.
length()-1);
00558
else if(rownum==m.
length()-1)
00559
return m.
subMatRows(0,m.
length()-1);
00560
else
00561
return vconcat(m.
subMatRows(0,rownum),
00562 m.
subMatRows(rownum+1,m.
length()-(rownum+1)));
00563 }
00564
00565
template<
class T>
00566 TMat<T> removeColumn(
const TMat<T>& m,
int colnum)
00567 {
00568
if(colnum==0)
00569
return m.
subMatColumns(1,m.
width()-1);
00570
else if(colnum==m.
width()-1)
00571
return m.
subMatColumns(0,m.
width()-1);
00572
else
00573
return hconcat(m.
subMatColumns(0,colnum),
00574 m.
subMatColumns(colnum+1,m.
width()-(colnum+1)));
00575 }
00576
00577
template<
class T>
00578 TMat<T> diagonalmatrix(
const TVec<T>& v)
00579 {
00580
TMat<T> m(v.
length(), v.
length());
00581
for(
int i=0; i<v.
length(); i++)
00582 m(i,i) = v[i];
00583
return m;
00584 }
00585
00586
00587
00588
00589
00590
00591
00592 template <
class T>
inline TMat<T> deepCopy(
const TMat<T> source)
00593 {
00594
CopiesMap copies;
00595
return deepCopy(source, copies);
00596 }
00597
00598
template <
class T>
inline TMat<T>
00599 deepCopy(
const TMat<T> source, CopiesMap copies)
00600 {
return source.
deepCopy(copies); }
00601
00602
template <
class T>
00603 inline void deepCopyField(
TMat<T>& field, CopiesMap& copies)
00604 {
00605 field.
makeDeepCopyFromShallowCopy(copies);
00606 }
00607
00608
template<
class T>
00609 void clear(
const TMat<T>& x)
00610 {
00611
if(
x.isCompact())
00612 {
00613
typename TMat<T>::compact_iterator it =
x.compact_begin();
00614
typename TMat<T>::compact_iterator itend =
x.compact_end();
00615
for(; it!=itend; ++it)
00616
clear(*it);
00617 }
00618
else
00619 {
00620
typename TMat<T>::iterator it =
x.begin();
00621
typename TMat<T>::iterator itend =
x.end();
00622
for(; it!=itend; ++it)
00623
clear(*it);
00624 }
00625 }
00626
00627
template<
class T>
00628 void swap(
TMat<T>& a,
TMat<T>& b)
00629 { swap_ranges(a.
begin(), a.
end(), b.
begin()); }
00630
00632
template<
class T>
00633 inline void operator<<(const TMat<T>& m1,
const TMat<T>& m2)
00634 {
00635
#ifdef BOUNDCHECK
00636
if(m1.size()!=m2.size())
00637
PLERROR(
"In operator<<(m1,m2) the 2 matrices must have the same number of elements\n"
00638
"m1: (%d, %d) && m2: (%d, %d)", m1.length(), m1.width(), m2.length(), m2.width());
00639
#endif
00640
copy(m2.begin(), m2.end(), m1.begin());
00641 }
00642
00644
template<
class T,
class U>
00645 void operator<<(const TMat<T>& m1,
const TMat<U>& m2)
00646 {
00647
#ifdef BOUNDCHECK
00648
if(m1.size()!=m2.size())
00649
PLERROR(
"In operator<<(m1,m2) the 2 matrices must have the same number of elements");
00650
#endif
00651
copy_cast(m2.begin(), m2.end(), m1.begin());
00652 }
00653
00655
template<
class T>
00656 inline void operator<<(const TMat<T>& m1,
const TVec<T>& m2)
00657 {
00658
#ifdef BOUNDCHECK
00659
if(m1.size()!=m2.size())
00660
PLERROR(
"In operator<<(m1,m2) the 2 matrices must have the same number of elements;\t m1.size()= %d;\t m2.size= %d", m1.size(), m2.size());
00661
#endif
00662
copy(m2.begin(), m2.end(), m1.begin());
00663 }
00664
00666
template<
class T,
class U>
00667 inline void operator<<(const TMat<T>& m1,
const TVec<U>& m2)
00668 {
00669
#ifdef BOUNDCHECK
00670
if(m1.size()!=m2.size())
00671
PLERROR(
"In operator<<(m1,m2) the 2 matrices must have the same number of elements");
00672
#endif
00673
copy_cast(m2.begin(), m2.end(), m1.begin());
00674 }
00675
00677
template<
class T>
00678 inline void operator<<(const TVec<T>& m1,
const TMat<T>& m2)
00679 {
00680
#ifdef BOUNDCHECK
00681
if(m1.size()!=m2.size())
00682
PLERROR(
"In operator<<(m1,m2) the 2 matrices must have the same number of elements");
00683
#endif
00684
copy(m2.begin(), m2.end(), m1.begin());
00685 }
00686
00688
template<
class T,
class U>
00689 inline void operator<<(const TVec<T>& m1,
const TMat<U>& m2)
00690 {
00691
#ifdef BOUNDCHECK
00692
if(m1.size()!=m2.size())
00693
PLERROR(
"In operator<<(m1,m2) the 2 matrices must have the same number of elements");
00694
#endif
00695
copy_cast(m2.begin(), m2.end(), m1.begin());
00696 }
00697
00699
template<
class T,
class U>
00700 inline void operator>>(
const TMat<T>& m1,
const TMat<U>& m2)
00701 { m2 << m1; }
00702
00704
template<
class T,
class U>
00705 inline void operator>>(
const TVec<T>& m1,
const TMat<U>& m2)
00706 { m2 << m1; }
00707
00709
template<
class T,
class U>
00710 inline void operator>>(
const TMat<T>& m1,
const TVec<U>& m2)
00711 { m2 << m1; }
00712
00713
00714
00716
template <
class T>
00717 inline ostream& operator<<(ostream& out, const TMat<T>& m)
00718 {
00719 m.
print(out);
00720
return out;
00721 }
00722
00724
00725
template <
class T>
00726 inline istream&
operator>>(istream& in,
const TMat<T>& m)
00727 {
00728 m.
input(in);
00729
return in;
00730 }
00731
00733
template <
class T>
00734 inline TMat<T> rowmatrix(
const TVec<T>& v)
00735 {
return v.
toMat(1,v.
length()); }
00736
00738
template <
class T>
00739 inline TMat<T> columnmatrix(
const TVec<T>& v)
00740 {
return v.
toMat(v.
length(),1); }
00741
00742
00743
00744
00745
00746
template <
class T,
class I>
00747
void selectRows(
const TMat<T>& source,
const TVec<I>& row_indices, TMat<T>& destination);
00748
00749
00750
00751
00752
00753
template <
class T,
class I>
00754
void selectColumns(
const TMat<T>& source,
const TVec<I>& column_indices, TMat<T>& destination);
00755
00756
00757
00758
00759
00760
00761
template <
class T>
00762
void select(
const TMat<T>& source,
const TVec<T>& row_indices,
const TVec<T>& column_indices, TMat<T>& destination);
00763
00764
00766
00767
00768
00769
00770
00771
00773
00774
00775
00776
00777
00778
00780
00781
00782
00783
00788
template<
class T>
00789 TMat<T>
removeRow(
const TMat<T>& m,
int rownum);
00790
00795
template<
class T>
00796 TMat<T>
removeColumn(
const TMat<T>& m,
int colnum);
00797
00798
00799
template<
class T>
00800 TMat<T>
diagonalmatrix(
const TVec<T>& v);
00801
00802
00803
template<
class T>
00804 void savePMat(
const string& filename,
const TMat<T>& mat)
00805 {
PLERROR(
"savePMat only implemented for float and double"); }
00806
00807
template<
class T>
00808
void loadPMat(
const string& filename, TMat<float>& mat)
00809 {
PLERROR(
"loadPMat only implemented for float and double"); }
00810
00813
00817
00818
template <
class T>
inline PStream &
00819 operator<<(PStream &out, const TMat<T> &m)
00820 {
00821 m.write(out);
00822
return out;
00823 }
00824
00825
template <
class T>
00826 PStream &
operator>>(
PStream &in,
TMat<T> &m)
00827 {
00828 m.
read(in);
00829
return in;
00830 }
00831
00832 inline string join(
const TVec<string>& s,
const string& separator)
00833 {
00834
string result;
00835
for(
int i=0; i<s.
size(); i++)
00836 {
00837 result += s[i];
00838
if(i<s.size()-1)
00839 result += separator;
00840 }
00841
return result;
00842 }
00843
00844
00845
00846
00847 }
00848
00849
#endif // TMAT_IMPL_H