VectorT.tcc 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925
  1. #ifndef _EVECTOR_BASICVECTOR_TCC
  2. #define _EVECTOR_BASICVECTOR_TCC
  3. #include <string>
  4. #include <sstream>
  5. #include <stdexcept>
  6. #include "core/basics/Exception.h"
  7. #define _THROW_EVector(string) fthrow(Exception, string)
  8. #include "core/vector/ippwrapper.h"
  9. #include "core/vector/VectorT.h"
  10. #include "core/vector/MatrixT.h"
  11. #include <iostream>
  12. namespace NICE {
  13. template<typename ElementType>
  14. inline VectorT<ElementType>::VectorT() {
  15. setDataPointer(NULL, 0, false);
  16. }
  17. template<typename ElementType>
  18. inline VectorT<ElementType>::VectorT(const size_t size) {
  19. setDataPointer(new ElementType[size], size, false);
  20. }
  21. template<typename ElementType>
  22. inline VectorT<ElementType>::VectorT(const size_t size,
  23. const ElementType& element) {
  24. setDataPointer(new ElementType[size], size, false);
  25. ippsSet(element, getDataPointer(), size);
  26. }
  27. template<typename ElementType>
  28. inline VectorT<ElementType>::VectorT(const ElementType* _data,
  29. const size_t size) {
  30. setDataPointer(new ElementType[size], size, false);
  31. ippsCopy(_data, getDataPointer(), size);
  32. }
  33. template<typename ElementType>
  34. inline VectorT<ElementType>::VectorT(ElementType* _data, const size_t size,
  35. const VectorBase::Mode mode) {
  36. switch (mode) {
  37. case external:
  38. setDataPointer(_data, size, true);
  39. break;
  40. case copy:
  41. setDataPointer(new ElementType[size], size, false);
  42. ippsCopy(_data, getDataPointer(), size);
  43. break;
  44. default:
  45. setDataPointer(NULL, 0, false);
  46. _THROW_EVector("Unknown Mode-enum.");
  47. }
  48. }
  49. template<typename ElementType>
  50. VectorT<ElementType>::VectorT(const std::vector<ElementType>& v) {
  51. setDataPointer(new ElementType[v.size()], v.size(), false);
  52. ippsCopy(&(*v.begin()), getDataPointer(), v.size());
  53. }
  54. template <class ElementType>
  55. VectorT<ElementType>::VectorT(std::istream& input, const bool & AwAFormat) {
  56. if (AwAFormat) //count, how many elements the vector contains
  57. {
  58. dataSize = 0;
  59. while (true)
  60. {
  61. ElementType c;
  62. input >> c;
  63. if (input.eof()) {
  64. break;
  65. }
  66. dataSize++;
  67. }
  68. //reset our stream to the beginning of the file
  69. input.clear() ;
  70. input.seekg(0, std::ios::beg) ;
  71. }
  72. else
  73. input >> dataSize;
  74. setDataPointer(new ElementType[dataSize], dataSize, false);
  75. if (AwAFormat)
  76. {
  77. int i = -1;
  78. while (true)
  79. {
  80. if (input.eof()) {
  81. break;
  82. // FIXME check if end of stream or followed by whitespace
  83. }
  84. i++;
  85. //ElementType c;
  86. //input >> c;
  87. //data[i] = c;
  88. input >> getDataPointer()[i];
  89. }
  90. }
  91. else
  92. {
  93. char c;
  94. input >> c;
  95. if (c != '<') {
  96. input.putback ( c );
  97. }
  98. int i = -1;
  99. while (true) {
  100. ws(input);
  101. if (input.peek() == int('>')) {
  102. std::string s;
  103. input >> s;
  104. break;
  105. }
  106. ++i;
  107. if (i >= int(dataSize)) {
  108. _THROW_EVector("syntax error 2 reading VectorT");
  109. }
  110. input >> getDataPointer()[i];
  111. }
  112. }
  113. }
  114. template<typename ElementType>
  115. VectorT<ElementType>::VectorT(const VectorT<ElementType>& v) {
  116. setDataPointer(new ElementType[v.dataSize], v.dataSize, false);
  117. ippsCopy(v.getDataPointer(), getDataPointer(), dataSize);
  118. }
  119. #ifdef NICE_USELIB_LINAL
  120. template<typename ElementType>
  121. inline VectorT<ElementType>::VectorT(const LinAl::VectorC<ElementType>& v) {
  122. setDataPointer(new ElementType[v.size()], v.size(), false);
  123. for (unsigned int i = 0; i < size(); i++) {
  124. (*this)(i) = v(i);
  125. }
  126. }
  127. template<typename ElementType>
  128. inline VectorT<ElementType>&
  129. VectorT<ElementType>::operator=(const LinAl::VectorCC<ElementType>& v) {
  130. if (size() == 0 && !externalStorage && getDataPointer() == NULL) {
  131. setDataPointer(new ElementType[v.size()], v.size(), false);
  132. } else if (this->size() != (unsigned int) v.size()) {
  133. this->resize(v.size());
  134. }
  135. for (unsigned int i = 0; i < size(); i++) {
  136. (*this)[i] = v(i);
  137. }
  138. return *this;
  139. }
  140. #endif // NICE_USELIB_LINAL
  141. template<typename ElementType>
  142. inline VectorT<ElementType>::~VectorT() {
  143. if (!externalStorage && data != NULL) {
  144. delete[] data;
  145. setDataPointer(NULL, 0, false);
  146. }
  147. }
  148. template<typename ElementType>
  149. void VectorT<ElementType>::resize(size_t size) {
  150. if(dataSize==size)
  151. return;
  152. // resize(0) simply means we want to empty the vector
  153. if(size==0)
  154. {
  155. ElementType *tmp = getDataPointer();
  156. if ( tmp != NULL )
  157. delete [] tmp;
  158. setDataPointer(NULL,0, false);
  159. }
  160. if(externalStorage) {
  161. if(size<dataSize) {
  162. dataSize = size;
  163. return;
  164. }
  165. _THROW_EVector("Cannot resize VectorT (external storage used)");
  166. }
  167. if(getDataPointer() != NULL) {
  168. size_t oldSize = dataSize;
  169. ElementType *tmp=getDataPointer();
  170. setDataPointer(new ElementType[size], size, false);
  171. ippsCopy(tmp, getDataPointer(), std::min(size, oldSize));
  172. delete[] tmp;
  173. } else {
  174. setDataPointer(new ElementType[size], size, false);
  175. }
  176. }
  177. template<typename ElementType>
  178. void VectorT<ElementType>::append( const VectorT<ElementType> & v )
  179. {
  180. unsigned int oldsize = size();
  181. resize ( oldsize + v.size() );
  182. VectorT<ElementType> subvec = getRangeRef(oldsize, size()-1);
  183. subvec = v;
  184. }
  185. template<typename ElementType>
  186. void VectorT<ElementType>::append( const ElementType & v )
  187. {
  188. unsigned int oldsize = size();
  189. resize ( oldsize + 1 );
  190. (*this)[oldsize] = v;
  191. }
  192. template<typename ElementType>
  193. VectorT<ElementType> VectorT<ElementType>::getRange ( const ptrdiff_t i, const ptrdiff_t j ) const
  194. {
  195. const ElementType *subDataPtr = getDataPointer() + i;
  196. VectorT<ElementType> subvec ( subDataPtr, j-i+1 );
  197. return subvec;
  198. }
  199. template<typename ElementType>
  200. VectorT<ElementType> VectorT<ElementType>::getRangeRef ( const ptrdiff_t i, const ptrdiff_t j )
  201. {
  202. ElementType *subDataPtr = getDataPointer() + i;
  203. VectorT<ElementType> subvec ( subDataPtr, j-i+1,
  204. VectorBase::external );
  205. return subvec;
  206. }
  207. template<typename ElementType>
  208. void VectorT<ElementType>::clear(void) {
  209. if (externalStorage) {
  210. _THROW_EVector("Cannot clear VectorT (external storage used)");
  211. }
  212. if (data != NULL) {
  213. delete[] data;
  214. setDataPointer(NULL, 0, false);
  215. }
  216. }
  217. template<class ElementType>
  218. inline const VectorT<ElementType>*
  219. VectorT<ElementType>::createConst(const ElementType* _data,
  220. const size_t size) {
  221. VectorT<ElementType>* result = new VectorT<ElementType>;
  222. result->setConstDataPointer(_data, size);
  223. return result;
  224. }
  225. template<class ElementType>
  226. const ElementType& VectorT<ElementType>::operator()(const ptrdiff_t i) const
  227. {
  228. if((ptrdiff_t)dataSize<=i||i<0) {
  229. //std::__throw_out_of_range("VectorT () access out of range");
  230. throw std::out_of_range("VectorT () access out of range");
  231. }
  232. return constData[i];
  233. }
  234. template<class ElementType>
  235. ElementType& VectorT<ElementType>::operator()(const ptrdiff_t i) {
  236. if((ptrdiff_t)dataSize<=i||i<0) {
  237. //std::__throw_out_of_range("VectorT () access out of range");
  238. throw std::out_of_range("VectorT () access out of range");
  239. }
  240. return data[i];
  241. }
  242. template<class ElementType>
  243. inline bool
  244. VectorT<ElementType>::operator==(const VectorT<ElementType>& v) const {
  245. if (size() != v.size()) {
  246. throw std::invalid_argument("VectorT::operator==(): v.size() != size()");
  247. } else if (size() == 0) {
  248. return true;
  249. }
  250. for (unsigned int i = 0; i < size(); i++) {
  251. if(!(operator[](i) == v[i]))
  252. return false;
  253. }
  254. return true;
  255. }
  256. template<class ElementType>
  257. inline bool
  258. VectorT<ElementType>::operator!=(const VectorT<ElementType>& v) const {
  259. if (size() != v.size()) {
  260. throw std::invalid_argument("VectorT::operator!=(): v.size() != size()");
  261. } else if (size() == 0) {
  262. return false;
  263. }
  264. for (unsigned int i = 0; i < size(); i++) {
  265. if(!(operator[](i) == v[i]))
  266. return true;
  267. }
  268. return false;
  269. }
  270. template<typename ElementType>
  271. void VectorT<ElementType>::multiply(const MatrixT<ElementType>& a, const VectorT<ElementType>& v, bool atranspose)
  272. {
  273. size_t arows, acols;
  274. if(atranspose) {
  275. arows=a.cols();
  276. acols=a.rows();
  277. } else {
  278. arows=a.rows();
  279. acols=a.cols();
  280. }
  281. if (size() == 0)
  282. resize(arows);
  283. if (arows != size() || acols != v.size())
  284. _THROW_EVector("Matrix multiplication: inconsistent sizes.");
  285. #ifdef NICE_USELIB_IPP
  286. size_t tsize=sizeof(ElementType);
  287. IppStatus ret;
  288. if(atranspose)
  289. {
  290. ret = ippmMul_mv(a.getDataPointer(), a.rows()*tsize, tsize, a.rows(), a.cols(),
  291. v.getDataPointer(), tsize, v.size(),
  292. this->getDataPointer(), tsize);
  293. }
  294. else
  295. {
  296. ret = ippmMul_tv(a.getDataPointer(), a.rows()*tsize, tsize, a.rows(), a.cols(),
  297. v.getDataPointer(), tsize, v.size(),
  298. this->getDataPointer(), tsize);
  299. }
  300. if(ret!=ippStsNoErr)
  301. _THROW_EVector(ippGetStatusString(ret));
  302. #else
  303. #pragma omp parallel for
  304. // FIXME not very efficient
  305. for (int i = 0; i < int(arows); i++)
  306. {
  307. ElementType sum = ElementType(0);
  308. for (unsigned int k = 0; k < acols; k++)
  309. {
  310. ElementType ela = atranspose ? a(k, i) : a(i, k);
  311. sum += ela * v(k);
  312. }
  313. (*this)(i) = sum;
  314. }
  315. #endif
  316. }
  317. template<typename ElementType>
  318. void VectorT<ElementType>::multiply(const VectorT<ElementType>& v, const RowMatrixT<ElementType>& a, bool atranspose)
  319. {
  320. size_t arows, acols;
  321. if(atranspose) {
  322. arows=a.cols();
  323. acols=a.rows();
  324. } else {
  325. arows=a.rows();
  326. acols=a.cols();
  327. }
  328. if (size() == 0)
  329. resize(acols);
  330. if (acols != size() || arows != v.size())
  331. _THROW_EVector("Matrix multiplication: inconsistent sizes.");
  332. #ifdef NICE_USELIB_IPP
  333. size_t tsize=sizeof(ElementType);
  334. IppStatus ret;
  335. if(atranspose)
  336. {
  337. ret = ippmMul_mv(a.getDataPointer(), a.cols()*tsize, tsize, a.cols(), a.rows(),
  338. v.getDataPointer(), tsize, v.size(),
  339. this->getDataPointer(), tsize);
  340. }
  341. else
  342. {
  343. ret = ippmMul_tv(a.getDataPointer(), a.cols()*tsize, tsize, a.cols(), a.rows(),
  344. v.getDataPointer(), tsize, v.size(),
  345. this->getDataPointer(), tsize);
  346. }
  347. if(ret!=ippStsNoErr)
  348. _THROW_EVector(ippGetStatusString(ret));
  349. #else
  350. #pragma omp parallel for
  351. // FIXME not very efficient
  352. for (int i = 0; i < int(acols); i++)
  353. {
  354. ElementType sum = ElementType(0);
  355. for (unsigned int k = 0; k < arows; k++)
  356. {
  357. ElementType ela = atranspose ? a(i, k) : a(k, i);
  358. sum += v(k) * ela;
  359. }
  360. (*this)(i) = sum;
  361. }
  362. #endif
  363. }
  364. template<typename ElementType>
  365. void VectorT<ElementType>::multiply(const RowMatrixT<ElementType>& a, const VectorT<ElementType>& v, bool atranspose)
  366. {
  367. size_t arows, acols;
  368. if(atranspose) {
  369. arows=a.cols();
  370. acols=a.rows();
  371. } else {
  372. arows=a.rows();
  373. acols=a.cols();
  374. }
  375. if (size() == 0)
  376. resize(arows);
  377. if (arows != size() || acols != v.size())
  378. _THROW_EVector("Matrix multiplication: inconsistent sizes.");
  379. #ifdef NICE_USELIB_IPP
  380. size_t tsize=sizeof(ElementType);
  381. IppStatus ret;
  382. if(atranspose) {
  383. ret = ippmMul_tv(a.getDataPointer(), a.cols()*tsize, tsize, a.cols(), a.rows(),
  384. v.getDataPointer(), tsize, v.size(),
  385. this->getDataPointer(), tsize);
  386. } else {
  387. ret = ippmMul_mv(a.getDataPointer(), a.cols()*tsize, tsize, a.cols(), a.rows(),
  388. v.getDataPointer(), tsize, v.size(),
  389. this->getDataPointer(), tsize);
  390. }
  391. if(ret!=ippStsNoErr)
  392. _THROW_EVector(ippGetStatusString(ret));
  393. #else
  394. // FIXME not very efficient
  395. ElementType ela;
  396. for (unsigned int i = 0; i < arows; i++)
  397. {
  398. ElementType sum = ElementType(0);
  399. for (unsigned int k = 0; k < acols; k++)
  400. {
  401. ela = atranspose ? a(k, i) : a(i, k);
  402. sum += ela * v(k);
  403. }
  404. (*this)(i) = sum;
  405. }
  406. #endif
  407. }
  408. template<typename ElementType>
  409. void VectorT<ElementType>::multiply(const VectorT<ElementType>& v, const MatrixT<ElementType>& a, bool atranspose)
  410. {
  411. size_t arows, acols;
  412. if(atranspose) {
  413. arows=a.cols();
  414. acols=a.rows();
  415. } else {
  416. arows=a.rows();
  417. acols=a.cols();
  418. }
  419. if (size() == 0)
  420. resize(acols);
  421. if (acols != size() || arows != v.size())
  422. _THROW_EVector("Matrix multiplication: inconsistent sizes.");
  423. #ifdef NICE_USELIB_IPP
  424. size_t tsize=sizeof(ElementType);
  425. IppStatus ret;
  426. if(atranspose) {
  427. ret = ippmMul_tv(a.getDataPointer(), a.rows()*tsize, tsize, a.rows(), a.cols(),
  428. v.getDataPointer(), tsize, v.size(),
  429. this->getDataPointer(), tsize);
  430. } else {
  431. ret = ippmMul_mv(a.getDataPointer(), a.rows()*tsize, tsize, a.rows(), a.cols(),
  432. v.getDataPointer(), tsize, v.size(),
  433. this->getDataPointer(), tsize);
  434. }
  435. if(ret!=ippStsNoErr)
  436. _THROW_EVector(ippGetStatusString(ret));
  437. #else
  438. // FIXME not very efficient
  439. ElementType ela;
  440. for (unsigned int i = 0; i < acols; i++)
  441. {
  442. ElementType sum = ElementType(0);
  443. for (unsigned int k = 0; k < arows; k++)
  444. {
  445. ela = atranspose ? a(i, k) : a(k, i);
  446. sum += v(k) * ela;
  447. }
  448. (*this)(i) = sum;
  449. }
  450. #endif
  451. }
  452. template<class ElementType>
  453. inline ElementType
  454. VectorT<ElementType>::scalarProduct(
  455. const VectorT<ElementType>& v) const {
  456. if (size() != v.size()) {
  457. throw std::invalid_argument("VectorT::scalarProduct(): v.size() != size()");
  458. } else if (size() == 0) {
  459. throw std::invalid_argument("VectorT::scalarProduct(): size() == 0");
  460. }
  461. ElementType result;
  462. IppStatus ret = ippsDotProd(getDataPointer(),v.getDataPointer(),dataSize,&result);
  463. if(ret!=ippStsNoErr)
  464. _THROW_EVector(ippGetStatusString(ret));
  465. return result;
  466. }
  467. template<class ElementType>
  468. inline ElementType VectorT<ElementType>::Median() const {
  469. VectorT<ElementType> sorted(*this);
  470. sorted.sortAscend();
  471. return sorted[dataSize/2];
  472. }
  473. #define _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(_IppName,_Name) \
  474. template<class ElementType> \
  475. inline ElementType \
  476. VectorT<ElementType>::_Name() const { \
  477. ElementType result=0; \
  478. IppStatus ret = ipps##_IppName(getDataPointer(), dataSize, &result); \
  479. if(ret!=ippStsNoErr) \
  480. _THROW_EVector(ippGetStatusString(ret)); \
  481. return result; \
  482. }
  483. #ifndef DISABLE_IPP_MAXMIN
  484. // in the current version of valgrind, valgrind
  485. // does not recognize some cpu operations used
  486. // in the IPP routines of ippMax and ippMin
  487. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Max,Max)
  488. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Min,Min)
  489. #else
  490. template<class ElementType>
  491. inline ElementType
  492. VectorT<ElementType>::Max() const
  493. {
  494. ElementType maximum = - std::numeric_limits<ElementType>::max();
  495. for ( uint i = 0 ; i < size() ; i++ )
  496. if ( (*this)(i) > maximum )
  497. maximum = (*this)(i);
  498. return maximum;
  499. }
  500. template<class ElementType>
  501. inline ElementType
  502. VectorT<ElementType>::Min() const
  503. {
  504. ElementType minimum = std::numeric_limits<ElementType>::max();
  505. for ( uint i = 0 ; i < size() ; i++ )
  506. if ( (*this)(i) < minimum )
  507. minimum = (*this)(i);
  508. return minimum;
  509. }
  510. #endif
  511. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Sum,Sum)
  512. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Mean,Mean)
  513. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(StdDev,StdDev)
  514. #ifdef NICE_USELIB_IPP
  515. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Norm_Inf,normInf)
  516. #else
  517. // The previous standard implementation didn't work for negative values!
  518. template<class ElementType>
  519. inline ElementType
  520. VectorT<ElementType>::normInf() const
  521. {
  522. ElementType zero ( 0 );
  523. ElementType minusOne ( -1 );
  524. ElementType infNorm = zero;
  525. for ( uint i = 0 ; i < size() ; i++ )
  526. {
  527. if ( (*this)(i) < zero ) //negative entry
  528. {
  529. if ( ((*this)(i) * minusOne) > infNorm)
  530. infNorm = ((*this)(i) * minusOne);
  531. }
  532. else //positive entry
  533. {
  534. if ( (*this)(i) > infNorm)
  535. infNorm = (*this)(i) ;
  536. }
  537. }
  538. return infNorm;
  539. }
  540. #endif
  541. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Norm_L1,normL1)
  542. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Norm_L2,normL2)
  543. #define _DEFINE_EVECTOR_VOIDIPFUNC(_IppName,_Name) \
  544. template<class ElementType> \
  545. inline void VectorT<ElementType>::_Name() { \
  546. IppStatus ret = ipps##_IppName(getDataPointer(), dataSize); \
  547. if(ret!=ippStsNoErr) \
  548. _THROW_EVector(ippGetStatusString(ret)); \
  549. }
  550. _DEFINE_EVECTOR_VOIDIPFUNC(Abs_I,absInplace)
  551. #define _DEFINE_EVECTOR_VOIDEVECTORFUNC(_IppName,_Name) \
  552. template<class ElementType> \
  553. inline VectorT<ElementType> VectorT<ElementType>::_Name() const { \
  554. VectorT<ElementType> result(dataSize); \
  555. IppStatus ret = ipps##_IppName(getDataPointer(),result.getDataPointer(), dataSize); \
  556. if(ret!=ippStsNoErr) \
  557. _THROW_EVector(ippGetStatusString(ret)); \
  558. return result; \
  559. }
  560. _DEFINE_EVECTOR_VOIDEVECTORFUNC(Abs,abs)
  561. template<class ElementType>
  562. inline int
  563. VectorT<ElementType>::MaxIndex() const {
  564. int result;
  565. ElementType elem;
  566. IppStatus ret = ippsMaxIndx(getDataPointer(), dataSize, &elem, &result);
  567. if(ret!=ippStsNoErr)
  568. _THROW_EVector(ippGetStatusString(ret));
  569. return result;
  570. }
  571. template<class ElementType>
  572. inline int
  573. VectorT<ElementType>::MinIndex() const {
  574. int result;
  575. ElementType elem;
  576. IppStatus ret = ippsMinIndx(getDataPointer(), dataSize, &elem, &result);
  577. if(ret!=ippStsNoErr)
  578. _THROW_EVector(ippGetStatusString(ret));
  579. return result;
  580. }
  581. template<class ElementType>
  582. inline VectorT<ElementType> VectorT<ElementType>::UniformRandom(const size_t size, ElementType min,
  583. ElementType max, unsigned int seed)
  584. {
  585. VectorT result(size);
  586. IppStatus ret = ippsRandUniform_Direct(result.getDataPointer(),size,min,max,&seed);
  587. if(ret!=ippStsNoErr)
  588. _THROW_EVector(ippGetStatusString(ret));
  589. return result;
  590. }
  591. template<class ElementType>
  592. inline VectorT<ElementType> VectorT<ElementType>::UniformRandom(const size_t size, ElementType min,
  593. ElementType max)
  594. {
  595. VectorT result(size);
  596. for (uint i = 0 ; i < size ; i++ )
  597. result[i] = (ElementType) ( randDouble((double)(max-min)) + (double)min );
  598. return result;
  599. }
  600. template<class ElementType>
  601. inline VectorT<ElementType> VectorT<ElementType>::GaussRandom(const size_t size, ElementType mean,
  602. ElementType stdev, unsigned int seed)
  603. {
  604. VectorT result(size);
  605. #ifdef NICE_USELIB_IPP
  606. IppStatus ret = ippsRandGauss_Direct(result.getDataPointer(),size,mean,stdev,&seed);
  607. if(ret!=ippStsNoErr)
  608. _THROW_EVector(ippGetStatusString(ret));
  609. #else
  610. initRand ( true, seed );
  611. for ( int i = 0 ; i < size ; i++ )
  612. result[i] = randGaussDouble ( stdev ) + mean;
  613. #endif
  614. return result;
  615. }
  616. template<class ElementType>
  617. inline VectorT<ElementType> VectorT<ElementType>::GaussRandom(const size_t size, ElementType mean,
  618. ElementType stdev)
  619. {
  620. VectorT result(size);
  621. for ( uint i = 0 ; i < size ; i++ )
  622. result[i] = randGaussDouble ( stdev ) + mean;
  623. return result;
  624. }
  625. template<typename ElementType>
  626. inline VectorT<ElementType>&
  627. VectorT<ElementType>::operator=(const VectorT<ElementType>& v) {
  628. if (dataSize == 0 && !externalStorage && getDataPointer() == NULL) {
  629. setDataPointer(new ElementType[v.size()], v.size(), false);
  630. } else if (this->dataSize != v.size()) {
  631. this->resize(v.size());
  632. }
  633. ippsCopy(v.getDataPointer(), getDataPointer(), v.dataSize);
  634. return *this;
  635. }
  636. template<typename ElementType>
  637. inline VectorT<ElementType>&
  638. VectorT<ElementType>::operator=(const ElementType& element) {
  639. ippsSet(element, getDataPointer(), this->dataSize);
  640. return *this;
  641. }
  642. template<typename ElementType>
  643. void VectorT<ElementType>::flip() {
  644. ippsFlip_I(getDataPointer(), this->dataSize);
  645. }
  646. template<typename ElementType>
  647. void VectorT<ElementType>::sortAscend() {
  648. ippsSortAscend_I(getDataPointer(), this->dataSize);
  649. }
  650. template<typename ElementType>
  651. void VectorT<ElementType>::sortDescend() {
  652. ippsSortDescend_I(getDataPointer(), this->dataSize);
  653. }
  654. /**
  655. * @brief sort elements in an descending order. Permutation is only correct if all elements are different.
  656. */
  657. template<typename ElementType>
  658. void VectorT<ElementType>::sortDescend(VectorT<int> & permutation) {
  659. //copy elements to extract ordering information lateron
  660. VectorT<ElementType> tmp_cp(*this);
  661. // sort the elements
  662. ippsSortDescend_I(getDataPointer(), this->dataSize);
  663. //compute permutation
  664. permutation.resize(this->size());
  665. int idxSelf ( 0 );
  666. for (typename VectorT<ElementType>::const_iterator itSelf = (*this).begin();
  667. itSelf != (*this).end();
  668. itSelf++, idxSelf++)
  669. {
  670. int idxOrig ( 0 );
  671. for (typename VectorT<ElementType>::const_iterator itOrig = tmp_cp.begin();
  672. itOrig != tmp_cp.end();
  673. itOrig++, idxOrig++)
  674. {
  675. if ( *itOrig == *itSelf )
  676. {
  677. permutation[idxOrig] = idxSelf;
  678. break;
  679. }
  680. }
  681. }
  682. }
  683. template<typename ElementType>
  684. MatrixT<ElementType> VectorT<ElementType>::toCrossProductMatrix() const {
  685. MatrixT<ElementType> result(size(), size());
  686. result(0, 0) = 0.0;
  687. result(0, 1) = -(*this)[2];
  688. result(0, 2) = (*this)[1];
  689. result(1, 0) = (*this)[2];
  690. result(1, 1) = 0.0;
  691. result(1, 2) = -(*this)[0];
  692. result(2, 0) = -(*this)[1];
  693. result(2, 1) = (*this)[0];
  694. result(2, 2) = 0.0;
  695. return result;
  696. }
  697. #define _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(_Op, _Name) \
  698. template<class ElementType> \
  699. inline VectorT<ElementType> & \
  700. VectorT<ElementType>::operator _Op##= (const ElementType& v) { \
  701. ipps##_Name##C_I(v, getDataPointer(), this->dataSize); \
  702. return *this; \
  703. }
  704. _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(+, Add)
  705. _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(-, Sub)
  706. _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(*, Mul)
  707. _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(/, Div)
  708. #define _DEFINE_EVECTOR_ASSIGNMENT(_Op, _Name) \
  709. template<class ElementType> \
  710. inline VectorT<ElementType> & \
  711. VectorT<ElementType>::operator _Op##= (const VectorT<ElementType>& v) { \
  712. if(this->dataSize!=v.size()) \
  713. _THROW_EVector("VectorT: different data size"); \
  714. ipps##_Name##_I(v.getDataPointer(), getDataPointer(), this->dataSize); \
  715. return *this; \
  716. }
  717. _DEFINE_EVECTOR_ASSIGNMENT(+, Add)
  718. _DEFINE_EVECTOR_ASSIGNMENT(-, Sub)
  719. _DEFINE_EVECTOR_ASSIGNMENT(*, Mul)
  720. _DEFINE_EVECTOR_ASSIGNMENT(/, Div)
  721. // shift operations
  722. template<typename ElementType>
  723. VectorT<ElementType> VectorT<ElementType>::LShiftCircular(const uint b) {
  724. VectorT<ElementType> result(size());
  725. Ipp32u bShift = b%size();
  726. #ifdef NICE_USELIB_IPP
  727. ippsCopy(getDataPointer()+bShift, result.getDataPointer() , size()-bShift);
  728. ippsCopy(getDataPointer() , result.getDataPointer()+size()-bShift, bShift );
  729. #else // NICE_USELIB_IPP
  730. memcpy(result.getDataPointer(), getDataPointer()+bShift, (size()-bShift)*sizeof(ElementType));
  731. memcpy(result.getDataPointer()+size()-bShift, getDataPointer(), bShift*sizeof(ElementType));
  732. #endif
  733. return result;
  734. }
  735. template<typename ElementType>
  736. void VectorT<ElementType>::LShiftCircularInplace(const uint b) {
  737. VectorT<ElementType> buffer = this->LShiftCircular(b);
  738. *this = buffer;
  739. }
  740. template<typename ElementType>
  741. VectorT<ElementType> VectorT<ElementType>::RShiftCircular(const uint b) {
  742. VectorT<ElementType> result(size());
  743. Ipp32u bShift = b%size();
  744. #ifdef NICE_USELIB_IPP
  745. ippsCopy(getDataPointer(), result.getDataPointer()+bShift, size()-bShift);
  746. ippsCopy(getDataPointer()+size()-bShift, result.getDataPointer(), bShift);
  747. #else // NICE_USELIB_IPP
  748. memcpy(result.getDataPointer()+bShift, getDataPointer(), (size()-bShift)*sizeof(ElementType));
  749. memcpy(result.getDataPointer(), getDataPointer()+size()-bShift, bShift*sizeof(ElementType));
  750. #endif
  751. return result;
  752. }
  753. template<typename ElementType>
  754. void VectorT<ElementType>::RShiftCircularInplace(const uint b) {
  755. VectorT<ElementType> buffer = this->RShiftCircular(b);
  756. *this = buffer;
  757. }
  758. template<typename ElementType>
  759. inline bool VectorT<ElementType>::isEqual(const VectorT<ElementType> &v, ElementType threshold) const
  760. {
  761. if( this->size() != v.size() )
  762. _THROW_EVector("VectorT: different data size");
  763. for (unsigned int j = 0; j < size(); j++) {
  764. if(fabs((*this)[j]-v[j])>threshold)
  765. return false;
  766. }
  767. return true;
  768. }
  769. template<typename ElementType>
  770. unsigned long VectorT<ElementType>::getHashValue() const
  771. {
  772. const char *buf = (const char*)getDataPointer();
  773. uint len = size() * sizeof(ElementType);
  774. // might overflow...but we do not care about it
  775. // According to http://www.ntecs.de/projects/guugelhupf/doc/html/x435.html
  776. // this is what STL is using
  777. unsigned long hash = 0;
  778. for ( int i = 0 ; i < len ; i++ )
  779. hash = 5*hash + buf[i];
  780. return hash;
  781. }
  782. template<typename ElementType>
  783. std::vector<ElementType> VectorT<ElementType>::std_vector () const
  784. {
  785. std::vector<ElementType> dst ( this->size() );
  786. for ( unsigned int i = 0 ; i < size(); i++ )
  787. dst[i] = (*this)[i];
  788. return dst;
  789. }
  790. } // namespace NICE
  791. #endif