00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
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
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
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
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
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
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
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