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