00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00048
#ifndef TVec_decl_INC
00049
#define TVec_decl_INC
00050
00051
#include <iterator>
00052
#include <numeric>
00053
#include <functional>
00054
#include <strstream>
00055
00056
#include <plearn/base/general.h>
00057
#include <plearn/base/Storage.h>
00058
#include <plearn/base/Range.h>
00059
#include <plearn/io/plstreams.h>
00060
00061
namespace PLearn {
00062
using namespace std;
00063
00064
00065
template<
class T>
class TMat;
00066
class Variable;
00067
class VarArray;
00068
class QRchunker;
00069
class QCchunker;
00070
00071
template <
class T>
00072 class TVec
00073 {
00074 friend class TMat<T>;
00075
00076
friend class Variable;
00077
friend class VarArray;
00078
00080
friend class QRchunker;
00081
friend class QCchunker;
00082
00083
protected:
00084 int length_;
00085 int offset_;
00086 PP< Storage<T> > storage;
00088
public:
00089
00090 typedef T
value_type;
00091 typedef int size_type;
00092 typedef T*
iterator;
00093 typedef const T*
const_iterator;
00094
00095 inline iterator
begin()
const
00096
{
00097
if (storage.
isNull())
return 0;
00098
return storage->data+offset_;
00099 }
00100
00101 inline iterator
end()
const
00102
{
return begin()+
length(); }
00103
00104
00105
00106
00107 inline TVec(
const vector<T> & vec)
00108 :length_((
int)vec.size()), offset_(0),
00109 storage(new
Storage<T>((
int)vec.size()))
00110 {
00111
for(
int i=0;i<length_;i++)
00112 (*this)[i]=vec[i];
00113 }
00114
00115 inline TVec()
00116 :length_(0),offset_(0)
00117 {}
00118
00119 inline explicit TVec(
int the_length)
00120 :length_(the_length), offset_(0),
00121 storage(new
Storage<T>(the_length))
00122 {}
00123
00125 inline TVec(
int the_length,
const T& init_value)
00126 :length_(the_length), offset_(0),
00127 storage(new
Storage<T>(the_length))
00128 { fill(init_value); }
00129
00133
TVec(
const T& start,
const T& stop,
const T& step);
00134
00136 inline TVec(
int the_length, T* the_data)
00137 :length_(the_length), offset_(0),
00138 storage(new
Storage<T>(the_length, the_data))
00139 {}
00140
00142 inline TVec(
const TVec<T>& other)
00143 :length_(other.length()), offset_(other.offset()),
00144 storage(other.storage)
00145 {}
00146
00148 inline const TVec<T>& operator=(
const TVec<T>& other)
00149 {
00150 storage = other.
storage;
00151 length_ = other.
length_;
00152 offset_ = other.
offset_;
00153
return *
this;
00154 }
00155
00156 operator vector<T>()
const
00157
{
00158
int n = length_;
00159
vector<T> res(n);
00160
if(n>0)
00161 {
00162 T* ptr =
data();
00163
for(
int i=0; i<n; i++)
00164 res[i] = *ptr++;
00165 }
00166
return res;
00167 }
00168
00169 bool hasMissing()
const
00170
{
00171 iterator it =
begin();
00172 iterator itend =
end();
00173
for(; it!=itend; ++it)
00174
if(
is_missing(*it))
00175
return true;
00176
return false;
00177 }
00178
00179 inline int size()
const {
return length_; }
00180 inline int length()
const {
return length_; }
00181 inline int capacity()
const {
return storage.
isNotNull() ? storage->length()-offset_ : 0; }
00182 inline int offset()
const {
return offset_; }
00183
00184 inline PP< Storage<T> >
getStorage()
const {
return storage; }
00185
00187 void compact()
00188 {
00189
if(storage && storage->length() !=
length())
00190 {
00191
if(storage->usage()>1)
00192
PLERROR(
"IN Mat::compact() compact operation not allowed when matrix storage is shared (for obvious reasons)");
00193 operator=(
copy());
00194 }
00195 }
00196
00198 inline operator char*()
const {
if(
isNull())
return 0;
else return (
char*)
data(); }
00199
00200
00201
00202
00203 inline size_t
byteLength()
const {
return length()*
sizeof(T); }
00204
00210 inline void resize(
int newlength,
int extrabytes=0)
00211 {
00212
#ifdef BOUNDCHECK
00213
if (newlength<0 || extrabytes<0)
00214
PLERROR(
"IN TVec::resize(int newlength)\nInvalid argument (<0)");
00215
#endif
00216
if (newlength == length_) {
00217
00218
return;
00219 }
00220
if (storage.
isNull() && newlength>0)
00221 {
00222 offset_ = 0;
00223 length_ = newlength;
00224
Storage<T>* s =
new Storage<T>(newlength + extrabytes);
00225 storage = s;
00226 }
00227
else
00228 {
00229
if (storage.
isNotNull() && (newlength >
capacity()))
00230 storage->resize (offset_ + newlength + extrabytes);
00231 length_ = newlength;
00232 }
00233 }
00234
00237 void write(
PStream& out)
const
00238
{
00239
const TVec<T>& v = *
this;
00240
if(storage &&
00241 ( out.
implicit_storage
00242 || out.
outmode==PStream::raw_ascii
00243 || out.
outmode==PStream::raw_binary
00244 || out.
outmode==PStream::pretty_ascii ) )
00245
writeSequence(out,v);
00246
else
00247 {
00248 out.
write(
"TVec(");
00249 out << v.
length();
00250 out << v.
offset();
00251 out << v.
getStorage();
00252 out.
write(
")\n");
00253 }
00254 }
00255
00258 void read(
PStream& in)
00259 {
00260
TVec<T>& v = *
this;
00261
switch(in.
inmode)
00262 {
00263
case PStream::raw_ascii:
00264
case PStream::raw_binary:
00265
readSequence(in, v);
00266
00267
case PStream::plearn_ascii:
00268
case PStream::plearn_binary:
00269 {
00270 in.
skipBlanksAndComments();
00271
int c = in.
peek();
00272
if(c!=
'T')
00273
readSequence(in,v);
00274
else
00275 {
00276
char word[6];
00277
00278
00279
for(
int i=0; i<5; i++)
00280 in.
get(word[i]);
00281 word[5]=
'\0';
00282
if(strcmp(word,
"TVec(")!=0)
00283
PLERROR(
"In operator>>(PStream&, TVec&) '%s' not a proper header for a TVec!",word);
00284
00285 in.
skipBlanksAndCommentsAndSeparators();
00286 in >> v.
length_;
00287 in.
skipBlanksAndCommentsAndSeparators();
00288 in >> v.
offset_;
00289 in.
skipBlanksAndCommentsAndSeparators();
00290 in >> v.
storage;
00291 in.
skipBlanksAndCommentsAndSeparators();
00292
int c = in.
get();
00293
if(c!=
')')
00294
PLERROR(
"In operator>>(PStream&, TVec&) expected a closing parenthesis, found '%c'",c);
00295 }
00296 }
00297
break;
00298
00299
default:
00300
PLERROR(
"In TVec<T>::read(PStream& in) unknown inmode!!!!!!!!!");
00301
break;
00302 }
00303 }
00304
00305
00306
00307 void save(
const string& filename)
const {
savePVec(filename, *
this); }
00308 void load(
const string& filename) {
loadPVec(filename, *
this); }
00309
00311 TVec<T> subVec(
int newstart,
int newlength)
const
00312
{
00313
#ifdef BOUNDCHECK
00314
if(newstart+newlength>
length() || newlength<0)
00315
PLERROR(
"TVec::subVec(int newstart, int newlength) OUT OF BOUNDS OR <0 length()"
00316
" length()=%d; newstart=%d; newlength=%d.",
length(), newstart, newlength);
00317
#endif
00318
TVec<T> subv = *
this;
00319 subv.
length_ = newlength;
00320 subv.
offset_ += newstart;
00321
return subv;
00322 }
00323
00328
void makeDeepCopyFromShallowCopy(map<const void*, void*>& copies);
00329
00334
TVec<T> deepCopy(map<const void*, void*>& copies)
const;
00335
00336
00337 inline TVec<T> subVec(
Range r) {
return subVec(r.
start, r.
length); }
00338
00340 void concat(
const TVec<T>& input1,
const TVec<T>& input2)
00341 {
00342
int l1 = input1.
length();
00343
int l2 = input2.
length();
00344
resize(l1+l2);
00345
for(
int i=0;i<l1;i++) (*this)[i] = input1[i];
00346
for(
int i=0;i<l2;i++) (*this)[l1+i] = input2[i];
00347 }
00348
00349 void concat(
const TVec<T>& input1,
const TVec<T>& input2,
const TVec<T>& input3)
00350 {
00351
int l1 = input1.
length();
00352
int l2 = input2.
length();
00353
int l3 = input3.
length();
00354
resize(l1+l2+l3);
00355
for(
int i=0;i<l1;i++) (*this)[i] = input1[i];
00356
for(
int i=0;i<l2;i++) (*this)[l1+i] = input2[i];
00357
for(
int i=0;i<l3;i++) (*this)[l1+l2+i] = input3[i];
00358 }
00359
00360 void concat(
const TVec<T>& input1,
const TVec<T>& input2,
const TVec<T>& input3,
const TVec<T>& input4)
00361 {
00362
int l1 = input1.
length();
00363
int l2 = input2.
length();
00364
int l3 = input3.
length();
00365
int l4 = input4.
length();
00366
resize(l1+l2+l3+l4);
00367
for(
int i=0;i<l1;i++) (*this)[i] = input1[i];
00368
for(
int i=0;i<l2;i++) (*this)[l1+i] = input2[i];
00369
for(
int i=0;i<l3;i++) (*this)[l1+l2+i] = input3[i];
00370
for(
int i=0;i<l4;i++) (*this)[l1+l2+l3+i] = input4[i];
00371 }
00372
00374
inline TMat<T> toMat(
int newlength,
int newwidth)
const;
00375
00377 inline TVec<T> copy()
const
00378
{
00379
TVec<T> freshcopy(
length());
00380 freshcopy << *
this;
00381
return freshcopy;
00382 }
00383
00385 void copyFrom(
const T* x,
int n)
const
00386
{
00387
#ifdef BOUNDCHECK
00388
if(n !=
length())
00389
PLERROR(
"IN TVec::copyFrom(T* x, int n)\nVecs do not have the same length()");
00390
#endif
00391
T* v1 =
data();
00392
for(
int i=0; i<n; i++)
00393 v1[i] =
x[i];
00394 }
00395
00397 void copyTo(T* x)
const
00398
{
00399 T* v1 =
data();
00400
for(
int i=0; i<
length(); i++)
00401
x[i] = v1[i];
00402 }
00403
00408 void makeSharedValue(T* x,
int n)
00409 {
00410
#ifdef BOUNDCHECK
00411
if(n !=
length())
00412
PLERROR(
"IN TVec::makeSharedValue(T* x, int n)\nn(%d)!=length_(%d)",
00413 n,
length());
00414
#endif
00415
T* v =
data();
00416
for(
int i=0; i<n; i++)
00417
x[i] = v[i];
00418 storage->pointTo(n,
x);
00419 }
00420
00421 bool isNull()
const
00422
{
return storage.
isNull(); }
00423
00424 bool isNotNull()
const
00425
{
return storage.
isNotNull(); }
00426
00427 bool isEmpty()
const
00428
{
return length_==0; }
00429
00430 bool isNotEmpty()
const
00431
{
return length_!=0; }
00432
00436
00438
00439
00440
00441
00443 bool operator!()
const
00444
{
return isEmpty(); }
00445
00446
00447 TVec<T>*
operator->()
00448 {
return this; }
00449
00451 inline void fill(
const T& value)
const
00452
{
00453
if (storage)
00454 fill_n(
data(),
length(), value);
00455 }
00456
00459 void fill(
const T& startval,
const T& step)
00460 {
00461 iterator it =
begin();
00462 iterator itend =
end();
00463
for(T
val=startval; it!=itend; ++it,
val+=step)
00464 *it =
val;
00465 }
00466
00468 inline void operator=(
const T& f)
const
00469
{ fill(f); }
00470
00471 inline void clear()
const
00472
{
if(!
isNull())
clear_n(
data(),
length()); }
00473
00475 inline void insert(
int position, T value)
00476 {
00477
#ifdef BOUNDCHECK
00478
if(position<0 || position>
length())
00479
PLERROR(
"OUT OF BOUNDS in TVec::insert");
00480
#endif
00481
resize(
length()+1);
00482 T* v =
data();
00483
for(
int i=
length()-1; i>position; i--)
00484 v[i] = v[i-1];
00485 v[position] = value;
00486 }
00487
00489 inline void remove(
int position)
00490 {
00491
#ifdef BOUNDCHECK
00492
if(position<0 || position>=
length())
00493
PLERROR(
"OUT OF BOUNDS in Vec::remove");
00494
#endif
00495
T* v =
data();
00496
for(
int i=position; i<
length()-1; i++)
00497 v[i] = v[i+1];
00498
resize(
length()-1);
00499 }
00500
00501 int findSorted(T value)
00502 {
00503
if (
isEmpty())
00504
return 0;
00505
00506 pair<iterator, iterator> range =
00507 equal_range(
begin(),
end(), value);
00508
00509
return int(range.first - begin());
00510 }
00511
00512 inline void insertSorted(T value,
bool uniq)
00513 {
00514
int i = findSorted(value);
00515
if(!uniq || i==
length() || (*this)[i]!=value)
00516 insert(i,value);
00517 }
00518
00519 inline void removeSorted(T value)
00520 {
00521
int i = findSorted(value);
00522
if(i<
length() && (*this)[i]==value)
00523
remove(i);
00524 }
00525
00526
00527 inline void append(
const T& newval)
00528 {
00529
resize(
length()+1,
length());
00530
lastElement() = newval;
00531 }
00532
00534 void append(
const vector<T>& newvec)
00535 {
00536
int currentsize =
length();
00537
if (currentsize + newvec.size() == 0)
00538
return;
00539
resize(currentsize + newvec.size());
00540 T* v =
data();
00541
for (
unsigned int i=0; i<newvec.size(); ++i)
00542 v[currentsize+i] = newvec[i];
00543 }
00544
00546 inline void appendIfNotThereAlready(
const T& newval)
00547 {
00548 T* v =
data();
00549
for (
int i=0;i<
length();i++)
00550
if (newval==v[i])
return;
00551 append(newval);
00552 }
00553
00555 inline void push_back(
const T& newval)
00556 { append(newval); }
00557
00558 inline void pop_back()
00559 {
00560
if(length_ <= 0)
00561
PLERROR(
"In TVec::pop_back already empty!");
00562 length_ -= 1;
00563 }
00564
00566 inline void push(
const T& newval)
00567 { append(newval); }
00568
00569 inline T
pop()
00570 { T res =
lastElement();
pop_back();
return res; }
00571
00572 inline T&
top()
const
00573
{
return lastElement(); }
00574
00575 inline void append(
const TVec<T>& values)
00576 {
00577
int oldLength =
length();
00578
if (values.
length() == 0)
00579
return;
00580
resize(oldLength+values.
length());
00581 T* v =
data()+oldLength;
00582 T* newv = values.
data();
00583
for(
int i=0; i<values.
length(); i++)
00584 v[i] = newv[i];
00585 }
00586
00587 inline T& operator[](
int i)
const
00588
{
00589
#ifdef BOUNDCHECK
00590
if(i<0 || i>=
length())
00591
PLERROR(
"OUT OF BOUND ACCESS %d IN TVec(%d)::operator[]",i,
length());
00592
#endif
00593
return storage->data[i+offset_];
00594 }
00595
00596
00597 inline T& operator[](
unsigned int i)
const
00598
{
00599
#ifdef BOUNDCHECK
00600
00601
if(i<0 || i>=(
unsigned int)
length())
00602
PLERROR(
"OUT OF BOUND ACCESS %d IN TVec(%d)::operator[]",i,
length());
00603
#endif
00604
return storage->data[i+offset_];
00605 }
00606
00607 inline T&
lastElement()
const
00608
{
return storage->data[offset_+
length()-1]; }
00609
00610 inline T&
firstElement()
const
00611
{
return storage->data[offset_]; }
00612
00613 inline T&
front()
const {
return firstElement(); }
00614 inline T&
back()
const {
return lastElement(); }
00615
00616
00617 inline T&
first()
const {
return firstElement(); }
00618 inline T&
last()
const {
return lastElement(); }
00619
00620
00622
template<
class I>
00623 inline void operator()(
const TVec<I>& indices,
TVec<T>& destination)
const
00624
{
selectElements(*
this, indices, destination); }
00625
00631
template<
class I>
00632 inline TVec<T> operator()(
const TVec<I>& indices)
const
00633
{
00634
TVec<T> result(indices.
length());
00635
selectElements(*
this, indices, result);
00636
return result;
00637 }
00638
00640 inline T*
data()
const
00641
{
00642
#ifdef BOUNDCHECK
00643
if(storage.
isNull())
00644
PLERROR(
"IN TVec::operator()\nAttempted to get a pointer to the data of an empty TVec");
00645
#endif
00646
return storage->data+offset_;
00647 }
00648
00650 inline void swap()
00651 {
00652
int half =
length()/2;
00653 T* ptr =
data();
00654
for(
int i=0; i<half; i++)
00655 std::swap(ptr[i],ptr[
length()-i-1]);
00656 }
00657
00659 TVec<bool> operator==(
const T& value)
const
00660
{
00661
TVec<bool> r(
length(),
false);
00662
00663
for (
int i=0; i<
length(); i++)
00664 {
00665
if ((*this)[i] == value) r[i] =
true;
00666 }
00667
return r;
00668 }
00669
00671 bool operator==(
const TVec<T>& value)
const
00672
{
00673
if (value.
isEmpty() &&
isEmpty())
return true;
00674
if (value.
length()!=
length())
return false;
00675 T*
x=
data();
00676 T* y=value.
data();
00677
for (
int i=0;i<
length();i++)
00678
if (
x[i]!=y[i])
return false;
00679
return true;
00680 }
00681 bool operator!=(
const TVec<T>& value)
const {
return !((*this)==value); }
00682
00684 bool contains(
const T& element)
const
00685
{
00686
if (
length()==0)
return false;
00687
bool contained=
false;
00688 T *v =
data();
00689
for (
int i=0; i<
length() && !contained; i++)
00690
if (v[i]==element)
00691 contained=
true;
00692
return contained;
00693 }
00694
00697 TVec<T> findIndices(
const T& element)
00698 {
00699
TVec<T> indices(0);
00700
if (!
isEmpty())
00701 {
00702 T *v =
data();
00703
for (
int i=0; i<
length(); i++)
00704
if (v[i]==element)
00705 indices.
append(i);
00706 }
00707
return indices;
00708 }
00709
00710 TVec<T> findIndices(
const TVec<T>& elements)
00711 {
00712
TVec<T> indices(0);
00713
if (!
isEmpty())
00714 {
00715 T *v =
data();
00716
for (
int i=0; i<
length(); i++)
00717
for (
int j=0, m=elements.
length(); j<m; j++)
00718
if (v[i] == elements[j])
00719 {
00720 indices.
append(i);
00721
break;
00722 }
00723 }
00724
return indices;
00725 }
00726
00729 int find(
const T& element,
int start=0)
const
00730
{
00731
if (
length()==0)
return -1;
00732 T *v =
data();
00733
for (
int i=start; i<
length(); i++)
00734
if(v[i]==element)
00735
return i;
00736
return -1;
00737 }
00738
00739 TVec<T> find(
TVec<T> elements)
00740 {
00741
TVec<T> indices(elements.
length(),-1);
00742
if (
length()==0)
return indices;
00743 T *v =
data();
00744
for (
int i=0, m=elements.
length(); i<m; i++)
00745
for (
int j=0; j<
length(); j++)
00746
if (v[j] == elements[i])
00747 {
00748 indices[i] = j;
00749
break;
00750 }
00751
return indices;
00752 }
00753
00755
void print(ostream& out = cout)
const;
00756 void println(ostream& out = cout)
const {
print(out); out<<
endl; }
00757
void printcol(ostream& out = cout)
const;
00758
void print(ostream& out,
const string& separator)
const;
00759
00760
void input(istream& in=cin)
const;
00761
00762
00763 void debugPrint(){
print(cerr);}
00764
00765
00766 void operator<<(
const string& datastring)
const
00767
{
00768 istrstream in(datastring.c_str());
00769 input(in);
00770 }
00771
00772 };
00773
00774 typedef TVec<real> Vec;
00775
00778 inline void operator<<(
const Vec& v,
real f)
00779 { v.
fill(f); }
00780
00781
template<
class T>
00782 class TypeTraits< TVec<T> >
00783 {
00784
public:
00785 static inline string name()
00786 {
return string(
"TVec< ") +
TypeTraits<T>::name()+
" >"; }
00787
00788 static inline unsigned char little_endian_typecode()
00789 {
return 0xFF; }
00790
00791 static inline unsigned char big_endian_typecode()
00792 {
return 0xFF; }
00793 };
00794
00795
00796 }
00797
00798
00799
#endif