00001 /*! \file rowcolfunc.h 00002 \brief Functions which apply a function object over rows or columns of a matrix. 00003 00004 Contains definitions of functions apply_rows, apply_columns, over_rows, over_columns 00005 which apply a function object over the rows or columns of a matrix. 00006 00007 */ 00008 00009 /* 00010 00011 Simple C++ Numerical Toolkit (SCPPNT) 00012 http://www.smallwaters.com/software/cpp/scppnt.html 00013 This release updates original work contributed by 00014 Brad Hanson (http://www.b-a-h.com/) in 2001. 00015 00016 */ 00017 00018 #ifndef SCPPNT_ROWCOLFUNC_H 00019 #define SCPPNT_ROWCOLFUNC_H 00020 00021 #ifdef SCPPNT_NO_DIR_PREFIX 00022 #include "scppnt.h" 00023 #else 00024 #include "scppnt/scppnt.h" 00025 #endif 00026 00027 namespace SCPPNT 00028 { 00029 00030 /*! \brief Apply a function object to each row of a matrix. 00031 00032 Applies the function object f to each row of a matrix. 00033 f can modify the elements of a row. 00034 00035 Here is an example of using apply_rows: 00036 00037 #include "scppnt/cmat.h" 00038 #include "scppnt/rowcolfunc.h" 00039 #include <iterator> 00040 00041 using namespace SCPPNT; 00042 00043 // Function object that standardizes a sequence of elements to sum to 1. 00044 template <class IT> 00045 class Standardize { 00046 public: 00047 void operator ()(Subscript num_elements, IT iterator) { 00048 typename std::iterator_traits<IT>::value_type sum = 0; 00049 Subscript n = num_elements; 00050 IT it = iterator; 00051 for (; n--; ++it) sum += *it; 00052 for (it = iterator; num_elements--; ++it) *it /= sum; 00053 } 00054 }; 00055 00056 Matrix<double> m(2, 2, "1.0 2.0 3.0 4.0"); 00057 00058 // Standardize each row of m to sum to 1 00059 apply_rows(m, f); 00060 Standardize<Matrix<double>::row_iterator> f; 00061 */ 00062 template<class M, class FUNC> void apply_rows(M &matrix, FUNC &f) 00063 { 00064 typename M::rows_iterator irows = matrix.begin_rows(); 00065 00066 Subscript ncolumns = matrix.num_columns(); 00067 00068 for (Subscript i = matrix.num_rows(); i--; ++irows) 00069 { 00070 f(ncolumns, *irows); 00071 } 00072 } 00073 00074 /*! \brief Apply a function object to each column of a matrix. 00075 00076 Applies the function object f to each column of a matrix. 00077 f can modify the elements of a column. 00078 00079 Here is an example of using apply_columns: 00080 00081 #include "scppnt/cmat.h" 00082 #include "scppnt/rowcolfunc.h" 00083 #include <iterator> 00084 00085 using namespace SCPPNT; 00086 00087 // Function object that standardizes a sequence of elements to sum to 1. 00088 template <class IT> 00089 class Standardize { 00090 public: 00091 void operator ()(Subscript num_elements, IT iterator) { 00092 typename std::iterator_traits<IT>::value_type sum = 0; 00093 Subscript n = num_elements; 00094 IT it = iterator; 00095 for (; n--; ++it) sum += *it; 00096 for (it = iterator; num_elements--; ++it) *it /= sum; 00097 } 00098 }; 00099 00100 Matrix<double> m(2, 2, "1.0 2.0 3.0 4.0"); 00101 00102 // Standardize each column of m to sum to 1 00103 Standardize<Matrix<double>::column_iterator> f; 00104 apply_columns(m, f); 00105 */ 00106 template<class M, class FUNC> void apply_columns(M &matrix, FUNC &f) 00107 { 00108 typename M::columns_iterator icolumns = matrix.begin_columns(); 00109 00110 Subscript nrows = matrix.num_rows(); 00111 00112 for (Subscript i = matrix.num_columns(); i--; ++icolumns) 00113 { 00114 f(nrows, *icolumns); 00115 } 00116 } 00117 00118 /*! \bried Apply a function object to each row of a matrix to produce a scalar, and return a vector containing these scalars. 00119 00120 Apply a function to each row of a matrix that returns a single value 00121 (the function is applied over columns of each row). These values are 00122 put into a vector that is returned (the number of elements in the 00123 vector is the number of rows in the matrix). 00124 00125 Here is an example of using over_columns: 00126 00127 #include "scppnt/cmat.h" 00128 #include "scppnt/vec.h" 00129 #include "scppnt/rowcolfunc.h" 00130 #include <iterator> 00131 00132 using namespace SCPPNT; 00133 00134 // Function object that returns the sum of each element of an array. 00135 template <class IT> 00136 class Sum { 00137 public: 00138 typename std::iterator_traits<IT>::value_type operator ()(Subscript num_elements, IT iterator) { 00139 typename std::iterator_traits<IT>::value_type sum = 0; 00140 for(; num_element--; ++iterator) sum += *iterator; 00141 } 00142 }; 00143 00144 Matrix<double> m(2, 2, "1.0 2.0 3.0 4.0"); 00145 00146 // Get sum of each column of m 00147 Sum<Matrix<double>::row_iterator> f; 00148 Vector<double> sums = over_columns<Matrix<double>,Vector<double>,Sum>(m, f); 00149 */ 00150 template<class M, class V, class FUNC> V over_columns(M &matrix, FUNC &f) 00151 { 00152 typename M::rows_iterator irows = matrix.begin_rows(); 00153 V vec(matrix.num_rows()); 00154 00155 Subscript ncolumns = matrix.num_columns(); 00156 00157 typename V::iterator iv = vec.begin(); 00158 for (Subscript i = matrix.num_rows(); i--; ++irows, ++iv) 00159 { 00160 *iv = f(ncolumns, *irows); 00161 } 00162 00163 return vec; 00164 } 00165 00166 /*! \bried Apply a function object to each column of a matrix to produce a scalar, and return a vector containing these scalars. 00167 00168 Apply a function to each column of a matrix that returns a single value 00169 (the function is applied over rows of each column). These values are 00170 put into a vector that is returned (the number of elements in the 00171 vector is the number of columns in the matrix). 00172 00173 Here is an example of using over_rows: 00174 00175 #include "scppnt/cmat.h" 00176 #include "scppnt/vec.h" 00177 #include "scppnt/rowcolfunc.h" 00178 #include <iterator> 00179 00180 using namespace SCPPNT; 00181 00182 // Function object that returns the sum of each element of an array. 00183 template <class IT> 00184 class Sum { 00185 public: 00186 typename std::iterator_traits<IT>::value_type operator ()(Subscript num_elements, IT iterator) { 00187 typename std::iterator_traits<IT>::value_type sum = 0; 00188 for(; num_element--; ++iterator) sum += *iterator; 00189 } 00190 }; 00191 00192 Matrix<double> m(2, 2, "1.0 2.0 3.0 4.0"); 00193 00194 // Get sum of each row of m 00195 Sum<Matrix<double>::column_iterator> f; 00196 Vector<double> sums = over_columns<Matrix<double>,Vector<double>,Sum>(m, f); 00197 */ 00198 template<class M, class V, class FUNC> V over_rows(M &matrix, FUNC &f) 00199 { 00200 typename M::columns_iterator icolumns = matrix.begin_columns(); 00201 V vec(matrix.num_columns()); 00202 00203 Subscript nrows = matrix.num_rows(); 00204 00205 typename V::iterator iv = vec.begin(); 00206 for (Subscript i = matrix.num_columns(); i--; ++icolumns, ++iv) 00207 { 00208 *iv = f(nrows, *icolumns); 00209 } 00210 00211 return vec; 00212 } 00213 } // namespace SCPPNT 00214 00215 #endif // SCPPNT_ROWCOLFUNC_H