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
00355
00362 void
00363 reinit(size_t arraySize);
00364
00365
00373 inline void
00374 reinitIfNecessary(size_t arraySize);
00375
00376
00390 Type&
00391 setElement(size_t index0, const Type& value) {
00392 return this->operator()(index0) = value;
00393 }
00394
00395
00402 size_t
00403 size() const {return m_size;}
00404
00413 Array1D<Type>&
00414 operator=(const Array1D<Type>& source);
00415
00423 Array1D<Type>&
00424 operator=(Type value);
00425
00433 Type&
00434 operator()(size_t index) {
00435 this->checkBounds(index);
00436 return m_dataPtr[index];
00437 }
00438
00446 Type operator()(size_t index) const {
00447 this->checkBounds(index);
00448 return m_dataPtr[index];
00449 }
00450
00459 Type& operator[](size_t index) {return this->operator()(index);}
00460
00469 Type operator[](size_t index) const {return this->operator()(index);}
00470
00482 template <class Type2>
00483 Array1D<Type>&
00484 operator+=(const Array1D<Type2>& arg);
00485
00493 Array1D<Type>&
00494 operator+=(const Type arg);
00495
00507 template <class Type2>
00508 Array1D<Type>&
00509 operator-=(const Array1D<Type2>& arg);
00510
00518 Array1D<Type>&
00519 operator-=(const Type arg);
00520
00532 template <class Type2>
00533 Array1D<Type>&
00534 operator*=(const Array1D<Type2>& arg);
00535
00543 Array1D<Type>&
00544 operator*=(const Type arg);
00545
00557 template <class Type2>
00558 Array1D<Type>&
00559 operator/=(const Array1D<Type2>& arg);
00560
00568 Array1D<Type>&
00569 operator/=(const Type arg);
00570
00571 private:
00572
00573
00577 void
00578 allocate();
00579
00586 inline void
00587 checkBounds(size_t index) const;
00588
00589
00595 void
00596 deAllocate();
00597
00598
00599
00600
00601
00606 static const std::string& ioIntro();
00607
00612 static const std::string& ioOutro();
00613
00618 static const char ioOpening = '[';
00619
00624 static const char ioClosing = ']';
00625
00630 static const char ioSeparator = ',';
00631
00632
00633 size_t m_size;
00634 Type* m_dataPtr;
00635 size_t* m_refCountPtr;
00636 bool m_isAllocated;
00637
00638 };
00639
00640
00641
00655 template <class Type>
00656 Array1D<Type>
00657 operator+(const Array1D<Type>& array0, const Array1D<Type>& array1);
00658
00672 template <class Type>
00673 Array1D<Type>
00674 operator-(const Array1D<Type>& array0, const Array1D<Type>& array1);
00675
00689 template <class Type>
00690 Array1D<Type>
00691 operator*(const Array1D<Type>& array0, const Array1D<Type>& array1);
00692
00706 template <class Type>
00707 Array1D<Type>
00708 operator/(const Array1D<Type>& array0, const Array1D<Type>& array1);
00709
00721 template <class Type>
00722 Array1D<Type> operator+(const Array1D<Type>& array, Type scalar);
00723
00735 template <class Type>
00736 Array1D<Type> operator-(const Array1D<Type>& array0, Type scalar);
00737
00749 template <class Type>
00750 Array1D<Type> operator*(const Array1D<Type>& array0, Type scalar);
00751
00763 template <class Type>
00764 Array1D<Type> operator/(const Array1D<Type>& array0, Type scalar);
00765
00777 template <class Type>
00778 inline Array1D<Type> operator+(Type scalar, const Array1D<Type>& array0);
00779
00780
00792 template <class Type>
00793 inline Array1D<Type> operator-(Type scalar, const Array1D<Type>& array0);
00794
00806 template <class Type>
00807 inline Array1D<Type> operator*(Type scalar, const Array1D<Type>& array0);
00808
00820 template <class Type>
00821 inline Array1D<Type> operator/(Type scalar, const Array1D<Type>& array0);
00822
00823
00835 template <class Type>
00836 Array1D<bool>
00837 operator==(const Array1D<Type>& array0, const Type arg);
00838
00839
00852 template <class Type>
00853 Array1D<bool>
00854 operator==(const Array1D<Type>& array0, const Array1D<Type>& array1);
00855
00856
00867 template <class Type>
00868 Array1D<bool>
00869 operator>(const Array1D<Type>& array0, const Type arg);
00870
00871
00883 template <class Type>
00884 Array1D<bool>
00885 operator>=(const Array1D<Type>& array0, const Type arg);
00886
00887
00898 template <class Type>
00899 Array1D<bool>
00900 operator<(const Array1D<Type>& array0, const Type arg);
00901
00902
00914 template <class Type>
00915 Array1D<bool>
00916 operator<=(const Array1D<Type>& array0, const Type arg);
00917
00918
00938 template <class Type>
00939 std::ostream& operator<<(std::ostream& stream, const Array1D<Type>& array0);
00940
00952 template <class Type>
00953 std::istream&
00954 operator>>(std::istream& stream, Array1D<Type>& array0);
00955
00956 }
00957
00958 }
00959
00960
00961
00962
00963 namespace dlr {
00964
00965 using numeric::Array1D;
00966
00967 }
00968
00969
00970
00971
00972
00973
00974
00975 #include <algorithm>
00976 #include <sstream>
00977 #include <vector>
00978 #include <dlrCommon/inputStream.h>
00979 #include <dlrNumeric/numericTraits.h>
00980
00981 namespace dlr {
00982
00983 namespace numeric {
00984
00985
00986
00987 template <class Type>
00988 const std::string&
00989 Array1D<Type>::
00990 ioIntro()
00991 {
00992 static const std::string intro = "Array1D(";
00993 return intro;
00994 }
00995
00996
00997
00998
00999 template <class Type>
01000 const std::string&
01001 Array1D<Type>::
01002 ioOutro()
01003 {
01004 static const std::string outro = ")";
01005 return outro;
01006 }
01007
01008
01009
01010 template <class Type>
01011 Array1D<Type>::
01012 Array1D()
01013 : m_size(0),
01014 m_dataPtr(0),
01015 m_refCountPtr(0),
01016 m_isAllocated(false)
01017 {
01018
01019 }
01020
01021
01022 template <class Type>
01023 Array1D<Type>::
01024 Array1D(size_t arraySize)
01025 : m_size(arraySize),
01026 m_dataPtr(0),
01027 m_refCountPtr(0),
01028 m_isAllocated(false)
01029 {
01030 this->allocate();
01031 }
01032
01033
01034
01035 template <class Type>
01036 Array1D<Type>::
01037 Array1D(const std::string& inputString)
01038 : m_size(0),
01039 m_dataPtr(0),
01040 m_refCountPtr(0),
01041 m_isAllocated(false)
01042 {
01043
01044 std::istringstream inputStream(inputString);
01045
01046
01047 Array1D<Type> inputArray;
01048 inputStream >> inputArray;
01049 if(!inputStream) {
01050 std::ostringstream message;
01051 message << "Couldn't parse input string: \"" << inputString << "\".";
01052 DLR_THROW3(ValueException, "Array1D::Array1D(const std::string&)",
01053 message.str().c_str());
01054 }
01055
01056
01057 *this = inputArray;
01058 }
01059
01060
01061
01062
01063
01064 template <class Type>
01065 Array1D<Type>::
01066 Array1D(const Array1D<Type>& source)
01067 : m_size(source.m_size),
01068 m_dataPtr(source.m_dataPtr),
01069 m_refCountPtr(source.m_refCountPtr),
01070 m_isAllocated(source.m_isAllocated)
01071 {
01072 if(m_isAllocated) {
01073 ++(*m_refCountPtr);
01074 }
01075 }
01076
01077
01078 template <class Type>
01079 Array1D<Type>::
01080 Array1D(size_t arraySize, Type* const dataPtr)
01081 : m_size(arraySize),
01082 m_dataPtr(dataPtr),
01083 m_refCountPtr(NULL),
01084 m_isAllocated(false)
01085 {
01086
01087 }
01088
01089
01090 template <class Type>
01091 Array1D<Type>::
01092 Array1D(size_t arraySize, Type* const dataPtr,
01093 size_t* const referenceCountPtr)
01094 : m_size(arraySize),
01095 m_dataPtr(dataPtr),
01096 m_refCountPtr(referenceCountPtr),
01097 m_isAllocated(true)
01098 {
01099 ++(*m_refCountPtr);
01100 }
01101
01102
01103 template <class Type>
01104 Array1D<Type>::~Array1D()
01105 {
01106 deAllocate();
01107 }
01108
01109
01110 template <class Type>
01111 inline void Array1D<Type>::
01112 checkDimension(size_t arraySize) const
01113 {
01114 #ifdef _DLRNUMERIC_CHECKBOUNDS_
01115 if(arraySize != this->size()) {
01116 std::ostringstream message;
01117 message << "Size mismatch: required size is " << arraySize
01118 << " while *this has dimension " << this->size() << ".";
01119 DLR_THROW(IndexException, "Array1D::checkDimension()",
01120 message.str().c_str());
01121 }
01122 #endif
01123 }
01124
01125
01126 template <class Type>
01127 Array1D<Type> Array1D<Type>::
01128 copy() const
01129 {
01130 Array1D<Type> newArray(m_size);
01131 newArray.copy(*this);
01132 return newArray;
01133 }
01134
01135
01136 template <class Type> template <class Type2>
01137 void Array1D<Type>::
01138 copy(const Array1D<Type2>& source)
01139 {
01140 if(source.size() != m_size) {
01141 std::ostringstream message;
01142 message << "Mismatched array sizes. Source array has "
01143 << source.size() << " elements, while destination array has "
01144 << m_size << " elements.";
01145 DLR_THROW3(ValueException, "Array1D::copy(const Array1D&)",
01146 message.str().c_str());
01147 }
01148 if(m_size != 0) {
01149 this->copy(source.data());
01150 }
01151 }
01152
01153
01154 template <class Type> template <class Type2>
01155 void
01156 Array1D<Type>::
01157 copy(const Type2* dataPtr)
01158 {
01159 std::copy(dataPtr, dataPtr + m_size, m_dataPtr);
01160 }
01161
01162
01163 template <class Type>
01164 Array1D<Type>& Array1D<Type>::
01165 operator=(Type val)
01166 {
01167 std::fill(m_dataPtr, m_dataPtr + m_size, val);
01168 return *this;
01169 }
01170
01171
01172
01173
01174 template <class Type>
01175 std::istream&
01176 Array1D<Type>::
01177 readFromStream(std::istream& inputStream)
01178 {
01179
01180 typedef typename NumericTraits<Type>::TextOutputType InputType;
01181
01182
01183 if (!inputStream){
01184 return inputStream;
01185 }
01186
01187
01188
01189
01190 std::ios_base::iostate oldExceptionState = inputStream.exceptions();
01191 inputStream.exceptions(
01192 std::ios_base::badbit | std::ios_base::failbit | std::ios_base::eofbit);
01193
01194
01195 try{
01196
01197
01198 InputStream stream(inputStream);
01199
01200 stream.skipWhiteSpace();
01201
01202
01203
01204 bool foundIntro = false;
01205 if(stream.peek() == ioIntro()[0]) {
01206 foundIntro = true;
01207 stream.expect(ioIntro());
01208 }
01209
01210
01211
01212
01213 stream.expect(ioOpening);
01214
01215
01216 InputType inputValue;
01217 std::vector<Type> inputBuffer;
01218 while(1) {
01219
01220 stream >> inputValue;
01221 inputBuffer.push_back(static_cast<Type>(inputValue));
01222
01223
01224 char inChar = 0;
01225 stream >> inChar;
01226 if(inChar == ioClosing) {
01227
01228 break;
01229 }
01230 if(inChar != ioSeparator) {
01231
01232 stream.clear(std::ios_base::failbit);
01233 }
01234 }
01235
01236
01237 if(foundIntro) {
01238 stream.expect(ioOutro());
01239 }
01240
01241
01242 this->reinit(inputBuffer.size());
01243 std::copy(inputBuffer.begin(), inputBuffer.end(), this->begin());
01244
01245 } catch(std::ios_base::failure) {
01246
01247 }
01248 inputStream.exceptions(oldExceptionState);
01249 return inputStream;
01250 }
01251
01252
01253 template <class Type>
01254 void Array1D<Type>::
01255 reinit(size_t arraySize)
01256 {
01257 this->deAllocate();
01258 this->m_size = arraySize;
01259 this->allocate();
01260 }
01261
01262
01263 template <class Type>
01264 void Array1D<Type>::
01265 reinitIfNecessary(size_t arraySize)
01266 {
01267 if(this->size() != arraySize) {
01268 this->reinit(arraySize);
01269 }
01270 }
01271
01272
01273 template <class Type>
01274 Array1D<Type>& Array1D<Type>::
01275 operator=(const Array1D<Type>& source)
01276 {
01277
01278 if(&source != this) {
01279 this->deAllocate();
01280 m_size = source.m_size;
01281 m_dataPtr = source.m_dataPtr;
01282 m_refCountPtr = source.m_refCountPtr;
01283 m_isAllocated = source.m_isAllocated;
01284
01285 if(m_isAllocated) {
01286 ++(*m_refCountPtr);
01287 }
01288 }
01289 return *this;
01290 }
01291
01292
01293 template <class Type> template <class Type2>
01294 Array1D<Type>&
01295 Array1D<Type>::
01296 operator+=(const Array1D<Type2>& arg)
01297 {
01298 if(m_size != arg.size()) {
01299 std::ostringstream message;
01300 message << "Mismatched array sizes. Argument array has "
01301 << arg.size() << " elements, while destination array has "
01302 << m_size << " elements.";
01303 DLR_THROW3(ValueException, "Array1D::operator+=(const Array1D&)",
01304 message.str().c_str());
01305 }
01306 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01307 std::plus<Type>());
01308 return *this;
01309 }
01310
01311
01312 template <class Type>
01313 Array1D<Type>&
01314 Array1D<Type>::
01315 operator+=(const Type arg)
01316 {
01317 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01318 std::bind2nd(std::plus<Type>(), arg));
01319 return *this;
01320 }
01321
01322
01323 template <class Type> template <class Type2>
01324 Array1D<Type>&
01325 Array1D<Type>::
01326 operator-=(const Array1D<Type2>& arg)
01327 {
01328 if(m_size != arg.size()) {
01329 std::ostringstream message;
01330 message << "Mismatched array sizes. Argument array has "
01331 << arg.size() << " elements, while destination array has "
01332 << m_size << " elements.";
01333 DLR_THROW3(ValueException, "Array1D::operator-=(const Array1D&)",
01334 message.str().c_str());
01335 }
01336 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01337 std::minus<Type>());
01338 return *this;
01339 }
01340
01341
01342 template <class Type>
01343 Array1D<Type>&
01344 Array1D<Type>::
01345 operator-=(const Type arg)
01346 {
01347 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01348 std::bind2nd(std::minus<Type>(), arg));
01349 return *this;
01350 }
01351
01352
01353 template <class Type> template <class Type2>
01354 Array1D<Type>&
01355 Array1D<Type>::
01356 operator*=(const Array1D<Type2>& arg)
01357 {
01358 if(m_size != arg.size()) {
01359 std::ostringstream message;
01360 message << "Mismatched array sizes. Argument array has "
01361 << arg.size() << " elements, while destination array has "
01362 << m_size << " elements.";
01363 DLR_THROW3(ValueException, "Array1D::operator*=(const Array1D&)",
01364 message.str().c_str());
01365 }
01366 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01367 std::multiplies<Type>());
01368 return *this;
01369 }
01370
01371
01372 template <class Type>
01373 Array1D<Type>&
01374 Array1D<Type>::
01375 operator*=(const Type arg)
01376 {
01377 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01378 std::bind2nd(std::multiplies<Type>(), arg));
01379 return *this;
01380 }
01381
01382
01383 template <class Type> template <class Type2>
01384 Array1D<Type>&
01385 Array1D<Type>::
01386 operator/=(const Array1D<Type2>& arg)
01387 {
01388 if(m_size != arg.size()) {
01389 std::ostringstream message;
01390 message << "Mismatched array sizes. Argument array has "
01391 << arg.size() << " elements, while destination array has "
01392 << m_size << " elements.";
01393 DLR_THROW3(ValueException, "Array1D::operator/=(const Array1D&)",
01394 message.str().c_str());
01395 }
01396 std::transform(m_dataPtr, m_dataPtr + m_size, arg.data(), m_dataPtr,
01397 std::divides<Type>());
01398 return *this;
01399 }
01400
01401
01402 template <class Type>
01403 Array1D<Type>&
01404 Array1D<Type>::
01405 operator/=(const Type arg)
01406 {
01407 std::transform(m_dataPtr, m_dataPtr + m_size, m_dataPtr,
01408 std::bind2nd(std::divides<Type>(), arg));
01409 return *this;
01410 }
01411
01412
01413 template <class Type>
01414 void Array1D<Type>::
01415 allocate()
01416 {
01417
01418
01419 if(m_size > 0) {
01420
01421
01422 m_dataPtr = new(Type[m_size]);
01423 m_refCountPtr = new size_t;
01424
01425
01426 *m_refCountPtr = 1;
01427 m_isAllocated = true;
01428 } else {
01429
01430 m_dataPtr = 0;
01431 m_refCountPtr = 0;
01432 m_isAllocated = false;
01433 }
01434 return;
01435 }
01436
01437
01438 template <class Type>
01439 inline void Array1D<Type>::
01440 checkBounds(size_t index) const
01441 {
01442 #ifdef _DLRNUMERIC_CHECKBOUNDS_
01443 if(index >= m_size) {
01444 std::ostringstream message;
01445 message << "Index " << index << " is invalid for a(n) " << m_size
01446 << " element array.";
01447 DLR_THROW(IndexException, "Array1D::checkBounds()",
01448 message.str().c_str());
01449 }
01450 #endif
01451 }
01452
01453
01454 template <class Type>
01455 void Array1D<Type>::
01456 deAllocate()
01457 {
01458
01459 if(m_isAllocated == true) {
01460
01461 if(--(*m_refCountPtr) == 0) {
01462
01463
01464 delete[] m_dataPtr;
01465 delete m_refCountPtr;
01466 m_isAllocated = false;
01467 }
01468 }
01469
01470 m_dataPtr = 0;
01471 m_refCountPtr = 0;
01472 }
01473
01474
01475
01476 template <class Type>
01477 Array1D<Type> operator+(const Array1D<Type>& array0,
01478 const Array1D<Type>& array1)
01479 {
01480 if(array0.size() != array1.size()) {
01481 std::ostringstream message;
01482 message << "Array sizes do not match. Array0 has " << array0.size()
01483 << " elements, while array1 has " << array1.size()
01484 << " elements.";
01485 DLR_THROW(ValueException, "Array1D::operator+()", message.str().c_str());
01486 }
01487 Array1D<Type> result(array0.size());
01488 std::transform(array0.begin(), array0.end(), array1.begin(),
01489 result.begin(), std::plus<Type>());
01490 return result;
01491 }
01492
01493
01494 template <class Type>
01495 Array1D<Type> operator-(const Array1D<Type>& array0,
01496 const Array1D<Type>& array1)
01497 {
01498 if(array0.size() != array1.size()) {
01499 std::ostringstream message;
01500 message << "Array sizes do not match. Array0 has " << array0.size()
01501 << " elements, while array1 has " << array1.size()
01502 << " elements.";
01503 DLR_THROW(ValueException, "Array1D::operator-()", message.str().c_str());
01504 }
01505 Array1D<Type> result(array0.size());
01506 std::transform(array0.begin(), array0.end(), array1.begin(),
01507 result.begin(), std::minus<Type>());
01508 return result;
01509 }
01510
01511
01512 template <class Type>
01513 Array1D<Type> operator*(const Array1D<Type>& array0,
01514 const Array1D<Type>& array1)
01515 {
01516 if(array0.size() != array1.size()) {
01517 std::ostringstream message;
01518 message << "Array sizes do not match. Array0 has " << array0.size()
01519 << " elements, while array1 has " << array1.size()
01520 << " elements.";
01521 DLR_THROW(ValueException, "Array1D::operator*()", message.str().c_str());
01522 }
01523 Array1D<Type> result(array0.size());
01524 std::transform(array0.begin(), array0.end(), array1.begin(),
01525 result.begin(), std::multiplies<Type>());
01526 return result;
01527 }
01528
01529
01530 template <class Type>
01531 Array1D<Type> operator/(const Array1D<Type>& array0,
01532 const Array1D<Type>& array1)
01533 {
01534 if(array0.size() != array1.size()) {
01535 std::ostringstream message;
01536 message << "Array sizes do not match. Array0 has " << array0.size()
01537 << " elements, while array1 has " << array1.size()
01538 << " elements.";
01539 DLR_THROW(ValueException, "Array1D::operator/()", message.str().c_str());
01540 }
01541 Array1D<Type> result(array0.size());
01542 std::transform(array0.begin(), array0.end(), array1.begin(),
01543 result.begin(), std::divides<Type>());
01544 return result;
01545 }
01546
01547
01548 template <class Type>
01549 Array1D<Type> operator+(const Array1D<Type>& array0, Type scalar)
01550 {
01551 Array1D<Type> result(array0.size());
01552 std::transform(array0.begin(), array0.end(), result.begin(),
01553 std::bind2nd(std::plus<Type>(), scalar));
01554 return result;
01555 }
01556
01557
01558 template <class Type>
01559 Array1D<Type> operator-(const Array1D<Type>& array0, Type scalar)
01560 {
01561 Array1D<Type> result(array0.size());
01562 std::transform(array0.begin(), array0.end(), result.begin(),
01563 std::bind2nd(std::minus<Type>(), scalar));
01564 return result;
01565 }
01566
01567
01568 template <class Type>
01569 Array1D<Type> operator*(const Array1D<Type>& array0, Type scalar)
01570 {
01571 Array1D<Type> result(array0.size());
01572 std::transform(array0.begin(), array0.end(), result.begin(),
01573 std::bind2nd(std::multiplies<Type>(), scalar));
01574 return result;
01575 }
01576
01577
01578 template <class Type>
01579 Array1D<Type> operator/(const Array1D<Type>& array0, Type scalar)
01580 {
01581 Array1D<Type> result(array0.size());
01582 std::transform(array0.begin(), array0.end(), result.begin(),
01583 std::bind2nd(std::divides<Type>(), scalar));
01584 return result;
01585 }
01586
01587
01588 template <class Type>
01589 inline Array1D<Type> operator+(Type scalar, const Array1D<Type>& array0)
01590 {
01591 return array0 + scalar;
01592 }
01593
01594
01595 template <class Type>
01596 Array1D<Type> operator-(Type scalar, const Array1D<Type>& array0)
01597 {
01598 Array1D<Type> result(array0.size());
01599 std::transform(array0.begin(), array0.end(), result.begin(),
01600 std::bind1st(std::minus<Type>(), scalar));
01601 return result;
01602 }
01603
01604
01605 template <class Type>
01606 inline Array1D<Type> operator*(Type scalar, const Array1D<Type>& array0)
01607 {
01608 return array0 * scalar;
01609 }
01610
01611
01612 template <class Type>
01613 Array1D<Type> operator/(Type scalar, const Array1D<Type>& array0)
01614 {
01615 Array1D<Type> result(array0.size());
01616 std::transform(array0.begin(), array0.end(), result.begin(),
01617 std::bind1st(std::divides<Type>(), scalar));
01618 return result;
01619 }
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.data(),
01629 std::bind2nd(std::equal_to<Type>(), arg));
01630 return result;
01631 }
01632
01633
01634
01635 template <class Type>
01636 Array1D<bool>
01637 operator==(const Array1D<Type>& array0, const Array1D<Type>& array1)
01638 {
01639 array0.checkDimension(array1.size());
01640 Array1D<bool> result(array0.size());
01641 std::transform(array0.begin(), array0.end(), array1.begin(),
01642 result.begin(), std::equal_to<Type>());
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::greater<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::greater_equal<Type>(), arg));
01665 return result;
01666 }
01667
01668
01669 template <class Type>
01670 Array1D<bool>
01671 operator<(const Array1D<Type>& array0, const Type arg)
01672 {
01673 Array1D<bool> result(array0.size());
01674 std::transform(array0.begin(), array0.end(), result.begin(),
01675 std::bind2nd(std::less<Type>(), arg));
01676 return result;
01677 }
01678
01679
01680 template <class Type>
01681 Array1D<bool>
01682 operator<=(const Array1D<Type>& array0, const Type arg)
01683 {
01684 Array1D<bool> result(array0.size());
01685 std::transform(array0.begin(), array0.end(), result.begin(),
01686 std::bind2nd(std::less_equal<Type>(), arg));
01687 return result;
01688 }
01689
01690
01691 template <class Type>
01692 std::ostream& operator<<(std::ostream& stream, const Array1D<Type>& array0)
01693 {
01694
01695 typedef typename NumericTraits<Type>::TextOutputType OutputType;
01696
01697 if (!stream){
01698 DLR_THROW(IOException, "operator<<(std::ostream&, const Array1D&)",
01699 "Invalid stream\n");
01700 }
01701
01702 size_t index;
01703 stream << "Array1D([";
01704 if (array0.size() > 0){
01705 for(index = 0; index < array0.size() - 1; ++index) {
01706 stream << static_cast<OutputType>(array0(index)) << ", ";
01707 }
01708 stream << static_cast<OutputType>(array0(index));
01709 }
01710 stream << "])";
01711 return stream;
01712 }
01713
01714
01715 template <class Type>
01716 std::istream& operator>>(std::istream& inputStream, Array1D<Type>& array0)
01717 {
01718 return array0.readFromStream(inputStream);
01719 }
01720
01721 }
01722
01723 }
01724
01725 #endif