00001
00057
00058
00061 #define __ARRAY_NO_GENERIC_IOSTREAM
00062
00063 #ifndef __ARRAY_H
00064 #define __ARRAY_H
00065
00066
00068
00069 #define Array2D Array
00070 #define Array2DReference ArrayReference
00071
00072
00073 #include <SharkDefs.h>
00074 #include <algorithm>
00075 #include <vector>
00076 #include <typeinfo>
00077
00078
00079
00080
00081
00082
00083
00084
00161
00162
00163
00164
00165
00166
00167
00168
00169 template< class T >
00170 class Array;
00171
00172
00173 class ArrayIndex;
00174
00175
00176 template< class T >
00177 class ArrayReference;
00178
00179
00200 class ArrayBase
00201 {
00202 public:
00203
00204
00224 unsigned ndim() const
00225 {
00226 return nd;
00227 }
00228
00229
00230
00250 unsigned nelem() const
00251 {
00252 return ne;
00253 }
00254
00255
00256
00279 bool samedim(const ArrayBase& v) const
00280 {
00281 if (nd == v.nd && ne == v.ne)
00282 {
00283 unsigned i;
00284 for (i = 0; i < nd && d[ i ] == v.d[ i ]; i++);
00285 return i == nd;
00286 }
00287 return false;
00288 }
00289
00290
00320 void resize(unsigned i, bool copy = false)
00321 {
00322 unsigned _d[ 1 ];
00323 _d[ 0 ] = i;
00324 resize_i(_d, 1, copy);
00325 }
00326
00327
00358 void resize(unsigned i, unsigned j, bool copy = false)
00359 {
00360 unsigned _d[ 2 ];
00361 _d[ 0 ] = i;
00362 _d[ 1 ] = j;
00363 resize_i(_d, 2, copy);
00364 }
00365
00366
00399 void resize(unsigned i, unsigned j, unsigned k, bool copy = false)
00400 {
00401 unsigned _d[ 3 ];
00402 _d[ 0 ] = i;
00403 _d[ 1 ] = j;
00404 _d[ 2 ] = k;
00405 resize_i(_d, 3, copy);
00406 }
00407
00408
00440 void resize(const std::vector< unsigned >& i, bool copy = false)
00441 {
00442 unsigned* _d = new unsigned[ i.size()];
00443
00444 for (unsigned j = 0; j < i.size(); ++j)
00445 _d[ j ] = i[ j ];
00446
00447 resize_i(_d, i.size(), copy);
00448
00449 delete[ ] _d;
00450 }
00451
00452
00485 void resize(const ArrayBase& v, bool copy = false)
00486 {
00487 resize_i(v.d, v.nd, copy);
00488 }
00489
00490
00511 unsigned dim(unsigned i) const
00512 {
00513 RANGE_CHECK(i < nd)
00514 return d[ i ];
00515 }
00516
00519 inline unsigned int rows() const
00520 {
00521 if (ndim() == 0) return 0;
00522 else return dim(0);
00523 }
00524
00527 inline unsigned int cols() const
00528 {
00529 if (ndim() == 0) return 0;
00530 else return dim(ndim() - 1);
00531 }
00532
00533
00554 unsigned* dimvec()
00555 {
00556 return d;
00557 }
00558
00559
00581 const unsigned* dimvec() const
00582 {
00583 return d;
00584 }
00585
00586
00607 virtual ArrayBase* clone() const = 0;
00608
00609
00630 virtual ArrayBase* empty() const = 0;
00631
00632
00651 virtual ~ArrayBase()
00652 {
00653 if (! stat && nd)
00654 {
00655 delete[ ] d;
00656 }
00657 }
00658
00659 protected:
00660
00661
00680 ArrayBase()
00681 {
00682 d = 0;
00683 nd = 0;
00684 ne = 0;
00685 stat = false;
00686 }
00687
00688
00712 ArrayBase(const ArrayBase& v)
00713 {
00714 nd = v.nd;
00715 ne = v.ne;
00716 stat = false;
00717
00718 if (nd)
00719 {
00720 d = new unsigned[ nd ];
00721 for (unsigned i = nd; i--; d[ i ] = v.d[ i ]);
00722 }
00723 }
00724
00725
00759 virtual void resize_i(unsigned* d, unsigned nd, bool copy) = 0;
00760
00761 #ifndef __ARRAY_NO_GENERIC_IOSTREAM
00762
00763
00789 virtual void readFrom(std::istream& is) = 0;
00790
00791
00815 virtual void writeTo(std::ostream& os) const = 0;
00816 #endif // !__ARRAY_NO_GENERIC_IOSTREAM
00817
00818
00876 unsigned* d;
00877
00879 unsigned nd;
00880
00882 unsigned ne;
00883
00885 bool stat;
00886
00887 #ifndef __ARRAY_NO_GENERIC_IOSTREAM
00888
00889
00922 friend inline std::istream& operator >> (std::istream& is, ArrayBase& a)
00923 {
00924 a.readFrom(is);
00925 IO_CHECK(is)
00926 return is;
00927 }
00928
00929
00959 friend inline std::ostream& operator << (std::ostream& os, const ArrayBase& a)
00960 {
00961 a.writeTo(os);
00962 IO_CHECK(os)
00963 return os;
00964 }
00965 #endif // __ARRAY_NO_GENERIC_IOSTREAM
00966 };
00967
00968
00987 template< class T >
00988 class Array : public ArrayBase
00989 {
00990 friend class ArrayReference< T >;
00991 friend class ArrayIndex;
00992
00993 public:
00994
00997 typedef T* iterator;
00998
01001 typedef T* const_iterator;
01002
01003
01004
01021 Array()
01022 {
01023 ne = 0;
01024 e = eEnd = 0;
01025 }
01026
01027
01028
01048 explicit Array(unsigned i)
01049 {
01050 d = new unsigned[ 1 ];
01051 d[ 0 ] = i;
01052 nd = 1;
01053 ne = i;
01054 e = 0;
01055 if (ne)
01056 {
01057 e = new T[ ne ];
01058 }
01059 stat = false;
01060 eEnd = e + ne;
01061 }
01062
01063
01084 Array(unsigned i, unsigned j)
01085 {
01086 d = new unsigned[ 2 ];
01087 d[ 0 ] = i;
01088 d[ 1 ] = j;
01089 nd = 2;
01090 ne = i * j;
01091 e = 0;
01092 if (ne) e = new T[ ne ];
01093 stat = false;
01094 eEnd = e + ne;
01095 }
01096
01097
01119 Array(unsigned i, unsigned j, unsigned k)
01120 {
01121 d = new unsigned[ 3 ];
01122 d[ 0 ] = i;
01123 d[ 1 ] = j;
01124 d[ 2 ] = k;
01125 nd = 3;
01126 ne = i * j * k;
01127 e = 0;
01128 if (ne)
01129 {
01130 e = new T[ ne ];
01131 }
01132 stat = false;
01133 eEnd = e + ne;
01134 }
01135
01136
01154 Array(std::vector< T >& v)
01155 {
01156 d = new unsigned[ 1 ];
01157 d[ 0 ] = v.size();
01158 nd = 1;
01159 ne = v.size();
01160 e = 0;
01161 if (ne)
01162 {
01163 e = new T[ ne ];
01164 for (unsigned i = ne; i--; e[ i ] = v[ i ]);
01165 }
01166 stat = false;
01167 eEnd = e + ne;
01168 }
01169
01170
01191 Array(Array< T >& v, bool)
01192 {
01193 d = v.d;
01194 e = v.e;
01195 nd = v.nd;
01196 ne = v.ne;
01197 stat = v.stat;
01198 v.nd = v.ne = 0;
01199 v.stat = true;
01200 eEnd = e + ne;
01201 }
01202
01203
01222 Array(const Array< T >& v) : ArrayBase(v)
01223 {
01224 if (ne)
01225 {
01226 e = new T[ ne ];
01227 for (unsigned i = ne; i--; e[ i ] = v.e[ i ]);
01228 eEnd = e + ne;
01229 }
01230 else
01231 {
01232 e = eEnd = 0;
01233 }
01234 }
01235
01236
01257 ~Array()
01258 {
01259 if (! stat && ne)
01260 {
01261 if (ne)
01262 {
01263 delete[ ] e;
01264 }
01265 }
01266 }
01267
01270 inline unsigned int rows() const
01271 {
01272 return ArrayBase::rows();
01273 }
01274
01277 inline unsigned int cols() const
01278 {
01279 return ArrayBase::cols();
01280 }
01281
01282
01306 T& operator()()
01307 {
01308 SIZE_CHECK(nd == 0)
01309 RANGE_CHECK(ne == 1)
01310 return e[ 0 ];
01311 }
01312
01313
01338 const T& operator()() const
01339 {
01340 SIZE_CHECK(nd == 0)
01341 RANGE_CHECK(ne == 1)
01342 return e[ 0 ];
01343 }
01344
01345
01367 T& operator()(unsigned i)
01368 {
01369 SIZE_CHECK(nd == 1)
01370 RANGE_CHECK(i < d[ 0 ])
01371 return e[ i ];
01372 }
01373
01374
01397 const T& operator()(unsigned i) const
01398 {
01399 SIZE_CHECK(nd == 1)
01400 RANGE_CHECK(i < d[ 0 ])
01401 return e[ i ];
01402 }
01403
01404
01430 T& operator()(unsigned i, unsigned j)
01431 {
01432 SIZE_CHECK(nd == 2)
01433 RANGE_CHECK(i < d[ 0 ])
01434 RANGE_CHECK(j < d[ 1 ])
01435 return e[ d[ 1 ] * i + j ];
01436 }
01437
01438
01464 const T& operator()(unsigned i, unsigned j) const
01465 {
01466 SIZE_CHECK(nd == 2)
01467 RANGE_CHECK(i < d[ 0 ])
01468 RANGE_CHECK(j < d[ 1 ])
01469 return e[ d[ 1 ] * i + j ];
01470 }
01471
01472
01500 T& operator()(unsigned i, unsigned j, unsigned k)
01501 {
01502 SIZE_CHECK(nd == 3)
01503 RANGE_CHECK(i < d[ 0 ])
01504 RANGE_CHECK(j < d[ 1 ])
01505 RANGE_CHECK(k < d[ 2 ])
01506 return e[ d[ 2 ] * d[ 1 ] * i + d[ 2 ] * j + k ];
01507 }
01508
01509
01537 const T& operator()(unsigned i, unsigned j, unsigned k) const
01538 {
01539 SIZE_CHECK(nd == 3)
01540 RANGE_CHECK(i < d[ 0 ])
01541 RANGE_CHECK(j < d[ 1 ])
01542 RANGE_CHECK(k < d[ 2 ])
01543 return e[ d[ 2 ] * d[ 1 ] * i + d[ 2 ] * j + k ];
01544 }
01545
01546
01547
01572 T& operator()(const std::vector< unsigned >& i)
01573 {
01574 unsigned l, m, n;
01575 SIZE_CHECK(i.size() == nd)
01576 #ifndef NDEBUG
01577 for (l = nd; l--;)
01578 {
01579 RANGE_CHECK(i[ l ] < d[ l ])
01580 }
01581 #endif
01582 for (l = nd, m = 0, n = 1; l--;)
01583 {
01584 m += i[ l ] * n;
01585 n *= d[ l ];
01586 }
01587
01588 return e[ m ];
01589 }
01590
01591
01592
01617 const T& operator()(const std::vector< unsigned >& i) const
01618 {
01619 unsigned l, m, n;
01620 SIZE_CHECK(i.size() == nd)
01621 #ifndef NDEBUG
01622 for (l = nd; l--;)
01623 {
01624 RANGE_CHECK(i[ l ] < d[ l ])
01625 }
01626 #endif
01627 for (l = nd, m = 0, n = 1; l--;)
01628 {
01629 m += i[ l ] * n;
01630 n *= d[ l ];
01631 }
01632
01633 return e[ m ];
01634 }
01635
01636
01637
01638 ArrayReference< T > operator [ ](unsigned i);
01639
01640
01641 const ArrayReference< T > operator [ ](unsigned i) const;
01642
01643
01661 Array< T >& operator = (const T& v)
01662 {
01663 for (unsigned i = ne; i--; e[ i ] = v);
01664 return *this;
01665 }
01666
01667
01668
01669
01670
01694 Array< T >& operator = (const std::vector< T >& v)
01695 {
01696 resize(v.size());
01697 for (unsigned i = ne; i--; e[ i ] = v[ i ]);
01698 return *this;
01699 }
01700
01701
01702
01703
01727 Array< T >& operator = (const Array< T >& v)
01728 {
01729
01730
01731
01732
01733 if (v.nd)
01734 {
01735 resize_i(v.d, v.nd, false);
01736 for (unsigned i = ne; i--; e[ i ] = v.e[ i ]);
01737 }
01738 else
01739 {
01740 if (nd)
01741 {
01742 delete[ ] d;
01743 }
01744 if (ne)
01745 {
01746 delete[ ] e;
01747 }
01748 nd = ne = 0;
01749 }
01750
01751 return *this;
01752 }
01753
01754
01755
01756
01778 T& elem(unsigned i)
01779 {
01780 RANGE_CHECK(i < ne)
01781 return e[ i ];
01782 }
01783
01784
01785
01808 const T& elem(unsigned i) const
01809 {
01810 RANGE_CHECK(i < ne)
01811 return e[ i ];
01812 }
01813
01814
01815
01831 T* elemvec()
01832 {
01833 return e;
01834 }
01835
01836
01837
01853 const T* elemvec() const
01854 {
01855 return e;
01856 }
01857
01858
01859
01883 Array< T >& append_elem(const T& w)
01884 {
01885 SIZE_CHECK(nd == 0 || nd == 1)
01886
01887 resize(ne + 1, true);
01888 e[ ne - 1 ] = w;
01889 return *this;
01890 }
01891
01892
01893
01921 Array< T >& append_elems(const Array< T >& w)
01922 {
01923 SIZE_CHECK((nd == 0 || nd == 1) && w.nd == 1)
01924
01925 unsigned i = 0, j = ne;
01926
01927 resize(ne + w.ne, true);
01928
01929 while (i < w.ne)
01930 {
01931 e[ j++ ] = w.e[ i++ ];
01932 }
01933
01934 return *this;
01935 }
01936
01937
01938
01939
01989 Array< T >& append_rows(const Array< T >& y)
01990 {
01991 SIZE_CHECK(ndim() == 0 ||
01992 ndim() == y.ndim() ||
01993 ndim() == y.ndim() + 1)
01994
01995 unsigned i, pos = nelem();
01996 Array< unsigned > da;
01997
01998
01999 if (ndim() == 0)
02000 {
02001 da.resize(y.ndim() + 1);
02002 da(0) = 1;
02003 for (i = 0; i < y.ndim(); ++i)
02004 {
02005 da(i + 1) = y.dim(i);
02006 }
02007 }
02008
02009 else if (ndim() == y.ndim())
02010 {
02011
02012
02013 da = dimarr();
02014 da(0) = dim(0) + y.dim(0);
02015 }
02016
02017
02018 else if (ndim() == y.ndim() + 1)
02019 {
02020 da = dimarr();
02021 da(0) ++;
02022 }
02023
02024 else
02025 {
02026 return *this;
02027 }
02028
02029
02030 resize_i(da.elemvec(), da.nelem(), true);
02031
02032 for (i = 0; i < y.nelem();)
02033 {
02034 elem(pos++) = y.elem(i++);
02035 }
02036
02037 return *this;
02038 }
02039
02040
02041
02042
02043
02070 Array< T >& remove_row(unsigned i)
02071 {
02072 RANGE_CHECK(ndim() > 0 && i < dim(0))
02073
02074 unsigned k;
02075 unsigned size = nelem() / dim(0);
02076
02077 Array< T > y;
02078 Array< unsigned > da(dimarr());
02079
02080 da(0)--;
02081
02082 y.resize_i(da.elemvec(), da.nelem(), false);
02083
02084 for (k = 0; k < i * size; ++k)
02085 {
02086 y.elem(k) = elem(k);
02087 }
02088
02089 for (; k < y.nelem(); ++k)
02090 {
02091 y.elem(k) = elem(k + size);
02092 }
02093
02094 return *this = y;
02095 }
02096
02097
02098
02099
02100
02126 Array< T > remove_col(unsigned k) const
02127 {
02128 RANGE_CHECK(ndim() > 0 && k < dim(ndim() - 1))
02129
02130 unsigned i, j, xi, zi;
02131 unsigned xlast = dim(ndim() - 1);
02132
02133 unsigned num = nelem() / xlast;
02134
02135 Array< T > z;
02136
02137 Array< unsigned > da(dimarr());
02138
02139 da(ndim() - 1) = xlast - 1;
02140
02141 z.resize_i(da.elemvec(), da.nelem(), false);
02142
02143 for (xi = zi = i = 0; i < num; ++i)
02144 {
02145
02146 for (j = 0; j < k; ++j)
02147 {
02148 z.elem(zi++) = elem(xi++);
02149 }
02150
02151 for (++xi, ++j; j < xlast; ++j)
02152 {
02153 z.elem(zi++) = elem(xi++);
02154 }
02155 }
02156
02157 return Array< T > (z, true);
02158 }
02159
02160
02161
02162
02163
02186 Array<T>& remove_cols(const Array<unsigned> idx)
02187 {
02188 RANGE_CHECK(ndim() > 0 && idx.ndim() == 1);
02189
02190 if (idx.nelem() == 0) return *this;
02191 std::sort(idx.begin(), idx.end());
02192
02193 T* source = e;
02194 T* dest = e;
02195 int i;
02196 int lastDim = ndim() - 1;
02197 int r, rc = idx.nelem();
02198 int f, fc = dim(lastDim);
02199 RANGE_CHECK(idx(rc - 1) < fc);
02200 for (i=0, r=0, f=0; i<ne; i++)
02201 {
02202 if (r < rc && f == idx(r))
02203 {
02204 source++;
02205 r++;
02206 }
02207 else
02208 {
02209 *dest = *source;
02210 source++;
02211 dest++;
02212 }
02213 f++;
02214 if (f == fc)
02215 {
02216 f = 0;
02217 r = 0;
02218 }
02219 }
02220
02221 std::vector<unsigned> newdim(ndim());
02222 for (i=0; i<lastDim; i++) newdim[i] = d[i];
02223 newdim[lastDim] = fc - rc;
02224 resize_i(&newdim[0], ndim(), true);
02225
02226 return *this;
02227 }
02228
02229
02230
02231
02232
02262 Array< T > & remove_cols(unsigned i, unsigned j)
02263 {
02264 Array< unsigned > idx(2);
02265
02266 idx(0) = i;
02267 idx(1) = j;
02268
02269 return remove_cols(idx);
02270 }
02271
02272
02273
02274
02305 Array< T > & remove_cols(unsigned i, unsigned j, unsigned k)
02306 {
02307 Array< unsigned > idx(3);
02308
02309 idx(0) = i;
02310 idx(1) = j;
02311 idx(2) = k;
02312
02313 return remove_cols(idx);
02314 }
02315
02316
02317
02318
02350 Array< T > & remove_cols(unsigned i, unsigned j, unsigned k,
02351 unsigned l)
02352 {
02353 Array< unsigned > idx(4);
02354
02355 idx(0) = i;
02356 idx(1) = j;
02357 idx(2) = k;
02358 idx(3) = l;
02359
02360 return remove_cols(idx);
02361 }
02362
02363
02364
02365
02399 Array< T > & remove_cols(unsigned i, unsigned j, unsigned k,
02400 unsigned l, unsigned m)
02401 {
02402 Array< unsigned > idx(5);
02403
02404 idx(0) = i;
02405 idx(1) = j;
02406 idx(2) = k;
02407 idx(3) = l;
02408 idx(4) = m;
02409
02410 return remove_cols(idx);
02411 }
02412
02413
02414
02415
02450 Array< T > & remove_cols(unsigned i, unsigned j, unsigned k,
02451 unsigned l, unsigned m, unsigned n)
02452 {
02453 Array< unsigned > idx(6);
02454
02455 idx(0) = i;
02456 idx(1) = j;
02457 idx(2) = k;
02458 idx(3) = l;
02459 idx(4) = m;
02460 idx(5) = n;
02461
02462 return remove_cols(idx);
02463 }
02464
02465
02466
02467
02503 Array< T > & remove_cols(unsigned i, unsigned j, unsigned k,
02504 unsigned l, unsigned m, unsigned n,
02505 unsigned o)
02506 {
02507 Array< unsigned > idx(7);
02508
02509 idx(0) = i;
02510 idx(1) = j;
02511 idx(2) = k;
02512 idx(3) = l;
02513 idx(4) = m;
02514 idx(5) = n;
02515 idx(6) = o;
02516
02517 return remove_cols(idx);
02518 }
02519
02520
02521
02522
02559 Array< T > & remove_cols(unsigned i, unsigned j, unsigned k,
02560 unsigned l, unsigned m, unsigned n,
02561 unsigned o, unsigned p)
02562 {
02563 Array< unsigned > idx(8);
02564
02565 idx(0) = i;
02566 idx(1) = j;
02567 idx(2) = k;
02568 idx(3) = l;
02569 idx(4) = m;
02570 idx(5) = n;
02571 idx(6) = o;
02572 idx(7) = p;
02573
02574 return remove_cols(idx);
02575 }
02576
02577
02578
02632 Array< T > append_cols(const Array< T >& y) const
02633 {
02634 SIZE_CHECK(ndim() == 0 || ndim() == y.ndim())
02635
02636 if (ndim() == 0)
02637 {
02638 return y;
02639 }
02640 else
02641 {
02642 unsigned i, j, xi, yi, zi;
02643
02644 unsigned xlast = dim(ndim() - 1);
02645
02646 unsigned ylast = y.dim(y.ndim() - 1);
02647 unsigned num;
02648
02649 Array< T > z;
02650
02651 Array< unsigned > da(dimarr());
02652
02653 da(ndim() - 1) = xlast + ylast;
02654
02655 z.resize_i(da.elemvec(), da.nelem(), false);
02656
02657 num = z.nelem() / (xlast + ylast);
02658 for (i = xi = yi = zi = 0; i < num; ++i)
02659 {
02660
02661 for (j = 0; j < xlast; ++j)
02662 {
02663 z.elem(zi++) = elem(xi++);
02664 }
02665
02666 for (j = 0; j < ylast; ++j)
02667 {
02668 z.elem(zi++) = y.elem(yi++);
02669 }
02670 }
02671
02672 return Array< T > (z, true);
02673 }
02674 }
02675
02676
02677
02678
02679
02735 Array< T > subarr(unsigned from, unsigned to) const
02736 {
02737 SIZE_CHECK(ndim() > 0)
02738 RANGE_CHECK(from <= to && from < dim(0) && to < dim(0))
02739
02740 unsigned i, j;
02741
02742 unsigned fromi = from * nelem() / dim(0);
02743
02744 unsigned toi = (to + 1) * nelem() / dim(0);
02745
02746 Array< T > z;
02747
02748 Array< unsigned > da(dimarr());
02749
02750 da(0) = to - from + 1;
02751
02752 z.resize_i(da.elemvec(), da.nelem(), false);
02753
02754 for (i = fromi, j = 0; i < toi; z.elem(j++) = elem(i++));
02755
02756 return Array< T > (z, true);
02757 }
02758
02759
02760
02761
02762
02796 Array< unsigned > pos2idx(unsigned p)
02797 {
02798 RANGE_CHECK(p < ne)
02799
02800 Array< unsigned > idx(ndim());
02801 for (unsigned i = 0, j = nelem(); i < ndim(); ++i)
02802 {
02803 p %= j;
02804 j /= dim(i);
02805 idx(i) = p / j;
02806 }
02807 return idx;
02808 }
02809
02810
02811
02812
02845 void pos2idx(unsigned p, Array<unsigned>& idx)
02846 {
02847 RANGE_CHECK(p < ne)
02848
02849 idx.resize(ndim());
02850 for (unsigned i = 0, j = nelem(); i < ndim(); ++i)
02851 {
02852 p %= j;
02853 j /= dim(i);
02854 idx(i) = p / j;
02855 }
02856 }
02857
02858
02859
02884 Array< T > row(unsigned i) const
02885 {
02886 return (*this)[ i ];
02887 }
02888
02889
02890
02918 Array< T > rows(const Array< unsigned >& idx) const
02919 {
02920 SIZE_CHECK(ndim() > 0)
02921 SIZE_CHECK(idx.ndim() <= 1)
02922
02923 unsigned i, j, k, l;
02924
02925 unsigned n = nelem() / dim(0);
02926
02927 Array< T > z;
02928
02929 Array< unsigned > da(dimarr());
02930
02931 da(0) = idx.nelem();
02932
02933 z.resize_i(da.elemvec(), da.nelem(), false);
02934
02935 for (k = i = 0; i < idx.nelem(); ++i)
02936 {
02937 for (l = idx(i) * n, j = 0; j < n; ++j)
02938 {
02939 z.elem(k++) = elem(l++);
02940 }
02941 }
02942
02943 return Array< T > (z, true);
02944 }
02945
02946
02947
02948
02977 Array< T > rows(unsigned i) const
02978 {
02979 Array< unsigned > idx(1);
02980
02981 idx(0) = i;
02982
02983 return rows(idx);
02984 }
02985
02986
02987
02988
03020 Array< T > rows(unsigned i, unsigned j) const
03021 {
03022 Array< unsigned > idx(2);
03023
03024 idx(0) = i;
03025 idx(1) = j;
03026
03027 return rows(idx);
03028 }
03029
03030
03031
03032
03066 Array< T > rows(unsigned i, unsigned j, unsigned k) const
03067 {
03068 Array< unsigned > idx(3);
03069
03070 idx(0) = i;
03071 idx(1) = j;
03072 idx(2) = k;
03073
03074 return rows(idx);
03075 }
03076
03077
03078
03079
03115 Array< T > rows(unsigned i, unsigned j, unsigned k,
03116 unsigned l) const
03117 {
03118 Array< unsigned > idx(4);
03119
03120 idx(0) = i;
03121 idx(1) = j;
03122 idx(2) = k;
03123 idx(3) = l;
03124
03125 return rows(idx);
03126 }
03127
03128
03129
03130
03169 Array< T > rows(unsigned i, unsigned j, unsigned k,
03170 unsigned l, unsigned m) const
03171 {
03172 Array< unsigned > idx(5);
03173
03174 idx(0) = i;
03175 idx(1) = j;
03176 idx(2) = k;
03177 idx(3) = l;
03178 idx(4) = m;
03179
03180 return rows(idx);
03181 }
03182
03183
03184
03185
03226 Array< T > rows(unsigned i, unsigned j, unsigned k,
03227 unsigned l, unsigned m, unsigned n) const
03228 {
03229 Array< unsigned > idx(6);
03230
03231 idx(0) = i;
03232 idx(1) = j;
03233 idx(2) = k;
03234 idx(3) = l;
03235 idx(4) = m;
03236 idx(5) = n;
03237
03238 return rows(idx);
03239 }
03240
03241
03242
03243
03286 Array< T > rows(unsigned i, unsigned j, unsigned k,
03287 unsigned l, unsigned m, unsigned n,
03288 unsigned o) const
03289 {
03290 Array< unsigned > idx(7);
03291
03292 idx(0) = i;
03293 idx(1) = j;
03294 idx(2) = k;
03295 idx(3) = l;
03296 idx(4) = m;
03297 idx(5) = n;
03298 idx(6) = o;
03299
03300 return rows(idx);
03301 }
03302
03303
03304
03305
03350 Array< T > rows(unsigned i, unsigned j, unsigned k,
03351 unsigned l, unsigned m, unsigned n,
03352 unsigned o, unsigned p) const
03353 {
03354 Array< unsigned > idx(8);
03355
03356 idx(0) = i;
03357 idx(1) = j;
03358 idx(2) = k;
03359 idx(3) = l;
03360 idx(4) = m;
03361 idx(5) = n;
03362 idx(6) = o;
03363 idx(7) = p;
03364
03365 return rows(idx);
03366 }
03367
03368
03369
03370
03371
03396 Array< T > col(unsigned i) const
03397 {
03398 SIZE_CHECK(ndim() > 0)
03399 RANGE_CHECK(i < dim(ndim() - 1))
03400
03401 Array< T > z;
03402
03403 Array< unsigned > da(dimarr());
03404
03405 z.resize_i(da.elemvec(), da.nelem() - 1, false);
03406
03407 for (unsigned k = 0; k < z.nelem(); ++k, i += dim(ndim() - 1))
03408 {
03409 z.elem(k) = elem(i);
03410 }
03411
03412 return z;
03413 }
03414
03415
03416
03417
03444 Array< T > cols(const Array< unsigned >& idx) const
03445 {
03446 SIZE_CHECK(ndim() > 0)
03447 SIZE_CHECK(idx.ndim() == 1)
03448
03449 unsigned j, k, m;
03450
03451 unsigned l = dim(ndim() - 1);
03452
03453 unsigned n = nelem() / l;
03454
03455 Array< T > z;
03456 Array< unsigned > ix(idx);
03457
03458 Array< unsigned > da(dimarr());
03459
03460 da(ndim() - 1) = ix.nelem();
03461
03462 z.resize_i(da.elemvec(), da.nelem(), false);
03463
03464 for (k = m = 0; k < n; ++k)
03465 {
03466 for (j = 0; j < ix.nelem(); ++j, ++m)
03467 {
03468 z.elem(m) = elem(ix(j));
03469 ix(j) += l;
03470 }
03471 }
03472
03473 return z;
03474 }
03475
03476
03477
03478
03506 Array< T > cols(unsigned i) const
03507 {
03508 Array< unsigned > idx(1);
03509
03510 idx(0) = i;
03511
03512 return cols(idx);
03513 }
03514
03515
03516
03517
03547 Array< T > cols(unsigned i, unsigned j) const
03548 {
03549 Array< unsigned > idx(2);
03550
03551 idx(0) = i;
03552 idx(1) = j;
03553
03554 return cols(idx);
03555 }
03556
03557
03558
03559
03591 Array< T > cols(unsigned i, unsigned j, unsigned k) const
03592 {
03593 Array< unsigned > idx(3);
03594
03595 idx(0) = i;
03596 idx(1) = j;
03597 idx(2) = k;
03598
03599 return cols(idx);
03600 }
03601
03602
03603
03604
03638 Array< T > cols(unsigned i, unsigned j, unsigned k,
03639 unsigned l) const
03640 {
03641 Array< unsigned > idx(4);
03642
03643 idx(0) = i;
03644 idx(1) = j;
03645 idx(2) = k;
03646 idx(3) = l;
03647
03648 return cols(idx);
03649 }
03650
03651
03652
03653
03691 Array< T > cols(unsigned i, unsigned j, unsigned k,
03692 unsigned l, unsigned m) const
03693 {
03694 Array< unsigned > idx(5);
03695
03696 idx(0) = i;
03697 idx(1) = j;
03698 idx(2) = k;
03699 idx(3) = l;
03700 idx(4) = m;
03701
03702 return cols(idx);
03703 }
03704
03705
03706
03707
03747 Array< T > cols(unsigned i, unsigned j, unsigned k,
03748 unsigned l, unsigned m, unsigned n) const
03749 {
03750 Array< unsigned > idx(6);
03751
03752 idx(0) = i;
03753 idx(1) = j;
03754 idx(2) = k;
03755 idx(3) = l;
03756 idx(4) = m;
03757 idx(5) = n;
03758
03759 return cols(idx);
03760 }
03761
03762
03763
03764
03806 Array< T > cols(unsigned i, unsigned j, unsigned k,
03807 unsigned l, unsigned m, unsigned n,
03808 unsigned o) const
03809 {
03810 Array< unsigned > idx(7);
03811
03812 idx(0) = i;
03813 idx(1) = j;
03814 idx(2) = k;
03815 idx(3) = l;
03816 idx(4) = m;
03817 idx(5) = n;
03818 idx(6) = o;
03819
03820 return cols(idx);
03821 }
03822
03823
03824
03825
03869 Array< T > cols(unsigned i, unsigned j, unsigned k,
03870 unsigned l, unsigned m, unsigned n,
03871 unsigned o, unsigned p) const
03872 {
03873 Array< unsigned > idx(8);
03874
03875 idx(0) = i;
03876 idx(1) = j;
03877 idx(2) = k;
03878 idx(3) = l;
03879 idx(4) = m;
03880 idx(5) = n;
03881 idx(6) = o;
03882 idx(7) = p;
03883
03884 return cols(idx);
03885 }
03886
03887
03888
03889
03929 Array< T >& transpose()
03930 {
03931 switch (ndim())
03932 {
03933 case 0 :
03934 case 1 :
03935 break;
03936 case 2 :
03937 {
03938 int d0 = d[1];
03939 int d1 = d[0];
03940 int i, j, k, s;
03941 for (i = 0, s = d0 * d1; s > 0; i++)
03942 {
03943 for (j = (i % d1) * d0 + i / d1; j > i; j = (j % d1) * d0 + j / d1);
03944 if (j < i) continue;
03945 for (k = i, j = (i % d1) * d0 + i / d1; j != i; k = j, j = (j % d1) * d0 + j / d1)
03946 {
03947 std::swap(e[k], e[j]);
03948 s--;
03949 }
03950 s--;
03951 }
03952 d[0] = d0;
03953 d[1] = d1;
03954 break;
03955 }
03956 default :
03957 {
03958 int d0 = d[1];
03959 int d1 = d[0];
03960 int i, j, k, s;
03961 unsigned a, b, c, size = nelem() / (d0 * d1);
03962 for (i = 0, s = d0 * d1; s > 0; i++)
03963 {
03964 for (j = (i % d1) * d0 + i / d1; j > i; j = (j % d1) * d0 + j / d1);
03965 if (j < i) continue;
03966 for (k = i, j = (i % d1) * d0 + i / d1; j != i; k = j, j = (j % d1) * d0 + j / d1)
03967 {
03968 a = k * size;
03969 b = j * size;
03970 for (c = 0; c < size; c++)
03971 {
03972 std::swap(e[a], e[b]);
03973 a++;
03974 b++;
03975 }
03976 s--;
03977 }
03978 s--;
03979 }
03980 d[0] = d0;
03981 d[1] = d1;
03982 break;
03983 }
03984 }
03985
03986 return *this;
03987 }
03988
03989
04026 Array<T>& rotate_rows(int n)
04027 {
04028 SIZE_CHECK(ndim() > 0);
04029
04030 int f, fc = d[0];
04031 int i, ic = ne / fc;
04032 std::vector<T> tmp(fc);
04033
04034 n = n % fc;
04035 if (n < 0) n += fc;
04036 if (n == 0) return *this;
04037 RANGE_CHECK(0 <= n && n < fc);
04038
04039 T* data = e;
04040 for (i=0; i<ic; i++)
04041 {
04042 for (f=0; f<fc; f++) tmp[f] = data[ic * f];
04043 for (f=0; f<n; f++) data[ic * f] = tmp[f - n + fc];
04044 for (; f<fc; f++) data[ic * f] = tmp[f - n];
04045 data++;
04046 }
04047
04048 return *this;
04049 }
04050
04051
04052
04095 Array<T>& rotate_cols(int n)
04096 {
04097 SIZE_CHECK(ndim() > 0);
04098
04099 int lastDim = nd - 1;
04100 int f, fc = d[lastDim];
04101 int i, ic = ne / fc;
04102 std::vector<T> tmp(fc);
04103
04104 n = n % fc;
04105 if (n < 0) n += fc;
04106 if (n == 0) return *this;
04107 RANGE_CHECK(0 < n && n < fc);
04108
04109 T* data = e;
04110 for (i=0; i<ic; i++)
04111 {
04112 for (f=0; f<fc; f++) tmp[f] = data[f];
04113 for (f=0; f<n; f++) data[f] = tmp[f - n + fc];
04114 for (; f<fc; f++) data[f] = tmp[f - n];
04115 data += fc;
04116 }
04117
04118 return *this;
04119 }
04120
04121
04122
04141 Array< unsigned > dimarr() const
04142 {
04143 Array< unsigned > dim(nd);
04144 for (unsigned i = nd; i--; dim(i) = d[ i ]);
04145 return dim;
04146 }
04147
04148
04149
04150
04171 ArrayBase* clone() const
04172 {
04173 return new Array< T > (*this);
04174 }
04175
04176
04177
04199 ArrayBase* empty() const
04200 {
04201 return new Array< T >();
04202 }
04203
04204 #ifdef _WIN32
04206 bool operator == (const Array< T >&) const
04207 {
04208 return false;
04209 }
04210
04212 bool operator != (const Array< T >&) const
04213 {
04214 return false;
04215 }
04216
04218 bool operator < (const Array< T >&) const
04219 {
04220 return false;
04221 }
04222
04224 bool operator > (const Array< T >&) const
04225 {
04226 return false;
04227 }
04228 #endif
04229
04230
04231
04252 inline iterator begin()
04253 {
04254 return e;
04255 }
04256
04257
04258
04279 inline const const_iterator begin() const
04280 {
04281 return e;
04282 }
04283
04284
04305 inline iterator end()
04306 {
04307 return eEnd;
04308 }
04309
04310
04331 inline const const_iterator end() const
04332 {
04333 return eEnd;
04334 }
04335
04336 protected:
04337
04338
04410 T* e;
04411
04413 T* eEnd;
04414
04415
04416
04460 void resize_i(unsigned* _d, unsigned _nd, bool copy)
04461 {
04462 unsigned j, _ne;
04463
04464
04465 if (nd != _nd)
04466 {
04467
04468 SIZE_CHECK(! stat)
04469
04470
04471 if (nd)
04472 {
04473 delete[ ] d;
04474 }
04475
04476
04477 if ((nd = _nd) > 0)
04478 {
04479 d = new unsigned[ _nd ];
04480 }
04481 }
04482
04483 #ifndef NDEBUG
04484 if (stat)
04485 {
04486 for (j = _nd; j--;)
04487 {
04488 SIZE_CHECK(d[ j ] == _d[ j ])
04489 }
04490 }
04491 #endif
04492
04493
04494 for (j = _nd, _ne = 1; j--; _ne *= (d[ j ] = _d[ j ]));
04495 if (_nd == 0)
04496 {
04497 _ne = 0;
04498 }
04499
04500 if (ne != _ne)
04501 {
04502 SIZE_CHECK(! stat);
04503 #ifndef NDEBUG
04504 if (nd != _nd) throw ("Array resize warning: copying elements will not arrange elements correctly");
04505 else
04506 {
04507 for (j = 1; j < _nd; j++)
04508 {
04509 if (d[j] != _d[j])
04510 throw ("Array resize warning: copying elements will not arrange elements correctly");
04511 }
04512 }
04513 #endif
04514
04515 if (copy)
04516 {
04517 T* _e = e;
04518 if (_ne)
04519 {
04520 e = new T[ _ne ];
04521 }
04522 for (j = ne < _ne ? ne : _ne; j--; e[ j ] = _e[ j ]);
04523 if (ne)
04524 {
04525 delete[ ] _e;
04526 }
04527 }
04528 else
04529 {
04530 if (ne)
04531 {
04532 delete[ ] e;
04533 }
04534 if (_ne)
04535 {
04536 e = new T[ _ne ];
04537 }
04538 }
04539 ne = _ne;
04540 }
04541 eEnd = e + ne;
04542 }
04543
04544
04545
04572 Array(unsigned* _d, T* _e, unsigned _nd, unsigned _ne, bool _stat)
04573 {
04574 d = _d;
04575 e = _e;
04576 nd = _nd;
04577 ne = _ne;
04578 stat = _stat;
04579 eEnd = e + ne;
04580 }
04581
04582 #ifndef __ARRAY_NO_GENERIC_IOSTREAM
04583
04584
04585
04636 void readFrom(std::istream& is)
04637 {
04638 const unsigned MaxLen = 1024;
04639 char s[ MaxLen ];
04640 char* p;
04641 unsigned i;
04642 std::vector< unsigned > idx;
04643
04644
04645 is >> std::ws;
04646 is.getline(s, MaxLen);
04647
04648
04649 p = strchr(s, '>');
04650
04651 if (p && *p) p++;
04652 if (p && *p) p++;
04653
04654
04655
04656 TYPE_CHECK(p && *p)
04657 if (p && *p)
04658 {
04659 do
04660 {
04661 if (*p == ',')
04662 {
04663 p++;
04664 }
04665 idx.push_back(unsigned(strtol(p, &p, 10)));
04666 }
04667 while (p && *p == ',');
04668
04669 TYPE_CHECK(p && *p == ')')
04670
04671 resize(idx);
04672
04673
04674 for (i = 0; i < ne && is.good(); i++)
04675 {
04676 is >> e[ i ];
04677 }
04678 }
04679
04680 is >> std::ws;
04681 }
04682
04683
04684
04685
04726 void writeTo(std::ostream& os) const
04727 {
04728 unsigned i;
04729
04730 os << "Array<" << typeid(T).name() << ">(";
04731 for (i = 0; i < nd; i++)
04732 {
04733 if (i) os << ',';
04734 os << d[ i ];
04735 }
04736 os << ")\n";
04737
04738 for (i = 0; i < ne; i++)
04739 {
04740 if (i) os << '\t';
04741 os << e[ i ];
04742 }
04743 os << std::endl;
04744 }
04745 #endif // !__ARRAY_NO_GENERIC_IOSTREAM
04746 };
04747
04748
04749
04766 template< class T >
04767 class ArrayReference : public Array< T >
04768 {
04769 public:
04770
04771
04788 ArrayReference()
04789 : Array< T >()
04790 {
04791 this->stat = true;
04792 this->d = NULL;
04793 this->e = NULL;
04794 this->nd = 0;
04795 this->ne = 0;
04796 }
04797
04798
04799
04823 ArrayReference(unsigned* _d, T* _e, unsigned _nd, unsigned _ne)
04824 : Array< T >()
04825 {
04826 this->d = _d;
04827 this->e = _e;
04828 this->nd = _nd;
04829 this->ne = _ne;
04830 this->stat = true;
04831 this->eEnd = this->e + this->ne;
04832 }
04833
04834
04835
04855 ~ArrayReference()
04856 { }
04857
04858
04859
04860
04879 ArrayReference< T > operator = (const T& v)
04880 {
04881 Array< T >::operator = (v);
04882 return *this;
04883 }
04884
04885
04886
04887
04912 ArrayReference< T > operator = (const std::vector< T >& v)
04913 {
04914 Array< T >::operator = (v);
04915 return *this;
04916 }
04917
04918
04919
04920
04945 ArrayReference< T > operator = (const Array< T >& v)
04946 {
04947 Array< T >::operator = (v);
04948 return *this;
04949 }
04950
04951
04952
04970 ArrayReference< T > copyReference(Array< T >& v)
04971 {
04972 this->d = v.d;
04973 this->e = v.e;
04974 this->nd = v.nd;
04975 this->ne = v.ne;
04976 this->stat = true;
04977 this->eEnd = this->e + this->ne;
04978 return *this;
04979 }
04980
04981
05000 ArrayReference< T > copyReference(ArrayReference< T > v)
05001 {
05002 this->d = v.d;
05003 this->e = v.e;
05004 this->nd = v.nd;
05005 this->ne = v.ne;
05006 this->stat = true;
05007 this->eEnd = this->e + this->ne;
05008 return *this;
05009 }
05010 };
05011
05012
05052 template< class T >
05053 inline ArrayReference< T > Array< T >::operator [ ](unsigned i)
05054 {
05055 SIZE_CHECK(nd > 0)
05056 RANGE_CHECK(i < d[ 0 ])
05057 return ArrayReference< T > (d + 1, e + i*(ne / d[ 0 ]), nd - 1, ne / d[ 0 ]);
05058 }
05059
05060
05061
05101 template< class T >
05102 inline const ArrayReference< T > Array< T >::operator [ ](unsigned i) const
05103 {
05104 SIZE_CHECK(nd > 0)
05105 RANGE_CHECK(i < d[ 0 ])
05106 return ArrayReference< T > (d + 1, e + i*(ne / d[ 0 ]), nd - 1, ne / d[ 0 ]);
05107 }
05108
05109
05110 #endif //__ARRAY_H
05111