Chris@49
|
1 // Copyright (C) 2009-2012 NICTA (www.nicta.com.au)
|
Chris@49
|
2 // Copyright (C) 2009-2012 Conrad Sanderson
|
Chris@49
|
3 // Copyright (C) 2012 Ryan Curtin
|
Chris@49
|
4 //
|
Chris@49
|
5 // This Source Code Form is subject to the terms of the Mozilla Public
|
Chris@49
|
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
|
Chris@49
|
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
Chris@49
|
8
|
Chris@49
|
9
|
Chris@49
|
10 //! \addtogroup operator_div
|
Chris@49
|
11 //! @{
|
Chris@49
|
12
|
Chris@49
|
13
|
Chris@49
|
14
|
Chris@49
|
15 //! Base / scalar
|
Chris@49
|
16 template<typename T1>
|
Chris@49
|
17 arma_inline
|
Chris@49
|
18 typename
|
Chris@49
|
19 enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_div_post> >::result
|
Chris@49
|
20 operator/
|
Chris@49
|
21 (
|
Chris@49
|
22 const T1& X,
|
Chris@49
|
23 const typename T1::elem_type k
|
Chris@49
|
24 )
|
Chris@49
|
25 {
|
Chris@49
|
26 arma_extra_debug_sigprint();
|
Chris@49
|
27
|
Chris@49
|
28 return eOp<T1, eop_scalar_div_post>(X, k);
|
Chris@49
|
29 }
|
Chris@49
|
30
|
Chris@49
|
31
|
Chris@49
|
32
|
Chris@49
|
33 //! scalar / Base
|
Chris@49
|
34 template<typename T1>
|
Chris@49
|
35 arma_inline
|
Chris@49
|
36 typename
|
Chris@49
|
37 enable_if2< is_arma_type<T1>::value, const eOp<T1, eop_scalar_div_pre> >::result
|
Chris@49
|
38 operator/
|
Chris@49
|
39 (
|
Chris@49
|
40 const typename T1::elem_type k,
|
Chris@49
|
41 const T1& X
|
Chris@49
|
42 )
|
Chris@49
|
43 {
|
Chris@49
|
44 arma_extra_debug_sigprint();
|
Chris@49
|
45
|
Chris@49
|
46 return eOp<T1, eop_scalar_div_pre>(X, k);
|
Chris@49
|
47 }
|
Chris@49
|
48
|
Chris@49
|
49
|
Chris@49
|
50
|
Chris@49
|
51 //! complex scalar / non-complex Base
|
Chris@49
|
52 template<typename T1>
|
Chris@49
|
53 arma_inline
|
Chris@49
|
54 typename
|
Chris@49
|
55 enable_if2
|
Chris@49
|
56 <
|
Chris@49
|
57 (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
|
Chris@49
|
58 const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>
|
Chris@49
|
59 >::result
|
Chris@49
|
60 operator/
|
Chris@49
|
61 (
|
Chris@49
|
62 const std::complex<typename T1::pod_type>& k,
|
Chris@49
|
63 const T1& X
|
Chris@49
|
64 )
|
Chris@49
|
65 {
|
Chris@49
|
66 arma_extra_debug_sigprint();
|
Chris@49
|
67
|
Chris@49
|
68 return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_pre>('j', X, k);
|
Chris@49
|
69 }
|
Chris@49
|
70
|
Chris@49
|
71
|
Chris@49
|
72
|
Chris@49
|
73 //! non-complex Base / complex scalar
|
Chris@49
|
74 template<typename T1>
|
Chris@49
|
75 arma_inline
|
Chris@49
|
76 typename
|
Chris@49
|
77 enable_if2
|
Chris@49
|
78 <
|
Chris@49
|
79 (is_arma_type<T1>::value && is_complex<typename T1::elem_type>::value == false),
|
Chris@49
|
80 const mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>
|
Chris@49
|
81 >::result
|
Chris@49
|
82 operator/
|
Chris@49
|
83 (
|
Chris@49
|
84 const T1& X,
|
Chris@49
|
85 const std::complex<typename T1::pod_type>& k
|
Chris@49
|
86 )
|
Chris@49
|
87 {
|
Chris@49
|
88 arma_extra_debug_sigprint();
|
Chris@49
|
89
|
Chris@49
|
90 return mtOp<typename std::complex<typename T1::pod_type>, T1, op_cx_scalar_div_post>('j', X, k);
|
Chris@49
|
91 }
|
Chris@49
|
92
|
Chris@49
|
93
|
Chris@49
|
94
|
Chris@49
|
95 //! element-wise division of Base objects with same element type
|
Chris@49
|
96 template<typename T1, typename T2>
|
Chris@49
|
97 arma_inline
|
Chris@49
|
98 typename
|
Chris@49
|
99 enable_if2
|
Chris@49
|
100 <
|
Chris@49
|
101 (is_arma_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
|
Chris@49
|
102 const eGlue<T1, T2, eglue_div>
|
Chris@49
|
103 >::result
|
Chris@49
|
104 operator/
|
Chris@49
|
105 (
|
Chris@49
|
106 const T1& X,
|
Chris@49
|
107 const T2& Y
|
Chris@49
|
108 )
|
Chris@49
|
109 {
|
Chris@49
|
110 arma_extra_debug_sigprint();
|
Chris@49
|
111
|
Chris@49
|
112 return eGlue<T1, T2, eglue_div>(X, Y);
|
Chris@49
|
113 }
|
Chris@49
|
114
|
Chris@49
|
115
|
Chris@49
|
116
|
Chris@49
|
117 //! element-wise division of Base objects with different element types
|
Chris@49
|
118 template<typename T1, typename T2>
|
Chris@49
|
119 inline
|
Chris@49
|
120 typename
|
Chris@49
|
121 enable_if2
|
Chris@49
|
122 <
|
Chris@49
|
123 (is_arma_type<T1>::value && is_arma_type<T2>::value && (is_same_type<typename T1::elem_type, typename T2::elem_type>::value == false)),
|
Chris@49
|
124 const mtGlue<typename promote_type<typename T1::elem_type, typename T2::elem_type>::result, T1, T2, glue_mixed_div>
|
Chris@49
|
125 >::result
|
Chris@49
|
126 operator/
|
Chris@49
|
127 (
|
Chris@49
|
128 const T1& X,
|
Chris@49
|
129 const T2& Y
|
Chris@49
|
130 )
|
Chris@49
|
131 {
|
Chris@49
|
132 arma_extra_debug_sigprint();
|
Chris@49
|
133
|
Chris@49
|
134 typedef typename T1::elem_type eT1;
|
Chris@49
|
135 typedef typename T2::elem_type eT2;
|
Chris@49
|
136
|
Chris@49
|
137 typedef typename promote_type<eT1,eT2>::result out_eT;
|
Chris@49
|
138
|
Chris@49
|
139 promote_type<eT1,eT2>::check();
|
Chris@49
|
140
|
Chris@49
|
141 return mtGlue<out_eT, T1, T2, glue_mixed_div>( X, Y );
|
Chris@49
|
142 }
|
Chris@49
|
143
|
Chris@49
|
144
|
Chris@49
|
145
|
Chris@49
|
146 //! element-wise division of sparse matrix by scalar
|
Chris@49
|
147 template<typename T1>
|
Chris@49
|
148 inline
|
Chris@49
|
149 typename
|
Chris@49
|
150 enable_if2<is_arma_sparse_type<T1>::value, SpMat<typename T1::elem_type> >::result
|
Chris@49
|
151 operator/
|
Chris@49
|
152 (
|
Chris@49
|
153 const T1& X,
|
Chris@49
|
154 const typename T1::elem_type y
|
Chris@49
|
155 )
|
Chris@49
|
156 {
|
Chris@49
|
157 arma_extra_debug_sigprint();
|
Chris@49
|
158
|
Chris@49
|
159 SpMat<typename T1::elem_type> result(X);
|
Chris@49
|
160
|
Chris@49
|
161 result /= y;
|
Chris@49
|
162
|
Chris@49
|
163 return result;
|
Chris@49
|
164 }
|
Chris@49
|
165
|
Chris@49
|
166
|
Chris@49
|
167
|
Chris@49
|
168 //! element-wise division of one sparse and one dense object
|
Chris@49
|
169 template<typename T1, typename T2>
|
Chris@49
|
170 inline
|
Chris@49
|
171 typename
|
Chris@49
|
172 enable_if2
|
Chris@49
|
173 <
|
Chris@49
|
174 (is_arma_sparse_type<T1>::value && is_arma_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
|
Chris@49
|
175 SpMat<typename T1::elem_type>
|
Chris@49
|
176 >::result
|
Chris@49
|
177 operator/
|
Chris@49
|
178 (
|
Chris@49
|
179 const T1& x,
|
Chris@49
|
180 const T2& y
|
Chris@49
|
181 )
|
Chris@49
|
182 {
|
Chris@49
|
183 arma_extra_debug_sigprint();
|
Chris@49
|
184
|
Chris@49
|
185 typedef typename T1::elem_type eT;
|
Chris@49
|
186
|
Chris@49
|
187 const SpProxy<T1> pa(x);
|
Chris@49
|
188 const Proxy<T2> pb(y);
|
Chris@49
|
189
|
Chris@49
|
190 const uword n_rows = pa.get_n_rows();
|
Chris@49
|
191 const uword n_cols = pa.get_n_cols();
|
Chris@49
|
192
|
Chris@49
|
193 arma_debug_assert_same_size(n_rows, n_cols, pb.get_n_rows(), pb.get_n_cols(), "element-wise division");
|
Chris@49
|
194
|
Chris@49
|
195 SpMat<eT> result(n_rows, n_cols);
|
Chris@49
|
196
|
Chris@49
|
197 uword new_n_nonzero = 0;
|
Chris@49
|
198
|
Chris@49
|
199 for(uword col=0; col < n_cols; ++col)
|
Chris@49
|
200 for(uword row=0; row < n_rows; ++row)
|
Chris@49
|
201 {
|
Chris@49
|
202 const eT val = pa.at(row,col) / pb.at(row, col);
|
Chris@49
|
203
|
Chris@49
|
204 if(val != eT(0))
|
Chris@49
|
205 {
|
Chris@49
|
206 ++new_n_nonzero;
|
Chris@49
|
207 }
|
Chris@49
|
208 }
|
Chris@49
|
209
|
Chris@49
|
210 result.mem_resize(new_n_nonzero);
|
Chris@49
|
211
|
Chris@49
|
212 uword cur_pos = 0;
|
Chris@49
|
213
|
Chris@49
|
214 for(uword col=0; col < n_cols; ++col)
|
Chris@49
|
215 for(uword row=0; row < n_rows; ++row)
|
Chris@49
|
216 {
|
Chris@49
|
217 const eT val = pa.at(row,col) / pb.at(row, col);
|
Chris@49
|
218
|
Chris@49
|
219 if(val != eT(0))
|
Chris@49
|
220 {
|
Chris@49
|
221 access::rw(result.values[cur_pos]) = val;
|
Chris@49
|
222 access::rw(result.row_indices[cur_pos]) = row;
|
Chris@49
|
223 ++access::rw(result.col_ptrs[col + 1]);
|
Chris@49
|
224 ++cur_pos;
|
Chris@49
|
225 }
|
Chris@49
|
226 }
|
Chris@49
|
227
|
Chris@49
|
228 // Fix column pointers
|
Chris@49
|
229 for(uword col = 1; col <= result.n_cols; ++col)
|
Chris@49
|
230 {
|
Chris@49
|
231 access::rw(result.col_ptrs[col]) += result.col_ptrs[col - 1];
|
Chris@49
|
232 }
|
Chris@49
|
233
|
Chris@49
|
234 return result;
|
Chris@49
|
235 }
|
Chris@49
|
236
|
Chris@49
|
237
|
Chris@49
|
238
|
Chris@49
|
239 //! element-wise division of one dense and one sparse object
|
Chris@49
|
240 template<typename T1, typename T2>
|
Chris@49
|
241 inline
|
Chris@49
|
242 typename
|
Chris@49
|
243 enable_if2
|
Chris@49
|
244 <
|
Chris@49
|
245 (is_arma_type<T1>::value && is_arma_sparse_type<T2>::value && is_same_type<typename T1::elem_type, typename T2::elem_type>::value),
|
Chris@49
|
246 Mat<typename T1::elem_type>
|
Chris@49
|
247 >::result
|
Chris@49
|
248 operator/
|
Chris@49
|
249 (
|
Chris@49
|
250 const T1& x,
|
Chris@49
|
251 const T2& y
|
Chris@49
|
252 )
|
Chris@49
|
253 {
|
Chris@49
|
254 arma_extra_debug_sigprint();
|
Chris@49
|
255
|
Chris@49
|
256 typedef typename T1::elem_type eT;
|
Chris@49
|
257
|
Chris@49
|
258 const Proxy<T1> pa(x);
|
Chris@49
|
259 const SpProxy<T2> pb(y);
|
Chris@49
|
260
|
Chris@49
|
261 const uword n_rows = pa.get_n_rows();
|
Chris@49
|
262 const uword n_cols = pa.get_n_cols();
|
Chris@49
|
263
|
Chris@49
|
264 arma_debug_assert_same_size(n_rows, n_cols, pb.get_n_rows(), pb.get_n_cols(), "element-wise division");
|
Chris@49
|
265
|
Chris@49
|
266 Mat<eT> result(n_rows, n_cols);
|
Chris@49
|
267
|
Chris@49
|
268 for(uword col=0; col < n_cols; ++col)
|
Chris@49
|
269 for(uword row=0; row < n_rows; ++row)
|
Chris@49
|
270 {
|
Chris@49
|
271 result.at(row, col) = pa.at(row, col) / pb.at(row, col);
|
Chris@49
|
272 }
|
Chris@49
|
273
|
Chris@49
|
274 return result;
|
Chris@49
|
275 }
|
Chris@49
|
276
|
Chris@49
|
277
|
Chris@49
|
278
|
Chris@49
|
279 //! @}
|