Chris@49
|
1 // Copyright (C) 2011-2013 NICTA (www.nicta.com.au)
|
Chris@49
|
2 // Copyright (C) 2011-2013 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 Gen
|
Chris@49
|
10 //! @{
|
Chris@49
|
11
|
Chris@49
|
12
|
Chris@49
|
13
|
Chris@49
|
14 template<typename T1, typename gen_type>
|
Chris@49
|
15 arma_inline
|
Chris@49
|
16 Gen<T1, gen_type>::Gen(const uword in_n_rows, const uword in_n_cols)
|
Chris@49
|
17 : n_rows(in_n_rows)
|
Chris@49
|
18 , n_cols(in_n_cols)
|
Chris@49
|
19 {
|
Chris@49
|
20 arma_extra_debug_sigprint();
|
Chris@49
|
21 }
|
Chris@49
|
22
|
Chris@49
|
23
|
Chris@49
|
24
|
Chris@49
|
25 template<typename T1, typename gen_type>
|
Chris@49
|
26 arma_inline
|
Chris@49
|
27 Gen<T1, gen_type>::~Gen()
|
Chris@49
|
28 {
|
Chris@49
|
29 arma_extra_debug_sigprint();
|
Chris@49
|
30 }
|
Chris@49
|
31
|
Chris@49
|
32
|
Chris@49
|
33
|
Chris@49
|
34 template<typename T1, typename gen_type>
|
Chris@49
|
35 arma_inline
|
Chris@49
|
36 typename T1::elem_type
|
Chris@49
|
37 Gen<T1, gen_type>::generate()
|
Chris@49
|
38 {
|
Chris@49
|
39 typedef typename T1::elem_type eT;
|
Chris@49
|
40
|
Chris@49
|
41 if(is_same_type<gen_type, gen_ones_full>::value == true) { return eT(1); }
|
Chris@49
|
42 else if(is_same_type<gen_type, gen_zeros >::value == true) { return eT(0); }
|
Chris@49
|
43 else if(is_same_type<gen_type, gen_randu >::value == true) { return eT(eop_aux_randu<eT>()); }
|
Chris@49
|
44 else if(is_same_type<gen_type, gen_randn >::value == true) { return eT(eop_aux_randn<eT>()); }
|
Chris@49
|
45 else { return eT(); }
|
Chris@49
|
46 }
|
Chris@49
|
47
|
Chris@49
|
48
|
Chris@49
|
49
|
Chris@49
|
50 template<typename T1, typename gen_type>
|
Chris@49
|
51 arma_inline
|
Chris@49
|
52 typename T1::elem_type
|
Chris@49
|
53 Gen<T1, gen_type>::operator[](const uword ii) const
|
Chris@49
|
54 {
|
Chris@49
|
55 typedef typename T1::elem_type eT;
|
Chris@49
|
56
|
Chris@49
|
57 if(is_same_type<gen_type, gen_ones_diag>::value == true)
|
Chris@49
|
58 {
|
Chris@49
|
59 return ((ii % n_rows) == (ii / n_rows)) ? eT(1) : eT(0);
|
Chris@49
|
60 }
|
Chris@49
|
61 else
|
Chris@49
|
62 {
|
Chris@49
|
63 return Gen<T1, gen_type>::generate();
|
Chris@49
|
64 }
|
Chris@49
|
65 }
|
Chris@49
|
66
|
Chris@49
|
67
|
Chris@49
|
68
|
Chris@49
|
69 template<typename T1, typename gen_type>
|
Chris@49
|
70 arma_inline
|
Chris@49
|
71 typename T1::elem_type
|
Chris@49
|
72 Gen<T1, gen_type>::at(const uword row, const uword col) const
|
Chris@49
|
73 {
|
Chris@49
|
74 typedef typename T1::elem_type eT;
|
Chris@49
|
75
|
Chris@49
|
76 if(is_same_type<gen_type, gen_ones_diag>::value == true)
|
Chris@49
|
77 {
|
Chris@49
|
78 return (row == col) ? eT(1) : eT(0);
|
Chris@49
|
79 }
|
Chris@49
|
80 else
|
Chris@49
|
81 {
|
Chris@49
|
82 return Gen<T1, gen_type>::generate();
|
Chris@49
|
83 }
|
Chris@49
|
84 }
|
Chris@49
|
85
|
Chris@49
|
86
|
Chris@49
|
87
|
Chris@49
|
88 template<typename T1, typename gen_type>
|
Chris@49
|
89 arma_inline
|
Chris@49
|
90 typename T1::elem_type
|
Chris@49
|
91 Gen<T1, gen_type>::at_alt(const uword ii) const
|
Chris@49
|
92 {
|
Chris@49
|
93 return operator[](ii);
|
Chris@49
|
94 }
|
Chris@49
|
95
|
Chris@49
|
96
|
Chris@49
|
97
|
Chris@49
|
98 template<typename T1, typename gen_type>
|
Chris@49
|
99 inline
|
Chris@49
|
100 void
|
Chris@49
|
101 Gen<T1, gen_type>::apply(Mat<typename T1::elem_type>& out) const
|
Chris@49
|
102 {
|
Chris@49
|
103 arma_extra_debug_sigprint();
|
Chris@49
|
104
|
Chris@49
|
105 // NOTE: we're assuming that the matrix has already been set to the correct size;
|
Chris@49
|
106 // this is done by either the Mat contructor or operator=()
|
Chris@49
|
107
|
Chris@49
|
108 if(is_same_type<gen_type, gen_ones_diag>::value == true) { out.eye(); }
|
Chris@49
|
109 else if(is_same_type<gen_type, gen_ones_full>::value == true) { out.ones(); }
|
Chris@49
|
110 else if(is_same_type<gen_type, gen_zeros >::value == true) { out.zeros(); }
|
Chris@49
|
111 else if(is_same_type<gen_type, gen_randu >::value == true) { out.randu(); }
|
Chris@49
|
112 else if(is_same_type<gen_type, gen_randn >::value == true) { out.randn(); }
|
Chris@49
|
113 }
|
Chris@49
|
114
|
Chris@49
|
115
|
Chris@49
|
116
|
Chris@49
|
117 template<typename T1, typename gen_type>
|
Chris@49
|
118 inline
|
Chris@49
|
119 void
|
Chris@49
|
120 Gen<T1, gen_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out) const
|
Chris@49
|
121 {
|
Chris@49
|
122 arma_extra_debug_sigprint();
|
Chris@49
|
123
|
Chris@49
|
124 arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "addition");
|
Chris@49
|
125
|
Chris@49
|
126 typedef typename T1::elem_type eT;
|
Chris@49
|
127
|
Chris@49
|
128
|
Chris@49
|
129 if(is_same_type<gen_type, gen_ones_diag>::value == true)
|
Chris@49
|
130 {
|
Chris@49
|
131 const uword N = (std::min)(n_rows, n_cols);
|
Chris@49
|
132
|
Chris@49
|
133 for(uword iq=0; iq < N; ++iq)
|
Chris@49
|
134 {
|
Chris@49
|
135 out.at(iq,iq) += eT(1);
|
Chris@49
|
136 }
|
Chris@49
|
137 }
|
Chris@49
|
138 else
|
Chris@49
|
139 {
|
Chris@49
|
140 eT* out_mem = out.memptr();
|
Chris@49
|
141 const uword n_elem = out.n_elem;
|
Chris@49
|
142
|
Chris@49
|
143 uword iq,jq;
|
Chris@49
|
144 for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2)
|
Chris@49
|
145 {
|
Chris@49
|
146 const eT tmp_i = Gen<T1, gen_type>::generate();
|
Chris@49
|
147 const eT tmp_j = Gen<T1, gen_type>::generate();
|
Chris@49
|
148
|
Chris@49
|
149 out_mem[iq] += tmp_i;
|
Chris@49
|
150 out_mem[jq] += tmp_j;
|
Chris@49
|
151 }
|
Chris@49
|
152
|
Chris@49
|
153 if(iq < n_elem)
|
Chris@49
|
154 {
|
Chris@49
|
155 out_mem[iq] += Gen<T1, gen_type>::generate();
|
Chris@49
|
156 }
|
Chris@49
|
157 }
|
Chris@49
|
158
|
Chris@49
|
159 }
|
Chris@49
|
160
|
Chris@49
|
161
|
Chris@49
|
162
|
Chris@49
|
163
|
Chris@49
|
164 template<typename T1, typename gen_type>
|
Chris@49
|
165 inline
|
Chris@49
|
166 void
|
Chris@49
|
167 Gen<T1, gen_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out) const
|
Chris@49
|
168 {
|
Chris@49
|
169 arma_extra_debug_sigprint();
|
Chris@49
|
170
|
Chris@49
|
171 arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "subtraction");
|
Chris@49
|
172
|
Chris@49
|
173 typedef typename T1::elem_type eT;
|
Chris@49
|
174
|
Chris@49
|
175
|
Chris@49
|
176 if(is_same_type<gen_type, gen_ones_diag>::value == true)
|
Chris@49
|
177 {
|
Chris@49
|
178 const uword N = (std::min)(n_rows, n_cols);
|
Chris@49
|
179
|
Chris@49
|
180 for(uword iq=0; iq < N; ++iq)
|
Chris@49
|
181 {
|
Chris@49
|
182 out.at(iq,iq) -= eT(1);
|
Chris@49
|
183 }
|
Chris@49
|
184 }
|
Chris@49
|
185 else
|
Chris@49
|
186 {
|
Chris@49
|
187 eT* out_mem = out.memptr();
|
Chris@49
|
188 const uword n_elem = out.n_elem;
|
Chris@49
|
189
|
Chris@49
|
190 uword iq,jq;
|
Chris@49
|
191 for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2)
|
Chris@49
|
192 {
|
Chris@49
|
193 const eT tmp_i = Gen<T1, gen_type>::generate();
|
Chris@49
|
194 const eT tmp_j = Gen<T1, gen_type>::generate();
|
Chris@49
|
195
|
Chris@49
|
196 out_mem[iq] -= tmp_i;
|
Chris@49
|
197 out_mem[jq] -= tmp_j;
|
Chris@49
|
198 }
|
Chris@49
|
199
|
Chris@49
|
200 if(iq < n_elem)
|
Chris@49
|
201 {
|
Chris@49
|
202 out_mem[iq] -= Gen<T1, gen_type>::generate();
|
Chris@49
|
203 }
|
Chris@49
|
204 }
|
Chris@49
|
205
|
Chris@49
|
206 }
|
Chris@49
|
207
|
Chris@49
|
208
|
Chris@49
|
209
|
Chris@49
|
210
|
Chris@49
|
211 template<typename T1, typename gen_type>
|
Chris@49
|
212 inline
|
Chris@49
|
213 void
|
Chris@49
|
214 Gen<T1, gen_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out) const
|
Chris@49
|
215 {
|
Chris@49
|
216 arma_extra_debug_sigprint();
|
Chris@49
|
217
|
Chris@49
|
218 arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise multiplication");
|
Chris@49
|
219
|
Chris@49
|
220 typedef typename T1::elem_type eT;
|
Chris@49
|
221
|
Chris@49
|
222
|
Chris@49
|
223 if(is_same_type<gen_type, gen_ones_diag>::value == true)
|
Chris@49
|
224 {
|
Chris@49
|
225 const uword N = (std::min)(n_rows, n_cols);
|
Chris@49
|
226
|
Chris@49
|
227 for(uword iq=0; iq < N; ++iq)
|
Chris@49
|
228 {
|
Chris@49
|
229 for(uword row=0; row < iq; ++row) { out.at(row,iq) = eT(0); }
|
Chris@49
|
230 for(uword row=iq+1; row < n_rows; ++row) { out.at(row,iq) = eT(0); }
|
Chris@49
|
231 }
|
Chris@49
|
232 }
|
Chris@49
|
233 else
|
Chris@49
|
234 {
|
Chris@49
|
235 eT* out_mem = out.memptr();
|
Chris@49
|
236 const uword n_elem = out.n_elem;
|
Chris@49
|
237
|
Chris@49
|
238 uword iq,jq;
|
Chris@49
|
239 for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2)
|
Chris@49
|
240 {
|
Chris@49
|
241 const eT tmp_i = Gen<T1, gen_type>::generate();
|
Chris@49
|
242 const eT tmp_j = Gen<T1, gen_type>::generate();
|
Chris@49
|
243
|
Chris@49
|
244 out_mem[iq] *= tmp_i;
|
Chris@49
|
245 out_mem[jq] *= tmp_j;
|
Chris@49
|
246 }
|
Chris@49
|
247
|
Chris@49
|
248 if(iq < n_elem)
|
Chris@49
|
249 {
|
Chris@49
|
250 out_mem[iq] *= Gen<T1, gen_type>::generate();
|
Chris@49
|
251 }
|
Chris@49
|
252 }
|
Chris@49
|
253
|
Chris@49
|
254 }
|
Chris@49
|
255
|
Chris@49
|
256
|
Chris@49
|
257
|
Chris@49
|
258
|
Chris@49
|
259 template<typename T1, typename gen_type>
|
Chris@49
|
260 inline
|
Chris@49
|
261 void
|
Chris@49
|
262 Gen<T1, gen_type>::apply_inplace_div(Mat<typename T1::elem_type>& out) const
|
Chris@49
|
263 {
|
Chris@49
|
264 arma_extra_debug_sigprint();
|
Chris@49
|
265
|
Chris@49
|
266 arma_debug_assert_same_size(out.n_rows, out.n_cols, n_rows, n_cols, "element-wise division");
|
Chris@49
|
267
|
Chris@49
|
268 typedef typename T1::elem_type eT;
|
Chris@49
|
269
|
Chris@49
|
270
|
Chris@49
|
271 if(is_same_type<gen_type, gen_ones_diag>::value == true)
|
Chris@49
|
272 {
|
Chris@49
|
273 const uword N = (std::min)(n_rows, n_cols);
|
Chris@49
|
274
|
Chris@49
|
275 for(uword iq=0; iq < N; ++iq)
|
Chris@49
|
276 {
|
Chris@49
|
277 const eT zero = eT(0);
|
Chris@49
|
278
|
Chris@49
|
279 for(uword row=0; row < iq; ++row) { out.at(row,iq) /= zero; }
|
Chris@49
|
280 for(uword row=iq+1; row < n_rows; ++row) { out.at(row,iq) /= zero; }
|
Chris@49
|
281 }
|
Chris@49
|
282 }
|
Chris@49
|
283 else
|
Chris@49
|
284 {
|
Chris@49
|
285 eT* out_mem = out.memptr();
|
Chris@49
|
286 const uword n_elem = out.n_elem;
|
Chris@49
|
287
|
Chris@49
|
288 uword iq,jq;
|
Chris@49
|
289 for(iq=0, jq=1; jq < n_elem; iq+=2, jq+=2)
|
Chris@49
|
290 {
|
Chris@49
|
291 const eT tmp_i = Gen<T1, gen_type>::generate();
|
Chris@49
|
292 const eT tmp_j = Gen<T1, gen_type>::generate();
|
Chris@49
|
293
|
Chris@49
|
294 out_mem[iq] /= tmp_i;
|
Chris@49
|
295 out_mem[jq] /= tmp_j;
|
Chris@49
|
296 }
|
Chris@49
|
297
|
Chris@49
|
298 if(iq < n_elem)
|
Chris@49
|
299 {
|
Chris@49
|
300 out_mem[iq] /= Gen<T1, gen_type>::generate();
|
Chris@49
|
301 }
|
Chris@49
|
302 }
|
Chris@49
|
303
|
Chris@49
|
304 }
|
Chris@49
|
305
|
Chris@49
|
306
|
Chris@49
|
307
|
Chris@49
|
308
|
Chris@49
|
309 //! @}
|
Chris@49
|
310
|