fn_prod.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2009 NICTA
00002 // 
00003 // Authors:
00004 // - Conrad Sanderson (conradsand at ieee dot org)
00005 // 
00006 // This file is part of the Armadillo C++ library.
00007 // It is provided without any warranty of fitness
00008 // for any purpose. You can redistribute this file
00009 // and/or modify it under the terms of the GNU
00010 // Lesser General Public License (LGPL) as published
00011 // by the Free Software Foundation, either version 3
00012 // of the License or (at your option) any later version.
00013 // (see http://www.opensource.org/licenses for more info)
00014 
00015 
00016 //! \addtogroup fn_prod
00017 //! @{
00018 
00019 
00020 //! \brief
00021 //! Delayed product of elements of a matrix along a specified dimension (either rows or columns).
00022 //! The result is stored in a dense matrix that has either one column or one row.
00023 //! For dim = 0, find the sum of each column (i.e. traverse across rows)
00024 //! For dim = 1, find the sum of each row (i.e. traverse across columns)
00025 //! The default is dim = 0.
00026 //! NOTE: this function works differently than in Matlab/Octave.
00027 
00028 template<typename T1>
00029 inline
00030 const Op<T1, op_prod>
00031 prod(const Base<typename T1::elem_type,T1>& X, const u32 dim = 0)
00032   {
00033   arma_extra_debug_sigprint();
00034   
00035   return Op<T1, op_prod>(X.get_ref(), dim, 0);
00036   }
00037 
00038 
00039 
00040 //! \brief
00041 //! Immediate 'product of all values' operation for a row vector
00042 template<typename eT>
00043 inline
00044 eT
00045 prod(const Row<eT>& X)
00046   {
00047   arma_extra_debug_sigprint();
00048   
00049   arma_debug_check( (X.n_elem < 1), "prod(): given object has no elements" );
00050   
00051   const u32 n_elem = X.n_elem;
00052   const eT* X_mem  = X.memptr();
00053   
00054   eT val = X_mem[0];
00055   
00056   for(u32 i=1; i<n_elem; ++i)
00057     {
00058     val *= X_mem[i];
00059     }
00060   
00061   return val;
00062   }
00063 
00064 
00065 
00066 //! \brief
00067 //! Immediate 'product of all values' operation for a column vector
00068 template<typename eT>
00069 inline
00070 eT
00071 prod(const Col<eT>& X)
00072   {
00073   arma_extra_debug_sigprint();
00074   
00075   arma_debug_check( (X.n_elem < 1), "prod(): given object has no elements" );
00076   
00077   const u32 n_elem = X.n_elem;
00078   const eT* X_mem  = X.memptr();
00079   
00080   eT val = X_mem[0];
00081   
00082   for(u32 i=1; i<n_elem; ++i)
00083     {
00084     val *= X_mem[i];
00085     }
00086   
00087   return val;
00088   }
00089 
00090 
00091 
00092 //! \brief
00093 //! Immediate 'product of all values' operation,
00094 //! invoked, for example, by: prod(prod(A))
00095 
00096 template<typename T1>
00097 inline
00098 typename T1::elem_type
00099 prod(const Op<T1, op_prod>& in)
00100   {
00101   arma_extra_debug_sigprint();
00102   arma_extra_debug_print("prod(): two consecutive prod() calls detected");
00103   
00104   typedef typename T1::elem_type eT;
00105   
00106   const unwrap<T1>   tmp(in.m);
00107   const Mat<eT>& X = tmp.M;
00108   
00109   arma_debug_check( (X.n_elem < 1), "prod(): given object has no elements" );
00110   
00111   const u32 n_elem = X.n_elem;
00112   const eT* X_mem  = X.memptr();
00113   
00114   eT val = X_mem[0];
00115   
00116   for(u32 i=1; i<n_elem; ++i)
00117     {
00118     val *= X_mem[i];
00119     }
00120   
00121   return val;
00122   }
00123 
00124 
00125 
00126 template<typename T1>
00127 inline
00128 const Op<Op<T1, op_prod>, op_prod>
00129 prod(const Op<T1, op_prod>& in, const u32 dim)
00130   {
00131   arma_extra_debug_sigprint();
00132   
00133   return Op<Op<T1, op_prod>, op_prod>(in, dim, 0);
00134   }
00135 
00136 
00137 
00138 //! product of all values of a subview_row
00139 template<typename eT>
00140 inline
00141 eT
00142 prod(const subview_row<eT>& S)
00143   {
00144   arma_extra_debug_sigprint();
00145   
00146   arma_debug_check( (S.n_elem < 1), "prod(): given object has no elements" );
00147   
00148   const Mat<eT>& X = S.m;
00149   
00150   const u32 row       = S.aux_row1;
00151   const u32 start_col = S.aux_col1;
00152   const u32 end_col   = S.aux_col2;
00153   
00154   eT val = X.at(row,start_col);
00155   
00156   for(u32 col=start_col+1; col<=end_col; ++col)
00157     {
00158     val *= X.at(row,col);
00159     }
00160   
00161   return val;
00162   }
00163 
00164 
00165 
00166 //! product of all values of a subview_col
00167 template<typename eT>
00168 inline
00169 eT
00170 prod(const subview_col<eT>& S)
00171   {
00172   arma_extra_debug_sigprint();
00173   
00174   arma_debug_check( (S.n_elem < 1), "prod(): given object has no elements" );
00175   
00176   const eT* S_colptr = S.colptr(0);
00177   const u32 n_rows   = S.n_rows;
00178   
00179   eT val = S_colptr[0];
00180   
00181   for(u32 row=1; row<n_rows; ++row)
00182     {
00183     val *= S_colptr[row];
00184     }
00185   
00186   return val;
00187   }
00188 
00189 
00190 
00191 //! product of all values of a diagview
00192 template<typename eT>
00193 inline
00194 eT
00195 prod(const diagview<eT>& X)
00196   {
00197   arma_extra_debug_sigprint();
00198   
00199   arma_debug_check( (X.n_elem < 1), "prod(): given object has no elements" );
00200   
00201   const u32 n_elem = X.n_elem;
00202   
00203   eT val = X[0];
00204   
00205   for(u32 i=1; i<n_elem; ++i)
00206     {
00207     val *= X[i];
00208     }
00209   
00210   return val;
00211   }
00212 
00213 
00214 
00215 //! @}