VectorT.tcc 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  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. }
  231. return constData[i];
  232. }
  233. template<class ElementType>
  234. ElementType& VectorT<ElementType>::operator()(const ptrdiff_t i) {
  235. if((ptrdiff_t)dataSize<=i||i<0) {
  236. std::__throw_out_of_range("VectorT () access out of range");
  237. }
  238. return data[i];
  239. }
  240. template<class ElementType>
  241. inline bool
  242. VectorT<ElementType>::operator==(const VectorT<ElementType>& v) const {
  243. if (size() != v.size()) {
  244. throw std::invalid_argument("VectorT::operator==(): v.size() != size()");
  245. } else if (size() == 0) {
  246. return true;
  247. }
  248. for (unsigned int i = 0; i < size(); i++) {
  249. if(!(operator[](i) == v[i]))
  250. return false;
  251. }
  252. return true;
  253. }
  254. template<class ElementType>
  255. inline bool
  256. VectorT<ElementType>::operator!=(const VectorT<ElementType>& v) const {
  257. if (size() != v.size()) {
  258. throw std::invalid_argument("VectorT::operator!=(): v.size() != size()");
  259. } else if (size() == 0) {
  260. return false;
  261. }
  262. for (unsigned int i = 0; i < size(); i++) {
  263. if(!(operator[](i) == v[i]))
  264. return true;
  265. }
  266. return false;
  267. }
  268. template<typename ElementType>
  269. void VectorT<ElementType>::multiply(const MatrixT<ElementType>& a, const VectorT<ElementType>& v, bool atranspose)
  270. {
  271. size_t arows, acols;
  272. if(atranspose) {
  273. arows=a.cols();
  274. acols=a.rows();
  275. } else {
  276. arows=a.rows();
  277. acols=a.cols();
  278. }
  279. if (size() == 0)
  280. resize(arows);
  281. if (arows != size() || acols != v.size())
  282. _THROW_EVector("Matrix multiplication: inconsistent sizes.");
  283. #ifdef NICE_USELIB_IPP
  284. size_t tsize=sizeof(ElementType);
  285. IppStatus ret;
  286. if(atranspose)
  287. {
  288. ret = ippmMul_mv(a.getDataPointer(), a.rows()*tsize, tsize, a.rows(), a.cols(),
  289. v.getDataPointer(), tsize, v.size(),
  290. this->getDataPointer(), tsize);
  291. }
  292. else
  293. {
  294. ret = ippmMul_tv(a.getDataPointer(), a.rows()*tsize, tsize, a.rows(), a.cols(),
  295. v.getDataPointer(), tsize, v.size(),
  296. this->getDataPointer(), tsize);
  297. }
  298. if(ret!=ippStsNoErr)
  299. _THROW_EVector(ippGetStatusString(ret));
  300. #else
  301. #pragma omp parallel for
  302. // FIXME not very efficient
  303. for (int i = 0; i < int(arows); i++)
  304. {
  305. ElementType sum = ElementType(0);
  306. for (unsigned int k = 0; k < acols; k++)
  307. {
  308. ElementType ela = atranspose ? a(k, i) : a(i, k);
  309. sum += ela * v(k);
  310. }
  311. (*this)(i) = sum;
  312. }
  313. #endif
  314. }
  315. template<typename ElementType>
  316. void VectorT<ElementType>::multiply(const VectorT<ElementType>& v, const RowMatrixT<ElementType>& a, bool atranspose)
  317. {
  318. size_t arows, acols;
  319. if(atranspose) {
  320. arows=a.cols();
  321. acols=a.rows();
  322. } else {
  323. arows=a.rows();
  324. acols=a.cols();
  325. }
  326. if (size() == 0)
  327. resize(acols);
  328. if (acols != size() || arows != v.size())
  329. _THROW_EVector("Matrix multiplication: inconsistent sizes.");
  330. #ifdef NICE_USELIB_IPP
  331. size_t tsize=sizeof(ElementType);
  332. IppStatus ret;
  333. if(atranspose)
  334. {
  335. ret = ippmMul_mv(a.getDataPointer(), a.cols()*tsize, tsize, a.cols(), a.rows(),
  336. v.getDataPointer(), tsize, v.size(),
  337. this->getDataPointer(), tsize);
  338. }
  339. else
  340. {
  341. ret = ippmMul_tv(a.getDataPointer(), a.cols()*tsize, tsize, a.cols(), a.rows(),
  342. v.getDataPointer(), tsize, v.size(),
  343. this->getDataPointer(), tsize);
  344. }
  345. if(ret!=ippStsNoErr)
  346. _THROW_EVector(ippGetStatusString(ret));
  347. #else
  348. #pragma omp parallel for
  349. // FIXME not very efficient
  350. for (int i = 0; i < int(acols); i++)
  351. {
  352. ElementType sum = ElementType(0);
  353. for (unsigned int k = 0; k < arows; k++)
  354. {
  355. ElementType ela = atranspose ? a(i, k) : a(k, i);
  356. sum += v(k) * ela;
  357. }
  358. (*this)(i) = sum;
  359. }
  360. #endif
  361. }
  362. template<typename ElementType>
  363. void VectorT<ElementType>::multiply(const RowMatrixT<ElementType>& a, const VectorT<ElementType>& v, bool atranspose)
  364. {
  365. size_t arows, acols;
  366. if(atranspose) {
  367. arows=a.cols();
  368. acols=a.rows();
  369. } else {
  370. arows=a.rows();
  371. acols=a.cols();
  372. }
  373. if (size() == 0)
  374. resize(arows);
  375. if (arows != size() || acols != v.size())
  376. _THROW_EVector("Matrix multiplication: inconsistent sizes.");
  377. #ifdef NICE_USELIB_IPP
  378. size_t tsize=sizeof(ElementType);
  379. IppStatus ret;
  380. if(atranspose) {
  381. ret = ippmMul_tv(a.getDataPointer(), a.cols()*tsize, tsize, a.cols(), a.rows(),
  382. v.getDataPointer(), tsize, v.size(),
  383. this->getDataPointer(), tsize);
  384. } else {
  385. ret = ippmMul_mv(a.getDataPointer(), a.cols()*tsize, tsize, a.cols(), a.rows(),
  386. v.getDataPointer(), tsize, v.size(),
  387. this->getDataPointer(), tsize);
  388. }
  389. if(ret!=ippStsNoErr)
  390. _THROW_EVector(ippGetStatusString(ret));
  391. #else
  392. // FIXME not very efficient
  393. ElementType ela;
  394. for (unsigned int i = 0; i < arows; i++)
  395. {
  396. ElementType sum = ElementType(0);
  397. for (unsigned int k = 0; k < acols; k++)
  398. {
  399. ela = atranspose ? a(k, i) : a(i, k);
  400. sum += ela * v(k);
  401. }
  402. (*this)(i) = sum;
  403. }
  404. #endif
  405. }
  406. template<typename ElementType>
  407. void VectorT<ElementType>::multiply(const VectorT<ElementType>& v, const MatrixT<ElementType>& a, bool atranspose)
  408. {
  409. size_t arows, acols;
  410. if(atranspose) {
  411. arows=a.cols();
  412. acols=a.rows();
  413. } else {
  414. arows=a.rows();
  415. acols=a.cols();
  416. }
  417. if (size() == 0)
  418. resize(acols);
  419. if (acols != size() || arows != v.size())
  420. _THROW_EVector("Matrix multiplication: inconsistent sizes.");
  421. #ifdef NICE_USELIB_IPP
  422. size_t tsize=sizeof(ElementType);
  423. IppStatus ret;
  424. if(atranspose) {
  425. ret = ippmMul_tv(a.getDataPointer(), a.rows()*tsize, tsize, a.rows(), a.cols(),
  426. v.getDataPointer(), tsize, v.size(),
  427. this->getDataPointer(), tsize);
  428. } else {
  429. ret = ippmMul_mv(a.getDataPointer(), a.rows()*tsize, tsize, a.rows(), a.cols(),
  430. v.getDataPointer(), tsize, v.size(),
  431. this->getDataPointer(), tsize);
  432. }
  433. if(ret!=ippStsNoErr)
  434. _THROW_EVector(ippGetStatusString(ret));
  435. #else
  436. // FIXME not very efficient
  437. ElementType ela;
  438. for (unsigned int i = 0; i < acols; i++)
  439. {
  440. ElementType sum = ElementType(0);
  441. for (unsigned int k = 0; k < arows; k++)
  442. {
  443. ela = atranspose ? a(i, k) : a(k, i);
  444. sum += v(k) * ela;
  445. }
  446. (*this)(i) = sum;
  447. }
  448. #endif
  449. }
  450. template<class ElementType>
  451. inline ElementType
  452. VectorT<ElementType>::scalarProduct(
  453. const VectorT<ElementType>& v) const {
  454. if (size() != v.size()) {
  455. throw std::invalid_argument("VectorT::scalarProduct(): v.size() != size()");
  456. } else if (size() == 0) {
  457. throw std::invalid_argument("VectorT::scalarProduct(): size() == 0");
  458. }
  459. ElementType result;
  460. IppStatus ret = ippsDotProd(getDataPointer(),v.getDataPointer(),dataSize,&result);
  461. if(ret!=ippStsNoErr)
  462. _THROW_EVector(ippGetStatusString(ret));
  463. return result;
  464. }
  465. template<class ElementType>
  466. inline ElementType VectorT<ElementType>::Median() const {
  467. VectorT<ElementType> sorted(*this);
  468. sorted.sortAscend();
  469. return sorted[dataSize/2];
  470. }
  471. #define _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(_IppName,_Name) \
  472. template<class ElementType> \
  473. inline ElementType \
  474. VectorT<ElementType>::_Name() const { \
  475. ElementType result=0; \
  476. IppStatus ret = ipps##_IppName(getDataPointer(), dataSize, &result); \
  477. if(ret!=ippStsNoErr) \
  478. _THROW_EVector(ippGetStatusString(ret)); \
  479. return result; \
  480. }
  481. #ifndef DISABLE_IPP_MAXMIN
  482. // in the current version of valgrind, valgrind
  483. // does not recognize some cpu operations used
  484. // in the IPP routines of ippMax and ippMin
  485. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Max,Max)
  486. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Min,Min)
  487. #else
  488. template<class ElementType>
  489. inline ElementType
  490. VectorT<ElementType>::Max() const
  491. {
  492. ElementType maximum = - std::numeric_limits<ElementType>::max();
  493. for ( uint i = 0 ; i < size() ; i++ )
  494. if ( (*this)(i) > maximum )
  495. maximum = (*this)(i);
  496. return maximum;
  497. }
  498. template<class ElementType>
  499. inline ElementType
  500. VectorT<ElementType>::Min() const
  501. {
  502. ElementType minimum = std::numeric_limits<ElementType>::max();
  503. for ( uint i = 0 ; i < size() ; i++ )
  504. if ( (*this)(i) < minimum )
  505. minimum = (*this)(i);
  506. return minimum;
  507. }
  508. #endif
  509. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Sum,Sum)
  510. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Mean,Mean)
  511. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(StdDev,StdDev)
  512. #ifdef NICE_USELIB_IPP
  513. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Norm_Inf,normInf)
  514. #else
  515. // The previous standard implementation didn't work for negative values!
  516. template<class ElementType>
  517. inline ElementType
  518. VectorT<ElementType>::normInf() const
  519. {
  520. ElementType zero ( 0 );
  521. ElementType minusOne ( -1 );
  522. ElementType infNorm = zero;
  523. for ( uint i = 0 ; i < size() ; i++ )
  524. {
  525. if ( (*this)(i) < zero ) //negative entry
  526. {
  527. if ( ((*this)(i) * minusOne) > infNorm)
  528. infNorm = ((*this)(i) * minusOne);
  529. }
  530. else //positive entry
  531. {
  532. if ( (*this)(i) > infNorm)
  533. infNorm = (*this)(i) ;
  534. }
  535. }
  536. return infNorm;
  537. }
  538. #endif
  539. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Norm_L1,normL1)
  540. _DEFINE_EVECTOR_CONSTVOIDELEMENTFUNC(Norm_L2,normL2)
  541. #define _DEFINE_EVECTOR_VOIDIPFUNC(_IppName,_Name) \
  542. template<class ElementType> \
  543. inline void VectorT<ElementType>::_Name() { \
  544. IppStatus ret = ipps##_IppName(getDataPointer(), dataSize); \
  545. if(ret!=ippStsNoErr) \
  546. _THROW_EVector(ippGetStatusString(ret)); \
  547. }
  548. _DEFINE_EVECTOR_VOIDIPFUNC(Abs_I,absInplace)
  549. #define _DEFINE_EVECTOR_VOIDEVECTORFUNC(_IppName,_Name) \
  550. template<class ElementType> \
  551. inline VectorT<ElementType> VectorT<ElementType>::_Name() const { \
  552. VectorT<ElementType> result(dataSize); \
  553. IppStatus ret = ipps##_IppName(getDataPointer(),result.getDataPointer(), dataSize); \
  554. if(ret!=ippStsNoErr) \
  555. _THROW_EVector(ippGetStatusString(ret)); \
  556. return result; \
  557. }
  558. _DEFINE_EVECTOR_VOIDEVECTORFUNC(Abs,abs)
  559. template<class ElementType>
  560. inline int
  561. VectorT<ElementType>::MaxIndex() const {
  562. int result;
  563. ElementType elem;
  564. IppStatus ret = ippsMaxIndx(getDataPointer(), dataSize, &elem, &result);
  565. if(ret!=ippStsNoErr)
  566. _THROW_EVector(ippGetStatusString(ret));
  567. return result;
  568. }
  569. template<class ElementType>
  570. inline int
  571. VectorT<ElementType>::MinIndex() const {
  572. int result;
  573. ElementType elem;
  574. IppStatus ret = ippsMinIndx(getDataPointer(), dataSize, &elem, &result);
  575. if(ret!=ippStsNoErr)
  576. _THROW_EVector(ippGetStatusString(ret));
  577. return result;
  578. }
  579. template<class ElementType>
  580. inline VectorT<ElementType> VectorT<ElementType>::UniformRandom(const size_t size, ElementType min,
  581. ElementType max, unsigned int seed)
  582. {
  583. VectorT result(size);
  584. IppStatus ret = ippsRandUniform_Direct(result.getDataPointer(),size,min,max,&seed);
  585. if(ret!=ippStsNoErr)
  586. _THROW_EVector(ippGetStatusString(ret));
  587. return result;
  588. }
  589. template<class ElementType>
  590. inline VectorT<ElementType> VectorT<ElementType>::UniformRandom(const size_t size, ElementType min,
  591. ElementType max)
  592. {
  593. VectorT result(size);
  594. for (uint i = 0 ; i < size ; i++ )
  595. result[i] = (ElementType) ( randDouble((double)(max-min)) + (double)min );
  596. return result;
  597. }
  598. template<class ElementType>
  599. inline VectorT<ElementType> VectorT<ElementType>::GaussRandom(const size_t size, ElementType mean,
  600. ElementType stdev, unsigned int seed)
  601. {
  602. VectorT result(size);
  603. #ifdef NICE_USELIB_IPP
  604. IppStatus ret = ippsRandGauss_Direct(result.getDataPointer(),size,mean,stdev,&seed);
  605. if(ret!=ippStsNoErr)
  606. _THROW_EVector(ippGetStatusString(ret));
  607. #else
  608. initRand ( true, seed );
  609. for ( int i = 0 ; i < size ; i++ )
  610. result[i] = randGaussDouble ( stdev ) + mean;
  611. #endif
  612. return result;
  613. }
  614. template<class ElementType>
  615. inline VectorT<ElementType> VectorT<ElementType>::GaussRandom(const size_t size, ElementType mean,
  616. ElementType stdev)
  617. {
  618. VectorT result(size);
  619. for ( uint i = 0 ; i < size ; i++ )
  620. result[i] = randGaussDouble ( stdev ) + mean;
  621. return result;
  622. }
  623. template<typename ElementType>
  624. inline VectorT<ElementType>&
  625. VectorT<ElementType>::operator=(const VectorT<ElementType>& v) {
  626. if (dataSize == 0 && !externalStorage && getDataPointer() == NULL) {
  627. setDataPointer(new ElementType[v.size()], v.size(), false);
  628. } else if (this->dataSize != v.size()) {
  629. this->resize(v.size());
  630. }
  631. ippsCopy(v.getDataPointer(), getDataPointer(), v.dataSize);
  632. return *this;
  633. }
  634. template<typename ElementType>
  635. inline VectorT<ElementType>&
  636. VectorT<ElementType>::operator=(const ElementType& element) {
  637. ippsSet(element, getDataPointer(), this->dataSize);
  638. return *this;
  639. }
  640. template<typename ElementType>
  641. void VectorT<ElementType>::flip() {
  642. ippsFlip_I(getDataPointer(), this->dataSize);
  643. }
  644. template<typename ElementType>
  645. void VectorT<ElementType>::sortAscend() {
  646. ippsSortAscend_I(getDataPointer(), this->dataSize);
  647. }
  648. template<typename ElementType>
  649. void VectorT<ElementType>::sortDescend() {
  650. ippsSortDescend_I(getDataPointer(), this->dataSize);
  651. }
  652. /**
  653. * @brief sort elements in an descending order.
  654. */
  655. template<typename ElementType>
  656. void VectorT<ElementType>::sortDescend(VectorT<int> & permutation) {
  657. // VectorT<ElementType> tmp_cp(*this);
  658. ippsSortDescend_I(getDataPointer(), this->dataSize);
  659. // permutation.resize(this->size());
  660. // for (int i = 0; i < this->size(); i++)
  661. // {
  662. // ElementTyp entry((*this)[i]);
  663. // for (int i = 0; i < this->size(); i++)
  664. // {
  665. //
  666. // }
  667. // }
  668. }
  669. template<typename ElementType>
  670. MatrixT<ElementType> VectorT<ElementType>::toCrossProductMatrix() const {
  671. MatrixT<ElementType> result(size(), size());
  672. result(0, 0) = 0.0;
  673. result(0, 1) = -(*this)[2];
  674. result(0, 2) = (*this)[1];
  675. result(1, 0) = (*this)[2];
  676. result(1, 1) = 0.0;
  677. result(1, 2) = -(*this)[0];
  678. result(2, 0) = -(*this)[1];
  679. result(2, 1) = (*this)[0];
  680. result(2, 2) = 0.0;
  681. return result;
  682. }
  683. #define _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(_Op, _Name) \
  684. template<class ElementType> \
  685. inline VectorT<ElementType> & \
  686. VectorT<ElementType>::operator _Op##= (const ElementType& v) { \
  687. ipps##_Name##C_I(v, getDataPointer(), this->dataSize); \
  688. return *this; \
  689. }
  690. _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(+, Add)
  691. _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(-, Sub)
  692. _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(*, Mul)
  693. _DEFINE_EVECTOR_AUGMENTED_ASSIGNMENT(/, Div)
  694. #define _DEFINE_EVECTOR_ASSIGNMENT(_Op, _Name) \
  695. template<class ElementType> \
  696. inline VectorT<ElementType> & \
  697. VectorT<ElementType>::operator _Op##= (const VectorT<ElementType>& v) { \
  698. if(this->dataSize!=v.size()) \
  699. _THROW_EVector("VectorT: different data size"); \
  700. ipps##_Name##_I(v.getDataPointer(), getDataPointer(), this->dataSize); \
  701. return *this; \
  702. }
  703. _DEFINE_EVECTOR_ASSIGNMENT(+, Add)
  704. _DEFINE_EVECTOR_ASSIGNMENT(-, Sub)
  705. _DEFINE_EVECTOR_ASSIGNMENT(*, Mul)
  706. _DEFINE_EVECTOR_ASSIGNMENT(/, Div)
  707. // shift operations
  708. template<typename ElementType>
  709. VectorT<ElementType> VectorT<ElementType>::LShiftCircular(const uint b) {
  710. VectorT<ElementType> result(size());
  711. Ipp32u bShift = b%size();
  712. #ifdef NICE_USELIB_IPP
  713. ippsCopy(getDataPointer()+bShift, result.getDataPointer() , size()-bShift);
  714. ippsCopy(getDataPointer() , result.getDataPointer()+size()-bShift, bShift );
  715. #else // NICE_USELIB_IPP
  716. memcpy(result.getDataPointer(), getDataPointer()+bShift, (size()-bShift)*sizeof(ElementType));
  717. memcpy(result.getDataPointer()+size()-bShift, getDataPointer(), bShift*sizeof(ElementType));
  718. #endif
  719. return result;
  720. }
  721. template<typename ElementType>
  722. void VectorT<ElementType>::LShiftCircularInplace(const uint b) {
  723. VectorT<ElementType> buffer = this->LShiftCircular(b);
  724. *this = buffer;
  725. }
  726. template<typename ElementType>
  727. VectorT<ElementType> VectorT<ElementType>::RShiftCircular(const uint b) {
  728. VectorT<ElementType> result(size());
  729. Ipp32u bShift = b%size();
  730. #ifdef NICE_USELIB_IPP
  731. ippsCopy(getDataPointer(), result.getDataPointer()+bShift, size()-bShift);
  732. ippsCopy(getDataPointer()+size()-bShift, result.getDataPointer(), bShift);
  733. #else // NICE_USELIB_IPP
  734. memcpy(result.getDataPointer()+bShift, getDataPointer(), (size()-bShift)*sizeof(ElementType));
  735. memcpy(result.getDataPointer(), getDataPointer()+size()-bShift, bShift*sizeof(ElementType));
  736. #endif
  737. return result;
  738. }
  739. template<typename ElementType>
  740. void VectorT<ElementType>::RShiftCircularInplace(const uint b) {
  741. VectorT<ElementType> buffer = this->RShiftCircular(b);
  742. *this = buffer;
  743. }
  744. template<typename ElementType>
  745. inline bool VectorT<ElementType>::isEqual(const VectorT<ElementType> &v, ElementType threshold) const
  746. {
  747. if( this->size() != v.size() )
  748. _THROW_EVector("VectorT: different data size");
  749. for (unsigned int j = 0; j < size(); j++) {
  750. if(fabs((*this)[j]-v[j])>threshold)
  751. return false;
  752. }
  753. return true;
  754. }
  755. template<typename ElementType>
  756. unsigned long VectorT<ElementType>::getHashValue() const
  757. {
  758. const char *buf = (const char*)getDataPointer();
  759. uint len = size() * sizeof(ElementType);
  760. // might overflow...but we do not care about it
  761. // According to http://www.ntecs.de/projects/guugelhupf/doc/html/x435.html
  762. // this is what STL is using
  763. unsigned long hash = 0;
  764. for ( int i = 0 ; i < len ; i++ )
  765. hash = 5*hash + buf[i];
  766. return hash;
  767. }
  768. template<typename ElementType>
  769. std::vector<ElementType> VectorT<ElementType>::std_vector () const
  770. {
  771. std::vector<ElementType> dst ( this->size() );
  772. for ( unsigned int i = 0 ; i < size(); i++ )
  773. dst[i] = (*this)[i];
  774. return dst;
  775. }
  776. } // namespace NICE
  777. #endif