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 arraySize);
00090
00102 explicit
00103 Array1D(const std::string& inputString);
00104
00111 Array1D(const Array1D<Type> &source);
00112
00123 Array1D(size_t arraySize, Type* const dataPtr);
00124
00142 Array1D(size_t arraySize, Type* const dataPtr,
00143 size_t* const referenceCountPtr);
00144
00149 ~Array1D();
00150
00156 iterator
00157 begin() {return m_dataPtr;}
00158
00165 const_iterator
00166 begin() const {return m_dataPtr;}
00167
00168
00175 inline void
00176 checkDimension(size_t arraySize) const;
00177
00178
00183 void
00184 clear() {this->reinit(0);}
00185
00191 Array1D<Type>
00192 copy() const;
00193
00204 template <class Type2> void
00205 copy(const Array1D<Type2>& source);
00206
00213 template <class Type2> void
00214 copy(const Type2* dataPtr);
00215
00223 Type*
00224 data() {return m_dataPtr;}
00225
00232 const Type*
00233 data() const {return m_dataPtr;}
00234
00245 Type*
00246 data(size_t index) {
00247 this->checkBounds(index);
00248 return m_dataPtr + index;
00249 }
00250
00260 const Type*
00261 data(size_t index) const {
00262 this->checkBounds(index);
00263 return m_dataPtr + index;
00264 }
00265
00266
00274 bool
00275 empty() const {return this->size() == 0;}
00276
00277
00284 iterator
00285 end() {return m_dataPtr + m_size;}
00286
00293 const_iterator
00294 end() const {return m_dataPtr + m_size;}
00295
00296
00306 inline Type
00307 getElement(size_t index0) const {return this->operator()(index0);}
00308
00309
00318 bool
00319 isAllocated() const {return m_isAllocated;}
00320
00327 size_t
00328 length() const {return this->size();}
00329
00342 std::istream&
00343 readFromStream(std::istream& inputStream);
00344
00352 size_t*
00353 refCountPtr() const {return m_refCountPtr;}
00354
00361 void
00362 reinit(size_t arraySize);
00363
00364
00378 Type&
00379 setElement(size_t index0, const Type& value) {
00380 return this->operator()(index0) = value;
00381 }
00382
00383
00390 size_t
00391 size() const {return m_size;}
00392
00401 Array1D<Type>&
00402 operator=(const Array1D<Type>& source);
00403
00411 Array1D<Type>&
00412 operator=(Type value);
00413
00421 Type&
00422 operator()(size_t index) {
00423 this->checkBounds(index);
00424 return m_dataPtr[index];
00425 }
00426
00434 Type operator()(size_t index) const {
00435 this->checkBounds(index);
00436 return m_dataPtr[index];
00437 }
00438
00447 Type& operator[](size_t index) {return this->operator()(index);}
00448
00457 Type operator[](size_t index) const {return this->operator()(index);}
00458
00470 template <class Type2>
00471 Array1D<Type>&
00472 operator+=(const Array1D<Type2>& arg);
00473
00481 Array1D<Type>&
00482 operator+=(const Type arg);
00483
00495 template <class Type2>
00496 Array1D<Type>&
00497 operator-=(const Array1D<Type2>& arg);
00498
00506 Array1D<Type>&
00507 operator-=(const Type arg);
00508
00520 template <class Type2>
00521 Array1D<Type>&
00522 operator*=(const Array1D<Type2>& arg);
00523
00531 Array1D<Type>&
00532 operator*=(const Type arg);
00533
00545 template <class Type2>
00546 Array1D<Type>&
00547 operator/=(const Array1D<Type2>& arg);
00548
00556 Array1D<Type>&
00557 operator/=(const Type arg);
00558
00559 private:
00560
00561
00565 void
00566 allocate();
00567
00574 inline void
00575 checkBounds(size_t index) const;
00576
00577
00583 void
00584 deAllocate();
00585
00586
00587
00588
00589
00594 static const std::string& ioIntro();
00595
00600 static const std::string& ioOutro();
00601
00606 static const char ioOpening = '[';
00607
00612 static const char ioClosing = ']';
00613
00618 static const char ioSeparator = ',';
00619
00620
00621 size_t m_size;
00622 Type* m_dataPtr;
00623 size_t* m_refCountPtr;
00624 bool m_isAllocated;
00625
00626 };
00627
00628
00629
00643 template <class Type>
00644 Array1D<Type>
00645 operator+(const Array1D<Type>& array0, const Array1D<Type>& array1);
00646
00660 template <class Type>
00661 Array1D<Type>
00662 operator-(const Array1D<Type>& array0, const Array1D<Type>& array1);
00663
00677 template <class Type>
00678 Array1D<Type>
00679 operator*(const Array1D<Type>& array0, const Array1D<Type>& array1);
00680
00694 template <class Type>
00695 Array1D<Type>
00696 operator/(const Array1D<Type>& array0, const Array1D<Type>& array1);
00697
00709 template <class Type>
00710 Array1D<Type> operator+(const Array1D<Type>& array, Type scalar);
00711
00723 template <class Type>
00724 Array1D<Type> operator-(const Array1D<Type>& array0, Type scalar);
00725
00737 template <class Type>
00738 Array1D<Type> operator*(const Array1D<Type>& array0, Type scalar);
00739
00751 template <class Type>
00752 Array1D<Type> operator/(const Array1D<Type>& array0, Type scalar);
00753
00765 template <class Type>
00766 inline Array1D<Type> operator+(Type scalar, const Array1D<Type>& array0);
00767
00768
00780 template <class Type>
00781 inline Array1D<Type> operator-(Type scalar, const Array1D<Type>& array0);
00782
00794 template <class Type>
00795 inline Array1D<Type> operator*(Type scalar, const Array1D<Type>& array0);
00796
00808 template <class Type>
00809 inline Array1D<Type> operator/(Type scalar, const Array1D<Type>& array0);
00810
00811
00823 template <class Type>
00824 Array1D<bool>
00825 operator==(const Array1D<Type>& array0, const Type arg);
00826
00827
00840 template <class Type>
00841 Array1D<bool>
00842 operator==(const Array1D<Type>& array0, const Array1D<Type>& array1);
00843
00844
00855 template <class Type>
00856 Array1D<bool>
00857 operator>(const Array1D<Type>& array0, const Type arg);
00858
00859
00871 template <class Type>
00872 Array1D<bool>
00873 operator>=(const Array1D<Type>& array0, const Type arg);
00874
00875
00886 template <class Type>
00887 Array1D<bool>
00888 operator<(const Array1D<Type>& array0, const Type arg);
00889
00890
00902 template <class Type>
00903 Array1D<bool>
00904 operator<=(const Array1D<Type>& array0, const Type arg);
00905
00906
00926 template <class Type>
00927 std::ostream& operator<<(std::ostream& stream, const Array1D<Type>& array0);
00928
00940 template <class Type>
00941 std::istream&
00942 operator>>(std::istream& stream, Array1D<Type>& array0);
00943
00944 }
00945
00946 }
00947
00948
00949
00950
00951 namespace dlr {
00952
00953 using numeric::Array1D;
00954
00955 }
00956
00957
00958
00959
00960
00961
00962
00963 #include <algorithm>
00964 #include <sstream>
00965 #include <vector>
00966 #include <dlrCommon/inputStream.h>
00967 #include <dlrNumeric/numericTraits.h>
00968
00969 namespace dlr {
00970
00971 namespace numeric {
00972
00973
00974
00975 template <class Type>
00976 const std::string&
00977 Array1D<Type>::
00978 ioIntro()
00979 {
00980 static const std::string intro = "Array1D(";
00981 return intro;
00982 }
00983
00984
00985
00986
00987 template <class Type>
00988 const std::string&
00989 Array1D<Type>::
00990 ioOutro()
00991 {
00992 static const std::string outro = ")";
00993 return outro;
00994 }
00995
00996
00997
00998 template <class Type>
00999 Array1D<Type>::
01000 Array1D()
01001 : m_size(0),
01002 m_dataPtr(0),
01003 m_refCountPtr(0),
01004 m_isAllocated(false)
01005 {
01006
01007 }
01008
01009
01010 template <class Type>
01011 Array1D<Type>::
01012 Array1D(size_t arraySize)
01013 : m_size(arraySize),
01014 m_dataPtr(0),
01015 m_refCountPtr(0),
01016 m_isAllocated(false)
01017 {
01018 this->allocate();
01019 }
01020
01021
01022
01023 template <class Type>
01024 Array1D<Type>::
01025 Array1D(const std::string& inputString)
01026 : m_size(0),
01027 m_dataPtr(0),
01028 m_refCountPtr(0),
01029 m_isAllocated(false)
01030 {
01031
01032 std::istringstream inputStream(inputString);
01033
01034
01035 Array1D<Type> inputArray;
01036 inputStream >> inputArray;
01037 if(!inputStream) {
01038 std::ostringstream message;
01039 message << "Couldn't parse input string: \"" << inputString << "\".";
01040 DLR_THROW3(ValueException, "Array1D::Array1D(const std::string&)",
01041 message.str().c_str());
01042 }
01043
01044
01045 *this = inputArray;
01046 }
01047
01048
01049
01050
01051
01052 template <class Type>
01053 Array1D<Type>::
01054 Array1D(const Array1D<Type>& source)
01055 : m_size(source.m_size),
01056 m_dataPtr(source.m_dataPtr),
01057 m_refCountPtr(source.m_refCountPtr),
01058 m_isAllocated(source.m_isAllocated)
01059 {
01060 if(m_isAllocated) {
01061 ++(*m_refCountPtr);
01062 }
01063 }
01064
01065
01066 template <class Type>
01067 Array1D<Type>::
01068 Array1D(size_t arraySize, Type* const dataPtr)
01069 : m_size(arraySize),
01070 m_dataPtr(dataPtr),
01071 m_refCountPtr(NULL),
01072 m_isAllocated(false)
01073 {
01074
01075 }
01076
01077
01078 template <class Type>
01079 Array1D<Type>::
01080 Array1D(size_t arraySize, Type* const dataPtr,
01081 size_t* const referenceCountPtr)
01082 : m_size(arraySize),
01083 m_dataPtr(dataPtr),
01084 m_refCountPtr(referenceCountPtr),
01085 m_isAllocated(true)
01086 {
01087 ++(*m_refCountPtr);
01088 }
01089
01090
01091 template <class Type>
01092 Array1D<Type>::~Array1D()
01093 {
01094 deAllocate();
01095 }
01096
01097
01098 template <class Type>
01099 inline void Array1D<Type>::
01100 checkDimension(size_t arraySize) const
01101 {
01102 #ifdef _DLRNUMERIC_CHECKBOUNDS_
01103 if(arraySize != this->size()) {
01104 std::ostringstream message;
01105 message << "Size mismatch: required size is " << arraySize
01106 << " while *this has dimension " << this->size() << ".";
01107 DLR_THROW(IndexException, "Array1D::checkDimension()",
01108 message.str().c_str());
01109 }
01110 #endif
01111 }
01112
01113
01114 template <class Type>
01115 Array1D<Type> Array1D<Type>::
01116 copy() const
01117 {
01118 Array1D<Type> newArray(m_size);
01119 newArray.copy(*this);
01120 return newArray;
01121 }
01122
01123
01124 template <class Type> template <class Type2>
01125 void Array1D<Type>::
01126 copy(const Array1D<Type2>& source)
01127 {
01128 if(source.size() != m_size) {
01129 std::ostringstream message;
01130 message << "Mismatched array sizes. Source array has "
01131 << source.size() << " elements, while destination array has "
01132 << m_size << " elements.";
01133 DLR_THROW3(ValueException, "Array1D::copy(const Array1D&)",
01134 message.str().c_str());
01135 }
01136 if(m_size != 0) {
01137 this->copy(source.data());
01138 }
01139 }
01140
01141
01142 template <class Type> template <class Type2>
01143 void
01144 Array1D<Type>::
01145 copy(const Type2* dataPtr)
01146 {
01147 std::copy(dataPtr, dataPtr + m_size, m_dataPtr);
01148 }
01149
01150
01151 template <class Type>
01152 Array1D<Type>& Array1D<Type>::
01153 operator=(Type val)
01154 {
01155 std::fill(m_dataPtr, m_dataPtr + m_size, val);
01156 return *this;
01157 }
01158
01159
01160
01161
01162 template <class Type>
01163 std::istream&
01164 Array1D<Type>::
01165 readFromStream(std::istream& inputStream)
01166 {
01167
01168 typedef typename NumericTraits<Type>::TextOutputType InputType;
01169
01170
01171 if (!inputStream){
01172 return inputStream;
01173 }
01174
01175
01176
01177
01178 std::ios_base::iostate oldExceptionState = inputStream.exceptions();
01179 inputStream.exceptions(
01180 std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
01181
01182
01183 try{
01184
01185
01186 InputStream stream(inputStream);
01187
01188 stream.skipWhiteSpace();
01189
01190
01191
01192 bool foundIntro = false;
01193 if(stream.peek() == ioIntro()[0]) {
01194 foundIntro = true;
01195 stream.expect(ioIntro());
01196 }
01197
01198
01199
01200
01201 stream.expect(ioOpening);
01202
01203
01204 InputType inputValue;
01205 std::vector<Type> inputBuffer;
01206 while(1) {
01207
01208 stream >> inputValue;
01209 inputBuffer.push_back(static_cast<Type>(inputValue));
01210
01211
01212 char inChar = 0;
01213 stream >> inChar;
01214 if(inChar == ioClosing) {
01215
01216 break;
01217 }
01218 if(inChar != ioSeparator) {
01219
01220 stream.clear(std::ios_base::failbit);
01221 }
01222 }
01223
01224
01225 if(foundIntro) {
01226 stream.expect(ioOutro());
01227 }
01228
01229
01230 this->reinit(inputBuffer.size());
01231 std::copy(inputBuffer.begin(), inputBuffer.end(), this->begin());
01232
01233 } catch(std::ios_base::failure) {
01234
01235 }
01236 inputStream.exceptions(oldExceptionState);
01237 return inputStream;
01238 }
01239
01240
01241 template <class Type>
01242 void Array1D<Type>::
01243 reinit(size_t arraySize)
01244 {
01245 this->deAllocate();
01246 this->m_size = arraySize;
01247 this->allocate();
01248 }
01249
01250
01251 template <class Type>
01252 Array1D<Type>& Array1D<Type>::
01253 operator=(const Array1D<Type>& source)
01254 {
01255
01256 if(&source != this) {
01257 this->deAllocate();
01258 m_size = source.m_size;
01259 m_dataPtr = source.m_dataPtr;
01260 m_refCountPtr = source.m_refCountPtr;
01261 m_isAllocated = source.m_isAllocated;
01262
01263 if(m_isAllocated) {
01264 ++(*m_refCountPtr);
01265 }
01266 }
01267 return *this;
01268 }
01269
01270
01271 template <class Type> template <class Type2>
01272 Array1D<Type>&
01273 Array1D<Type>::
01274 operator+=(const Array1D<Type2>& arg)
01275 {
01276 if(m_size != arg.size()) {
01277 std::ostringstream message;
01278 message << "Mismatched array sizes. Argument array has "
01279 << arg.size() << " elements, while destination array has "
01280 << m_size << " elements.";
01281 DLR_THROW3(ValueException, "Array1D::operator+=(const Array1D&)",
01282 message.str().c_str());
01283 }
01284 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01285 std::plus<Type>());
01286 return *this;
01287 }
01288
01289
01290 template <class Type>
01291 Array1D<Type>&
01292 Array1D<Type>::
01293 operator+=(const Type arg)
01294 {
01295 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01296 std::bind2nd(std::plus<Type>(), arg));
01297 return *this;
01298 }
01299
01300
01301 template <class Type> template <class Type2>
01302 Array1D<Type>&
01303 Array1D<Type>::
01304 operator-=(const Array1D<Type2>& arg)
01305 {
01306 if(m_size != arg.size()) {
01307 std::ostringstream message;
01308 message << "Mismatched array sizes. Argument array has "
01309 << arg.size() << " elements, while destination array has "
01310 << m_size << " elements.";
01311 DLR_THROW3(ValueException, "Array1D::operator-=(const Array1D&)",
01312 message.str().c_str());
01313 }
01314 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01315 std::minus<Type>());
01316 return *this;
01317 }
01318
01319
01320 template <class Type>
01321 Array1D<Type>&
01322 Array1D<Type>::
01323 operator-=(const Type arg)
01324 {
01325 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01326 std::bind2nd(std::minus<Type>(), arg));
01327 return *this;
01328 }
01329
01330
01331 template <class Type> template <class Type2>
01332 Array1D<Type>&
01333 Array1D<Type>::
01334 operator*=(const Array1D<Type2>& arg)
01335 {
01336 if(m_size != arg.size()) {
01337 std::ostringstream message;
01338 message << "Mismatched array sizes. Argument array has "
01339 << arg.size() << " elements, while destination array has "
01340 << m_size << " elements.";
01341 DLR_THROW3(ValueException, "Array1D::operator*=(const Array1D&)",
01342 message.str().c_str());
01343 }
01344 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01345 std::multiplies<Type>());
01346 return *this;
01347 }
01348
01349
01350 template <class Type>
01351 Array1D<Type>&
01352 Array1D<Type>::
01353 operator*=(const Type arg)
01354 {
01355 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01356 std::bind2nd(std::multiplies<Type>(), arg));
01357 return *this;
01358 }
01359
01360
01361 template <class Type> template <class Type2>
01362 Array1D<Type>&
01363 Array1D<Type>::
01364 operator/=(const Array1D<Type2>& arg)
01365 {
01366 if(m_size != arg.size()) {
01367 std::ostringstream message;
01368 message << "Mismatched array sizes. Argument array has "
01369 << arg.size() << " elements, while destination array has "
01370 << m_size << " elements.";
01371 DLR_THROW3(ValueException, "Array1D::operator/=(const Array1D&)",
01372 message.str().c_str());
01373 }
01374 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01375 std::divides<Type>());
01376 return *this;
01377 }
01378
01379
01380 template <class Type>
01381 Array1D<Type>&
01382 Array1D<Type>::
01383 operator/=(const Type arg)
01384 {
01385 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01386 std::bind2nd(std::divides<Type>(), arg));
01387 return *this;
01388 }
01389
01390
01391 template <class Type>
01392 void Array1D<Type>::
01393 allocate()
01394 {
01395
01396
01397 if(m_size > 0) {
01398
01399
01400 m_dataPtr = new(Type[m_size]);
01401 m_refCountPtr = new size_t;
01402
01403
01404 *m_refCountPtr = 1;
01405 m_isAllocated = true;
01406 } else {
01407
01408 m_dataPtr = 0;
01409 m_refCountPtr = 0;
01410 m_isAllocated = false;
01411 }
01412 return;
01413 }
01414
01415
01416 template <class Type>
01417 inline void Array1D<Type>::
01418 checkBounds(size_t index) const
01419 {
01420 #ifdef _DLRNUMERIC_CHECKBOUNDS_
01421 if(index >= m_size) {
01422 std::ostringstream message;
01423 message << "Index " << index << " is invalid for a(n) " << m_size
01424 << " element array.";
01425 DLR_THROW(IndexException, "Array1D::checkBounds()",
01426 message.str().c_str());
01427 }
01428 #endif
01429 }
01430
01431
01432 template <class Type>
01433 void Array1D<Type>::
01434 deAllocate()
01435 {
01436
01437 if(m_isAllocated == true) {
01438
01439 if(--(*m_refCountPtr) == 0) {
01440
01441
01442 delete[] m_dataPtr;
01443 delete m_refCountPtr;
01444 m_isAllocated = false;
01445 }
01446 }
01447
01448 m_dataPtr = 0;
01449 m_refCountPtr = 0;
01450 }
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::plus<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::minus<Type>());
01486 return result;
01487 }
01488
01489
01490 template <class Type>
01491 Array1D<Type> operator*(const Array1D<Type>& array0,
01492 const Array1D<Type>& array1)
01493 {
01494 if(array0.size() != array1.size()) {
01495 std::ostringstream message;
01496 message << "Array sizes do not match. Array0 has " << array0.size()
01497 << " elements, while array1 has " << array1.size()
01498 << " elements.";
01499 DLR_THROW(ValueException, "Array1D::operator*()", message.str().c_str());
01500 }
01501 Array1D<Type> result(array0.size());
01502 std::transform(array0.begin(), array0.end(), array1.begin(),
01503 result.begin(), std::multiplies<Type>());
01504 return result;
01505 }
01506
01507
01508 template <class Type>
01509 Array1D<Type> operator/(const Array1D<Type>& array0,
01510 const Array1D<Type>& array1)
01511 {
01512 if(array0.size() != array1.size()) {
01513 std::ostringstream message;
01514 message << "Array sizes do not match. Array0 has " << array0.size()
01515 << " elements, while array1 has " << array1.size()
01516 << " elements.";
01517 DLR_THROW(ValueException, "Array1D::operator/()", message.str().c_str());
01518 }
01519 Array1D<Type> result(array0.size());
01520 std::transform(array0.begin(), array0.end(), array1.begin(),
01521 result.begin(), std::divides<Type>());
01522 return result;
01523 }
01524
01525
01526 template <class Type>
01527 Array1D<Type> operator+(const Array1D<Type>& array0, Type scalar)
01528 {
01529 Array1D<Type> result(array0.size());
01530 std::transform(array0.begin(), array0.end(), result.begin(),
01531 std::bind2nd(std::plus<Type>(), scalar));
01532 return result;
01533 }
01534
01535
01536 template <class Type>
01537 Array1D<Type> operator-(const Array1D<Type>& array0, Type scalar)
01538 {
01539 Array1D<Type> result(array0.size());
01540 std::transform(array0.begin(), array0.end(), result.begin(),
01541 std::bind2nd(std::minus<Type>(), scalar));
01542 return result;
01543 }
01544
01545
01546 template <class Type>
01547 Array1D<Type> operator*(const Array1D<Type>& array0, Type scalar)
01548 {
01549 Array1D<Type> result(array0.size());
01550 std::transform(array0.begin(), array0.end(), result.begin(),
01551 std::bind2nd(std::multiplies<Type>(), scalar));
01552 return result;
01553 }
01554
01555
01556 template <class Type>
01557 Array1D<Type> operator/(const Array1D<Type>& array0, Type scalar)
01558 {
01559 Array1D<Type> result(array0.size());
01560 std::transform(array0.begin(), array0.end(), result.begin(),
01561 std::bind2nd(std::divides<Type>(), scalar));
01562 return result;
01563 }
01564
01565
01566 template <class Type>
01567 inline Array1D<Type> operator+(Type scalar, const Array1D<Type>& array0)
01568 {
01569 return array0 + scalar;
01570 }
01571
01572
01573 template <class Type>
01574 Array1D<Type> operator-(Type scalar, const Array1D<Type>& array0)
01575 {
01576 Array1D<Type> result(array0.size());
01577 std::transform(array0.begin(), array0.end(), result.begin(),
01578 std::bind1st(std::minus<Type>(), scalar));
01579 return result;
01580 }
01581
01582
01583 template <class Type>
01584 inline Array1D<Type> operator*(Type scalar, const Array1D<Type>& array0)
01585 {
01586 return array0 * scalar;
01587 }
01588
01589
01590 template <class Type>
01591 Array1D<Type> operator/(Type scalar, const Array1D<Type>& array0)
01592 {
01593 Array1D<Type> result(array0.size());
01594 std::transform(array0.begin(), array0.end(), result.begin(),
01595 std::bind1st(std::divides<Type>(), scalar));
01596 return result;
01597 }
01598
01599
01600
01601 template <class Type>
01602 Array1D<bool>
01603 operator==(const Array1D<Type>& array0, const Type arg)
01604 {
01605 Array1D<bool> result(array0.size());
01606 std::transform(array0.begin(), array0.end(), result.data(),
01607 std::bind2nd(std::equal_to<Type>(), arg));
01608 return result;
01609 }
01610
01611
01612
01613 template <class Type>
01614 Array1D<bool>
01615 operator==(const Array1D<Type>& array0, const Array1D<Type>& array1)
01616 {
01617 array0.checkDimension(array1.size());
01618 Array1D<bool> result(array0.size());
01619 std::transform(array0.begin(), array0.end(), array1.begin(),
01620 result.begin(), std::equal_to<Type>());
01621 return result;
01622 }
01623
01624
01625 template <class Type>
01626 Array1D<bool>
01627 operator>(const Array1D<Type>& array0, const Type arg)
01628 {
01629 Array1D<bool> result(array0.size());
01630 std::transform(array0.begin(), array0.end(), result.begin(),
01631 std::bind2nd(std::greater<Type>(), arg));
01632 return result;
01633 }
01634
01635
01636 template <class Type>
01637 Array1D<bool>
01638 operator>=(const Array1D<Type>& array0, const Type arg)
01639 {
01640 Array1D<bool> result(array0.size());
01641 std::transform(array0.begin(), array0.end(), result.begin(),
01642 std::bind2nd(std::greater_equal<Type>(), arg));
01643 return result;
01644 }
01645
01646
01647 template <class Type>
01648 Array1D<bool>
01649 operator<(const Array1D<Type>& array0, const Type arg)
01650 {
01651 Array1D<bool> result(array0.size());
01652 std::transform(array0.begin(), array0.end(), result.begin(),
01653 std::bind2nd(std::less<Type>(), arg));
01654 return result;
01655 }
01656
01657
01658 template <class Type>
01659 Array1D<bool>
01660 operator<=(const Array1D<Type>& array0, const Type arg)
01661 {
01662 Array1D<bool> result(array0.size());
01663 std::transform(array0.begin(), array0.end(), result.begin(),
01664 std::bind2nd(std::less_equal<Type>(), arg));
01665 return result;
01666 }
01667
01668
01669 template <class Type>
01670 std::ostream& operator<<(std::ostream& stream, const Array1D<Type>& array0)
01671 {
01672
01673 typedef typename NumericTraits<Type>::TextOutputType OutputType;
01674
01675 if (!stream){
01676 DLR_THROW(IOException, "operator<<(std::ostream&, const Array1D&)",
01677 "Invalid stream\n");
01678 }
01679
01680 size_t index;
01681 stream << "Array1D([";
01682 if (array0.size() > 0){
01683 for(index = 0; index < array0.size() - 1; ++index) {
01684 stream << static_cast<OutputType>(array0(index)) << ", ";
01685 }
01686 stream << static_cast<OutputType>(array0(index));
01687 }
01688 stream << "])";
01689 return stream;
01690 }
01691
01692
01693 template <class Type>
01694 std::istream& operator>>(std::istream& inputStream, Array1D<Type>& array0)
01695 {
01696 return array0.readFromStream(inputStream);
01697 }
01698
01699 }
01700
01701 }
01702
01703 #endif