$search
00001 // Copyright (C) 2011 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2011 Conrad Sanderson 00003 // 00004 // This file is part of the Armadillo C++ library. 00005 // It is provided without any warranty of fitness 00006 // for any purpose. You can redistribute this file 00007 // and/or modify it under the terms of the GNU 00008 // Lesser General Public License (LGPL) as published 00009 // by the Free Software Foundation, either version 3 00010 // of the License or (at your option) any later version. 00011 // (see http://www.opensource.org/licenses for more info) 00012 00013 00016 00017 00018 00019 template<typename eT> 00020 arma_hot 00021 arma_inline 00022 void 00023 arrayops::copy(eT* dest, const eT* src, const uword n_elem) 00024 { 00025 switch(n_elem) 00026 { 00027 default: 00028 arrayops::copy_big(dest, src, n_elem); 00029 break; 00030 case 8: 00031 dest[7] = src[7]; 00032 case 7: 00033 dest[6] = src[6]; 00034 case 6: 00035 dest[5] = src[5]; 00036 case 5: 00037 dest[4] = src[4]; 00038 case 4: 00039 dest[3] = src[3]; 00040 case 3: 00041 dest[2] = src[2]; 00042 case 2: 00043 dest[1] = src[1]; 00044 case 1: 00045 dest[0] = src[0]; 00046 } 00047 } 00048 00049 00050 00051 template<typename eT> 00052 inline 00053 void 00054 arrayops::copy_big(eT* dest, const eT* src, const uword n_elem) 00055 { 00056 switch(n_elem) 00057 { 00058 default: 00059 std::memcpy(dest, src, n_elem*sizeof(eT)); 00060 break; 00061 case 32: 00062 dest[31] = src[31]; 00063 case 31: 00064 dest[30] = src[30]; 00065 case 30: 00066 dest[29] = src[29]; 00067 case 29: 00068 dest[28] = src[28]; 00069 case 28: 00070 dest[27] = src[27]; 00071 case 27: 00072 dest[26] = src[26]; 00073 case 26: 00074 dest[25] = src[25]; 00075 case 25: 00076 dest[24] = src[24]; 00077 case 24: 00078 dest[23] = src[23]; 00079 case 23: 00080 dest[22] = src[22]; 00081 case 22: 00082 dest[21] = src[21]; 00083 case 21: 00084 dest[20] = src[20]; 00085 case 20: 00086 dest[19] = src[19]; 00087 case 19: 00088 dest[18] = src[18]; 00089 case 18: 00090 dest[17] = src[17]; 00091 case 17: 00092 dest[16] = src[16]; 00093 case 16: 00094 dest[15] = src[15]; 00095 case 15: 00096 dest[14] = src[14]; 00097 case 14: 00098 dest[13] = src[13]; 00099 case 13: 00100 dest[12] = src[12]; 00101 case 12: 00102 dest[11] = src[11]; 00103 case 11: 00104 dest[10] = src[10]; 00105 case 10: 00106 dest[9] = src[9]; 00107 case 9: 00108 dest[8] = src[8]; 00109 case 8: 00110 dest[7] = src[7]; 00111 case 7: 00112 dest[6] = src[6]; 00113 case 6: 00114 dest[5] = src[5]; 00115 case 5: 00116 dest[4] = src[4]; 00117 case 4: 00118 dest[3] = src[3]; 00119 case 3: 00120 dest[2] = src[2]; 00121 case 2: 00122 dest[1] = src[1]; 00123 case 1: 00124 dest[0] = src[0]; 00125 } 00126 } 00127 00128 00129 00130 template<typename out_eT, typename in_eT> 00131 arma_hot 00132 arma_inline 00133 void 00134 arrayops::convert_cx_scalar 00135 ( 00136 out_eT& out, 00137 const in_eT& in, 00138 const typename arma_not_cx<out_eT>::result* junk1, 00139 const typename arma_not_cx< in_eT>::result* junk2 00140 ) 00141 { 00142 arma_ignore(junk1); 00143 arma_ignore(junk2); 00144 00145 out = out_eT(in); 00146 } 00147 00148 00149 00150 template<typename out_eT, typename in_T> 00151 arma_hot 00152 arma_inline 00153 void 00154 arrayops::convert_cx_scalar 00155 ( 00156 out_eT& out, 00157 const std::complex<in_T>& in, 00158 const typename arma_not_cx<out_eT>::result* junk 00159 ) 00160 { 00161 arma_ignore(junk); 00162 00163 out = out_eT( in.real() ); 00164 } 00165 00166 00167 00168 template<typename out_T, typename in_T> 00169 arma_hot 00170 arma_inline 00171 void 00172 arrayops::convert_cx_scalar 00173 ( 00174 std::complex<out_T>& out, 00175 const std::complex< in_T>& in 00176 ) 00177 { 00178 typedef std::complex<out_T> out_eT; 00179 00180 out = out_eT(in); 00181 } 00182 00183 00184 00185 template<typename out_eT, typename in_eT> 00186 arma_hot 00187 inline 00188 void 00189 arrayops::convert(out_eT* dest, const in_eT* src, const uword n_elem) 00190 { 00191 uword i,j; 00192 00193 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00194 { 00195 dest[i] = out_eT( src[i] ); 00196 dest[j] = out_eT( src[j] ); 00197 } 00198 00199 if(i < n_elem) 00200 { 00201 dest[i] = out_eT( src[i] ); 00202 } 00203 } 00204 00205 00206 00207 template<typename out_eT, typename in_eT> 00208 arma_hot 00209 inline 00210 void 00211 arrayops::convert_cx(out_eT* dest, const in_eT* src, const uword n_elem) 00212 { 00213 uword i,j; 00214 00215 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00216 { 00217 arrayops::convert_cx_scalar( dest[i], src[i] ); 00218 arrayops::convert_cx_scalar( dest[j], src[j] ); 00219 } 00220 00221 if(i < n_elem) 00222 { 00223 arrayops::convert_cx_scalar( dest[i], src[i] ); 00224 } 00225 } 00226 00227 00228 00229 template<typename eT> 00230 arma_hot 00231 inline 00232 void 00233 arrayops::inplace_plus(eT* dest, const eT* src, const uword n_elem) 00234 { 00235 uword i,j; 00236 00237 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00238 { 00239 dest[i] += src[i]; 00240 dest[j] += src[j]; 00241 } 00242 00243 if(i < n_elem) 00244 { 00245 dest[i] += src[i]; 00246 } 00247 } 00248 00249 00250 00251 template<typename eT> 00252 arma_hot 00253 inline 00254 void 00255 arrayops::inplace_minus(eT* dest, const eT* src, const uword n_elem) 00256 { 00257 uword i,j; 00258 00259 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00260 { 00261 dest[i] -= src[i]; 00262 dest[j] -= src[j]; 00263 } 00264 00265 if(i < n_elem) 00266 { 00267 dest[i] -= src[i]; 00268 } 00269 } 00270 00271 00272 00273 template<typename eT> 00274 arma_hot 00275 inline 00276 void 00277 arrayops::inplace_mul(eT* dest, const eT* src, const uword n_elem) 00278 { 00279 uword i,j; 00280 00281 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00282 { 00283 dest[i] *= src[i]; 00284 dest[j] *= src[j]; 00285 } 00286 00287 if(i < n_elem) 00288 { 00289 dest[i] *= src[i]; 00290 } 00291 } 00292 00293 00294 00295 template<typename eT> 00296 arma_hot 00297 inline 00298 void 00299 arrayops::inplace_div(eT* dest, const eT* src, const uword n_elem) 00300 { 00301 uword i,j; 00302 00303 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00304 { 00305 dest[i] /= src[i]; 00306 dest[j] /= src[j]; 00307 } 00308 00309 if(i < n_elem) 00310 { 00311 dest[i] /= src[i]; 00312 } 00313 } 00314 00315 00316 00317 template<typename eT> 00318 arma_hot 00319 inline 00320 void 00321 arrayops::inplace_set(eT* dest, const eT val, const uword n_elem) 00322 { 00323 uword i,j; 00324 00325 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00326 { 00327 dest[i] = val; 00328 dest[j] = val; 00329 } 00330 00331 if(i < n_elem) 00332 { 00333 dest[i] = val; 00334 } 00335 } 00336 00337 00338 00339 template<typename eT> 00340 arma_hot 00341 inline 00342 void 00343 arrayops::inplace_plus(eT* dest, const eT val, const uword n_elem) 00344 { 00345 uword i,j; 00346 00347 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00348 { 00349 dest[i] += val; 00350 dest[j] += val; 00351 } 00352 00353 if(i < n_elem) 00354 { 00355 dest[i] += val; 00356 } 00357 } 00358 00359 00360 00361 template<typename eT> 00362 arma_hot 00363 inline 00364 void 00365 arrayops::inplace_minus(eT* dest, const eT val, const uword n_elem) 00366 { 00367 uword i,j; 00368 00369 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00370 { 00371 dest[i] -= val; 00372 dest[j] -= val; 00373 } 00374 00375 if(i < n_elem) 00376 { 00377 dest[i] -= val; 00378 } 00379 } 00380 00381 00382 00383 template<typename eT> 00384 arma_hot 00385 inline 00386 void 00387 arrayops::inplace_mul(eT* dest, const eT val, const uword n_elem) 00388 { 00389 uword i,j; 00390 00391 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00392 { 00393 dest[i] *= val; 00394 dest[j] *= val; 00395 } 00396 00397 if(i < n_elem) 00398 { 00399 dest[i] *= val; 00400 } 00401 } 00402 00403 00404 00405 template<typename eT> 00406 arma_hot 00407 inline 00408 void 00409 arrayops::inplace_div(eT* dest, const eT val, const uword n_elem) 00410 { 00411 uword i,j; 00412 00413 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00414 { 00415 dest[i] /= val; 00416 dest[j] /= val; 00417 } 00418 00419 if(i < n_elem) 00420 { 00421 dest[i] /= val; 00422 } 00423 } 00424 00425 00426 00427 template<typename eT> 00428 arma_hot 00429 arma_pure 00430 inline 00431 eT 00432 arrayops::accumulate(const eT* src, const uword n_elem) 00433 { 00434 uword i,j; 00435 00436 eT acc1 = eT(0); 00437 eT acc2 = eT(0); 00438 00439 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00440 { 00441 acc1 += src[i]; 00442 acc2 += src[j]; 00443 } 00444 00445 if(i < n_elem) 00446 { 00447 acc1 += src[i]; 00448 } 00449 00450 return acc1 + acc2; 00451 } 00452 00453 00454 00455 template<typename eT> 00456 arma_hot 00457 arma_pure 00458 inline 00459 eT 00460 arrayops::product(const eT* src, const uword n_elem) 00461 { 00462 eT val1 = eT(1); 00463 eT val2 = eT(1); 00464 00465 uword i,j; 00466 00467 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00468 { 00469 val1 *= src[i]; 00470 val2 *= src[j]; 00471 } 00472 00473 if(i < n_elem) 00474 { 00475 val1 *= src[i]; 00476 } 00477 00478 return val1 * val2; 00479 } 00480 00481 00482 00483 template<typename eT> 00484 arma_hot 00485 arma_pure 00486 inline 00487 bool 00488 arrayops::is_finite(const eT* src, const uword n_elem) 00489 { 00490 uword i,j; 00491 00492 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00493 { 00494 const eT val_i = src[i]; 00495 const eT val_j = src[j]; 00496 00497 if( (arma_isfinite(val_i) == false) || (arma_isfinite(val_j) == false) ) 00498 { 00499 return false; 00500 } 00501 } 00502 00503 if(i < n_elem) 00504 { 00505 if(arma_isfinite(src[i]) == false) 00506 { 00507 return false; 00508 } 00509 } 00510 00511 return true; 00512 } 00513 00514 00515 00516 // TODO: this function is currently not used 00517 template<typename eT> 00518 arma_hot 00519 arma_pure 00520 inline 00521 typename get_pod_type<eT>::result 00522 arrayops::norm_1(const eT* src, const uword n_elem) 00523 { 00524 typedef typename get_pod_type<eT>::result T; 00525 00526 T acc = T(0); 00527 00528 uword i,j; 00529 00530 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00531 { 00532 acc += std::abs(src[i]); 00533 acc += std::abs(src[j]); 00534 } 00535 00536 if(i < n_elem) 00537 { 00538 acc += std::abs(src[i]); 00539 } 00540 00541 return acc; 00542 } 00543 00544 00545 00546 // TODO: this function is currently not used 00547 template<typename eT> 00548 arma_hot 00549 arma_pure 00550 inline 00551 eT 00552 arrayops::norm_2(const eT* src, const uword n_elem, const typename arma_not_cx<eT>::result* junk) 00553 { 00554 arma_ignore(junk); 00555 00556 eT acc = eT(0); 00557 00558 uword i,j; 00559 00560 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00561 { 00562 const eT tmp_i = src[i]; 00563 const eT tmp_j = src[j]; 00564 00565 acc += tmp_i * tmp_i; 00566 acc += tmp_j * tmp_j; 00567 } 00568 00569 if(i < n_elem) 00570 { 00571 const eT tmp_i = src[i]; 00572 00573 acc += tmp_i * tmp_i; 00574 } 00575 00576 return std::sqrt(acc); 00577 } 00578 00579 00580 00581 // TODO: this function is currently not used 00582 template<typename T> 00583 arma_hot 00584 arma_pure 00585 inline 00586 T 00587 arrayops::norm_2(const std::complex<T>* src, const uword n_elem) 00588 { 00589 T acc = T(0); 00590 00591 uword i,j; 00592 00593 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00594 { 00595 const T tmp_i = std::abs(src[i]); 00596 const T tmp_j = std::abs(src[j]); 00597 00598 acc += tmp_i * tmp_i; 00599 acc += tmp_j * tmp_j; 00600 } 00601 00602 if(i < n_elem) 00603 { 00604 const T tmp_i = std::abs(src[i]); 00605 00606 acc += tmp_i * tmp_i; 00607 } 00608 00609 return std::sqrt(acc); 00610 } 00611 00612 00613 00614 // TODO: this function is currently not used 00615 template<typename eT> 00616 arma_hot 00617 arma_pure 00618 inline 00619 typename get_pod_type<eT>::result 00620 arrayops::norm_k(const eT* src, const uword n_elem, const int k) 00621 { 00622 typedef typename get_pod_type<eT>::result T; 00623 00624 T acc = T(0); 00625 00626 uword i,j; 00627 00628 for(i=0, j=1; j<n_elem; i+=2, j+=2) 00629 { 00630 acc += std::pow(std::abs(src[i]), k); 00631 acc += std::pow(std::abs(src[j]), k); 00632 } 00633 00634 if(i < n_elem) 00635 { 00636 acc += std::pow(std::abs(src[i]), k); 00637 } 00638 00639 return std::pow(acc, T(1)/T(k)); 00640 } 00641 00642 00643 00644 // TODO: this function is currently not used 00645 template<typename eT> 00646 arma_hot 00647 arma_pure 00648 inline 00649 typename get_pod_type<eT>::result 00650 arrayops::norm_max(const eT* src, const uword n_elem) 00651 { 00652 typedef typename get_pod_type<eT>::result T; 00653 00654 T max_val = std::abs(src[0]); 00655 00656 uword i,j; 00657 00658 for(i=1, j=2; j<n_elem; i+=2, j+=2) 00659 { 00660 const T tmp_i = std::abs(src[i]); 00661 const T tmp_j = std::abs(src[j]); 00662 00663 if(max_val < tmp_i) { max_val = tmp_i; } 00664 if(max_val < tmp_j) { max_val = tmp_j; } 00665 } 00666 00667 if(i < n_elem) 00668 { 00669 const T tmp_i = std::abs(src[i]); 00670 00671 if(max_val < tmp_i) { max_val = tmp_i; } 00672 } 00673 00674 return max_val; 00675 } 00676 00677 00678 00679 // TODO: this function is currently not used 00680 template<typename eT> 00681 arma_hot 00682 arma_pure 00683 inline 00684 typename get_pod_type<eT>::result 00685 arrayops::norm_min(const eT* src, const uword n_elem) 00686 { 00687 typedef typename get_pod_type<eT>::result T; 00688 00689 T min_val = std::abs(src[0]); 00690 00691 uword i,j; 00692 00693 for(i=1, j=2; j<n_elem; i+=2, j+=2) 00694 { 00695 const T tmp_i = std::abs(src[i]); 00696 const T tmp_j = std::abs(src[j]); 00697 00698 if(min_val > tmp_i) { min_val = tmp_i; } 00699 if(min_val > tmp_j) { min_val = tmp_j; } 00700 } 00701 00702 if(i < n_elem) 00703 { 00704 const T tmp_i = std::abs(src[i]); 00705 00706 if(min_val > tmp_i) { min_val = tmp_i; } 00707 } 00708 00709 return min_val; 00710 } 00711 00712 00713