comparison armadillo-3.900.4/include/armadillo_bits/subview_cube_meat.hpp @ 49:1ec0e2823891

Switch to using subrepo copies of qm-dsp, nnls-chroma, vamp-plugin-sdk; update Armadillo version; assume build without external BLAS/LAPACK
author Chris Cannam
date Thu, 13 Jun 2013 10:25:24 +0100
parents
children
comparison
equal deleted inserted replaced
48:69251e11a913 49:1ec0e2823891
1 // Copyright (C) 2008-2013 NICTA (www.nicta.com.au)
2 // Copyright (C) 2008-2013 Conrad Sanderson
3 //
4 // This Source Code Form is subject to the terms of the Mozilla Public
5 // License, v. 2.0. If a copy of the MPL was not distributed with this
6 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8
9 //! \addtogroup subview_cube
10 //! @{
11
12
13 template<typename eT>
14 inline
15 subview_cube<eT>::~subview_cube()
16 {
17 arma_extra_debug_sigprint();
18 }
19
20
21
22 template<typename eT>
23 arma_inline
24 subview_cube<eT>::subview_cube
25 (
26 const Cube<eT>& in_m,
27 const uword in_row1,
28 const uword in_col1,
29 const uword in_slice1,
30 const uword in_n_rows,
31 const uword in_n_cols,
32 const uword in_n_slices
33 )
34 : m (in_m)
35 , aux_row1 (in_row1)
36 , aux_col1 (in_col1)
37 , aux_slice1 (in_slice1)
38 , n_rows (in_n_rows)
39 , n_cols (in_n_cols)
40 , n_elem_slice(in_n_rows * in_n_cols)
41 , n_slices (in_n_slices)
42 , n_elem (n_elem_slice * in_n_slices)
43 {
44 arma_extra_debug_sigprint();
45 }
46
47
48
49 template<typename eT>
50 inline
51 void
52 subview_cube<eT>::operator+= (const eT val)
53 {
54 arma_extra_debug_sigprint();
55
56 const uword local_n_rows = n_rows;
57 const uword local_n_cols = n_cols;
58 const uword local_n_slices = n_slices;
59
60 for(uword slice = 0; slice < local_n_slices; ++slice)
61 {
62 for(uword col = 0; col < local_n_cols; ++col)
63 {
64 arrayops::inplace_plus( slice_colptr(slice,col), val, local_n_rows );
65 }
66 }
67 }
68
69
70
71 template<typename eT>
72 inline
73 void
74 subview_cube<eT>::operator-= (const eT val)
75 {
76 arma_extra_debug_sigprint();
77
78 const uword local_n_rows = n_rows;
79 const uword local_n_cols = n_cols;
80 const uword local_n_slices = n_slices;
81
82 for(uword slice = 0; slice < local_n_slices; ++slice)
83 {
84 for(uword col = 0; col < local_n_cols; ++col)
85 {
86 arrayops::inplace_minus( slice_colptr(slice,col), val, local_n_rows );
87 }
88 }
89 }
90
91
92
93 template<typename eT>
94 inline
95 void
96 subview_cube<eT>::operator*= (const eT val)
97 {
98 arma_extra_debug_sigprint();
99
100 const uword local_n_rows = n_rows;
101 const uword local_n_cols = n_cols;
102 const uword local_n_slices = n_slices;
103
104 for(uword slice = 0; slice < local_n_slices; ++slice)
105 {
106 for(uword col = 0; col < local_n_cols; ++col)
107 {
108 arrayops::inplace_mul( slice_colptr(slice,col), val, local_n_rows );
109 }
110 }
111 }
112
113
114
115 template<typename eT>
116 inline
117 void
118 subview_cube<eT>::operator/= (const eT val)
119 {
120 arma_extra_debug_sigprint();
121
122 const uword local_n_rows = n_rows;
123 const uword local_n_cols = n_cols;
124 const uword local_n_slices = n_slices;
125
126 for(uword slice = 0; slice < local_n_slices; ++slice)
127 {
128 for(uword col = 0; col < local_n_cols; ++col)
129 {
130 arrayops::inplace_div( slice_colptr(slice,col), val, local_n_rows );
131 }
132 }
133 }
134
135
136
137 template<typename eT>
138 template<typename T1>
139 inline
140 void
141 subview_cube<eT>::operator= (const BaseCube<eT,T1>& in)
142 {
143 arma_extra_debug_sigprint();
144
145 const unwrap_cube<T1> tmp(in.get_ref());
146
147 const Cube<eT>& x = tmp.M;
148 subview_cube<eT>& t = *this;
149
150 arma_debug_assert_same_size(t, x, "copy into subcube");
151
152 const uword t_n_rows = t.n_rows;
153 const uword t_n_cols = t.n_cols;
154 const uword t_n_slices = t.n_slices;
155
156 for(uword slice = 0; slice < t_n_slices; ++slice)
157 {
158 for(uword col = 0; col < t_n_cols; ++col)
159 {
160 arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
161 }
162 }
163 }
164
165
166
167 template<typename eT>
168 template<typename T1>
169 inline
170 void
171 subview_cube<eT>::operator+= (const BaseCube<eT,T1>& in)
172 {
173 arma_extra_debug_sigprint();
174
175 const unwrap_cube<T1> tmp(in.get_ref());
176
177 const Cube<eT>& x = tmp.M;
178 subview_cube<eT>& t = *this;
179
180 arma_debug_assert_same_size(t, x, "addition");
181
182 const uword t_n_rows = t.n_rows;
183 const uword t_n_cols = t.n_cols;
184 const uword t_n_slices = t.n_slices;
185
186 for(uword slice = 0; slice < t_n_slices; ++slice)
187 {
188 for(uword col = 0; col < t_n_cols; ++col)
189 {
190 arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
191 }
192 }
193 }
194
195
196
197 template<typename eT>
198 template<typename T1>
199 inline
200 void
201 subview_cube<eT>::operator-= (const BaseCube<eT,T1>& in)
202 {
203 arma_extra_debug_sigprint();
204
205 const unwrap_cube<T1> tmp(in.get_ref());
206
207 const Cube<eT>& x = tmp.M;
208 subview_cube<eT>& t = *this;
209
210 arma_debug_assert_same_size(t, x, "subtraction");
211
212 const uword t_n_rows = t.n_rows;
213 const uword t_n_cols = t.n_cols;
214 const uword t_n_slices = t.n_slices;
215
216 for(uword slice = 0; slice < t_n_slices; ++slice)
217 {
218 for(uword col = 0; col < t_n_cols; ++col)
219 {
220 arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
221 }
222 }
223 }
224
225
226
227 template<typename eT>
228 template<typename T1>
229 inline
230 void
231 subview_cube<eT>::operator%= (const BaseCube<eT,T1>& in)
232 {
233 arma_extra_debug_sigprint();
234
235 const unwrap_cube<T1> tmp(in.get_ref());
236
237 const Cube<eT>& x = tmp.M;
238 subview_cube<eT>& t = *this;
239
240 arma_debug_assert_same_size(t, x, "element-wise multiplication");
241
242 const uword t_n_rows = t.n_rows;
243 const uword t_n_cols = t.n_cols;
244 const uword t_n_slices = t.n_slices;
245
246 for(uword slice = 0; slice < t_n_slices; ++slice)
247 {
248 for(uword col = 0; col < t_n_cols; ++col)
249 {
250 arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
251 }
252 }
253 }
254
255
256
257 template<typename eT>
258 template<typename T1>
259 inline
260 void
261 subview_cube<eT>::operator/= (const BaseCube<eT,T1>& in)
262 {
263 arma_extra_debug_sigprint();
264
265 const unwrap_cube<T1> tmp(in.get_ref());
266
267 const Cube<eT>& x = tmp.M;
268 subview_cube<eT>& t = *this;
269
270 arma_debug_assert_same_size(t, x, "element-wise division");
271
272 const uword t_n_rows = t.n_rows;
273 const uword t_n_cols = t.n_cols;
274 const uword t_n_slices = t.n_slices;
275
276 for(uword slice = 0; slice < t_n_slices; ++slice)
277 {
278 for(uword col = 0; col < t_n_cols; ++col)
279 {
280 arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
281 }
282 }
283 }
284
285
286
287 //! x.subcube(...) = y.subcube(...)
288 template<typename eT>
289 inline
290 void
291 subview_cube<eT>::operator= (const subview_cube<eT>& x_in)
292 {
293 arma_extra_debug_sigprint();
294
295 const bool overlap = check_overlap(x_in);
296
297 Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) : 0;
298 const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
299 const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) : x_in;
300
301 subview_cube<eT>& t = *this;
302
303 arma_debug_assert_same_size(t, x, "copy into subcube");
304
305 const uword t_n_rows = t.n_rows;
306 const uword t_n_cols = t.n_cols;
307 const uword t_n_slices = t.n_slices;
308
309 for(uword slice = 0; slice < t_n_slices; ++slice)
310 {
311 for(uword col = 0; col < t_n_cols; ++col)
312 {
313 arrayops::copy( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
314 }
315 }
316
317 if(overlap)
318 {
319 delete tmp_subview_cube;
320 delete tmp_cube;
321 }
322
323 }
324
325
326
327 template<typename eT>
328 inline
329 void
330 subview_cube<eT>::operator+= (const subview_cube<eT>& x_in)
331 {
332 arma_extra_debug_sigprint();
333
334 const bool overlap = check_overlap(x_in);
335
336 Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) : 0;
337 const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
338 const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) : x_in;
339
340 subview_cube<eT>& t = *this;
341
342 arma_debug_assert_same_size(t, x, "addition");
343
344 const uword t_n_rows = t.n_rows;
345 const uword t_n_cols = t.n_cols;
346 const uword t_n_slices = t.n_slices;
347
348 for(uword slice = 0; slice < t_n_slices; ++slice)
349 {
350 for(uword col = 0; col < t_n_cols; ++col)
351 {
352 arrayops::inplace_plus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
353 }
354 }
355
356 if(overlap)
357 {
358 delete tmp_subview_cube;
359 delete tmp_cube;
360 }
361
362 }
363
364
365
366 template<typename eT>
367 inline
368 void
369 subview_cube<eT>::operator-= (const subview_cube<eT>& x_in)
370 {
371 arma_extra_debug_sigprint();
372
373 const bool overlap = check_overlap(x_in);
374
375 Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) : 0;
376 const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
377 const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) : x_in;
378
379 subview_cube<eT>& t = *this;
380
381 arma_debug_assert_same_size(t, x, "subtraction");
382
383 const uword t_n_rows = t.n_rows;
384 const uword t_n_cols = t.n_cols;
385 const uword t_n_slices = t.n_slices;
386
387 for(uword slice = 0; slice < t_n_slices; ++slice)
388 {
389 for(uword col = 0; col < t_n_cols; ++col)
390 {
391 arrayops::inplace_minus( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
392 }
393 }
394
395 if(overlap)
396 {
397 delete tmp_subview_cube;
398 delete tmp_cube;
399 }
400
401 }
402
403
404
405 template<typename eT>
406 inline
407 void
408 subview_cube<eT>::operator%= (const subview_cube<eT>& x_in)
409 {
410 arma_extra_debug_sigprint();
411
412 const bool overlap = check_overlap(x_in);
413
414 Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) : 0;
415 const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
416 const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) : x_in;
417
418 subview_cube<eT>& t = *this;
419
420 arma_debug_assert_same_size(t, x, "element-wise multiplication");
421
422 const uword t_n_rows = t.n_rows;
423 const uword t_n_cols = t.n_cols;
424 const uword t_n_slices = t.n_slices;
425
426 for(uword slice = 0; slice < t_n_slices; ++slice)
427 {
428 for(uword col = 0; col < t_n_cols; ++col)
429 {
430 arrayops::inplace_mul( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
431 }
432 }
433
434 if(overlap)
435 {
436 delete tmp_subview_cube;
437 delete tmp_cube;
438 }
439
440 }
441
442
443
444 template<typename eT>
445 inline
446 void
447 subview_cube<eT>::operator/= (const subview_cube<eT>& x_in)
448 {
449 arma_extra_debug_sigprint();
450
451 const bool overlap = check_overlap(x_in);
452
453 Cube<eT>* tmp_cube = overlap ? new Cube<eT>(x_in.m) : 0;
454 const subview_cube<eT>* tmp_subview_cube = overlap ? new subview_cube<eT>(*tmp_cube, x_in.aux_row1, x_in.aux_col1, x_in.aux_slice1, x_in.n_rows, x_in.n_cols, x_in.n_slices) : 0;
455 const subview_cube<eT>& x = overlap ? (*tmp_subview_cube) : x_in;
456
457 subview_cube<eT>& t = *this;
458
459 arma_debug_assert_same_size(t, x, "element-wise division");
460
461 const uword t_n_rows = t.n_rows;
462 const uword t_n_cols = t.n_cols;
463 const uword t_n_slices = t.n_slices;
464
465 for(uword slice = 0; slice < t_n_slices; ++slice)
466 {
467 for(uword col = 0; col < t_n_cols; ++col)
468 {
469 arrayops::inplace_div( t.slice_colptr(slice,col), x.slice_colptr(slice,col), t_n_rows );
470 }
471 }
472
473 if(overlap)
474 {
475 delete tmp_subview_cube;
476 delete tmp_cube;
477 }
478
479 }
480
481
482
483 template<typename eT>
484 template<typename T1>
485 inline
486 void
487 subview_cube<eT>::operator= (const Base<eT,T1>& in)
488 {
489 arma_extra_debug_sigprint();
490
491 const unwrap<T1> tmp(in.get_ref());
492
493 const Mat<eT>& x = tmp.M;
494 subview_cube<eT>& t = *this;
495
496 const uword t_n_rows = t.n_rows;
497 const uword t_n_cols = t.n_cols;
498 const uword t_n_slices = t.n_slices;
499
500 const uword x_n_rows = x.n_rows;
501 const uword x_n_cols = x.n_cols;
502
503 if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
504 {
505 // interpret the matrix as a cube with one slice
506
507 for(uword col = 0; col < t_n_cols; ++col)
508 {
509 arrayops::copy( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
510 }
511 }
512 else
513 if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
514 {
515 for(uword i=0; i < t_n_slices; ++i)
516 {
517 arrayops::copy( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
518 }
519 }
520 else
521 if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
522 {
523 Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
524
525 const uword t_aux_row1 = t.aux_row1;
526 const uword t_aux_col1 = t.aux_col1;
527 const uword t_aux_slice1 = t.aux_slice1;
528
529 for(uword slice=0; slice < t_n_slices; ++slice)
530 {
531 const uword mod_slice = t_aux_slice1 + slice;
532
533 const eT* x_colptr = x.colptr(slice);
534
535 uword i,j;
536 for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
537 {
538 const eT tmp_i = x_colptr[i];
539 const eT tmp_j = x_colptr[j];
540
541 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) = tmp_i;
542 Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) = tmp_j;
543 }
544
545 if(i < t_n_cols)
546 {
547 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) = x_colptr[i];
548 }
549 }
550 }
551 else
552 {
553 if(arma_config::debug == true)
554 {
555 arma_stop( arma_incompat_size_string(t, x, "copy into subcube") );
556 }
557 }
558 }
559
560
561
562 template<typename eT>
563 template<typename T1>
564 inline
565 void
566 subview_cube<eT>::operator+= (const Base<eT,T1>& in)
567 {
568 arma_extra_debug_sigprint();
569
570 const unwrap<T1> tmp(in.get_ref());
571
572 const Mat<eT>& x = tmp.M;
573 subview_cube<eT>& t = *this;
574
575 const uword t_n_rows = t.n_rows;
576 const uword t_n_cols = t.n_cols;
577 const uword t_n_slices = t.n_slices;
578
579 const uword x_n_rows = x.n_rows;
580 const uword x_n_cols = x.n_cols;
581
582 if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
583 {
584 for(uword col = 0; col < t_n_cols; ++col)
585 {
586 arrayops::inplace_plus( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
587 }
588 }
589 else
590 if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
591 {
592 for(uword i=0; i < t_n_slices; ++i)
593 {
594 arrayops::inplace_plus( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
595 }
596 }
597 else
598 if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
599 {
600 Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
601
602 const uword t_aux_row1 = t.aux_row1;
603 const uword t_aux_col1 = t.aux_col1;
604 const uword t_aux_slice1 = t.aux_slice1;
605
606 for(uword slice=0; slice < t_n_slices; ++slice)
607 {
608 const uword mod_slice = t_aux_slice1 + slice;
609
610 const eT* x_colptr = x.colptr(slice);
611
612 uword i,j;
613 for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
614 {
615 const eT tmp_i = x_colptr[i];
616 const eT tmp_j = x_colptr[j];
617
618 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) += tmp_i;
619 Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) += tmp_j;
620 }
621
622 if(i < t_n_cols)
623 {
624 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) += x_colptr[i];
625 }
626 }
627 }
628 else
629 {
630 if(arma_config::debug == true)
631 {
632 arma_stop( arma_incompat_size_string(t, x, "addition") );
633 }
634 }
635 }
636
637
638
639 template<typename eT>
640 template<typename T1>
641 inline
642 void
643 subview_cube<eT>::operator-= (const Base<eT,T1>& in)
644 {
645 arma_extra_debug_sigprint();
646
647 const unwrap<T1> tmp(in.get_ref());
648
649 const Mat<eT>& x = tmp.M;
650 subview_cube<eT>& t = *this;
651
652 const uword t_n_rows = t.n_rows;
653 const uword t_n_cols = t.n_cols;
654 const uword t_n_slices = t.n_slices;
655
656 const uword x_n_rows = x.n_rows;
657 const uword x_n_cols = x.n_cols;
658
659 if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
660 {
661 for(uword col = 0; col < t_n_cols; ++col)
662 {
663 arrayops::inplace_minus( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
664 }
665 }
666 else
667 if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
668 {
669 for(uword i=0; i < t_n_slices; ++i)
670 {
671 arrayops::inplace_minus( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
672 }
673 }
674 else
675 if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
676 {
677 Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
678
679 const uword t_aux_row1 = t.aux_row1;
680 const uword t_aux_col1 = t.aux_col1;
681 const uword t_aux_slice1 = t.aux_slice1;
682
683 for(uword slice=0; slice < t_n_slices; ++slice)
684 {
685 const uword mod_slice = t_aux_slice1 + slice;
686
687 const eT* x_colptr = x.colptr(slice);
688
689 uword i,j;
690 for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
691 {
692 const eT tmp_i = x_colptr[i];
693 const eT tmp_j = x_colptr[j];
694
695 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) -= tmp_i;
696 Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) -= tmp_j;
697 }
698
699 if(i < t_n_cols)
700 {
701 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) -= x_colptr[i];
702 }
703 }
704 }
705 else
706 {
707 if(arma_config::debug == true)
708 {
709 arma_stop( arma_incompat_size_string(t, x, "subtraction") );
710 }
711 }
712 }
713
714
715
716 template<typename eT>
717 template<typename T1>
718 inline
719 void
720 subview_cube<eT>::operator%= (const Base<eT,T1>& in)
721 {
722 arma_extra_debug_sigprint();
723
724 const unwrap<T1> tmp(in.get_ref());
725
726 const Mat<eT>& x = tmp.M;
727 subview_cube<eT>& t = *this;
728
729 const uword t_n_rows = t.n_rows;
730 const uword t_n_cols = t.n_cols;
731 const uword t_n_slices = t.n_slices;
732
733 const uword x_n_rows = x.n_rows;
734 const uword x_n_cols = x.n_cols;
735
736 if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
737 {
738 for(uword col = 0; col < t_n_cols; ++col)
739 {
740 arrayops::inplace_mul( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
741 }
742 }
743 else
744 if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
745 {
746 for(uword i=0; i < t_n_slices; ++i)
747 {
748 arrayops::inplace_mul( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
749 }
750 }
751 else
752 if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
753 {
754 Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
755
756 const uword t_aux_row1 = t.aux_row1;
757 const uword t_aux_col1 = t.aux_col1;
758 const uword t_aux_slice1 = t.aux_slice1;
759
760 for(uword slice=0; slice < t_n_slices; ++slice)
761 {
762 const uword mod_slice = t_aux_slice1 + slice;
763
764 const eT* x_colptr = x.colptr(slice);
765
766 uword i,j;
767 for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
768 {
769 const eT tmp_i = x_colptr[i];
770 const eT tmp_j = x_colptr[j];
771
772 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) *= tmp_i;
773 Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) *= tmp_j;
774 }
775
776 if(i < t_n_cols)
777 {
778 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) *= x_colptr[i];
779 }
780 }
781 }
782 else
783 {
784 if(arma_config::debug == true)
785 {
786 arma_stop( arma_incompat_size_string(t, x, "element-wise multiplication") );
787 }
788 }
789 }
790
791
792
793 template<typename eT>
794 template<typename T1>
795 inline
796 void
797 subview_cube<eT>::operator/= (const Base<eT,T1>& in)
798 {
799 arma_extra_debug_sigprint();
800
801 const unwrap<T1> tmp(in.get_ref());
802
803 const Mat<eT>& x = tmp.M;
804 subview_cube<eT>& t = *this;
805
806 const uword t_n_rows = t.n_rows;
807 const uword t_n_cols = t.n_cols;
808 const uword t_n_slices = t.n_slices;
809
810 const uword x_n_rows = x.n_rows;
811 const uword x_n_cols = x.n_cols;
812
813 if( (t_n_rows == x_n_rows) && (t_n_cols == x_n_cols) && (t_n_slices == 1) )
814 {
815 for(uword col = 0; col < t_n_cols; ++col)
816 {
817 arrayops::inplace_div( t.slice_colptr(0, col), x.colptr(col), t_n_rows );
818 }
819 }
820 else
821 if( (t_n_rows == x_n_rows) && (t_n_cols == 1) && (t_n_slices == x_n_cols) )
822 {
823 for(uword i=0; i < t_n_slices; ++i)
824 {
825 arrayops::inplace_div( t.slice_colptr(i, 0), x.colptr(i), t_n_rows );
826 }
827 }
828 else
829 if( (t_n_rows == 1) && (t_n_cols == x_n_rows) && (t_n_slices == x_n_cols) )
830 {
831 Cube<eT>& Q = const_cast< Cube<eT>& >(t.m);
832
833 const uword t_aux_row1 = t.aux_row1;
834 const uword t_aux_col1 = t.aux_col1;
835 const uword t_aux_slice1 = t.aux_slice1;
836
837 for(uword slice=0; slice < t_n_slices; ++slice)
838 {
839 const uword mod_slice = t_aux_slice1 + slice;
840
841 const eT* x_colptr = x.colptr(slice);
842
843 uword i,j;
844 for(i=0, j=1; j < t_n_cols; i+=2, j+=2)
845 {
846 const eT tmp_i = x_colptr[i];
847 const eT tmp_j = x_colptr[j];
848
849 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) /= tmp_i;
850 Q.at(t_aux_row1, t_aux_col1 + j, mod_slice) /= tmp_j;
851 }
852
853 if(i < t_n_cols)
854 {
855 Q.at(t_aux_row1, t_aux_col1 + i, mod_slice) /= x_colptr[i];
856 }
857 }
858 }
859 else
860 {
861 if(arma_config::debug == true)
862 {
863 arma_stop( arma_incompat_size_string(t, x, "element-wise division") );
864 }
865 }
866 }
867
868
869
870 //! transform each element in the subview using a functor
871 template<typename eT>
872 template<typename functor>
873 inline
874 void
875 subview_cube<eT>::transform(functor F)
876 {
877 arma_extra_debug_sigprint();
878
879 Cube<eT>& Q = const_cast< Cube<eT>& >(m);
880
881 const uword start_col = aux_col1;
882 const uword start_row = aux_row1;
883 const uword start_slice = aux_slice1;
884
885 const uword end_col_plus1 = start_col + n_cols;
886 const uword end_row_plus1 = start_row + n_rows;
887 const uword end_slice_plus1 = start_slice + n_slices;
888
889 for(uword uslice = start_slice; uslice < end_slice_plus1; ++uslice)
890 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol )
891 for(uword urow = start_row; urow < end_row_plus1; ++urow )
892 {
893 Q.at(urow, ucol, uslice) = eT( F( Q.at(urow, ucol, uslice) ) );
894 }
895 }
896
897
898
899 //! imbue (fill) the subview with values provided by a functor
900 template<typename eT>
901 template<typename functor>
902 inline
903 void
904 subview_cube<eT>::imbue(functor F)
905 {
906 arma_extra_debug_sigprint();
907
908 Cube<eT>& Q = const_cast< Cube<eT>& >(m);
909
910 const uword start_col = aux_col1;
911 const uword start_row = aux_row1;
912 const uword start_slice = aux_slice1;
913
914 const uword end_col_plus1 = start_col + n_cols;
915 const uword end_row_plus1 = start_row + n_rows;
916 const uword end_slice_plus1 = start_slice + n_slices;
917
918 for(uword uslice = start_slice; uslice < end_slice_plus1; ++uslice)
919 for(uword ucol = start_col; ucol < end_col_plus1; ++ucol )
920 for(uword urow = start_row; urow < end_row_plus1; ++urow )
921 {
922 Q.at(urow, ucol, uslice) = eT( F() );
923 }
924 }
925
926
927
928 template<typename eT>
929 inline
930 void
931 subview_cube<eT>::fill(const eT val)
932 {
933 arma_extra_debug_sigprint();
934
935 const uword local_n_rows = n_rows;
936 const uword local_n_cols = n_cols;
937 const uword local_n_slices = n_slices;
938
939 for(uword slice = 0; slice < local_n_slices; ++slice)
940 {
941 for(uword col = 0; col < local_n_cols; ++col)
942 {
943 arrayops::inplace_set( slice_colptr(slice,col), val, local_n_rows );
944 }
945 }
946
947 }
948
949
950
951 template<typename eT>
952 inline
953 void
954 subview_cube<eT>::zeros()
955 {
956 arma_extra_debug_sigprint();
957
958 fill(eT(0));
959 }
960
961
962
963 template<typename eT>
964 inline
965 void
966 subview_cube<eT>::ones()
967 {
968 arma_extra_debug_sigprint();
969
970 fill(eT(1));
971 }
972
973
974
975 template<typename eT>
976 inline
977 eT
978 subview_cube<eT>::at_alt(const uword i) const
979 {
980 return operator[](i);
981 }
982
983
984
985 template<typename eT>
986 inline
987 eT&
988 subview_cube<eT>::operator[](const uword i)
989 {
990 const uword in_slice = i / n_elem_slice;
991 const uword offset = in_slice * n_elem_slice;
992 const uword j = i - offset;
993
994 const uword in_col = j / n_rows;
995 const uword in_row = j % n_rows;
996
997 const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
998
999 return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] );
1000 }
1001
1002
1003
1004 template<typename eT>
1005 inline
1006 eT
1007 subview_cube<eT>::operator[](const uword i) const
1008 {
1009 const uword in_slice = i / n_elem_slice;
1010 const uword offset = in_slice * n_elem_slice;
1011 const uword j = i - offset;
1012
1013 const uword in_col = j / n_rows;
1014 const uword in_row = j % n_rows;
1015
1016 const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1017
1018 return m.mem[index];
1019 }
1020
1021
1022
1023 template<typename eT>
1024 inline
1025 eT&
1026 subview_cube<eT>::operator()(const uword i)
1027 {
1028 arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds");
1029
1030 const uword in_slice = i / n_elem_slice;
1031 const uword offset = in_slice * n_elem_slice;
1032 const uword j = i - offset;
1033
1034 const uword in_col = j / n_rows;
1035 const uword in_row = j % n_rows;
1036
1037 const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1038
1039 return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] );
1040 }
1041
1042
1043
1044 template<typename eT>
1045 inline
1046 eT
1047 subview_cube<eT>::operator()(const uword i) const
1048 {
1049 arma_debug_check( (i >= n_elem), "subview_cube::operator(): index out of bounds");
1050
1051 const uword in_slice = i / n_elem_slice;
1052 const uword offset = in_slice * n_elem_slice;
1053 const uword j = i - offset;
1054
1055 const uword in_col = j / n_rows;
1056 const uword in_row = j % n_rows;
1057
1058 const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1059
1060 return m.mem[index];
1061 }
1062
1063
1064
1065 template<typename eT>
1066 arma_inline
1067 eT&
1068 subview_cube<eT>::operator()(const uword in_row, const uword in_col, const uword in_slice)
1069 {
1070 arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds");
1071
1072 const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1073
1074 return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] );
1075 }
1076
1077
1078
1079 template<typename eT>
1080 arma_inline
1081 eT
1082 subview_cube<eT>::operator()(const uword in_row, const uword in_col, const uword in_slice) const
1083 {
1084 arma_debug_check( ( (in_row >= n_rows) || (in_col >= n_cols) || (in_slice >= n_slices) ), "subview_cube::operator(): location out of bounds");
1085
1086 const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1087
1088 return m.mem[index];
1089 }
1090
1091
1092
1093 template<typename eT>
1094 arma_inline
1095 eT&
1096 subview_cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice)
1097 {
1098 const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1099
1100 return access::rw( (const_cast< Cube<eT>& >(m)).mem[index] );
1101 }
1102
1103
1104
1105 template<typename eT>
1106 arma_inline
1107 eT
1108 subview_cube<eT>::at(const uword in_row, const uword in_col, const uword in_slice) const
1109 {
1110 const uword index = (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 + in_row;
1111
1112 return m.mem[index];
1113 }
1114
1115
1116
1117 template<typename eT>
1118 arma_inline
1119 eT*
1120 subview_cube<eT>::slice_colptr(const uword in_slice, const uword in_col)
1121 {
1122 return & access::rw((const_cast< Cube<eT>& >(m)).mem[ (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 ]);
1123 }
1124
1125
1126
1127 template<typename eT>
1128 arma_inline
1129 const eT*
1130 subview_cube<eT>::slice_colptr(const uword in_slice, const uword in_col) const
1131 {
1132 return & m.mem[ (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 ];
1133 }
1134
1135
1136
1137 template<typename eT>
1138 inline
1139 bool
1140 subview_cube<eT>::check_overlap(const subview_cube<eT>& x) const
1141 {
1142 const subview_cube<eT>& t = *this;
1143
1144 if(&t.m != &x.m)
1145 {
1146 return false;
1147 }
1148 else
1149 {
1150 if( (t.n_elem == 0) || (x.n_elem == 0) )
1151 {
1152 return false;
1153 }
1154 else
1155 {
1156 const uword t_row_start = t.aux_row1;
1157 const uword t_row_end_p1 = t_row_start + t.n_rows;
1158
1159 const uword t_col_start = t.aux_col1;
1160 const uword t_col_end_p1 = t_col_start + t.n_cols;
1161
1162 const uword t_slice_start = t.aux_slice1;
1163 const uword t_slice_end_p1 = t_slice_start + t.n_slices;
1164
1165
1166 const uword x_row_start = x.aux_row1;
1167 const uword x_row_end_p1 = x_row_start + x.n_rows;
1168
1169 const uword x_col_start = x.aux_col1;
1170 const uword x_col_end_p1 = x_col_start + x.n_cols;
1171
1172 const uword x_slice_start = x.aux_slice1;
1173 const uword x_slice_end_p1 = x_slice_start + x.n_slices;
1174
1175
1176 const bool outside_rows = ( (x_row_start >= t_row_end_p1 ) || (t_row_start >= x_row_end_p1 ) );
1177 const bool outside_cols = ( (x_col_start >= t_col_end_p1 ) || (t_col_start >= x_col_end_p1 ) );
1178 const bool outside_slices = ( (x_slice_start >= t_slice_end_p1) || (t_slice_start >= x_slice_end_p1) );
1179
1180 return ( (outside_rows == false) && (outside_cols == false) && (outside_slices == false) );
1181 }
1182 }
1183 }
1184
1185
1186
1187 template<typename eT>
1188 inline
1189 bool
1190 subview_cube<eT>::check_overlap(const Mat<eT>& x) const
1191 {
1192 const subview_cube<eT>& t = *this;
1193
1194 const uword t_aux_slice1 = t.aux_slice1;
1195 const uword t_aux_slice2_plus_1 = t_aux_slice1 + t.n_slices;
1196
1197 for(uword slice = t_aux_slice1; slice < t_aux_slice2_plus_1; ++slice)
1198 {
1199 const Mat<eT>& y = *(t.m.mat_ptrs[slice]);
1200
1201 if( x.memptr() == y.memptr() )
1202 {
1203 return true;
1204 }
1205 }
1206
1207 return false;
1208 }
1209
1210
1211
1212 //! cube X = Y.subcube(...)
1213 template<typename eT>
1214 inline
1215 void
1216 subview_cube<eT>::extract(Cube<eT>& out, const subview_cube<eT>& in)
1217 {
1218 arma_extra_debug_sigprint();
1219
1220 // NOTE: we're assuming that the cube has already been set to the correct size and there is no aliasing;
1221 // size setting and alias checking is done by either the Cube contructor or operator=()
1222
1223 const uword n_rows = in.n_rows;
1224 const uword n_cols = in.n_cols;
1225 const uword n_slices = in.n_slices;
1226
1227 arma_extra_debug_print(arma_boost::format("out.n_rows = %d out.n_cols = %d out.n_slices = %d in.m.n_rows = %d in.m.n_cols = %d in.m.n_slices = %d") % out.n_rows % out.n_cols % out.n_slices % in.m.n_rows % in.m.n_cols % in.m.n_slices);
1228
1229
1230 for(uword slice = 0; slice < n_slices; ++slice)
1231 {
1232 for(uword col = 0; col < n_cols; ++col)
1233 {
1234 arrayops::copy( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
1235 }
1236 }
1237 }
1238
1239
1240
1241 //! cube X += Y.subcube(...)
1242 template<typename eT>
1243 inline
1244 void
1245 subview_cube<eT>::plus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
1246 {
1247 arma_extra_debug_sigprint();
1248
1249 arma_debug_assert_same_size(out, in, "addition");
1250
1251 const uword n_rows = out.n_rows;
1252 const uword n_cols = out.n_cols;
1253 const uword n_slices = out.n_slices;
1254
1255 for(uword slice = 0; slice<n_slices; ++slice)
1256 {
1257 for(uword col = 0; col<n_cols; ++col)
1258 {
1259 arrayops::inplace_plus( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
1260 }
1261 }
1262 }
1263
1264
1265
1266 //! cube X -= Y.subcube(...)
1267 template<typename eT>
1268 inline
1269 void
1270 subview_cube<eT>::minus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
1271 {
1272 arma_extra_debug_sigprint();
1273
1274 arma_debug_assert_same_size(out, in, "subtraction");
1275
1276 const uword n_rows = out.n_rows;
1277 const uword n_cols = out.n_cols;
1278 const uword n_slices = out.n_slices;
1279
1280 for(uword slice = 0; slice<n_slices; ++slice)
1281 {
1282 for(uword col = 0; col<n_cols; ++col)
1283 {
1284 arrayops::inplace_minus( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
1285 }
1286 }
1287 }
1288
1289
1290
1291 //! cube X %= Y.subcube(...)
1292 template<typename eT>
1293 inline
1294 void
1295 subview_cube<eT>::schur_inplace(Cube<eT>& out, const subview_cube<eT>& in)
1296 {
1297 arma_extra_debug_sigprint();
1298
1299 arma_debug_assert_same_size(out, in, "element-wise multiplication");
1300
1301 const uword n_rows = out.n_rows;
1302 const uword n_cols = out.n_cols;
1303 const uword n_slices = out.n_slices;
1304
1305 for(uword slice = 0; slice<n_slices; ++slice)
1306 {
1307 for(uword col = 0; col<n_cols; ++col)
1308 {
1309 arrayops::inplace_mul( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
1310 }
1311 }
1312 }
1313
1314
1315
1316 //! cube X /= Y.subcube(...)
1317 template<typename eT>
1318 inline
1319 void
1320 subview_cube<eT>::div_inplace(Cube<eT>& out, const subview_cube<eT>& in)
1321 {
1322 arma_extra_debug_sigprint();
1323
1324 arma_debug_assert_same_size(out, in, "element-wise division");
1325
1326 const uword n_rows = out.n_rows;
1327 const uword n_cols = out.n_cols;
1328 const uword n_slices = out.n_slices;
1329
1330 for(uword slice = 0; slice<n_slices; ++slice)
1331 {
1332 for(uword col = 0; col<n_cols; ++col)
1333 {
1334 arrayops::inplace_div( out.slice_colptr(slice,col), in.slice_colptr(slice,col), n_rows );
1335 }
1336 }
1337 }
1338
1339
1340
1341 //! mat X = Y.subcube(...)
1342 template<typename eT>
1343 inline
1344 void
1345 subview_cube<eT>::extract(Mat<eT>& out, const subview_cube<eT>& in)
1346 {
1347 arma_extra_debug_sigprint();
1348
1349 arma_debug_assert_cube_as_mat(out, in, "copy into matrix", false);
1350
1351 const uword in_n_rows = in.n_rows;
1352 const uword in_n_cols = in.n_cols;
1353 const uword in_n_slices = in.n_slices;
1354
1355 const uword out_vec_state = out.vec_state;
1356
1357 if(in_n_slices == 1)
1358 {
1359 out.set_size(in_n_rows, in_n_cols);
1360
1361 for(uword col=0; col < in_n_cols; ++col)
1362 {
1363 arrayops::copy( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
1364 }
1365 }
1366 else
1367 {
1368 if(out_vec_state == 0)
1369 {
1370 if(in_n_cols == 1)
1371 {
1372 out.set_size(in_n_rows, in_n_slices);
1373
1374 for(uword i=0; i < in_n_slices; ++i)
1375 {
1376 arrayops::copy( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
1377 }
1378 }
1379 else
1380 if(in_n_rows == 1)
1381 {
1382 const Cube<eT>& Q = in.m;
1383
1384 const uword in_aux_row1 = in.aux_row1;
1385 const uword in_aux_col1 = in.aux_col1;
1386 const uword in_aux_slice1 = in.aux_slice1;
1387
1388 out.set_size(in_n_cols, in_n_slices);
1389
1390 for(uword slice=0; slice < in_n_slices; ++slice)
1391 {
1392 const uword mod_slice = in_aux_slice1 + slice;
1393
1394 eT* out_colptr = out.colptr(slice);
1395
1396 uword i,j;
1397 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
1398 {
1399 const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1400 const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
1401
1402 out_colptr[i] = tmp_i;
1403 out_colptr[j] = tmp_j;
1404 }
1405
1406 if(i < in_n_cols)
1407 {
1408 out_colptr[i] = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1409 }
1410 }
1411 }
1412 }
1413 else
1414 {
1415 out.set_size(in_n_slices);
1416
1417 eT* out_mem = out.memptr();
1418
1419 const Cube<eT>& Q = in.m;
1420
1421 const uword in_aux_row1 = in.aux_row1;
1422 const uword in_aux_col1 = in.aux_col1;
1423 const uword in_aux_slice1 = in.aux_slice1;
1424
1425 for(uword i=0; i<in_n_slices; ++i)
1426 {
1427 out_mem[i] = Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
1428 }
1429 }
1430 }
1431 }
1432
1433
1434
1435 //! mat X += Y.subcube(...)
1436 template<typename eT>
1437 inline
1438 void
1439 subview_cube<eT>::plus_inplace(Mat<eT>& out, const subview_cube<eT>& in)
1440 {
1441 arma_extra_debug_sigprint();
1442
1443 arma_debug_assert_cube_as_mat(out, in, "addition", true);
1444
1445 const uword in_n_rows = in.n_rows;
1446 const uword in_n_cols = in.n_cols;
1447 const uword in_n_slices = in.n_slices;
1448
1449 const uword out_n_rows = out.n_rows;
1450 const uword out_n_cols = out.n_cols;
1451 const uword out_vec_state = out.vec_state;
1452
1453 if(in_n_slices == 1)
1454 {
1455 for(uword col=0; col < in_n_cols; ++col)
1456 {
1457 arrayops::inplace_plus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
1458 }
1459 }
1460 else
1461 {
1462 if(out_vec_state == 0)
1463 {
1464 if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
1465 {
1466 for(uword i=0; i < in_n_slices; ++i)
1467 {
1468 arrayops::inplace_plus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
1469 }
1470 }
1471 else
1472 if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
1473 {
1474 const Cube<eT>& Q = in.m;
1475
1476 const uword in_aux_row1 = in.aux_row1;
1477 const uword in_aux_col1 = in.aux_col1;
1478 const uword in_aux_slice1 = in.aux_slice1;
1479
1480 for(uword slice=0; slice < in_n_slices; ++slice)
1481 {
1482 const uword mod_slice = in_aux_slice1 + slice;
1483
1484 eT* out_colptr = out.colptr(slice);
1485
1486 uword i,j;
1487 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
1488 {
1489 const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1490 const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
1491
1492 out_colptr[i] += tmp_i;
1493 out_colptr[j] += tmp_j;
1494 }
1495
1496 if(i < in_n_cols)
1497 {
1498 out_colptr[i] += Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1499 }
1500 }
1501 }
1502 }
1503 else
1504 {
1505 eT* out_mem = out.memptr();
1506
1507 const Cube<eT>& Q = in.m;
1508
1509 const uword in_aux_row1 = in.aux_row1;
1510 const uword in_aux_col1 = in.aux_col1;
1511 const uword in_aux_slice1 = in.aux_slice1;
1512
1513 for(uword i=0; i<in_n_slices; ++i)
1514 {
1515 out_mem[i] += Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
1516 }
1517 }
1518 }
1519 }
1520
1521
1522
1523 //! mat X -= Y.subcube(...)
1524 template<typename eT>
1525 inline
1526 void
1527 subview_cube<eT>::minus_inplace(Mat<eT>& out, const subview_cube<eT>& in)
1528 {
1529 arma_extra_debug_sigprint();
1530
1531 arma_debug_assert_cube_as_mat(out, in, "subtraction", true);
1532
1533 const uword in_n_rows = in.n_rows;
1534 const uword in_n_cols = in.n_cols;
1535 const uword in_n_slices = in.n_slices;
1536
1537 const uword out_n_rows = out.n_rows;
1538 const uword out_n_cols = out.n_cols;
1539 const uword out_vec_state = out.vec_state;
1540
1541 if(in_n_slices == 1)
1542 {
1543 for(uword col=0; col < in_n_cols; ++col)
1544 {
1545 arrayops::inplace_minus( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
1546 }
1547 }
1548 else
1549 {
1550 if(out_vec_state == 0)
1551 {
1552 if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
1553 {
1554 for(uword i=0; i < in_n_slices; ++i)
1555 {
1556 arrayops::inplace_minus( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
1557 }
1558 }
1559 else
1560 if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
1561 {
1562 const Cube<eT>& Q = in.m;
1563
1564 const uword in_aux_row1 = in.aux_row1;
1565 const uword in_aux_col1 = in.aux_col1;
1566 const uword in_aux_slice1 = in.aux_slice1;
1567
1568 for(uword slice=0; slice < in_n_slices; ++slice)
1569 {
1570 const uword mod_slice = in_aux_slice1 + slice;
1571
1572 eT* out_colptr = out.colptr(slice);
1573
1574 uword i,j;
1575 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
1576 {
1577 const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1578 const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
1579
1580 out_colptr[i] -= tmp_i;
1581 out_colptr[j] -= tmp_j;
1582 }
1583
1584 if(i < in_n_cols)
1585 {
1586 out_colptr[i] -= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1587 }
1588 }
1589 }
1590 }
1591 else
1592 {
1593 eT* out_mem = out.memptr();
1594
1595 const Cube<eT>& Q = in.m;
1596
1597 const uword in_aux_row1 = in.aux_row1;
1598 const uword in_aux_col1 = in.aux_col1;
1599 const uword in_aux_slice1 = in.aux_slice1;
1600
1601 for(uword i=0; i<in_n_slices; ++i)
1602 {
1603 out_mem[i] -= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
1604 }
1605 }
1606 }
1607 }
1608
1609
1610
1611 //! mat X %= Y.subcube(...)
1612 template<typename eT>
1613 inline
1614 void
1615 subview_cube<eT>::schur_inplace(Mat<eT>& out, const subview_cube<eT>& in)
1616 {
1617 arma_extra_debug_sigprint();
1618
1619 arma_debug_assert_cube_as_mat(out, in, "element-wise multiplication", true);
1620
1621 const uword in_n_rows = in.n_rows;
1622 const uword in_n_cols = in.n_cols;
1623 const uword in_n_slices = in.n_slices;
1624
1625 const uword out_n_rows = out.n_rows;
1626 const uword out_n_cols = out.n_cols;
1627 const uword out_vec_state = out.vec_state;
1628
1629 if(in_n_slices == 1)
1630 {
1631 for(uword col=0; col < in_n_cols; ++col)
1632 {
1633 arrayops::inplace_mul( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
1634 }
1635 }
1636 else
1637 {
1638 if(out_vec_state == 0)
1639 {
1640 if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
1641 {
1642 for(uword i=0; i < in_n_slices; ++i)
1643 {
1644 arrayops::inplace_mul( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
1645 }
1646 }
1647 else
1648 if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
1649 {
1650 const Cube<eT>& Q = in.m;
1651
1652 const uword in_aux_row1 = in.aux_row1;
1653 const uword in_aux_col1 = in.aux_col1;
1654 const uword in_aux_slice1 = in.aux_slice1;
1655
1656 for(uword slice=0; slice < in_n_slices; ++slice)
1657 {
1658 const uword mod_slice = in_aux_slice1 + slice;
1659
1660 eT* out_colptr = out.colptr(slice);
1661
1662 uword i,j;
1663 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
1664 {
1665 const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1666 const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
1667
1668 out_colptr[i] *= tmp_i;
1669 out_colptr[j] *= tmp_j;
1670 }
1671
1672 if(i < in_n_cols)
1673 {
1674 out_colptr[i] *= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1675 }
1676 }
1677 }
1678 }
1679 else
1680 {
1681 eT* out_mem = out.memptr();
1682
1683 const Cube<eT>& Q = in.m;
1684
1685 const uword in_aux_row1 = in.aux_row1;
1686 const uword in_aux_col1 = in.aux_col1;
1687 const uword in_aux_slice1 = in.aux_slice1;
1688
1689 for(uword i=0; i<in_n_slices; ++i)
1690 {
1691 out_mem[i] *= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
1692 }
1693 }
1694 }
1695 }
1696
1697
1698
1699 //! mat X /= Y.subcube(...)
1700 template<typename eT>
1701 inline
1702 void
1703 subview_cube<eT>::div_inplace(Mat<eT>& out, const subview_cube<eT>& in)
1704 {
1705 arma_extra_debug_sigprint();
1706
1707 arma_debug_assert_cube_as_mat(out, in, "element-wise division", true);
1708
1709 const uword in_n_rows = in.n_rows;
1710 const uword in_n_cols = in.n_cols;
1711 const uword in_n_slices = in.n_slices;
1712
1713 const uword out_n_rows = out.n_rows;
1714 const uword out_n_cols = out.n_cols;
1715 const uword out_vec_state = out.vec_state;
1716
1717 if(in_n_slices == 1)
1718 {
1719 for(uword col=0; col < in_n_cols; ++col)
1720 {
1721 arrayops::inplace_div( out.colptr(col), in.slice_colptr(0, col), in_n_rows );
1722 }
1723 }
1724 else
1725 {
1726 if(out_vec_state == 0)
1727 {
1728 if( (in_n_rows == out_n_rows) && (in_n_cols == 1) && (in_n_slices == out_n_cols) )
1729 {
1730 for(uword i=0; i < in_n_slices; ++i)
1731 {
1732 arrayops::inplace_div( out.colptr(i), in.slice_colptr(i, 0), in_n_rows );
1733 }
1734 }
1735 else
1736 if( (in_n_rows == 1) && (in_n_cols == out_n_rows) && (in_n_slices == out_n_cols) )
1737 {
1738 const Cube<eT>& Q = in.m;
1739
1740 const uword in_aux_row1 = in.aux_row1;
1741 const uword in_aux_col1 = in.aux_col1;
1742 const uword in_aux_slice1 = in.aux_slice1;
1743
1744 for(uword slice=0; slice < in_n_slices; ++slice)
1745 {
1746 const uword mod_slice = in_aux_slice1 + slice;
1747
1748 eT* out_colptr = out.colptr(slice);
1749
1750 uword i,j;
1751 for(i=0, j=1; j < in_n_cols; i+=2, j+=2)
1752 {
1753 const eT tmp_i = Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1754 const eT tmp_j = Q.at(in_aux_row1, in_aux_col1 + j, mod_slice);
1755
1756 out_colptr[i] /= tmp_i;
1757 out_colptr[j] /= tmp_j;
1758 }
1759
1760 if(i < in_n_cols)
1761 {
1762 out_colptr[i] /= Q.at(in_aux_row1, in_aux_col1 + i, mod_slice);
1763 }
1764 }
1765 }
1766 }
1767 else
1768 {
1769 eT* out_mem = out.memptr();
1770
1771 const Cube<eT>& Q = in.m;
1772
1773 const uword in_aux_row1 = in.aux_row1;
1774 const uword in_aux_col1 = in.aux_col1;
1775 const uword in_aux_slice1 = in.aux_slice1;
1776
1777 for(uword i=0; i<in_n_slices; ++i)
1778 {
1779 out_mem[i] /= Q.at(in_aux_row1, in_aux_col1, in_aux_slice1 + i);
1780 }
1781 }
1782 }
1783 }
1784
1785
1786
1787 //! @}