Chris@49
|
1 // Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
|
Chris@49
|
2 // Copyright (C) 2009-2012 Conrad Sanderson
|
Chris@49
|
3 //
|
Chris@49
|
4 // This Source Code Form is subject to the terms of the Mozilla Public
|
Chris@49
|
5 // License, v. 2.0. If a copy of the MPL was not distributed with this
|
Chris@49
|
6 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
Chris@49
|
7
|
Chris@49
|
8
|
Chris@49
|
9 //! \addtogroup op_prod
|
Chris@49
|
10 //! @{
|
Chris@49
|
11
|
Chris@49
|
12 //! \brief
|
Chris@49
|
13 //! Immediate product of elements of a matrix along a specified dimension (either rows or columns).
|
Chris@49
|
14 //! The result is stored in a dense matrix that has either one column or one row.
|
Chris@49
|
15 //! See the prod() function for more details.
|
Chris@49
|
16 template<typename T1>
|
Chris@49
|
17 inline
|
Chris@49
|
18 void
|
Chris@49
|
19 op_prod::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_prod>& in)
|
Chris@49
|
20 {
|
Chris@49
|
21 arma_extra_debug_sigprint();
|
Chris@49
|
22
|
Chris@49
|
23 typedef typename T1::elem_type eT;
|
Chris@49
|
24
|
Chris@49
|
25 const uword dim = in.aux_uword_a;
|
Chris@49
|
26 arma_debug_check( (dim > 1), "prod(): incorrect usage. dim must be 0 or 1");
|
Chris@49
|
27
|
Chris@49
|
28 const unwrap_check<T1> tmp(in.m, out);
|
Chris@49
|
29 const Mat<eT>& X = tmp.M;
|
Chris@49
|
30
|
Chris@49
|
31 const uword X_n_rows = X.n_rows;
|
Chris@49
|
32 const uword X_n_cols = X.n_cols;
|
Chris@49
|
33
|
Chris@49
|
34 if(dim == 0) // traverse across rows (i.e. find the product in each column)
|
Chris@49
|
35 {
|
Chris@49
|
36 out.set_size(1, X_n_cols);
|
Chris@49
|
37
|
Chris@49
|
38 eT* out_mem = out.memptr();
|
Chris@49
|
39
|
Chris@49
|
40 for(uword col=0; col<X_n_cols; ++col)
|
Chris@49
|
41 {
|
Chris@49
|
42 out_mem[col] = arrayops::product(X.colptr(col), X_n_rows);
|
Chris@49
|
43 }
|
Chris@49
|
44 }
|
Chris@49
|
45 else // traverse across columns (i.e. find the product in each row)
|
Chris@49
|
46 {
|
Chris@49
|
47 out.set_size(X_n_rows, 1);
|
Chris@49
|
48
|
Chris@49
|
49 eT* out_mem = out.memptr();
|
Chris@49
|
50
|
Chris@49
|
51 for(uword row=0; row<X_n_rows; ++row)
|
Chris@49
|
52 {
|
Chris@49
|
53 eT val = eT(1);
|
Chris@49
|
54
|
Chris@49
|
55 uword i,j;
|
Chris@49
|
56 for(i=0, j=1; j < X_n_cols; i+=2, j+=2)
|
Chris@49
|
57 {
|
Chris@49
|
58 val *= X.at(row,i);
|
Chris@49
|
59 val *= X.at(row,j);
|
Chris@49
|
60 }
|
Chris@49
|
61
|
Chris@49
|
62 if(i < X_n_cols)
|
Chris@49
|
63 {
|
Chris@49
|
64 val *= X.at(row,i);
|
Chris@49
|
65 }
|
Chris@49
|
66
|
Chris@49
|
67 out_mem[row] = val;
|
Chris@49
|
68 }
|
Chris@49
|
69 }
|
Chris@49
|
70 }
|
Chris@49
|
71
|
Chris@49
|
72
|
Chris@49
|
73
|
Chris@49
|
74 template<typename eT>
|
Chris@49
|
75 inline
|
Chris@49
|
76 eT
|
Chris@49
|
77 op_prod::prod(const subview<eT>& X)
|
Chris@49
|
78 {
|
Chris@49
|
79 arma_extra_debug_sigprint();
|
Chris@49
|
80
|
Chris@49
|
81 eT val = eT(1);
|
Chris@49
|
82
|
Chris@49
|
83 const uword X_n_rows = X.n_rows;
|
Chris@49
|
84 const uword X_n_cols = X.n_cols;
|
Chris@49
|
85
|
Chris@49
|
86 if(X_n_rows == 1)
|
Chris@49
|
87 {
|
Chris@49
|
88 const Mat<eT>& A = X.m;
|
Chris@49
|
89
|
Chris@49
|
90 const uword start_row = X.aux_row1;
|
Chris@49
|
91 const uword start_col = X.aux_col1;
|
Chris@49
|
92
|
Chris@49
|
93 const uword end_col_p1 = start_col + X_n_cols;
|
Chris@49
|
94
|
Chris@49
|
95 uword i,j;
|
Chris@49
|
96 for(i=start_col, j=start_col+1; j < end_col_p1; i+=2, j+=2)
|
Chris@49
|
97 {
|
Chris@49
|
98 val *= A.at(start_row, i);
|
Chris@49
|
99 val *= A.at(start_row, j);
|
Chris@49
|
100 }
|
Chris@49
|
101
|
Chris@49
|
102 if(i < end_col_p1)
|
Chris@49
|
103 {
|
Chris@49
|
104 val *= A.at(start_row, i);
|
Chris@49
|
105 }
|
Chris@49
|
106 }
|
Chris@49
|
107 else
|
Chris@49
|
108 {
|
Chris@49
|
109 for(uword col=0; col < X_n_cols; ++col)
|
Chris@49
|
110 {
|
Chris@49
|
111 val *= arrayops::product( X.colptr(col), X_n_rows );
|
Chris@49
|
112 }
|
Chris@49
|
113 }
|
Chris@49
|
114
|
Chris@49
|
115 return val;
|
Chris@49
|
116 }
|
Chris@49
|
117
|
Chris@49
|
118
|
Chris@49
|
119
|
Chris@49
|
120 template<typename T1>
|
Chris@49
|
121 inline
|
Chris@49
|
122 typename T1::elem_type
|
Chris@49
|
123 op_prod::prod(const Base<typename T1::elem_type,T1>& X)
|
Chris@49
|
124 {
|
Chris@49
|
125 arma_extra_debug_sigprint();
|
Chris@49
|
126
|
Chris@49
|
127 typedef typename T1::elem_type eT;
|
Chris@49
|
128
|
Chris@49
|
129 const Proxy<T1> P(X.get_ref());
|
Chris@49
|
130
|
Chris@49
|
131 eT val = eT(1);
|
Chris@49
|
132
|
Chris@49
|
133 if(Proxy<T1>::prefer_at_accessor == false)
|
Chris@49
|
134 {
|
Chris@49
|
135 typedef typename Proxy<T1>::ea_type ea_type;
|
Chris@49
|
136
|
Chris@49
|
137 const ea_type A = P.get_ea();
|
Chris@49
|
138
|
Chris@49
|
139 const uword n_elem = P.get_n_elem();
|
Chris@49
|
140
|
Chris@49
|
141 uword i,j;
|
Chris@49
|
142 for(i=0, j=1; j < n_elem; i+=2, j+=2)
|
Chris@49
|
143 {
|
Chris@49
|
144 val *= A[i];
|
Chris@49
|
145 val *= A[j];
|
Chris@49
|
146 }
|
Chris@49
|
147
|
Chris@49
|
148 if(i < n_elem)
|
Chris@49
|
149 {
|
Chris@49
|
150 val *= A[i];
|
Chris@49
|
151 }
|
Chris@49
|
152 }
|
Chris@49
|
153 else
|
Chris@49
|
154 {
|
Chris@49
|
155 const uword n_rows = P.get_n_rows();
|
Chris@49
|
156 const uword n_cols = P.get_n_cols();
|
Chris@49
|
157
|
Chris@49
|
158 if(n_rows == 1)
|
Chris@49
|
159 {
|
Chris@49
|
160 uword i,j;
|
Chris@49
|
161 for(i=0, j=1; j < n_cols; i+=2, j+=2)
|
Chris@49
|
162 {
|
Chris@49
|
163 val *= P.at(0,i);
|
Chris@49
|
164 val *= P.at(0,j);
|
Chris@49
|
165 }
|
Chris@49
|
166
|
Chris@49
|
167 if(i < n_cols)
|
Chris@49
|
168 {
|
Chris@49
|
169 val *= P.at(0,i);
|
Chris@49
|
170 }
|
Chris@49
|
171 }
|
Chris@49
|
172 else
|
Chris@49
|
173 {
|
Chris@49
|
174 for(uword col=0; col < n_cols; ++col)
|
Chris@49
|
175 {
|
Chris@49
|
176 uword i,j;
|
Chris@49
|
177 for(i=0, j=1; j < n_rows; i+=2, j+=2)
|
Chris@49
|
178 {
|
Chris@49
|
179 val *= P.at(i,col);
|
Chris@49
|
180 val *= P.at(j,col);
|
Chris@49
|
181 }
|
Chris@49
|
182
|
Chris@49
|
183 if(i < n_rows)
|
Chris@49
|
184 {
|
Chris@49
|
185 val *= P.at(i,col);
|
Chris@49
|
186 }
|
Chris@49
|
187 }
|
Chris@49
|
188 }
|
Chris@49
|
189 }
|
Chris@49
|
190
|
Chris@49
|
191 return val;
|
Chris@49
|
192 }
|
Chris@49
|
193
|
Chris@49
|
194
|
Chris@49
|
195
|
Chris@49
|
196 //! @}
|