00001
00015 #ifndef _DLR_ARRAY1D_H_
00016 #define _DLR_ARRAY1D_H_
00017
00018 #include <iostream>
00019 #include <string>
00020 #include <dlrCommon/exception.h>
00021
00022 namespace dlr {
00023
00024
00030 namespace numeric {
00031
00054 template <class Type>
00055 class Array1D {
00056 public:
00057
00058
00062 typedef Type value_type;
00063
00067 typedef Type* iterator;
00068
00073 typedef const Type* const_iterator;
00074
00075
00076
00080 Array1D();
00081
00088 explicit
00089 Array1D(size_t size);
00090
00102 explicit
00103 Array1D(const std::string& inputString);
00104
00111 Array1D(const Array1D<Type> &source);
00112
00123 Array1D(size_t size, Type* const dataPtr);
00124
00142 Array1D(size_t size, Type* const dataPtr, size_t* const refCountPtr);
00143
00148 ~Array1D();
00149
00155 iterator
00156 begin() {return m_dataPtr;}
00157
00164 const_iterator
00165 begin() const {return m_dataPtr;}
00166
00167
00174 inline void
00175 checkDimension(size_t size) const;
00176
00177
00182 void
00183 clear() {this->reinit(0);}
00184
00190 Array1D<Type>
00191 copy() const;
00192
00203 template <class Type2> void
00204 copy(const Array1D<Type2>& source);
00205
00212 template <class Type2> void
00213 copy(const Type2* dataPtr);
00214
00222 Type*
00223 data() {return m_dataPtr;}
00224
00231 const Type*
00232 data() const {return m_dataPtr;}
00233
00244 Type*
00245 data(size_t index) {
00246 this->checkBounds(index);
00247 return m_dataPtr + index;
00248 }
00249
00259 const Type*
00260 data(size_t index) const {
00261 this->checkBounds(index);
00262 return m_dataPtr + index;
00263 }
00264
00265
00273 bool
00274 empty() const {return this->size() == 0;}
00275
00276
00283 iterator
00284 end() {return m_dataPtr + m_size;}
00285
00292 const_iterator
00293 end() const {return m_dataPtr + m_size;}
00294
00303 bool
00304 isAllocated() const {return m_isAllocated;}
00305
00312 size_t
00313 length() const {return this->size();}
00314
00327 std::istream&
00328 readFromStream(std::istream& inputStream);
00329
00337 size_t*
00338 refCountPtr() const {return m_refCountPtr;}
00339
00346 void
00347 reinit(size_t size);
00348
00355 size_t
00356 size() const {return m_size;}
00357
00366 Array1D<Type>&
00367 operator=(const Array1D<Type>& source);
00368
00376 Array1D<Type>&
00377 operator=(Type value);
00378
00386 Type&
00387 operator()(size_t index) {
00388 this->checkBounds(index);
00389 return m_dataPtr[index];
00390 }
00391
00399 Type operator()(size_t index) const {
00400 this->checkBounds(index);
00401 return m_dataPtr[index];
00402 }
00403
00412 Type& operator[](size_t index) {return this->operator()(index);}
00413
00422 Type operator[](size_t index) const {return this->operator()(index);}
00423
00435 template <class Type2>
00436 Array1D<Type>&
00437 operator+=(const Array1D<Type2>& arg);
00438
00446 Array1D<Type>&
00447 operator+=(const Type arg);
00448
00460 template <class Type2>
00461 Array1D<Type>&
00462 operator-=(const Array1D<Type2>& arg);
00463
00471 Array1D<Type>&
00472 operator-=(const Type arg);
00473
00485 template <class Type2>
00486 Array1D<Type>&
00487 operator*=(const Array1D<Type2>& arg);
00488
00496 Array1D<Type>&
00497 operator*=(const Type arg);
00498
00510 template <class Type2>
00511 Array1D<Type>&
00512 operator/=(const Array1D<Type2>& arg);
00513
00521 Array1D<Type>&
00522 operator/=(const Type arg);
00523
00524 private:
00525
00526
00530 void
00531 allocate();
00532
00539 inline void
00540 checkBounds(size_t index) const;
00541
00542
00548 void
00549 deAllocate();
00550
00551
00552
00553
00554
00559 static const std::string& ioIntro();
00560
00565 static const std::string& ioOutro();
00566
00571 static const char ioOpening = '[';
00572
00577 static const char ioClosing = ']';
00578
00583 static const char ioSeparator = ',';
00584
00585
00586 size_t m_size;
00587 Type* m_dataPtr;
00588 size_t* m_refCountPtr;
00589 bool m_isAllocated;
00590
00591 };
00592
00593
00594
00608 template <class Type>
00609 Array1D<Type>
00610 operator+(const Array1D<Type>& array0, const Array1D<Type>& array1);
00611
00625 template <class Type>
00626 Array1D<Type>
00627 operator-(const Array1D<Type>& array0, const Array1D<Type>& array1);
00628
00642 template <class Type>
00643 Array1D<Type>
00644 operator*(const Array1D<Type>& array0, const Array1D<Type>& array1);
00645
00659 template <class Type>
00660 Array1D<Type>
00661 operator/(const Array1D<Type>& array0, const Array1D<Type>& array1);
00662
00674 template <class Type>
00675 Array1D<Type> operator+(const Array1D<Type>& array, Type scalar);
00676
00688 template <class Type>
00689 Array1D<Type> operator-(const Array1D<Type>& array0, Type scalar);
00690
00702 template <class Type>
00703 Array1D<Type> operator*(const Array1D<Type>& array0, Type scalar);
00704
00716 template <class Type>
00717 Array1D<Type> operator/(const Array1D<Type>& array0, Type scalar);
00718
00730 template <class Type>
00731 inline Array1D<Type> operator+(Type scalar, const Array1D<Type>& array0);
00732
00733
00745 template <class Type>
00746 inline Array1D<Type> operator-(Type scalar, const Array1D<Type>& array0);
00747
00759 template <class Type>
00760 inline Array1D<Type> operator*(Type scalar, const Array1D<Type>& array0);
00761
00773 template <class Type>
00774 inline Array1D<Type> operator/(Type scalar, const Array1D<Type>& array0);
00775
00776
00788 template <class Type>
00789 Array1D<bool>
00790 operator==(const Array1D<Type>& array0, const Type arg);
00791
00792
00805 template <class Type>
00806 Array1D<bool>
00807 operator==(const Array1D<Type>& array0, const Array1D<Type>& array1);
00808
00809
00820 template <class Type>
00821 Array1D<bool>
00822 operator>(const Array1D<Type>& array0, const Type arg);
00823
00824
00836 template <class Type>
00837 Array1D<bool>
00838 operator>=(const Array1D<Type>& array0, const Type arg);
00839
00840
00851 template <class Type>
00852 Array1D<bool>
00853 operator<(const Array1D<Type>& array0, const Type arg);
00854
00855
00867 template <class Type>
00868 Array1D<bool>
00869 operator<=(const Array1D<Type>& array0, const Type arg);
00870
00871
00891 template <class Type>
00892 std::ostream& operator<<(std::ostream& stream, const Array1D<Type>& array0);
00893
00905 template <class Type>
00906 std::istream&
00907 operator>>(std::istream& stream, Array1D<Type>& array0);
00908
00909 }
00910
00911 }
00912
00913
00914
00915
00916 namespace dlr {
00917
00918 using numeric::Array1D;
00919
00920 }
00921
00922
00923
00924
00925
00926
00927
00928 #include <algorithm>
00929 #include <sstream>
00930 #include <vector>
00931 #include <dlrCommon/inputStream.h>
00932 #include <dlrNumeric/numericTraits.h>
00933
00934 namespace dlr {
00935
00936 namespace numeric {
00937
00938
00939
00940 template <class Type>
00941 const std::string&
00942 Array1D<Type>::
00943 ioIntro()
00944 {
00945 static const std::string intro = "Array1D(";
00946 return intro;
00947 }
00948
00949
00950
00951
00952 template <class Type>
00953 const std::string&
00954 Array1D<Type>::
00955 ioOutro()
00956 {
00957 static const std::string outro = ")";
00958 return outro;
00959 }
00960
00961
00962
00963 template <class Type>
00964 Array1D<Type>::
00965 Array1D()
00966 : m_size(0),
00967 m_dataPtr(0),
00968 m_refCountPtr(0),
00969 m_isAllocated(false)
00970 {
00971
00972 }
00973
00974
00975 template <class Type>
00976 Array1D<Type>::
00977 Array1D(size_t size)
00978 : m_size(size),
00979 m_dataPtr(0),
00980 m_refCountPtr(0),
00981 m_isAllocated(false)
00982 {
00983 this->allocate();
00984 }
00985
00986
00987
00988 template <class Type>
00989 Array1D<Type>::
00990 Array1D(const std::string& inputString)
00991 : m_size(0),
00992 m_dataPtr(0),
00993 m_refCountPtr(0),
00994 m_isAllocated(false)
00995 {
00996
00997 std::istringstream inputStream(inputString);
00998
00999
01000 Array1D<Type> inputArray;
01001 inputStream >> inputArray;
01002 if(!inputStream) {
01003 std::ostringstream message;
01004 message << "Couldn't parse input string: \"" << inputString << "\".";
01005 DLR_THROW3(ValueException, "Array1D::Array1D(const std::string&)",
01006 message.str().c_str());
01007 }
01008
01009
01010 *this = inputArray;
01011 }
01012
01013
01014
01015
01016
01017 template <class Type>
01018 Array1D<Type>::
01019 Array1D(const Array1D<Type>& source)
01020 : m_size(source.m_size),
01021 m_dataPtr(source.m_dataPtr),
01022 m_refCountPtr(source.m_refCountPtr),
01023 m_isAllocated(source.m_isAllocated)
01024 {
01025 if(m_isAllocated) {
01026 ++(*m_refCountPtr);
01027 }
01028 }
01029
01030
01031 template <class Type>
01032 Array1D<Type>::
01033 Array1D(size_t size, Type* const dataPtr)
01034 : m_size(size),
01035 m_dataPtr(dataPtr),
01036 m_refCountPtr(NULL),
01037 m_isAllocated(false)
01038 {
01039
01040 }
01041
01042
01043 template <class Type>
01044 Array1D<Type>::
01045 Array1D(size_t size, Type* const dataPtr, size_t* const refCountPtr)
01046 : m_size(size),
01047 m_dataPtr(dataPtr),
01048 m_refCountPtr(refCountPtr),
01049 m_isAllocated(true)
01050 {
01051 ++(*m_refCountPtr);
01052 }
01053
01054
01055 template <class Type>
01056 Array1D<Type>::~Array1D()
01057 {
01058 deAllocate();
01059 }
01060
01061
01062 template <class Type>
01063 inline void Array1D<Type>::
01064 checkDimension(size_t size) const
01065 {
01066 #ifdef _DLRNUMERIC_CHECKBOUNDS_
01067 if(size != this->size()) {
01068 std::ostringstream message;
01069 message << "Size mismatch: required size is " << size
01070 << " while *this has dimension " << this->size() << ".";
01071 DLR_THROW(IndexException, "Array1D::checkDimension()",
01072 message.str().c_str());
01073 }
01074 #endif
01075 }
01076
01077
01078 template <class Type>
01079 Array1D<Type> Array1D<Type>::
01080 copy() const
01081 {
01082 Array1D<Type> newArray(m_size);
01083 newArray.copy(*this);
01084 return newArray;
01085 }
01086
01087
01088 template <class Type> template <class Type2>
01089 void Array1D<Type>::
01090 copy(const Array1D<Type2>& source)
01091 {
01092 if(source.size() != m_size) {
01093 std::ostringstream message;
01094 message << "Mismatched array sizes. Source array has "
01095 << source.size() << " elements, while destination array has "
01096 << m_size << " elements.";
01097 DLR_THROW3(ValueException, "Array1D::copy(const Array1D&)",
01098 message.str().c_str());
01099 }
01100 if(m_size != 0) {
01101 this->copy(source.data());
01102 }
01103 }
01104
01105
01106 template <class Type> template <class Type2>
01107 void
01108 Array1D<Type>::
01109 copy(const Type2* dataPtr)
01110 {
01111 std::copy(dataPtr, dataPtr + m_size, m_dataPtr);
01112 }
01113
01114
01115 template <class Type>
01116 Array1D<Type>& Array1D<Type>::
01117 operator=(Type val)
01118 {
01119 std::fill(m_dataPtr, m_dataPtr + m_size, val);
01120 return *this;
01121 }
01122
01123
01124
01125
01126 template <class Type>
01127 std::istream&
01128 Array1D<Type>::
01129 readFromStream(std::istream& inputStream)
01130 {
01131
01132 typedef typename NumericTraits<Type>::TextOutputType InputType;
01133
01134
01135 if (!inputStream){
01136 return inputStream;
01137 }
01138
01139
01140
01141
01142 std::ios_base::iostate oldExceptionState = inputStream.exceptions();
01143 inputStream.exceptions(
01144 std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
01145
01146
01147 try{
01148
01149
01150 InputStream stream(inputStream);
01151
01152 stream.skipWhiteSpace();
01153
01154
01155
01156 bool foundIntro = false;
01157 if(stream.peek() == ioIntro()[0]) {
01158 foundIntro = true;
01159 stream.expect(ioIntro());
01160 }
01161
01162
01163
01164
01165 stream.expect(ioOpening);
01166
01167
01168 InputType inputValue;
01169 std::vector<Type> inputBuffer;
01170 while(1) {
01171
01172 stream >> inputValue;
01173 inputBuffer.push_back(static_cast<Type>(inputValue));
01174
01175
01176 char inChar = 0;
01177 stream >> inChar;
01178 if(inChar == ioClosing) {
01179
01180 break;
01181 }
01182 if(inChar != ioSeparator) {
01183
01184 stream.clear(std::ios_base::failbit);
01185 }
01186 }
01187
01188
01189 if(foundIntro) {
01190 stream.expect(ioOutro());
01191 }
01192
01193
01194 this->reinit(inputBuffer.size());
01195 std::copy(inputBuffer.begin(), inputBuffer.end(), this->begin());
01196
01197 } catch(std::ios_base::failure) {
01198
01199 }
01200 inputStream.exceptions(oldExceptionState);
01201 return inputStream;
01202 }
01203
01204
01205 template <class Type>
01206 void Array1D<Type>::
01207 reinit(size_t size)
01208 {
01209 this->deAllocate();
01210 this->m_size = size;
01211 this->allocate();
01212 }
01213
01214
01215 template <class Type>
01216 Array1D<Type>& Array1D<Type>::
01217 operator=(const Array1D<Type>& source)
01218 {
01219
01220 if(&source != this) {
01221 this->deAllocate();
01222 m_size = source.m_size;
01223 m_dataPtr = source.m_dataPtr;
01224 m_refCountPtr = source.m_refCountPtr;
01225 m_isAllocated = source.m_isAllocated;
01226
01227 if(m_isAllocated) {
01228 ++(*m_refCountPtr);
01229 }
01230 }
01231 return *this;
01232 }
01233
01234
01235 template <class Type> template <class Type2>
01236 Array1D<Type>&
01237 Array1D<Type>::
01238 operator+=(const Array1D<Type2>& arg)
01239 {
01240 if(m_size != arg.size()) {
01241 std::ostringstream message;
01242 message << "Mismatched array sizes. Argument array has "
01243 << arg.size() << " elements, while destination array has "
01244 << m_size << " elements.";
01245 DLR_THROW3(ValueException, "Array1D::operator+=(const Array1D&)",
01246 message.str().c_str());
01247 }
01248 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01249 std::plus<Type>());
01250 return *this;
01251 }
01252
01253
01254 template <class Type>
01255 Array1D<Type>&
01256 Array1D<Type>::
01257 operator+=(const Type arg)
01258 {
01259 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01260 std::bind2nd(std::plus<Type>(), arg));
01261 return *this;
01262 }
01263
01264
01265 template <class Type> template <class Type2>
01266 Array1D<Type>&
01267 Array1D<Type>::
01268 operator-=(const Array1D<Type2>& arg)
01269 {
01270 if(m_size != arg.size()) {
01271 std::ostringstream message;
01272 message << "Mismatched array sizes. Argument array has "
01273 << arg.size() << " elements, while destination array has "
01274 << m_size << " elements.";
01275 DLR_THROW3(ValueException, "Array1D::operator-=(const Array1D&)",
01276 message.str().c_str());
01277 }
01278 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01279 std::minus<Type>());
01280 return *this;
01281 }
01282
01283
01284 template <class Type>
01285 Array1D<Type>&
01286 Array1D<Type>::
01287 operator-=(const Type arg)
01288 {
01289 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01290 std::bind2nd(std::minus<Type>(), arg));
01291 return *this;
01292 }
01293
01294
01295 template <class Type> template <class Type2>
01296 Array1D<Type>&
01297 Array1D<Type>::
01298 operator*=(const Array1D<Type2>& arg)
01299 {
01300 if(m_size != arg.size()) {
01301 std::ostringstream message;
01302 message << "Mismatched array sizes. Argument array has "
01303 << arg.size() << " elements, while destination array has "
01304 << m_size << " elements.";
01305 DLR_THROW3(ValueException, "Array1D::operator*=(const Array1D&)",
01306 message.str().c_str());
01307 }
01308 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01309 std::multiplies<Type>());
01310 return *this;
01311 }
01312
01313
01314 template <class Type>
01315 Array1D<Type>&
01316 Array1D<Type>::
01317 operator*=(const Type arg)
01318 {
01319 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01320 std::bind2nd(std::multiplies<Type>(), arg));
01321 return *this;
01322 }
01323
01324
01325 template <class Type> template <class Type2>
01326 Array1D<Type>&
01327 Array1D<Type>::
01328 operator/=(const Array1D<Type2>& arg)
01329 {
01330 if(m_size != arg.size()) {
01331 std::ostringstream message;
01332 message << "Mismatched array sizes. Argument array has "
01333 << arg.size() << " elements, while destination array has "
01334 << m_size << " elements.";
01335 DLR_THROW3(ValueException, "Array1D::operator/=(const Array1D&)",
01336 message.str().c_str());
01337 }
01338 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01339 std::divides<Type>());
01340 return *this;
01341 }
01342
01343
01344 template <class Type>
01345 Array1D<Type>&
01346 Array1D<Type>::
01347 operator/=(const Type arg)
01348 {
01349 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01350 std::bind2nd(std::divides<Type>(), arg));
01351 return *this;
01352 }
01353
01354
01355 template <class Type>
01356 void Array1D<Type>::
01357 allocate()
01358 {
01359
01360
01361 if(m_size > 0) {
01362
01363
01364 m_dataPtr = new(Type[m_size]);
01365 m_refCountPtr = new size_t;
01366
01367
01368 *m_refCountPtr = 1;
01369 m_isAllocated = true;
01370 } else {
01371
01372 m_dataPtr = 0;
01373 m_refCountPtr = 0;
01374 m_isAllocated = false;
01375 }
01376 return;
01377 }
01378
01379
01380 template <class Type>
01381 inline void Array1D<Type>::
01382 checkBounds(size_t index) const
01383 {
01384 #ifdef _DLRNUMERIC_CHECKBOUNDS_
01385 if(index < 0 || index >= m_size) {
01386 std::ostringstream message;
01387 message << "Index " << index << " is invalid for a(n) " << m_size
01388 << " element array.";
01389 DLR_THROW(IndexException, "Array1D::checkBounds()",
01390 message.str().c_str());
01391 }
01392 #endif
01393 }
01394
01395
01396 template <class Type>
01397 void Array1D<Type>::
01398 deAllocate()
01399 {
01400
01401 if(m_isAllocated == true) {
01402
01403 if(--(*m_refCountPtr) == 0) {
01404
01405
01406 delete[] m_dataPtr;
01407 delete m_refCountPtr;
01408 m_isAllocated = false;
01409 }
01410 }
01411
01412 m_dataPtr = 0;
01413 m_refCountPtr = 0;
01414 }
01415
01416
01417
01418 template <class Type>
01419 Array1D<Type> operator+(const Array1D<Type>& array0,
01420 const Array1D<Type>& array1)
01421 {
01422 if(array0.size() != array1.size()) {
01423 std::ostringstream message;
01424 message << "Array sizes do not match. Array0 has " << array0.size()
01425 << " elements, while array1 has " << array1.size()
01426 << " elements.";
01427 DLR_THROW(ValueException, "Array1D::operator+()", message.str().c_str());
01428 }
01429 Array1D<Type> result(array0.size());
01430 std::transform(array0.begin(), array0.end(), array1.begin(),
01431 result.begin(), std::plus<Type>());
01432 return result;
01433 }
01434
01435
01436 template <class Type>
01437 Array1D<Type> operator-(const Array1D<Type>& array0,
01438 const Array1D<Type>& array1)
01439 {
01440 if(array0.size() != array1.size()) {
01441 std::ostringstream message;
01442 message << "Array sizes do not match. Array0 has " << array0.size()
01443 << " elements, while array1 has " << array1.size()
01444 << " elements.";
01445 DLR_THROW(ValueException, "Array1D::operator-()", message.str().c_str());
01446 }
01447 Array1D<Type> result(array0.size());
01448 std::transform(array0.begin(), array0.end(), array1.begin(),
01449 result.begin(), std::minus<Type>());
01450 return result;
01451 }
01452
01453
01454 template <class Type>
01455 Array1D<Type> operator*(const Array1D<Type>& array0,
01456 const Array1D<Type>& array1)
01457 {
01458 if(array0.size() != array1.size()) {
01459 std::ostringstream message;
01460 message << "Array sizes do not match. Array0 has " << array0.size()
01461 << " elements, while array1 has " << array1.size()
01462 << " elements.";
01463 DLR_THROW(ValueException, "Array1D::operator*()", message.str().c_str());
01464 }
01465 Array1D<Type> result(array0.size());
01466 std::transform(array0.begin(), array0.end(), array1.begin(),
01467 result.begin(), std::multiplies<Type>());
01468 return result;
01469 }
01470
01471
01472 template <class Type>
01473 Array1D<Type> operator/(const Array1D<Type>& array0,
01474 const Array1D<Type>& array1)
01475 {
01476 if(array0.size() != array1.size()) {
01477 std::ostringstream message;
01478 message << "Array sizes do not match. Array0 has " << array0.size()
01479 << " elements, while array1 has " << array1.size()
01480 << " elements.";
01481 DLR_THROW(ValueException, "Array1D::operator/()", message.str().c_str());
01482 }
01483 Array1D<Type> result(array0.size());
01484 std::transform(array0.begin(), array0.end(), array1.begin(),
01485 result.begin(), std::divides<Type>());
01486 return result;
01487 }
01488
01489
01490 template <class Type>
01491 Array1D<Type> operator+(const Array1D<Type>& array0, Type scalar)
01492 {
01493 Array1D<Type> result(array0.size());
01494 std::transform(array0.begin(), array0.end(), result.begin(),
01495 std::bind2nd(std::plus<Type>(), scalar));
01496 return result;
01497 }
01498
01499
01500 template <class Type>
01501 Array1D<Type> operator-(const Array1D<Type>& array0, Type scalar)
01502 {
01503 Array1D<Type> result(array0.size());
01504 std::transform(array0.begin(), array0.end(), result.begin(),
01505 std::bind2nd(std::minus<Type>(), scalar));
01506 return result;
01507 }
01508
01509
01510 template <class Type>
01511 Array1D<Type> operator*(const Array1D<Type>& array0, Type scalar)
01512 {
01513 Array1D<Type> result(array0.size());
01514 std::transform(array0.begin(), array0.end(), result.begin(),
01515 std::bind2nd(std::multiplies<Type>(), scalar));
01516 return result;
01517 }
01518
01519
01520 template <class Type>
01521 Array1D<Type> operator/(const Array1D<Type>& array0, Type scalar)
01522 {
01523 Array1D<Type> result(array0.size());
01524 std::transform(array0.begin(), array0.end(), result.begin(),
01525 std::bind2nd(std::divides<Type>(), scalar));
01526 return result;
01527 }
01528
01529
01530 template <class Type>
01531 inline Array1D<Type> operator+(Type scalar, const Array1D<Type>& array0)
01532 {
01533 return array0 + scalar;
01534 }
01535
01536
01537 template <class Type>
01538 Array1D<Type> operator-(Type scalar, const Array1D<Type>& array0)
01539 {
01540 Array1D<Type> result(array0.size());
01541 std::transform(array0.begin(), array0.end(), result.begin(),
01542 std::bind1st(std::minus<Type>(), scalar));
01543 return result;
01544 }
01545
01546
01547 template <class Type>
01548 inline Array1D<Type> operator*(Type scalar, const Array1D<Type>& array0)
01549 {
01550 return array0 * scalar;
01551 }
01552
01553
01554 template <class Type>
01555 Array1D<Type> operator/(Type scalar, const Array1D<Type>& array0)
01556 {
01557 Array1D<Type> result(array0.size());
01558 std::transform(array0.begin(), array0.end(), result.begin(),
01559 std::bind1st(std::divides<Type>(), scalar));
01560 return result;
01561 }
01562
01563
01564
01565 template <class Type>
01566 Array1D<bool>
01567 operator==(const Array1D<Type>& array0, const Type arg)
01568 {
01569 Array1D<bool> result(array0.size());
01570 std::transform(array0.begin(), array0.end(), result.data(),
01571 std::bind2nd(std::equal_to<Type>(), arg));
01572 return result;
01573 }
01574
01575
01576
01577 template <class Type>
01578 Array1D<bool>
01579 operator==(const Array1D<Type>& array0, const Array1D<Type>& array1)
01580 {
01581 array0.checkDimension(array1.size());
01582 Array1D<bool> result(array0.size());
01583 std::transform(array0.begin(), array0.end(), array1.begin(),
01584 result.begin(), std::equal_to<Type>());
01585 return result;
01586 }
01587
01588
01589 template <class Type>
01590 Array1D<bool>
01591 operator>(const Array1D<Type>& array0, const Type arg)
01592 {
01593 Array1D<bool> result(array0.size());
01594 std::transform(array0.begin(), array0.end(), result.begin(),
01595 std::bind2nd(std::greater<Type>(), arg));
01596 return result;
01597 }
01598
01599
01600 template <class Type>
01601 Array1D<bool>
01602 operator>=(const Array1D<Type>& array0, const Type arg)
01603 {
01604 Array1D<bool> result(array0.size());
01605 std::transform(array0.begin(), array0.end(), result.begin(),
01606 std::bind2nd(std::greater_equal<Type>(), arg));
01607 return result;
01608 }
01609
01610
01611 template <class Type>
01612 Array1D<bool>
01613 operator<(const Array1D<Type>& array0, const Type arg)
01614 {
01615 Array1D<bool> result(array0.size());
01616 std::transform(array0.begin(), array0.end(), result.begin(),
01617 std::bind2nd(std::less<Type>(), arg));
01618 return result;
01619 }
01620
01621
01622 template <class Type>
01623 Array1D<bool>
01624 operator<=(const Array1D<Type>& array0, const Type arg)
01625 {
01626 Array1D<bool> result(array0.size());
01627 std::transform(array0.begin(), array0.end(), result.begin(),
01628 std::bind2nd(std::less_equal<Type>(), arg));
01629 return result;
01630 }
01631
01632
01633 template <class Type>
01634 std::ostream& operator<<(std::ostream& stream, const Array1D<Type>& array0)
01635 {
01636
01637 typedef typename NumericTraits<Type>::TextOutputType OutputType;
01638
01639 if (!stream){
01640 DLR_THROW(IOException, "operator<<(std::ostream&, const Array1D&)",
01641 "Invalid stream\n");
01642 }
01643
01644 size_t index;
01645 stream << "Array1D([";
01646 if (array0.size() > 0){
01647 for(index = 0; index < array0.size() - 1; ++index) {
01648 stream << static_cast<OutputType>(array0(index)) << ", ";
01649 }
01650 stream << static_cast<OutputType>(array0(index));
01651 }
01652 stream << "])";
01653 return stream;
01654 }
01655
01656
01657 template <class Type>
01658 std::istream& operator>>(std::istream& inputStream, Array1D<Type>& array0)
01659 {
01660 return array0.readFromStream(inputStream);
01661 }
01662
01663 }
01664
01665 }
01666
01667 #endif // #ifdef _DLR_ARRAY1D_H_
01668