1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17
18
19 //! \addtogroup subview
20 //! @{
21
22
23 template<typename eT>
24 inline
~subview()25 subview<eT>::~subview()
26 {
27 arma_extra_debug_sigprint_this(this);
28 }
29
30
31
32 template<typename eT>
33 inline
subview(const Mat<eT> & in_m,const uword in_row1,const uword in_col1,const uword in_n_rows,const uword in_n_cols)34 subview<eT>::subview(const Mat<eT>& in_m, const uword in_row1, const uword in_col1, const uword in_n_rows, const uword in_n_cols)
35 : m (in_m )
36 , aux_row1(in_row1 )
37 , aux_col1(in_col1 )
38 , n_rows (in_n_rows)
39 , n_cols (in_n_cols)
40 , n_elem (in_n_rows*in_n_cols)
41 {
42 arma_extra_debug_sigprint_this(this);
43 }
44
45
46
47 template<typename eT>
48 inline
subview(const subview<eT> & in)49 subview<eT>::subview(const subview<eT>& in)
50 : m (in.m )
51 , aux_row1(in.aux_row1)
52 , aux_col1(in.aux_col1)
53 , n_rows (in.n_rows )
54 , n_cols (in.n_cols )
55 , n_elem (in.n_elem )
56 {
57 arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in);
58 }
59
60
61
62 template<typename eT>
63 inline
subview(subview<eT> && in)64 subview<eT>::subview(subview<eT>&& in)
65 : m (in.m )
66 , aux_row1(in.aux_row1)
67 , aux_col1(in.aux_col1)
68 , n_rows (in.n_rows )
69 , n_cols (in.n_cols )
70 , n_elem (in.n_elem )
71 {
72 arma_extra_debug_sigprint(arma_str::format("this = %x in = %x") % this % &in);
73
74 // for paranoia
75
76 access::rw(in.aux_row1) = 0;
77 access::rw(in.aux_col1) = 0;
78 access::rw(in.n_rows ) = 0;
79 access::rw(in.n_cols ) = 0;
80 access::rw(in.n_elem ) = 0;
81 }
82
83
84
85 template<typename eT>
86 template<typename op_type>
87 inline
88 void
inplace_op(const eT val)89 subview<eT>::inplace_op(const eT val)
90 {
91 arma_extra_debug_sigprint();
92
93 subview<eT>& s = *this;
94
95 const uword s_n_rows = s.n_rows;
96 const uword s_n_cols = s.n_cols;
97
98 if(s_n_rows == 1)
99 {
100 Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
101
102 const uword A_n_rows = A.n_rows;
103
104 eT* Aptr = &(A.at(s.aux_row1,s.aux_col1));
105
106 uword jj;
107 for(jj=1; jj < s_n_cols; jj+=2)
108 {
109 if(is_same_type<op_type, op_internal_plus >::yes) { (*Aptr) += val; Aptr += A_n_rows; (*Aptr) += val; Aptr += A_n_rows; }
110 if(is_same_type<op_type, op_internal_minus>::yes) { (*Aptr) -= val; Aptr += A_n_rows; (*Aptr) -= val; Aptr += A_n_rows; }
111 if(is_same_type<op_type, op_internal_schur>::yes) { (*Aptr) *= val; Aptr += A_n_rows; (*Aptr) *= val; Aptr += A_n_rows; }
112 if(is_same_type<op_type, op_internal_div >::yes) { (*Aptr) /= val; Aptr += A_n_rows; (*Aptr) /= val; Aptr += A_n_rows; }
113 }
114
115 if((jj-1) < s_n_cols)
116 {
117 if(is_same_type<op_type, op_internal_plus >::yes) { (*Aptr) += val; }
118 if(is_same_type<op_type, op_internal_minus>::yes) { (*Aptr) -= val; }
119 if(is_same_type<op_type, op_internal_schur>::yes) { (*Aptr) *= val; }
120 if(is_same_type<op_type, op_internal_div >::yes) { (*Aptr) /= val; }
121 }
122 }
123 else
124 {
125 for(uword ucol=0; ucol < s_n_cols; ++ucol)
126 {
127 if(is_same_type<op_type, op_internal_plus >::yes) { arrayops::inplace_plus ( colptr(ucol), val, s_n_rows ); }
128 if(is_same_type<op_type, op_internal_minus>::yes) { arrayops::inplace_minus( colptr(ucol), val, s_n_rows ); }
129 if(is_same_type<op_type, op_internal_schur>::yes) { arrayops::inplace_mul ( colptr(ucol), val, s_n_rows ); }
130 if(is_same_type<op_type, op_internal_div >::yes) { arrayops::inplace_div ( colptr(ucol), val, s_n_rows ); }
131 }
132 }
133 }
134
135
136
137 template<typename eT>
138 template<typename op_type, typename T1>
139 inline
140 void
inplace_op(const Base<eT,T1> & in,const char * identifier)141 subview<eT>::inplace_op(const Base<eT,T1>& in, const char* identifier)
142 {
143 arma_extra_debug_sigprint();
144
145 const Proxy<T1> P(in.get_ref());
146
147 subview<eT>& s = *this;
148
149 const uword s_n_rows = s.n_rows;
150 const uword s_n_cols = s.n_cols;
151
152 arma_debug_assert_same_size(s, P, identifier);
153
154 const bool use_mp = arma_config::openmp && Proxy<T1>::use_mp && mp_gate<eT>::eval(s.n_elem);
155 const bool has_overlap = P.has_overlap(s);
156
157 if(has_overlap) { arma_extra_debug_print("aliasing or overlap detected"); }
158
159 if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (use_mp) || (has_overlap) )
160 {
161 const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, has_overlap);
162 const Mat<eT>& B = tmp.M;
163
164 if(s_n_rows == 1)
165 {
166 Mat<eT>& A = const_cast< Mat<eT>& >(m);
167
168 const uword A_n_rows = A.n_rows;
169
170 eT* Aptr = &(A.at(aux_row1,aux_col1));
171 const eT* Bptr = B.memptr();
172
173 uword jj;
174 for(jj=1; jj < s_n_cols; jj+=2)
175 {
176 const eT tmp1 = (*Bptr); Bptr++;
177 const eT tmp2 = (*Bptr); Bptr++;
178
179 if(is_same_type<op_type, op_internal_equ >::yes) { (*Aptr) = tmp1; Aptr += A_n_rows; (*Aptr) = tmp2; Aptr += A_n_rows; }
180 if(is_same_type<op_type, op_internal_plus >::yes) { (*Aptr) += tmp1; Aptr += A_n_rows; (*Aptr) += tmp2; Aptr += A_n_rows; }
181 if(is_same_type<op_type, op_internal_minus>::yes) { (*Aptr) -= tmp1; Aptr += A_n_rows; (*Aptr) -= tmp2; Aptr += A_n_rows; }
182 if(is_same_type<op_type, op_internal_schur>::yes) { (*Aptr) *= tmp1; Aptr += A_n_rows; (*Aptr) *= tmp2; Aptr += A_n_rows; }
183 if(is_same_type<op_type, op_internal_div >::yes) { (*Aptr) /= tmp1; Aptr += A_n_rows; (*Aptr) /= tmp2; Aptr += A_n_rows; }
184 }
185
186 if((jj-1) < s_n_cols)
187 {
188 if(is_same_type<op_type, op_internal_equ >::yes) { (*Aptr) = (*Bptr); }
189 if(is_same_type<op_type, op_internal_plus >::yes) { (*Aptr) += (*Bptr); }
190 if(is_same_type<op_type, op_internal_minus>::yes) { (*Aptr) -= (*Bptr); }
191 if(is_same_type<op_type, op_internal_schur>::yes) { (*Aptr) *= (*Bptr); }
192 if(is_same_type<op_type, op_internal_div >::yes) { (*Aptr) /= (*Bptr); }
193 }
194 }
195 else // not a row vector
196 {
197 if((s.aux_row1 == 0) && (s_n_rows == s.m.n_rows))
198 {
199 if(is_same_type<op_type, op_internal_equ >::yes) { arrayops::copy ( s.colptr(0), B.memptr(), s.n_elem ); }
200 if(is_same_type<op_type, op_internal_plus >::yes) { arrayops::inplace_plus ( s.colptr(0), B.memptr(), s.n_elem ); }
201 if(is_same_type<op_type, op_internal_minus>::yes) { arrayops::inplace_minus( s.colptr(0), B.memptr(), s.n_elem ); }
202 if(is_same_type<op_type, op_internal_schur>::yes) { arrayops::inplace_mul ( s.colptr(0), B.memptr(), s.n_elem ); }
203 if(is_same_type<op_type, op_internal_div >::yes) { arrayops::inplace_div ( s.colptr(0), B.memptr(), s.n_elem ); }
204 }
205 else
206 {
207 for(uword ucol=0; ucol < s_n_cols; ++ucol)
208 {
209 if(is_same_type<op_type, op_internal_equ >::yes) { arrayops::copy ( s.colptr(ucol), B.colptr(ucol), s_n_rows ); }
210 if(is_same_type<op_type, op_internal_plus >::yes) { arrayops::inplace_plus ( s.colptr(ucol), B.colptr(ucol), s_n_rows ); }
211 if(is_same_type<op_type, op_internal_minus>::yes) { arrayops::inplace_minus( s.colptr(ucol), B.colptr(ucol), s_n_rows ); }
212 if(is_same_type<op_type, op_internal_schur>::yes) { arrayops::inplace_mul ( s.colptr(ucol), B.colptr(ucol), s_n_rows ); }
213 if(is_same_type<op_type, op_internal_div >::yes) { arrayops::inplace_div ( s.colptr(ucol), B.colptr(ucol), s_n_rows ); }
214 }
215 }
216 }
217 }
218 else // use the Proxy
219 {
220 if(s_n_rows == 1)
221 {
222 Mat<eT>& A = const_cast< Mat<eT>& >(m);
223
224 const uword A_n_rows = A.n_rows;
225
226 eT* Aptr = &(A.at(aux_row1,aux_col1));
227
228 uword jj;
229 for(jj=1; jj < s_n_cols; jj+=2)
230 {
231 const uword ii = (jj-1);
232
233 const eT tmp1 = (Proxy<T1>::use_at) ? P.at(0,ii) : P[ii];
234 const eT tmp2 = (Proxy<T1>::use_at) ? P.at(0,jj) : P[jj];
235
236 if(is_same_type<op_type, op_internal_equ >::yes) { (*Aptr) = tmp1; Aptr += A_n_rows; (*Aptr) = tmp2; Aptr += A_n_rows; }
237 if(is_same_type<op_type, op_internal_plus >::yes) { (*Aptr) += tmp1; Aptr += A_n_rows; (*Aptr) += tmp2; Aptr += A_n_rows; }
238 if(is_same_type<op_type, op_internal_minus>::yes) { (*Aptr) -= tmp1; Aptr += A_n_rows; (*Aptr) -= tmp2; Aptr += A_n_rows; }
239 if(is_same_type<op_type, op_internal_schur>::yes) { (*Aptr) *= tmp1; Aptr += A_n_rows; (*Aptr) *= tmp2; Aptr += A_n_rows; }
240 if(is_same_type<op_type, op_internal_div >::yes) { (*Aptr) /= tmp1; Aptr += A_n_rows; (*Aptr) /= tmp2; Aptr += A_n_rows; }
241 }
242
243 const uword ii = (jj-1);
244 if(ii < s_n_cols)
245 {
246 if(is_same_type<op_type, op_internal_equ >::yes) { (*Aptr) = (Proxy<T1>::use_at) ? P.at(0,ii) : P[ii]; }
247 if(is_same_type<op_type, op_internal_plus >::yes) { (*Aptr) += (Proxy<T1>::use_at) ? P.at(0,ii) : P[ii]; }
248 if(is_same_type<op_type, op_internal_minus>::yes) { (*Aptr) -= (Proxy<T1>::use_at) ? P.at(0,ii) : P[ii]; }
249 if(is_same_type<op_type, op_internal_schur>::yes) { (*Aptr) *= (Proxy<T1>::use_at) ? P.at(0,ii) : P[ii]; }
250 if(is_same_type<op_type, op_internal_div >::yes) { (*Aptr) /= (Proxy<T1>::use_at) ? P.at(0,ii) : P[ii]; }
251 }
252 }
253 else // not a row vector
254 {
255 if(Proxy<T1>::use_at)
256 {
257 for(uword ucol=0; ucol < s_n_cols; ++ucol)
258 {
259 eT* s_col_data = s.colptr(ucol);
260
261 uword jj;
262 for(jj=1; jj < s_n_rows; jj+=2)
263 {
264 const uword ii = (jj-1);
265
266 const eT tmp1 = P.at(ii,ucol);
267 const eT tmp2 = P.at(jj,ucol);
268
269 if(is_same_type<op_type, op_internal_equ >::yes) { (*s_col_data) = tmp1; s_col_data++; (*s_col_data) = tmp2; s_col_data++; }
270 if(is_same_type<op_type, op_internal_plus >::yes) { (*s_col_data) += tmp1; s_col_data++; (*s_col_data) += tmp2; s_col_data++; }
271 if(is_same_type<op_type, op_internal_minus>::yes) { (*s_col_data) -= tmp1; s_col_data++; (*s_col_data) -= tmp2; s_col_data++; }
272 if(is_same_type<op_type, op_internal_schur>::yes) { (*s_col_data) *= tmp1; s_col_data++; (*s_col_data) *= tmp2; s_col_data++; }
273 if(is_same_type<op_type, op_internal_div >::yes) { (*s_col_data) /= tmp1; s_col_data++; (*s_col_data) /= tmp2; s_col_data++; }
274 }
275
276 const uword ii = (jj-1);
277 if(ii < s_n_rows)
278 {
279 if(is_same_type<op_type, op_internal_equ >::yes) { (*s_col_data) = P.at(ii,ucol); }
280 if(is_same_type<op_type, op_internal_plus >::yes) { (*s_col_data) += P.at(ii,ucol); }
281 if(is_same_type<op_type, op_internal_minus>::yes) { (*s_col_data) -= P.at(ii,ucol); }
282 if(is_same_type<op_type, op_internal_schur>::yes) { (*s_col_data) *= P.at(ii,ucol); }
283 if(is_same_type<op_type, op_internal_div >::yes) { (*s_col_data) /= P.at(ii,ucol); }
284 }
285 }
286 }
287 else
288 {
289 typename Proxy<T1>::ea_type Pea = P.get_ea();
290
291 uword count = 0;
292
293 for(uword ucol=0; ucol < s_n_cols; ++ucol)
294 {
295 eT* s_col_data = s.colptr(ucol);
296
297 uword jj;
298 for(jj=1; jj < s_n_rows; jj+=2)
299 {
300 const eT tmp1 = Pea[count]; count++;
301 const eT tmp2 = Pea[count]; count++;
302
303 if(is_same_type<op_type, op_internal_equ >::yes) { (*s_col_data) = tmp1; s_col_data++; (*s_col_data) = tmp2; s_col_data++; }
304 if(is_same_type<op_type, op_internal_plus >::yes) { (*s_col_data) += tmp1; s_col_data++; (*s_col_data) += tmp2; s_col_data++; }
305 if(is_same_type<op_type, op_internal_minus>::yes) { (*s_col_data) -= tmp1; s_col_data++; (*s_col_data) -= tmp2; s_col_data++; }
306 if(is_same_type<op_type, op_internal_schur>::yes) { (*s_col_data) *= tmp1; s_col_data++; (*s_col_data) *= tmp2; s_col_data++; }
307 if(is_same_type<op_type, op_internal_div >::yes) { (*s_col_data) /= tmp1; s_col_data++; (*s_col_data) /= tmp2; s_col_data++; }
308 }
309
310 if((jj-1) < s_n_rows)
311 {
312 if(is_same_type<op_type, op_internal_equ >::yes) { (*s_col_data) = Pea[count]; count++; }
313 if(is_same_type<op_type, op_internal_plus >::yes) { (*s_col_data) += Pea[count]; count++; }
314 if(is_same_type<op_type, op_internal_minus>::yes) { (*s_col_data) -= Pea[count]; count++; }
315 if(is_same_type<op_type, op_internal_schur>::yes) { (*s_col_data) *= Pea[count]; count++; }
316 if(is_same_type<op_type, op_internal_div >::yes) { (*s_col_data) /= Pea[count]; count++; }
317 }
318 }
319 }
320 }
321 }
322 }
323
324
325
326 template<typename eT>
327 template<typename op_type>
328 inline
329 void
inplace_op(const subview<eT> & x,const char * identifier)330 subview<eT>::inplace_op(const subview<eT>& x, const char* identifier)
331 {
332 arma_extra_debug_sigprint();
333
334 if(check_overlap(x))
335 {
336 const Mat<eT> tmp(x);
337
338 if(is_same_type<op_type, op_internal_equ >::yes) { (*this).operator= (tmp); }
339 if(is_same_type<op_type, op_internal_plus >::yes) { (*this).operator+=(tmp); }
340 if(is_same_type<op_type, op_internal_minus>::yes) { (*this).operator-=(tmp); }
341 if(is_same_type<op_type, op_internal_schur>::yes) { (*this).operator%=(tmp); }
342 if(is_same_type<op_type, op_internal_div >::yes) { (*this).operator/=(tmp); }
343
344 return;
345 }
346
347 subview<eT>& s = *this;
348
349 arma_debug_assert_same_size(s, x, identifier);
350
351 const uword s_n_cols = s.n_cols;
352 const uword s_n_rows = s.n_rows;
353
354 if(s_n_rows == 1)
355 {
356 Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
357 const Mat<eT>& B = x.m;
358
359 const uword A_n_rows = A.n_rows;
360 const uword B_n_rows = B.n_rows;
361
362 eT* Aptr = &(A.at(s.aux_row1,s.aux_col1));
363 const eT* Bptr = &(B.at(x.aux_row1,x.aux_col1));
364
365 uword jj;
366 for(jj=1; jj < s_n_cols; jj+=2)
367 {
368 const eT tmp1 = (*Bptr); Bptr += B_n_rows;
369 const eT tmp2 = (*Bptr); Bptr += B_n_rows;
370
371 if(is_same_type<op_type, op_internal_equ >::yes) { (*Aptr) = tmp1; Aptr += A_n_rows; (*Aptr) = tmp2; Aptr += A_n_rows; }
372 if(is_same_type<op_type, op_internal_plus >::yes) { (*Aptr) += tmp1; Aptr += A_n_rows; (*Aptr) += tmp2; Aptr += A_n_rows; }
373 if(is_same_type<op_type, op_internal_minus>::yes) { (*Aptr) -= tmp1; Aptr += A_n_rows; (*Aptr) -= tmp2; Aptr += A_n_rows; }
374 if(is_same_type<op_type, op_internal_schur>::yes) { (*Aptr) *= tmp1; Aptr += A_n_rows; (*Aptr) *= tmp2; Aptr += A_n_rows; }
375 if(is_same_type<op_type, op_internal_div >::yes) { (*Aptr) /= tmp1; Aptr += A_n_rows; (*Aptr) /= tmp2; Aptr += A_n_rows; }
376 }
377
378 if((jj-1) < s_n_cols)
379 {
380 if(is_same_type<op_type, op_internal_equ >::yes) { (*Aptr) = (*Bptr); }
381 if(is_same_type<op_type, op_internal_plus >::yes) { (*Aptr) += (*Bptr); }
382 if(is_same_type<op_type, op_internal_minus>::yes) { (*Aptr) -= (*Bptr); }
383 if(is_same_type<op_type, op_internal_schur>::yes) { (*Aptr) *= (*Bptr); }
384 if(is_same_type<op_type, op_internal_div >::yes) { (*Aptr) /= (*Bptr); }
385 }
386 }
387 else
388 {
389 for(uword ucol=0; ucol < s_n_cols; ++ucol)
390 {
391 if(is_same_type<op_type, op_internal_equ >::yes) { arrayops::copy ( s.colptr(ucol), x.colptr(ucol), s_n_rows ); }
392 if(is_same_type<op_type, op_internal_plus >::yes) { arrayops::inplace_plus ( s.colptr(ucol), x.colptr(ucol), s_n_rows ); }
393 if(is_same_type<op_type, op_internal_minus>::yes) { arrayops::inplace_minus( s.colptr(ucol), x.colptr(ucol), s_n_rows ); }
394 if(is_same_type<op_type, op_internal_schur>::yes) { arrayops::inplace_mul ( s.colptr(ucol), x.colptr(ucol), s_n_rows ); }
395 if(is_same_type<op_type, op_internal_div >::yes) { arrayops::inplace_div ( s.colptr(ucol), x.colptr(ucol), s_n_rows ); }
396 }
397 }
398 }
399
400
401
402 template<typename eT>
403 inline
404 void
operator =(const eT val)405 subview<eT>::operator= (const eT val)
406 {
407 arma_extra_debug_sigprint();
408
409 if(n_elem != 1)
410 {
411 arma_debug_assert_same_size(n_rows, n_cols, 1, 1, "copy into submatrix");
412 }
413
414 Mat<eT>& X = const_cast< Mat<eT>& >(m);
415
416 X.at(aux_row1, aux_col1) = val;
417 }
418
419
420
421 template<typename eT>
422 inline
423 void
operator +=(const eT val)424 subview<eT>::operator+= (const eT val)
425 {
426 arma_extra_debug_sigprint();
427
428 inplace_op<op_internal_plus>(val);
429 }
430
431
432
433 template<typename eT>
434 inline
435 void
operator -=(const eT val)436 subview<eT>::operator-= (const eT val)
437 {
438 arma_extra_debug_sigprint();
439
440 inplace_op<op_internal_minus>(val);
441 }
442
443
444
445 template<typename eT>
446 inline
447 void
operator *=(const eT val)448 subview<eT>::operator*= (const eT val)
449 {
450 arma_extra_debug_sigprint();
451
452 inplace_op<op_internal_schur>(val);
453 }
454
455
456
457 template<typename eT>
458 inline
459 void
operator /=(const eT val)460 subview<eT>::operator/= (const eT val)
461 {
462 arma_extra_debug_sigprint();
463
464 inplace_op<op_internal_div>(val);
465 }
466
467
468
469 template<typename eT>
470 inline
471 void
operator =(const subview<eT> & x)472 subview<eT>::operator= (const subview<eT>& x)
473 {
474 arma_extra_debug_sigprint();
475
476 inplace_op<op_internal_equ>(x, "copy into submatrix");
477 }
478
479
480
481 template<typename eT>
482 inline
483 void
operator +=(const subview<eT> & x)484 subview<eT>::operator+= (const subview<eT>& x)
485 {
486 arma_extra_debug_sigprint();
487
488 inplace_op<op_internal_plus>(x, "addition");
489 }
490
491
492
493 template<typename eT>
494 inline
495 void
operator -=(const subview<eT> & x)496 subview<eT>::operator-= (const subview<eT>& x)
497 {
498 arma_extra_debug_sigprint();
499
500 inplace_op<op_internal_minus>(x, "subtraction");
501 }
502
503
504
505 template<typename eT>
506 inline
507 void
operator %=(const subview & x)508 subview<eT>::operator%= (const subview& x)
509 {
510 arma_extra_debug_sigprint();
511
512 inplace_op<op_internal_schur>(x, "element-wise multiplication");
513 }
514
515
516
517 template<typename eT>
518 inline
519 void
operator /=(const subview & x)520 subview<eT>::operator/= (const subview& x)
521 {
522 arma_extra_debug_sigprint();
523
524 inplace_op<op_internal_div>(x, "element-wise division");
525 }
526
527
528
529 template<typename eT>
530 template<typename T1>
531 inline
532 void
operator =(const Base<eT,T1> & in)533 subview<eT>::operator= (const Base<eT,T1>& in)
534 {
535 arma_extra_debug_sigprint();
536
537 inplace_op<op_internal_equ>(in, "copy into submatrix");
538 }
539
540
541
542 template<typename eT>
543 template<typename T1>
544 inline
545 void
operator +=(const Base<eT,T1> & in)546 subview<eT>::operator+= (const Base<eT,T1>& in)
547 {
548 arma_extra_debug_sigprint();
549
550 inplace_op<op_internal_plus>(in, "addition");
551 }
552
553
554
555 template<typename eT>
556 template<typename T1>
557 inline
558 void
operator -=(const Base<eT,T1> & in)559 subview<eT>::operator-= (const Base<eT,T1>& in)
560 {
561 arma_extra_debug_sigprint();
562
563 inplace_op<op_internal_minus>(in, "subtraction");
564 }
565
566
567
568 template<typename eT>
569 template<typename T1>
570 inline
571 void
operator %=(const Base<eT,T1> & in)572 subview<eT>::operator%= (const Base<eT,T1>& in)
573 {
574 arma_extra_debug_sigprint();
575
576 inplace_op<op_internal_schur>(in, "element-wise multiplication");
577 }
578
579
580
581 template<typename eT>
582 template<typename T1>
583 inline
584 void
operator /=(const Base<eT,T1> & in)585 subview<eT>::operator/= (const Base<eT,T1>& in)
586 {
587 arma_extra_debug_sigprint();
588
589 inplace_op<op_internal_div>(in, "element-wise division");
590 }
591
592
593
594 template<typename eT>
595 template<typename T1>
596 inline
597 void
operator =(const SpBase<eT,T1> & x)598 subview<eT>::operator=(const SpBase<eT, T1>& x)
599 {
600 arma_extra_debug_sigprint();
601
602 const SpProxy<T1> p(x.get_ref());
603
604 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "copy into submatrix");
605
606 // Clear the subview.
607 zeros();
608
609 // Iterate through the sparse subview and set the nonzero values appropriately.
610 typename SpProxy<T1>::const_iterator_type cit = p.begin();
611 typename SpProxy<T1>::const_iterator_type cit_end = p.end();
612
613 while(cit != cit_end)
614 {
615 at(cit.row(), cit.col()) = *cit;
616 ++cit;
617 }
618 }
619
620
621
622 template<typename eT>
623 template<typename T1>
624 inline
625 void
operator +=(const SpBase<eT,T1> & x)626 subview<eT>::operator+=(const SpBase<eT, T1>& x)
627 {
628 arma_extra_debug_sigprint();
629
630 const SpProxy<T1> p(x.get_ref());
631
632 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
633
634 // Iterate through the sparse subview and add its values.
635 typename SpProxy<T1>::const_iterator_type cit = p.begin();
636 typename SpProxy<T1>::const_iterator_type cit_end = p.end();
637
638 while(cit != cit_end)
639 {
640 at(cit.row(), cit.col()) += *cit;
641 ++cit;
642 }
643 }
644
645
646
647 template<typename eT>
648 template<typename T1>
649 inline
650 void
operator -=(const SpBase<eT,T1> & x)651 subview<eT>::operator-=(const SpBase<eT, T1>& x)
652 {
653 arma_extra_debug_sigprint();
654
655 const SpProxy<T1> p(x.get_ref());
656
657 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
658
659 // Iterate through the sparse subview and subtract its values.
660 typename SpProxy<T1>::const_iterator_type cit = p.begin();
661 typename SpProxy<T1>::const_iterator_type cit_end = p.end();
662
663 while(cit != cit_end)
664 {
665 at(cit.row(), cit.col()) -= *cit;
666 ++cit;
667 }
668 }
669
670
671
672 template<typename eT>
673 template<typename T1>
674 inline
675 void
operator %=(const SpBase<eT,T1> & x)676 subview<eT>::operator%=(const SpBase<eT, T1>& x)
677 {
678 arma_extra_debug_sigprint();
679
680 const uword s_n_rows = (*this).n_rows;
681 const uword s_n_cols = (*this).n_cols;
682
683 const SpProxy<T1> p(x.get_ref());
684
685 arma_debug_assert_same_size(s_n_rows, s_n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise multiplication");
686
687 if(n_elem == 0) { return; }
688
689 if(p.get_n_nonzero() == 0) { (*this).zeros(); return; }
690
691 // Iterate over nonzero values.
692 // Any zero values in the sparse expression will result in a zero in our subview.
693 typename SpProxy<T1>::const_iterator_type cit = p.begin();
694 typename SpProxy<T1>::const_iterator_type cit_end = p.end();
695
696 uword r = 0;
697 uword c = 0;
698
699 while(cit != cit_end)
700 {
701 const uword cit_row = cit.row();
702 const uword cit_col = cit.col();
703
704 while( ((r == cit_row) && (c == cit_col)) == false )
705 {
706 at(r,c) = eT(0);
707
708 r++; if(r >= s_n_rows) { r = 0; c++; }
709 }
710
711 at(r, c) *= (*cit);
712
713 ++cit;
714 r++; if(r >= s_n_rows) { r = 0; c++; }
715 }
716 }
717
718
719
720 template<typename eT>
721 template<typename T1>
722 inline
723 void
operator /=(const SpBase<eT,T1> & x)724 subview<eT>::operator/=(const SpBase<eT, T1>& x)
725 {
726 arma_extra_debug_sigprint();
727
728 const SpProxy<T1> p(x.get_ref());
729
730 arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
731
732 // This is probably going to fill your subview with a bunch of NaNs,
733 // so I'm not going to bother to implement it fast.
734 // You can have slow NaNs. They're fine too.
735 for(uword c = 0; c < n_cols; ++c)
736 for(uword r = 0; r < n_rows; ++r)
737 {
738 at(r, c) /= p.at(r, c);
739 }
740 }
741
742
743
744 template<typename eT>
745 template<typename T1, typename gen_type>
746 inline
747 typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void>::result
operator =(const Gen<T1,gen_type> & in)748 subview<eT>::operator= (const Gen<T1,gen_type>& in)
749 {
750 arma_extra_debug_sigprint();
751
752 arma_debug_assert_same_size(n_rows, n_cols, in.n_rows, in.n_cols, "copy into submatrix");
753
754 in.apply(*this);
755 }
756
757
758
759 template<typename eT>
760 inline
761 void
operator =(const std::initializer_list<eT> & list)762 subview<eT>::operator=(const std::initializer_list<eT>& list)
763 {
764 arma_extra_debug_sigprint();
765
766 arma_debug_check( (is_vec() == false), "copy into submatrix: size mismatch" );
767
768 const uword N = uword(list.size());
769
770 if(n_rows == 1)
771 {
772 arma_debug_assert_same_size(1, n_cols, 1, N, "copy into submatrix");
773
774 auto it = list.begin();
775
776 for(uword ii=0; ii < N; ++ii) { (*this).at(0,ii) = (*it); ++it; }
777 }
778 else
779 if(n_cols == 1)
780 {
781 arma_debug_assert_same_size(n_rows, 1, N, 1, "copy into submatrix");
782
783 arrayops::copy( (*this).colptr(0), list.begin(), N );
784 }
785 }
786
787
788
789 template<typename eT>
790 inline
791 void
operator =(const std::initializer_list<std::initializer_list<eT>> & list)792 subview<eT>::operator=(const std::initializer_list< std::initializer_list<eT> >& list)
793 {
794 arma_extra_debug_sigprint();
795
796 const Mat<eT> tmp(list);
797
798 (*this).operator=(tmp);
799 }
800
801
802
803 //! apply a functor to each element
804 template<typename eT>
805 template<typename functor>
806 inline
807 void
for_each(functor F)808 subview<eT>::for_each(functor F)
809 {
810 arma_extra_debug_sigprint();
811
812 Mat<eT>& X = const_cast< Mat<eT>& >(m);
813
814 if(n_rows == 1)
815 {
816 const uword urow = aux_row1;
817 const uword start_col = aux_col1;
818 const uword end_col_plus1 = start_col + n_cols;
819
820 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
821 {
822 F( X.at(urow, ucol) );
823 }
824 }
825 else
826 {
827 const uword start_col = aux_col1;
828 const uword start_row = aux_row1;
829
830 const uword end_col_plus1 = start_col + n_cols;
831 const uword end_row_plus1 = start_row + n_rows;
832
833 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
834 for(uword urow = start_row; urow < end_row_plus1; ++urow)
835 {
836 F( X.at(urow, ucol) );
837 }
838 }
839 }
840
841
842
843 template<typename eT>
844 template<typename functor>
845 inline
846 void
for_each(functor F) const847 subview<eT>::for_each(functor F) const
848 {
849 arma_extra_debug_sigprint();
850
851 const Mat<eT>& X = m;
852
853 if(n_rows == 1)
854 {
855 const uword urow = aux_row1;
856 const uword start_col = aux_col1;
857 const uword end_col_plus1 = start_col + n_cols;
858
859 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
860 {
861 F( X.at(urow, ucol) );
862 }
863 }
864 else
865 {
866 const uword start_col = aux_col1;
867 const uword start_row = aux_row1;
868
869 const uword end_col_plus1 = start_col + n_cols;
870 const uword end_row_plus1 = start_row + n_rows;
871
872 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
873 for(uword urow = start_row; urow < end_row_plus1; ++urow)
874 {
875 F( X.at(urow, ucol) );
876 }
877 }
878 }
879
880
881
882 //! transform each element in the subview using a functor
883 template<typename eT>
884 template<typename functor>
885 inline
886 void
transform(functor F)887 subview<eT>::transform(functor F)
888 {
889 arma_extra_debug_sigprint();
890
891 Mat<eT>& X = const_cast< Mat<eT>& >(m);
892
893 if(n_rows == 1)
894 {
895 const uword urow = aux_row1;
896 const uword start_col = aux_col1;
897 const uword end_col_plus1 = start_col + n_cols;
898
899 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
900 {
901 X.at(urow, ucol) = eT( F( X.at(urow, ucol) ) );
902 }
903 }
904 else
905 {
906 const uword start_col = aux_col1;
907 const uword start_row = aux_row1;
908
909 const uword end_col_plus1 = start_col + n_cols;
910 const uword end_row_plus1 = start_row + n_rows;
911
912 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
913 for(uword urow = start_row; urow < end_row_plus1; ++urow)
914 {
915 X.at(urow, ucol) = eT( F( X.at(urow, ucol) ) );
916 }
917 }
918 }
919
920
921
922 //! imbue (fill) the subview with values provided by a functor
923 template<typename eT>
924 template<typename functor>
925 inline
926 void
imbue(functor F)927 subview<eT>::imbue(functor F)
928 {
929 arma_extra_debug_sigprint();
930
931 Mat<eT>& X = const_cast< Mat<eT>& >(m);
932
933 if(n_rows == 1)
934 {
935 const uword urow = aux_row1;
936 const uword start_col = aux_col1;
937 const uword end_col_plus1 = start_col + n_cols;
938
939 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
940 {
941 X.at(urow, ucol) = eT( F() );
942 }
943 }
944 else
945 {
946 const uword start_col = aux_col1;
947 const uword start_row = aux_row1;
948
949 const uword end_col_plus1 = start_col + n_cols;
950 const uword end_row_plus1 = start_row + n_rows;
951
952 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol)
953 for(uword urow = start_row; urow < end_row_plus1; ++urow)
954 {
955 X.at(urow, ucol) = eT( F() );
956 }
957 }
958 }
959
960
961
962 template<typename eT>
963 inline
964 void
replace(const eT old_val,const eT new_val)965 subview<eT>::replace(const eT old_val, const eT new_val)
966 {
967 arma_extra_debug_sigprint();
968
969 subview<eT>& s = *this;
970
971 const uword s_n_cols = s.n_cols;
972 const uword s_n_rows = s.n_rows;
973
974 if(s_n_rows == 1)
975 {
976 Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
977
978 const uword A_n_rows = A.n_rows;
979
980 eT* Aptr = &(A.at(s.aux_row1,s.aux_col1));
981
982 if(arma_isnan(old_val))
983 {
984 for(uword ucol=0; ucol < s_n_cols; ++ucol)
985 {
986 (*Aptr) = (arma_isnan(*Aptr)) ? new_val : (*Aptr);
987
988 Aptr += A_n_rows;
989 }
990 }
991 else
992 {
993 for(uword ucol=0; ucol < s_n_cols; ++ucol)
994 {
995 (*Aptr) = ((*Aptr) == old_val) ? new_val : (*Aptr);
996
997 Aptr += A_n_rows;
998 }
999 }
1000 }
1001 else
1002 {
1003 for(uword ucol=0; ucol < s_n_cols; ++ucol)
1004 {
1005 arrayops::replace(s.colptr(ucol), s_n_rows, old_val, new_val);
1006 }
1007 }
1008 }
1009
1010
1011
1012 template<typename eT>
1013 inline
1014 void
clean(const typename get_pod_type<eT>::result threshold)1015 subview<eT>::clean(const typename get_pod_type<eT>::result threshold)
1016 {
1017 arma_extra_debug_sigprint();
1018
1019 subview<eT>& s = *this;
1020
1021 const uword s_n_cols = s.n_cols;
1022 const uword s_n_rows = s.n_rows;
1023
1024 for(uword ucol=0; ucol < s_n_cols; ++ucol)
1025 {
1026 arrayops::clean( s.colptr(ucol), s_n_rows, threshold );
1027 }
1028 }
1029
1030
1031
1032 template<typename eT>
1033 inline
1034 void
clamp(const eT min_val,const eT max_val)1035 subview<eT>::clamp(const eT min_val, const eT max_val)
1036 {
1037 arma_extra_debug_sigprint();
1038
1039 if(is_cx<eT>::no)
1040 {
1041 arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview::clamp(): min_val must be less than max_val" );
1042 }
1043 else
1044 {
1045 arma_debug_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview::clamp(): real(min_val) must be less than real(max_val)" );
1046 arma_debug_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "subview::clamp(): imag(min_val) must be less than imag(max_val)" );
1047 }
1048
1049 subview<eT>& s = *this;
1050
1051 const uword s_n_cols = s.n_cols;
1052 const uword s_n_rows = s.n_rows;
1053
1054 for(uword ucol=0; ucol < s_n_cols; ++ucol)
1055 {
1056 arrayops::clamp( s.colptr(ucol), s_n_rows, min_val, max_val );
1057 }
1058 }
1059
1060
1061
1062 template<typename eT>
1063 inline
1064 void
fill(const eT val)1065 subview<eT>::fill(const eT val)
1066 {
1067 arma_extra_debug_sigprint();
1068
1069 subview<eT>& s = *this;
1070
1071 const uword s_n_cols = s.n_cols;
1072 const uword s_n_rows = s.n_rows;
1073
1074 if(s_n_rows == 1)
1075 {
1076 Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
1077
1078 const uword A_n_rows = A.n_rows;
1079
1080 eT* Aptr = &(A.at(s.aux_row1,s.aux_col1));
1081
1082 uword jj;
1083 for(jj=1; jj < s_n_cols; jj+=2)
1084 {
1085 (*Aptr) = val; Aptr += A_n_rows;
1086 (*Aptr) = val; Aptr += A_n_rows;
1087 }
1088
1089 if((jj-1) < s_n_cols)
1090 {
1091 (*Aptr) = val;
1092 }
1093 }
1094 else
1095 {
1096 if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) )
1097 {
1098 arrayops::inplace_set( s.colptr(0), val, s.n_elem );
1099 }
1100 else
1101 {
1102 for(uword ucol=0; ucol < s_n_cols; ++ucol)
1103 {
1104 arrayops::inplace_set( s.colptr(ucol), val, s_n_rows );
1105 }
1106 }
1107 }
1108 }
1109
1110
1111
1112 template<typename eT>
1113 inline
1114 void
zeros()1115 subview<eT>::zeros()
1116 {
1117 arma_extra_debug_sigprint();
1118
1119 (*this).fill(eT(0));
1120 }
1121
1122
1123
1124 template<typename eT>
1125 inline
1126 void
ones()1127 subview<eT>::ones()
1128 {
1129 arma_extra_debug_sigprint();
1130
1131 (*this).fill(eT(1));
1132 }
1133
1134
1135
1136 template<typename eT>
1137 inline
1138 void
eye()1139 subview<eT>::eye()
1140 {
1141 arma_extra_debug_sigprint();
1142
1143 (*this).zeros();
1144
1145 const uword N = (std::min)(n_rows, n_cols);
1146
1147 for(uword ii=0; ii < N; ++ii)
1148 {
1149 at(ii,ii) = eT(1);
1150 }
1151 }
1152
1153
1154
1155 template<typename eT>
1156 inline
1157 void
randu()1158 subview<eT>::randu()
1159 {
1160 arma_extra_debug_sigprint();
1161
1162 subview<eT>& s = (*this);
1163
1164 const uword s_n_rows = s.n_rows;
1165 const uword s_n_cols = s.n_cols;
1166
1167 if(s_n_rows == 1)
1168 {
1169 podarray<eT> tmp(s_n_cols);
1170
1171 eT* tmp_mem = tmp.memptr();
1172
1173 arma_rng::randu<eT>::fill( tmp_mem, s_n_cols );
1174
1175 for(uword ii=0; ii < s_n_cols; ++ii) { at(0,ii) = tmp_mem[ii]; }
1176 }
1177 else
1178 {
1179 if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) )
1180 {
1181 arma_rng::randu<eT>::fill( s.colptr(0), s.n_elem );
1182 }
1183 else
1184 {
1185 for(uword ii=0; ii < s_n_cols; ++ii)
1186 {
1187 arma_rng::randu<eT>::fill( s.colptr(ii), s_n_rows );
1188 }
1189 }
1190 }
1191 }
1192
1193
1194
1195 template<typename eT>
1196 inline
1197 void
randn()1198 subview<eT>::randn()
1199 {
1200 arma_extra_debug_sigprint();
1201
1202 subview<eT>& s = (*this);
1203
1204 const uword s_n_rows = s.n_rows;
1205 const uword s_n_cols = s.n_cols;
1206
1207 if(s_n_rows == 1)
1208 {
1209 podarray<eT> tmp(s_n_cols);
1210
1211 eT* tmp_mem = tmp.memptr();
1212
1213 arma_rng::randn<eT>::fill( tmp_mem, s_n_cols );
1214
1215 for(uword ii=0; ii < s_n_cols; ++ii) { at(0,ii) = tmp_mem[ii]; }
1216 }
1217 else
1218 {
1219 if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) )
1220 {
1221 arma_rng::randn<eT>::fill( s.colptr(0), s.n_elem );
1222 }
1223 else
1224 {
1225 for(uword ii=0; ii < s_n_cols; ++ii)
1226 {
1227 arma_rng::randn<eT>::fill( s.colptr(ii), s_n_rows );
1228 }
1229 }
1230 }
1231 }
1232
1233
1234
1235 template<typename eT>
1236 inline
1237 arma_warn_unused
1238 eT
at_alt(const uword ii) const1239 subview<eT>::at_alt(const uword ii) const
1240 {
1241 return operator[](ii);
1242 }
1243
1244
1245
1246 template<typename eT>
1247 inline
1248 arma_warn_unused
1249 eT&
operator [](const uword ii)1250 subview<eT>::operator[](const uword ii)
1251 {
1252 const uword in_col = ii / n_rows;
1253 const uword in_row = ii % n_rows;
1254
1255 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1256
1257 return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
1258 }
1259
1260
1261
1262 template<typename eT>
1263 inline
1264 arma_warn_unused
1265 eT
operator [](const uword ii) const1266 subview<eT>::operator[](const uword ii) const
1267 {
1268 const uword in_col = ii / n_rows;
1269 const uword in_row = ii % n_rows;
1270
1271 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1272
1273 return m.mem[index];
1274 }
1275
1276
1277
1278 template<typename eT>
1279 inline
1280 arma_warn_unused
1281 eT&
operator ()(const uword ii)1282 subview<eT>::operator()(const uword ii)
1283 {
1284 arma_debug_check_bounds( (ii >= n_elem), "subview::operator(): index out of bounds" );
1285
1286 const uword in_col = ii / n_rows;
1287 const uword in_row = ii % n_rows;
1288
1289 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1290
1291 return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
1292 }
1293
1294
1295
1296 template<typename eT>
1297 inline
1298 arma_warn_unused
1299 eT
operator ()(const uword ii) const1300 subview<eT>::operator()(const uword ii) const
1301 {
1302 arma_debug_check_bounds( (ii >= n_elem), "subview::operator(): index out of bounds" );
1303
1304 const uword in_col = ii / n_rows;
1305 const uword in_row = ii % n_rows;
1306
1307 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1308
1309 return m.mem[index];
1310 }
1311
1312
1313
1314 template<typename eT>
1315 inline
1316 arma_warn_unused
1317 eT&
operator ()(const uword in_row,const uword in_col)1318 subview<eT>::operator()(const uword in_row, const uword in_col)
1319 {
1320 arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds" );
1321
1322 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1323
1324 return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
1325 }
1326
1327
1328
1329 template<typename eT>
1330 inline
1331 arma_warn_unused
1332 eT
operator ()(const uword in_row,const uword in_col) const1333 subview<eT>::operator()(const uword in_row, const uword in_col) const
1334 {
1335 arma_debug_check_bounds( ((in_row >= n_rows) || (in_col >= n_cols)), "subview::operator(): index out of bounds" );
1336
1337 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1338
1339 return m.mem[index];
1340 }
1341
1342
1343
1344 template<typename eT>
1345 inline
1346 arma_warn_unused
1347 eT&
at(const uword in_row,const uword in_col)1348 subview<eT>::at(const uword in_row, const uword in_col)
1349 {
1350 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1351
1352 return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
1353 }
1354
1355
1356
1357 template<typename eT>
1358 inline
1359 arma_warn_unused
1360 eT
at(const uword in_row,const uword in_col) const1361 subview<eT>::at(const uword in_row, const uword in_col) const
1362 {
1363 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1364
1365 return m.mem[index];
1366 }
1367
1368
1369
1370 template<typename eT>
1371 inline
1372 arma_warn_unused
1373 eT&
front()1374 subview<eT>::front()
1375 {
1376 const uword index = aux_col1*m.n_rows + aux_row1;
1377
1378 return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
1379 }
1380
1381
1382
1383 template<typename eT>
1384 inline
1385 arma_warn_unused
1386 eT
front() const1387 subview<eT>::front() const
1388 {
1389 const uword index = aux_col1*m.n_rows + aux_row1;
1390
1391 return m.mem[index];
1392 }
1393
1394
1395
1396 template<typename eT>
1397 inline
1398 arma_warn_unused
1399 eT&
back()1400 subview<eT>::back()
1401 {
1402 const uword in_row = n_rows - 1;
1403 const uword in_col = n_cols - 1;
1404
1405 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1406
1407 return access::rw( (const_cast< Mat<eT>& >(m)).mem[index] );
1408 }
1409
1410
1411
1412 template<typename eT>
1413 inline
1414 arma_warn_unused
1415 eT
back() const1416 subview<eT>::back() const
1417 {
1418 const uword in_row = n_rows - 1;
1419 const uword in_col = n_cols - 1;
1420
1421 const uword index = (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1422
1423 return m.mem[index];
1424 }
1425
1426
1427
1428 template<typename eT>
1429 arma_inline
1430 eT*
colptr(const uword in_col)1431 subview<eT>::colptr(const uword in_col)
1432 {
1433 return & access::rw((const_cast< Mat<eT>& >(m)).mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ]);
1434 }
1435
1436
1437
1438 template<typename eT>
1439 arma_inline
1440 const eT*
colptr(const uword in_col) const1441 subview<eT>::colptr(const uword in_col) const
1442 {
1443 return & m.mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ];
1444 }
1445
1446
1447
1448 template<typename eT>
1449 template<typename eT2>
1450 inline
1451 bool
check_overlap(const subview<eT2> & x) const1452 subview<eT>::check_overlap(const subview<eT2>& x) const
1453 {
1454 if(is_same_type<eT,eT2>::value == false) { return false; }
1455
1456 const subview<eT>& s = (*this);
1457
1458 if(void_ptr(&(s.m)) != void_ptr(&(x.m))) { return false; }
1459
1460 if( (s.n_elem == 0) || (x.n_elem == 0) ) { return false; }
1461
1462 const uword s_row_start = s.aux_row1;
1463 const uword s_row_end_p1 = s_row_start + s.n_rows;
1464
1465 const uword s_col_start = s.aux_col1;
1466 const uword s_col_end_p1 = s_col_start + s.n_cols;
1467
1468
1469 const uword x_row_start = x.aux_row1;
1470 const uword x_row_end_p1 = x_row_start + x.n_rows;
1471
1472 const uword x_col_start = x.aux_col1;
1473 const uword x_col_end_p1 = x_col_start + x.n_cols;
1474
1475
1476 const bool outside_rows = ( (x_row_start >= s_row_end_p1) || (s_row_start >= x_row_end_p1) );
1477 const bool outside_cols = ( (x_col_start >= s_col_end_p1) || (s_col_start >= x_col_end_p1) );
1478
1479 return ( (outside_rows == false) && (outside_cols == false) );
1480 }
1481
1482
1483
1484 template<typename eT>
1485 inline
1486 arma_warn_unused
1487 bool
is_vec() const1488 subview<eT>::is_vec() const
1489 {
1490 return ( (n_rows == 1) || (n_cols == 1) );
1491 }
1492
1493
1494
1495 template<typename eT>
1496 inline
1497 arma_warn_unused
1498 bool
is_finite() const1499 subview<eT>::is_finite() const
1500 {
1501 arma_extra_debug_sigprint();
1502
1503 const uword local_n_rows = n_rows;
1504 const uword local_n_cols = n_cols;
1505
1506 for(uword ii=0; ii<local_n_cols; ++ii)
1507 {
1508 if(arrayops::is_finite(colptr(ii), local_n_rows) == false) { return false; }
1509 }
1510
1511 return true;
1512 }
1513
1514
1515
1516 template<typename eT>
1517 inline
1518 arma_warn_unused
1519 bool
is_zero(const typename get_pod_type<eT>::result tol) const1520 subview<eT>::is_zero(const typename get_pod_type<eT>::result tol) const
1521 {
1522 arma_extra_debug_sigprint();
1523
1524 const uword local_n_rows = n_rows;
1525 const uword local_n_cols = n_cols;
1526
1527 for(uword ii=0; ii<local_n_cols; ++ii)
1528 {
1529 if(arrayops::is_zero(colptr(ii), local_n_rows, tol) == false) { return false; }
1530 }
1531
1532 return true;
1533 }
1534
1535
1536
1537 template<typename eT>
1538 inline
1539 arma_warn_unused
1540 bool
has_inf() const1541 subview<eT>::has_inf() const
1542 {
1543 arma_extra_debug_sigprint();
1544
1545 const uword local_n_rows = n_rows;
1546 const uword local_n_cols = n_cols;
1547
1548 for(uword ii=0; ii<local_n_cols; ++ii)
1549 {
1550 if(arrayops::has_inf(colptr(ii), local_n_rows)) { return true; }
1551 }
1552
1553 return false;
1554 }
1555
1556
1557
1558 template<typename eT>
1559 inline
1560 arma_warn_unused
1561 bool
has_nan() const1562 subview<eT>::has_nan() const
1563 {
1564 arma_extra_debug_sigprint();
1565
1566 const uword local_n_rows = n_rows;
1567 const uword local_n_cols = n_cols;
1568
1569 for(uword ii=0; ii<local_n_cols; ++ii)
1570 {
1571 if(arrayops::has_nan(colptr(ii), local_n_rows)) { return true; }
1572 }
1573
1574 return false;
1575 }
1576
1577
1578
1579 //! X = Y.submat(...)
1580 template<typename eT>
1581 inline
1582 void
extract(Mat<eT> & out,const subview<eT> & in)1583 subview<eT>::extract(Mat<eT>& out, const subview<eT>& in)
1584 {
1585 arma_extra_debug_sigprint();
1586
1587 // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
1588 // size setting and alias checking is done by either the Mat contructor or operator=()
1589
1590 const uword n_rows = in.n_rows; // number of rows in the subview
1591 const uword n_cols = in.n_cols; // number of columns in the subview
1592
1593 arma_extra_debug_print(arma_str::format("out.n_rows = %d out.n_cols = %d in.m.n_rows = %d in.m.n_cols = %d") % out.n_rows % out.n_cols % in.m.n_rows % in.m.n_cols );
1594
1595
1596 if(in.is_vec())
1597 {
1598 if(n_cols == 1) // a column vector
1599 {
1600 arma_extra_debug_print("subview::extract(): copying col (going across rows)");
1601
1602 // in.colptr(0) the first column of the subview, taking into account any row offset
1603 arrayops::copy( out.memptr(), in.colptr(0), n_rows );
1604 }
1605 else // a row vector (possibly empty)
1606 {
1607 arma_extra_debug_print("subview::extract(): copying row (going across columns)");
1608
1609 eT* out_mem = out.memptr();
1610
1611 const uword X_n_rows = in.m.n_rows;
1612
1613 const eT* Xptr = &(in.m.at(in.aux_row1,in.aux_col1));
1614
1615 uword j;
1616
1617 for(j=1; j < n_cols; j+=2)
1618 {
1619 const eT tmp1 = (*Xptr); Xptr += X_n_rows;
1620 const eT tmp2 = (*Xptr); Xptr += X_n_rows;
1621
1622 (*out_mem) = tmp1; out_mem++;
1623 (*out_mem) = tmp2; out_mem++;
1624 }
1625
1626 if((j-1) < n_cols)
1627 {
1628 (*out_mem) = (*Xptr);
1629 }
1630 }
1631 }
1632 else // general submatrix
1633 {
1634 arma_extra_debug_print("subview::extract(): general submatrix");
1635
1636 if( (in.aux_row1 == 0) && (n_rows == in.m.n_rows) )
1637 {
1638 arrayops::copy( out.memptr(), in.colptr(0), in.n_elem );
1639 }
1640 else
1641 {
1642 for(uword col=0; col < n_cols; ++col)
1643 {
1644 arrayops::copy( out.colptr(col), in.colptr(col), n_rows );
1645 }
1646 }
1647 }
1648 }
1649
1650
1651
1652 //! X += Y.submat(...)
1653 template<typename eT>
1654 inline
1655 void
plus_inplace(Mat<eT> & out,const subview<eT> & in)1656 subview<eT>::plus_inplace(Mat<eT>& out, const subview<eT>& in)
1657 {
1658 arma_extra_debug_sigprint();
1659
1660 arma_debug_assert_same_size(out, in, "addition");
1661
1662 const uword n_rows = in.n_rows;
1663 const uword n_cols = in.n_cols;
1664
1665 if(n_rows == 1)
1666 {
1667 eT* out_mem = out.memptr();
1668
1669 const Mat<eT>& X = in.m;
1670
1671 const uword row = in.aux_row1;
1672 const uword start_col = in.aux_col1;
1673
1674 uword i,j;
1675 for(i=0, j=1; j < n_cols; i+=2, j+=2)
1676 {
1677 const eT tmp1 = X.at(row, start_col+i);
1678 const eT tmp2 = X.at(row, start_col+j);
1679
1680 out_mem[i] += tmp1;
1681 out_mem[j] += tmp2;
1682 }
1683
1684 if(i < n_cols)
1685 {
1686 out_mem[i] += X.at(row, start_col+i);
1687 }
1688 }
1689 else
1690 {
1691 for(uword col=0; col < n_cols; ++col)
1692 {
1693 arrayops::inplace_plus(out.colptr(col), in.colptr(col), n_rows);
1694 }
1695 }
1696 }
1697
1698
1699
1700 //! X -= Y.submat(...)
1701 template<typename eT>
1702 inline
1703 void
minus_inplace(Mat<eT> & out,const subview<eT> & in)1704 subview<eT>::minus_inplace(Mat<eT>& out, const subview<eT>& in)
1705 {
1706 arma_extra_debug_sigprint();
1707
1708 arma_debug_assert_same_size(out, in, "subtraction");
1709
1710 const uword n_rows = in.n_rows;
1711 const uword n_cols = in.n_cols;
1712
1713 if(n_rows == 1)
1714 {
1715 eT* out_mem = out.memptr();
1716
1717 const Mat<eT>& X = in.m;
1718
1719 const uword row = in.aux_row1;
1720 const uword start_col = in.aux_col1;
1721
1722 uword i,j;
1723 for(i=0, j=1; j < n_cols; i+=2, j+=2)
1724 {
1725 const eT tmp1 = X.at(row, start_col+i);
1726 const eT tmp2 = X.at(row, start_col+j);
1727
1728 out_mem[i] -= tmp1;
1729 out_mem[j] -= tmp2;
1730 }
1731
1732 if(i < n_cols)
1733 {
1734 out_mem[i] -= X.at(row, start_col+i);
1735 }
1736 }
1737 else
1738 {
1739 for(uword col=0; col < n_cols; ++col)
1740 {
1741 arrayops::inplace_minus(out.colptr(col), in.colptr(col), n_rows);
1742 }
1743 }
1744 }
1745
1746
1747
1748 //! X %= Y.submat(...)
1749 template<typename eT>
1750 inline
1751 void
schur_inplace(Mat<eT> & out,const subview<eT> & in)1752 subview<eT>::schur_inplace(Mat<eT>& out, const subview<eT>& in)
1753 {
1754 arma_extra_debug_sigprint();
1755
1756 arma_debug_assert_same_size(out, in, "element-wise multiplication");
1757
1758 const uword n_rows = in.n_rows;
1759 const uword n_cols = in.n_cols;
1760
1761 if(n_rows == 1)
1762 {
1763 eT* out_mem = out.memptr();
1764
1765 const Mat<eT>& X = in.m;
1766
1767 const uword row = in.aux_row1;
1768 const uword start_col = in.aux_col1;
1769
1770 uword i,j;
1771 for(i=0, j=1; j < n_cols; i+=2, j+=2)
1772 {
1773 const eT tmp1 = X.at(row, start_col+i);
1774 const eT tmp2 = X.at(row, start_col+j);
1775
1776 out_mem[i] *= tmp1;
1777 out_mem[j] *= tmp2;
1778 }
1779
1780 if(i < n_cols)
1781 {
1782 out_mem[i] *= X.at(row, start_col+i);
1783 }
1784 }
1785 else
1786 {
1787 for(uword col=0; col < n_cols; ++col)
1788 {
1789 arrayops::inplace_mul(out.colptr(col), in.colptr(col), n_rows);
1790 }
1791 }
1792 }
1793
1794
1795
1796 //! X /= Y.submat(...)
1797 template<typename eT>
1798 inline
1799 void
div_inplace(Mat<eT> & out,const subview<eT> & in)1800 subview<eT>::div_inplace(Mat<eT>& out, const subview<eT>& in)
1801 {
1802 arma_extra_debug_sigprint();
1803
1804 arma_debug_assert_same_size(out, in, "element-wise division");
1805
1806 const uword n_rows = in.n_rows;
1807 const uword n_cols = in.n_cols;
1808
1809 if(n_rows == 1)
1810 {
1811 eT* out_mem = out.memptr();
1812
1813 const Mat<eT>& X = in.m;
1814
1815 const uword row = in.aux_row1;
1816 const uword start_col = in.aux_col1;
1817
1818 uword i,j;
1819 for(i=0, j=1; j < n_cols; i+=2, j+=2)
1820 {
1821 const eT tmp1 = X.at(row, start_col+i);
1822 const eT tmp2 = X.at(row, start_col+j);
1823
1824 out_mem[i] /= tmp1;
1825 out_mem[j] /= tmp2;
1826 }
1827
1828 if(i < n_cols)
1829 {
1830 out_mem[i] /= X.at(row, start_col+i);
1831 }
1832 }
1833 else
1834 {
1835 for(uword col=0; col < n_cols; ++col)
1836 {
1837 arrayops::inplace_div(out.colptr(col), in.colptr(col), n_rows);
1838 }
1839 }
1840 }
1841
1842
1843
1844 //! creation of subview (row vector)
1845 template<typename eT>
1846 inline
1847 subview_row<eT>
row(const uword row_num)1848 subview<eT>::row(const uword row_num)
1849 {
1850 arma_extra_debug_sigprint();
1851
1852 arma_debug_check_bounds( row_num >= n_rows, "subview::row(): out of bounds" );
1853
1854 const uword base_row = aux_row1 + row_num;
1855
1856 return subview_row<eT>(m, base_row, aux_col1, n_cols);
1857 }
1858
1859
1860
1861 //! creation of subview (row vector)
1862 template<typename eT>
1863 inline
1864 const subview_row<eT>
row(const uword row_num) const1865 subview<eT>::row(const uword row_num) const
1866 {
1867 arma_extra_debug_sigprint();
1868
1869 arma_debug_check_bounds( row_num >= n_rows, "subview::row(): out of bounds" );
1870
1871 const uword base_row = aux_row1 + row_num;
1872
1873 return subview_row<eT>(m, base_row, aux_col1, n_cols);
1874 }
1875
1876
1877
1878 template<typename eT>
1879 inline
1880 subview_row<eT>
operator ()(const uword row_num,const span & col_span)1881 subview<eT>::operator()(const uword row_num, const span& col_span)
1882 {
1883 arma_extra_debug_sigprint();
1884
1885 const bool col_all = col_span.whole;
1886
1887 const uword local_n_cols = n_cols;
1888
1889 const uword in_col1 = col_all ? 0 : col_span.a;
1890 const uword in_col2 = col_span.b;
1891 const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
1892
1893 const uword base_col1 = aux_col1 + in_col1;
1894 const uword base_row = aux_row1 + row_num;
1895
1896 arma_debug_check_bounds
1897 (
1898 (row_num >= n_rows)
1899 ||
1900 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
1901 ,
1902 "subview::operator(): indices out of bounds or incorrectly used"
1903 );
1904
1905 return subview_row<eT>(m, base_row, base_col1, submat_n_cols);
1906 }
1907
1908
1909
1910 template<typename eT>
1911 inline
1912 const subview_row<eT>
operator ()(const uword row_num,const span & col_span) const1913 subview<eT>::operator()(const uword row_num, const span& col_span) const
1914 {
1915 arma_extra_debug_sigprint();
1916
1917 const bool col_all = col_span.whole;
1918
1919 const uword local_n_cols = n_cols;
1920
1921 const uword in_col1 = col_all ? 0 : col_span.a;
1922 const uword in_col2 = col_span.b;
1923 const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
1924
1925 const uword base_col1 = aux_col1 + in_col1;
1926 const uword base_row = aux_row1 + row_num;
1927
1928 arma_debug_check_bounds
1929 (
1930 (row_num >= n_rows)
1931 ||
1932 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
1933 ,
1934 "subview::operator(): indices out of bounds or incorrectly used"
1935 );
1936
1937 return subview_row<eT>(m, base_row, base_col1, submat_n_cols);
1938 }
1939
1940
1941
1942 //! creation of subview (column vector)
1943 template<typename eT>
1944 inline
1945 subview_col<eT>
col(const uword col_num)1946 subview<eT>::col(const uword col_num)
1947 {
1948 arma_extra_debug_sigprint();
1949
1950 arma_debug_check_bounds( col_num >= n_cols, "subview::col(): out of bounds" );
1951
1952 const uword base_col = aux_col1 + col_num;
1953
1954 return subview_col<eT>(m, base_col, aux_row1, n_rows);
1955 }
1956
1957
1958
1959 //! creation of subview (column vector)
1960 template<typename eT>
1961 inline
1962 const subview_col<eT>
col(const uword col_num) const1963 subview<eT>::col(const uword col_num) const
1964 {
1965 arma_extra_debug_sigprint();
1966
1967 arma_debug_check_bounds( col_num >= n_cols, "subview::col(): out of bounds" );
1968
1969 const uword base_col = aux_col1 + col_num;
1970
1971 return subview_col<eT>(m, base_col, aux_row1, n_rows);
1972 }
1973
1974
1975
1976 template<typename eT>
1977 inline
1978 subview_col<eT>
operator ()(const span & row_span,const uword col_num)1979 subview<eT>::operator()(const span& row_span, const uword col_num)
1980 {
1981 arma_extra_debug_sigprint();
1982
1983 const bool row_all = row_span.whole;
1984
1985 const uword local_n_rows = n_rows;
1986
1987 const uword in_row1 = row_all ? 0 : row_span.a;
1988 const uword in_row2 = row_span.b;
1989 const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
1990
1991 const uword base_row1 = aux_row1 + in_row1;
1992 const uword base_col = aux_col1 + col_num;
1993
1994 arma_debug_check_bounds
1995 (
1996 (col_num >= n_cols)
1997 ||
1998 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
1999 ,
2000 "subview::operator(): indices out of bounds or incorrectly used"
2001 );
2002
2003 return subview_col<eT>(m, base_col, base_row1, submat_n_rows);
2004 }
2005
2006
2007
2008 template<typename eT>
2009 inline
2010 const subview_col<eT>
operator ()(const span & row_span,const uword col_num) const2011 subview<eT>::operator()(const span& row_span, const uword col_num) const
2012 {
2013 arma_extra_debug_sigprint();
2014
2015 const bool row_all = row_span.whole;
2016
2017 const uword local_n_rows = n_rows;
2018
2019 const uword in_row1 = row_all ? 0 : row_span.a;
2020 const uword in_row2 = row_span.b;
2021 const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
2022
2023 const uword base_row1 = aux_row1 + in_row1;
2024 const uword base_col = aux_col1 + col_num;
2025
2026 arma_debug_check_bounds
2027 (
2028 (col_num >= n_cols)
2029 ||
2030 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
2031 ,
2032 "subview::operator(): indices out of bounds or incorrectly used"
2033 );
2034
2035 return subview_col<eT>(m, base_col, base_row1, submat_n_rows);
2036 }
2037
2038
2039
2040 //! create a Col object which uses memory from an existing matrix object.
2041 //! this approach is currently not alias safe
2042 //! and does not take into account that the parent matrix object could be deleted.
2043 //! if deleted memory is accessed by the created Col object,
2044 //! it will cause memory corruption and/or a crash
2045 template<typename eT>
2046 inline
2047 Col<eT>
unsafe_col(const uword col_num)2048 subview<eT>::unsafe_col(const uword col_num)
2049 {
2050 arma_extra_debug_sigprint();
2051
2052 arma_debug_check_bounds( col_num >= n_cols, "subview::unsafe_col(): out of bounds" );
2053
2054 return Col<eT>(colptr(col_num), n_rows, false, true);
2055 }
2056
2057
2058
2059 //! create a Col object which uses memory from an existing matrix object.
2060 //! this approach is currently not alias safe
2061 //! and does not take into account that the parent matrix object could be deleted.
2062 //! if deleted memory is accessed by the created Col object,
2063 //! it will cause memory corruption and/or a crash
2064 template<typename eT>
2065 inline
2066 const Col<eT>
unsafe_col(const uword col_num) const2067 subview<eT>::unsafe_col(const uword col_num) const
2068 {
2069 arma_extra_debug_sigprint();
2070
2071 arma_debug_check_bounds( col_num >= n_cols, "subview::unsafe_col(): out of bounds" );
2072
2073 return Col<eT>(const_cast<eT*>(colptr(col_num)), n_rows, false, true);
2074 }
2075
2076
2077
2078 //! creation of subview (submatrix comprised of specified row vectors)
2079 template<typename eT>
2080 inline
2081 subview<eT>
rows(const uword in_row1,const uword in_row2)2082 subview<eT>::rows(const uword in_row1, const uword in_row2)
2083 {
2084 arma_extra_debug_sigprint();
2085
2086 arma_debug_check_bounds
2087 (
2088 (in_row1 > in_row2) || (in_row2 >= n_rows),
2089 "subview::rows(): indices out of bounds or incorrectly used"
2090 );
2091
2092 const uword subview_n_rows = in_row2 - in_row1 + 1;
2093 const uword base_row1 = aux_row1 + in_row1;
2094
2095 return subview<eT>(m, base_row1, aux_col1, subview_n_rows, n_cols );
2096 }
2097
2098
2099
2100 //! creation of subview (submatrix comprised of specified row vectors)
2101 template<typename eT>
2102 inline
2103 const subview<eT>
rows(const uword in_row1,const uword in_row2) const2104 subview<eT>::rows(const uword in_row1, const uword in_row2) const
2105 {
2106 arma_extra_debug_sigprint();
2107
2108 arma_debug_check_bounds
2109 (
2110 (in_row1 > in_row2) || (in_row2 >= n_rows),
2111 "subview::rows(): indices out of bounds or incorrectly used"
2112 );
2113
2114 const uword subview_n_rows = in_row2 - in_row1 + 1;
2115 const uword base_row1 = aux_row1 + in_row1;
2116
2117 return subview<eT>(m, base_row1, aux_col1, subview_n_rows, n_cols );
2118 }
2119
2120
2121
2122 //! creation of subview (submatrix comprised of specified column vectors)
2123 template<typename eT>
2124 inline
2125 subview<eT>
cols(const uword in_col1,const uword in_col2)2126 subview<eT>::cols(const uword in_col1, const uword in_col2)
2127 {
2128 arma_extra_debug_sigprint();
2129
2130 arma_debug_check_bounds
2131 (
2132 (in_col1 > in_col2) || (in_col2 >= n_cols),
2133 "subview::cols(): indices out of bounds or incorrectly used"
2134 );
2135
2136 const uword subview_n_cols = in_col2 - in_col1 + 1;
2137 const uword base_col1 = aux_col1 + in_col1;
2138
2139 return subview<eT>(m, aux_row1, base_col1, n_rows, subview_n_cols);
2140 }
2141
2142
2143
2144 //! creation of subview (submatrix comprised of specified column vectors)
2145 template<typename eT>
2146 inline
2147 const subview<eT>
cols(const uword in_col1,const uword in_col2) const2148 subview<eT>::cols(const uword in_col1, const uword in_col2) const
2149 {
2150 arma_extra_debug_sigprint();
2151
2152 arma_debug_check_bounds
2153 (
2154 (in_col1 > in_col2) || (in_col2 >= n_cols),
2155 "subview::cols(): indices out of bounds or incorrectly used"
2156 );
2157
2158 const uword subview_n_cols = in_col2 - in_col1 + 1;
2159 const uword base_col1 = aux_col1 + in_col1;
2160
2161 return subview<eT>(m, aux_row1, base_col1, n_rows, subview_n_cols);
2162 }
2163
2164
2165
2166 //! creation of subview (submatrix)
2167 template<typename eT>
2168 inline
2169 subview<eT>
submat(const uword in_row1,const uword in_col1,const uword in_row2,const uword in_col2)2170 subview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2)
2171 {
2172 arma_extra_debug_sigprint();
2173
2174 arma_debug_check_bounds
2175 (
2176 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
2177 "subview::submat(): indices out of bounds or incorrectly used"
2178 );
2179
2180 const uword subview_n_rows = in_row2 - in_row1 + 1;
2181 const uword subview_n_cols = in_col2 - in_col1 + 1;
2182
2183 const uword base_row1 = aux_row1 + in_row1;
2184 const uword base_col1 = aux_col1 + in_col1;
2185
2186 return subview<eT>(m, base_row1, base_col1, subview_n_rows, subview_n_cols);
2187 }
2188
2189
2190
2191 //! creation of subview (generic submatrix)
2192 template<typename eT>
2193 inline
2194 const subview<eT>
submat(const uword in_row1,const uword in_col1,const uword in_row2,const uword in_col2) const2195 subview<eT>::submat(const uword in_row1, const uword in_col1, const uword in_row2, const uword in_col2) const
2196 {
2197 arma_extra_debug_sigprint();
2198
2199 arma_debug_check_bounds
2200 (
2201 (in_row1 > in_row2) || (in_col1 > in_col2) || (in_row2 >= n_rows) || (in_col2 >= n_cols),
2202 "subview::submat(): indices out of bounds or incorrectly used"
2203 );
2204
2205 const uword subview_n_rows = in_row2 - in_row1 + 1;
2206 const uword subview_n_cols = in_col2 - in_col1 + 1;
2207
2208 const uword base_row1 = aux_row1 + in_row1;
2209 const uword base_col1 = aux_col1 + in_col1;
2210
2211 return subview<eT>(m, base_row1, base_col1, subview_n_rows, subview_n_cols);
2212 }
2213
2214
2215
2216 //! creation of subview (submatrix)
2217 template<typename eT>
2218 inline
2219 subview<eT>
submat(const span & row_span,const span & col_span)2220 subview<eT>::submat(const span& row_span, const span& col_span)
2221 {
2222 arma_extra_debug_sigprint();
2223
2224 const bool row_all = row_span.whole;
2225 const bool col_all = col_span.whole;
2226
2227 const uword local_n_rows = n_rows;
2228 const uword local_n_cols = n_cols;
2229
2230 const uword in_row1 = row_all ? 0 : row_span.a;
2231 const uword in_row2 = row_span.b;
2232 const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
2233
2234 const uword in_col1 = col_all ? 0 : col_span.a;
2235 const uword in_col2 = col_span.b;
2236 const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
2237
2238 arma_debug_check_bounds
2239 (
2240 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
2241 ||
2242 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
2243 ,
2244 "subview::submat(): indices out of bounds or incorrectly used"
2245 );
2246
2247 const uword base_row1 = aux_row1 + in_row1;
2248 const uword base_col1 = aux_col1 + in_col1;
2249
2250 return subview<eT>(m, base_row1, base_col1, submat_n_rows, submat_n_cols);
2251 }
2252
2253
2254
2255 //! creation of subview (generic submatrix)
2256 template<typename eT>
2257 inline
2258 const subview<eT>
submat(const span & row_span,const span & col_span) const2259 subview<eT>::submat(const span& row_span, const span& col_span) const
2260 {
2261 arma_extra_debug_sigprint();
2262
2263 const bool row_all = row_span.whole;
2264 const bool col_all = col_span.whole;
2265
2266 const uword local_n_rows = n_rows;
2267 const uword local_n_cols = n_cols;
2268
2269 const uword in_row1 = row_all ? 0 : row_span.a;
2270 const uword in_row2 = row_span.b;
2271 const uword submat_n_rows = row_all ? local_n_rows : in_row2 - in_row1 + 1;
2272
2273 const uword in_col1 = col_all ? 0 : col_span.a;
2274 const uword in_col2 = col_span.b;
2275 const uword submat_n_cols = col_all ? local_n_cols : in_col2 - in_col1 + 1;
2276
2277 arma_debug_check_bounds
2278 (
2279 ( row_all ? false : ((in_row1 > in_row2) || (in_row2 >= local_n_rows)) )
2280 ||
2281 ( col_all ? false : ((in_col1 > in_col2) || (in_col2 >= local_n_cols)) )
2282 ,
2283 "subview::submat(): indices out of bounds or incorrectly used"
2284 );
2285
2286 const uword base_row1 = aux_row1 + in_row1;
2287 const uword base_col1 = aux_col1 + in_col1;
2288
2289 return subview<eT>(m, base_row1, base_col1, submat_n_rows, submat_n_cols);
2290 }
2291
2292
2293
2294 template<typename eT>
2295 inline
2296 subview<eT>
operator ()(const span & row_span,const span & col_span)2297 subview<eT>::operator()(const span& row_span, const span& col_span)
2298 {
2299 arma_extra_debug_sigprint();
2300
2301 return (*this).submat(row_span, col_span);
2302 }
2303
2304
2305
2306 template<typename eT>
2307 inline
2308 const subview<eT>
operator ()(const span & row_span,const span & col_span) const2309 subview<eT>::operator()(const span& row_span, const span& col_span) const
2310 {
2311 arma_extra_debug_sigprint();
2312
2313 return (*this).submat(row_span, col_span);
2314 }
2315
2316
2317
2318 template<typename eT>
2319 inline
2320 subview_each1< subview<eT>, 0 >
each_col()2321 subview<eT>::each_col()
2322 {
2323 arma_extra_debug_sigprint();
2324
2325 return subview_each1< subview<eT>, 0 >(*this);
2326 }
2327
2328
2329
2330 template<typename eT>
2331 inline
2332 subview_each1< subview<eT>, 1 >
each_row()2333 subview<eT>::each_row()
2334 {
2335 arma_extra_debug_sigprint();
2336
2337 return subview_each1< subview<eT>, 1 >(*this);
2338 }
2339
2340
2341
2342 template<typename eT>
2343 template<typename T1>
2344 inline
2345 subview_each2< subview<eT>, 0, T1 >
each_col(const Base<uword,T1> & indices)2346 subview<eT>::each_col(const Base<uword,T1>& indices)
2347 {
2348 arma_extra_debug_sigprint();
2349
2350 return subview_each2< subview<eT>, 0, T1 >(*this, indices);
2351 }
2352
2353
2354
2355 template<typename eT>
2356 template<typename T1>
2357 inline
2358 subview_each2< subview<eT>, 1, T1 >
each_row(const Base<uword,T1> & indices)2359 subview<eT>::each_row(const Base<uword,T1>& indices)
2360 {
2361 arma_extra_debug_sigprint();
2362
2363 return subview_each2< subview<eT>, 1, T1 >(*this, indices);
2364 }
2365
2366
2367
2368 //! apply a lambda function to each column, where each column is interpreted as a column vector
2369 template<typename eT>
2370 inline
2371 void
each_col(const std::function<void (Col<eT> &)> & F)2372 subview<eT>::each_col(const std::function< void(Col<eT>&) >& F)
2373 {
2374 arma_extra_debug_sigprint();
2375
2376 for(uword ii=0; ii < n_cols; ++ii)
2377 {
2378 Col<eT> tmp(colptr(ii), n_rows, false, true);
2379 F(tmp);
2380 }
2381 }
2382
2383
2384
2385 template<typename eT>
2386 inline
2387 void
each_col(const std::function<void (const Col<eT> &)> & F) const2388 subview<eT>::each_col(const std::function< void(const Col<eT>&) >& F) const
2389 {
2390 arma_extra_debug_sigprint();
2391
2392 for(uword ii=0; ii < n_cols; ++ii)
2393 {
2394 const Col<eT> tmp(colptr(ii), n_rows, false, true);
2395 F(tmp);
2396 }
2397 }
2398
2399
2400
2401 //! apply a lambda function to each row, where each row is interpreted as a row vector
2402 template<typename eT>
2403 inline
2404 void
each_row(const std::function<void (Row<eT> &)> & F)2405 subview<eT>::each_row(const std::function< void(Row<eT>&) >& F)
2406 {
2407 arma_extra_debug_sigprint();
2408
2409 podarray<eT> array1(n_cols);
2410 podarray<eT> array2(n_cols);
2411
2412 Row<eT> tmp1( array1.memptr(), n_cols, false, true );
2413 Row<eT> tmp2( array2.memptr(), n_cols, false, true );
2414
2415 eT* tmp1_mem = tmp1.memptr();
2416 eT* tmp2_mem = tmp2.memptr();
2417
2418 uword ii, jj;
2419
2420 for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2)
2421 {
2422 for(uword col_id = 0; col_id < n_cols; ++col_id)
2423 {
2424 const eT* col_mem = colptr(col_id);
2425
2426 tmp1_mem[col_id] = col_mem[ii];
2427 tmp2_mem[col_id] = col_mem[jj];
2428 }
2429
2430 F(tmp1);
2431 F(tmp2);
2432
2433 for(uword col_id = 0; col_id < n_cols; ++col_id)
2434 {
2435 eT* col_mem = colptr(col_id);
2436
2437 col_mem[ii] = tmp1_mem[col_id];
2438 col_mem[jj] = tmp2_mem[col_id];
2439 }
2440 }
2441
2442 if(ii < n_rows)
2443 {
2444 tmp1 = (*this).row(ii);
2445
2446 F(tmp1);
2447
2448 (*this).row(ii) = tmp1;
2449 }
2450 }
2451
2452
2453
2454 template<typename eT>
2455 inline
2456 void
each_row(const std::function<void (const Row<eT> &)> & F) const2457 subview<eT>::each_row(const std::function< void(const Row<eT>&) >& F) const
2458 {
2459 arma_extra_debug_sigprint();
2460
2461 podarray<eT> array1(n_cols);
2462 podarray<eT> array2(n_cols);
2463
2464 Row<eT> tmp1( array1.memptr(), n_cols, false, true );
2465 Row<eT> tmp2( array2.memptr(), n_cols, false, true );
2466
2467 eT* tmp1_mem = tmp1.memptr();
2468 eT* tmp2_mem = tmp2.memptr();
2469
2470 uword ii, jj;
2471
2472 for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2)
2473 {
2474 for(uword col_id = 0; col_id < n_cols; ++col_id)
2475 {
2476 const eT* col_mem = colptr(col_id);
2477
2478 tmp1_mem[col_id] = col_mem[ii];
2479 tmp2_mem[col_id] = col_mem[jj];
2480 }
2481
2482 F(tmp1);
2483 F(tmp2);
2484 }
2485
2486 if(ii < n_rows)
2487 {
2488 tmp1 = (*this).row(ii);
2489
2490 F(tmp1);
2491 }
2492 }
2493
2494
2495
2496 //! creation of diagview (diagonal)
2497 template<typename eT>
2498 inline
2499 diagview<eT>
diag(const sword in_id)2500 subview<eT>::diag(const sword in_id)
2501 {
2502 arma_extra_debug_sigprint();
2503
2504 const uword row_offset = (in_id < 0) ? uword(-in_id) : 0;
2505 const uword col_offset = (in_id > 0) ? uword( in_id) : 0;
2506
2507 arma_debug_check_bounds
2508 (
2509 ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
2510 "subview::diag(): requested diagonal out of bounds"
2511 );
2512
2513 const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
2514
2515 const uword base_row_offset = aux_row1 + row_offset;
2516 const uword base_col_offset = aux_col1 + col_offset;
2517
2518 return diagview<eT>(m, base_row_offset, base_col_offset, len);
2519 }
2520
2521
2522
2523 //! creation of diagview (diagonal)
2524 template<typename eT>
2525 inline
2526 const diagview<eT>
diag(const sword in_id) const2527 subview<eT>::diag(const sword in_id) const
2528 {
2529 arma_extra_debug_sigprint();
2530
2531 const uword row_offset = uword( (in_id < 0) ? -in_id : 0 );
2532 const uword col_offset = uword( (in_id > 0) ? in_id : 0 );
2533
2534 arma_debug_check_bounds
2535 (
2536 ((row_offset > 0) && (row_offset >= n_rows)) || ((col_offset > 0) && (col_offset >= n_cols)),
2537 "subview::diag(): requested diagonal out of bounds"
2538 );
2539
2540 const uword len = (std::min)(n_rows - row_offset, n_cols - col_offset);
2541
2542 const uword base_row_offset = aux_row1 + row_offset;
2543 const uword base_col_offset = aux_col1 + col_offset;
2544
2545 return diagview<eT>(m, base_row_offset, base_col_offset, len);
2546 }
2547
2548
2549
2550 template<typename eT>
2551 inline
2552 void
swap_rows(const uword in_row1,const uword in_row2)2553 subview<eT>::swap_rows(const uword in_row1, const uword in_row2)
2554 {
2555 arma_extra_debug_sigprint();
2556
2557 arma_debug_check_bounds
2558 (
2559 (in_row1 >= n_rows) || (in_row2 >= n_rows),
2560 "subview::swap_rows(): out of bounds"
2561 );
2562
2563 eT* mem = (const_cast< Mat<eT>& >(m)).memptr();
2564
2565 if(n_elem > 0)
2566 {
2567 const uword m_n_rows = m.n_rows;
2568
2569 for(uword ucol=0; ucol < n_cols; ++ucol)
2570 {
2571 const uword offset = (aux_col1 + ucol) * m_n_rows;
2572 const uword pos1 = aux_row1 + in_row1 + offset;
2573 const uword pos2 = aux_row1 + in_row2 + offset;
2574
2575 std::swap( access::rw(mem[pos1]), access::rw(mem[pos2]) );
2576 }
2577 }
2578 }
2579
2580
2581
2582 template<typename eT>
2583 inline
2584 void
swap_cols(const uword in_col1,const uword in_col2)2585 subview<eT>::swap_cols(const uword in_col1, const uword in_col2)
2586 {
2587 arma_extra_debug_sigprint();
2588
2589 arma_debug_check_bounds
2590 (
2591 (in_col1 >= n_cols) || (in_col2 >= n_cols),
2592 "subview::swap_cols(): out of bounds"
2593 );
2594
2595 if(n_elem > 0)
2596 {
2597 eT* ptr1 = colptr(in_col1);
2598 eT* ptr2 = colptr(in_col2);
2599
2600 for(uword urow=0; urow < n_rows; ++urow)
2601 {
2602 std::swap( ptr1[urow], ptr2[urow] );
2603 }
2604 }
2605 }
2606
2607
2608
2609 template<typename eT>
2610 inline
2611 typename subview<eT>::iterator
begin()2612 subview<eT>::begin()
2613 {
2614 return iterator(*this, aux_row1, aux_col1);
2615 }
2616
2617
2618
2619 template<typename eT>
2620 inline
2621 typename subview<eT>::const_iterator
begin() const2622 subview<eT>::begin() const
2623 {
2624 return const_iterator(*this, aux_row1, aux_col1);
2625 }
2626
2627
2628
2629 template<typename eT>
2630 inline
2631 typename subview<eT>::const_iterator
cbegin() const2632 subview<eT>::cbegin() const
2633 {
2634 return const_iterator(*this, aux_row1, aux_col1);
2635 }
2636
2637
2638
2639 template<typename eT>
2640 inline
2641 typename subview<eT>::iterator
end()2642 subview<eT>::end()
2643 {
2644 return iterator(*this, aux_row1, aux_col1 + n_cols);
2645 }
2646
2647
2648
2649 template<typename eT>
2650 inline
2651 typename subview<eT>::const_iterator
end() const2652 subview<eT>::end() const
2653 {
2654 return const_iterator(*this, aux_row1, aux_col1 + n_cols);
2655 }
2656
2657
2658
2659 template<typename eT>
2660 inline
2661 typename subview<eT>::const_iterator
cend() const2662 subview<eT>::cend() const
2663 {
2664 return const_iterator(*this, aux_row1, aux_col1 + n_cols);
2665 }
2666
2667
2668
2669 //
2670 //
2671 //
2672
2673
2674
2675 template<typename eT>
2676 inline
iterator()2677 subview<eT>::iterator::iterator()
2678 : M (nullptr)
2679 , current_ptr(nullptr)
2680 , current_row(0 )
2681 , current_col(0 )
2682 , aux_row1 (0 )
2683 , aux_row2_p1(0 )
2684 {
2685 arma_extra_debug_sigprint();
2686 // Technically this iterator is invalid (it does not point to a valid element)
2687 }
2688
2689
2690
2691 template<typename eT>
2692 inline
iterator(const iterator & X)2693 subview<eT>::iterator::iterator(const iterator& X)
2694 : M (X.M )
2695 , current_ptr(X.current_ptr)
2696 , current_row(X.current_row)
2697 , current_col(X.current_col)
2698 , aux_row1 (X.aux_row1 )
2699 , aux_row2_p1(X.aux_row2_p1)
2700 {
2701 arma_extra_debug_sigprint();
2702 }
2703
2704
2705
2706 template<typename eT>
2707 inline
iterator(subview<eT> & in_sv,const uword in_row,const uword in_col)2708 subview<eT>::iterator::iterator(subview<eT>& in_sv, const uword in_row, const uword in_col)
2709 : M (&(const_cast< Mat<eT>& >(in_sv.m)))
2710 , current_ptr(&(M->at(in_row,in_col)) )
2711 , current_row(in_row )
2712 , current_col(in_col )
2713 , aux_row1 (in_sv.aux_row1 )
2714 , aux_row2_p1(in_sv.aux_row1 + in_sv.n_rows )
2715 {
2716 arma_extra_debug_sigprint();
2717 }
2718
2719
2720
2721 template<typename eT>
2722 inline
2723 arma_warn_unused
2724 eT&
operator *()2725 subview<eT>::iterator::operator*()
2726 {
2727 return (*current_ptr);
2728 }
2729
2730
2731
2732 template<typename eT>
2733 inline
2734 typename subview<eT>::iterator&
operator ++()2735 subview<eT>::iterator::operator++()
2736 {
2737 current_row++;
2738
2739 if(current_row == aux_row2_p1)
2740 {
2741 current_row = aux_row1;
2742 current_col++;
2743
2744 current_ptr = &( (*M).at(current_row,current_col) );
2745 }
2746 else
2747 {
2748 current_ptr++;
2749 }
2750
2751 return *this;
2752 }
2753
2754
2755
2756 template<typename eT>
2757 inline
2758 arma_warn_unused
2759 typename subview<eT>::iterator
operator ++(int)2760 subview<eT>::iterator::operator++(int)
2761 {
2762 typename subview<eT>::iterator temp(*this);
2763
2764 ++(*this);
2765
2766 return temp;
2767 }
2768
2769
2770
2771 template<typename eT>
2772 inline
2773 arma_warn_unused
2774 bool
operator ==(const iterator & rhs) const2775 subview<eT>::iterator::operator==(const iterator& rhs) const
2776 {
2777 return (current_ptr == rhs.current_ptr);
2778 }
2779
2780
2781
2782 template<typename eT>
2783 inline
2784 arma_warn_unused
2785 bool
operator !=(const iterator & rhs) const2786 subview<eT>::iterator::operator!=(const iterator& rhs) const
2787 {
2788 return (current_ptr != rhs.current_ptr);
2789 }
2790
2791
2792
2793 template<typename eT>
2794 inline
2795 arma_warn_unused
2796 bool
operator ==(const const_iterator & rhs) const2797 subview<eT>::iterator::operator==(const const_iterator& rhs) const
2798 {
2799 return (current_ptr == rhs.current_ptr);
2800 }
2801
2802
2803
2804 template<typename eT>
2805 inline
2806 arma_warn_unused
2807 bool
operator !=(const const_iterator & rhs) const2808 subview<eT>::iterator::operator!=(const const_iterator& rhs) const
2809 {
2810 return (current_ptr != rhs.current_ptr);
2811 }
2812
2813
2814
2815 //
2816 //
2817 //
2818
2819
2820
2821 template<typename eT>
2822 inline
const_iterator()2823 subview<eT>::const_iterator::const_iterator()
2824 : M (nullptr)
2825 , current_ptr(nullptr)
2826 , current_row(0 )
2827 , current_col(0 )
2828 , aux_row1 (0 )
2829 , aux_row2_p1(0 )
2830 {
2831 arma_extra_debug_sigprint();
2832 // Technically this iterator is invalid (it does not point to a valid element)
2833 }
2834
2835
2836
2837 template<typename eT>
2838 inline
const_iterator(const iterator & X)2839 subview<eT>::const_iterator::const_iterator(const iterator& X)
2840 : M (X.M )
2841 , current_ptr(X.current_ptr)
2842 , current_row(X.current_row)
2843 , current_col(X.current_col)
2844 , aux_row1 (X.aux_row1 )
2845 , aux_row2_p1(X.aux_row2_p1)
2846 {
2847 arma_extra_debug_sigprint();
2848 }
2849
2850
2851
2852 template<typename eT>
2853 inline
const_iterator(const const_iterator & X)2854 subview<eT>::const_iterator::const_iterator(const const_iterator& X)
2855 : M (X.M )
2856 , current_ptr(X.current_ptr)
2857 , current_row(X.current_row)
2858 , current_col(X.current_col)
2859 , aux_row1 (X.aux_row1 )
2860 , aux_row2_p1(X.aux_row2_p1)
2861 {
2862 arma_extra_debug_sigprint();
2863 }
2864
2865
2866
2867 template<typename eT>
2868 inline
const_iterator(const subview<eT> & in_sv,const uword in_row,const uword in_col)2869 subview<eT>::const_iterator::const_iterator(const subview<eT>& in_sv, const uword in_row, const uword in_col)
2870 : M (&(in_sv.m) )
2871 , current_ptr(&(M->at(in_row,in_col)) )
2872 , current_row(in_row )
2873 , current_col(in_col )
2874 , aux_row1 (in_sv.aux_row1 )
2875 , aux_row2_p1(in_sv.aux_row1 + in_sv.n_rows)
2876 {
2877 arma_extra_debug_sigprint();
2878 }
2879
2880
2881
2882 template<typename eT>
2883 inline
2884 arma_warn_unused
2885 const eT&
operator *()2886 subview<eT>::const_iterator::operator*()
2887 {
2888 return (*current_ptr);
2889 }
2890
2891
2892
2893 template<typename eT>
2894 inline
2895 typename subview<eT>::const_iterator&
operator ++()2896 subview<eT>::const_iterator::operator++()
2897 {
2898 current_row++;
2899
2900 if(current_row == aux_row2_p1)
2901 {
2902 current_row = aux_row1;
2903 current_col++;
2904
2905 current_ptr = &( (*M).at(current_row,current_col) );
2906 }
2907 else
2908 {
2909 current_ptr++;
2910 }
2911
2912 return *this;
2913 }
2914
2915
2916
2917 template<typename eT>
2918 inline
2919 arma_warn_unused
2920 typename subview<eT>::const_iterator
operator ++(int)2921 subview<eT>::const_iterator::operator++(int)
2922 {
2923 typename subview<eT>::const_iterator temp(*this);
2924
2925 ++(*this);
2926
2927 return temp;
2928 }
2929
2930
2931
2932 template<typename eT>
2933 inline
2934 arma_warn_unused
2935 bool
operator ==(const iterator & rhs) const2936 subview<eT>::const_iterator::operator==(const iterator& rhs) const
2937 {
2938 return (current_ptr == rhs.current_ptr);
2939 }
2940
2941
2942
2943 template<typename eT>
2944 inline
2945 arma_warn_unused
2946 bool
operator !=(const iterator & rhs) const2947 subview<eT>::const_iterator::operator!=(const iterator& rhs) const
2948 {
2949 return (current_ptr != rhs.current_ptr);
2950 }
2951
2952
2953
2954 template<typename eT>
2955 inline
2956 arma_warn_unused
2957 bool
operator ==(const const_iterator & rhs) const2958 subview<eT>::const_iterator::operator==(const const_iterator& rhs) const
2959 {
2960 return (current_ptr == rhs.current_ptr);
2961 }
2962
2963
2964
2965 template<typename eT>
2966 inline
2967 arma_warn_unused
2968 bool
operator !=(const const_iterator & rhs) const2969 subview<eT>::const_iterator::operator!=(const const_iterator& rhs) const
2970 {
2971 return (current_ptr != rhs.current_ptr);
2972 }
2973
2974
2975
2976 //
2977 //
2978 //
2979
2980
2981
2982 template<typename eT>
2983 inline
row_iterator()2984 subview<eT>::row_iterator::row_iterator()
2985 : M (nullptr)
2986 , current_row(0 )
2987 , current_col(0 )
2988 , aux_col1 (0 )
2989 , aux_col2_p1(0 )
2990 {
2991 arma_extra_debug_sigprint();
2992 // Technically this iterator is invalid (it does not point to a valid element)
2993 }
2994
2995
2996
2997 template<typename eT>
2998 inline
row_iterator(const row_iterator & X)2999 subview<eT>::row_iterator::row_iterator(const row_iterator& X)
3000 : M (X.M )
3001 , current_row(X.current_row)
3002 , current_col(X.current_col)
3003 , aux_col1 (X.aux_col1 )
3004 , aux_col2_p1(X.aux_col2_p1)
3005 {
3006 arma_extra_debug_sigprint();
3007 }
3008
3009
3010
3011 template<typename eT>
3012 inline
row_iterator(subview<eT> & in_sv,const uword in_row,const uword in_col)3013 subview<eT>::row_iterator::row_iterator(subview<eT>& in_sv, const uword in_row, const uword in_col)
3014 : M (&(const_cast< Mat<eT>& >(in_sv.m)))
3015 , current_row(in_row )
3016 , current_col(in_col )
3017 , aux_col1 (in_sv.aux_col1 )
3018 , aux_col2_p1(in_sv.aux_col1 + in_sv.n_cols )
3019 {
3020 arma_extra_debug_sigprint();
3021 }
3022
3023
3024
3025 template<typename eT>
3026 inline
3027 arma_warn_unused
3028 eT&
operator *()3029 subview<eT>::row_iterator::operator*()
3030 {
3031 return M->at(current_row,current_col);
3032 }
3033
3034
3035
3036 template<typename eT>
3037 inline
3038 typename subview<eT>::row_iterator&
operator ++()3039 subview<eT>::row_iterator::operator++()
3040 {
3041 current_col++;
3042
3043 if(current_col == aux_col2_p1)
3044 {
3045 current_col = aux_col1;
3046 current_row++;
3047 }
3048
3049 return *this;
3050 }
3051
3052
3053
3054 template<typename eT>
3055 inline
3056 arma_warn_unused
3057 typename subview<eT>::row_iterator
operator ++(int)3058 subview<eT>::row_iterator::operator++(int)
3059 {
3060 typename subview<eT>::row_iterator temp(*this);
3061
3062 ++(*this);
3063
3064 return temp;
3065 }
3066
3067
3068
3069 template<typename eT>
3070 inline
3071 arma_warn_unused
3072 bool
operator ==(const row_iterator & rhs) const3073 subview<eT>::row_iterator::operator==(const row_iterator& rhs) const
3074 {
3075 return ( (current_row == rhs.current_row) && (current_col == rhs.current_col) );
3076 }
3077
3078
3079
3080 template<typename eT>
3081 inline
3082 arma_warn_unused
3083 bool
operator !=(const row_iterator & rhs) const3084 subview<eT>::row_iterator::operator!=(const row_iterator& rhs) const
3085 {
3086 return ( (current_row != rhs.current_row) || (current_col != rhs.current_col) );
3087 }
3088
3089
3090
3091 template<typename eT>
3092 inline
3093 arma_warn_unused
3094 bool
operator ==(const const_row_iterator & rhs) const3095 subview<eT>::row_iterator::operator==(const const_row_iterator& rhs) const
3096 {
3097 return ( (current_row == rhs.current_row) && (current_col == rhs.current_col) );
3098 }
3099
3100
3101
3102 template<typename eT>
3103 inline
3104 arma_warn_unused
3105 bool
operator !=(const const_row_iterator & rhs) const3106 subview<eT>::row_iterator::operator!=(const const_row_iterator& rhs) const
3107 {
3108 return ( (current_row != rhs.current_row) || (current_col != rhs.current_col) );
3109 }
3110
3111
3112
3113 //
3114 //
3115 //
3116
3117
3118
3119 template<typename eT>
3120 inline
const_row_iterator()3121 subview<eT>::const_row_iterator::const_row_iterator()
3122 : M (nullptr)
3123 , current_row(0 )
3124 , current_col(0 )
3125 , aux_col1 (0 )
3126 , aux_col2_p1(0 )
3127 {
3128 arma_extra_debug_sigprint();
3129 // Technically this iterator is invalid (it does not point to a valid element)
3130 }
3131
3132
3133
3134 template<typename eT>
3135 inline
const_row_iterator(const row_iterator & X)3136 subview<eT>::const_row_iterator::const_row_iterator(const row_iterator& X)
3137 : M (X.M )
3138 , current_row(X.current_row)
3139 , current_col(X.current_col)
3140 , aux_col1 (X.aux_col1 )
3141 , aux_col2_p1(X.aux_col2_p1)
3142 {
3143 arma_extra_debug_sigprint();
3144 }
3145
3146
3147
3148 template<typename eT>
3149 inline
const_row_iterator(const const_row_iterator & X)3150 subview<eT>::const_row_iterator::const_row_iterator(const const_row_iterator& X)
3151 : M (X.M )
3152 , current_row(X.current_row)
3153 , current_col(X.current_col)
3154 , aux_col1 (X.aux_col1 )
3155 , aux_col2_p1(X.aux_col2_p1)
3156 {
3157 arma_extra_debug_sigprint();
3158 }
3159
3160
3161
3162 template<typename eT>
3163 inline
const_row_iterator(const subview<eT> & in_sv,const uword in_row,const uword in_col)3164 subview<eT>::const_row_iterator::const_row_iterator(const subview<eT>& in_sv, const uword in_row, const uword in_col)
3165 : M (&(in_sv.m) )
3166 , current_row(in_row )
3167 , current_col(in_col )
3168 , aux_col1 (in_sv.aux_col1 )
3169 , aux_col2_p1(in_sv.aux_col1 + in_sv.n_cols)
3170 {
3171 arma_extra_debug_sigprint();
3172 }
3173
3174
3175
3176 template<typename eT>
3177 inline
3178 arma_warn_unused
3179 const eT&
operator *() const3180 subview<eT>::const_row_iterator::operator*() const
3181 {
3182 return M->at(current_row,current_col);
3183 }
3184
3185
3186
3187 template<typename eT>
3188 inline
3189 typename subview<eT>::const_row_iterator&
operator ++()3190 subview<eT>::const_row_iterator::operator++()
3191 {
3192 current_col++;
3193
3194 if(current_col == aux_col2_p1)
3195 {
3196 current_col = aux_col1;
3197 current_row++;
3198 }
3199
3200 return *this;
3201 }
3202
3203
3204
3205 template<typename eT>
3206 inline
3207 arma_warn_unused
3208 typename subview<eT>::const_row_iterator
operator ++(int)3209 subview<eT>::const_row_iterator::operator++(int)
3210 {
3211 typename subview<eT>::const_row_iterator temp(*this);
3212
3213 ++(*this);
3214
3215 return temp;
3216 }
3217
3218
3219
3220 template<typename eT>
3221 inline
3222 arma_warn_unused
3223 bool
operator ==(const row_iterator & rhs) const3224 subview<eT>::const_row_iterator::operator==(const row_iterator& rhs) const
3225 {
3226 return ( (current_row == rhs.current_row) && (current_col == rhs.current_col) );
3227 }
3228
3229
3230
3231 template<typename eT>
3232 inline
3233 arma_warn_unused
3234 bool
operator !=(const row_iterator & rhs) const3235 subview<eT>::const_row_iterator::operator!=(const row_iterator& rhs) const
3236 {
3237 return ( (current_row != rhs.current_row) || (current_col != rhs.current_col) );
3238 }
3239
3240
3241
3242 template<typename eT>
3243 inline
3244 arma_warn_unused
3245 bool
operator ==(const const_row_iterator & rhs) const3246 subview<eT>::const_row_iterator::operator==(const const_row_iterator& rhs) const
3247 {
3248 return ( (current_row == rhs.current_row) && (current_col == rhs.current_col) );
3249 }
3250
3251
3252
3253 template<typename eT>
3254 inline
3255 arma_warn_unused
3256 bool
operator !=(const const_row_iterator & rhs) const3257 subview<eT>::const_row_iterator::operator!=(const const_row_iterator& rhs) const
3258 {
3259 return ( (current_row != rhs.current_row) || (current_col != rhs.current_col) );
3260 }
3261
3262
3263
3264 //
3265 //
3266 //
3267
3268
3269
3270 template<typename eT>
3271 inline
subview_col(const Mat<eT> & in_m,const uword in_col)3272 subview_col<eT>::subview_col(const Mat<eT>& in_m, const uword in_col)
3273 : subview<eT>(in_m, 0, in_col, in_m.n_rows, 1)
3274 , colmem(subview<eT>::colptr(0))
3275 {
3276 arma_extra_debug_sigprint();
3277 }
3278
3279
3280
3281 template<typename eT>
3282 inline
subview_col(const Mat<eT> & in_m,const uword in_col,const uword in_row1,const uword in_n_rows)3283 subview_col<eT>::subview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
3284 : subview<eT>(in_m, in_row1, in_col, in_n_rows, 1)
3285 , colmem(subview<eT>::colptr(0))
3286 {
3287 arma_extra_debug_sigprint();
3288 }
3289
3290
3291
3292 template<typename eT>
3293 inline
subview_col(const subview_col<eT> & in)3294 subview_col<eT>::subview_col(const subview_col<eT>& in)
3295 : subview<eT>(in) // interprets 'subview_col' as 'subview'
3296 , colmem(in.colmem)
3297 {
3298 arma_extra_debug_sigprint();
3299 }
3300
3301
3302
3303 template<typename eT>
3304 inline
subview_col(subview_col<eT> && in)3305 subview_col<eT>::subview_col(subview_col<eT>&& in)
3306 : subview<eT>(std::move(in)) // interprets 'subview_col' as 'subview'
3307 , colmem(in.colmem)
3308 {
3309 arma_extra_debug_sigprint();
3310
3311 access::rw(in.colmem) = nullptr;
3312 }
3313
3314
3315
3316 template<typename eT>
3317 inline
3318 void
operator =(const subview<eT> & X)3319 subview_col<eT>::operator=(const subview<eT>& X)
3320 {
3321 arma_extra_debug_sigprint();
3322
3323 subview<eT>::operator=(X);
3324 }
3325
3326
3327
3328 template<typename eT>
3329 inline
3330 void
operator =(const subview_col<eT> & X)3331 subview_col<eT>::operator=(const subview_col<eT>& X)
3332 {
3333 arma_extra_debug_sigprint();
3334
3335 subview<eT>::operator=(X); // interprets 'subview_col' as 'subview'
3336 }
3337
3338
3339
3340 template<typename eT>
3341 inline
3342 void
operator =(const std::initializer_list<eT> & list)3343 subview_col<eT>::operator=(const std::initializer_list<eT>& list)
3344 {
3345 arma_extra_debug_sigprint();
3346
3347 const uword N = uword(list.size());
3348
3349 arma_debug_assert_same_size(subview<eT>::n_rows, subview<eT>::n_cols, N, 1, "copy into submatrix");
3350
3351 arrayops::copy( access::rwp(colmem), list.begin(), N );
3352 }
3353
3354
3355
3356 template<typename eT>
3357 inline
3358 void
operator =(const eT val)3359 subview_col<eT>::operator=(const eT val)
3360 {
3361 arma_extra_debug_sigprint();
3362
3363 if(subview<eT>::n_elem != 1)
3364 {
3365 arma_debug_assert_same_size(subview<eT>::n_rows, subview<eT>::n_cols, 1, 1, "copy into submatrix");
3366 }
3367
3368 access::rw( colmem[0] ) = val;
3369 }
3370
3371
3372
3373 template<typename eT>
3374 template<typename T1>
3375 inline
3376 void
operator =(const Base<eT,T1> & X)3377 subview_col<eT>::operator=(const Base<eT,T1>& X)
3378 {
3379 arma_extra_debug_sigprint();
3380
3381 subview<eT>::operator=(X);
3382 }
3383
3384
3385
3386 template<typename eT>
3387 template<typename T1>
3388 inline
3389 void
operator =(const SpBase<eT,T1> & X)3390 subview_col<eT>::operator=(const SpBase<eT,T1>& X)
3391 {
3392 arma_extra_debug_sigprint();
3393
3394 subview<eT>::operator=(X.get_ref());
3395 }
3396
3397
3398
3399 template<typename eT>
3400 template<typename T1, typename gen_type>
3401 inline
3402 typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void>::result
operator =(const Gen<T1,gen_type> & in)3403 subview_col<eT>::operator= (const Gen<T1,gen_type>& in)
3404 {
3405 arma_extra_debug_sigprint();
3406
3407 arma_debug_assert_same_size(subview<eT>::n_rows, uword(1), in.n_rows, (in.is_col ? uword(1) : in.n_cols), "copy into submatrix");
3408
3409 in.apply(*this);
3410 }
3411
3412
3413
3414 template<typename eT>
3415 arma_inline
3416 arma_warn_unused
3417 const Op<subview_col<eT>,op_htrans>
t() const3418 subview_col<eT>::t() const
3419 {
3420 return Op<subview_col<eT>,op_htrans>(*this);
3421 }
3422
3423
3424
3425 template<typename eT>
3426 arma_inline
3427 arma_warn_unused
3428 const Op<subview_col<eT>,op_htrans>
ht() const3429 subview_col<eT>::ht() const
3430 {
3431 return Op<subview_col<eT>,op_htrans>(*this);
3432 }
3433
3434
3435
3436 template<typename eT>
3437 arma_inline
3438 arma_warn_unused
3439 const Op<subview_col<eT>,op_strans>
st() const3440 subview_col<eT>::st() const
3441 {
3442 return Op<subview_col<eT>,op_strans>(*this);
3443 }
3444
3445
3446
3447 template<typename eT>
3448 arma_inline
3449 arma_warn_unused
3450 const Op<subview_col<eT>,op_strans>
as_row() const3451 subview_col<eT>::as_row() const
3452 {
3453 return Op<subview_col<eT>,op_strans>(*this);
3454 }
3455
3456
3457
3458 template<typename eT>
3459 inline
3460 void
fill(const eT val)3461 subview_col<eT>::fill(const eT val)
3462 {
3463 arma_extra_debug_sigprint();
3464
3465 arrayops::inplace_set( access::rwp(colmem), val, subview<eT>::n_rows );
3466 }
3467
3468
3469
3470 template<typename eT>
3471 inline
3472 void
zeros()3473 subview_col<eT>::zeros()
3474 {
3475 arma_extra_debug_sigprint();
3476
3477 arrayops::fill_zeros( access::rwp(colmem), subview<eT>::n_rows );
3478 }
3479
3480
3481
3482 template<typename eT>
3483 inline
3484 void
ones()3485 subview_col<eT>::ones()
3486 {
3487 arma_extra_debug_sigprint();
3488
3489 arrayops::inplace_set( access::rwp(colmem), eT(1), subview<eT>::n_rows );
3490 }
3491
3492
3493
3494 template<typename eT>
3495 arma_inline
3496 eT
at_alt(const uword ii) const3497 subview_col<eT>::at_alt(const uword ii) const
3498 {
3499 const eT* colmem_aligned = colmem;
3500 memory::mark_as_aligned(colmem_aligned);
3501
3502 return colmem_aligned[ii];
3503 }
3504
3505
3506
3507 template<typename eT>
3508 arma_inline
3509 eT&
operator [](const uword ii)3510 subview_col<eT>::operator[](const uword ii)
3511 {
3512 return access::rw( colmem[ii] );
3513 }
3514
3515
3516
3517 template<typename eT>
3518 arma_inline
3519 eT
operator [](const uword ii) const3520 subview_col<eT>::operator[](const uword ii) const
3521 {
3522 return colmem[ii];
3523 }
3524
3525
3526
3527 template<typename eT>
3528 inline
3529 eT&
operator ()(const uword ii)3530 subview_col<eT>::operator()(const uword ii)
3531 {
3532 arma_debug_check_bounds( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds" );
3533
3534 return access::rw( colmem[ii] );
3535 }
3536
3537
3538
3539 template<typename eT>
3540 inline
3541 eT
operator ()(const uword ii) const3542 subview_col<eT>::operator()(const uword ii) const
3543 {
3544 arma_debug_check_bounds( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds" );
3545
3546 return colmem[ii];
3547 }
3548
3549
3550
3551 template<typename eT>
3552 inline
3553 eT&
operator ()(const uword in_row,const uword in_col)3554 subview_col<eT>::operator()(const uword in_row, const uword in_col)
3555 {
3556 arma_debug_check_bounds( ((in_row >= subview<eT>::n_rows) || (in_col > 0)), "subview::operator(): index out of bounds" );
3557
3558 return access::rw( colmem[in_row] );
3559 }
3560
3561
3562
3563 template<typename eT>
3564 inline
3565 eT
operator ()(const uword in_row,const uword in_col) const3566 subview_col<eT>::operator()(const uword in_row, const uword in_col) const
3567 {
3568 arma_debug_check_bounds( ((in_row >= subview<eT>::n_rows) || (in_col > 0)), "subview::operator(): index out of bounds" );
3569
3570 return colmem[in_row];
3571 }
3572
3573
3574
3575 template<typename eT>
3576 inline
3577 eT&
at(const uword in_row,const uword)3578 subview_col<eT>::at(const uword in_row, const uword)
3579 {
3580 return access::rw( colmem[in_row] );
3581 }
3582
3583
3584
3585 template<typename eT>
3586 inline
3587 eT
at(const uword in_row,const uword) const3588 subview_col<eT>::at(const uword in_row, const uword) const
3589 {
3590 return colmem[in_row];
3591 }
3592
3593
3594
3595 template<typename eT>
3596 arma_inline
3597 eT*
colptr(const uword)3598 subview_col<eT>::colptr(const uword)
3599 {
3600 return const_cast<eT*>(colmem);
3601 }
3602
3603
3604 template<typename eT>
3605 arma_inline
3606 const eT*
colptr(const uword) const3607 subview_col<eT>::colptr(const uword) const
3608 {
3609 return colmem;
3610 }
3611
3612
3613 template<typename eT>
3614 inline
3615 subview_col<eT>
rows(const uword in_row1,const uword in_row2)3616 subview_col<eT>::rows(const uword in_row1, const uword in_row2)
3617 {
3618 arma_extra_debug_sigprint();
3619
3620 arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used" );
3621
3622 const uword subview_n_rows = in_row2 - in_row1 + 1;
3623
3624 const uword base_row1 = this->aux_row1 + in_row1;
3625
3626 return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
3627 }
3628
3629
3630
3631 template<typename eT>
3632 inline
3633 const subview_col<eT>
rows(const uword in_row1,const uword in_row2) const3634 subview_col<eT>::rows(const uword in_row1, const uword in_row2) const
3635 {
3636 arma_extra_debug_sigprint();
3637
3638 arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::rows(): indices out of bounds or incorrectly used" );
3639
3640 const uword subview_n_rows = in_row2 - in_row1 + 1;
3641
3642 const uword base_row1 = this->aux_row1 + in_row1;
3643
3644 return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
3645 }
3646
3647
3648
3649 template<typename eT>
3650 inline
3651 subview_col<eT>
subvec(const uword in_row1,const uword in_row2)3652 subview_col<eT>::subvec(const uword in_row1, const uword in_row2)
3653 {
3654 arma_extra_debug_sigprint();
3655
3656 arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used" );
3657
3658 const uword subview_n_rows = in_row2 - in_row1 + 1;
3659
3660 const uword base_row1 = this->aux_row1 + in_row1;
3661
3662 return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
3663 }
3664
3665
3666
3667 template<typename eT>
3668 inline
3669 const subview_col<eT>
subvec(const uword in_row1,const uword in_row2) const3670 subview_col<eT>::subvec(const uword in_row1, const uword in_row2) const
3671 {
3672 arma_extra_debug_sigprint();
3673
3674 arma_debug_check_bounds( ( (in_row1 > in_row2) || (in_row2 >= subview<eT>::n_rows) ), "subview_col::subvec(): indices out of bounds or incorrectly used" );
3675
3676 const uword subview_n_rows = in_row2 - in_row1 + 1;
3677
3678 const uword base_row1 = this->aux_row1 + in_row1;
3679
3680 return subview_col<eT>(this->m, this->aux_col1, base_row1, subview_n_rows);
3681 }
3682
3683
3684
3685 template<typename eT>
3686 inline
3687 subview_col<eT>
subvec(const uword start_row,const SizeMat & s)3688 subview_col<eT>::subvec(const uword start_row, const SizeMat& s)
3689 {
3690 arma_extra_debug_sigprint();
3691
3692 arma_debug_check( (s.n_cols != 1), "subview_col::subvec(): given size does not specify a column vector" );
3693
3694 arma_debug_check_bounds( ( (start_row >= subview<eT>::n_rows) || ((start_row + s.n_rows) > subview<eT>::n_rows) ), "subview_col::subvec(): size out of bounds" );
3695
3696 const uword base_row1 = this->aux_row1 + start_row;
3697
3698 return subview_col<eT>(this->m, this->aux_col1, base_row1, s.n_rows);
3699 }
3700
3701
3702
3703 template<typename eT>
3704 inline
3705 const subview_col<eT>
subvec(const uword start_row,const SizeMat & s) const3706 subview_col<eT>::subvec(const uword start_row, const SizeMat& s) const
3707 {
3708 arma_extra_debug_sigprint();
3709
3710 arma_debug_check( (s.n_cols != 1), "subview_col::subvec(): given size does not specify a column vector" );
3711
3712 arma_debug_check_bounds( ( (start_row >= subview<eT>::n_rows) || ((start_row + s.n_rows) > subview<eT>::n_rows) ), "subview_col::subvec(): size out of bounds" );
3713
3714 const uword base_row1 = this->aux_row1 + start_row;
3715
3716 return subview_col<eT>(this->m, this->aux_col1, base_row1, s.n_rows);
3717 }
3718
3719
3720
3721 template<typename eT>
3722 inline
3723 subview_col<eT>
head(const uword N)3724 subview_col<eT>::head(const uword N)
3725 {
3726 arma_extra_debug_sigprint();
3727
3728 arma_debug_check_bounds( (N > subview<eT>::n_rows), "subview_col::head(): size out of bounds" );
3729
3730 return subview_col<eT>(this->m, this->aux_col1, this->aux_row1, N);
3731 }
3732
3733
3734
3735 template<typename eT>
3736 inline
3737 const subview_col<eT>
head(const uword N) const3738 subview_col<eT>::head(const uword N) const
3739 {
3740 arma_extra_debug_sigprint();
3741
3742 arma_debug_check_bounds( (N > subview<eT>::n_rows), "subview_col::head(): size out of bounds" );
3743
3744 return subview_col<eT>(this->m, this->aux_col1, this->aux_row1, N);
3745 }
3746
3747
3748
3749 template<typename eT>
3750 inline
3751 subview_col<eT>
tail(const uword N)3752 subview_col<eT>::tail(const uword N)
3753 {
3754 arma_extra_debug_sigprint();
3755
3756 arma_debug_check_bounds( (N > subview<eT>::n_rows), "subview_col::tail(): size out of bounds" );
3757
3758 const uword start_row = subview<eT>::aux_row1 + subview<eT>::n_rows - N;
3759
3760 return subview_col<eT>(this->m, this->aux_col1, start_row, N);
3761 }
3762
3763
3764
3765 template<typename eT>
3766 inline
3767 const subview_col<eT>
tail(const uword N) const3768 subview_col<eT>::tail(const uword N) const
3769 {
3770 arma_extra_debug_sigprint();
3771
3772 arma_debug_check_bounds( (N > subview<eT>::n_rows), "subview_col::tail(): size out of bounds" );
3773
3774 const uword start_row = subview<eT>::aux_row1 + subview<eT>::n_rows - N;
3775
3776 return subview_col<eT>(this->m, this->aux_col1, start_row, N);
3777 }
3778
3779
3780
3781 template<typename eT>
3782 inline
3783 arma_warn_unused
3784 eT
min() const3785 subview_col<eT>::min() const
3786 {
3787 arma_extra_debug_sigprint();
3788
3789 if(subview<eT>::n_elem == 0)
3790 {
3791 arma_debug_check(true, "min(): object has no elements");
3792
3793 return Datum<eT>::nan;
3794 }
3795
3796 return op_min::direct_min(colmem, subview<eT>::n_elem);
3797 }
3798
3799
3800
3801 template<typename eT>
3802 inline
3803 arma_warn_unused
3804 eT
max() const3805 subview_col<eT>::max() const
3806 {
3807 arma_extra_debug_sigprint();
3808
3809 if(subview<eT>::n_elem == 0)
3810 {
3811 arma_debug_check(true, "max(): object has no elements");
3812
3813 return Datum<eT>::nan;
3814 }
3815
3816 return op_max::direct_max(colmem, subview<eT>::n_elem);
3817 }
3818
3819
3820
3821 template<typename eT>
3822 inline
3823 eT
min(uword & index_of_min_val) const3824 subview_col<eT>::min(uword& index_of_min_val) const
3825 {
3826 arma_extra_debug_sigprint();
3827
3828 if(subview<eT>::n_elem == 0)
3829 {
3830 arma_debug_check(true, "min(): object has no elements");
3831
3832 index_of_min_val = uword(0);
3833
3834 return Datum<eT>::nan;
3835 }
3836 else
3837 {
3838 return op_min::direct_min(colmem, subview<eT>::n_elem, index_of_min_val);
3839 }
3840 }
3841
3842
3843
3844 template<typename eT>
3845 inline
3846 eT
max(uword & index_of_max_val) const3847 subview_col<eT>::max(uword& index_of_max_val) const
3848 {
3849 arma_extra_debug_sigprint();
3850
3851 if(subview<eT>::n_elem == 0)
3852 {
3853 arma_debug_check(true, "max(): object has no elements");
3854
3855 index_of_max_val = uword(0);
3856
3857 return Datum<eT>::nan;
3858 }
3859 else
3860 {
3861 return op_max::direct_max(colmem, subview<eT>::n_elem, index_of_max_val);
3862 }
3863 }
3864
3865
3866
3867 template<typename eT>
3868 inline
3869 arma_warn_unused
3870 uword
index_min() const3871 subview_col<eT>::index_min() const
3872 {
3873 arma_extra_debug_sigprint();
3874
3875 uword index = 0;
3876
3877 if(subview<eT>::n_elem == 0)
3878 {
3879 arma_debug_check(true, "index_min(): object has no elements");
3880 }
3881 else
3882 {
3883 op_min::direct_min(colmem, subview<eT>::n_elem, index);
3884 }
3885
3886 return index;
3887 }
3888
3889
3890
3891 template<typename eT>
3892 inline
3893 arma_warn_unused
3894 uword
index_max() const3895 subview_col<eT>::index_max() const
3896 {
3897 arma_extra_debug_sigprint();
3898
3899 uword index = 0;
3900
3901 if(subview<eT>::n_elem == 0)
3902 {
3903 arma_debug_check(true, "index_max(): object has no elements");
3904 }
3905 else
3906 {
3907 op_max::direct_max(colmem, subview<eT>::n_elem, index);
3908 }
3909
3910 return index;
3911 }
3912
3913
3914
3915 //
3916 //
3917 //
3918
3919
3920 template<typename eT>
3921 inline
subview_cols(const Mat<eT> & in_m,const uword in_col1,const uword in_n_cols)3922 subview_cols<eT>::subview_cols(const Mat<eT>& in_m, const uword in_col1, const uword in_n_cols)
3923 : subview<eT>(in_m, 0, in_col1, in_m.n_rows, in_n_cols)
3924 {
3925 arma_extra_debug_sigprint();
3926 }
3927
3928
3929
3930 template<typename eT>
3931 inline
subview_cols(const subview_cols<eT> & in)3932 subview_cols<eT>::subview_cols(const subview_cols<eT>& in)
3933 : subview<eT>(in) // interprets 'subview_cols' as 'subview'
3934 {
3935 arma_extra_debug_sigprint();
3936 }
3937
3938
3939
3940 template<typename eT>
3941 inline
subview_cols(subview_cols<eT> && in)3942 subview_cols<eT>::subview_cols(subview_cols<eT>&& in)
3943 : subview<eT>(std::move(in)) // interprets 'subview_cols' as 'subview'
3944 {
3945 arma_extra_debug_sigprint();
3946 }
3947
3948
3949
3950 template<typename eT>
3951 inline
3952 void
operator =(const subview<eT> & X)3953 subview_cols<eT>::operator=(const subview<eT>& X)
3954 {
3955 arma_extra_debug_sigprint();
3956
3957 subview<eT>::operator=(X);
3958 }
3959
3960
3961
3962 template<typename eT>
3963 inline
3964 void
operator =(const subview_cols<eT> & X)3965 subview_cols<eT>::operator=(const subview_cols<eT>& X)
3966 {
3967 arma_extra_debug_sigprint();
3968
3969 subview<eT>::operator=(X); // interprets 'subview_cols' as 'subview'
3970 }
3971
3972
3973
3974 template<typename eT>
3975 inline
3976 void
operator =(const std::initializer_list<eT> & list)3977 subview_cols<eT>::operator=(const std::initializer_list<eT>& list)
3978 {
3979 arma_extra_debug_sigprint();
3980
3981 subview<eT>::operator=(list);
3982 }
3983
3984
3985
3986 template<typename eT>
3987 inline
3988 void
operator =(const std::initializer_list<std::initializer_list<eT>> & list)3989 subview_cols<eT>::operator=(const std::initializer_list< std::initializer_list<eT> >& list)
3990 {
3991 arma_extra_debug_sigprint();
3992
3993 subview<eT>::operator=(list);
3994 }
3995
3996
3997
3998 template<typename eT>
3999 inline
4000 void
operator =(const eT val)4001 subview_cols<eT>::operator=(const eT val)
4002 {
4003 arma_extra_debug_sigprint();
4004
4005 subview<eT>::operator=(val);
4006 }
4007
4008
4009
4010 template<typename eT>
4011 template<typename T1>
4012 inline
4013 void
operator =(const Base<eT,T1> & X)4014 subview_cols<eT>::operator=(const Base<eT,T1>& X)
4015 {
4016 arma_extra_debug_sigprint();
4017
4018 subview<eT>::operator=(X.get_ref());
4019 }
4020
4021
4022
4023 template<typename eT>
4024 template<typename T1>
4025 inline
4026 void
operator =(const SpBase<eT,T1> & X)4027 subview_cols<eT>::operator=(const SpBase<eT,T1>& X)
4028 {
4029 arma_extra_debug_sigprint();
4030
4031 subview<eT>::operator=(X.get_ref());
4032 }
4033
4034
4035
4036 template<typename eT>
4037 template<typename T1, typename gen_type>
4038 inline
4039 typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void>::result
operator =(const Gen<T1,gen_type> & in)4040 subview_cols<eT>::operator= (const Gen<T1,gen_type>& in)
4041 {
4042 arma_extra_debug_sigprint();
4043
4044 subview<eT>::operator=(in);
4045 }
4046
4047
4048
4049 template<typename eT>
4050 arma_inline
4051 arma_warn_unused
4052 const Op<subview_cols<eT>,op_htrans>
t() const4053 subview_cols<eT>::t() const
4054 {
4055 return Op<subview_cols<eT>,op_htrans>(*this);
4056 }
4057
4058
4059
4060 template<typename eT>
4061 arma_inline
4062 arma_warn_unused
4063 const Op<subview_cols<eT>,op_htrans>
ht() const4064 subview_cols<eT>::ht() const
4065 {
4066 return Op<subview_cols<eT>,op_htrans>(*this);
4067 }
4068
4069
4070
4071 template<typename eT>
4072 arma_inline
4073 arma_warn_unused
4074 const Op<subview_cols<eT>,op_strans>
st() const4075 subview_cols<eT>::st() const
4076 {
4077 return Op<subview_cols<eT>,op_strans>(*this);
4078 }
4079
4080
4081
4082 template<typename eT>
4083 arma_inline
4084 arma_warn_unused
4085 const Op<subview_cols<eT>,op_vectorise_col>
as_col() const4086 subview_cols<eT>::as_col() const
4087 {
4088 return Op<subview_cols<eT>,op_vectorise_col>(*this);
4089 }
4090
4091
4092
4093 template<typename eT>
4094 inline
4095 arma_warn_unused
4096 eT
at_alt(const uword ii) const4097 subview_cols<eT>::at_alt(const uword ii) const
4098 {
4099 return operator[](ii);
4100 }
4101
4102
4103
4104 template<typename eT>
4105 inline
4106 arma_warn_unused
4107 eT&
operator [](const uword ii)4108 subview_cols<eT>::operator[](const uword ii)
4109 {
4110 const uword index = subview<eT>::aux_col1 * subview<eT>::m.n_rows + ii;
4111
4112 return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
4113 }
4114
4115
4116
4117 template<typename eT>
4118 inline
4119 arma_warn_unused
4120 eT
operator [](const uword ii) const4121 subview_cols<eT>::operator[](const uword ii) const
4122 {
4123 const uword index = subview<eT>::aux_col1 * subview<eT>::m.n_rows + ii;
4124
4125 return subview<eT>::m.mem[index];
4126 }
4127
4128
4129
4130 template<typename eT>
4131 inline
4132 arma_warn_unused
4133 eT&
operator ()(const uword ii)4134 subview_cols<eT>::operator()(const uword ii)
4135 {
4136 arma_debug_check_bounds( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds" );
4137
4138 const uword index = subview<eT>::aux_col1 * subview<eT>::m.n_rows + ii;
4139
4140 return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
4141 }
4142
4143
4144
4145 template<typename eT>
4146 inline
4147 arma_warn_unused
4148 eT
operator ()(const uword ii) const4149 subview_cols<eT>::operator()(const uword ii) const
4150 {
4151 arma_debug_check_bounds( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds" );
4152
4153 const uword index = subview<eT>::aux_col1 * subview<eT>::m.n_rows + ii;
4154
4155 return subview<eT>::m.mem[index];
4156 }
4157
4158
4159
4160 template<typename eT>
4161 inline
4162 arma_warn_unused
4163 eT&
operator ()(const uword in_row,const uword in_col)4164 subview_cols<eT>::operator()(const uword in_row, const uword in_col)
4165 {
4166 arma_debug_check_bounds( ((in_row >= subview<eT>::n_rows) || (in_col >= subview<eT>::n_cols)), "subview::operator(): index out of bounds" );
4167
4168 const uword index = (in_col + subview<eT>::aux_col1) * subview<eT>::m.n_rows + in_row;
4169
4170 return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
4171 }
4172
4173
4174
4175 template<typename eT>
4176 inline
4177 arma_warn_unused
4178 eT
operator ()(const uword in_row,const uword in_col) const4179 subview_cols<eT>::operator()(const uword in_row, const uword in_col) const
4180 {
4181 arma_debug_check_bounds( ((in_row >= subview<eT>::n_rows) || (in_col >= subview<eT>::n_cols)), "subview::operator(): index out of bounds" );
4182
4183 const uword index = (in_col + subview<eT>::aux_col1) * subview<eT>::m.n_rows + in_row;
4184
4185 return subview<eT>::m.mem[index];
4186 }
4187
4188
4189
4190 template<typename eT>
4191 inline
4192 arma_warn_unused
4193 eT&
at(const uword in_row,const uword in_col)4194 subview_cols<eT>::at(const uword in_row, const uword in_col)
4195 {
4196 const uword index = (in_col + subview<eT>::aux_col1) * subview<eT>::m.n_rows + in_row;
4197
4198 return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
4199 }
4200
4201
4202
4203 template<typename eT>
4204 inline
4205 arma_warn_unused
4206 eT
at(const uword in_row,const uword in_col) const4207 subview_cols<eT>::at(const uword in_row, const uword in_col) const
4208 {
4209 const uword index = (in_col + subview<eT>::aux_col1) * subview<eT>::m.n_rows + in_row;
4210
4211 return subview<eT>::m.mem[index];
4212 }
4213
4214
4215
4216 template<typename eT>
4217 arma_inline
4218 eT*
colptr(const uword in_col)4219 subview_cols<eT>::colptr(const uword in_col)
4220 {
4221 return & access::rw((const_cast< Mat<eT>& >(subview<eT>::m)).mem[ (in_col + subview<eT>::aux_col1) * subview<eT>::m.n_rows ]);
4222 }
4223
4224
4225
4226 template<typename eT>
4227 arma_inline
4228 const eT*
colptr(const uword in_col) const4229 subview_cols<eT>::colptr(const uword in_col) const
4230 {
4231 return & subview<eT>::m.mem[ (in_col + subview<eT>::aux_col1) * subview<eT>::m.n_rows ];
4232 }
4233
4234
4235
4236 //
4237 //
4238 //
4239
4240
4241
4242 template<typename eT>
4243 inline
subview_row(const Mat<eT> & in_m,const uword in_row)4244 subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row)
4245 : subview<eT>(in_m, in_row, 0, 1, in_m.n_cols)
4246 {
4247 arma_extra_debug_sigprint();
4248 }
4249
4250
4251
4252 template<typename eT>
4253 inline
subview_row(const Mat<eT> & in_m,const uword in_row,const uword in_col1,const uword in_n_cols)4254 subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
4255 : subview<eT>(in_m, in_row, in_col1, 1, in_n_cols)
4256 {
4257 arma_extra_debug_sigprint();
4258 }
4259
4260
4261
4262 template<typename eT>
4263 inline
subview_row(const subview_row<eT> & in)4264 subview_row<eT>::subview_row(const subview_row<eT>& in)
4265 : subview<eT>(in) // interprets 'subview_row' as 'subview'
4266 {
4267 arma_extra_debug_sigprint();
4268 }
4269
4270
4271
4272 template<typename eT>
4273 inline
subview_row(subview_row<eT> && in)4274 subview_row<eT>::subview_row(subview_row<eT>&& in)
4275 : subview<eT>(std::move(in)) // interprets 'subview_row' as 'subview'
4276 {
4277 arma_extra_debug_sigprint();
4278 }
4279
4280
4281
4282 template<typename eT>
4283 inline
4284 void
operator =(const subview<eT> & X)4285 subview_row<eT>::operator=(const subview<eT>& X)
4286 {
4287 arma_extra_debug_sigprint();
4288
4289 subview<eT>::operator=(X);
4290 }
4291
4292
4293
4294 template<typename eT>
4295 inline
4296 void
operator =(const subview_row<eT> & X)4297 subview_row<eT>::operator=(const subview_row<eT>& X)
4298 {
4299 arma_extra_debug_sigprint();
4300
4301 subview<eT>::operator=(X); // interprets 'subview_row' as 'subview'
4302 }
4303
4304
4305
4306 template<typename eT>
4307 inline
4308 void
operator =(const eT val)4309 subview_row<eT>::operator=(const eT val)
4310 {
4311 arma_extra_debug_sigprint();
4312
4313 subview<eT>::operator=(val); // interprets 'subview_row' as 'subview'
4314 }
4315
4316
4317
4318 template<typename eT>
4319 inline
4320 void
operator =(const std::initializer_list<eT> & list)4321 subview_row<eT>::operator=(const std::initializer_list<eT>& list)
4322 {
4323 arma_extra_debug_sigprint();
4324
4325 const uword N = uword(list.size());
4326
4327 arma_debug_assert_same_size(subview<eT>::n_rows, subview<eT>::n_cols, 1, N, "copy into submatrix");
4328
4329 auto it = list.begin();
4330
4331 for(uword ii=0; ii < N; ++ii)
4332 {
4333 (*this).operator[](ii) = (*it);
4334 ++it;
4335 }
4336 }
4337
4338
4339
4340 template<typename eT>
4341 template<typename T1>
4342 inline
4343 void
operator =(const Base<eT,T1> & X)4344 subview_row<eT>::operator=(const Base<eT,T1>& X)
4345 {
4346 arma_extra_debug_sigprint();
4347
4348 subview<eT>::operator=(X);
4349 }
4350
4351
4352
4353 template<typename eT>
4354 template<typename T1>
4355 inline
4356 void
operator =(const SpBase<eT,T1> & X)4357 subview_row<eT>::operator=(const SpBase<eT,T1>& X)
4358 {
4359 arma_extra_debug_sigprint();
4360
4361 subview<eT>::operator=(X.get_ref());
4362 }
4363
4364
4365
4366 template<typename eT>
4367 template<typename T1, typename gen_type>
4368 inline
4369 typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void>::result
operator =(const Gen<T1,gen_type> & in)4370 subview_row<eT>::operator= (const Gen<T1,gen_type>& in)
4371 {
4372 arma_extra_debug_sigprint();
4373
4374 arma_debug_assert_same_size(uword(1), subview<eT>::n_cols, (in.is_row ? uword(1) : in.n_rows), in.n_cols, "copy into submatrix");
4375
4376 in.apply(*this);
4377 }
4378
4379
4380
4381 template<typename eT>
4382 arma_inline
4383 arma_warn_unused
4384 const Op<subview_row<eT>,op_htrans>
t() const4385 subview_row<eT>::t() const
4386 {
4387 return Op<subview_row<eT>,op_htrans>(*this);
4388 }
4389
4390
4391
4392 template<typename eT>
4393 arma_inline
4394 arma_warn_unused
4395 const Op<subview_row<eT>,op_htrans>
ht() const4396 subview_row<eT>::ht() const
4397 {
4398 return Op<subview_row<eT>,op_htrans>(*this);
4399 }
4400
4401
4402
4403 template<typename eT>
4404 arma_inline
4405 arma_warn_unused
4406 const Op<subview_row<eT>,op_strans>
st() const4407 subview_row<eT>::st() const
4408 {
4409 return Op<subview_row<eT>,op_strans>(*this);
4410 }
4411
4412
4413
4414 template<typename eT>
4415 arma_inline
4416 arma_warn_unused
4417 const Op<subview_row<eT>,op_strans>
as_col() const4418 subview_row<eT>::as_col() const
4419 {
4420 return Op<subview_row<eT>,op_strans>(*this);
4421 }
4422
4423
4424
4425 template<typename eT>
4426 inline
4427 eT
at_alt(const uword ii) const4428 subview_row<eT>::at_alt(const uword ii) const
4429 {
4430 const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4431
4432 return subview<eT>::m.mem[index];
4433 }
4434
4435
4436
4437 template<typename eT>
4438 inline
4439 eT&
operator [](const uword ii)4440 subview_row<eT>::operator[](const uword ii)
4441 {
4442 const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4443
4444 return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
4445 }
4446
4447
4448
4449 template<typename eT>
4450 inline
4451 eT
operator [](const uword ii) const4452 subview_row<eT>::operator[](const uword ii) const
4453 {
4454 const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4455
4456 return subview<eT>::m.mem[index];
4457 }
4458
4459
4460
4461 template<typename eT>
4462 inline
4463 eT&
operator ()(const uword ii)4464 subview_row<eT>::operator()(const uword ii)
4465 {
4466 arma_debug_check_bounds( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds" );
4467
4468 const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4469
4470 return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
4471 }
4472
4473
4474
4475 template<typename eT>
4476 inline
4477 eT
operator ()(const uword ii) const4478 subview_row<eT>::operator()(const uword ii) const
4479 {
4480 arma_debug_check_bounds( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds" );
4481
4482 const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4483
4484 return subview<eT>::m.mem[index];
4485 }
4486
4487
4488
4489 template<typename eT>
4490 inline
4491 eT&
operator ()(const uword in_row,const uword in_col)4492 subview_row<eT>::operator()(const uword in_row, const uword in_col)
4493 {
4494 arma_debug_check_bounds( ((in_row > 0) || (in_col >= subview<eT>::n_cols)), "subview::operator(): index out of bounds" );
4495
4496 const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4497
4498 return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
4499 }
4500
4501
4502
4503 template<typename eT>
4504 inline
4505 eT
operator ()(const uword in_row,const uword in_col) const4506 subview_row<eT>::operator()(const uword in_row, const uword in_col) const
4507 {
4508 arma_debug_check_bounds( ((in_row > 0) || (in_col >= subview<eT>::n_cols)), "subview::operator(): index out of bounds" );
4509
4510 const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4511
4512 return subview<eT>::m.mem[index];
4513 }
4514
4515
4516
4517 template<typename eT>
4518 inline
4519 eT&
at(const uword,const uword in_col)4520 subview_row<eT>::at(const uword, const uword in_col)
4521 {
4522 const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4523
4524 return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
4525 }
4526
4527
4528
4529 template<typename eT>
4530 inline
4531 eT
at(const uword,const uword in_col) const4532 subview_row<eT>::at(const uword, const uword in_col) const
4533 {
4534 const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
4535
4536 return subview<eT>::m.mem[index];
4537 }
4538
4539
4540
4541 template<typename eT>
4542 inline
4543 subview_row<eT>
cols(const uword in_col1,const uword in_col2)4544 subview_row<eT>::cols(const uword in_col1, const uword in_col2)
4545 {
4546 arma_extra_debug_sigprint();
4547
4548 arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used" );
4549
4550 const uword subview_n_cols = in_col2 - in_col1 + 1;
4551
4552 const uword base_col1 = this->aux_col1 + in_col1;
4553
4554 return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
4555 }
4556
4557
4558
4559 template<typename eT>
4560 inline
4561 const subview_row<eT>
cols(const uword in_col1,const uword in_col2) const4562 subview_row<eT>::cols(const uword in_col1, const uword in_col2) const
4563 {
4564 arma_extra_debug_sigprint();
4565
4566 arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::cols(): indices out of bounds or incorrectly used" );
4567
4568 const uword subview_n_cols = in_col2 - in_col1 + 1;
4569
4570 const uword base_col1 = this->aux_col1 + in_col1;
4571
4572 return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
4573 }
4574
4575
4576
4577 template<typename eT>
4578 inline
4579 subview_row<eT>
subvec(const uword in_col1,const uword in_col2)4580 subview_row<eT>::subvec(const uword in_col1, const uword in_col2)
4581 {
4582 arma_extra_debug_sigprint();
4583
4584 arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used" );
4585
4586 const uword subview_n_cols = in_col2 - in_col1 + 1;
4587
4588 const uword base_col1 = this->aux_col1 + in_col1;
4589
4590 return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
4591 }
4592
4593
4594
4595 template<typename eT>
4596 inline
4597 const subview_row<eT>
subvec(const uword in_col1,const uword in_col2) const4598 subview_row<eT>::subvec(const uword in_col1, const uword in_col2) const
4599 {
4600 arma_extra_debug_sigprint();
4601
4602 arma_debug_check_bounds( ( (in_col1 > in_col2) || (in_col2 >= subview<eT>::n_cols) ), "subview_row::subvec(): indices out of bounds or incorrectly used" );
4603
4604 const uword subview_n_cols = in_col2 - in_col1 + 1;
4605
4606 const uword base_col1 = this->aux_col1 + in_col1;
4607
4608 return subview_row<eT>(this->m, this->aux_row1, base_col1, subview_n_cols);
4609 }
4610
4611
4612
4613 template<typename eT>
4614 inline
4615 subview_row<eT>
subvec(const uword start_col,const SizeMat & s)4616 subview_row<eT>::subvec(const uword start_col, const SizeMat& s)
4617 {
4618 arma_extra_debug_sigprint();
4619
4620 arma_debug_check( (s.n_rows != 1), "subview_row::subvec(): given size does not specify a row vector" );
4621
4622 arma_debug_check_bounds( ( (start_col >= subview<eT>::n_cols) || ((start_col + s.n_cols) > subview<eT>::n_cols) ), "subview_row::subvec(): size out of bounds" );
4623
4624 const uword base_col1 = this->aux_col1 + start_col;
4625
4626 return subview_row<eT>(this->m, this->aux_row1, base_col1, s.n_cols);
4627 }
4628
4629
4630
4631 template<typename eT>
4632 inline
4633 const subview_row<eT>
subvec(const uword start_col,const SizeMat & s) const4634 subview_row<eT>::subvec(const uword start_col, const SizeMat& s) const
4635 {
4636 arma_extra_debug_sigprint();
4637
4638 arma_debug_check( (s.n_rows != 1), "subview_row::subvec(): given size does not specify a row vector" );
4639
4640 arma_debug_check_bounds( ( (start_col >= subview<eT>::n_cols) || ((start_col + s.n_cols) > subview<eT>::n_cols) ), "subview_row::subvec(): size out of bounds" );
4641
4642 const uword base_col1 = this->aux_col1 + start_col;
4643
4644 return subview_row<eT>(this->m, this->aux_row1, base_col1, s.n_cols);
4645 }
4646
4647
4648
4649 template<typename eT>
4650 inline
4651 subview_row<eT>
head(const uword N)4652 subview_row<eT>::head(const uword N)
4653 {
4654 arma_extra_debug_sigprint();
4655
4656 arma_debug_check_bounds( (N > subview<eT>::n_cols), "subview_row::head(): size out of bounds" );
4657
4658 return subview_row<eT>(this->m, this->aux_row1, this->aux_col1, N);
4659 }
4660
4661
4662
4663 template<typename eT>
4664 inline
4665 const subview_row<eT>
head(const uword N) const4666 subview_row<eT>::head(const uword N) const
4667 {
4668 arma_extra_debug_sigprint();
4669
4670 arma_debug_check_bounds( (N > subview<eT>::n_cols), "subview_row::head(): size out of bounds" );
4671
4672 return subview_row<eT>(this->m, this->aux_row1, this->aux_col1, N);
4673 }
4674
4675
4676
4677 template<typename eT>
4678 inline
4679 subview_row<eT>
tail(const uword N)4680 subview_row<eT>::tail(const uword N)
4681 {
4682 arma_extra_debug_sigprint();
4683
4684 arma_debug_check_bounds( (N > subview<eT>::n_cols), "subview_row::tail(): size out of bounds" );
4685
4686 const uword start_col = subview<eT>::aux_col1 + subview<eT>::n_cols - N;
4687
4688 return subview_row<eT>(this->m, this->aux_row1, start_col, N);
4689 }
4690
4691
4692
4693 template<typename eT>
4694 inline
4695 const subview_row<eT>
tail(const uword N) const4696 subview_row<eT>::tail(const uword N) const
4697 {
4698 arma_extra_debug_sigprint();
4699
4700 arma_debug_check_bounds( (N > subview<eT>::n_cols), "subview_row::tail(): size out of bounds" );
4701
4702 const uword start_col = subview<eT>::aux_col1 + subview<eT>::n_cols - N;
4703
4704 return subview_row<eT>(this->m, this->aux_row1, start_col, N);
4705 }
4706
4707
4708
4709 template<typename eT>
4710 inline
4711 arma_warn_unused
4712 uword
index_min() const4713 subview_row<eT>::index_min() const
4714 {
4715 const Proxy< subview_row<eT> > P(*this);
4716
4717 uword index = 0;
4718
4719 if(P.get_n_elem() == 0)
4720 {
4721 arma_debug_check(true, "index_min(): object has no elements");
4722 }
4723 else
4724 {
4725 op_min::min_with_index(P, index);
4726 }
4727
4728 return index;
4729 }
4730
4731
4732
4733 template<typename eT>
4734 inline
4735 arma_warn_unused
4736 uword
index_max() const4737 subview_row<eT>::index_max() const
4738 {
4739 const Proxy< subview_row<eT> > P(*this);
4740
4741 uword index = 0;
4742
4743 if(P.get_n_elem() == 0)
4744 {
4745 arma_debug_check(true, "index_max(): object has no elements");
4746 }
4747 else
4748 {
4749 op_max::max_with_index(P, index);
4750 }
4751
4752 return index;
4753 }
4754
4755
4756
4757 template<typename eT>
4758 inline
4759 typename subview<eT>::row_iterator
begin()4760 subview_row<eT>::begin()
4761 {
4762 return typename subview<eT>::row_iterator(*this, subview<eT>::aux_row1, subview<eT>::aux_col1);
4763 }
4764
4765
4766
4767 template<typename eT>
4768 inline
4769 typename subview<eT>::const_row_iterator
begin() const4770 subview_row<eT>::begin() const
4771 {
4772 return typename subview<eT>::const_row_iterator(*this, subview<eT>::aux_row1, subview<eT>::aux_col1);
4773 }
4774
4775
4776
4777 template<typename eT>
4778 inline
4779 typename subview<eT>::const_row_iterator
cbegin() const4780 subview_row<eT>::cbegin() const
4781 {
4782 return typename subview<eT>::const_row_iterator(*this, subview<eT>::aux_row1, subview<eT>::aux_col1);
4783 }
4784
4785
4786
4787 template<typename eT>
4788 inline
4789 typename subview<eT>::row_iterator
end()4790 subview_row<eT>::end()
4791 {
4792 return typename subview<eT>::row_iterator(*this, subview<eT>::aux_row1 + subview<eT>::n_rows, subview<eT>::aux_col1);
4793 }
4794
4795
4796
4797 template<typename eT>
4798 inline
4799 typename subview<eT>::const_row_iterator
end() const4800 subview_row<eT>::end() const
4801 {
4802 return typename subview<eT>::const_row_iterator(*this, subview<eT>::aux_row1 + subview<eT>::n_rows, subview<eT>::aux_col1);
4803 }
4804
4805
4806
4807 template<typename eT>
4808 inline
4809 typename subview<eT>::const_row_iterator
cend() const4810 subview_row<eT>::cend() const
4811 {
4812 return typename subview<eT>::const_row_iterator(*this, subview<eT>::aux_row1 + subview<eT>::n_rows, subview<eT>::aux_col1);
4813 }
4814
4815
4816
4817 //
4818 //
4819 //
4820
4821
4822
4823 template<typename eT>
4824 inline
subview_row_strans(const subview_row<eT> & in_sv_row)4825 subview_row_strans<eT>::subview_row_strans(const subview_row<eT>& in_sv_row)
4826 : sv_row(in_sv_row )
4827 , n_rows(in_sv_row.n_cols)
4828 , n_elem(in_sv_row.n_elem)
4829 {
4830 arma_extra_debug_sigprint();
4831 }
4832
4833
4834
4835 template<typename eT>
4836 inline
4837 void
extract(Mat<eT> & out) const4838 subview_row_strans<eT>::extract(Mat<eT>& out) const
4839 {
4840 arma_extra_debug_sigprint();
4841
4842 // NOTE: this function assumes that matrix 'out' has already been set to the correct size
4843
4844 const Mat<eT>& X = sv_row.m;
4845
4846 eT* out_mem = out.memptr();
4847
4848 const uword row = sv_row.aux_row1;
4849 const uword start_col = sv_row.aux_col1;
4850 const uword sv_row_n_cols = sv_row.n_cols;
4851
4852 uword ii,jj;
4853
4854 for(ii=0, jj=1; jj < sv_row_n_cols; ii+=2, jj+=2)
4855 {
4856 const eT tmp1 = X.at(row, start_col+ii);
4857 const eT tmp2 = X.at(row, start_col+jj);
4858
4859 out_mem[ii] = tmp1;
4860 out_mem[jj] = tmp2;
4861 }
4862
4863 if(ii < sv_row_n_cols)
4864 {
4865 out_mem[ii] = X.at(row, start_col+ii);
4866 }
4867 }
4868
4869
4870
4871 template<typename eT>
4872 inline
4873 eT
at_alt(const uword ii) const4874 subview_row_strans<eT>::at_alt(const uword ii) const
4875 {
4876 return sv_row[ii];
4877 }
4878
4879
4880
4881 template<typename eT>
4882 inline
4883 eT
operator [](const uword ii) const4884 subview_row_strans<eT>::operator[](const uword ii) const
4885 {
4886 return sv_row[ii];
4887 }
4888
4889
4890
4891 template<typename eT>
4892 inline
4893 eT
operator ()(const uword ii) const4894 subview_row_strans<eT>::operator()(const uword ii) const
4895 {
4896 return sv_row(ii);
4897 }
4898
4899
4900
4901 template<typename eT>
4902 inline
4903 eT
operator ()(const uword in_row,const uword in_col) const4904 subview_row_strans<eT>::operator()(const uword in_row, const uword in_col) const
4905 {
4906 return sv_row(in_col, in_row); // deliberately swapped
4907 }
4908
4909
4910
4911 template<typename eT>
4912 inline
4913 eT
at(const uword in_row,const uword) const4914 subview_row_strans<eT>::at(const uword in_row, const uword) const
4915 {
4916 return sv_row.at(0, in_row); // deliberately swapped
4917 }
4918
4919
4920
4921 //
4922 //
4923 //
4924
4925
4926
4927 template<typename eT>
4928 inline
subview_row_htrans(const subview_row<eT> & in_sv_row)4929 subview_row_htrans<eT>::subview_row_htrans(const subview_row<eT>& in_sv_row)
4930 : sv_row(in_sv_row )
4931 , n_rows(in_sv_row.n_cols)
4932 , n_elem(in_sv_row.n_elem)
4933 {
4934 arma_extra_debug_sigprint();
4935 }
4936
4937
4938
4939 template<typename eT>
4940 inline
4941 void
extract(Mat<eT> & out) const4942 subview_row_htrans<eT>::extract(Mat<eT>& out) const
4943 {
4944 arma_extra_debug_sigprint();
4945
4946 // NOTE: this function assumes that matrix 'out' has already been set to the correct size
4947
4948 const Mat<eT>& X = sv_row.m;
4949
4950 eT* out_mem = out.memptr();
4951
4952 const uword row = sv_row.aux_row1;
4953 const uword start_col = sv_row.aux_col1;
4954 const uword sv_row_n_cols = sv_row.n_cols;
4955
4956 for(uword ii=0; ii < sv_row_n_cols; ++ii)
4957 {
4958 out_mem[ii] = access::alt_conj( X.at(row, start_col+ii) );
4959 }
4960 }
4961
4962
4963
4964 template<typename eT>
4965 inline
4966 eT
at_alt(const uword ii) const4967 subview_row_htrans<eT>::at_alt(const uword ii) const
4968 {
4969 return access::alt_conj( sv_row[ii] );
4970 }
4971
4972
4973
4974 template<typename eT>
4975 inline
4976 eT
operator [](const uword ii) const4977 subview_row_htrans<eT>::operator[](const uword ii) const
4978 {
4979 return access::alt_conj( sv_row[ii] );
4980 }
4981
4982
4983
4984 template<typename eT>
4985 inline
4986 eT
operator ()(const uword ii) const4987 subview_row_htrans<eT>::operator()(const uword ii) const
4988 {
4989 return access::alt_conj( sv_row(ii) );
4990 }
4991
4992
4993
4994 template<typename eT>
4995 inline
4996 eT
operator ()(const uword in_row,const uword in_col) const4997 subview_row_htrans<eT>::operator()(const uword in_row, const uword in_col) const
4998 {
4999 return access::alt_conj( sv_row(in_col, in_row) ); // deliberately swapped
5000 }
5001
5002
5003
5004 template<typename eT>
5005 inline
5006 eT
at(const uword in_row,const uword) const5007 subview_row_htrans<eT>::at(const uword in_row, const uword) const
5008 {
5009 return access::alt_conj( sv_row.at(0, in_row) ); // deliberately swapped
5010 }
5011
5012
5013
5014 //! @}
5015