fn_misc.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2010 NICTA and the authors listed below
00002 // http://nicta.com.au
00003 // 
00004 // Authors:
00005 // - Conrad Sanderson (conradsand at ieee dot org)
00006 // 
00007 // This file is part of the Armadillo C++ library.
00008 // It is provided without any warranty of fitness
00009 // for any purpose. You can redistribute this file
00010 // and/or modify it under the terms of the GNU
00011 // Lesser General Public License (LGPL) as published
00012 // by the Free Software Foundation, either version 3
00013 // of the License or (at your option) any later version.
00014 // (see http://www.opensource.org/licenses for more info)
00015 
00016 
00017 //! \addtogroup fn_misc
00018 //! @{
00019 
00020 
00021 
00022 //! \brief
00023 //! Generate a vector with 'num' elements.
00024 //! The values of the elements linearly increase from 'start' upto (and including) 'end'.
00025 
00026 template<typename vec_type>
00027 inline
00028 vec_type
00029 linspace
00030   (
00031   const typename vec_type::pod_type start,
00032   const typename vec_type::pod_type end,
00033   const u32 num,
00034   const u32 dim = 0
00035   )
00036   {
00037   arma_extra_debug_sigprint();
00038   
00039   arma_type_check< (is_Mat<vec_type>::value == false) >::apply();
00040   
00041   arma_debug_check( (num < 2), "linspace(): num must be >= 2");
00042   
00043   arma_warn( (dim != 0), "linspace(): the 'dim' argument is deprecated -- please use template based specification instead" );
00044   
00045   typedef typename vec_type::elem_type eT;
00046   typedef typename vec_type::pod_type   T;
00047   
00048   // // this will be the default in the future:
00049   // const u32 n_rows = (is_Row<vec_type>::value == true) ? 1   : num;
00050   // const u32 n_cols = (is_Row<vec_type>::value == true) ? num : 1;
00051   
00052   // for temporary compatibility with old user code:
00053   const u32 n_rows = (is_Row<vec_type>::value == true) ? 1   : ( (dim == 0) ? num : 1   );
00054   const u32 n_cols = (is_Row<vec_type>::value == true) ? num : ( (dim == 0) ? 1   : num );
00055   
00056   const eT delta = (end-start)/T(num-1);
00057   
00058   Mat<eT> x(n_rows, n_cols);
00059   eT* x_mem = x.memptr();
00060   
00061   x_mem[0] = start;
00062   
00063   for(u32 i=1; i<num; ++i)
00064     {
00065     x_mem[i] = x_mem[i-1] + delta;
00066     }
00067   
00068   return x;
00069   }
00070 
00071 
00072 
00073 inline
00074 mat
00075 linspace(const double start, const double end, const u32 num, const u32 dim = 0)
00076   {
00077   arma_extra_debug_sigprint();
00078   return linspace<mat>(start, end, num, dim);
00079   }
00080 
00081 
00082 
00083 //
00084 // real
00085 
00086 template<typename T1>
00087 arma_inline
00088 const T1&
00089 real(const Base<typename T1::pod_type, T1>& X)
00090   {
00091   arma_extra_debug_sigprint();
00092   
00093   return X.get_ref();
00094   }
00095 
00096 
00097 
00098 template<typename T1>
00099 arma_inline
00100 const T1&
00101 real(const BaseCube<typename T1::pod_type, T1>& X)
00102   {
00103   arma_extra_debug_sigprint();
00104   
00105   return X.get_ref();
00106   }
00107 
00108 
00109 
00110 template<typename T1>
00111 inline
00112 Mat<typename T1::pod_type>
00113 real(const Base<std::complex<typename T1::pod_type>, T1>& X)
00114   {
00115   arma_extra_debug_sigprint();
00116   
00117   typedef typename T1::pod_type T;
00118   
00119   const Proxy<T1> A(X.get_ref());
00120   
00121   Mat<T> out(A.n_rows, A.n_cols);
00122   
00123   T* out_mem = out.memptr();
00124   
00125   for(u32 i=0; i<out.n_elem; ++i)
00126     {
00127     out_mem[i] = std::real(A[i]);
00128     }
00129   
00130   return out;
00131   }
00132 
00133 
00134 
00135 template<typename T1>
00136 inline
00137 Cube<typename T1::pod_type>
00138 real(const BaseCube<std::complex<typename T1::pod_type>, T1>& X)
00139   {
00140   arma_extra_debug_sigprint();
00141   
00142   typedef typename T1::pod_type T;
00143   
00144   const ProxyCube<T1> A(X.get_ref());
00145   
00146   Cube<T> out(A.n_rows, A.n_cols, A.n_slices);
00147   
00148   T* out_mem = out.memptr();
00149   
00150   for(u32 i=0; i<out.n_elem; ++i)
00151     {
00152     out_mem[i] = std::real(A[i]);
00153     }
00154   
00155   return out;
00156   }
00157 
00158 
00159 
00160 //
00161 // imag
00162 
00163 template<typename T1>
00164 inline
00165 const eOp<Mat<typename T1::pod_type>, eop_zeros>
00166 imag(const Base<typename T1::pod_type,T1>& X)
00167   {
00168   arma_extra_debug_sigprint();
00169   
00170   const Proxy<T1> A(X.get_ref());
00171   
00172   return eOp<Mat<typename T1::pod_type>, eop_zeros>(A.n_rows, A.n_cols);
00173   }
00174 
00175 
00176 
00177 template<typename T1>
00178 inline
00179 const eOpCube<Cube<typename T1::pod_type>, eop_cube_zeros>
00180 imag(const BaseCube<typename T1::pod_type,T1>& X)
00181   {
00182   arma_extra_debug_sigprint();
00183   
00184   const ProxyCube<T1> A(X.get_ref());
00185   
00186   return eOpCube<Cube<typename T1::pod_type>, eop_cube_zeros>(A.n_rows, A.n_cols, A.n_slices);
00187   }
00188 
00189 
00190 
00191 template<typename T1>
00192 inline
00193 Mat<typename T1::pod_type>
00194 imag(const Base<std::complex<typename T1::pod_type>,T1>& X)
00195   {
00196   arma_extra_debug_sigprint();
00197   
00198   typedef typename T1::pod_type T;
00199   
00200   const Proxy<T1> A(X.get_ref());
00201   
00202   Mat<T> out(A.n_rows, A.n_cols);
00203   
00204   T* out_mem = out.memptr();
00205   
00206   for(u32 i=0; i<out.n_elem; ++i)
00207     {
00208     out_mem[i] = std::imag(A[i]);
00209     }
00210   
00211   return out;
00212   }
00213 
00214 
00215 
00216 template<typename T1>
00217 inline
00218 Cube<typename T1::pod_type>
00219 imag(const BaseCube<std::complex<typename T1::pod_type>,T1>& X)
00220   {
00221   arma_extra_debug_sigprint();
00222   
00223   typedef typename T1::pod_type T;
00224   
00225   const ProxyCube<T1> A(X.get_ref());
00226   
00227   Cube<T> out(A.n_rows, A.n_cols, A.n_slices);
00228   
00229   T* out_mem = out.memptr();
00230   
00231   for(u32 i=0; i<out.n_elem; ++i)
00232     {
00233     out_mem[i] = std::imag(A[i]);
00234     }
00235   
00236   return out;
00237   }
00238 
00239 
00240 
00241 //
00242 // log_add
00243 
00244 template<typename eT>
00245 inline
00246 eT
00247 log_add(eT log_a, eT log_b)
00248   {
00249   if(log_a < log_b)
00250     {
00251     std::swap(log_a, log_b);
00252     }
00253   
00254   const eT negdelta = log_b - log_a;
00255   
00256   if( (negdelta < Math<eT>::log_min()) || (arma_isfinite(negdelta) == false) )
00257     {
00258     return log_a;
00259     }
00260   else
00261     {
00262     #if defined(ARMA_HAVE_LOG1P)
00263       return (log_a + log1p(std::exp(negdelta)));
00264     #else
00265       return (log_a + std::log(1.0 + std::exp(negdelta)));
00266     #endif
00267     }
00268   }
00269 
00270 
00271 
00272 //
00273 // log
00274 
00275 template<typename T1>
00276 arma_inline
00277 const eOp<T1, eop_log>
00278 log(const Base<typename T1::elem_type,T1>& A)
00279   {
00280   arma_extra_debug_sigprint();
00281   
00282   return eOp<T1, eop_log>(A.get_ref());
00283   }
00284 
00285 
00286 
00287 template<typename T1>
00288 arma_inline
00289 const eOpCube<T1, eop_cube_log>
00290 log(const BaseCube<typename T1::elem_type,T1>& A)
00291   {
00292   arma_extra_debug_sigprint();
00293   
00294   return eOpCube<T1, eop_cube_log>(A.get_ref());
00295   }
00296 
00297 
00298 
00299 //
00300 // trunc_log
00301 
00302 template<typename T1>
00303 arma_inline
00304 const eOp<T1, eop_trunc_log>
00305 trunc_log(const Base<typename T1::elem_type,T1>& A)
00306   {
00307   arma_extra_debug_sigprint();
00308   
00309   return eOp<T1, eop_trunc_log>(A.get_ref());
00310   }
00311 
00312 
00313 
00314 template<typename T1>
00315 arma_inline
00316 const eOpCube<T1, eop_cube_trunc_log>
00317 trunc_log(const BaseCube<typename T1::elem_type,T1>& A)
00318   {
00319   arma_extra_debug_sigprint();
00320   
00321   return eOpCube<T1, eop_cube_trunc_log>(A.get_ref());
00322   }
00323 
00324 
00325 
00326 //
00327 // log10
00328 
00329 template<typename T1>
00330 arma_inline
00331 const eOp<T1, eop_log10>
00332 log10(const Base<typename T1::elem_type,T1>& A)
00333   {
00334   arma_extra_debug_sigprint();
00335   
00336   return eOp<T1, eop_log10>(A.get_ref());
00337   }
00338 
00339 
00340 
00341 template<typename T1>
00342 arma_inline
00343 const eOpCube<T1, eop_cube_log10>
00344 log10(const BaseCube<typename T1::elem_type,T1>& A)
00345   {
00346   arma_extra_debug_sigprint();
00347   
00348   return eOpCube<T1, eop_cube_log10>(A.get_ref());
00349   }
00350 
00351 
00352 
00353 //
00354 // exp
00355 
00356 template<typename T1>
00357 arma_inline
00358 const eOp<T1, eop_exp>
00359 exp(const Base<typename T1::elem_type,T1>& A)
00360   {
00361   arma_extra_debug_sigprint();
00362   
00363   return eOp<T1, eop_exp>(A.get_ref());
00364   }
00365 
00366 
00367 
00368 template<typename T1>
00369 arma_inline
00370 const eOpCube<T1, eop_cube_exp>
00371 exp(const BaseCube<typename T1::elem_type,T1>& A)
00372   {
00373   arma_extra_debug_sigprint();
00374   
00375   return eOpCube<T1, eop_cube_exp>(A.get_ref());
00376   }
00377 
00378 
00379 
00380 //
00381 // trunc_exp
00382 
00383 template<typename T1>
00384 arma_inline
00385 const eOp<T1, eop_trunc_exp>
00386 trunc_exp(const Base<typename T1::elem_type,T1>& A)
00387   {
00388   arma_extra_debug_sigprint();
00389   
00390   return eOp<T1, eop_trunc_exp>(A.get_ref());
00391   }
00392 
00393 
00394 
00395 template<typename T1>
00396 arma_inline
00397 const eOpCube<T1, eop_cube_trunc_exp>
00398 trunc_exp(const BaseCube<typename T1::elem_type,T1>& A)
00399   {
00400   arma_extra_debug_sigprint();
00401   
00402   return eOpCube<T1, eop_cube_trunc_exp>(A.get_ref());
00403   }
00404 
00405 
00406 
00407 //
00408 // abs
00409 
00410 
00411 template<typename T1>
00412 arma_inline
00413 const eOp<T1, eop_abs>
00414 abs(const Base<typename T1::elem_type,T1>& X)
00415   {
00416   arma_extra_debug_sigprint();
00417   
00418   return eOp<T1, eop_abs>(X.get_ref());
00419   }
00420 
00421 
00422 
00423 template<typename T1>
00424 arma_inline
00425 const eOpCube<T1, eop_cube_abs>
00426 abs(const BaseCube<typename T1::elem_type,T1>& X)
00427   {
00428   arma_extra_debug_sigprint();
00429   
00430   return eOpCube<T1, eop_cube_abs>(X.get_ref());
00431   }
00432 
00433 
00434 
00435 template<typename T1>
00436 inline
00437 Mat<typename T1::pod_type>
00438 abs(const Base< std::complex<typename T1::pod_type>,T1>& X)
00439   {
00440   arma_extra_debug_sigprint();
00441   
00442   const Proxy<T1> A(X.get_ref());
00443 
00444   // if T1 is a complex matrix,
00445   // pod_type is the underlying type used by std::complex;
00446   // otherwise pod_type is the same as elem_type
00447   
00448   typedef typename T1::elem_type  in_eT;
00449   typedef typename T1::pod_type  out_eT;
00450 
00451   Mat<out_eT> out(A.n_rows, A.n_cols);
00452   
00453   out_eT* out_mem = out.memptr();
00454   
00455   for(u32 i=0; i<out.n_elem; ++i)
00456     {
00457     out_mem[i] = std::abs(A[i]);
00458     }
00459   
00460   return out;
00461   }
00462 
00463 
00464 
00465 template<typename T1>
00466 inline
00467 Mat<typename T1::pod_type>
00468 abs(const BaseCube< std::complex<typename T1::pod_type>,T1>& X)
00469   {
00470   arma_extra_debug_sigprint();
00471   
00472   const ProxyCube<T1> A(X.get_ref());
00473 
00474   // if T1 is a complex matrix,
00475   // pod_type is the underlying type used by std::complex;
00476   // otherwise pod_type is the same as elem_type
00477   
00478   typedef typename T1::elem_type  in_eT;
00479   typedef typename T1::pod_type  out_eT;
00480 
00481   Cube<out_eT> out(A.n_rows, A.n_cols, A.n_slices);
00482   
00483   out_eT* out_mem = out.memptr();
00484   
00485   for(u32 i=0; i<out.n_elem; ++i)
00486     {
00487     out_mem[i] = std::abs(A[i]);
00488     }
00489   
00490   return out;
00491   }
00492 
00493 
00494 
00495 //
00496 // fabs
00497 
00498 template<typename T1>
00499 arma_inline
00500 const eOp<T1, eop_abs>
00501 fabs(const Base<typename T1::pod_type,T1>& X)
00502   {
00503   arma_extra_debug_sigprint();
00504   
00505   return eOp<T1, eop_abs>(X.get_ref());
00506   }
00507 
00508 
00509 
00510 template<typename T1>
00511 arma_inline
00512 const eOpCube<T1, eop_cube_abs>
00513 fabs(const BaseCube<typename T1::pod_type,T1>& X)
00514   {
00515   arma_extra_debug_sigprint();
00516   
00517   return eOpCube<T1, eop_cube_abs>(X.get_ref());
00518   }
00519 
00520 
00521 
00522 template<typename T1>
00523 arma_inline
00524 Mat<typename T1::pod_type>
00525 fabs(const Base< std::complex<typename T1::pod_type>,T1>& X)
00526   {
00527   arma_extra_debug_sigprint();
00528   
00529   return abs(X);
00530   }
00531 
00532 
00533 
00534 template<typename T1>
00535 arma_inline
00536 Mat<typename T1::pod_type>
00537 fabs(const BaseCube< std::complex<typename T1::pod_type>,T1>& X)
00538   {
00539   arma_extra_debug_sigprint();
00540   
00541   return abs(X);
00542   }
00543 
00544 
00545 
00546 //
00547 // square
00548 
00549 template<typename T1>
00550 arma_inline
00551 const eOp<T1, eop_square>
00552 square(const Base<typename T1::elem_type,T1>& A)
00553   {
00554   arma_extra_debug_sigprint();
00555   
00556   return eOp<T1, eop_square>(A.get_ref());
00557   }
00558 
00559 
00560 
00561 template<typename T1>
00562 arma_inline
00563 const eOpCube<T1, eop_cube_square>
00564 square(const BaseCube<typename T1::elem_type,T1>& A)
00565   {
00566   arma_extra_debug_sigprint();
00567   
00568   return eOpCube<T1, eop_cube_square>(A.get_ref());
00569   }
00570 
00571 
00572 
00573 //
00574 // sqrt
00575 
00576 template<typename T1>
00577 arma_inline
00578 const eOp<T1, eop_sqrt>
00579 sqrt(const Base<typename T1::elem_type,T1>& A)
00580   {
00581   arma_extra_debug_sigprint();
00582   
00583   return eOp<T1, eop_sqrt>(A.get_ref());
00584   }
00585 
00586 
00587 
00588 template<typename T1>
00589 arma_inline
00590 const eOpCube<T1, eop_cube_sqrt>
00591 sqrt(const BaseCube<typename T1::elem_type,T1>& A)
00592   {
00593   arma_extra_debug_sigprint();
00594   
00595   return eOpCube<T1, eop_cube_sqrt>(A.get_ref());
00596   }
00597 
00598 
00599 
00600 //
00601 // conj
00602 
00603 template<typename T1>
00604 arma_inline
00605 const T1&
00606 conj(const Base<typename T1::pod_type,T1>& A)
00607   {
00608   arma_extra_debug_sigprint();
00609 
00610   return A.get_ref();
00611   }
00612 
00613 
00614 
00615 template<typename T1>
00616 arma_inline
00617 const T1&
00618 conj(const BaseCube<typename T1::pod_type,T1>& A)
00619   {
00620   arma_extra_debug_sigprint();
00621 
00622   return A.get_ref();
00623   }
00624 
00625 
00626 
00627 template<typename T1>
00628 arma_inline
00629 const eOp<T1, eop_conj>
00630 conj(const Base<std::complex<typename T1::pod_type>,T1>& A)
00631   {
00632   arma_extra_debug_sigprint();
00633 
00634   return eOp<T1, eop_conj>(A.get_ref());
00635   }
00636 
00637 
00638 
00639 template<typename T1>
00640 arma_inline
00641 const eOpCube<T1, eop_cube_conj>
00642 conj(const BaseCube<std::complex<typename T1::pod_type>,T1>& A)
00643   {
00644   arma_extra_debug_sigprint();
00645 
00646   return eOpCube<T1, eop_cube_conj>(A.get_ref());
00647   }
00648 
00649 
00650 
00651 template<typename T1>
00652 arma_inline
00653 const T1&
00654 conj(const eOp<T1, eop_conj>& A)
00655   {
00656   arma_extra_debug_sigprint();
00657   
00658   return A.m;
00659   }
00660 
00661 
00662 
00663 template<typename T1>
00664 arma_inline
00665 const T1&
00666 conj(const eOpCube<T1, eop_cube_conj>& A)
00667   {
00668   arma_extra_debug_sigprint();
00669   
00670   return A.m;
00671   }
00672 
00673 
00674 
00675 // TODO: this needs a more elaborate template restriction mechanism to work properly,
00676 //       i.e. an overloaded version of thus function should do nothing if the input type is non-complex
00677 // 
00678 // //! the conjugate of the transpose of a complex matrix is the same as the hermitian transpose
00679 // template<typename T1>
00680 // arma_inline
00681 // const Op<T1, op_htrans>
00682 // conj(const Op<T1, op_trans>& A)
00683 //   {
00684 //   arma_extra_debug_sigprint();
00685 //   
00686 //   return Op<T1, op_htrans>(A.m);
00687 //   }
00688 
00689 
00690 
00691 // pow
00692 
00693 template<typename T1>
00694 arma_inline
00695 const eOp<T1, eop_pow>
00696 pow(const Base<typename T1::elem_type,T1>& A, const typename T1::elem_type exponent)
00697   {
00698   arma_extra_debug_sigprint();
00699   
00700   return eOp<T1, eop_pow>(A.get_ref(), exponent);
00701   }
00702 
00703 
00704 
00705 template<typename T1>
00706 arma_inline
00707 const eOpCube<T1, eop_cube_pow>
00708 pow(const BaseCube<typename T1::elem_type,T1>& A, const typename T1::elem_type exponent)
00709   {
00710   arma_extra_debug_sigprint();
00711   
00712   return eOpCube<T1, eop_cube_pow>(A.get_ref(), exponent);
00713   }
00714 
00715 
00716 
00717 // pow, specialised handling (non-complex exponent for complex matrices)
00718 
00719 template<typename T1>
00720 arma_inline
00721 const eOp<T1, eop_pow>
00722 pow(const Base<typename T1::elem_type,T1>& A, const typename T1::elem_type::value_type exponent)
00723   {
00724   arma_extra_debug_sigprint();
00725   
00726   typedef typename T1::elem_type eT;
00727   
00728   return eOp<T1, eop_pow>(A.get_ref(), eT(exponent));
00729   }
00730 
00731 
00732 
00733 template<typename T1>
00734 arma_inline
00735 const eOpCube<T1, eop_cube_pow>
00736 pow(const BaseCube<typename T1::elem_type,T1>& A, const typename T1::elem_type::value_type exponent)
00737   {
00738   arma_extra_debug_sigprint();
00739   
00740   typedef typename T1::elem_type eT;
00741   
00742   return eOpCube<T1, eop_cube_pow>(A.get_ref(), eT(exponent));
00743   }
00744 
00745 
00746 
00747 #if defined(ARMA_GOOD_COMPILER)
00748 
00749 
00750 // pow_s32  (integer exponent)
00751 
00752 template<typename T1>
00753 arma_inline
00754 const eOp<T1, eop_pow_int>
00755 pow(const Base<typename T1::elem_type,T1>& A, const int exponent)
00756   {
00757   arma_extra_debug_sigprint();
00758   
00759   if(exponent >= 0)
00760     {
00761     return eOp<T1, eop_pow_int>(A.get_ref(), exponent, 0);
00762     }
00763   else
00764     {
00765     return eOp<T1, eop_pow_int>(A.get_ref(), -exponent, 1);
00766     }
00767   }
00768 
00769 
00770 
00771 template<typename T1>
00772 arma_inline
00773 const eOpCube<T1, eop_cube_pow_int>
00774 pow(const BaseCube<typename T1::elem_type,T1>& A, const int exponent)
00775   {
00776   arma_extra_debug_sigprint();
00777   
00778   if(exponent >= 0)
00779     {
00780     return eOpCube<T1, eop_cube_pow_int>(A.get_ref(),  exponent, 0);
00781     }
00782   else
00783     {
00784     return eOpCube<T1, eop_cube_pow_int>(A.get_ref(), -exponent, 1);
00785     }
00786   }
00787 
00788 
00789 
00790 #endif
00791 
00792 
00793 
00794 //! @}