00001
00012 #ifndef DLRNUMERIC_ARRAYND_H
00013 #define DLRNUMERIC_ARRAYND_H
00014
00015 #include <iostream>
00016 #include <string>
00017 #include <dlrCommon/exception.h>
00018 #include <dlrNumeric/array1D.h>
00019
00020 namespace dlr {
00021
00022
00023 namespace numeric {
00024
00072 template <size_t Dimension, class Type>
00073 class ArrayND {
00074 public:
00075
00076
00080 typedef Type value_type;
00081
00085 typedef Type* iterator;
00086
00091 typedef const Type* const_iterator;
00092
00093
00094
00095
00099 ArrayND();
00100
00101
00128 explicit
00129 ArrayND(size_t dimension, size_t const shape[]);
00130
00131
00151 explicit
00152 ArrayND(const Array1D<size_t>& shape);
00153
00154
00161 ArrayND(const ArrayND<Dimension, Type> &source);
00162
00163
00173 explicit
00174 ArrayND(const std::string& inputString);
00175
00176
00181 ~ArrayND();
00182
00183
00189 iterator
00190 begin() {return m_storage.begin();}
00191
00192
00199 const_iterator
00200 begin() const {return m_storage.begin();}
00201
00202
00209 inline void
00210 checkDimension(Array1D<size_t> const& shape) const;
00211
00212
00217 void
00218 clear() {m_shape.reinit(0); m_storage.reinit(0);}
00219
00220
00226 ArrayND<Dimension, Type>
00227 copy() const;
00228
00229
00240 template <class Type2> void
00241 copy(const ArrayND<Dimension, Type2>& source);
00242
00243
00250 template <class Type2> void
00251 copy(const Type2* dataPtr);
00252
00253
00265 Type*
00266 data() {return m_storage.data();}
00267
00268
00277 const Type*
00278 data() const {return m_storage.data();}
00279
00280
00288 bool
00289 empty() const {return m_storage.empty();}
00290
00291
00298 iterator
00299 end() {return m_storage.end();}
00300
00301
00308 const_iterator
00309 end() const {return m_storage.end();}
00310
00311
00322 size_t
00323 flattenIndex(const Array1D<size_t>& indexArray) const;
00324
00325
00335 inline Type
00336 getElement(size_t index0) const {return this->operator()(index0);}
00337
00338
00348 inline Type
00349 getElement(Array1D<size_t> const& index0) const {
00350 return this->operator()(index0);
00351 }
00352
00353
00365 inline const Array1D<size_t>&
00366 getShape() const {return m_shape;}
00367
00368
00383 size_t
00384 getStride(size_t axis) const {return m_strideArray[axis];}
00385
00386
00395 bool
00396 isAllocated() const {return true;}
00397
00398
00406 Array1D<Type>
00407 ravel() {return m_storage;}
00408
00409
00417 Array1D<Type> const
00418 ravel() const {return m_storage;}
00419
00420
00427 void
00428 reinit(Array1D<size_t> const& shape);
00429
00430
00444 Type&
00445 setElement(size_t index0, const Type& value) {
00446 return this->operator()(index0) = value;
00447 }
00448
00449
00463 Type&
00464 setElement(Array1D<size_t> const& index0, const Type& value) {
00465 return this->operator()(this->flattenIndex(index0)) = value;
00466 }
00467
00468
00474 size_t
00475 size() const {return m_storage.size();}
00476
00477
00486 ArrayND<Dimension, Type>&
00487 operator=(const ArrayND<Dimension, Type>& source);
00488
00489
00497 inline ArrayND<Dimension, Type>&
00498 operator=(Type value);
00499
00500
00508 Type&
00509 operator()(size_t index0) {return m_storage(index0);}
00510
00511
00519 Type operator()(size_t index0) const {return m_storage(index0);}
00520
00521
00529 Type&
00530 operator()(Array1D<size_t> const& index0) {
00531 return m_storage[this->flattenIndex(index0)];
00532 }
00533
00534
00542 Type operator()(Array1D<size_t> const& index0) const {
00543 return m_storage[this->flattenIndex(index0)];
00544 }
00545
00546
00555 Type& operator[](size_t index) {return this->operator()(index);}
00556
00557
00566 Type operator[](size_t index) const {return this->operator()(index);}
00567
00568
00580 template <class Type2>
00581 ArrayND<Dimension, Type>&
00582 operator+=(const ArrayND<Dimension, Type2>& arg);
00583
00584
00592 ArrayND<Dimension, Type>&
00593 operator+=(const Type arg);
00594
00595
00607 template <class Type2>
00608 ArrayND<Dimension, Type>&
00609 operator-=(const ArrayND<Dimension, Type2>& arg);
00610
00611
00619 ArrayND<Dimension, Type>&
00620 operator-=(const Type arg);
00621
00622
00634 template <class Type2>
00635 ArrayND<Dimension, Type>&
00636 operator*=(const ArrayND<Dimension, Type2>& arg);
00637
00638
00646 ArrayND<Dimension, Type>&
00647 operator*=(const Type arg);
00648
00649
00661 template <class Type2>
00662 ArrayND<Dimension, Type>&
00663 operator/=(const ArrayND<Dimension, Type2>& arg);
00664
00665
00673 ArrayND<Dimension, Type>&
00674 operator/=(const Type arg);
00675
00676 private:
00677
00678
00679 size_t computeSize(Array1D<size_t> const& shape) const;
00680 Array1D<size_t> computeStride(Array1D<size_t> const& shape) const;
00681
00682
00683
00684 Array1D<size_t> m_shape;
00685 Array1D<Type> m_storage;
00686 Array1D<size_t> m_strideArray;
00687 };
00688
00689
00690
00691
00705 template <size_t Dimension, class Type>
00706 ArrayND<Dimension, Type>
00707 operator+(const ArrayND<Dimension, Type>& array0,
00708 const ArrayND<Dimension, Type>& arrayN);
00709
00710
00724 template <size_t Dimension, class Type>
00725 ArrayND<Dimension, Type>
00726 operator-(const ArrayND<Dimension, Type>& array0,
00727 const ArrayND<Dimension, Type>& arrayN);
00728
00729
00743 template <size_t Dimension, class Type>
00744 ArrayND<Dimension, Type>
00745 operator*(const ArrayND<Dimension, Type>& array0,
00746 const ArrayND<Dimension, Type>& arrayN);
00747
00748
00762 template <size_t Dimension, class Type>
00763 ArrayND<Dimension, Type>
00764 operator/(const ArrayND<Dimension, Type>& array0,
00765 const ArrayND<Dimension, Type>& arrayN);
00766
00767
00779 template <size_t Dimension, class Type>
00780 ArrayND<Dimension, Type>
00781 operator+(const ArrayND<Dimension, Type>& array, Type scalar);
00782
00783
00795 template <size_t Dimension, class Type>
00796 ArrayND<Dimension, Type>
00797 operator-(const ArrayND<Dimension, Type>& array0, Type scalar);
00798
00799
00811 template <size_t Dimension, class Type>
00812 ArrayND<Dimension, Type>
00813 operator*(const ArrayND<Dimension, Type>& array0, Type scalar);
00814
00815
00827 template <size_t Dimension, class Type>
00828 ArrayND<Dimension, Type>
00829 operator/(const ArrayND<Dimension, Type>& array0, Type scalar);
00830
00831
00843 template <size_t Dimension, class Type>
00844 inline ArrayND<Dimension, Type>
00845 operator+(Type scalar, const ArrayND<Dimension, Type>& array0);
00846
00847
00859 template <size_t Dimension, class Type>
00860 inline ArrayND<Dimension, Type>
00861 operator-(Type scalar, const ArrayND<Dimension, Type>& array0);
00862
00863
00875 template <size_t Dimension, class Type>
00876 inline ArrayND<Dimension, Type>
00877 operator*(Type scalar, const ArrayND<Dimension, Type>& array0);
00878
00879
00891 template <size_t Dimension, class Type>
00892 inline ArrayND<Dimension, Type>
00893 operator/(Type scalar, const ArrayND<Dimension, Type>& array0);
00894
00895
00907 template <size_t Dimension, class Type>
00908 ArrayND<Dimension, bool>
00909 operator==(const ArrayND<Dimension, Type>& array0, const Type arg);
00910
00911
00924 template <size_t Dimension, class Type>
00925 ArrayND<Dimension, bool>
00926 operator==(const ArrayND<Dimension, Type>& array0,
00927 const ArrayND<Dimension, Type>& arrayN);
00928
00929
00940 template <size_t Dimension, class Type>
00941 ArrayND<Dimension, bool>
00942 operator>(const ArrayND<Dimension, Type>& array0, const Type arg);
00943
00944
00956 template <size_t Dimension, class Type>
00957 ArrayND<Dimension, bool>
00958 operator>=(const ArrayND<Dimension, Type>& array0, const Type arg);
00959
00960
00971 template <size_t Dimension, class Type>
00972 ArrayND<Dimension, bool>
00973 operator<(const ArrayND<Dimension, Type>& array0, const Type arg);
00974
00975
00987 template <size_t Dimension, class Type>
00988 ArrayND<Dimension, bool>
00989 operator<=(const ArrayND<Dimension, Type>& array0, const Type arg);
00990
00991
00992 template <size_t Dimension, class Type>
00993 std::ostream& operator<<(std::ostream& stream,
00994 const ArrayND<Dimension, Type>& array0);
00995
00996
00997 template <size_t Dimension, class Type>
00998 std::istream& operator>>(std::istream& stream,
00999 ArrayND<Dimension, Type> & array0);
01000
01001 }
01002
01003 }
01004
01005
01006
01007
01008
01009 #include <algorithm>
01010 #include <numeric>
01011 #include <sstream>
01012 #include <vector>
01013 #include <dlrNumeric/numericTraits.h>
01014
01015 namespace dlr {
01016
01017 namespace numeric {
01018
01019 template <size_t Dimension, class Type>
01020 ArrayND<Dimension, Type>::
01021 ArrayND()
01022 : m_shape(),
01023 m_storage(),
01024 m_strideArray()
01025 {
01026
01027 }
01028
01029
01030 template <size_t Dimension, class Type>
01031 ArrayND<Dimension, Type>::
01032 ArrayND(size_t dimension, size_t const shape[])
01033 : m_shape(dimension),
01034 m_storage(),
01035 m_strideArray()
01036 {
01037 m_shape.copy(shape);
01038 m_storage.reinit(this->computeSize(m_shape));
01039 }
01040
01041
01042
01043 template <size_t Dimension, class Type>
01044 ArrayND<Dimension, Type>::
01045 ArrayND(const Array1D<size_t>& shape)
01046 : m_shape(shape.copy()),
01047 m_storage(this->computeSize(m_shape)),
01048 m_strideArray(this->computeStride(m_shape))
01049 {
01050
01051 }
01052
01053
01054
01055
01056
01057 template <size_t Dimension, class Type>
01058 ArrayND<Dimension, Type>::
01059 ArrayND(const ArrayND<Dimension, Type>& source)
01060 : m_shape(source.m_shape.copy()),
01061 m_storage(source.m_storage),
01062 m_strideArray(source.m_strideArray.copy())
01063 {
01064
01065 }
01066
01067
01068
01069 template <size_t Dimension, class Type>
01070 ArrayND<Dimension, Type>::
01071 ArrayND(const std::string& inputString)
01072 {
01073 std::istringstream stream(inputString);
01074 stream >> *this;
01075 if(!stream) {
01076 DLR_THROW(ValueException, "ArrayND::ArrayND(std::string const&)",
01077 "Malformed input string.");
01078 }
01079 }
01080
01081
01082 template <size_t Dimension, class Type>
01083 ArrayND<Dimension, Type>::
01084 ~ArrayND()
01085 {
01086
01087 }
01088
01089
01090 template <size_t Dimension, class Type>
01091 inline void ArrayND<Dimension, Type>::
01092 checkDimension(Array1D<size_t> const& shape) const
01093 {
01094
01095
01096 if(shape.size() != m_shape.size()) {
01097 std::ostringstream message;
01098 message << "Dimensionality mismatch: required dimensionality is "
01099 << shape.size()
01100 << " while *this has dimension " << m_shape.size() << ".";
01101 DLR_THROW(IndexException, "ArrayND::checkDimension()",
01102 message.str().c_str());
01103 }
01104 for(size_t dimension = 0; dimension < m_shape.size(); ++dimension) {
01105 if(m_shape[dimension] != shape[dimension]) {
01106 std::ostringstream message;
01107 message << "Shape mismatch: required shape is " << shape
01108 << " while *this has shape " << m_shape << ".";
01109 DLR_THROW(IndexException, "ArrayND::checkDimension()",
01110 message.str().c_str());
01111 }
01112 }
01113
01114 }
01115
01116
01117 template <size_t Dimension, class Type>
01118 ArrayND<Dimension, Type> ArrayND<Dimension, Type>::
01119 copy() const
01120 {
01121 ArrayND<Dimension, Type> newArray(m_shape);
01122 newArray.copy(*this);
01123 return newArray;
01124 }
01125
01126
01127 template <size_t Dimension, class Type> template <class Type2>
01128 void ArrayND<Dimension, Type>::
01129 copy(const ArrayND<Dimension, Type2>& source)
01130 {
01131 this->checkDimension(source.m_shape);
01132 if(m_storage.size() != 0) {
01133 this->copy(source.data());
01134 }
01135 }
01136
01137
01138 template <size_t Dimension, class Type> template <class Type2>
01139 void
01140 ArrayND<Dimension, Type>::
01141 copy(const Type2* dataPtr)
01142 {
01143 m_storage.copy(dataPtr);
01144 }
01145
01146
01147 template <size_t Dimension, class Type>
01148 ArrayND<Dimension, Type>&
01149 ArrayND<Dimension, Type>::
01150 operator=(Type val)
01151 {
01152 m_storage = val;
01153 return *this;
01154 }
01155
01156
01157 template <size_t Dimension, class Type>
01158 size_t
01159 ArrayND<Dimension, Type>::
01160 flattenIndex(const Array1D<size_t>& indexArray) const
01161 {
01162 dlr::numeric::Array1D<size_t>::const_iterator endMinus = indexArray.end();
01163 --endMinus;
01164 return std::inner_product(indexArray.begin(), endMinus,
01165 m_strideArray.begin(), *endMinus);
01166 }
01167
01168
01169 template <size_t Dimension, class Type>
01170 void ArrayND<Dimension, Type>::
01171 reinit(Array1D<size_t> const& shape)
01172 {
01173 m_shape = shape.copy();
01174 m_storage.reinit(this->computeSize(m_shape));
01175 m_strideArray = this->computeStride(m_shape);
01176 }
01177
01178
01179 template <size_t Dimension, class Type>
01180 ArrayND<Dimension, Type>& ArrayND<Dimension, Type>::
01181 operator=(const ArrayND<Dimension, Type>& source)
01182 {
01183
01184 if(&source != this) {
01185 m_shape = source.m_shape.copy();
01186 m_storage = source.m_storage;
01187 m_strideArray = source.m_strideArray.copy();
01188 }
01189 return *this;
01190 }
01191
01192
01193 template <size_t Dimension, class Type> template <class Type2>
01194 ArrayND<Dimension, Type>&
01195 ArrayND<Dimension, Type>::
01196 operator+=(const ArrayND<Dimension, Type2>& arg)
01197 {
01198
01199 m_storage += arg.m_storage;
01200 return *this;
01201 }
01202
01203
01204 template <size_t Dimension, class Type>
01205 ArrayND<Dimension, Type>&
01206 ArrayND<Dimension, Type>::
01207 operator+=(const Type arg)
01208 {
01209 m_storage += arg;
01210 return *this;
01211 }
01212
01213
01214 template <size_t Dimension, class Type> template <class Type2>
01215 ArrayND<Dimension, Type>&
01216 ArrayND<Dimension, Type>::
01217 operator-=(const ArrayND<Dimension, Type2>& arg)
01218 {
01219
01220 m_storage -= arg.m_storage;
01221 return *this;
01222 }
01223
01224
01225 template <size_t Dimension, class Type>
01226 ArrayND<Dimension, Type>&
01227 ArrayND<Dimension, Type>::
01228 operator-=(const Type arg)
01229 {
01230 m_storage -= arg;
01231 return *this;
01232 }
01233
01234
01235 template <size_t Dimension, class Type> template <class Type2>
01236 ArrayND<Dimension, Type>&
01237 ArrayND<Dimension, Type>::
01238 operator*=(const ArrayND<Dimension, Type2>& arg)
01239 {
01240
01241 m_storage *= arg.m_storage;
01242 return *this;
01243 }
01244
01245
01246 template <size_t Dimension, class Type>
01247 ArrayND<Dimension, Type>&
01248 ArrayND<Dimension, Type>::
01249 operator*=(const Type arg)
01250 {
01251 m_storage *= arg;
01252 return *this;
01253 }
01254
01255
01256 template <size_t Dimension, class Type> template <class Type2>
01257 ArrayND<Dimension, Type>&
01258 ArrayND<Dimension, Type>::
01259 operator/=(const ArrayND<Dimension, Type2>& arg)
01260 {
01261
01262 m_storage /= arg.m_storage;
01263 return *this;
01264 }
01265
01266
01267 template <size_t Dimension, class Type>
01268 ArrayND<Dimension, Type>&
01269 ArrayND<Dimension, Type>::
01270 operator/=(const Type arg)
01271 {
01272 m_storage /= arg;
01273 return *this;
01274 }
01275
01276
01277 template <size_t Dimension, class Type>
01278 size_t
01279 ArrayND<Dimension, Type>::
01280 computeSize(Array1D<size_t> const& shape) const
01281 {
01282 return std::accumulate(shape.begin(), shape.end(), size_t(1),
01283 std::multiplies<size_t>());
01284 }
01285
01286
01287 template <size_t Dimension, class Type>
01288 Array1D<size_t>
01289 ArrayND<Dimension, Type>::
01290 computeStride(Array1D<size_t> const& shape) const
01291 {
01292 Array1D<size_t> strideArray(shape.size());
01293 strideArray[shape.size() - 1] = 1;
01294 for(size_t ii = shape.size() - 1; ii != 0; --ii) {
01295 strideArray[ii - 1] = shape[ii] * strideArray[ii];
01296 }
01297 return strideArray;
01298 }
01299
01300
01301
01302
01303 template <size_t Dimension, class Type>
01304 ArrayND<Dimension, Type> operator+(const ArrayND<Dimension, Type>& array0,
01305 const ArrayND<Dimension, Type>& arrayN)
01306 {
01307 if(array0.size() != arrayN.size()) {
01308 std::ostringstream message;
01309 message << "Array sizes do not match. Array0 has " << array0.size()
01310 << " elements, while arrayN has " << arrayN.size()
01311 << " elements.";
01312 DLR_THROW(ValueException, "ArrayND::operator+()", message.str().c_str());
01313 }
01314 ArrayND<Dimension, Type> result(array0.getShape());
01315 std::transform(array0.begin(), array0.end(), arrayN.begin(),
01316 result.begin(), std::plus<Type>());
01317 return result;
01318 }
01319
01320
01321 template <size_t Dimension, class Type>
01322 ArrayND<Dimension, Type> operator-(const ArrayND<Dimension, Type>& array0,
01323 const ArrayND<Dimension, Type>& arrayN)
01324 {
01325 if(array0.size() != arrayN.size()) {
01326 std::ostringstream message;
01327 message << "Array sizes do not match. Array0 has " << array0.size()
01328 << " elements, while arrayN has " << arrayN.size()
01329 << " elements.";
01330 DLR_THROW(ValueException, "ArrayND::operator-()", message.str().c_str());
01331 }
01332 ArrayND<Dimension, Type> result(array0.getShape());
01333 std::transform(array0.begin(), array0.end(), arrayN.begin(),
01334 result.begin(), std::minus<Type>());
01335 return result;
01336 }
01337
01338
01339 template <size_t Dimension, class Type>
01340 ArrayND<Dimension, Type> operator*(const ArrayND<Dimension, Type>& array0,
01341 const ArrayND<Dimension, Type>& arrayN)
01342 {
01343 if(array0.size() != arrayN.size()) {
01344 std::ostringstream message;
01345 message << "Array sizes do not match. Array0 has " << array0.size()
01346 << " elements, while arrayN has " << arrayN.size()
01347 << " elements.";
01348 DLR_THROW(ValueException, "ArrayND::operator*()", message.str().c_str());
01349 }
01350 ArrayND<Dimension, Type> result(array0.getShape());
01351 std::transform(array0.begin(), array0.end(), arrayN.begin(),
01352 result.begin(), std::multiplies<Type>());
01353 return result;
01354 }
01355
01356
01357 template <size_t Dimension, class Type>
01358 ArrayND<Dimension, Type> operator/(const ArrayND<Dimension, Type>& array0,
01359 const ArrayND<Dimension, Type>& arrayN)
01360 {
01361 if(array0.size() != arrayN.size()) {
01362 std::ostringstream message;
01363 message << "Array sizes do not match. Array0 has " << array0.size()
01364 << " elements, while arrayN has " << arrayN.size()
01365 << " elements.";
01366 DLR_THROW(ValueException, "ArrayND::operator/()", message.str().c_str());
01367 }
01368 ArrayND<Dimension, Type> result(array0.getShape());
01369 std::transform(array0.begin(), array0.end(), arrayN.begin(),
01370 result.begin(), std::divides<Type>());
01371 return result;
01372 }
01373
01374
01375 template <size_t Dimension, class Type>
01376 ArrayND<Dimension, Type> operator+(const ArrayND<Dimension, Type>& array0, Type scalar)
01377 {
01378 ArrayND<Dimension, Type> result(array0.getShape());
01379 std::transform(array0.begin(), array0.end(), result.begin(),
01380 std::bind2nd(std::plus<Type>(), scalar));
01381 return result;
01382 }
01383
01384
01385 template <size_t Dimension, class Type>
01386 ArrayND<Dimension, Type> operator-(const ArrayND<Dimension, Type>& array0, Type scalar)
01387 {
01388 ArrayND<Dimension, Type> result(array0.getShape());
01389 std::transform(array0.begin(), array0.end(), result.begin(),
01390 std::bind2nd(std::minus<Type>(), scalar));
01391 return result;
01392 }
01393
01394
01395 template <size_t Dimension, class Type>
01396 ArrayND<Dimension, Type> operator*(const ArrayND<Dimension, Type>& array0, Type scalar)
01397 {
01398 ArrayND<Dimension, Type> result(array0.getShape());
01399 std::transform(array0.begin(), array0.end(), result.begin(),
01400 std::bind2nd(std::multiplies<Type>(), scalar));
01401 return result;
01402 }
01403
01404
01405 template <size_t Dimension, class Type>
01406 ArrayND<Dimension, Type> operator/(const ArrayND<Dimension, Type>& array0, Type scalar)
01407 {
01408 ArrayND<Dimension, Type> result(array0.getShape());
01409 std::transform(array0.begin(), array0.end(), result.begin(),
01410 std::bind2nd(std::divides<Type>(), scalar));
01411 return result;
01412 }
01413
01414
01415 template <size_t Dimension, class Type>
01416 inline ArrayND<Dimension, Type> operator+(Type scalar, const ArrayND<Dimension, Type>& array0)
01417 {
01418 return array0 + scalar;
01419 }
01420
01421
01422 template <size_t Dimension, class Type>
01423 ArrayND<Dimension, Type> operator-(Type scalar, const ArrayND<Dimension, Type>& array0)
01424 {
01425 ArrayND<Dimension, Type> result(array0.getShape());
01426 std::transform(array0.begin(), array0.end(), result.begin(),
01427 std::bind1st(std::minus<Type>(), scalar));
01428 return result;
01429 }
01430
01431
01432 template <size_t Dimension, class Type>
01433 inline ArrayND<Dimension, Type> operator*(Type scalar, const ArrayND<Dimension, Type>& array0)
01434 {
01435 return array0 * scalar;
01436 }
01437
01438
01439 template <size_t Dimension, class Type>
01440 ArrayND<Dimension, Type> operator/(Type scalar, const ArrayND<Dimension, Type>& array0)
01441 {
01442 ArrayND<Dimension, Type> result(array0.getShape());
01443 std::transform(array0.begin(), array0.end(), result.begin(),
01444 std::bind1st(std::divides<Type>(), scalar));
01445 return result;
01446 }
01447
01448
01449
01450 template <size_t Dimension, class Type>
01451 ArrayND<Dimension, bool>
01452 operator==(const ArrayND<Dimension, Type>& array0, const Type arg)
01453 {
01454 ArrayND<Dimension, bool> result(array0.getShape());
01455 std::transform(array0.begin(), array0.end(), result.data(),
01456 std::bind2nd(std::equal_to<Type>(), arg));
01457 return result;
01458 }
01459
01460
01461
01462 template <size_t Dimension, class Type>
01463 ArrayND<Dimension, bool>
01464 operator==(const ArrayND<Dimension, Type>& array0,
01465 const ArrayND<Dimension, Type>& arrayN)
01466 {
01467 array0.checkDimension(arrayN.getShape());
01468 ArrayND<Dimension, bool> result(array0.getShape());
01469 std::transform(array0.begin(), array0.end(), arrayN.begin(),
01470 result.begin(), std::equal_to<Type>());
01471 return result;
01472 }
01473
01474
01475 template <size_t Dimension, class Type>
01476 ArrayND<Dimension, bool>
01477 operator>(const ArrayND<Dimension, Type>& array0, const Type arg)
01478 {
01479 ArrayND<Dimension, bool> result(array0.getShape());
01480 std::transform(array0.begin(), array0.end(), result.begin(),
01481 std::bind2nd(std::greater<Type>(), arg));
01482 return result;
01483 }
01484
01485
01486 template <size_t Dimension, class Type>
01487 ArrayND<Dimension, bool>
01488 operator>=(const ArrayND<Dimension, Type>& array0, const Type arg)
01489 {
01490 ArrayND<Dimension, bool> result(array0.getShape());
01491 std::transform(array0.begin(), array0.end(), result.begin(),
01492 std::bind2nd(std::greater_equal<Type>(), arg));
01493 return result;
01494 }
01495
01496
01497 template <size_t Dimension, class Type>
01498 ArrayND<Dimension, bool>
01499 operator<(const ArrayND<Dimension, Type>& array0, const Type arg)
01500 {
01501 ArrayND<Dimension, bool> result(array0.getShape());
01502 std::transform(array0.begin(), array0.end(), result.begin(),
01503 std::bind2nd(std::less<Type>(), arg));
01504 return result;
01505 }
01506
01507
01508 template <size_t Dimension, class Type>
01509 ArrayND<Dimension, bool>
01510 operator<=(const ArrayND<Dimension, Type>& array0, const Type arg)
01511 {
01512 ArrayND<Dimension, bool> result(array0.getShape());
01513 std::transform(array0.begin(), array0.end(), result.begin(),
01514 std::bind2nd(std::less_equal<Type>(), arg));
01515 return result;
01516 }
01517
01518
01519 template <size_t Dimension, class Type>
01520 std::ostream& operator<<(std::ostream& stream,
01521 const ArrayND<Dimension, Type>& array0)
01522 {
01523 if (!stream){
01524 return stream;
01525 }
01526 stream << "ArrayND {\n"
01527 << " shape: " << array0.getShape() << "\n"
01528 << " data: " << array0.ravel() << "\n"
01529 << "}";
01530 return stream;
01531 }
01532
01533
01534
01535 template <size_t Dimension, class Type>
01536 std::istream& operator>>(std::istream& stream,
01537 ArrayND<Dimension, Type> & array0)
01538 {
01539 if (!stream){
01540 return stream;
01541 }
01542
01543
01544 InputStream inputStream(stream, InputStream::SKIP_WHITESPACE);
01545 inputStream.expect("ArrayND");
01546 inputStream.expect("{");
01547
01548 Array1D<size_t> shape;
01549 inputStream.expect("shape:");
01550 inputStream >> shape;
01551
01552 Array1D<Type> data;
01553 inputStream.expect("data:");
01554 inputStream >> data;
01555
01556 if(!inputStream) {
01557 return stream;
01558 }
01559 array0.reinit(shape);
01560 array0.copy(data.data());
01561 return stream;
01562 }
01563
01564 }
01565
01566 }
01567
01568 #endif